d3d12: Implement d3d12_context_queue_priority_manager

Reviewed-by: Pohsiang (John) Hsu <pohhsu@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37376>
This commit is contained in:
Sil Vilerino 2025-09-04 16:41:22 -04:00 committed by Marge Bot
parent 304e3ab552
commit 11db73820f
8 changed files with 428 additions and 16 deletions

View file

@ -39,6 +39,7 @@
#include "util/u_framebuffer.h" #include "util/u_framebuffer.h"
#include "util/u_suballoc.h" #include "util/u_suballoc.h"
#include "util/u_threaded_context.h" #include "util/u_threaded_context.h"
struct d3d12_context_queue_priority_manager;
#define D3D12_GFX_SHADER_STAGES (MESA_SHADER_STAGES - 1) #define D3D12_GFX_SHADER_STAGES (MESA_SHADER_STAGES - 1)
@ -297,6 +298,11 @@ struct d3d12_context {
/* used by d3d12_blit.cpp */ /* used by d3d12_blit.cpp */
void *stencil_resolve_vs, *stencil_resolve_fs, *stencil_resolve_fs_no_flip, *sampler_state; void *stencil_resolve_vs, *stencil_resolve_fs, *stencil_resolve_fs_no_flip, *sampler_state;
#endif // HAVE_GALLIUM_D3D12_GRAPHICS #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 * static inline struct d3d12_context *
@ -324,6 +330,11 @@ d3d12_current_batch(struct d3d12_context *ctx)
struct pipe_context * struct pipe_context *
d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags); 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 bool
d3d12_enable_fake_so_buffers(struct d3d12_context *ctx, unsigned factor); d3d12_enable_fake_so_buffers(struct d3d12_context *ctx, unsigned factor);

View file

@ -60,12 +60,27 @@
#include "util/u_dl.h" #include "util/u_dl.h"
#include <dxguids/dxguids.h> #include <dxguids/dxguids.h>
#include <string.h> #include <string.h>
#include "d3d12_interop_public.h"
static void static void
d3d12_context_destroy(struct pipe_context *pctx) d3d12_context_destroy(struct pipe_context *pctx)
{ {
struct d3d12_context *ctx = d3d12_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); struct d3d12_screen *screen = d3d12_screen(pctx->screen);
mtx_lock(&screen->submit_mutex); mtx_lock(&screen->submit_mutex);
list_del(&ctx->context_list_entry); list_del(&ctx->context_list_entry);
@ -339,6 +354,131 @@ d3d12_video_create_codec(struct pipe_context *context,
} }
#endif #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<ID3D12CommandQueueDynamicPriorityPreview> 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<D3D12_COMMAND_QUEUE_GLOBAL_PRIORITY>(*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<D3D12_COMMAND_QUEUE_PROCESS_PRIORITY>(*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<ID3D12CommandQueueDynamicPriorityPreview> 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<uint32_t>(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<uint32_t>(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 * struct pipe_context *
d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
{ {

View file

@ -45,6 +45,136 @@ struct d3d12_interop_resource_info {
uint64_t buffer_offset; 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 #ifdef __cplusplus
} }
#endif #endif

View file

@ -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)); memcpy(&info->adapter_luid, &screen->adapter_luid, sizeof(screen->adapter_luid));
info->device = screen->dev; info->device = screen->dev;
info->queue = screen->cmdqueue; 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); return sizeof(*info);
} }
@ -1426,6 +1435,32 @@ try_create_device_factory(util_dl_library *d3d12_mod)
} }
#endif #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 bool
d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter) 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 #endif // HAVE_GALLIUM_D3D12_GRAPHICS
D3D12_COMMAND_QUEUE_DESC queue_desc; #if ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) )
queue_desc.Type = screen->queue_type; if (d3d12_init_screen_command_queue(screen, D3D12_COMMAND_QUEUE_FLAG_ALLOW_DYNAMIC_PRIORITY)) {
queue_desc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL; screen->supports_dynamic_queue_priority = true;
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();
} else } else
#endif #endif // ( USE_D3D12_PREVIEW_HEADERS && ( D3D12_PREVIEW_SDK_VERSION >= 717 ) )
{ {
if (FAILED(screen->dev->CreateCommandQueue(&queue_desc, screen->supports_dynamic_queue_priority = false;
IID_PPV_ARGS(&screen->cmdqueue)))) if (!d3d12_init_screen_command_queue(screen, D3D12_COMMAND_QUEUE_FLAG_NONE)) {
debug_printf("D3D12: failed to create command queue\n");
return false; return false;
}
} }
if (FAILED(screen->dev->CreateFence(0, D3D12_FENCE_FLAG_SHARED, IID_PPV_ARGS(&screen->fence)))) if (FAILED(screen->dev->CreateFence(0, D3D12_FENCE_FLAG_SHARED, IID_PPV_ARGS(&screen->fence))))

View file

