d3d12converter: Update API signature

Always use device's main direct queue, and control gpu waiting
behavior by using boolean value

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7057>
This commit is contained in:
Seungha Yang 2024-06-19 19:06:42 +09:00 committed by GStreamer Marge Bot
parent f6eb3a01c0
commit fa7c4a2e39
9 changed files with 54 additions and 50 deletions

View file

@ -251,8 +251,11 @@ struct _GstD3D12ConverterPrivate
} }
converter_upload_data_free (upload_data); converter_upload_data_free (upload_data);
gst_clear_object (&srv_heap_pool); gst_clear_object (&srv_heap_pool);
gst_clear_object (&cq);
} }
GstD3D12CommandQueue *cq = nullptr;
GstVideoInfo in_info; GstVideoInfo in_info;
GstVideoInfo out_info; GstVideoInfo out_info;
@ -1592,6 +1595,7 @@ gst_d3d12_converter_calculate_border_color (GstD3D12Converter * self)
/** /**
* gst_d3d12_converter_new: * gst_d3d12_converter_new:
* @device: a #GstD3D12Device * @device: a #GstD3D12Device
* @queue: (allow-none): a #GstD3D12CommandQueue
* @in_info: a #GstVideoInfo * @in_info: a #GstVideoInfo
* @out_info: a #GstVideoInfo * @out_info: a #GstVideoInfo
* @blend_desc: (nullable): D3D12_BLEND_DESC * @blend_desc: (nullable): D3D12_BLEND_DESC
@ -1606,9 +1610,10 @@ gst_d3d12_converter_calculate_border_color (GstD3D12Converter * self)
* Since: 1.26 * Since: 1.26
*/ */
GstD3D12Converter * GstD3D12Converter *
gst_d3d12_converter_new (GstD3D12Device * device, const GstVideoInfo * in_info, gst_d3d12_converter_new (GstD3D12Device * device, GstD3D12CommandQueue * queue,
const GstVideoInfo * out_info, const D3D12_BLEND_DESC * blend_desc, const GstVideoInfo * in_info, const GstVideoInfo * out_info,
const gfloat blend_factor[4], GstStructure * config) const D3D12_BLEND_DESC * blend_desc, const gfloat blend_factor[4],
GstStructure * config)
{ {
GstD3D12Converter *self; GstD3D12Converter *self;
GstD3D12Format in_d3d12_format; GstD3D12Format in_d3d12_format;
@ -1622,10 +1627,19 @@ gst_d3d12_converter_new (GstD3D12Device * device, const GstVideoInfo * in_info,
g_return_val_if_fail (GST_IS_D3D12_DEVICE (device), nullptr); g_return_val_if_fail (GST_IS_D3D12_DEVICE (device), nullptr);
g_return_val_if_fail (in_info != nullptr, nullptr); g_return_val_if_fail (in_info != nullptr, nullptr);
g_return_val_if_fail (out_info != nullptr, nullptr); g_return_val_if_fail (out_info != nullptr, nullptr);
g_return_val_if_fail (queue == nullptr || GST_IS_D3D12_COMMAND_QUEUE (queue),
nullptr);
self = (GstD3D12Converter *) g_object_new (GST_TYPE_D3D12_CONVERTER, nullptr); self = (GstD3D12Converter *) g_object_new (GST_TYPE_D3D12_CONVERTER, nullptr);
gst_object_ref_sink (self); gst_object_ref_sink (self);
auto priv = self->priv; auto priv = self->priv;
priv->cq = queue;
if (!priv->cq) {
priv->cq = gst_d3d12_device_get_command_queue (device,
D3D12_COMMAND_LIST_TYPE_DIRECT);
}
gst_object_ref (priv->cq);
if (blend_desc) if (blend_desc)
priv->blend_desc = *blend_desc; priv->blend_desc = *blend_desc;
@ -2149,15 +2163,14 @@ gst_d3d12_converter_check_needs_upload (GstD3D12Converter * self,
* @out_buf: a #GstBuffer * @out_buf: a #GstBuffer
* @fence_data: a #GstD3D12FenceData * @fence_data: a #GstD3D12FenceData
* @command_list: a ID3D12GraphicsCommandList * @command_list: a ID3D12GraphicsCommandList
* @queue: (allow-none): a #GstD3D12CommandQueue * @execute_gpu_wait: Executes wait operation against @queue
* *
* Records command list for conversion operation. converter will attach * Records command list for conversion operation. converter will attach
* conversion command associated resources such as command allocator * conversion command associated resources such as command allocator
* to @fence_data. * to @fence_data.
* *
* If @queue is passed and @in_buf needs external fence wait, * If @execute_wait is %TRUE and buffers are associated with external fences,
* ID3D12CommandQueue::Wait() method for each external fence object * this method will schedule GPU wait operation against @queue.
* will be executed in this method
* *
* Returns: %TRUE if successful * Returns: %TRUE if successful
* *
@ -2166,15 +2179,13 @@ gst_d3d12_converter_check_needs_upload (GstD3D12Converter * self,
gboolean gboolean
gst_d3d12_converter_convert_buffer (GstD3D12Converter * converter, gst_d3d12_converter_convert_buffer (GstD3D12Converter * converter,
GstBuffer * in_buf, GstBuffer * out_buf, GstD3D12FenceData * fence_data, GstBuffer * in_buf, GstBuffer * out_buf, GstD3D12FenceData * fence_data,
ID3D12GraphicsCommandList * command_list, GstD3D12CommandQueue * queue) ID3D12GraphicsCommandList * command_list, gboolean execute_gpu_wait)
{ {
g_return_val_if_fail (GST_IS_D3D12_CONVERTER (converter), FALSE); 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 (in_buf), FALSE);
g_return_val_if_fail (GST_IS_BUFFER (out_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 (fence_data, FALSE);
g_return_val_if_fail (command_list, 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 in_frame;
GstD3D12Frame out_frame; GstD3D12Frame out_frame;
@ -2210,9 +2221,9 @@ gst_d3d12_converter_convert_buffer (GstD3D12Converter * converter,
auto ret = gst_d3d12_converter_execute (converter, auto ret = gst_d3d12_converter_execute (converter,
&in_frame, &out_frame, fence_data, command_list); &in_frame, &out_frame, fence_data, command_list);
if (ret && queue) { if (ret && execute_gpu_wait) {
gst_d3d12_frame_fence_gpu_wait (&in_frame, queue); gst_d3d12_frame_fence_gpu_wait (&in_frame, priv->cq);
gst_d3d12_frame_fence_gpu_wait (&out_frame, queue); gst_d3d12_frame_fence_gpu_wait (&out_frame, priv->cq);
} }
gst_d3d12_frame_unmap (&in_frame); gst_d3d12_frame_unmap (&in_frame);

View file

@ -153,6 +153,7 @@ GType gst_d3d12_converter_get_type (void);
GST_D3D12_API GST_D3D12_API
GstD3D12Converter * gst_d3d12_converter_new (GstD3D12Device * device, GstD3D12Converter * gst_d3d12_converter_new (GstD3D12Device * device,
GstD3D12CommandQueue * queue,
const GstVideoInfo * in_info, const GstVideoInfo * in_info,
const GstVideoInfo * out_info, const GstVideoInfo * out_info,
const D3D12_BLEND_DESC * blend_desc, const D3D12_BLEND_DESC * blend_desc,
@ -165,7 +166,7 @@ gboolean gst_d3d12_converter_convert_buffer (GstD3D12Converter * conv
GstBuffer * out_buf, GstBuffer * out_buf,
GstD3D12FenceData * fence_data, GstD3D12FenceData * fence_data,
ID3D12GraphicsCommandList * command_list, ID3D12GraphicsCommandList * command_list,
GstD3D12CommandQueue * queue); gboolean execute_gpu_wait);
GST_D3D12_API GST_D3D12_API
gboolean gst_d3d12_converter_update_blend_state (GstD3D12Converter * converter, gboolean gst_d3d12_converter_update_blend_state (GstD3D12Converter * converter,

View file

@ -1028,8 +1028,8 @@ gst_d3d12_compositor_pad_setup_converter (GstVideoAggregatorPad * pad,
auto ctx = std::make_unique < PadContext > (self->device); auto ctx = std::make_unique < PadContext > (self->device);
ctx->info = pad->info; ctx->info = pad->info;
ctx->conv = gst_d3d12_converter_new (self->device, &pad->info, info, ctx->conv = gst_d3d12_converter_new (self->device, nullptr, &pad->info,
&priv->blend_desc, priv->blend_factor, nullptr); info, &priv->blend_desc, priv->blend_factor, nullptr);
if (!ctx->conv) { if (!ctx->conv) {
GST_ERROR_OBJECT (pad, "Couldn't create converter"); GST_ERROR_OBJECT (pad, "Couldn't create converter");
return FALSE; return FALSE;
@ -1156,11 +1156,9 @@ gst_d3d12_compositor_preprare_func (GstVideoAggregatorPad * pad,
} }
} }
auto cq = gst_d3d12_device_get_command_queue (priv->ctx->device,
D3D12_COMMAND_LIST_TYPE_DIRECT);
if (!gst_d3d12_converter_convert_buffer (priv->ctx->conv, if (!gst_d3d12_converter_convert_buffer (priv->ctx->conv,
buffer, self->priv->generated_output_buf, fence_data, buffer, self->priv->generated_output_buf, fence_data,
priv->ctx->cl.Get (), cq)) { priv->ctx->cl.Get (), TRUE)) {
GST_ERROR_OBJECT (self, "Couldn't build command list"); GST_ERROR_OBJECT (self, "Couldn't build command list");
gst_d3d12_fence_data_unref (fence_data); gst_d3d12_fence_data_unref (fence_data);
return FALSE; return FALSE;

View file

@ -1750,7 +1750,7 @@ gst_d3d12_convert_set_info (GstD3D12BaseFilter * filter,
auto ctx = std::make_unique < ConvertContext > (filter->device); auto ctx = std::make_unique < ConvertContext > (filter->device);
ctx->conv = gst_d3d12_converter_new (filter->device, in_info, ctx->conv = gst_d3d12_converter_new (filter->device, nullptr, in_info,
out_info, nullptr, nullptr, config); out_info, nullptr, nullptr, config);
if (!ctx->conv) { if (!ctx->conv) {
GST_ERROR_OBJECT (self, "Couldn't create converter"); GST_ERROR_OBJECT (self, "Couldn't create converter");
@ -2012,9 +2012,9 @@ gst_d3d12_convert_transform (GstBaseTransform * trans, GstBuffer * inbuf,
auto cq = gst_d3d12_device_get_command_queue (priv->ctx->device, auto cq = gst_d3d12_device_get_command_queue (priv->ctx->device,
D3D12_COMMAND_LIST_TYPE_DIRECT); D3D12_COMMAND_LIST_TYPE_DIRECT);
auto fence = gst_d3d12_command_queue_get_fence_handle (cq);
if (!gst_d3d12_converter_convert_buffer (priv->ctx->conv, if (!gst_d3d12_converter_convert_buffer (priv->ctx->conv,
inbuf, outbuf, fence_data, priv->ctx->cl.Get (), cq)) { inbuf, outbuf, fence_data, priv->ctx->cl.Get (), TRUE)) {
GST_ERROR_OBJECT (self, "Couldn't build command list"); GST_ERROR_OBJECT (self, "Couldn't build command list");
gst_d3d12_fence_data_unref (fence_data); gst_d3d12_fence_data_unref (fence_data);
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
@ -2029,20 +2029,16 @@ gst_d3d12_convert_transform (GstBaseTransform * trans, GstBuffer * inbuf,
ID3D12CommandList *cmd_list[] = { priv->ctx->cl.Get () }; ID3D12CommandList *cmd_list[] = { priv->ctx->cl.Get () };
hr = gst_d3d12_device_execute_command_lists (priv->ctx->device, hr = gst_d3d12_command_queue_execute_command_lists (cq,
D3D12_COMMAND_LIST_TYPE_DIRECT, 1, cmd_list, &priv->ctx->fence_val); 1, cmd_list, &priv->ctx->fence_val);
if (!gst_d3d12_result (hr, priv->ctx->device)) { if (!gst_d3d12_result (hr, priv->ctx->device)) {
GST_ERROR_OBJECT (self, "Couldn't execute command list"); GST_ERROR_OBJECT (self, "Couldn't execute command list");
gst_d3d12_fence_data_unref (fence_data); gst_d3d12_fence_data_unref (fence_data);
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }
gst_d3d12_buffer_after_write (outbuf, gst_d3d12_buffer_after_write (outbuf, fence, priv->ctx->fence_val);
gst_d3d12_device_get_fence_handle (priv->ctx->device, gst_d3d12_command_queue_set_notify (cq, priv->ctx->fence_val,
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,
FENCE_NOTIFY_MINI_OBJECT (fence_data)); FENCE_NOTIFY_MINI_OBJECT (fence_data));
priv->ctx->scheduled.push (priv->ctx->fence_val); priv->ctx->scheduled.push (priv->ctx->fence_val);

View file

@ -1102,13 +1102,13 @@ gst_d3d12_dxgi_capture_open (GstD3D12DxgiCapture * self,
blend_desc.RenderTarget[0].RenderTargetWriteMask = blend_desc.RenderTarget[0].RenderTargetWriteMask =
D3D12_COLOR_WRITE_ENABLE_ALL; D3D12_COLOR_WRITE_ENABLE_ALL;
priv->mouse_blend = gst_d3d12_converter_new (self->device, &info, &info, priv->mouse_blend = gst_d3d12_converter_new (self->device, nullptr, &info,
&blend_desc, nullptr, nullptr); &info, &blend_desc, nullptr, nullptr);
blend_desc.RenderTarget[0].SrcBlend = D3D12_BLEND_INV_DEST_COLOR; blend_desc.RenderTarget[0].SrcBlend = D3D12_BLEND_INV_DEST_COLOR;
blend_desc.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_COLOR; blend_desc.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_COLOR;
priv->mouse_xor_blend = gst_d3d12_converter_new (self->device, &info, &info, priv->mouse_xor_blend = gst_d3d12_converter_new (self->device, nullptr, &info,
&blend_desc, nullptr, nullptr); &info, &blend_desc, nullptr, nullptr);
hr = device->CreateFence (0, hr = device->CreateFence (0,
D3D12_FENCE_FLAG_SHARED, IID_PPV_ARGS (&priv->shared_fence)); D3D12_FENCE_FLAG_SHARED, IID_PPV_ARGS (&priv->shared_fence));
@ -1391,7 +1391,7 @@ gst_d3d12_dxgi_capture_draw_mouse (GstD3D12DxgiCapture * self,
auto cq = gst_d3d12_device_get_command_queue (priv->device, auto cq = gst_d3d12_device_get_command_queue (priv->device,
D3D12_COMMAND_LIST_TYPE_DIRECT); D3D12_COMMAND_LIST_TYPE_DIRECT);
if (!gst_d3d12_converter_convert_buffer (priv->mouse_blend, if (!gst_d3d12_converter_convert_buffer (priv->mouse_blend,
priv->mouse_buf, buffer, fence_data, cl.Get (), cq)) { priv->mouse_buf, buffer, fence_data, cl.Get (), TRUE)) {
GST_ERROR_OBJECT (self, "Couldn't build mouse blend command"); GST_ERROR_OBJECT (self, "Couldn't build mouse blend command");
gst_d3d12_fence_data_unref (fence_data); gst_d3d12_fence_data_unref (fence_data);
return FALSE; return FALSE;
@ -1403,7 +1403,7 @@ gst_d3d12_dxgi_capture_draw_mouse (GstD3D12DxgiCapture * self,
"dest-width", ptr_w, "dest-height", ptr_h, nullptr); "dest-width", ptr_w, "dest-height", ptr_h, nullptr);
if (!gst_d3d12_converter_convert_buffer (priv->mouse_xor_blend, if (!gst_d3d12_converter_convert_buffer (priv->mouse_xor_blend,
priv->mouse_xor_buf, buffer, fence_data, cl.Get (), nullptr)) { priv->mouse_xor_buf, buffer, fence_data, cl.Get (), FALSE)) {
GST_ERROR_OBJECT (self, "Couldn't build mouse blend command"); GST_ERROR_OBJECT (self, "Couldn't build mouse blend command");
gst_d3d12_fence_data_unref (fence_data); gst_d3d12_fence_data_unref (fence_data);
return FALSE; return FALSE;

View file

@ -1577,7 +1577,7 @@ gst_d3d12_test_src_setup_context (GstD3D12TestSrc * self, GstCaps * caps)
gst_video_info_set_format (&draw_info, GST_VIDEO_FORMAT_BGRA, gst_video_info_set_format (&draw_info, GST_VIDEO_FORMAT_BGRA,
priv->info.width, priv->info.height); priv->info.width, priv->info.height);
ctx->conv = gst_d3d12_converter_new (self->device, ctx->conv = gst_d3d12_converter_new (self->device, nullptr,
&draw_info, &priv->info, nullptr, nullptr, config); &draw_info, &priv->info, nullptr, nullptr, config);
if (!ctx->conv) { if (!ctx->conv) {
@ -2201,10 +2201,9 @@ gst_d3d12_test_src_create (GstBaseSrc * bsrc, guint64 offset,
pts = priv->accum_rtime + priv->running_time; pts = priv->accum_rtime + priv->running_time;
gst_d3d12_test_src_draw_pattern (self, pts, cl.Get ()); gst_d3d12_test_src_draw_pattern (self, pts, cl.Get ());
if (!gst_d3d12_converter_convert_buffer (priv->ctx->conv, 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)) { FALSE)) {
GST_ERROR_OBJECT (self, "Couldn't build convert command"); GST_ERROR_OBJECT (self, "Couldn't build convert command");
gst_clear_buffer (&convert_buffer); gst_clear_buffer (&convert_buffer);
gst_d3d12_fence_data_unref (fence_data); gst_d3d12_fence_data_unref (fence_data);

View file

@ -327,7 +327,7 @@ SwapChain::setup_swapchain (GstD3D12Window * window, GstD3D12Device * device,
converter_config_ = gst_structure_copy (conv_config); converter_config_ = gst_structure_copy (conv_config);
if (!resource_->conv) { if (!resource_->conv) {
resource_->conv = gst_d3d12_converter_new (resource_->device, resource_->conv = gst_d3d12_converter_new (resource_->device, nullptr,
in_info, out_info, nullptr, nullptr, gst_structure_copy (conv_config)); in_info, out_info, nullptr, nullptr, gst_structure_copy (conv_config));
if (!resource_->conv) { if (!resource_->conv) {
GST_ERROR ("Couldn't create converter"); GST_ERROR ("Couldn't create converter");

View file

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

View file

@ -465,7 +465,7 @@ gst_dwrite_d3d12_render_blend (GstDWriteRender * render, GstBuffer * layout_buf,
if (priv->direct_blend) { if (priv->direct_blend) {
GST_LOG_OBJECT (self, "Direct blend"); GST_LOG_OBJECT (self, "Direct blend");
ret = gst_d3d12_converter_convert_buffer (priv->blend_conv, ret = gst_d3d12_converter_convert_buffer (priv->blend_conv,
layout_buf, output, fence_data, priv->cl.Get (), cq); layout_buf, output, fence_data, priv->cl.Get (), TRUE);
} else { } else {
GST_LOG_OBJECT (self, "Need conversion for blending"); GST_LOG_OBJECT (self, "Need conversion for blending");
@ -477,7 +477,7 @@ gst_dwrite_d3d12_render_blend (GstDWriteRender * render, GstBuffer * layout_buf,
if (ret) { if (ret) {
ret = gst_d3d12_converter_convert_buffer (priv->pre_conv, ret = gst_d3d12_converter_convert_buffer (priv->pre_conv,
output, bgra_buf, fence_data, priv->cl.Get (), cq); output, bgra_buf, fence_data, priv->cl.Get (), TRUE);
} }
if (ret) { if (ret) {
@ -494,7 +494,7 @@ gst_dwrite_d3d12_render_blend (GstDWriteRender * render, GstBuffer * layout_buf,
priv->cl->ResourceBarrier (1, &barrier); priv->cl->ResourceBarrier (1, &barrier);
ret = gst_d3d12_converter_convert_buffer (priv->blend_conv, ret = gst_d3d12_converter_convert_buffer (priv->blend_conv,
layout_buf, bgra_buf, fence_data, priv->cl.Get (), nullptr); layout_buf, bgra_buf, fence_data, priv->cl.Get (), FALSE);
} }
if (ret) { if (ret) {
@ -525,7 +525,7 @@ gst_dwrite_d3d12_render_blend (GstDWriteRender * render, GstBuffer * layout_buf,
priv->cl->ResourceBarrier (barriers.size (), barriers.data ()); priv->cl->ResourceBarrier (barriers.size (), barriers.data ());
ret = gst_d3d12_converter_convert_buffer (priv->post_conv, ret = gst_d3d12_converter_convert_buffer (priv->post_conv,
bgra_buf, output, fence_data, priv->cl.Get (), nullptr); bgra_buf, output, fence_data, priv->cl.Get (), FALSE);
} }
gst_clear_buffer (&bgra_buf); gst_clear_buffer (&bgra_buf);
@ -537,14 +537,13 @@ gst_dwrite_d3d12_render_blend (GstDWriteRender * render, GstBuffer * layout_buf,
if (ret) { if (ret) {
ID3D12CommandList *cl[] = { priv->cl.Get () }; ID3D12CommandList *cl[] = { priv->cl.Get () };
hr = gst_d3d12_device_execute_command_lists (priv->device, hr = gst_d3d12_command_queue_execute_command_lists (cq,
D3D12_COMMAND_LIST_TYPE_DIRECT, 1, cl, &priv->fence_val); 1, cl, &priv->fence_val);
ret = gst_d3d12_result (hr, priv->device); ret = gst_d3d12_result (hr, priv->device);
} }
if (ret) { if (ret) {
gst_d3d12_device_set_fence_notify (priv->device, gst_d3d12_command_queue_set_notify (cq, priv->fence_val,
D3D12_COMMAND_LIST_TYPE_DIRECT, priv->fence_val,
FENCE_NOTIFY_MINI_OBJECT (fence_data)); FENCE_NOTIFY_MINI_OBJECT (fence_data));
priv->scheduled.push (priv->fence_val); priv->scheduled.push (priv->fence_val);
@ -792,7 +791,7 @@ create_converter (GstDWriteD3D12Render * self, const GstVideoInfo * in_info,
GST_D3D12_CONVERTER_ALPHA_MODE_PREMULTIPLIED, nullptr); GST_D3D12_CONVERTER_ALPHA_MODE_PREMULTIPLIED, nullptr);
} }
auto ret = gst_d3d12_converter_new (priv->device, in_info, out_info, auto ret = gst_d3d12_converter_new (priv->device, nullptr, in_info, out_info,
&blend_desc, nullptr, config); &blend_desc, nullptr, config);
if (!ret) if (!ret)