diff --git a/src/gallium/drivers/d3d12/d3d12_context.h b/src/gallium/drivers/d3d12/d3d12_context.h index 113edf06a8b..800257b977a 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.h +++ b/src/gallium/drivers/d3d12/d3d12_context.h @@ -39,6 +39,7 @@ #include "util/u_framebuffer.h" #include "util/u_suballoc.h" #include "util/u_threaded_context.h" +struct d3d12_context_queue_priority_manager; #define D3D12_GFX_SHADER_STAGES (MESA_SHADER_STAGES - 1) @@ -297,6 +298,11 @@ struct d3d12_context { /* used by d3d12_blit.cpp */ void *stencil_resolve_vs, *stencil_resolve_fs, *stencil_resolve_fs_no_flip, *sampler_state; #endif // HAVE_GALLIUM_D3D12_GRAPHICS + +#if ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + struct d3d12_context_queue_priority_manager* priority_manager; // Object passed and managed by frontend + mtx_t priority_manager_lock; // Mutex to protect access to priority_manager +#endif // ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) }; static inline struct d3d12_context * @@ -324,6 +330,11 @@ d3d12_current_batch(struct d3d12_context *ctx) struct pipe_context * d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags); +#if ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) +int +d3d12_context_set_queue_priority_manager(struct pipe_context *ctx, struct d3d12_context_queue_priority_manager *priority_manager); +#endif // ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + bool d3d12_enable_fake_so_buffers(struct d3d12_context *ctx, unsigned factor); diff --git a/src/gallium/drivers/d3d12/d3d12_context_common.cpp b/src/gallium/drivers/d3d12/d3d12_context_common.cpp index fdc283485fd..9ffc2f822ca 100644 --- a/src/gallium/drivers/d3d12/d3d12_context_common.cpp +++ b/src/gallium/drivers/d3d12/d3d12_context_common.cpp @@ -60,12 +60,27 @@ #include "util/u_dl.h" #include #include +#include "d3d12_interop_public.h" static void d3d12_context_destroy(struct pipe_context *pctx) { struct d3d12_context *ctx = d3d12_context(pctx); +#if ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + + if (ctx->priority_manager) + { + struct d3d12_screen *screen = d3d12_screen(pctx->screen); + if (ctx->priority_manager->unregister_work_queue(ctx->priority_manager, screen->cmdqueue) != 0) + { + debug_printf("D3D12: Failed to unregister command queue with frontend priority manager\n"); + assert(false); + } + } + +#endif // ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + struct d3d12_screen *screen = d3d12_screen(pctx->screen); mtx_lock(&screen->submit_mutex); list_del(&ctx->context_list_entry); @@ -339,6 +354,131 @@ d3d12_video_create_codec(struct pipe_context *context, } #endif +#if ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + +int +d3d12_context_set_queue_priority(struct d3d12_context_queue_priority_manager* manager, + ID3D12CommandQueue *d3d12_queue, + const uint32_t* global_priority, + const uint32_t* local_priority) +{ + if (!global_priority || !local_priority) + return -1; + + struct d3d12_context* ctx12 = d3d12_context(manager->context); + mtx_lock(&ctx12->priority_manager_lock); + { + // Set the queue priority + ComPtr prio_iface; + if(FAILED(d3d12_queue->QueryInterface(IID_PPV_ARGS(&prio_iface)))) + { + mtx_unlock(&ctx12->priority_manager_lock); + return -1; + } + + D3D12_COMMAND_QUEUE_GLOBAL_PRIORITY global_priority_val = static_cast(*global_priority); + if(FAILED(prio_iface->SetGlobalPriority(global_priority_val))) + { + mtx_unlock(&ctx12->priority_manager_lock); + return -1; + } + + D3D12_COMMAND_QUEUE_PROCESS_PRIORITY local_priority_val = static_cast(*local_priority); + if(FAILED(prio_iface->SetProcessPriority(local_priority_val))) + { + mtx_unlock(&ctx12->priority_manager_lock); + return -1; + } + } + + mtx_unlock(&ctx12->priority_manager_lock); + return 0; +} + +int +d3d12_context_get_queue_priority(struct d3d12_context_queue_priority_manager* manager, + ID3D12CommandQueue *d3d12_queue, + uint32_t *global_priority, + uint32_t *local_priority) +{ + struct d3d12_context* ctx12 = d3d12_context(manager->context); + + mtx_lock(&ctx12->priority_manager_lock); + { + ComPtr prio_iface; + if (FAILED(d3d12_queue->QueryInterface(IID_PPV_ARGS(&prio_iface)))) + { + mtx_unlock(&ctx12->priority_manager_lock); + return -1; + } + + if (global_priority) + { + D3D12_COMMAND_QUEUE_GLOBAL_PRIORITY global_priority_val = {}; + if (FAILED(prio_iface->GetGlobalPriority(&global_priority_val))) + { + mtx_unlock(&ctx12->priority_manager_lock); + return -1; + } + *global_priority = static_cast(global_priority_val); + } + + if (local_priority) + { + D3D12_COMMAND_QUEUE_PROCESS_PRIORITY local_priority_val = {}; + if (FAILED(prio_iface->GetProcessPriority(&local_priority_val))) + { + mtx_unlock(&ctx12->priority_manager_lock); + return -1; + } + *local_priority = static_cast(local_priority_val); + } + } + mtx_unlock(&ctx12->priority_manager_lock); + return 0; +} + +int +d3d12_context_set_queue_priority_manager(struct pipe_context *ctx, struct d3d12_context_queue_priority_manager *priority_manager) +{ + if (ctx && priority_manager) + { + struct d3d12_context *d3d12_ctx = d3d12_context(ctx); + d3d12_ctx->priority_manager = (struct d3d12_context_queue_priority_manager*) priority_manager; + + // Validate that the frontend has set all required function pointers + assert ( d3d12_ctx->priority_manager->register_work_queue ); + assert ( d3d12_ctx->priority_manager->unregister_work_queue ); + + // Initialize the priority manager lock + if (thrd_success != mtx_init(&d3d12_ctx->priority_manager_lock, mtx_plain)) + { + debug_printf("D3D12: Failed to initialize context priority manager lock\n"); + return 1; + } + + // + // Fill the function pointers for the context queue priority manager that the frontend expects + // + + d3d12_ctx->priority_manager->context = ctx; + d3d12_ctx->priority_manager->set_queue_priority = d3d12_context_set_queue_priority; + d3d12_ctx->priority_manager->get_queue_priority = d3d12_context_get_queue_priority; + + // Register the context's command queue with the frontend's priority manager + struct d3d12_screen *screen = d3d12_screen(ctx->screen); + if (d3d12_ctx->priority_manager->register_work_queue(d3d12_ctx->priority_manager, screen->cmdqueue) != 0) + { + debug_printf("D3D12: Failed to register command queue with frontend priority manager\n"); + return 1; + } + } + + return 0; +} + +#endif // ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + struct pipe_context * d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) { diff --git a/src/gallium/drivers/d3d12/d3d12_interop_public.h b/src/gallium/drivers/d3d12/d3d12_interop_public.h index 4376037731e..0e888ef19de 100644 --- a/src/gallium/drivers/d3d12/d3d12_interop_public.h +++ b/src/gallium/drivers/d3d12/d3d12_interop_public.h @@ -45,6 +45,136 @@ struct d3d12_interop_resource_info { uint64_t buffer_offset; }; +#if ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + +/* + * Structure that contains information about scheduling priority management + * for GPU workloads exposed through work queues. + * + * Used by gallium frontend and driver to manage scheduling priority + * of GPU workloads. + * + * The frontend passes the [Input] callbacks after context creation + * and the gallium driver fills the callbacks in this structure + * annotated as [Output] parameters. + * + */ +struct d3d12_context_queue_priority_manager +{ + /* + * [Input] Register a work queue. + * + * The driver must call register_work_queue() + * callback ONCE for every queue created. Multiple registrations of the same + * queue are idempotent. + * + * The callback passed is expected to be thread safe. + * + * Parameters: + * manager: [In] Pointer to the manager structure itself + * queue: [In] Driver passes the queue to be registered in the frontend + * + * return: 0 for success, error code otherwise + */ + int (*register_work_queue)(struct d3d12_context_queue_priority_manager* manager, ID3D12CommandQueue *queue); + + /* + * [Input] Unregister a work queue. + * + * The driver must call unregister_work_queue() + * callback ONCE for every queue destroyed + * that was previously registered by register_work_queue() + * + * The callback passed is expected to be thread safe. + * + * The driver will call unregister_work_queue() for all registered queues + * on destruction of the pipe_context for sanity. + * + * Parameters: + * manager: [In] Pointer to the manager structure itself + * queue: [In] Driver passes the queue to be unregistered in the frontend + * + * return: 0 for success, error code otherwise + */ + int (*unregister_work_queue)(struct d3d12_context_queue_priority_manager* manager, ID3D12CommandQueue *queue); + + /* + * [Output] Set the scheduling priority of a registered work queue. + * + * Frontend can call set_queue_priority() to set the priority of a registered queue. + * + * The function returned is expected to be thread safe. + * + * Parameters: + * manager: [In] Pointer to the manager structure itself + * queue: [In] The frontend sends one of the queues previously + * registered by the driver in register_work_queue, representing the + * queue to set the priority for + * global_priority: [In] the global priority to be set. Value castable from D3D12_COMMAND_QUEUE_GLOBAL_PRIORITY + * local_priority: [In] the local priority to be set. Value castable from D3D12_COMMAND_QUEUE_PROCESS_PRIORITY + * + * return: 0 for success, error code otherwise + */ + int (*set_queue_priority)(struct d3d12_context_queue_priority_manager* manager, + ID3D12CommandQueue *queue, + const uint32_t* global_priority, + const uint32_t* local_priority); + + /* + * [Output] Get the scheduling priority of a registered work queue. + * + * The function returned is expected to be thread safe. + * + * Parameters: + * manager: [In] Pointer to the manager structure itself + * queue: [In] The frontend sends one of the queues previously + * registered by the driver in register_work_queue, representing the + * queue to set the priority for + * global_priority: [Out] the current global priority of the queue. Value castable to D3D12_COMMAND_QUEUE_GLOBAL_PRIORITY + * local_priority: [Out] the current local priority of the queue. Value castable to D3D12_COMMAND_QUEUE_PROCESS_PRIORITY + * + * return: 0 for success, error code otherwise + */ + int (*get_queue_priority)(struct d3d12_context_queue_priority_manager* manager, + ID3D12CommandQueue *queue, + uint32_t *global_priority, + uint32_t *local_priority); + + struct pipe_context *context; +}; + +struct d3d12_interop_device_info1 { + uint64_t adapter_luid; + ID3D12Device *device; + ID3D12CommandQueue *queue; + + /* + * Function pointer to set a queue priority manager for a context. + * If this function is NULL, the driver does not support queue priority management. + * + * The lifetime of the d3d12_context_queue_priority_manager is managed by the caller, + * and it must be valid for the duration of the context's usage. + * The caller is responsible for destroying and cleaning up any previously + * set manager before calling this function. + * + * Any objects created by pipe_context that also create work queues + * such as pipe_video_codec, must also use the d3d12_context_queue_priority_manager, + * and unregister any queues on destruction of such children objects. + * + * The driver must call unregister_work_queue() for each registered queue + * on destruction of the pipe_context for sanity. + * + * Parameters: + * - pipe_context*: context to configure + * - d3d12_context_queue_priority_manager*: manager to use + * + * Returns int (0 for success, error code otherwise) + */ + int (*set_context_queue_priority_manager)(struct pipe_context *context, struct d3d12_context_queue_priority_manager *manager); +}; + +#endif // ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + #ifdef __cplusplus } #endif diff --git a/src/gallium/drivers/d3d12/d3d12_screen.cpp b/src/gallium/drivers/d3d12/d3d12_screen.cpp index b83582de22e..a350999e2b3 100644 --- a/src/gallium/drivers/d3d12/d3d12_screen.cpp +++ b/src/gallium/drivers/d3d12/d3d12_screen.cpp @@ -1157,6 +1157,15 @@ d3d12_interop_query_device_info(struct pipe_screen *pscreen, uint32_t data_size, memcpy(&info->adapter_luid, &screen->adapter_luid, sizeof(screen->adapter_luid)); info->device = screen->dev; info->queue = screen->cmdqueue; + +#if ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + if (data_size >= sizeof(d3d12_interop_device_info1)) { + d3d12_interop_device_info1 *info1 = (d3d12_interop_device_info1 *)data; + info1->set_context_queue_priority_manager = d3d12_context_set_queue_priority_manager; + return sizeof(*info1); + } +#endif // ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + return sizeof(*info); } @@ -1426,6 +1435,32 @@ try_create_device_factory(util_dl_library *d3d12_mod) } #endif +static bool +d3d12_init_screen_command_queue(struct d3d12_screen *screen, D3D12_COMMAND_QUEUE_FLAGS queue_flags) +{ + D3D12_COMMAND_QUEUE_DESC queue_desc = {}; + queue_desc.Type = screen->queue_type; + queue_desc.Flags = queue_flags; + +#ifndef _GAMING_XBOX + ID3D12Device9 *device9 = NULL; + if (SUCCEEDED(screen->dev->QueryInterface(&device9))) { + if (FAILED(device9->CreateCommandQueue1(&queue_desc, OpenGLOn12CreatorID, + IID_PPV_ARGS(&screen->cmdqueue)))) { + device9->Release(); + return false; + } + device9->Release(); + } else +#endif + { + if (FAILED(screen->dev->CreateCommandQueue(&queue_desc, + IID_PPV_ARGS(&screen->cmdqueue)))) + return false; + } + return true; +} + bool d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter) { @@ -1578,25 +1613,17 @@ d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter) } #endif // HAVE_GALLIUM_D3D12_GRAPHICS - D3D12_COMMAND_QUEUE_DESC queue_desc; - queue_desc.Type = screen->queue_type; - queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL; - queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; - queue_desc.NodeMask = 0; - -#ifndef _GAMING_XBOX - ID3D12Device9 *device9; - if (SUCCEEDED(screen->dev->QueryInterface(&device9))) { - if (FAILED(device9->CreateCommandQueue1(&queue_desc, OpenGLOn12CreatorID, - IID_PPV_ARGS(&screen->cmdqueue)))) - return false; - device9->Release(); +#if ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + if (d3d12_init_screen_command_queue(screen, D3D12_COMMAND_QUEUE_FLAG_ALLOW_DYNAMIC_PRIORITY)) { + screen->supports_dynamic_queue_priority = true; } else -#endif +#endif // ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) { - if (FAILED(screen->dev->CreateCommandQueue(&queue_desc, - IID_PPV_ARGS(&screen->cmdqueue)))) + screen->supports_dynamic_queue_priority = false; + if (!d3d12_init_screen_command_queue(screen, D3D12_COMMAND_QUEUE_FLAG_NONE)) { + debug_printf("D3D12: failed to create command queue\n"); return false; + } } if (FAILED(screen->dev->CreateFence(0, D3D12_FENCE_FLAG_SHARED, IID_PPV_ARGS(&screen->fence)))) diff --git a/src/gallium/drivers/d3d12/d3d12_screen.h b/src/gallium/drivers/d3d12/d3d12_screen.h index 5c5adea8eee..3ac643754d7 100644 --- a/src/gallium/drivers/d3d12/d3d12_screen.h +++ b/src/gallium/drivers/d3d12/d3d12_screen.h @@ -151,6 +151,7 @@ struct d3d12_screen { bool have_load_at_vertex; bool support_shader_images; bool support_create_not_resident; + bool supports_dynamic_queue_priority; #ifdef _GAMING_XBOX UINT64 frame_token; diff --git a/src/gallium/drivers/d3d12/d3d12_video_dec.cpp b/src/gallium/drivers/d3d12/d3d12_video_dec.cpp index a0332aeb70a..47505f7647f 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_dec.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_dec.cpp @@ -41,6 +41,7 @@ #endif #include "d3d12_video_buffer.h" #include "d3d12_residency.h" +#include "d3d12_interop_public.h" #include "vl/vl_video_buffer.h" #include "util/format/u_format.h" @@ -131,6 +132,21 @@ d3d12_video_create_decoder(struct pipe_context *context, const struct pipe_video goto failed; } +#if ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + + if (pD3D12Ctx->priority_manager) + { + // Register queue with priority manager + if (pD3D12Ctx->priority_manager->register_work_queue(pD3D12Ctx->priority_manager, pD3D12Dec->m_spDecodeCommandQueue.Get()) != 0) + { + debug_printf("[d3d12_video_decoder] d3d12_video_create_decoder - Failure on " + "pipe_priority_manager::register_work_queue\n"); + goto failed; + } + } + +#endif // ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + return &pD3D12Dec->base; failed: @@ -181,6 +197,20 @@ d3d12_video_decoder_destroy(struct pipe_video_codec *codec) // No need for m_pD3D12Screen as it is not managed by d3d12_video_decoder +#if ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + + struct d3d12_context* ctx = d3d12_context(pD3D12Dec->base.context); + if (ctx->priority_manager) + { + if (ctx->priority_manager->unregister_work_queue(ctx->priority_manager, pD3D12Dec->m_spDecodeCommandQueue.Get()) != 0) + { + debug_printf("D3D12: Failed to unregister command queue with frontend priority manager\n"); + assert(false); + } + } + +#endif // ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + // Call dtor to make ComPtr work delete pD3D12Dec; } @@ -824,6 +854,11 @@ d3d12_video_decoder_create_command_objects(const struct d3d12_screen *pD3D12Scre assert(pD3D12Dec->m_spD3D12VideoDevice); D3D12_COMMAND_QUEUE_DESC commandQueueDesc = { D3D12_COMMAND_LIST_TYPE_VIDEO_DECODE }; +#if ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + if (pD3D12Screen->supports_dynamic_queue_priority) + commandQueueDesc.Flags |= D3D12_COMMAND_QUEUE_FLAG_ALLOW_DYNAMIC_PRIORITY; +#endif // ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + HRESULT hr = pD3D12Screen->dev->CreateCommandQueue(&commandQueueDesc, IID_PPV_ARGS(pD3D12Dec->m_spDecodeCommandQueue.GetAddressOf())); if (FAILED(hr)) { diff --git a/src/gallium/drivers/d3d12/d3d12_video_enc.cpp b/src/gallium/drivers/d3d12/d3d12_video_enc.cpp index cd77f3e6b98..28c54fb0bc6 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_enc.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_enc.cpp @@ -46,6 +46,7 @@ #include "d3d12_video_encoder_references_manager_hevc.h" #include "d3d12_video_encoder_references_manager_av1.h" #include "d3d12_residency.h" +#include "d3d12_interop_public.h" #include "vl/vl_video_buffer.h" #include "util/format/u_format.h" @@ -257,6 +258,20 @@ d3d12_video_encoder_destroy(struct pipe_video_codec *codec) if (pD3D12Enc->m_SliceHeaderRepackBuffer) pD3D12Enc->m_screen->resource_destroy(pD3D12Enc->m_screen, pD3D12Enc->m_SliceHeaderRepackBuffer); +#if ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + + struct d3d12_context* ctx = d3d12_context(pD3D12Enc->base.context); + if (ctx->priority_manager) + { + if (ctx->priority_manager->unregister_work_queue(ctx->priority_manager, pD3D12Enc->m_spEncodeCommandQueue.Get()) != 0) + { + debug_printf("D3D12: Failed to unregister command queue with frontend priority manager\n"); + assert(false); + } + } + +#endif // ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + // Call d3d12_video_encoder dtor to make ComPtr and other member's destructors work delete pD3D12Enc; } @@ -2324,6 +2339,10 @@ d3d12_video_encoder_create_command_objects(struct d3d12_video_encoder *pD3D12Enc assert(pD3D12Enc->m_spD3D12VideoDevice); D3D12_COMMAND_QUEUE_DESC commandQueueDesc = { D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE }; +#if ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + if (pD3D12Enc->m_pD3D12Screen->supports_dynamic_queue_priority) + commandQueueDesc.Flags |= D3D12_COMMAND_QUEUE_FLAG_ALLOW_DYNAMIC_PRIORITY; +#endif // ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) HRESULT hr = pD3D12Enc->m_pD3D12Screen->dev->CreateCommandQueue( &commandQueueDesc, IID_PPV_ARGS(pD3D12Enc->m_spEncodeCommandQueue.GetAddressOf())); @@ -2452,6 +2471,21 @@ d3d12_video_encoder_create_encoder(struct pipe_context *context, const struct pi PIPE_VIDEO_CAP_ENC_SLICED_NOTIFICATIONS); d3d12_video_encoder_initialize_two_pass(pD3D12Enc, codec->two_pass); +#if ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + + if (pD3D12Ctx->priority_manager) + { + // Register queue with priority manager + if (pD3D12Ctx->priority_manager->register_work_queue(pD3D12Ctx->priority_manager, pD3D12Enc->m_spEncodeCommandQueue.Get()) != 0) + { + debug_printf("[d3d12_video_encoder] d3d12_video_encoder_create_encoder - Failure on " + "pipe_priority_manager::register_work_queue\n"); + goto failed; + } + } + +#endif // ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + return &pD3D12Enc->base; failed: diff --git a/src/gallium/drivers/d3d12/d3d12_video_proc.cpp b/src/gallium/drivers/d3d12/d3d12_video_proc.cpp index e2d689c5581..e3f4028e7c5 100644 --- a/src/gallium/drivers/d3d12/d3d12_video_proc.cpp +++ b/src/gallium/drivers/d3d12/d3d12_video_proc.cpp @@ -29,6 +29,7 @@ #include "d3d12_resource.h" #include "d3d12_video_buffer.h" #include "d3d12_format.h" +#include "d3d12_interop_public.h" void d3d12_video_processor_begin_frame(struct pipe_video_codec * codec, @@ -305,6 +306,20 @@ d3d12_video_processor_destroy(struct pipe_video_codec * codec) d3d12_video_processor_sync_completion(codec, curBatchFence, OS_TIMEOUT_INFINITE); } +#if ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + + struct d3d12_context* ctx = d3d12_context(pD3D12Proc->base.context); + if (ctx->priority_manager) + { + if (ctx->priority_manager->unregister_work_queue(ctx->priority_manager, pD3D12Proc->m_spCommandQueue.Get()) != 0) + { + debug_printf("D3D12: Failed to unregister command queue with frontend priority manager\n"); + assert(false); + } + } + +#endif // ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + // Call dtor to make ComPtr work delete pD3D12Proc; } @@ -473,6 +488,21 @@ d3d12_video_processor_create(struct pipe_context *context, const struct pipe_vid debug_printf("[d3d12_video_processor] d3d12_video_create_processor - Created successfully!\n"); +#if ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + + if (pD3D12Ctx->priority_manager) + { + // Register queue with priority manager + if (pD3D12Ctx->priority_manager->register_work_queue(pD3D12Ctx->priority_manager, pD3D12Proc->m_spCommandQueue.Get()) != 0) + { + debug_printf("[d3d12_video_processor] d3d12_video_create_processor - Failure on " + "pipe_priority_manager::register_work_queue\n"); + goto failed; + } + } + +#endif // ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + return &pD3D12Proc->base; failed: @@ -652,6 +682,10 @@ d3d12_video_processor_create_command_objects(struct d3d12_video_processor *pD3D1 assert(pD3D12Proc->m_spD3D12VideoDevice); D3D12_COMMAND_QUEUE_DESC commandQueueDesc = { D3D12_COMMAND_LIST_TYPE_VIDEO_PROCESS }; +#if ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) + if (pD3D12Proc->m_pD3D12Screen->supports_dynamic_queue_priority) + commandQueueDesc.Flags |= D3D12_COMMAND_QUEUE_FLAG_ALLOW_DYNAMIC_PRIORITY; +#endif // ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) ) HRESULT hr = pD3D12Proc->m_pD3D12Screen->dev->CreateCommandQueue( &commandQueueDesc, IID_PPV_ARGS(pD3D12Proc->m_spCommandQueue.GetAddressOf()));