mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-20 16:51:10 +00:00
d3d12converter: Add support for GPU-side external fence waiting
Ideally, GPU waiting should be scheduled just before executing command list. But handling the case outside of converter is a bit complicated. Under an assumption that constructed command list will be executed immediately, schedules GPU-side waiting inside of conversion method to simplify the flow. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6749>
This commit is contained in:
parent
c95725bb79
commit
2a14793ee1
8 changed files with 46 additions and 21 deletions
|
@ -2149,11 +2149,16 @@ gst_d3d12_converter_check_needs_upload (GstD3D12Converter * self,
|
|||
* @out_buf: a #GstBuffer
|
||||
* @fence_data: a #GstD3D12FenceData
|
||||
* @cl: a ID3D12GraphicsCommandList
|
||||
* @queue: (allow-none): a ID3D12CommandQueue
|
||||
*
|
||||
* Records command list for conversion operation. converter will attach
|
||||
* conversion command associated resources such as command allocator
|
||||
* to @fence_data.
|
||||
*
|
||||
* If @queue is passed and @in_buf needs external fence wait,
|
||||
* ID3D12CommandQueue::Wait() method for each external fence object
|
||||
* will be executed in this method
|
||||
*
|
||||
* Returns: %TRUE if successful
|
||||
*
|
||||
* Since: 1.26
|
||||
|
@ -2161,7 +2166,7 @@ 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)
|
||||
ID3D12GraphicsCommandList * cl, ID3D12CommandQueue * queue)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_D3D12_CONVERTER (converter), FALSE);
|
||||
g_return_val_if_fail (GST_IS_BUFFER (in_buf), FALSE);
|
||||
|
@ -2202,6 +2207,12 @@ gst_d3d12_converter_convert_buffer (GstD3D12Converter * converter,
|
|||
|
||||
auto ret = gst_d3d12_converter_execute (converter,
|
||||
&in_frame, &out_frame, fence_data, cl);
|
||||
|
||||
if (ret && queue) {
|
||||
gst_d3d12_frame_fence_gpu_wait (&in_frame, queue);
|
||||
gst_d3d12_frame_fence_gpu_wait (&out_frame, queue);
|
||||
}
|
||||
|
||||
gst_d3d12_frame_unmap (&in_frame);
|
||||
gst_d3d12_frame_unmap (&out_frame);
|
||||
|
||||
|
|
|
@ -164,7 +164,8 @@ gboolean gst_d3d12_converter_convert_buffer (GstD3D12Converter * conv
|
|||
GstBuffer * in_buf,
|
||||
GstBuffer * out_buf,
|
||||
GstD3D12FenceData * fence_data,
|
||||
ID3D12GraphicsCommandList * command_list);
|
||||
ID3D12GraphicsCommandList * command_list,
|
||||
ID3D12CommandQueue * queue);
|
||||
|
||||
GST_D3D12_API
|
||||
gboolean gst_d3d12_converter_update_blend_state (GstD3D12Converter * converter,
|
||||
|
|
|
@ -1156,9 +1156,12 @@ 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 ())) {
|
||||
priv->ctx->cl.Get (), cq_handle)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't build command list");
|
||||
gst_d3d12_fence_data_unref (fence_data);
|
||||
return FALSE;
|
||||
|
|
|
@ -2010,8 +2010,12 @@ gst_d3d12_convert_transform (GstBaseTransform * trans, GstBuffer * inbuf,
|
|||
gst_d3d12_fence_data_pool_acquire (priv->fence_data_pool, &fence_data);
|
||||
gst_d3d12_fence_data_add_notify_mini_object (fence_data, gst_ca);
|
||||
|
||||
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 ())) {
|
||||
inbuf, outbuf, fence_data, priv->ctx->cl.Get (), cq_handle)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't build command list");
|
||||
gst_d3d12_fence_data_unref (fence_data);
|
||||
return GST_FLOW_ERROR;
|
||||
|
|
|
@ -1379,8 +1379,12 @@ gst_d3d12_dxgi_capture_draw_mouse (GstD3D12DxgiCapture * self,
|
|||
ptr_w, "src-height", ptr_h, "dest-x", ptr_x, "dest-y", ptr_y,
|
||||
"dest-width", ptr_w, "dest-height", ptr_h, 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);
|
||||
|
||||
if (!gst_d3d12_converter_convert_buffer (priv->mouse_blend,
|
||||
priv->mouse_buf, buffer, fence_data, cl.Get ())) {
|
||||
priv->mouse_buf, buffer, fence_data, cl.Get (), cq_handle)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't build mouse blend command");
|
||||
gst_d3d12_fence_data_unref (fence_data);
|
||||
return FALSE;
|
||||
|
@ -1392,7 +1396,7 @@ gst_d3d12_dxgi_capture_draw_mouse (GstD3D12DxgiCapture * self,
|
|||
"dest-width", ptr_w, "dest-height", ptr_h, nullptr);
|
||||
|
||||
if (!gst_d3d12_converter_convert_buffer (priv->mouse_xor_blend,
|
||||
priv->mouse_xor_buf, buffer, fence_data, cl.Get ())) {
|
||||
priv->mouse_xor_buf, buffer, fence_data, cl.Get (), nullptr)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't build mouse blend command");
|
||||
gst_d3d12_fence_data_unref (fence_data);
|
||||
return FALSE;
|
||||
|
@ -1406,10 +1410,6 @@ gst_d3d12_dxgi_capture_draw_mouse (GstD3D12DxgiCapture * self,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
auto cq = gst_d3d12_device_get_command_queue (priv->device,
|
||||
D3D12_COMMAND_LIST_TYPE_DIRECT);
|
||||
gst_d3d12_command_queue_execute_wait (cq, priv->shared_fence.Get (),
|
||||
priv->fence_val);
|
||||
ID3D12CommandList *cmd_list[] = { cl.Get () };
|
||||
|
||||
guint64 fence_val = 0;
|
||||
|
@ -1480,15 +1480,13 @@ gst_d3d12_dxgi_capture_do_capture (GstD3D12DxgiCapture * capture,
|
|||
return ret;
|
||||
}
|
||||
|
||||
gst_d3d12_memory_set_external_fence (dmem, priv->shared_fence.Get (),
|
||||
priv->fence_val);
|
||||
|
||||
if (draw_mouse && !gst_d3d12_dxgi_capture_draw_mouse (self, buffer, crop_box)) {
|
||||
priv->WaitGPU ();
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
/* Set external fence after drawing mouse.
|
||||
* Otherwise converter will wait for fence value */
|
||||
gst_d3d12_memory_set_external_fence (dmem, priv->shared_fence.Get (),
|
||||
priv->fence_val);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
|
|
@ -2203,7 +2203,8 @@ gst_d3d12_test_src_create (GstBaseSrc * bsrc, guint64 offset,
|
|||
gst_d3d12_test_src_draw_pattern (self, pts, cl.Get ());
|
||||
|
||||
if (!gst_d3d12_converter_convert_buffer (priv->ctx->conv,
|
||||
priv->ctx->render_buffer, convert_buffer, fence_data, cl.Get ())) {
|
||||
priv->ctx->render_buffer, convert_buffer, fence_data, cl.Get (),
|
||||
nullptr)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't build convert command");
|
||||
gst_clear_buffer (&convert_buffer);
|
||||
gst_d3d12_fence_data_unref (fence_data);
|
||||
|
|
|
@ -1559,8 +1559,11 @@ gst_d3d12_window_set_buffer (GstD3D12Window * window, GstBuffer * buffer)
|
|||
cl->ResourceBarrier (1, &barrier);
|
||||
}
|
||||
|
||||
auto cq_handle = gst_d3d12_command_queue_get_handle (priv->ctx->queue);
|
||||
|
||||
if (!gst_d3d12_converter_convert_buffer (priv->ctx->conv,
|
||||
priv->ctx->cached_buf, conv_outbuf, fence_data, cl.Get ())) {
|
||||
priv->ctx->cached_buf, conv_outbuf, fence_data, cl.Get (),
|
||||
cq_handle)) {
|
||||
GST_ERROR_OBJECT (window, "Couldn't build convert command");
|
||||
gst_d3d12_fence_data_unref (fence_data);
|
||||
return GST_FLOW_ERROR;
|
||||
|
|
|
@ -454,10 +454,14 @@ gst_dwrite_d3d12_render_blend (GstDWriteRender * render, GstBuffer * layout_buf,
|
|||
|
||||
gboolean ret = TRUE;
|
||||
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);
|
||||
|
||||
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 ());
|
||||
layout_buf, output, fence_data, priv->cl.Get (), cq_handle);
|
||||
} else {
|
||||
GST_LOG_OBJECT (self, "Need conversion for blending");
|
||||
|
||||
|
@ -469,7 +473,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 ());
|
||||
output, bgra_buf, fence_data, priv->cl.Get (), cq_handle);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
|
@ -486,7 +490,7 @@ gst_dwrite_d3d12_render_blend (GstDWriteRender * render, GstBuffer * layout_buf,
|
|||
priv->cl->ResourceBarrier (1, &barrier);
|
||||
|
||||
ret = gst_d3d12_converter_convert_buffer (priv->blend_conv,
|
||||
layout_buf, bgra_buf, fence_data, priv->cl.Get ());
|
||||
layout_buf, bgra_buf, fence_data, priv->cl.Get (), nullptr);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
|
@ -517,7 +521,7 @@ gst_dwrite_d3d12_render_blend (GstDWriteRender * render, GstBuffer * layout_buf,
|
|||
priv->cl->ResourceBarrier (barriers.size (), barriers.data ());
|
||||
|
||||
ret = gst_d3d12_converter_convert_buffer (priv->post_conv,
|
||||
bgra_buf, output, fence_data, priv->cl.Get ());
|
||||
bgra_buf, output, fence_data, priv->cl.Get (), nullptr);
|
||||
}
|
||||
|
||||
gst_clear_buffer (&bgra_buf);
|
||||
|
|
Loading…
Reference in a new issue