From 6942868bda04d0d11baf91dbb360713b04924a88 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Tue, 18 Jun 2024 22:04:23 +0900 Subject: [PATCH] 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: --- .../gst/d3d12/gstd3d12commandqueue.cpp | 35 +++++++++++-------- .../gst-libs/gst/d3d12/gstd3d12commandqueue.h | 13 +++---- .../gst/d3d12/gstd3d12device-private.h | 5 +-- .../gst-libs/gst/d3d12/gstd3d12device.cpp | 10 +++--- .../gst-libs/gst/d3d12/gstd3d12frame.cpp | 5 +-- .../gst-libs/gst/d3d12/gstd3d12memory.cpp | 29 ++++++++++----- .../sys/d3d12/gstd3d12decoder.cpp | 4 +-- .../sys/d3d12/gstd3d12encoder.cpp | 10 ++++-- .../sys/d3d12/gstd3d12ipcclient.cpp | 4 +-- .../sys/dwrite/gstdwriterender_d3d12.cpp | 2 +- 10 files changed, 74 insertions(+), 43 deletions(-) diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12commandqueue.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12commandqueue.cpp index c05f60acbe..3cf40add70 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12commandqueue.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12commandqueue.cpp @@ -262,7 +262,7 @@ gst_d3d12_command_queue_execute_command_lists_unlocked (GstD3D12CommandQueue * * gst_d3d12_command_queue_execute_command_lists: * @queue: a #GstD3D12CommandQueue * @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 * * 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 - * @fence_to_wait: (allow-none): a ID3D11Fence - * @fence_value_to_wait: fence value to wait + * @num_fences_to_wait: the number of fences 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 - * @command_lists: array of ID3D12CommandList + * @command_lists: (allow-none): array of ID3D12CommandList * @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 * * Since: 1.26 */ HRESULT -gst_d3d12_command_queue_execute_wait_and_command_lists (GstD3D12CommandQueue * - queue, ID3D12Fence * fence_to_wait, guint64 fence_value_to_wait, - guint num_command_lists, ID3D12CommandList ** command_lists, - guint64 * fence_value) +gst_d3d12_command_queue_execute_command_lists_full (GstD3D12CommandQueue * + queue, guint num_fences_to_wait, ID3D12Fence ** fences_to_wait, + const guint64 * fence_values_to_wait, guint num_command_lists, + ID3D12CommandList ** command_lists, guint64 * fence_value) { 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; std::lock_guard < std::mutex > lk (priv->execute_lock); - if (fence_to_wait) { - auto hr = priv->cq->Wait (fence_to_wait, fence_value_to_wait); - if (FAILED (hr)) - return hr; + for (guint i = 0; i < num_fences_to_wait; i++) { + auto fence = fences_to_wait[i]; + auto val = fence_values_to_wait[i]; + 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, diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12commandqueue.h b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12commandqueue.h index 2f9e3a4d60..ac351b9fe0 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12commandqueue.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12commandqueue.h @@ -86,12 +86,13 @@ HRESULT gst_d3d12_command_queue_execute_command_lists (GstD3D12Co guint64 * fence_value); GST_D3D12_API -HRESULT gst_d3d12_command_queue_execute_wait_and_command_lists (GstD3D12CommandQueue * queue, - ID3D12Fence * fence_to_wait, - guint64 fence_value_to_wait, - guint num_command_lists, - ID3D12CommandList ** command_lists, - guint64 * fence_value); +HRESULT gst_d3d12_command_queue_execute_command_lists_full (GstD3D12CommandQueue * queue, + guint num_fences_to_wait, + ID3D12Fence ** fences_to_wait, + const guint64 * fence_values_to_wait, + guint num_command_lists, + ID3D12CommandList ** command_lists, + guint64 * fence_value); GST_D3D12_API HRESULT gst_d3d12_command_queue_execute_wait (GstD3D12CommandQueue * queue, diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device-private.h b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device-private.h index 651b2c4b9a..262398ea15 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device-private.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device-private.h @@ -48,8 +48,9 @@ gboolean gst_d3d12_device_copy_texture_region (GstD3D12Device * device, guint num_args, const GstD3D12CopyTextureRegionArgs * args, GstD3D12FenceData * fence_data, - ID3D12Fence * fence_to_wait, - guint64 fence_value_to_wait, + guint num_fences_to_wait, + ID3D12Fence ** fences_to_wait, + const guint64 * fence_values_to_wait, D3D12_COMMAND_LIST_TYPE command_type, guint64 * fence_value); diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device.cpp index bc83689fe1..67f917ea9f 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device.cpp @@ -1504,8 +1504,8 @@ gst_d3d12_device_fence_wait (GstD3D12Device * device, gboolean gst_d3d12_device_copy_texture_region (GstD3D12Device * device, guint num_args, const GstD3D12CopyTextureRegionArgs * args, - GstD3D12FenceData * fence_data, - ID3D12Fence * fence_to_wait, guint64 fence_value_to_wait, + GstD3D12FenceData * fence_data, guint num_fences_to_wait, + ID3D12Fence ** fences_to_wait, const guint64 * fence_values_to_wait, D3D12_COMMAND_LIST_TYPE command_type, guint64 * fence_value) { 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 () }; - 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); /* We can release command list since command list pool will hold it */ diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12frame.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12frame.cpp index 6a8fc06bd9..739f6dfe9c 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12frame.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12frame.cpp @@ -359,7 +359,7 @@ gst_d3d12_frame_copy (GstD3D12Frame * dest, const GstD3D12Frame * src, return gst_d3d12_device_copy_texture_region (dest->device, 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); 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); } /** diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12memory.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12memory.cpp index c5d4d51880..0407fb7124 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12memory.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12memory.cpp @@ -488,12 +488,14 @@ gst_d3d12_memory_download (GstD3D12Memory * dmem) auto cq = gst_d3d12_device_get_command_queue (dmem->device, 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; /* Use async copy queue when downloading */ 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)) { GST_ERROR_OBJECT (dmem->device, "Couldn't download texture to staging"); return FALSE; @@ -529,9 +531,15 @@ gst_d3d12_memory_upload (GstD3D12Memory * dmem) 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 (), - copy_args.data (), nullptr, priv->external_fence.Get (), - priv->external_fence_val, D3D12_COMMAND_LIST_TYPE_DIRECT, + copy_args.data (), nullptr, num_fences_to_wait, fences_to_wait, + fence_values_to_wait, D3D12_COMMAND_LIST_TYPE_DIRECT, &dmem->fence_value)) { GST_ERROR_OBJECT (dmem->device, "Couldn't upload texture"); return FALSE; @@ -1177,11 +1185,11 @@ gst_d3d12_memory_copy (GstMemory * mem, gssize offset, gssize size) gst_memory_unmap (mem, &info); 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); 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; @@ -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_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, - copy_args.size (), copy_args.data (), fence_data, fence_to_wait.Get (), - fence_value_to_wait, D3D12_COMMAND_LIST_TYPE_DIRECT, + copy_args.size (), copy_args.data (), fence_data, num_fences_to_wait, + fences_to_wait, fence_value_to_wait, D3D12_COMMAND_LIST_TYPE_DIRECT, &dst_dmem->fence_value); GST_MINI_OBJECT_FLAG_SET (dst, GST_D3D12_MEMORY_TRANSFER_NEED_DOWNLOAD); diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12decoder.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12decoder.cpp index 7244e75a82..9727003c65 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12decoder.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12decoder.cpp @@ -1539,8 +1539,8 @@ gst_d3d12_decoder_process_output (GstD3D12Decoder * self, } gst_d3d12_device_copy_texture_region (self->device, copy_args.size (), - copy_args.data (), fence_data, nullptr, decoder_pic->fence_val, - queue_type, ©_fence_val); + copy_args.data (), fence_data, 0, nullptr, nullptr, queue_type, + ©_fence_val); if (!out_resource) { guint8 *map_data; diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12encoder.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12encoder.cpp index 65e38ab9d9..d126eac2ba 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12encoder.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12encoder.cpp @@ -776,9 +776,15 @@ gst_d3d12_encoder_upload_frame (GstD3D12Encoder * self, GstBuffer * buffer) } 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 (), - copy_args.data (), nullptr, fence_to_wait.Get (), fence_val_to_wait, - D3D12_COMMAND_LIST_TYPE_DIRECT, &fence_val); + copy_args.data (), nullptr, num_fences_to_wait, fences_to_wait, + fence_values_to_wait, D3D12_COMMAND_LIST_TYPE_DIRECT, &fence_val); gst_d3d12_buffer_after_write (upload, fence_val); } else { GstVideoFrame src_frame, dst_frame; diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12ipcclient.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12ipcclient.cpp index 34010abc84..65472587a6 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12ipcclient.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12ipcclient.cpp @@ -515,8 +515,8 @@ gst_d3d12_ipc_client_have_data (GstD3D12IpcClient * self) guint64 copy_fence_val; gst_d3d12_device_copy_texture_region (priv->device, copy_args.size (), - copy_args.data (), nullptr, nullptr, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, - ©_fence_val); + copy_args.data (), nullptr, 0, nullptr, nullptr, + D3D12_COMMAND_LIST_TYPE_DIRECT, ©_fence_val); auto data = new GstD3D12IpcReleaseData (); data->self = (GstD3D12IpcClient *) gst_object_ref (self); diff --git a/subprojects/gst-plugins-bad/sys/dwrite/gstdwriterender_d3d12.cpp b/subprojects/gst-plugins-bad/sys/dwrite/gstdwriterender_d3d12.cpp index 80c5f064cf..911254be13 100644 --- a/subprojects/gst-plugins-bad/sys/dwrite/gstdwriterender_d3d12.cpp +++ b/subprojects/gst-plugins-bad/sys/dwrite/gstdwriterender_d3d12.cpp @@ -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_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->scheduled.push (priv->fence_val);