Last active
August 28, 2023 08:50
-
-
Save averne/ad479113b133405e6f1b68251013b47a to your computer and use it in GitHub Desktop.
NVDEC/deko3d interop
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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