@ -151,6 +151,7 @@ struct d3d12_screen {
bool have_load_at_vertex; bool have_load_at_vertex;
bool support_shader_images; bool support_shader_images;
bool support_create_not_resident; bool support_create_not_resident;
bool supports_dynamic_queue_priority;
#ifdef _GAMING_XBOX #ifdef _GAMING_XBOX
UINT64 frame_token; UINT64 frame_token;

View file

@ -41,6 +41,7 @@
#endif #endif
#include "d3d12_video_buffer.h" #include "d3d12_video_buffer.h"
#include "d3d12_residency.h" #include "d3d12_residency.h"
#include "d3d12_interop_public.h"
#include "vl/vl_video_buffer.h" #include "vl/vl_video_buffer.h"
#include "util/format/u_format.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; 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; return &pD3D12Dec->base;
failed: 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 // 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 // Call dtor to make ComPtr work
delete pD3D12Dec; delete pD3D12Dec;
} }
@ -824,6 +854,11 @@ d3d12_video_decoder_create_command_objects(const struct d3d12_screen *pD3D12Scre
assert(pD3D12Dec->m_spD3D12VideoDevice); assert(pD3D12Dec->m_spD3D12VideoDevice);
D3D12_COMMAND_QUEUE_DESC commandQueueDesc = { D3D12_COMMAND_LIST_TYPE_VIDEO_DECODE }; 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, HRESULT hr = pD3D12Screen->dev->CreateCommandQueue(&commandQueueDesc,
IID_PPV_ARGS(pD3D12Dec->m_spDecodeCommandQueue.GetAddressOf())); IID_PPV_ARGS(pD3D12Dec->m_spDecodeCommandQueue.GetAddressOf()));
if (FAILED(hr)) { if (FAILED(hr)) {

View file

@ -46,6 +46,7 @@
#include "d3d12_video_encoder_references_manager_hevc.h" #include "d3d12_video_encoder_references_manager_hevc.h"
#include "d3d12_video_encoder_references_manager_av1.h" #include "d3d12_video_encoder_references_manager_av1.h"
#include "d3d12_residency.h" #include "d3d12_residency.h"
#include "d3d12_interop_public.h"
#include "vl/vl_video_buffer.h" #include "vl/vl_video_buffer.h"
#include "util/format/u_format.h" #include "util/format/u_format.h"
@ -257,6 +258,20 @@ d3d12_video_encoder_destroy(struct pipe_video_codec *codec)
if (pD3D12Enc->m_SliceHeaderRepackBuffer) if (pD3D12Enc->m_SliceHeaderRepackBuffer)
pD3D12Enc->m_screen->resource_destroy(pD3D12Enc->m_screen, 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 // Call d3d12_video_encoder dtor to make ComPtr and other member's destructors work
delete pD3D12Enc; delete pD3D12Enc;
} }
@ -2324,6 +2339,10 @@ d3d12_video_encoder_create_command_objects(struct d3d12_video_encoder *pD3D12Enc
assert(pD3D12Enc->m_spD3D12VideoDevice); assert(pD3D12Enc->m_spD3D12VideoDevice);
D3D12_COMMAND_QUEUE_DESC commandQueueDesc = { D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE }; 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( HRESULT hr = pD3D12Enc->m_pD3D12Screen->dev->CreateCommandQueue(
&commandQueueDesc, &commandQueueDesc,
IID_PPV_ARGS(pD3D12Enc->m_spEncodeCommandQueue.GetAddressOf())); 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); PIPE_VIDEO_CAP_ENC_SLICED_NOTIFICATIONS);
d3d12_video_encoder_initialize_two_pass(pD3D12Enc, codec->two_pass); 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; return &pD3D12Enc->base;
failed: failed:

View file

@ -29,6 +29,7 @@
#include "d3d12_resource.h" #include "d3d12_resource.h"
#include "d3d12_video_buffer.h" #include "d3d12_video_buffer.h"
#include "d3d12_format.h" #include "d3d12_format.h"
#include "d3d12_interop_public.h"
void void
d3d12_video_processor_begin_frame(struct pipe_video_codec * codec, 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); 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 // Call dtor to make ComPtr work
delete pD3D12Proc; 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"); 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; return &pD3D12Proc->base;
failed: failed:
@ -652,6 +682,10 @@ d3d12_video_processor_create_command_objects(struct d3d12_video_processor *pD3D1
assert(pD3D12Proc->m_spD3D12VideoDevice); assert(pD3D12Proc->m_spD3D12VideoDevice);
D3D12_COMMAND_QUEUE_DESC commandQueueDesc = { D3D12_COMMAND_LIST_TYPE_VIDEO_PROCESS }; 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( HRESULT hr = pD3D12Proc->m_pD3D12Screen->dev->CreateCommandQueue(
&commandQueueDesc, &commandQueueDesc,
IID_PPV_ARGS(pD3D12Proc->m_spCommandQueue.GetAddressOf())); IID_PPV_ARGS(pD3D12Proc->m_spCommandQueue.GetAddressOf()));