Skip to content

Instantly share code, notes, and snippets.

@averne
Last active August 28, 2023 08:50
Show Gist options
  • Save averne/ad479113b133405e6f1b68251013b47a to your computer and use it in GitHub Desktop.
Save averne/ad479113b133405e6f1b68251013b47a to your computer and use it in GitHub Desktop.
NVDEC/deko3d interop
// Sample code (untested) for interop between NVDEC and deko3d
// * This only maps the luma plane, as an R8 texture (thus assuming 8-bit data),
// for 10+ bit you would need R16
// * For the chroma plane, the memblock can be shared with the luma plane,
// but you would need a new layout using R8G8 (R16G16 for 10+ bit),
// to adjust the width and height for subsampling,
// and to use (frame->data[1] - frame->data[0]) as offset into the memblock
// * Note that hardware decoding backbuffers are issued (and reused) from a pool,
// thus for efficient use you can cache images/buffer mappings.
// The map handle (ff_tx1_map_get_handle(map)) can be used a key for this.
// Empirically around 5 maps are observed to be concurrently in use, with mpv as client.
// Create layout for the texture
// The important part is to use DkImageFlags_UsageVideo,
// which ensures a consistent texture layout between NVDEC and the GPU
DkImageLayoutMaker layout_maker;
dkImageLayoutMakerDefaults(&layout_maker, dk_device);
layout_maker.type = DkImageType_2D;
layout_maker.format = DkImageFormat_R8_Unorm;
layout_maker.dimensions[0] = luma_width;
layout_maker.dimensions[1] = luma_height;
layout_maker.dimensions[2] = 1;
layout_maker.flags = DkImageFlags_UsageLoadStore |
DkImageFlags_Usage2DEngine | DkImageFlags_UsageVideo;
DkImageLayout layout;
dkImageLayoutInitialize(&layout, &layout_maker);
// Retrieve the CPU address of the decoded data,
// and create a GPU mapping (memblock) over it
AVFrame *frame; // The frame returned by the hardware decoder
AVTX1Map *map = ff_tx1_frame_get_fbuf_map(frame);
DkMemBlockMaker memblock_maker;
dkMemBlockMakerDefaults(&memblock_maker, dk_device, ff_tx1_map_get_size(map));
memblock_maker.flags = DkMemBlockFlags_CpuUncached |
DkMemBlockFlags_GpuCached | DkMemBlockFlags_Image;
memblock_maker.storage = ff_tx1_map_get_addr(map);
DkMemBlock memblock = dkMemBlockCreate(&memblock_maker);
// Finally, create a texture over that memblock using the layout we calculated
DkImage image;
dkImageInitialize(&image, &layout, memblock, 0);
// Initialize image/sample descriptors as usual,
// and invalidate the texture cache before use
// Deinitialization
dkMemBlockDestroy(memblock)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment