mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-10 17:35:59 +00:00
d3d12converter: Add support for blending
Create new PSO if blend state update is required Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5875>
This commit is contained in:
parent
7c701058ed
commit
f4fe17d8d2
5 changed files with 116 additions and 7 deletions
|
@ -1833,7 +1833,7 @@ gst_d3d12_convert_set_info (GstD3D12BaseFilter * filter,
|
|||
auto ctx = std::make_unique < ConvertContext > (filter->device);
|
||||
|
||||
ctx->conv = gst_d3d12_converter_new (filter->device, in_info,
|
||||
out_info, config);
|
||||
out_info, nullptr, nullptr, config);
|
||||
if (!ctx->conv) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't create converter");
|
||||
return FALSE;
|
||||
|
|
|
@ -203,6 +203,7 @@ enum
|
|||
/* *INDENT-OFF* */
|
||||
struct QuadData
|
||||
{
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC desc;
|
||||
ComPtr<ID3D12PipelineState> pso;
|
||||
guint num_rtv;
|
||||
};
|
||||
|
@ -231,6 +232,9 @@ struct _GstD3D12ConverterPrivate
|
|||
{
|
||||
transform = g_matrix_identity;
|
||||
custom_transform = g_matrix_identity;
|
||||
blend_desc = CD3DX12_BLEND_DESC (D3D12_DEFAULT);
|
||||
for (guint i = 0; i < 4; i++)
|
||||
blend_factor[i] = 1.0f;
|
||||
}
|
||||
|
||||
~_GstD3D12ConverterPrivate ()
|
||||
|
@ -251,6 +255,8 @@ struct _GstD3D12ConverterPrivate
|
|||
D3D12_RECT scissor_rect[GST_VIDEO_MAX_PLANES];
|
||||
|
||||
D3D12_BLEND_DESC blend_desc;
|
||||
FLOAT blend_factor[4];
|
||||
gboolean update_pso = FALSE;
|
||||
|
||||
ConverterRootSignaturePtr crs;
|
||||
ComPtr<ID3D12RootSignature> rs;
|
||||
|
@ -663,7 +669,7 @@ gst_d3d12_converter_setup_resource (GstD3D12Converter * self,
|
|||
pso_desc.pRootSignature = priv->rs.Get ();
|
||||
pso_desc.VS = vs_blob;
|
||||
pso_desc.PS = psblob_list[i].bytecode;
|
||||
pso_desc.BlendState = CD3DX12_BLEND_DESC (D3D12_DEFAULT);
|
||||
pso_desc.BlendState = priv->blend_desc;
|
||||
pso_desc.SampleMask = UINT_MAX;
|
||||
pso_desc.RasterizerState = CD3DX12_RASTERIZER_DESC (D3D12_DEFAULT);
|
||||
pso_desc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
|
||||
|
@ -686,6 +692,7 @@ gst_d3d12_converter_setup_resource (GstD3D12Converter * self,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
priv->quad_data[i].desc = pso_desc;
|
||||
priv->quad_data[i].pso = pso;
|
||||
priv->quad_data[i].num_rtv = psblob_list[i].num_rtv;
|
||||
}
|
||||
|
@ -1532,7 +1539,8 @@ gst_d3d12_converter_calculate_border_color (GstD3D12Converter * self)
|
|||
|
||||
GstD3D12Converter *
|
||||
gst_d3d12_converter_new (GstD3D12Device * device, const GstVideoInfo * in_info,
|
||||
const GstVideoInfo * out_info, GstStructure * config)
|
||||
const GstVideoInfo * out_info, const D3D12_BLEND_DESC * blend_desc,
|
||||
const gfloat blend_factor[4], GstStructure * config)
|
||||
{
|
||||
GstD3D12Converter *self;
|
||||
GstD3D12Format in_d3d12_format;
|
||||
|
@ -1551,6 +1559,14 @@ gst_d3d12_converter_new (GstD3D12Device * device, const GstVideoInfo * in_info,
|
|||
gst_object_ref_sink (self);
|
||||
auto priv = self->priv;
|
||||
|
||||
if (blend_desc)
|
||||
priv->blend_desc = *blend_desc;
|
||||
|
||||
if (blend_factor) {
|
||||
for (guint i = 0; i < 4; i++)
|
||||
priv->blend_factor[i] = blend_factor[i];
|
||||
}
|
||||
|
||||
if (config) {
|
||||
gint value;
|
||||
if (gst_structure_get_enum (config, GST_D3D12_CONVERTER_OPT_GAMMA_MODE,
|
||||
|
@ -1706,6 +1722,48 @@ gst_d3d12_converter_new (GstD3D12Device * device, const GstVideoInfo * in_info,
|
|||
return self;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_d3d12_converter_update_pso (GstD3D12Converter * self)
|
||||
{
|
||||
auto priv = self->priv;
|
||||
if (!priv->update_pso)
|
||||
return TRUE;
|
||||
|
||||
std::vector < QuadData > quad_data;
|
||||
quad_data.resize (priv->quad_data.size ());
|
||||
|
||||
auto device = gst_d3d12_device_get_device_handle (self->device);
|
||||
|
||||
for (size_t i = 0; i < quad_data.size (); i++) {
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc = priv->quad_data[i].desc;
|
||||
pso_desc.BlendState = priv->blend_desc;
|
||||
|
||||
ComPtr < ID3D12PipelineState > pso;
|
||||
auto hr =
|
||||
device->CreateGraphicsPipelineState (&pso_desc, IID_PPV_ARGS (&pso));
|
||||
if (!gst_d3d12_result (hr, self->device)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't create pso");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
quad_data[i].desc = pso_desc;
|
||||
quad_data[i].pso = pso;
|
||||
quad_data[i].num_rtv = priv->quad_data[i].num_rtv;
|
||||
}
|
||||
|
||||
priv->update_pso = FALSE;
|
||||
priv->quad_data = quad_data;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
pso_free_func (ID3D12PipelineState * pso)
|
||||
{
|
||||
if (pso)
|
||||
pso->Release ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_d3d12_converter_execute (GstD3D12Converter * self,
|
||||
GstBuffer * in_buf, GstBuffer * out_buf, GstD3D12FenceData * fence_data,
|
||||
|
@ -1764,6 +1822,11 @@ gst_d3d12_converter_execute (GstD3D12Converter * self,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gst_d3d12_converter_update_pso (self)) {
|
||||
GST_ERROR_OBJECT (self, "Failed to update pso");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
auto & barriers = priv->barriers;
|
||||
auto & rtv_handles = priv->rtv_handles;
|
||||
|
||||
|
@ -1913,8 +1976,10 @@ gst_d3d12_converter_execute (GstD3D12Converter * self,
|
|||
}
|
||||
}
|
||||
|
||||
auto pso = priv->quad_data[0].pso.Get ();
|
||||
|
||||
cl->SetGraphicsRootSignature (priv->rs.Get ());
|
||||
cl->SetPipelineState (priv->quad_data[0].pso.Get ());
|
||||
cl->SetPipelineState (pso);
|
||||
|
||||
ID3D12DescriptorHeap *heaps[] = { srv_heap.Get () };
|
||||
cl->SetDescriptorHeaps (1, heaps);
|
||||
|
@ -1934,17 +1999,28 @@ gst_d3d12_converter_execute (GstD3D12Converter * self,
|
|||
cl->RSSetScissorRects (priv->quad_data[0].num_rtv, priv->scissor_rect);
|
||||
cl->OMSetRenderTargets (priv->quad_data[0].num_rtv,
|
||||
rtv_handles.data (), FALSE, nullptr);
|
||||
cl->OMSetBlendFactor (priv->blend_factor);
|
||||
cl->DrawIndexedInstanced (6, 1, 0, 0, 0);
|
||||
|
||||
pso->AddRef ();
|
||||
gst_d3d12_fence_data_add_notify (fence_data, pso,
|
||||
(GDestroyNotify) pso_free_func);
|
||||
|
||||
auto offset = priv->quad_data[0].num_rtv;
|
||||
if (priv->quad_data.size () == 2) {
|
||||
cl->SetPipelineState (priv->quad_data[1].pso.Get ());
|
||||
pso = priv->quad_data[1].pso.Get ();
|
||||
|
||||
cl->SetPipelineState (pso);
|
||||
cl->RSSetViewports (priv->quad_data[1].num_rtv, &priv->viewport[offset]);
|
||||
cl->RSSetScissorRects (priv->quad_data[1].num_rtv,
|
||||
&priv->scissor_rect[offset]);
|
||||
cl->OMSetRenderTargets (priv->quad_data[1].num_rtv,
|
||||
rtv_handles.data () + offset, FALSE, nullptr);
|
||||
cl->DrawIndexedInstanced (6, 1, 0, 0, 0);
|
||||
|
||||
pso->AddRef ();
|
||||
gst_d3d12_fence_data_add_notify (fence_data, pso,
|
||||
(GDestroyNotify) pso_free_func);
|
||||
}
|
||||
|
||||
gst_d3d12_fence_data_add_notify (fence_data,
|
||||
|
@ -2028,3 +2104,30 @@ gst_d3d12_converter_convert_buffer (GstD3D12Converter * converter,
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_d3d12_converter_update_blend_state (GstD3D12Converter * converter,
|
||||
const D3D12_BLEND_DESC * blend_desc, const gfloat blend_factor[4])
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_D3D12_CONVERTER (converter), FALSE);
|
||||
|
||||
auto priv = converter->priv;
|
||||
std::lock_guard < std::mutex > lk (priv->prop_lock);
|
||||
D3D12_BLEND_DESC new_blend = CD3DX12_BLEND_DESC (D3D12_DEFAULT);
|
||||
|
||||
if (blend_desc)
|
||||
new_blend = *blend_desc;
|
||||
|
||||
if (memcmp (&priv->blend_desc, &new_blend, sizeof (D3D12_BLEND_DESC)) != 0)
|
||||
priv->update_pso = TRUE;
|
||||
|
||||
if (blend_factor) {
|
||||
for (guint i = 0; i < 4; i++)
|
||||
priv->blend_factor[i] = blend_factor[i];
|
||||
} else {
|
||||
for (guint i = 0; i < 4; i++)
|
||||
priv->blend_factor[i] = 1.0f;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -136,6 +136,8 @@ GType gst_d3d12_converter_get_type (void);
|
|||
GstD3D12Converter * gst_d3d12_converter_new (GstD3D12Device * device,
|
||||
const GstVideoInfo * in_info,
|
||||
const GstVideoInfo * out_info,
|
||||
const D3D12_BLEND_DESC * blend_desc,
|
||||
const gfloat blend_factor[4],
|
||||
GstStructure * config);
|
||||
|
||||
gboolean gst_d3d12_converter_convert_buffer (GstD3D12Converter * converter,
|
||||
|
@ -144,4 +146,8 @@ gboolean gst_d3d12_converter_convert_buffer (GstD3D12Converter * conv
|
|||
GstD3D12FenceData * fence_data,
|
||||
ID3D12GraphicsCommandList * command_list);
|
||||
|
||||
gboolean gst_d3d12_converter_update_blend_state (GstD3D12Converter * converter,
|
||||
const D3D12_BLEND_DESC * blend_desc,
|
||||
const gfloat blend_factor[4]);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -1523,7 +1523,7 @@ gst_d3d12_test_src_setup_context (GstD3D12TestSrc * self, GstCaps * caps)
|
|||
gst_video_info_set_format (&draw_info, GST_VIDEO_FORMAT_BGRA,
|
||||
priv->info.width, priv->info.height);
|
||||
ctx->conv = gst_d3d12_converter_new (self->device,
|
||||
&draw_info, &priv->info, config);
|
||||
&draw_info, &priv->info, nullptr, nullptr, config);
|
||||
|
||||
if (!ctx->conv) {
|
||||
GST_ERROR_OBJECT (self, "Failed to create converter");
|
||||
|
|
|
@ -1074,7 +1074,7 @@ gst_d3d12_window_prepare (GstD3D12Window * window, GstD3D12Device * device,
|
|||
}
|
||||
|
||||
priv->ctx->conv = gst_d3d12_converter_new (window->device,
|
||||
&priv->input_info, &priv->display_info, config);
|
||||
&priv->input_info, &priv->display_info, nullptr, nullptr, config);
|
||||
if (!priv->ctx->conv) {
|
||||
GST_ERROR_OBJECT (window, "Couldn't create converter");
|
||||
priv->ctx = nullptr;
|
||||
|
|
Loading…
Reference in a new issue