d3d12commandqueue: Update API name and arguments

Accepts multiple fences since single command list may have
multiple dependent resources which are associated with
different GPU engines

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7057>
This commit is contained in:
Seungha Yang 2024-06-18 22:04:23 +09:00 committed by GStreamer Marge Bot
parent 713ea313f8
commit 6942868bda
10 changed files with 74 additions and 43 deletions

View file

@ -262,7 +262,7 @@ gst_d3d12_command_queue_execute_command_lists_unlocked (GstD3D12CommandQueue *
* gst_d3d12_command_queue_execute_command_lists: * gst_d3d12_command_queue_execute_command_lists:
* @queue: a #GstD3D12CommandQueue * @queue: a #GstD3D12CommandQueue
* @num_command_lists: command list size * @num_command_lists: command list size
* @command_lists: array of ID3D12CommandList * @command_lists: (allow-none): array of ID3D12CommandList
* @fence_value: (out) (optional): fence value of submitted command * @fence_value: (out) (optional): fence value of submitted command
* *
* Executes command list and signals queue. If @num_command_lists is zero, * Executes command list and signals queue. If @num_command_lists is zero,
@ -287,35 +287,42 @@ gst_d3d12_command_queue_execute_command_lists (GstD3D12CommandQueue * queue,
} }
/** /**
* gst_d3d12_command_queue_execute_wait_and_command_lists: * gst_d3d12_command_queue_execute_command_lists_full:
* @queue: a #GstD3D12CommandQueue * @queue: a #GstD3D12CommandQueue
* @fence_to_wait: (allow-none): a ID3D11Fence * @num_fences_to_wait: the number of fences to wait
* @fence_value_to_wait: fence value to wait * @fences_to_wait: (allow-none): array of ID3D11Fence
* @fence_values_to_wait: (allow-none): array of fence value to wait
* @num_command_lists: command list size * @num_command_lists: command list size
* @command_lists: array of ID3D12CommandList * @command_lists: (allow-none): array of ID3D12CommandList
* @fence_value: (out) (optional): fence value of submitted command * @fence_value: (out) (optional): fence value of submitted command
* *
* Executes wait if @fence_to_wait is passed, and executes command list. * Executes wait if @num_fences_to_wait is non-zero, and executes command list.
* *
* Return: HRESULT code * Return: HRESULT code
* *
* Since: 1.26 * Since: 1.26
*/ */
HRESULT HRESULT
gst_d3d12_command_queue_execute_wait_and_command_lists (GstD3D12CommandQueue * gst_d3d12_command_queue_execute_command_lists_full (GstD3D12CommandQueue *
queue, ID3D12Fence * fence_to_wait, guint64 fence_value_to_wait, queue, guint num_fences_to_wait, ID3D12Fence ** fences_to_wait,
guint num_command_lists, ID3D12CommandList ** command_lists, const guint64 * fence_values_to_wait, guint num_command_lists,
guint64 * fence_value) ID3D12CommandList ** command_lists, guint64 * fence_value)
{ {
g_return_val_if_fail (GST_IS_D3D12_COMMAND_QUEUE (queue), E_INVALIDARG); g_return_val_if_fail (GST_IS_D3D12_COMMAND_QUEUE (queue), E_INVALIDARG);
g_return_val_if_fail (num_fences_to_wait == 0 ||
(fences_to_wait && fence_values_to_wait), E_INVALIDARG);
auto priv = queue->priv; auto priv = queue->priv;
std::lock_guard < std::mutex > lk (priv->execute_lock); std::lock_guard < std::mutex > lk (priv->execute_lock);
if (fence_to_wait) { for (guint i = 0; i < num_fences_to_wait; i++) {
auto hr = priv->cq->Wait (fence_to_wait, fence_value_to_wait); auto fence = fences_to_wait[i];
if (FAILED (hr)) auto val = fence_values_to_wait[i];
return hr; if (fence != priv->fence.Get () && fence->GetCompletedValue () < val) {
auto hr = priv->cq->Wait (fence, val);
if (FAILED (hr))
return hr;
}
} }
return gst_d3d12_command_queue_execute_command_lists_unlocked (queue, return gst_d3d12_command_queue_execute_command_lists_unlocked (queue,

View file

@ -86,12 +86,13 @@ HRESULT gst_d3d12_command_queue_execute_command_lists (GstD3D12Co
guint64 * fence_value); guint64 * fence_value);
GST_D3D12_API GST_D3D12_API
HRESULT gst_d3d12_command_queue_execute_wait_and_command_lists (GstD3D12CommandQueue * queue, HRESULT gst_d3d12_command_queue_execute_command_lists_full (GstD3D12CommandQueue * queue,
ID3D12Fence * fence_to_wait, guint num_fences_to_wait,
guint64 fence_value_to_wait, ID3D12Fence ** fences_to_wait,
guint num_command_lists, const guint64 * fence_values_to_wait,
ID3D12CommandList ** command_lists, guint num_command_lists,
guint64 * fence_value); ID3D12CommandList ** command_lists,
guint64 * fence_value);
GST_D3D12_API GST_D3D12_API
HRESULT gst_d3d12_command_queue_execute_wait (GstD3D12CommandQueue * queue, HRESULT gst_d3d12_command_queue_execute_wait (GstD3D12CommandQueue * queue,

View file

@ -48,8 +48,9 @@ gboolean gst_d3d12_device_copy_texture_region (GstD3D12Device * device,
guint num_args, guint num_args,
const GstD3D12CopyTextureRegionArgs * args, const GstD3D12CopyTextureRegionArgs * args,
GstD3D12FenceData * fence_data, GstD3D12FenceData * fence_data,
ID3D12Fence * fence_to_wait, guint num_fences_to_wait,
guint64 fence_value_to_wait, ID3D12Fence ** fences_to_wait,
const guint64 * fence_values_to_wait,
D3D12_COMMAND_LIST_TYPE command_type, D3D12_COMMAND_LIST_TYPE command_type,
guint64 * fence_value); guint64 * fence_value);

View file

@ -1504,8 +1504,8 @@ gst_d3d12_device_fence_wait (GstD3D12Device * device,
gboolean gboolean
gst_d3d12_device_copy_texture_region (GstD3D12Device * device, gst_d3d12_device_copy_texture_region (GstD3D12Device * device,
guint num_args, const GstD3D12CopyTextureRegionArgs * args, guint num_args, const GstD3D12CopyTextureRegionArgs * args,
GstD3D12FenceData * fence_data, GstD3D12FenceData * fence_data, guint num_fences_to_wait,
ID3D12Fence * fence_to_wait, guint64 fence_value_to_wait, ID3D12Fence ** fences_to_wait, const guint64 * fence_values_to_wait,
D3D12_COMMAND_LIST_TYPE command_type, guint64 * fence_value) D3D12_COMMAND_LIST_TYPE command_type, guint64 * fence_value)
{ {
g_return_val_if_fail (GST_IS_D3D12_DEVICE (device), FALSE); g_return_val_if_fail (GST_IS_D3D12_DEVICE (device), FALSE);
@ -1581,8 +1581,10 @@ gst_d3d12_device_copy_texture_region (GstD3D12Device * device,
} }
ID3D12CommandList *cmd_list[] = { cl.Get () }; ID3D12CommandList *cmd_list[] = { cl.Get () };
hr = gst_d3d12_command_queue_execute_wait_and_command_lists (queue,
fence_to_wait, fence_value_to_wait, 1, cmd_list, &fence_val); hr = gst_d3d12_command_queue_execute_command_lists_full (queue,
num_fences_to_wait, fences_to_wait, fence_values_to_wait, 1, cmd_list,
&fence_val);
auto ret = gst_d3d12_result (hr, device); auto ret = gst_d3d12_result (hr, device);
/* We can release command list since command list pool will hold it */ /* We can release command list since command list pool will hold it */

View file

@ -359,7 +359,7 @@ gst_d3d12_frame_copy (GstD3D12Frame * dest, const GstD3D12Frame * src,
return gst_d3d12_device_copy_texture_region (dest->device, return gst_d3d12_device_copy_texture_region (dest->device,
GST_VIDEO_INFO_N_PLANES (&dest->info), args, fence_data, GST_VIDEO_INFO_N_PLANES (&dest->info), args, fence_data,
nullptr, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, fence_value); 0, nullptr, nullptr, D3D12_COMMAND_LIST_TYPE_DIRECT, fence_value);
} }
/** /**
@ -414,7 +414,8 @@ gst_d3d12_frame_copy_plane (GstD3D12Frame * dest, const GstD3D12Frame * src,
cq_handle->Wait (dest->fence[plane].fence, dest->fence[plane].fence_value); cq_handle->Wait (dest->fence[plane].fence, dest->fence[plane].fence_value);
return gst_d3d12_device_copy_texture_region (dest->device, 1, &args, return gst_d3d12_device_copy_texture_region (dest->device, 1, &args,
fence_data, nullptr, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, fence_value); fence_data, 0, nullptr, nullptr, D3D12_COMMAND_LIST_TYPE_DIRECT,
fence_value);
} }
/** /**

View file

@ -488,12 +488,14 @@ gst_d3d12_memory_download (GstD3D12Memory * dmem)
auto cq = gst_d3d12_device_get_command_queue (dmem->device, auto cq = gst_d3d12_device_get_command_queue (dmem->device,
D3D12_COMMAND_LIST_TYPE_DIRECT); D3D12_COMMAND_LIST_TYPE_DIRECT);
auto direct_fence = gst_d3d12_command_queue_get_fence_handle (cq); ID3D12Fence *direct_fence[] =
{ gst_d3d12_command_queue_get_fence_handle (cq) };
guint64 fence_value_to_wait[] = { dmem->fence_value };
guint64 fence_val = 0; guint64 fence_val = 0;
/* Use async copy queue when downloading */ /* Use async copy queue when downloading */
if (!gst_d3d12_device_copy_texture_region (dmem->device, copy_args.size (), if (!gst_d3d12_device_copy_texture_region (dmem->device, copy_args.size (),
copy_args.data (), nullptr, direct_fence, dmem->fence_value, copy_args.data (), nullptr, 1, direct_fence, fence_value_to_wait,
D3D12_COMMAND_LIST_TYPE_COPY, &fence_val)) { D3D12_COMMAND_LIST_TYPE_COPY, &fence_val)) {
GST_ERROR_OBJECT (dmem->device, "Couldn't download texture to staging"); GST_ERROR_OBJECT (dmem->device, "Couldn't download texture to staging");
return FALSE; return FALSE;
@ -529,9 +531,15 @@ gst_d3d12_memory_upload (GstD3D12Memory * dmem)
copy_args.push_back (args); copy_args.push_back (args);
} }
guint num_fences_to_wait = 0;
ID3D12Fence *fences_to_wait[] = { priv->external_fence.Get () };
guint64 fence_values_to_wait[] = { priv->external_fence_val };
if (fences_to_wait[0])
num_fences_to_wait = 1;
if (!gst_d3d12_device_copy_texture_region (dmem->device, copy_args.size (), if (!gst_d3d12_device_copy_texture_region (dmem->device, copy_args.size (),
copy_args.data (), nullptr, priv->external_fence.Get (), copy_args.data (), nullptr, num_fences_to_wait, fences_to_wait,
priv->external_fence_val, D3D12_COMMAND_LIST_TYPE_DIRECT, fence_values_to_wait, D3D12_COMMAND_LIST_TYPE_DIRECT,
&dmem->fence_value)) { &dmem->fence_value)) {
GST_ERROR_OBJECT (dmem->device, "Couldn't upload texture"); GST_ERROR_OBJECT (dmem->device, "Couldn't upload texture");
return FALSE; return FALSE;
@ -1177,11 +1185,11 @@ gst_d3d12_memory_copy (GstMemory * mem, gssize offset, gssize size)
gst_memory_unmap (mem, &info); gst_memory_unmap (mem, &info);
ComPtr < ID3D12Fence > fence_to_wait; ComPtr < ID3D12Fence > fence_to_wait;
guint64 fence_value_to_wait; guint64 fence_value_to_wait[1];
{ {
std::lock_guard < std::mutex > lk (mem_priv->lock); std::lock_guard < std::mutex > lk (mem_priv->lock);
fence_to_wait = mem_priv->external_fence; fence_to_wait = mem_priv->external_fence;
fence_value_to_wait = mem_priv->external_fence_val; fence_value_to_wait[0] = mem_priv->external_fence_val;
} }
GstD3D12FenceData *fence_data; GstD3D12FenceData *fence_data;
@ -1189,9 +1197,14 @@ gst_d3d12_memory_copy (GstMemory * mem, gssize offset, gssize size)
gst_d3d12_fence_data_add_notify_mini_object (fence_data, gst_d3d12_fence_data_add_notify_mini_object (fence_data,
gst_memory_ref (mem)); gst_memory_ref (mem));
ID3D12Fence *fences_to_wait[] = { fence_to_wait.Get () };
guint num_fences_to_wait = 0;
if (fence_to_wait)
num_fences_to_wait = 1;
gst_d3d12_device_copy_texture_region (dmem->device, gst_d3d12_device_copy_texture_region (dmem->device,
copy_args.size (), copy_args.data (), fence_data, fence_to_wait.Get (), copy_args.size (), copy_args.data (), fence_data, num_fences_to_wait,
fence_value_to_wait, D3D12_COMMAND_LIST_TYPE_DIRECT, fences_to_wait, fence_value_to_wait, D3D12_COMMAND_LIST_TYPE_DIRECT,
&dst_dmem->fence_value); &dst_dmem->fence_value);
GST_MINI_OBJECT_FLAG_SET (dst, GST_D3D12_MEMORY_TRANSFER_NEED_DOWNLOAD); GST_MINI_OBJECT_FLAG_SET (dst, GST_D3D12_MEMORY_TRANSFER_NEED_DOWNLOAD);

View file

@ -1539,8 +1539,8 @@ gst_d3d12_decoder_process_output (GstD3D12Decoder * self,
} }
gst_d3d12_device_copy_texture_region (self->device, copy_args.size (), gst_d3d12_device_copy_texture_region (self->device, copy_args.size (),
copy_args.data (), fence_data, nullptr, decoder_pic->fence_val, copy_args.data (), fence_data, 0, nullptr, nullptr, queue_type,
queue_type, &copy_fence_val); &copy_fence_val);
if (!out_resource) { if (!out_resource) {
guint8 *map_data; guint8 *map_data;

View file

@ -776,9 +776,15 @@ gst_d3d12_encoder_upload_frame (GstD3D12Encoder * self, GstBuffer * buffer)
} }
guint64 fence_val = 0; guint64 fence_val = 0;
guint num_fences_to_wait = 0;
ID3D12Fence *fences_to_wait[] = { fence_to_wait.Get () };
guint64 fence_values_to_wait[] = { fence_val_to_wait };
if (fence_to_wait)
num_fences_to_wait++;
gst_d3d12_device_copy_texture_region (self->device, copy_args.size (), gst_d3d12_device_copy_texture_region (self->device, copy_args.size (),
copy_args.data (), nullptr, fence_to_wait.Get (), fence_val_to_wait, copy_args.data (), nullptr, num_fences_to_wait, fences_to_wait,
D3D12_COMMAND_LIST_TYPE_DIRECT, &fence_val); fence_values_to_wait, D3D12_COMMAND_LIST_TYPE_DIRECT, &fence_val);
gst_d3d12_buffer_after_write (upload, fence_val); gst_d3d12_buffer_after_write (upload, fence_val);
} else { } else {
GstVideoFrame src_frame, dst_frame; GstVideoFrame src_frame, dst_frame;

View file

@ -515,8 +515,8 @@ gst_d3d12_ipc_client_have_data (GstD3D12IpcClient * self)
guint64 copy_fence_val; guint64 copy_fence_val;
gst_d3d12_device_copy_texture_region (priv->device, copy_args.size (), gst_d3d12_device_copy_texture_region (priv->device, copy_args.size (),
copy_args.data (), nullptr, nullptr, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, copy_args.data (), nullptr, 0, nullptr, nullptr,
&copy_fence_val); D3D12_COMMAND_LIST_TYPE_DIRECT, &copy_fence_val);
auto data = new GstD3D12IpcReleaseData (); auto data = new GstD3D12IpcReleaseData ();
data->self = (GstD3D12IpcClient *) gst_object_ref (self); data->self = (GstD3D12IpcClient *) gst_object_ref (self);

View file

@ -372,7 +372,7 @@ gst_dwrite_d3d12_render_draw_layout (GstDWriteRender * render,
gst_d3d12_fence_data_add_notify_com (fence_data, wrapped_clone.Detach ()); gst_d3d12_fence_data_add_notify_com (fence_data, wrapped_clone.Detach ());
gst_d3d12_device_copy_texture_region (priv->device, gst_d3d12_device_copy_texture_region (priv->device,
1, &args, fence_data, nullptr, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, 1, &args, fence_data, 0, nullptr, nullptr, D3D12_COMMAND_LIST_TYPE_DIRECT,
&priv->fence_val); &priv->fence_val);
priv->scheduled.push (priv->fence_val); priv->scheduled.push (priv->fence_val);