d3d11converter: Introduce config to be extensible
authorSeungha Yang <seungha@centricular.com>
Mon, 17 May 2021 16:24:29 +0000 (01:24 +0900)
committerSeungha Yang <seungha@centricular.com>
Fri, 28 May 2021 12:44:10 +0000 (21:44 +0900)
Add a config argument like that of GstVideoConverter so that
we can add more options without modifying existing methods

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2276>

sys/d3d11/gstd3d11compositor.cpp
sys/d3d11/gstd3d11convert.cpp
sys/d3d11/gstd3d11converter.cpp
sys/d3d11/gstd3d11converter.h
sys/d3d11/gstd3d11overlaycompositor.cpp
sys/d3d11/gstd3d11shader.cpp
sys/d3d11/gstd3d11shader.h
sys/d3d11/gstd3d11window.cpp
sys/d3d11/gstd3d11window_dummy.cpp

index ac46c6f..6463ec1 100644 (file)
@@ -1200,11 +1200,20 @@ gst_d3d11_compositor_pad_setup_converter (GstVideoAggregatorPad * pad,
 #endif
 
   if (!cpad->convert || cpad->alpha_updated || self->reconfigured) {
+    GstStructure *config;
+
     if (cpad->convert)
       gst_d3d11_converter_free (cpad->convert);
+
+    config = gst_structure_new_empty ("config");
+    if (cpad->alpha <= 1.0) {
+      gst_structure_set (config, GST_D3D11_CONVERTER_OPT_ALPHA_VALUE,
+          G_TYPE_DOUBLE, cpad->alpha, nullptr);
+    }
+
     cpad->convert =
-        gst_d3d11_converter_new_with_alpha (self->device,
-        &pad->info, &vagg->info, cpad->alpha);
+        gst_d3d11_converter_new (self->device, &pad->info, &vagg->info, config);
+
     cpad->alpha_updated = FALSE;
     if (!cpad->convert) {
       GST_ERROR_OBJECT (pad, "Couldn't create converter");
@@ -2049,7 +2058,7 @@ gst_d3d11_compositor_create_checker_quad (GstD3D11Compositor * self)
   context_handle->Unmap (index_buffer.Get (), 0);
 
   quad = gst_d3d11_quad_new (self->device,
-      ps.Get (), vs.Get (), layout.Get (), NULL,
+      ps.Get (), vs.Get (), layout.Get (), nullptr, 0,
       vertex_buffer.Get (), sizeof (VertexData), index_buffer.Get (),
       DXGI_FORMAT_R16_UINT, 6);
   if (!quad) {
index 8f272e6..4ce213f 100644 (file)
@@ -1783,7 +1783,8 @@ gst_d3d11_base_convert_set_info (GstD3D11BaseFilter * filter,
     goto format_unknown;
   }
 
-  self->converter = gst_d3d11_converter_new (filter->device, in_info, out_info);
+  self->converter =
+      gst_d3d11_converter_new (filter->device, in_info, out_info, nullptr);
 
   if (!self->converter) {
     GST_ERROR_OBJECT (self, "couldn't set converter");
index fd5545c..09ccba8 100644 (file)
@@ -50,6 +50,12 @@ typedef struct
 
 typedef struct
 {
+  FLOAT alpha_mul;
+  FLOAT padding[3];
+} AlphaConstBuffer;
+
+typedef struct
+{
   struct {
     FLOAT x;
     FLOAT y;
@@ -63,16 +69,24 @@ typedef struct
 
 typedef struct
 {
-  const gchar *constant_buffer;
+  gboolean has_transform;
+  gboolean has_alpha;
   const gchar *func;
 } PixelShaderTemplate;
 
-#define COLOR_TRANSFORM_COEFF \
-    "cbuffer PixelShaderColorTransform : register(b0)\n" \
-    "{\n" \
-    "  float3x4 trans_matrix;\n" \
-    "  float3 padding;\n" \
-    "};\n"
+static const gchar templ_color_transform_const_buffer[] =
+    "cbuffer PixelShaderColorTransform : register(b%u)\n"
+    "{\n"
+    "  float3x4 trans_matrix;\n"
+    "  float3 padding;\n"
+    "};";
+
+static const gchar templ_alpha_const_buffer[] =
+    "cbuffer AlphaConstBuffer : register(b%u)\n"
+    "{\n"
+    "  float alpha_mul;\n"
+    "  float3 padding;\n"
+    "};";
 
 #define HLSL_FUNC_YUV_TO_RGB \
     "float3 yuv_to_rgb (float3 yuv)\n" \
@@ -99,18 +113,18 @@ typedef struct
     "  float4 Plane_1: SV_TARGET1;"
 
 static const PixelShaderTemplate templ_REORDER =
-    { NULL, NULL };
+    { FALSE, TRUE, NULL };
 
 static const PixelShaderTemplate templ_YUV_to_RGB =
-    { COLOR_TRANSFORM_COEFF, HLSL_FUNC_YUV_TO_RGB };
+    { TRUE, FALSE, HLSL_FUNC_YUV_TO_RGB };
 
 static const PixelShaderTemplate templ_RGB_to_YUV =
-    { COLOR_TRANSFORM_COEFF, HLSL_FUNC_RGB_TO_YUV };
+    { TRUE, FALSE, HLSL_FUNC_RGB_TO_YUV };
 
 static const gchar templ_REORDER_BODY[] =
     "  float4 xyza;\n"
     "  xyza.xyz = shaderTexture[0].Sample(samplerState, input.Texture).xyz;\n"
-    "  xyza.a = shaderTexture[0].Sample(samplerState, input.Texture).a * %f;\n"
+    "  xyza.a = shaderTexture[0].Sample(samplerState, input.Texture).a * alpha_mul;\n"
     "  output.Plane_0 = xyza;\n";
 
 static const gchar templ_VUYA_to_RGB_BODY[] =
@@ -275,6 +289,7 @@ static const gchar templ_PACKED_YUV_TO_SEMI_PLANAR_CHROMA_BODY[] =
 static const gchar templ_pixel_shader[] =
     /* constant buffer */
     "%s\n"
+    "%s\n"
     "Texture2D shaderTexture[4];\n"
     "SamplerState samplerState;\n"
     "\n"
@@ -331,7 +346,7 @@ struct _GstD3D11Converter
   GstD3D11Device *device;
   GstVideoInfo in_info;
   GstVideoInfo out_info;
-  gfloat alpha;
+  gdouble alpha;
 
   const GstD3D11Format *in_d3d11_format;
   const GstD3D11Format *out_d3d11_format;
@@ -348,13 +363,32 @@ struct _GstD3D11Converter
   gint input_texture_width;
   gint input_texture_height;
   ID3D11Buffer *vertex_buffer;
+  ID3D11Buffer *alpha_const_buffer;
   gboolean update_vertex;
+  gboolean update_alpha;
 
   ID3D11SamplerState *linear_sampler;
 
   ConvertInfo convert_info;
+
+  GstStructure *config;
 };
 
+static gdouble
+get_opt_double (GstD3D11Converter * self, const gchar * opt, gdouble def)
+{
+  gdouble res;
+  if (!gst_structure_get_double (self->config, opt, &res))
+    res = def;
+
+  return res;
+}
+
+#define DEFAULT_OPT_ALPHA_VALUE 1.0
+
+#define GET_OPT_ALPHA_VALUE(c) get_opt_double(c, \
+    GST_D3D11_CONVERTER_OPT_ALPHA_VALUE, DEFAULT_OPT_ALPHA_VALUE);
+
 /* from video-converter.c */
 typedef struct
 {
@@ -594,7 +628,7 @@ setup_convert_info_rgb_to_rgb (GstD3D11Converter * self,
   ConvertInfo *convert_info = &self->convert_info;
 
   convert_info->templ = &templ_REORDER;
-  convert_info->ps_body[0] = g_strdup_printf (templ_REORDER_BODY, self->alpha);
+  convert_info->ps_body[0] = g_strdup_printf (templ_REORDER_BODY);
   convert_info->ps_output[0] = HLSL_PS_OUTPUT_ONE_PLANE_BODY;
 
   return TRUE;
@@ -847,7 +881,7 @@ setup_convert_info_vuya_to_vuya (GstD3D11Converter * self,
   info->templ = &templ_REORDER;
   info->ps_output[0] = HLSL_PS_OUTPUT_ONE_PLANE_BODY;
 
-  info->ps_body[0] = g_strdup_printf (templ_REORDER_BODY, self->alpha);
+  info->ps_body[0] = g_strdup_printf (templ_REORDER_BODY);
 
   return TRUE;
 }
@@ -1071,13 +1105,16 @@ gst_d3d11_color_convert_setup_shader (GstD3D11Converter * self,
   ComPtr<ID3D11VertexShader> vs;
   ComPtr<ID3D11InputLayout> layout;
   ComPtr<ID3D11SamplerState> linear_sampler;
-  ComPtr<ID3D11Buffer> const_buffer;
+  ComPtr<ID3D11Buffer> transform_const_buffer;
+  ComPtr<ID3D11Buffer> alpha_const_buffer;
   ComPtr<ID3D11Buffer> vertex_buffer;
   ComPtr<ID3D11Buffer> index_buffer;
   /* *INDENT-ON* */
   const guint index_count = 2 * 3;
   gint i;
   gboolean ret;
+  ID3D11Buffer *const_buffers[2] = { nullptr, nullptr };
+  guint num_const_buffers = 0;
 
   memset (&sampler_desc, 0, sizeof (sampler_desc));
   memset (input_desc, 0, sizeof (input_desc));
@@ -1105,14 +1142,32 @@ gst_d3d11_color_convert_setup_shader (GstD3D11Converter * self,
     gchar *shader_code = NULL;
 
     if (convert_info->ps_body[i]) {
+      gchar *transform_const_buffer = nullptr;
+      gchar *alpha_const_buffer = nullptr;
+      guint register_idx = 0;
+
       g_assert (convert_info->ps_output[i] != NULL);
 
+      if (convert_info->templ->has_transform) {
+        transform_const_buffer =
+            g_strdup_printf (templ_color_transform_const_buffer, register_idx);
+        register_idx++;
+      }
+
+      if (convert_info->templ->has_alpha) {
+        alpha_const_buffer =
+            g_strdup_printf (templ_alpha_const_buffer, register_idx);
+        register_idx++;
+      }
+
       shader_code = g_strdup_printf (templ_pixel_shader,
-          convert_info->templ->constant_buffer ?
-          convert_info->templ->constant_buffer : "",
+          transform_const_buffer ? transform_const_buffer : "",
+          alpha_const_buffer ? alpha_const_buffer : "",
           convert_info->ps_output[i],
           convert_info->templ->func ? convert_info->templ->func : "",
           convert_info->ps_body[i]);
+      g_free (transform_const_buffer);
+      g_free (alpha_const_buffer);
 
       ret = gst_d3d11_create_pixel_shader (device, shader_code, &ps[i]);
       g_free (shader_code);
@@ -1122,9 +1177,11 @@ gst_d3d11_color_convert_setup_shader (GstD3D11Converter * self,
     }
   }
 
-  if (convert_info->templ->constant_buffer) {
+  if (convert_info->templ->has_transform) {
     D3D11_BUFFER_DESC const_buffer_desc = { 0, };
 
+    G_STATIC_ASSERT (sizeof (PixelShaderColorTransform) % 16 == 0);
+
     const_buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
     const_buffer_desc.ByteWidth = sizeof (PixelShaderColorTransform);
     const_buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
@@ -1132,14 +1189,15 @@ gst_d3d11_color_convert_setup_shader (GstD3D11Converter * self,
     const_buffer_desc.MiscFlags = 0;
     const_buffer_desc.StructureByteStride = 0;
 
-    hr = device_handle->CreateBuffer (&const_buffer_desc, NULL, &const_buffer);
+    hr = device_handle->CreateBuffer (&const_buffer_desc, nullptr,
+        &transform_const_buffer);
     if (!gst_d3d11_result (hr, device)) {
       GST_ERROR ("Couldn't create constant buffer, hr: 0x%x", (guint) hr);
       return FALSE;
     }
 
     gst_d3d11_device_lock (device);
-    hr = context_handle->Map (const_buffer.Get (),
+    hr = context_handle->Map (transform_const_buffer.Get (),
         0, D3D11_MAP_WRITE_DISCARD, 0, &map);
 
     if (!gst_d3d11_result (hr, device)) {
@@ -1151,8 +1209,55 @@ gst_d3d11_color_convert_setup_shader (GstD3D11Converter * self,
     memcpy (map.pData, &convert_info->transform,
         sizeof (PixelShaderColorTransform));
 
-    context_handle->Unmap (const_buffer.Get (), 0);
+    context_handle->Unmap (transform_const_buffer.Get (), 0);
     gst_d3d11_device_unlock (device);
+
+    const_buffers[num_const_buffers] = transform_const_buffer.Get ();
+    num_const_buffers++;
+  }
+
+  if (convert_info->templ->has_alpha) {
+    D3D11_BUFFER_DESC const_buffer_desc = { 0, };
+    AlphaConstBuffer *alpha_const;
+
+    G_STATIC_ASSERT (sizeof (AlphaConstBuffer) % 16 == 0);
+
+    const_buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
+    const_buffer_desc.ByteWidth = sizeof (AlphaConstBuffer);
+    const_buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+    const_buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+    const_buffer_desc.MiscFlags = 0;
+    const_buffer_desc.StructureByteStride = 0;
+
+    hr = device_handle->CreateBuffer (&const_buffer_desc,
+        nullptr, &alpha_const_buffer);
+    if (!gst_d3d11_result (hr, device)) {
+      GST_ERROR ("Couldn't create constant buffer, hr: 0x%x", (guint) hr);
+      return FALSE;
+    }
+
+    gst_d3d11_device_lock (device);
+    hr = context_handle->Map (alpha_const_buffer.Get (),
+        0, D3D11_MAP_WRITE_DISCARD, 0, &map);
+
+    if (!gst_d3d11_result (hr, device)) {
+      GST_ERROR ("Couldn't map constant buffer, hr: 0x%x", (guint) hr);
+      gst_d3d11_device_unlock (device);
+      return FALSE;
+    }
+
+    alpha_const = (AlphaConstBuffer *) map.pData;
+    memset (alpha_const, 0, sizeof (AlphaConstBuffer));
+    alpha_const->alpha_mul = (FLOAT) self->alpha;
+
+    context_handle->Unmap (alpha_const_buffer.Get (), 0);
+    gst_d3d11_device_unlock (device);
+
+    self->alpha_const_buffer = alpha_const_buffer.Get ();
+    /* We will hold this buffer and update later */
+    self->alpha_const_buffer->AddRef ();
+    const_buffers[num_const_buffers] = alpha_const_buffer.Get ();
+    num_const_buffers++;
   }
 
   input_desc[0].SemanticName = "POSITION";
@@ -1265,13 +1370,15 @@ gst_d3d11_color_convert_setup_shader (GstD3D11Converter * self,
 
   self->quad[0] = gst_d3d11_quad_new (device,
       ps[0].Get (), vs.Get (), layout.Get (),
-      const_buffer.Get (), vertex_buffer.Get (), sizeof (VertexData),
+      const_buffers, num_const_buffers,
+      vertex_buffer.Get (), sizeof (VertexData),
       index_buffer.Get (), DXGI_FORMAT_R16_UINT, index_count);
 
   if (ps[1]) {
     self->quad[1] = gst_d3d11_quad_new (device,
         ps[1].Get (), vs.Get (), layout.Get (),
-        const_buffer.Get (), vertex_buffer.Get (), sizeof (VertexData),
+        const_buffers, num_const_buffers,
+        vertex_buffer.Get (), sizeof (VertexData),
         index_buffer.Get (), DXGI_FORMAT_R16_UINT, index_count);
   }
 
@@ -1299,9 +1406,28 @@ gst_d3d11_color_convert_setup_shader (GstD3D11Converter * self,
   return TRUE;
 }
 
-static GstD3D11Converter *
-gst_d3d11_converter_new_internal (GstD3D11Device * device,
-    GstVideoInfo * in_info, GstVideoInfo * out_info, gfloat alpha)
+static gboolean
+copy_config (GQuark field_id, const GValue * value, GstD3D11Converter * self)
+{
+  gst_structure_id_set_value (self->config, field_id, value);
+
+  return TRUE;
+}
+
+static gboolean
+gst_d3d11_converter_set_config (GstD3D11Converter * converter,
+    GstStructure * config)
+{
+  gst_structure_foreach (config, (GstStructureForeachFunc) copy_config,
+      converter);
+  gst_structure_free (config);
+
+  return TRUE;
+}
+
+GstD3D11Converter *
+gst_d3d11_converter_new (GstD3D11Device * device,
+    GstVideoInfo * in_info, GstVideoInfo * out_info, GstStructure * config)
 {
   const GstVideoInfo *unknown_info;
   const GstD3D11Format *in_d3d11_format;
@@ -1338,7 +1464,11 @@ gst_d3d11_converter_new_internal (GstD3D11Device * device,
 
   converter = g_new0 (GstD3D11Converter, 1);
   converter->device = (GstD3D11Device *) gst_object_ref (device);
-  converter->alpha = alpha;
+  converter->config = gst_structure_new_empty ("GstD3D11Converter-Config");
+  if (config)
+    gst_d3d11_converter_set_config (converter, config);
+
+  converter->alpha = GET_OPT_ALPHA_VALUE (converter);
 
   if (GST_VIDEO_INFO_IS_RGB (in_info)) {
     if (GST_VIDEO_INFO_IS_RGB (out_info)) {
@@ -1408,6 +1538,9 @@ format_unknown:
   {
     GST_ERROR ("%s couldn't be converted to d3d11 format",
         gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (unknown_info)));
+    if (config)
+      gst_structure_free (config);
+
     return NULL;
   }
 conversion_not_supported:
@@ -1420,23 +1553,6 @@ conversion_not_supported:
   }
 }
 
-GstD3D11Converter *
-gst_d3d11_converter_new (GstD3D11Device * device,
-    GstVideoInfo * in_info, GstVideoInfo * out_info)
-{
-  return gst_d3d11_converter_new_internal (device, in_info, out_info, 1.0f);
-}
-
-GstD3D11Converter *
-gst_d3d11_converter_new_with_alpha (GstD3D11Device * device,
-    GstVideoInfo * in_info, GstVideoInfo * out_info, gfloat alpha)
-{
-  g_return_val_if_fail (alpha >= 0.0f, NULL);
-  g_return_val_if_fail (alpha <= 1.0f, NULL);
-
-  return gst_d3d11_converter_new_internal (device, in_info, out_info, alpha);
-}
-
 void
 gst_d3d11_converter_free (GstD3D11Converter * converter)
 {
@@ -1453,8 +1569,13 @@ gst_d3d11_converter_free (GstD3D11Converter * converter)
 
   GST_D3D11_CLEAR_COM (converter->vertex_buffer);
   GST_D3D11_CLEAR_COM (converter->linear_sampler);
+  GST_D3D11_CLEAR_COM (converter->alpha_const_buffer);
 
   gst_clear_object (&converter->device);
+
+  if (converter->config)
+    gst_structure_free (converter->config);
+
   g_free (converter);
 }
 
@@ -1608,6 +1729,32 @@ gst_d3d11_converter_convert_unlocked (GstD3D11Converter * converter,
     }
   }
 
+  if (converter->update_alpha) {
+    D3D11_MAPPED_SUBRESOURCE map;
+    ID3D11DeviceContext *context_handle;
+    AlphaConstBuffer *alpha_const;
+    HRESULT hr;
+
+    g_assert (converter->alpha_const_buffer != nullptr);
+
+    context_handle =
+        gst_d3d11_device_get_device_context_handle (converter->device);
+
+    hr = context_handle->Map (converter->alpha_const_buffer,
+        0, D3D11_MAP_WRITE_DISCARD, 0, &map);
+
+    if (!gst_d3d11_result (hr, converter->device)) {
+      GST_ERROR ("Couldn't map constant buffer, hr: 0x%x", (guint) hr);
+      return FALSE;
+    }
+
+    alpha_const = (AlphaConstBuffer *) map.pData;
+    alpha_const->alpha_mul = (FLOAT) converter->alpha;
+
+    context_handle->Unmap (converter->alpha_const_buffer, 0);
+    converter->update_alpha = FALSE;
+  }
+
   ret = gst_d3d11_draw_quad_unlocked (converter->quad[0], converter->viewport,
       1, srv, converter->num_input_view, rtv, 1, blend, blend_factor,
       &converter->linear_sampler, 1);
@@ -1670,6 +1817,7 @@ gst_d3d11_converter_update_src_rect (GstD3D11Converter * converter,
   g_return_val_if_fail (converter != NULL, FALSE);
   g_return_val_if_fail (src_rect != NULL, FALSE);
 
+  gst_d3d11_device_lock (converter->device);
   if (converter->src_rect.left != src_rect->left ||
       converter->src_rect.top != src_rect->top ||
       converter->src_rect.right != src_rect->right ||
@@ -1679,6 +1827,7 @@ gst_d3d11_converter_update_src_rect (GstD3D11Converter * converter,
     /* vertex buffer will be updated on next convert() call */
     converter->update_vertex = TRUE;
   }
+  gst_d3d11_device_unlock (converter->device);
 
   return TRUE;
 }
@@ -1690,6 +1839,7 @@ gst_d3d11_converter_update_dest_rect (GstD3D11Converter * converter,
   g_return_val_if_fail (converter != NULL, FALSE);
   g_return_val_if_fail (dest_rect != NULL, FALSE);
 
+  gst_d3d11_device_lock (converter->device);
   if (converter->dest_rect.left != dest_rect->left ||
       converter->dest_rect.top != dest_rect->top ||
       converter->dest_rect.right != dest_rect->right ||
@@ -1699,6 +1849,32 @@ gst_d3d11_converter_update_dest_rect (GstD3D11Converter * converter,
     /* vertex buffer will be updated on next convert() call */
     converter->update_vertex = TRUE;
   }
+  gst_d3d11_device_unlock (converter->device);
+
+  return TRUE;
+}
+
+gboolean
+gst_d3d11_converter_update_config (GstD3D11Converter * converter,
+    GstStructure * config)
+{
+  g_return_val_if_fail (converter != nullptr, FALSE);
+  g_return_val_if_fail (config != nullptr, FALSE);
+
+  gst_d3d11_device_lock (converter->device);
+  gst_d3d11_converter_set_config (converter, config);
+
+  /* Check whether options are updated or not */
+  if (converter->alpha_const_buffer) {
+    gdouble alpha = GET_OPT_ALPHA_VALUE (converter);
+
+    if (alpha != converter->alpha) {
+      GST_DEBUG ("Updating alpha %lf -> %lf", converter->alpha, alpha);
+      converter->alpha = alpha;
+      converter->update_alpha = TRUE;
+    }
+  }
+  gst_d3d11_device_unlock (converter->device);
 
   return TRUE;
 }
index 27788ad..c30ea2c 100644 (file)
@@ -28,14 +28,18 @@ G_BEGIN_DECLS
 
 typedef struct _GstD3D11Converter GstD3D11Converter;
 
+/**
+ * GST_D3D11_CONVERTER_OPT_ALPHA_VALUE
+ *
+ * #G_TYPE_FLOAT, the alpha value color value to use.
+ * Default is 1.0
+ */
+#define GST_D3D11_CONVERTER_OPT_ALPHA_VALUE "GstD3D11Converter.alpha-value"
+
 GstD3D11Converter * gst_d3d11_converter_new  (GstD3D11Device * device,
                                               GstVideoInfo * in_info,
-                                              GstVideoInfo * out_info);
-
-GstD3D11Converter * gst_d3d11_converter_new_with_alpha (GstD3D11Device * device,
-                                                        GstVideoInfo * in_info,
-                                                        GstVideoInfo * out_info,
-                                                        gfloat alpha);
+                                              GstVideoInfo * out_info,
+                                              GstStructure * config);
 
 void                gst_d3d11_converter_free    (GstD3D11Converter * converter);
 
@@ -60,6 +64,9 @@ gboolean            gst_d3d11_converter_update_src_rect (GstD3D11Converter * con
 gboolean            gst_d3d11_converter_update_dest_rect (GstD3D11Converter * converter,
                                                           RECT * dest_rect);
 
+gboolean            gst_d3d11_converter_update_config    (GstD3D11Converter * converter,
+                                                          GstStructure * config);
+
 G_END_DECLS
 
 #endif /* __GST_D3D11_COLOR_CONVERTER_H__ */
index 798ee04..b09ca9c 100644 (file)
@@ -285,7 +285,7 @@ gst_d3d11_composition_overlay_new (GstD3D11OverlayCompositor * self,
   overlay->texture = texture.Detach ();
   overlay->srv = srv.Detach ();
   overlay->quad = gst_d3d11_quad_new (device,
-      self->ps, self->vs, self->layout, NULL,
+      self->ps, self->vs, self->layout, nullptr, 0,
       vertex_buffer.Get (), sizeof (VertexData),
       self->index_buffer, DXGI_FORMAT_R16_UINT, index_count);
 
index ef502bb..ded8689 100644 (file)
@@ -37,6 +37,9 @@ GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_shader_debug);
 G_END_DECLS
 /* *INDENT-ON* */
 
+/* too many const buffers doesn't make sense */
+#define MAX_CONST_BUFFERS 16
+
 static GModule *d3d_compiler_module = NULL;
 static pD3DCompile GstD3DCompileFunc = NULL;
 
@@ -237,7 +240,8 @@ struct _GstD3D11Quad
   ID3D11PixelShader *ps;
   ID3D11VertexShader *vs;
   ID3D11InputLayout *layout;
-  ID3D11Buffer *const_buffer;
+  ID3D11Buffer *const_buffer[MAX_CONST_BUFFERS];
+  guint num_const_buffers;
   ID3D11Buffer *vertex_buffer;
   guint vertex_stride;
   ID3D11Buffer *index_buffer;
@@ -253,7 +257,7 @@ struct _GstD3D11Quad
 GstD3D11Quad *
 gst_d3d11_quad_new (GstD3D11Device * device, ID3D11PixelShader * pixel_shader,
     ID3D11VertexShader * vertex_shader, ID3D11InputLayout * layout,
-    ID3D11Buffer * const_buffer,
+    ID3D11Buffer ** const_buffers, guint num_const_buffers,
     ID3D11Buffer * vertex_buffer, guint vertex_stride,
     ID3D11Buffer * index_buffer, DXGI_FORMAT index_format, guint index_count)
 {
@@ -263,6 +267,7 @@ gst_d3d11_quad_new (GstD3D11Device * device, ID3D11PixelShader * pixel_shader,
   g_return_val_if_fail (pixel_shader != NULL, NULL);
   g_return_val_if_fail (vertex_shader != NULL, NULL);
   g_return_val_if_fail (layout != NULL, NULL);
+  g_return_val_if_fail (num_const_buffers <= MAX_CONST_BUFFERS, NULL);
   g_return_val_if_fail (vertex_buffer != NULL, NULL);
   g_return_val_if_fail (vertex_stride > 0, NULL);
   g_return_val_if_fail (index_buffer != NULL, NULL);
@@ -286,9 +291,17 @@ gst_d3d11_quad_new (GstD3D11Device * device, ID3D11PixelShader * pixel_shader,
   vertex_buffer->AddRef ();
   index_buffer->AddRef ();
 
-  if (const_buffer) {
-    quad->const_buffer = const_buffer;
-    const_buffer->AddRef ();
+  if (num_const_buffers > 0) {
+    guint i;
+
+    g_assert (const_buffers);
+
+    for (i = 0; i < num_const_buffers; i++) {
+      quad->const_buffer[i] = const_buffers[i];
+      quad->const_buffer[i]->AddRef ();
+    }
+
+    quad->num_const_buffers = num_const_buffers;
   }
 
   return quad;
@@ -297,12 +310,15 @@ gst_d3d11_quad_new (GstD3D11Device * device, ID3D11PixelShader * pixel_shader,
 void
 gst_d3d11_quad_free (GstD3D11Quad * quad)
 {
+  guint i;
+
   g_return_if_fail (quad != NULL);
 
   GST_D3D11_CLEAR_COM (quad->ps);
   GST_D3D11_CLEAR_COM (quad->vs);
   GST_D3D11_CLEAR_COM (quad->layout);
-  GST_D3D11_CLEAR_COM (quad->const_buffer);
+  for (i = 0; i < quad->num_const_buffers; i++)
+    quad->const_buffer[i]->Release ();
   GST_D3D11_CLEAR_COM (quad->vertex_buffer);
   GST_D3D11_CLEAR_COM (quad->index_buffer);
 
@@ -364,8 +380,10 @@ gst_d3d11_draw_quad_unlocked (GstD3D11Quad * quad,
   context->PSSetShader (quad->ps, NULL, 0);
   context->RSSetViewports (num_viewport, viewport);
 
-  if (quad->const_buffer)
-    context->PSSetConstantBuffers (0, 1, &quad->const_buffer);
+  if (quad->num_const_buffers) {
+    context->PSSetConstantBuffers (0, quad->num_const_buffers,
+        quad->const_buffer);
+  }
 
   if (srv)
     context->PSSetShaderResources (0, num_srv, srv);
index fe9bcc8..5fc0419 100644 (file)
@@ -47,7 +47,8 @@ GstD3D11Quad * gst_d3d11_quad_new (GstD3D11Device * device,
                                    ID3D11PixelShader * pixel_shader,
                                    ID3D11VertexShader * vertex_shader,
                                    ID3D11InputLayout * layout,
-                                   ID3D11Buffer * const_buffer,
+                                   ID3D11Buffer ** const_buffers,
+                                   guint num_const_buffers,
                                    ID3D11Buffer * vertex_buffer,
                                    guint vertex_stride,
                                    ID3D11Buffer * index_buffer,
index dc87b9b..4be0fb8 100644 (file)
@@ -734,7 +734,7 @@ gst_d3d11_window_prepare_default (GstD3D11Window * window, guint display_width,
   /* configure shader even if video processor is available for fallback */
   window->converter =
       gst_d3d11_converter_new (window->device, &window->info,
-      &window->render_info);
+      &window->render_info, nullptr);
 
   if (!window->converter) {
     GST_ERROR_OBJECT (window, "Cannot create converter");
index f3dc4f5..8fd013e 100644 (file)
@@ -176,7 +176,7 @@ gst_d3d11_window_dummy_prepare (GstD3D11Window * window,
 
   window->converter =
       gst_d3d11_converter_new (window->device, &window->info,
-      &window->render_info);
+      &window->render_info, nullptr);
 
   if (!window->converter) {
     GST_ERROR_OBJECT (window, "Cannot create converter");