d3d12memory: Hide fence value from header

Instead of exposing fence value to wait in header, user setter/getter
methods.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7057>
This commit is contained in:
Seungha Yang 2024-06-19 01:00:28 +09:00 committed by GStreamer Marge Bot
parent 49c4247cb3
commit f6eb3a01c0
22 changed files with 170 additions and 162 deletions

View file

@ -2148,8 +2148,8 @@ gst_d3d12_converter_check_needs_upload (GstD3D12Converter * self,
* @in_buf: a #GstBuffer
* @out_buf: a #GstBuffer
* @fence_data: a #GstD3D12FenceData
* @cl: a ID3D12GraphicsCommandList
* @queue: (allow-none): a ID3D12CommandQueue
* @command_list: a ID3D12GraphicsCommandList
* @queue: (allow-none): a #GstD3D12CommandQueue
*
* Records command list for conversion operation. converter will attach
* conversion command associated resources such as command allocator
@ -2166,13 +2166,15 @@ gst_d3d12_converter_check_needs_upload (GstD3D12Converter * self,
gboolean
gst_d3d12_converter_convert_buffer (GstD3D12Converter * converter,
GstBuffer * in_buf, GstBuffer * out_buf, GstD3D12FenceData * fence_data,
ID3D12GraphicsCommandList * cl, ID3D12CommandQueue * queue)
ID3D12GraphicsCommandList * command_list, GstD3D12CommandQueue * queue)
{
g_return_val_if_fail (GST_IS_D3D12_CONVERTER (converter), FALSE);
g_return_val_if_fail (GST_IS_BUFFER (in_buf), FALSE);
g_return_val_if_fail (GST_IS_BUFFER (out_buf), FALSE);
g_return_val_if_fail (fence_data, FALSE);
g_return_val_if_fail (cl, FALSE);
g_return_val_if_fail (command_list, FALSE);
g_return_val_if_fail (queue == nullptr || GST_IS_D3D12_COMMAND_QUEUE (queue),
FALSE);
GstD3D12Frame in_frame;
GstD3D12Frame out_frame;
@ -2206,7 +2208,7 @@ gst_d3d12_converter_convert_buffer (GstD3D12Converter * converter,
}
auto ret = gst_d3d12_converter_execute (converter,
&in_frame, &out_frame, fence_data, cl);
&in_frame, &out_frame, fence_data, command_list);
if (ret && queue) {
gst_d3d12_frame_fence_gpu_wait (&in_frame, queue);

View file

@ -165,7 +165,7 @@ gboolean gst_d3d12_converter_convert_buffer (GstD3D12Converter * conv
GstBuffer * out_buf,
GstD3D12FenceData * fence_data,
ID3D12GraphicsCommandList * command_list,
ID3D12CommandQueue * queue);
GstD3D12CommandQueue * queue);
GST_D3D12_API
gboolean gst_d3d12_converter_update_blend_state (GstD3D12Converter * converter,

View file

@ -1814,6 +1814,7 @@ gst_d3d12_device_clear_yuv_texture (GstD3D12Device * device, GstMemory * mem)
ID3D12CommandList *cmd_list[] = { cl.Get () };
guint64 fence_val = 0;
auto fence = gst_d3d12_command_queue_get_fence_handle (priv->direct_queue);
hr = gst_d3d12_command_queue_execute_command_lists (priv->direct_queue,
1, cmd_list, &fence_val);
auto ret = gst_d3d12_result (hr, device);
@ -1822,7 +1823,7 @@ gst_d3d12_device_clear_yuv_texture (GstD3D12Device * device, GstMemory * mem)
if (ret) {
gst_d3d12_command_queue_set_notify (priv->direct_queue, fence_val,
gst_ca, (GDestroyNotify) gst_d3d12_command_allocator_unref);
dmem->fence_value = fence_val;
gst_d3d12_memory_set_fence (dmem, fence, fence_val, FALSE);
} else {
gst_d3d12_command_allocator_unref (gst_ca);
}

View file

@ -223,7 +223,7 @@ gst_d3d12_frame_map (GstD3D12Frame * frame, const GstVideoInfo * info,
rtv_handle.Offset (rtv_inc_size);
}
gst_d3d12_memory_get_external_fence (dmem, &frame->fence[plane_idx].fence,
gst_d3d12_memory_get_fence (dmem, &frame->fence[plane_idx].fence,
&frame->fence[plane_idx].fence_value);
plane_idx++;
@ -351,15 +351,26 @@ gst_d3d12_frame_copy (GstD3D12Frame * dest, const GstD3D12Frame * src,
gst_d3d12_fence_data_push (fence_data,
FENCE_NOTIFY_MINI_OBJECT (gst_buffer_ref (src->buffer)));
auto cq = gst_d3d12_device_get_command_queue (src->device,
D3D12_COMMAND_LIST_TYPE_DIRECT);
auto cq_handle = gst_d3d12_command_queue_get_handle (cq);
gst_d3d12_frame_fence_gpu_wait (src, cq_handle);
gst_d3d12_frame_fence_gpu_wait (dest, cq_handle);
std::vector < ID3D12Fence * >fences_to_wait;
std::vector < guint64 > fence_values_to_wait;
for (guint i = 0; i < G_N_ELEMENTS (dest->fence); i++) {
if (dest->fence[i].fence) {
fences_to_wait.push_back (dest->fence[i].fence);
fence_values_to_wait.push_back (dest->fence[i].fence_value);
}
if (src->fence[i].fence) {
fences_to_wait.push_back (src->fence[i].fence);
fence_values_to_wait.push_back (src->fence[i].fence_value);
}
}
return gst_d3d12_device_copy_texture_region (dest->device,
GST_VIDEO_INFO_N_PLANES (&dest->info), args, fence_data,
0, nullptr, nullptr, D3D12_COMMAND_LIST_TYPE_DIRECT, fence_value);
(guint) fences_to_wait.size (), fences_to_wait.data (),
fence_values_to_wait.data (), D3D12_COMMAND_LIST_TYPE_DIRECT,
fence_value);
}
/**
@ -421,9 +432,9 @@ gst_d3d12_frame_copy_plane (GstD3D12Frame * dest, const GstD3D12Frame * src,
/**
* gst_d3d12_frame_fence_gpu_wait:
* @frame: a #GstD3D12Frame
* @queue: a ID3D12CommandQueue
* @queue: a GstD3D12CommandQueue
*
* Executes ID3D12CommandQueue::Wait() if external fence exists
* Executes ID3D12CommandQueue::Wait() if @frame has different fence object
*
* Returns: %TRUE on success.
*
@ -431,16 +442,18 @@ gst_d3d12_frame_copy_plane (GstD3D12Frame * dest, const GstD3D12Frame * src,
*/
gboolean
gst_d3d12_frame_fence_gpu_wait (const GstD3D12Frame * frame,
ID3D12CommandQueue * queue)
GstD3D12CommandQueue * queue)
{
g_return_val_if_fail (frame, FALSE);
g_return_val_if_fail (GST_IS_D3D12_DEVICE (frame->device), FALSE);
g_return_val_if_fail (queue, FALSE);
g_return_val_if_fail (GST_IS_D3D12_COMMAND_QUEUE (queue), FALSE);
ID3D12Fence *last_fence = nullptr;
guint64 last_fence_val = 0;
auto fence = gst_d3d12_command_queue_get_fence_handle (queue);
for (guint i = 0; i < G_N_ELEMENTS (frame->fence); i++) {
if (frame->fence[i].fence) {
if (frame->fence[i].fence && frame->fence[i].fence != fence) {
if (frame->fence[i].fence == last_fence &&
frame->fence[i].fence_value <= last_fence_val) {
continue;
@ -448,8 +461,8 @@ gst_d3d12_frame_fence_gpu_wait (const GstD3D12Frame * frame,
last_fence = frame->fence[i].fence;
last_fence_val = frame->fence[i].fence_value;
auto hr = queue->Wait (frame->fence[i].fence,
frame->fence[i].fence_value);
auto hr = gst_d3d12_command_queue_execute_wait (queue,
frame->fence[i].fence, frame->fence[i].fence_value);
if (!gst_d3d12_result (hr, frame->device))
return FALSE;
}

View file

@ -112,7 +112,7 @@ gboolean gst_d3d12_frame_copy_plane (GstD3D12Frame * dest,
GST_D3D12_API
gboolean gst_d3d12_frame_fence_gpu_wait (const GstD3D12Frame * frame,
ID3D12CommandQueue * queue);
GstD3D12CommandQueue * queue);
GST_D3D12_API
gboolean gst_d3d12_frame_fence_cpu_wait (const GstD3D12Frame * frame);

View file

@ -372,8 +372,8 @@ struct _GstD3D12MemoryPrivate
gpointer user_data = nullptr;
GDestroyNotify notify = nullptr;
ComPtr<ID3D12Fence> external_fence;
UINT64 external_fence_val = 0;
ComPtr<ID3D12Fence> fence;
UINT64 fence_val = 0;
};
/* *INDENT-ON* */
@ -415,45 +415,27 @@ gst_d3d12_memory_ensure_staging_resource (GstD3D12Memory * dmem)
}
static void
gst_d3d12_memory_set_external_fence_unlocked (GstD3D12Memory * dmem,
ID3D12Fence * fence, guint64 fence_val)
gst_d3d12_memory_set_fence_unlocked (GstD3D12Memory * dmem,
ID3D12Fence * fence, guint64 fence_val, gboolean wait)
{
auto priv = dmem->priv;
HRESULT hr;
if (priv->external_fence) {
auto completed = priv->external_fence->GetCompletedValue ();
if (completed < priv->external_fence_val) {
hr = priv->external_fence->SetEventOnCompletion (priv->external_fence_val,
if (priv->fence && priv->fence.Get () != fence && wait) {
auto completed = priv->fence->GetCompletedValue ();
if (completed < priv->fence_val) {
hr = priv->fence->SetEventOnCompletion (priv->fence_val,
priv->event_handle);
if (SUCCEEDED (hr))
WaitForSingleObjectEx (priv->event_handle, INFINITE, FALSE);
}
priv->external_fence = nullptr;
priv->external_fence_val = 0;
}
if (fence) {
priv->external_fence = fence;
priv->external_fence_val = fence_val;
}
}
static void
gst_d3d12_memory_wait_gpu (GstD3D12Memory * dmem,
D3D12_COMMAND_LIST_TYPE command_type, guint64 fence_value)
{
auto priv = dmem->priv;
gst_d3d12_memory_set_external_fence_unlocked (dmem, nullptr, 0);
auto completed = gst_d3d12_device_get_completed_value (dmem->device,
command_type);
if (completed < fence_value) {
gst_d3d12_device_fence_wait (dmem->device, command_type,
fence_value, priv->event_handle);
}
priv->fence = fence;
if (fence)
priv->fence_val = fence_val;
else
priv->fence_val = 0;
}
static gboolean
@ -479,28 +461,26 @@ gst_d3d12_memory_download (GstD3D12Memory * dmem)
copy_args.push_back (args);
}
if (priv->external_fence) {
auto cq = gst_d3d12_device_get_command_queue (dmem->device,
D3D12_COMMAND_LIST_TYPE_COPY);
gst_d3d12_command_queue_execute_wait (cq, priv->external_fence.Get (),
priv->external_fence_val);
}
auto fence = gst_d3d12_device_get_fence_handle (dmem->device,
D3D12_COMMAND_LIST_TYPE_DIRECT);
ID3D12Fence *direct_fence[] = { fence };
guint64 fence_value_to_wait[] = { dmem->fence_value };
guint64 fence_val = 0;
guint num_fences_to_wait = 0;
ID3D12Fence *fences_to_wait[] = { priv->fence.Get () };
guint64 fence_values_to_wait[] = { priv->fence_val };
if (priv->fence)
num_fences_to_wait = 1;
/* Use async copy queue when downloading */
if (!gst_d3d12_device_copy_texture_region (dmem->device, copy_args.size (),
copy_args.data (), nullptr, 1, direct_fence, fence_value_to_wait,
D3D12_COMMAND_LIST_TYPE_COPY, &fence_val)) {
copy_args.data (), nullptr, num_fences_to_wait, fences_to_wait,
fence_values_to_wait, D3D12_COMMAND_LIST_TYPE_COPY, &fence_val)) {
GST_ERROR_OBJECT (dmem->device, "Couldn't download texture to staging");
return FALSE;
}
gst_d3d12_memory_wait_gpu (dmem, D3D12_COMMAND_LIST_TYPE_COPY, fence_val);
gst_d3d12_device_fence_wait (dmem->device, D3D12_COMMAND_LIST_TYPE_COPY,
fence_val, priv->event_handle);
priv->fence = nullptr;
priv->fence_val = 0;
GST_MEMORY_FLAG_UNSET (dmem, GST_D3D12_MEMORY_TRANSFER_NEED_DOWNLOAD);
@ -531,19 +511,22 @@ gst_d3d12_memory_upload (GstD3D12Memory * dmem)
}
guint num_fences_to_wait = 0;
ID3D12Fence *fences_to_wait[] = { priv->external_fence.Get () };
guint64 fence_values_to_wait[] = { priv->external_fence_val };
ID3D12Fence *fences_to_wait[] = { priv->fence.Get () };
guint64 fence_values_to_wait[] = { priv->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, num_fences_to_wait, fences_to_wait,
fence_values_to_wait, D3D12_COMMAND_LIST_TYPE_DIRECT,
&dmem->fence_value)) {
&priv->fence_val)) {
GST_ERROR_OBJECT (dmem->device, "Couldn't upload texture");
return FALSE;
}
priv->fence = gst_d3d12_device_get_fence_handle (dmem->device,
D3D12_COMMAND_LIST_TYPE_DIRECT);
GST_MEMORY_FLAG_UNSET (dmem, GST_D3D12_MEMORY_TRANSFER_NEED_UPLOAD);
return TRUE;
@ -648,9 +631,11 @@ gst_d3d12_memory_sync (GstD3D12Memory * mem)
{
g_return_val_if_fail (gst_is_d3d12_memory (GST_MEMORY_CAST (mem)), FALSE);
auto priv = mem->priv;
std::lock_guard < std::mutex > lk (priv->lock);
gst_d3d12_memory_upload (mem);
gst_d3d12_memory_wait_gpu (mem,
D3D12_COMMAND_LIST_TYPE_DIRECT, mem->fence_value);
gst_d3d12_memory_set_fence_unlocked (mem, nullptr, 0, TRUE);
return TRUE;
}
@ -989,49 +974,61 @@ gst_d3d12_memory_get_token_data (GstD3D12Memory * mem, gint64 token)
}
/**
* gst_d3d12_memory_set_external_fence:
* gst_d3d12_memory_set_fence:
* @mem: a #GstD3D12Memory
* @fence: (allow-none): a ID3D12Fence
* @fence_val: fence value
* @fence_value: fence value
* @wait: waits for previously configured fence if any
*
* Sets external fence handle to @mem. Later memory map operation will wait
* for @fence if needed
* Replace fence object of @mem with new @fence.
* This method will block calling thread for synchronization
* if @wait is %TRUE and configured fence is different from new @fence
*
* Since: 1.26
*/
void
gst_d3d12_memory_set_external_fence (GstD3D12Memory * mem, ID3D12Fence * fence,
guint64 fence_val)
gst_d3d12_memory_set_fence (GstD3D12Memory * mem, ID3D12Fence * fence,
guint64 fence_value, gboolean wait)
{
g_return_if_fail (gst_is_d3d12_memory (GST_MEMORY_CAST (mem)));
auto priv = mem->priv;
std::lock_guard < std::mutex > lk (priv->lock);
gst_d3d12_memory_set_external_fence_unlocked (mem, fence, fence_val);
gst_d3d12_memory_set_fence_unlocked (mem, fence, fence_value, wait);
}
/**
* gst_d3d12_memory_get_external_fence:
* gst_d3d12_memory_get_fence:
* @mem: a #GstD3D12Memory
* @fence: (out) (transfer full) (nullable): a ID3D12Fence
* @fence_val: (out): fence value
* @fence: (out) (transfer full) (allow-none): a ID3D12Fence
* @fence_value: (out) (allow-none): fence value
*
* Gets configured external fence and fence value
* Gets configured fence and fence value. Valid operations against returned
* fence object are ID3D12Fence::GetCompletedValue() and
* ID3D12Fence::SetEventOnCompletion(). Caller should not try to update
* completed value via ID3D12Fence::Signal() since the fence is likely
* owned by external component and shared only for read-only operations.
*
* Returns: %TRUE if external fence was configured in @mem
* Returns: %TRUE if @mem has configured fence object
*
* Since: 1.26
*/
gboolean
gst_d3d12_memory_get_external_fence (GstD3D12Memory * mem, ID3D12Fence ** fence,
guint64 * fence_val)
gst_d3d12_memory_get_fence (GstD3D12Memory * mem, ID3D12Fence ** fence,
guint64 * fence_value)
{
auto priv = mem->priv;
std::lock_guard < std::mutex > lk (priv->lock);
if (priv->external_fence) {
*fence = priv->external_fence.Get ();
(*fence)->AddRef ();
*fence_val = priv->external_fence_val;
if (priv->fence) {
if (fence) {
*fence = priv->fence.Get ();
(*fence)->AddRef ();
}
if (fence_value)
*fence_value = priv->fence_val;
return TRUE;
}
@ -1187,8 +1184,8 @@ gst_d3d12_memory_copy (GstMemory * mem, gssize offset, gssize size)
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[0] = mem_priv->external_fence_val;
fence_to_wait = mem_priv->fence;
fence_value_to_wait[0] = mem_priv->fence_val;
}
GstD3D12FenceData *fence_data;
@ -1204,7 +1201,9 @@ gst_d3d12_memory_copy (GstMemory * mem, gssize offset, gssize size)
gst_d3d12_device_copy_texture_region (dmem->device,
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);
&dst_priv->fence_val);
dst_priv->fence = gst_d3d12_device_get_fence_handle (dmem->device,
D3D12_COMMAND_LIST_TYPE_DIRECT);
GST_MINI_OBJECT_FLAG_SET (dst, GST_D3D12_MEMORY_TRANSFER_NEED_DOWNLOAD);
@ -1245,8 +1244,7 @@ gst_d3d12_allocator_free (GstAllocator * allocator, GstMemory * mem)
GST_LOG_OBJECT (allocator, "Free memory %p", mem);
gst_d3d12_memory_wait_gpu (dmem, D3D12_COMMAND_LIST_TYPE_DIRECT,
dmem->fence_value);
gst_d3d12_memory_set_fence_unlocked (dmem, nullptr, 0, TRUE);
if (dmem->priv->notify)
dmem->priv->notify (dmem->priv->user_data);

View file

@ -162,7 +162,6 @@ struct _GstD3D12Memory
GstMemory mem;
GstD3D12Device *device;
guint64 fence_value;
/*< private >*/
GstD3D12MemoryPrivate *priv;
@ -218,14 +217,15 @@ gpointer gst_d3d12_memory_get_token_data (GstD3D12Memory * mem,
gint64 token);
GST_D3D12_API
void gst_d3d12_memory_set_external_fence (GstD3D12Memory * mem,
ID3D12Fence * fence,
guint64 fence_val);
void gst_d3d12_memory_set_fence (GstD3D12Memory * mem,
ID3D12Fence * fence,
guint64 fence_value,
gboolean wait);
GST_D3D12_API
gboolean gst_d3d12_memory_get_external_fence (GstD3D12Memory * mem,
ID3D12Fence ** fence,
guint64 * fence_val);
gboolean gst_d3d12_memory_get_fence (GstD3D12Memory * mem,
ID3D12Fence ** fence,
guint64 * fence_value);
GST_D3D12_API
ID3D11Texture2D * gst_d3d12_memory_get_d3d11_texture (GstD3D12Memory * mem,

View file

@ -631,10 +631,13 @@ gst_d3d12_buffer_copy_into (GstBuffer * dest, GstBuffer * src,
gst_d3d12_frame_unmap (&dest_frame);
gst_d3d12_frame_unmap (&src_frame);
auto fence = gst_d3d12_device_get_fence_handle (dest_device,
D3D12_COMMAND_LIST_TYPE_DIRECT);
if (ret) {
for (guint i = 0; i < num_mem; i++) {
auto dmem = (GstD3D12Memory *) gst_buffer_peek_memory (dest, i);
dmem->fence_value = fence_val;
gst_d3d12_memory_set_fence (dmem, fence, fence_val, FALSE);
}
}

View file

@ -1158,10 +1158,9 @@ gst_d3d12_compositor_preprare_func (GstVideoAggregatorPad * pad,
auto cq = gst_d3d12_device_get_command_queue (priv->ctx->device,
D3D12_COMMAND_LIST_TYPE_DIRECT);
auto cq_handle = gst_d3d12_command_queue_get_handle (cq);
if (!gst_d3d12_converter_convert_buffer (priv->ctx->conv,
buffer, self->priv->generated_output_buf, fence_data,
priv->ctx->cl.Get (), cq_handle)) {
priv->ctx->cl.Get (), cq)) {
GST_ERROR_OBJECT (self, "Couldn't build command list");
gst_d3d12_fence_data_unref (fence_data);
return FALSE;
@ -2329,7 +2328,9 @@ gst_d3d12_compositor_draw_background (GstD3D12Compositor * self)
return FALSE;
}
gst_d3d12_buffer_after_write (priv->generated_output_buf,
auto fence = gst_d3d12_device_get_fence_handle (self->device,
D3D12_COMMAND_LIST_TYPE_DIRECT);
gst_d3d12_buffer_after_write (priv->generated_output_buf, fence,
bg_render->fence_val);
if (bg_render->vertex_index_upload) {
@ -2386,6 +2387,8 @@ gst_d3d12_compositor_aggregate_frames (GstVideoAggregator * vagg,
}
guint64 fence_val = priv->bg_render->fence_val;
auto fence = gst_d3d12_device_get_fence_handle (self->device,
D3D12_COMMAND_LIST_TYPE_DIRECT);
GST_OBJECT_LOCK (self);
for (iter = GST_ELEMENT (vagg)->sinkpads; iter; iter = g_list_next (iter)) {
auto pad = GST_VIDEO_AGGREGATOR_PAD (iter->data);
@ -2424,7 +2427,7 @@ gst_d3d12_compositor_aggregate_frames (GstVideoAggregator * vagg,
}
fence_val = pad_priv->ctx->fence_val;
gst_d3d12_buffer_after_write (priv->generated_output_buf, fence_val);
gst_d3d12_buffer_after_write (priv->generated_output_buf, fence, fence_val);
}
GST_OBJECT_UNLOCK (self);

View file

@ -2012,10 +2012,9 @@ gst_d3d12_convert_transform (GstBaseTransform * trans, GstBuffer * inbuf,
auto cq = gst_d3d12_device_get_command_queue (priv->ctx->device,
D3D12_COMMAND_LIST_TYPE_DIRECT);
auto cq_handle = gst_d3d12_command_queue_get_handle (cq);
if (!gst_d3d12_converter_convert_buffer (priv->ctx->conv,
inbuf, outbuf, fence_data, priv->ctx->cl.Get (), cq_handle)) {
inbuf, outbuf, fence_data, priv->ctx->cl.Get (), cq)) {
GST_ERROR_OBJECT (self, "Couldn't build command list");
gst_d3d12_fence_data_unref (fence_data);
return GST_FLOW_ERROR;
@ -2038,7 +2037,9 @@ gst_d3d12_convert_transform (GstBaseTransform * trans, GstBuffer * inbuf,
return GST_FLOW_ERROR;
}
gst_d3d12_buffer_after_write (outbuf, priv->ctx->fence_val);
gst_d3d12_buffer_after_write (outbuf,
gst_d3d12_device_get_fence_handle (priv->ctx->device,
D3D12_COMMAND_LIST_TYPE_DIRECT), priv->ctx->fence_val);
gst_d3d12_device_set_fence_notify (priv->ctx->device,
D3D12_COMMAND_LIST_TYPE_DIRECT, priv->ctx->fence_val,

View file

@ -1541,6 +1541,7 @@ gst_d3d12_decoder_process_output (GstD3D12Decoder * self,
gst_d3d12_device_copy_texture_region (self->device, copy_args.size (),
copy_args.data (), fence_data, 0, nullptr, nullptr, queue_type,
&copy_fence_val);
auto fence = gst_d3d12_device_get_fence_handle (self->device, queue_type);
if (!out_resource) {
guint8 *map_data;
@ -1574,7 +1575,8 @@ gst_d3d12_decoder_process_output (GstD3D12Decoder * self,
priv->session->staging->Unmap (0, nullptr);
gst_video_frame_unmap (&vframe);
} else {
gst_d3d12_buffer_after_write (frame->output_buffer, copy_fence_val);
gst_d3d12_buffer_after_write (frame->output_buffer,
fence, copy_fence_val);
}
}

View file

@ -1390,10 +1390,8 @@ gst_d3d12_dxgi_capture_draw_mouse (GstD3D12DxgiCapture * self,
auto cq = gst_d3d12_device_get_command_queue (priv->device,
D3D12_COMMAND_LIST_TYPE_DIRECT);
auto cq_handle = gst_d3d12_command_queue_get_handle (cq);
if (!gst_d3d12_converter_convert_buffer (priv->mouse_blend,
priv->mouse_buf, buffer, fence_data, cl.Get (), cq_handle)) {
priv->mouse_buf, buffer, fence_data, cl.Get (), cq)) {
GST_ERROR_OBJECT (self, "Couldn't build mouse blend command");
gst_d3d12_fence_data_unref (fence_data);
return FALSE;
@ -1432,7 +1430,8 @@ gst_d3d12_dxgi_capture_draw_mouse (GstD3D12DxgiCapture * self,
gst_d3d12_command_queue_set_notify (cq, fence_val, fence_data,
(GDestroyNotify) gst_d3d12_fence_data_unref);
gst_d3d12_buffer_after_write (buffer, fence_val);
gst_d3d12_buffer_after_write (buffer,
gst_d3d12_command_queue_get_fence_handle (cq), fence_val);
return TRUE;
}
@ -1488,8 +1487,8 @@ gst_d3d12_dxgi_capture_do_capture (GstD3D12DxgiCapture * capture,
return ret;
}
gst_d3d12_memory_set_external_fence (dmem, priv->shared_fence.Get (),
priv->fence_val);
gst_d3d12_memory_set_fence (dmem, priv->shared_fence.Get (),
priv->fence_val, FALSE);
GST_MINI_OBJECT_FLAG_SET (dmem, GST_D3D12_MEMORY_TRANSFER_NEED_DOWNLOAD);
GST_MINI_OBJECT_FLAG_UNSET (dmem, GST_D3D12_MEMORY_TRANSFER_NEED_UPLOAD);

View file

@ -739,8 +739,7 @@ gst_d3d12_encoder_upload_frame (GstD3D12Encoder * self, GstBuffer * buffer)
ComPtr < ID3D12Fence > fence_to_wait;
guint64 fence_val_to_wait = 0;
gst_d3d12_memory_get_external_fence (dmem,
&fence_to_wait, &fence_val_to_wait);
gst_d3d12_memory_get_fence (dmem, &fence_to_wait, &fence_val_to_wait);
dmem = (GstD3D12Memory *) gst_buffer_peek_memory (upload, 0);
auto dst_resource = gst_d3d12_memory_get_resource_handle (dmem);
@ -785,7 +784,9 @@ gst_d3d12_encoder_upload_frame (GstD3D12Encoder * self, GstBuffer * buffer)
gst_d3d12_device_copy_texture_region (self->device, copy_args.size (),
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);
gst_d3d12_buffer_after_write (upload,
gst_d3d12_device_get_fence_handle (self->device,
D3D12_COMMAND_LIST_TYPE_DIRECT), fence_val);
} else {
GstVideoFrame src_frame, dst_frame;
if (!gst_video_frame_map (&src_frame, info, buffer, GST_MAP_READ)) {
@ -1441,21 +1442,11 @@ gst_d3d12_encoder_handle_frame (GstVideoEncoder * encoder,
ComPtr < ID3D12Fence > fence_to_wait;
guint64 fence_val_to_wait = 0;
if (gst_d3d12_memory_get_external_fence (mem,
&fence_to_wait, &fence_val_to_wait)) {
if (gst_d3d12_memory_get_fence (mem, &fence_to_wait, &fence_val_to_wait)) {
gst_d3d12_command_queue_execute_wait (priv->cmd->queue,
fence_to_wait.Get (), fence_val_to_wait);
}
auto completed = gst_d3d12_device_get_completed_value (self->device,
D3D12_COMMAND_LIST_TYPE_DIRECT);
if (completed < mem->fence_value) {
auto fence = gst_d3d12_device_get_fence_handle (self->device,
D3D12_COMMAND_LIST_TYPE_DIRECT);
gst_d3d12_command_queue_execute_wait (priv->cmd->queue, fence,
mem->fence_value);
}
ID3D12CommandList *cmd_list[] = { cl.Get () };
hr = gst_d3d12_command_queue_execute_command_lists (priv->cmd->queue,
1, cmd_list, &priv->cmd->fence_val);

View file

@ -546,14 +546,8 @@ public:
context_->Signal (shared_fence11_.Get (), fence_val_);
gst_memory_unmap (mem, &map_info);
auto cq = gst_d3d12_device_get_command_queue (device12_,
D3D12_COMMAND_LIST_TYPE_DIRECT);
gst_d3d12_command_queue_execute_wait (cq, shared_fence12_.Get (),
fence_val_);
guint64 fence_val_12;
gst_d3d12_command_queue_execute_command_lists (cq,
0, nullptr, &fence_val_12);
dmem->fence_value = fence_val_12;
gst_d3d12_memory_set_fence (dmem,
shared_fence12_.Get (), fence_val_, FALSE);
*width = crop_w;
*height = crop_h;

View file

@ -525,7 +525,9 @@ gst_d3d12_ipc_client_have_data (GstD3D12IpcClient * self)
gst_d3d12_command_queue_set_notify (queue, copy_fence_val, data,
(GDestroyNotify) gst_d3d12_ipc_client_release_imported_data);
gst_d3d12_buffer_after_write (buffer, copy_fence_val);
gst_d3d12_buffer_after_write (buffer,
gst_d3d12_device_get_fence_handle (priv->device,
D3D12_COMMAND_LIST_TYPE_DIRECT), copy_fence_val);
lk.lock ();
} else {
@ -545,8 +547,8 @@ gst_d3d12_ipc_client_have_data (GstD3D12IpcClient * self)
texture.Get (), 0, data,
(GDestroyNotify) gst_d3d12_ipc_client_release_imported_data);
gst_d3d12_memory_set_external_fence (GST_D3D12_MEMORY_CAST (mem),
priv->server_fence.Get (), fence_val);
gst_d3d12_memory_set_fence (GST_D3D12_MEMORY_CAST (mem),
priv->server_fence.Get (), fence_val, FALSE);
GST_MINI_OBJECT_FLAG_SET (mem, GST_MEMORY_FLAG_READONLY);

View file

@ -796,7 +796,7 @@ gst_d3d12_ipc_server_send_data (GstD3D12IpcServer * server, GstSample * sample,
data->handle = handle;
data->layout = layout;
data->pts = pts;
data->fence_val = dmem->fence_value;
gst_d3d12_memory_get_fence (dmem, nullptr, &data->fence_val);
data->seq_num = priv->seq_num;
priv->seq_num++;

View file

@ -114,14 +114,15 @@ gst_d3d12_msaa_mode_get_type (void)
}
void
gst_d3d12_buffer_after_write (GstBuffer * buffer, guint64 fence_value)
gst_d3d12_buffer_after_write (GstBuffer * buffer, ID3D12Fence * fence,
guint64 fence_value)
{
for (guint i = 0; i < gst_buffer_n_memory (buffer); i++) {
auto mem = gst_buffer_peek_memory (buffer, i);
g_return_if_fail (gst_is_d3d12_memory (mem));
auto dmem = GST_D3D12_MEMORY_CAST (mem);
dmem->fence_value = fence_value;
gst_d3d12_memory_set_fence (dmem, fence, fence_value, FALSE);
GST_MINI_OBJECT_FLAG_SET (dmem, GST_D3D12_MEMORY_TRANSFER_NEED_DOWNLOAD);
GST_MINI_OBJECT_FLAG_UNSET (dmem, GST_D3D12_MEMORY_TRANSFER_NEED_UPLOAD);
}

View file

@ -50,6 +50,7 @@ enum GstD3D12MSAAMode
GType gst_d3d12_msaa_mode_get_type (void);
void gst_d3d12_buffer_after_write (GstBuffer * buffer,
ID3D12Fence * fence,
guint64 fence_value);
gboolean gst_d3d12_need_transform (gfloat rotation_x,

View file

@ -2230,7 +2230,9 @@ gst_d3d12_test_src_create (GstBaseSrc * bsrc, guint64 offset,
return GST_FLOW_ERROR;
}
gst_d3d12_buffer_after_write (convert_buffer, priv->ctx->fence_val);
gst_d3d12_buffer_after_write (convert_buffer,
gst_d3d12_device_get_fence_handle (self->device,
D3D12_COMMAND_LIST_TYPE_DIRECT), priv->ctx->fence_val);
gst_d3d12_device_set_fence_notify (self->device,
D3D12_COMMAND_LIST_TYPE_DIRECT, priv->ctx->fence_val,

View file

@ -566,9 +566,8 @@ gst_d3d12_window_render (GstD3D12Window * self, SwapChainResource * resource,
auto cq = gst_d3d12_device_get_command_queue (device,
D3D12_COMMAND_LIST_TYPE_DIRECT);
auto cq_handle = gst_d3d12_command_queue_get_handle (cq);
if (!gst_d3d12_converter_convert_buffer (resource->conv,
buffer, conv_outbuf, fence_data, cl.Get (), cq_handle)) {
buffer, conv_outbuf, fence_data, cl.Get (), cq)) {
GST_ERROR_OBJECT (self, "Couldn't build convert command");
gst_d3d12_fence_data_unref (fence_data);
return GST_FLOW_ERROR;

View file

@ -378,7 +378,9 @@ gst_dwrite_d3d12_render_draw_layout (GstDWriteRender * render,
&priv->fence_val);
priv->scheduled.push (priv->fence_val);
dmem->fence_value = priv->fence_val;
gst_d3d12_memory_set_fence (dmem,
gst_d3d12_device_get_fence_handle (priv->device,
D3D12_COMMAND_LIST_TYPE_DIRECT), priv->fence_val, FALSE);
GST_MINI_OBJECT_FLAG_SET (dmem, GST_D3D12_MEMORY_TRANSFER_NEED_DOWNLOAD);
GST_MINI_OBJECT_FLAG_UNSET (dmem, GST_D3D12_MEMORY_TRANSFER_NEED_UPLOAD);
@ -458,12 +460,12 @@ gst_dwrite_d3d12_render_blend (GstDWriteRender * render, GstBuffer * layout_buf,
GstBuffer *bgra_buf = nullptr;
auto cq = gst_d3d12_device_get_command_queue (priv->device,
D3D12_COMMAND_LIST_TYPE_DIRECT);
auto cq_handle = gst_d3d12_command_queue_get_handle (cq);
auto fence = gst_d3d12_command_queue_get_fence_handle (cq);
if (priv->direct_blend) {
GST_LOG_OBJECT (self, "Direct blend");
ret = gst_d3d12_converter_convert_buffer (priv->blend_conv,
layout_buf, output, fence_data, priv->cl.Get (), cq_handle);
layout_buf, output, fence_data, priv->cl.Get (), cq);
} else {
GST_LOG_OBJECT (self, "Need conversion for blending");
@ -475,7 +477,7 @@ gst_dwrite_d3d12_render_blend (GstDWriteRender * render, GstBuffer * layout_buf,
if (ret) {
ret = gst_d3d12_converter_convert_buffer (priv->pre_conv,
output, bgra_buf, fence_data, priv->cl.Get (), cq_handle);
output, bgra_buf, fence_data, priv->cl.Get (), cq);
}
if (ret) {
@ -549,7 +551,7 @@ gst_dwrite_d3d12_render_blend (GstDWriteRender * render, GstBuffer * layout_buf,
for (guint i = 0; i < gst_buffer_n_memory (output); i++) {
auto dmem = (GstD3D12Memory *) gst_buffer_peek_memory (output, i);
dmem->fence_value = priv->fence_val;
gst_d3d12_memory_set_fence (dmem, fence, priv->fence_val, FALSE);
GST_MINI_OBJECT_FLAG_SET (dmem, GST_D3D12_MEMORY_TRANSFER_NEED_DOWNLOAD);
GST_MINI_OBJECT_FLAG_UNSET (dmem, GST_D3D12_MEMORY_TRANSFER_NEED_UPLOAD);
}

View file

@ -857,15 +857,9 @@ gst_webview2_src_create (GstBaseSrc * src, guint64 offset, guint size,
if (!system_copy) {
gst_memory_unmap (mem, &out_map);
if (is_d3d12) {
auto cq = gst_d3d12_device_get_command_queue (priv->device12,
D3D12_COMMAND_LIST_TYPE_DIRECT);
gst_d3d12_command_queue_execute_wait (cq,
priv->fence12.Get (), priv->fence_val);
guint64 fence_val_12;
gst_d3d12_command_queue_execute_command_lists (cq,
0, nullptr, &fence_val_12);
auto dmem = GST_D3D12_MEMORY_CAST (mem);
dmem->fence_value = fence_val_12;
gst_d3d12_memory_set_fence (dmem, priv->fence12.Get (), priv->fence_val,
FALSE);
}
} else {
auto context = gst_d3d11_device_get_device_context_handle (priv->device);