From fd8457580968f1cf6c75a494875a3eeccfb0b84c Mon Sep 17 00:00:00 2001 From: Sil Vilerino Date: Wed, 7 Sep 2022 13:37:18 -0400 Subject: [PATCH] d3d12: Add support for importing d3d12_video_buffer from handle Reviewed-by: Giancarlo Devich Part-of: --- src/gallium/drivers/d3d12/d3d12_context.cpp | 1 + .../drivers/d3d12/d3d12_video_buffer.cpp | 45 ++++++++++++++++--- .../drivers/d3d12/d3d12_video_buffer.h | 8 ++++ src/gallium/include/pipe/p_context.h | 10 +++++ 4 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/d3d12/d3d12_context.cpp b/src/gallium/drivers/d3d12/d3d12_context.cpp index ef52590c2bf..83b1a41b89a 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.cpp +++ b/src/gallium/drivers/d3d12/d3d12_context.cpp @@ -2509,6 +2509,7 @@ d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) // Add d3d12 video functions entrypoints ctx->base.create_video_codec = d3d12_video_create_codec; ctx->base.create_video_buffer = d3d12_video_buffer_create; + ctx->base.video_buffer_from_handle = d3d12_video_buffer_from_handle; #endif slab_create_child(&ctx->transfer_pool, &d3d12_screen(pscreen)->transfer_pool); slab_create_child(&ctx->transfer_pool_unsync, &d3d12_screen(pscreen)->transfer_pool); diff --git a/src/gallium/drivers/d3d12/d3d12_video_buffer.cpp b/src/gallium/drivers/d3d12/d3d12_video_buffer.cpp index ad51a93d1f4..44b674d310a 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_buffer.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_buffer.cpp @@ -32,12 +32,13 @@ #include "util/u_video.h" #include "vl/vl_video_buffer.h" #include "util/u_sampler.h" +#include "frontend/winsys_handle.h" -/** - * creates a video buffer - */ -struct pipe_video_buffer * -d3d12_video_buffer_create(struct pipe_context *pipe, const struct pipe_video_buffer *tmpl) +static struct pipe_video_buffer * +d3d12_video_buffer_create_impl(struct pipe_context *pipe, + const struct pipe_video_buffer *tmpl, + struct winsys_handle *handle, + unsigned usage) { assert(pipe); assert(tmpl); @@ -46,7 +47,6 @@ d3d12_video_buffer_create(struct pipe_context *pipe, const struct pipe_video_buf /// Initialize d3d12_video_buffer /// - if (!(tmpl->buffer_format == PIPE_FORMAT_NV12)) { debug_printf("[d3d12_video_buffer] buffer_format is only supported as PIPE_FORMAT_NV12.\n"); return nullptr; @@ -91,7 +91,16 @@ d3d12_video_buffer_create(struct pipe_context *pipe, const struct pipe_video_buf templ.flags = 0; // This calls d3d12_create_resource as the function ptr is set in d3d12_screen.resource_create - pD3D12VideoBuffer->texture = (struct d3d12_resource *) pipe->screen->resource_create(pipe->screen, &templ); + if(handle) + { + // WINSYS_HANDLE_TYPE_D3D12_RES implies taking ownership of the reference + if(handle->type == WINSYS_HANDLE_TYPE_D3D12_RES) + ((IUnknown *)handle->com_obj)->AddRef(); + pD3D12VideoBuffer->texture = (struct d3d12_resource *) pipe->screen->resource_from_handle(pipe->screen, &templ, handle, usage); + } + else + pD3D12VideoBuffer->texture = (struct d3d12_resource *) pipe->screen->resource_create(pipe->screen, &templ); + d3d12_promote_to_permanent_residency((struct d3d12_screen*) pipe->screen, pD3D12VideoBuffer->texture); if (pD3D12VideoBuffer->texture == nullptr) { @@ -110,6 +119,28 @@ failed: return nullptr; } + +/** + * creates a video buffer from a handle + */ +struct pipe_video_buffer * +d3d12_video_buffer_from_handle( struct pipe_context *pipe, + const struct pipe_video_buffer *tmpl, + struct winsys_handle *handle, + unsigned usage) +{ + return d3d12_video_buffer_create_impl(pipe, tmpl, handle, usage); +} + +/** + * creates a video buffer + */ +struct pipe_video_buffer * +d3d12_video_buffer_create(struct pipe_context *pipe, const struct pipe_video_buffer *tmpl) +{ + return d3d12_video_buffer_create_impl(pipe, tmpl, NULL, 0); +} + /** * destroy this video buffer */ diff --git a/src/gallium/drivers/d3d12/d3d12_video_buffer.h b/src/gallium/drivers/d3d12/d3d12_video_buffer.h index 62f0454a2c3..292ac128a6e 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_buffer.h +++ b/src/gallium/drivers/d3d12/d3d12_video_buffer.h @@ -39,6 +39,14 @@ struct pipe_video_buffer * d3d12_video_buffer_create(struct pipe_context *pipe, const struct pipe_video_buffer *tmpl); +/** + * creates a video buffer from a handle + */ +struct pipe_video_buffer * +d3d12_video_buffer_from_handle( struct pipe_context *pipe, + const struct pipe_video_buffer *tmpl, + struct winsys_handle *handle, + unsigned usage); /** * destroy this video buffer */ diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index c4471a3723a..24f777ecb68 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -34,6 +34,7 @@ #include "p_defines.h" #include "util/u_debug.h" #include +#include "frontend/winsys_handle.h" #ifdef __cplusplus extern "C" { @@ -1192,6 +1193,15 @@ struct pipe_context { const struct pipe_video_buffer *templat, const uint64_t *modifiers, unsigned int modifiers_count); + + /** + * Creates a video buffer as decoding target, from external memory + */ + struct pipe_video_buffer *(*video_buffer_from_handle)( struct pipe_context *context, + const struct pipe_video_buffer *templat, + struct winsys_handle *handle, + unsigned usage ); + };