From cb7e454b53adad0211c2983c5c2179a3034ffce7 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Sun, 13 Feb 2022 20:32:48 +0900 Subject: [PATCH] d3d11: Reorganize format mapping table ... and handle GST <-> D3D11 format mapping in a single place to make adding format easier Part-of: --- .../gst-libs/gst/d3d11/gstd3d11_private.h | 60 ++++ .../gst-libs/gst/d3d11/gstd3d11bufferpool.cpp | 27 +- .../gst-libs/gst/d3d11/gstd3d11device.cpp | 299 +++++++----------- .../gst-libs/gst/d3d11/gstd3d11format.cpp | 237 +++++++++++--- .../gst-libs/gst/d3d11/gstd3d11format.h | 20 +- .../gst-libs/gst/d3d11/gstd3d11memory.cpp | 98 ++---- .../gst/d3d11/gstd3d11stagingbufferpool.cpp | 15 +- 7 files changed, 421 insertions(+), 335 deletions(-) diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11_private.h b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11_private.h index 0634f19ffe..f2c1904ea0 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11_private.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11_private.h @@ -25,6 +25,7 @@ #include #include #include +#include "gstd3d11format.h" G_BEGIN_DECLS @@ -45,6 +46,65 @@ void gst_d3d11_device_dxgi_debug (GstD3D11Device * device, } \ } G_STMT_END + +#define MAKE_FORMAT_MAP_YUV(g,d,r0,r1,r2,r3) \ + { GST_VIDEO_FORMAT_ ##g, DXGI_FORMAT_ ##d, \ + { DXGI_FORMAT_ ##r0, DXGI_FORMAT_ ##r1, DXGI_FORMAT_ ##r2, DXGI_FORMAT_ ##r3 }, \ + { DXGI_FORMAT_ ##r0, DXGI_FORMAT_ ##r1, DXGI_FORMAT_ ##r2, DXGI_FORMAT_ ##r3 }, \ + (D3D11_FORMAT_SUPPORT) (D3D11_FORMAT_SUPPORT_RENDER_TARGET | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE) } + +#define MAKE_FORMAT_MAP_YUV_FULL(g,d,r0,r1,r2,r3,f) \ + { GST_VIDEO_FORMAT_ ##g, DXGI_FORMAT_ ##d, \ + { DXGI_FORMAT_ ##r0, DXGI_FORMAT_ ##r1, DXGI_FORMAT_ ##r2, DXGI_FORMAT_ ##r3 }, \ + { DXGI_FORMAT_ ##r0, DXGI_FORMAT_ ##r1, DXGI_FORMAT_ ##r2, DXGI_FORMAT_ ##r3 }, \ + (D3D11_FORMAT_SUPPORT) (f) } + +#define MAKE_FORMAT_MAP_RGB(g,d) \ + { GST_VIDEO_FORMAT_ ##g, DXGI_FORMAT_ ##d, \ + { DXGI_FORMAT_ ##d, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, \ + { DXGI_FORMAT_ ##d, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, \ + (D3D11_FORMAT_SUPPORT) (D3D11_FORMAT_SUPPORT_RENDER_TARGET | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE) } + +static const GstD3D11Format _gst_d3d11_default_format_map[] = { + MAKE_FORMAT_MAP_RGB (BGRA, B8G8R8A8_UNORM), + MAKE_FORMAT_MAP_RGB (RGBA, R8G8B8A8_UNORM), + MAKE_FORMAT_MAP_RGB (BGRx, B8G8R8A8_UNORM), + MAKE_FORMAT_MAP_RGB (RGBx, R8G8B8A8_UNORM), + MAKE_FORMAT_MAP_RGB (RGB10A2_LE, R10G10B10A2_UNORM), + MAKE_FORMAT_MAP_YUV (VUYA, AYUV, R8G8B8A8_UNORM, UNKNOWN, UNKNOWN, UNKNOWN), + MAKE_FORMAT_MAP_YUV (NV12, NV12, R8_UNORM, R8G8_UNORM, UNKNOWN, UNKNOWN), + MAKE_FORMAT_MAP_YUV (NV21, UNKNOWN, R8_UNORM, R8G8_UNORM, UNKNOWN, UNKNOWN), + MAKE_FORMAT_MAP_YUV (P010_10LE, P010, R16_UNORM, R16G16_UNORM, UNKNOWN, UNKNOWN), + MAKE_FORMAT_MAP_YUV (P012_LE, P016, R16_UNORM, R16G16_UNORM, UNKNOWN, UNKNOWN), + MAKE_FORMAT_MAP_YUV (P016_LE, P016, R16_UNORM, R16G16_UNORM, UNKNOWN, UNKNOWN), + MAKE_FORMAT_MAP_YUV (I420, UNKNOWN, R8_UNORM, R8_UNORM, R8_UNORM, UNKNOWN), + MAKE_FORMAT_MAP_YUV (YV12, UNKNOWN, R8_UNORM, R8_UNORM, R8_UNORM, UNKNOWN), + MAKE_FORMAT_MAP_YUV (I420_10LE, UNKNOWN, R16_UNORM, R16_UNORM, R16_UNORM, UNKNOWN), + MAKE_FORMAT_MAP_YUV (I420_12LE, UNKNOWN, R16_UNORM, R16_UNORM, R16_UNORM, UNKNOWN), + MAKE_FORMAT_MAP_YUV (Y42B, UNKNOWN, R8_UNORM, R8_UNORM, R8_UNORM, UNKNOWN), + MAKE_FORMAT_MAP_YUV (I422_10LE, UNKNOWN, R16_UNORM, R16_UNORM, R16_UNORM, UNKNOWN), + MAKE_FORMAT_MAP_YUV (I422_12LE, UNKNOWN, R16_UNORM, R16_UNORM, R16_UNORM, UNKNOWN), + MAKE_FORMAT_MAP_YUV (Y444, UNKNOWN, R8_UNORM, R8_UNORM, R8_UNORM, UNKNOWN), + MAKE_FORMAT_MAP_YUV (Y444_10LE, UNKNOWN, R16_UNORM, R16_UNORM, R16_UNORM, UNKNOWN), + MAKE_FORMAT_MAP_YUV (Y444_12LE, UNKNOWN, R16_UNORM, R16_UNORM, R16_UNORM, UNKNOWN), + MAKE_FORMAT_MAP_YUV (Y444_16LE, UNKNOWN, R16_UNORM, R16_UNORM, R16_UNORM, UNKNOWN), + /* GRAY */ + /* NOTE: To support conversion by using video processor, + * mark DXGI_FORMAT_{R8,R16}_UNORM formats as known dxgi_format. + * Otherwise, d3d11 elements will not try to use video processor for + * those formats */ + MAKE_FORMAT_MAP_RGB (GRAY8, R8_UNORM), + MAKE_FORMAT_MAP_RGB (GRAY16_LE, R16_UNORM), + MAKE_FORMAT_MAP_YUV_FULL (Y410, Y410, R10G10B10A2_UNORM, UNKNOWN, UNKNOWN, UNKNOWN, + D3D11_FORMAT_SUPPORT_SHADER_SAMPLE), +}; + +#undef MAKE_FORMAT_MAP_YUV +#undef MAKE_FORMAT_MAP_YUV_FULL +#undef MAKE_FORMAT_MAP_RGB + +#define GST_D3D11_N_FORMATS G_N_ELEMENTS(_gst_d3d11_default_format_map) + G_END_DECLS #endif /* __GST_D3D11_PRIVATE_H__ */ diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11bufferpool.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11bufferpool.cpp index 91d64a98bc..eb216089db 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11bufferpool.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11bufferpool.cpp @@ -147,6 +147,7 @@ gst_d3d11_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) D3D11_TEXTURE2D_DESC *desc; const GstD3D11Format *format; gsize offset = 0; + guint align = 0; gint i; if (!gst_buffer_pool_config_get_params (config, &caps, NULL, &min_buffers, @@ -180,26 +181,24 @@ gst_d3d11_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) } desc = priv->d3d11_params->desc; + align = gst_d3d11_dxgi_format_get_alignment (desc[0].Format); /* resolution of semi-planar formats must be multiple of 2 */ - if (desc[0].Format == DXGI_FORMAT_NV12 || desc[0].Format == DXGI_FORMAT_P010 - || desc[0].Format == DXGI_FORMAT_P016) { - if (desc[0].Width % 2 || desc[0].Height % 2) { - gint width, height; - GstVideoAlignment align; + if (align != 0 && (desc[0].Width % align || desc[0].Height % align)) { + gint width, height; + GstVideoAlignment video_align; - GST_WARNING_OBJECT (self, "Resolution %dx%d is not mutiple of 2, fixing", - desc[0].Width, desc[0].Height); + GST_WARNING_OBJECT (self, "Resolution %dx%d is not mutiple of %d, fixing", + desc[0].Width, desc[0].Height, align); - width = GST_ROUND_UP_2 (desc[0].Width); - height = GST_ROUND_UP_2 (desc[0].Height); + width = GST_ROUND_UP_N (desc[0].Width, align); + height = GST_ROUND_UP_N (desc[0].Height, align); - gst_video_alignment_reset (&align); - align.padding_right = width - desc[0].Width; - align.padding_bottom = height - desc[0].Height; + gst_video_alignment_reset (&video_align); + video_align.padding_right = width - desc[0].Width; + video_align.padding_bottom = height - desc[0].Height; - gst_d3d11_allocation_params_alignment (priv->d3d11_params, &align); - } + gst_d3d11_allocation_params_alignment (priv->d3d11_params, &video_align); } #ifndef GST_DISABLE_GST_DEBUG { diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11device.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11device.cpp index 35525e8278..3b4c57f85d 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11device.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11device.cpp @@ -94,8 +94,6 @@ enum #define DEFAULT_ADAPTER 0 #define DEFAULT_CREATE_FLAGS 0 -#define GST_D3D11_N_FORMATS 25 - struct _GstD3D11DevicePrivate { guint adapter; @@ -464,79 +462,141 @@ can_support_format (GstD3D11Device * self, DXGI_FORMAT format, HRESULT hr; UINT supported; D3D11_FORMAT_SUPPORT flags = D3D11_FORMAT_SUPPORT_TEXTURE2D; + const gchar *format_name = gst_d3d11_dxgi_format_to_string (format); flags |= extra_flags; if (!is_windows_8_or_greater ()) { - GST_INFO_OBJECT (self, "DXGI format %d needs Windows 8 or greater", - (guint) format); + GST_INFO_OBJECT (self, "DXGI_FORMAT_%s (%d) needs Windows 8 or greater", + format_name, (guint) format); return FALSE; } hr = handle->CheckFormatSupport (format, &supported); if (FAILED (hr)) { - GST_DEBUG_OBJECT (self, "DXGI format %d is not supported by device", - (guint) format); + GST_DEBUG_OBJECT (self, "DXGI_FORMAT_%s (%d) is not supported by device", + format_name, (guint) format); return FALSE; } if ((supported & flags) != flags) { GST_DEBUG_OBJECT (self, - "DXGI format %d doesn't support flag 0x%x (supported flag 0x%x)", - (guint) format, (guint) supported, (guint) flags); + "DXGI_FORMAT_%s (%d) doesn't support flag 0x%x (supported flag 0x%x)", + format_name, (guint) format, (guint) supported, (guint) flags); return FALSE; } - GST_INFO_OBJECT (self, "Device supports DXGI format %d", (guint) format); + GST_INFO_OBJECT (self, "Device supports DXGI_FORMAT_%s (%d)", + format_name, (guint) format); return TRUE; } +static void +update_format_support_flag (GstD3D11Device * self, GstD3D11Format * format) +{ + GstD3D11DevicePrivate *priv = self->priv; + ID3D11Device *handle = priv->device; + HRESULT hr; + UINT supported; + DXGI_FORMAT dxgi_format; + + if (format->dxgi_format != DXGI_FORMAT_UNKNOWN) + dxgi_format = format->dxgi_format; + else + dxgi_format = format->resource_format[0]; + + hr = handle->CheckFormatSupport (dxgi_format, &supported); + if (FAILED (hr)) { + GST_DEBUG_OBJECT (self, "DXGI_FORMAT_%s (%d) is not supported by device", + gst_d3d11_dxgi_format_to_string (dxgi_format), (guint) dxgi_format); + return; + } + + format->support_flags = (D3D11_FORMAT_SUPPORT) supported; +} + +static void +dump_format (GstD3D11Device * self, GstD3D11Format * format) +{ + GST_LOG_OBJECT (self, "%s -> DXGI_FORMAT_%s (%d), " + "resource format: %s (%d), %s (%d), %s (%d), %s (%d), flags 0x%x", + gst_video_format_to_string (format->format), + gst_d3d11_dxgi_format_to_string (format->dxgi_format), + format->dxgi_format, + gst_d3d11_dxgi_format_to_string (format->resource_format[0]), + format->resource_format[0], + gst_d3d11_dxgi_format_to_string (format->resource_format[1]), + format->resource_format[1], + gst_d3d11_dxgi_format_to_string (format->resource_format[2]), + format->resource_format[2], + gst_d3d11_dxgi_format_to_string (format->resource_format[3]), + format->resource_format[3], (guint) format->support_flags); +} + static void gst_d3d11_device_setup_format_table (GstD3D11Device * self) { GstD3D11DevicePrivate *priv = self->priv; - guint n_formats = 0; - /* RGB formats */ - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_BGRA; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_B8G8R8A8_UNORM; - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_B8G8R8A8_UNORM; - n_formats++; + for (guint i = 0; i < G_N_ELEMENTS (priv->format_table); i++) { + GstD3D11Format *format = &priv->format_table[i]; - /* Identical to BGRA, but alpha will be ignored */ - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_BGRx; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_B8G8R8A8_UNORM; - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_B8G8R8A8_UNORM; - n_formats++; + *format = _gst_d3d11_default_format_map[i]; - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_RGBA; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R8G8B8A8_UNORM; - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_R8G8B8A8_UNORM; - n_formats++; + switch (format->format) { + /* RGB */ + case GST_VIDEO_FORMAT_BGRA: + case GST_VIDEO_FORMAT_BGRx: + case GST_VIDEO_FORMAT_RGBA: + case GST_VIDEO_FORMAT_RGBx: + case GST_VIDEO_FORMAT_RGB10A2_LE: + g_assert (format->dxgi_format != DXGI_FORMAT_UNKNOWN); + update_format_support_flag (self, format); + break; + /* YUV DXGI native formats */ + case GST_VIDEO_FORMAT_VUYA: + case GST_VIDEO_FORMAT_Y410: + case GST_VIDEO_FORMAT_NV12: + case GST_VIDEO_FORMAT_P010_10LE: + case GST_VIDEO_FORMAT_P012_LE: + case GST_VIDEO_FORMAT_P016_LE: + if (!can_support_format (self, + format->dxgi_format, format->support_flags)) { + format->dxgi_format = DXGI_FORMAT_UNKNOWN; + } + update_format_support_flag (self, format); + break; + /* YUV non-DXGI native formats */ + case GST_VIDEO_FORMAT_NV21: + case GST_VIDEO_FORMAT_I420: + case GST_VIDEO_FORMAT_YV12: + case GST_VIDEO_FORMAT_I420_10LE: + case GST_VIDEO_FORMAT_I420_12LE: + case GST_VIDEO_FORMAT_Y42B: + case GST_VIDEO_FORMAT_I422_10LE: + case GST_VIDEO_FORMAT_I422_12LE: + case GST_VIDEO_FORMAT_Y444: + case GST_VIDEO_FORMAT_Y444_10LE: + case GST_VIDEO_FORMAT_Y444_12LE: + case GST_VIDEO_FORMAT_Y444_16LE: + { + g_assert (format->dxgi_format == DXGI_FORMAT_UNKNOWN); + update_format_support_flag (self, format); + break; + } + case GST_VIDEO_FORMAT_GRAY8: + case GST_VIDEO_FORMAT_GRAY16_LE: + g_assert (format->dxgi_format != DXGI_FORMAT_UNKNOWN); + update_format_support_flag (self, format); + break; + default: + g_assert_not_reached (); + break; + } - /* Identical to RGBA, but alpha will be ignored */ - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_RGBx; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R8G8B8A8_UNORM; - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_R8G8B8A8_UNORM; - n_formats++; - - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_RGB10A2_LE; - priv->format_table[n_formats].resource_format[0] = - DXGI_FORMAT_R10G10B10A2_UNORM; - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_R10G10B10A2_UNORM; - n_formats++; - - /* YUV packed */ - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_VUYA; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R8G8B8A8_UNORM; - if (can_support_format (self, DXGI_FORMAT_AYUV, - D3D11_FORMAT_SUPPORT_RENDER_TARGET | - D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_AYUV; - else - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_UNKNOWN; - n_formats++; + dump_format (self, format); + } /* FIXME: d3d11 sampler doesn't support packed-and-subsampled formats * very well (and it's really poorly documented). @@ -592,153 +652,6 @@ gst_d3d11_device_setup_format_table (GstD3D11Device * self) priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_UNKNOWN; n_formats++; #endif - - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_Y410; - priv->format_table[n_formats].resource_format[0] = - DXGI_FORMAT_R10G10B10A2_UNORM; - if (can_support_format (self, DXGI_FORMAT_Y410, - D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_Y410; - else - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_UNKNOWN; - n_formats++; - - /* YUV semi-planar */ - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_NV12; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R8_UNORM; - priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R8G8_UNORM; - if (can_support_format (self, DXGI_FORMAT_NV12, - D3D11_FORMAT_SUPPORT_RENDER_TARGET | - D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_NV12; - else - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_UNKNOWN; - n_formats++; - - /* no native format for NV21 */ - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_NV21; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R8_UNORM; - priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R8G8_UNORM; - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_UNKNOWN; - n_formats++; - - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_P010_10LE; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM; - priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R16G16_UNORM; - if (can_support_format (self, DXGI_FORMAT_P010, - D3D11_FORMAT_SUPPORT_RENDER_TARGET | - D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_P010; - else - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_UNKNOWN; - n_formats++; - - /* P012 is identical to P016 from runtime point of view */ - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_P012_LE; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM; - priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R16G16_UNORM; - if (can_support_format (self, DXGI_FORMAT_P016, - D3D11_FORMAT_SUPPORT_RENDER_TARGET | - D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_P016; - else - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_UNKNOWN; - n_formats++; - - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_P016_LE; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM; - priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R16G16_UNORM; - if (can_support_format (self, DXGI_FORMAT_P016, - D3D11_FORMAT_SUPPORT_RENDER_TARGET | - D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_P016; - else - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_UNKNOWN; - n_formats++; - - /* YUV planar */ - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_I420; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R8_UNORM; - priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R8_UNORM; - priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R8_UNORM; - n_formats++; - - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_YV12; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R8_UNORM; - priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R8_UNORM; - priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R8_UNORM; - n_formats++; - - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_I420_10LE; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM; - priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R16_UNORM; - priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R16_UNORM; - n_formats++; - - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_I420_12LE; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM; - priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R16_UNORM; - priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R16_UNORM; - n_formats++; - - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_Y42B; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R8_UNORM; - priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R8_UNORM; - priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R8_UNORM; - n_formats++; - - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_I422_10LE; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM; - priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R16_UNORM; - priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R16_UNORM; - n_formats++; - - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_I422_12LE; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM; - priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R16_UNORM; - priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R16_UNORM; - n_formats++; - - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_Y444; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R8_UNORM; - priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R8_UNORM; - priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R8_UNORM; - n_formats++; - - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_Y444_10LE; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM; - priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R16_UNORM; - priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R16_UNORM; - n_formats++; - - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_Y444_12LE; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM; - priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R16_UNORM; - priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R16_UNORM; - n_formats++; - - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_Y444_16LE; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM; - priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R16_UNORM; - priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R16_UNORM; - n_formats++; - - /* GRAY */ - /* NOTE: To support conversion by using video processor, - * mark DXGI_FORMAT_{R8,R16}_UNORM formats as known dxgi_format. - * Otherwise, d3d11 elements will not try to use video processor for - * those formats */ - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_GRAY8; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R8_UNORM; - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_R8_UNORM; - n_formats++; - - priv->format_table[n_formats].format = GST_VIDEO_FORMAT_GRAY16_LE; - priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM; - priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_R16_UNORM; - n_formats++; - - g_assert (n_formats == GST_D3D11_N_FORMATS); } static void diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11format.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11format.cpp index 538b0ea4f8..7d8ed7dcdd 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11format.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11format.cpp @@ -51,44 +51,6 @@ ensure_debug_category (void) #define ensure_debug_category() /* NOOP */ #endif /* GST_DISABLE_GST_DEBUG */ -/** - * gst_d3d11_dxgi_format_n_planes: - * @format: a DXGI_FORMAT - * - * Returns: the number of planes for @format - * - * Since: 1.20 - */ -guint -gst_d3d11_dxgi_format_n_planes (DXGI_FORMAT format) -{ - switch (format) { - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R10G10B10A2_UNORM: - case DXGI_FORMAT_AYUV: - case DXGI_FORMAT_YUY2: - case DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_R16G16_UNORM: - case DXGI_FORMAT_G8R8_G8B8_UNORM: - case DXGI_FORMAT_R8G8_B8G8_UNORM: - case DXGI_FORMAT_Y210: - case DXGI_FORMAT_Y410: - case DXGI_FORMAT_R16G16B16A16_UNORM: - return 1; - case DXGI_FORMAT_NV12: - case DXGI_FORMAT_P010: - case DXGI_FORMAT_P016: - return 2; - default: - break; - } - - return 0; -} - /** * gst_d3d11_dxgi_format_get_size: * @format: a DXGI_FORMAT @@ -208,3 +170,202 @@ gst_d3d11_format_init (GstD3D11Format * format) memset (format, 0, sizeof (GstD3D11Format)); } + +/** + * gst_d3d11_dxgi_format_get_resource_format: + * @format: a DXGI_FORMAT + * @resource_format: (out caller-allocats): Resource formats for each plane + * + * Returns: the number of planes for @format + * + * Since: 1.22 + */ +guint +gst_d3d11_dxgi_format_get_resource_format (DXGI_FORMAT format, + DXGI_FORMAT resource_format[GST_VIDEO_MAX_PLANES]) +{ + for (guint i = 0; i < GST_VIDEO_MAX_PLANES; i++) + resource_format[i] = DXGI_FORMAT_UNKNOWN; + + if (format == DXGI_FORMAT_UNKNOWN) + return 0; + + for (guint i = 0; i < GST_D3D11_N_FORMATS; i++) { + const GstD3D11Format *fmt = &_gst_d3d11_default_format_map[i]; + + if (fmt->dxgi_format == format) { + guint n_planes = 0; + + for (n_planes = 0; n_planes < GST_VIDEO_MAX_PLANES; n_planes++) { + if (fmt->resource_format[n_planes] == DXGI_FORMAT_UNKNOWN) + break; + + resource_format[n_planes] = fmt->resource_format[n_planes]; + } + + return n_planes; + } + } + + resource_format[0] = format; + return 1; +} + +/** + * gst_d3d11_dxgi_format_get_alignment: + * @format: a DXGI_FORMAT + * + * Returns: Width and height Alignment requirement for given @format + * + * Since: 1.22 + */ +guint +gst_d3d11_dxgi_format_get_alignment (DXGI_FORMAT format) +{ + switch (format) { + case DXGI_FORMAT_NV12: + case DXGI_FORMAT_P010: + case DXGI_FORMAT_P016: + return 2; + default: + break; + } + + return 0; +} + +const gchar * +gst_d3d11_dxgi_format_to_string (DXGI_FORMAT format) +{ +#define CASE(f) \ + case DXGI_FORMAT_ ##f: \ + return G_STRINGIFY (f); + + switch (format) { + CASE (UNKNOWN); + CASE (R32G32B32A32_TYPELESS); + CASE (R32G32B32A32_FLOAT); + CASE (R32G32B32A32_UINT); + CASE (R32G32B32A32_SINT); + CASE (R32G32B32_TYPELESS); + CASE (R32G32B32_FLOAT); + CASE (R32G32B32_UINT); + CASE (R32G32B32_SINT); + CASE (R16G16B16A16_TYPELESS); + CASE (R16G16B16A16_FLOAT); + CASE (R16G16B16A16_UNORM); + CASE (R16G16B16A16_UINT); + CASE (R16G16B16A16_SNORM); + CASE (R16G16B16A16_SINT); + CASE (R32G32_TYPELESS); + CASE (R32G32_FLOAT); + CASE (R32G32_UINT); + CASE (R32G32_SINT); + CASE (R32G8X24_TYPELESS); + CASE (D32_FLOAT_S8X24_UINT); + CASE (R32_FLOAT_X8X24_TYPELESS); + CASE (X32_TYPELESS_G8X24_UINT); + CASE (R10G10B10A2_TYPELESS); + CASE (R10G10B10A2_UNORM); + CASE (R10G10B10A2_UINT); + CASE (R11G11B10_FLOAT); + CASE (R8G8B8A8_TYPELESS); + CASE (R8G8B8A8_UNORM); + CASE (R8G8B8A8_UNORM_SRGB); + CASE (R8G8B8A8_UINT); + CASE (R8G8B8A8_SNORM); + CASE (R8G8B8A8_SINT); + CASE (R16G16_TYPELESS); + CASE (R16G16_FLOAT); + CASE (R16G16_UNORM); + CASE (R16G16_UINT); + CASE (R16G16_SNORM); + CASE (R16G16_SINT); + CASE (R32_TYPELESS); + CASE (D32_FLOAT); + CASE (R32_FLOAT); + CASE (R32_UINT); + CASE (R32_SINT); + CASE (R24G8_TYPELESS); + CASE (D24_UNORM_S8_UINT); + CASE (R24_UNORM_X8_TYPELESS); + CASE (X24_TYPELESS_G8_UINT); + CASE (R8G8_TYPELESS); + CASE (R8G8_UNORM); + CASE (R8G8_UINT); + CASE (R8G8_SNORM); + CASE (R8G8_SINT); + CASE (R16_TYPELESS); + CASE (R16_FLOAT); + CASE (D16_UNORM); + CASE (R16_UNORM); + CASE (R16_UINT); + CASE (R16_SNORM); + CASE (R16_SINT); + CASE (R8_TYPELESS); + CASE (R8_UNORM); + CASE (R8_UINT); + CASE (R8_SNORM); + CASE (R8_SINT); + CASE (A8_UNORM); + CASE (R1_UNORM); + CASE (R9G9B9E5_SHAREDEXP); + CASE (R8G8_B8G8_UNORM); + CASE (G8R8_G8B8_UNORM); + CASE (BC1_TYPELESS); + CASE (BC1_UNORM); + CASE (BC1_UNORM_SRGB); + CASE (BC2_TYPELESS); + CASE (BC2_UNORM); + CASE (BC2_UNORM_SRGB); + CASE (BC3_TYPELESS); + CASE (BC3_UNORM); + CASE (BC3_UNORM_SRGB); + CASE (BC4_TYPELESS); + CASE (BC4_UNORM); + CASE (BC4_SNORM); + CASE (BC5_TYPELESS); + CASE (BC5_UNORM); + CASE (BC5_SNORM); + CASE (B5G6R5_UNORM); + CASE (B5G5R5A1_UNORM); + CASE (B8G8R8A8_UNORM); + CASE (B8G8R8X8_UNORM); + CASE (R10G10B10_XR_BIAS_A2_UNORM); + CASE (B8G8R8A8_TYPELESS); + CASE (B8G8R8A8_UNORM_SRGB); + CASE (B8G8R8X8_TYPELESS); + CASE (B8G8R8X8_UNORM_SRGB); + CASE (BC6H_TYPELESS); + CASE (BC6H_UF16); + CASE (BC6H_SF16); + CASE (BC7_TYPELESS); + CASE (BC7_UNORM); + CASE (BC7_UNORM_SRGB); + CASE (AYUV); + CASE (Y410); + CASE (Y416); + CASE (NV12); + CASE (P010); + CASE (P016); + case DXGI_FORMAT_420_OPAQUE: + return "420_OPAQUE"; + CASE (YUY2); + CASE (Y210); + CASE (Y216); + CASE (NV11); + CASE (AI44); + CASE (IA44); + CASE (P8); + CASE (A8P8); + CASE (B4G4R4A4_UNORM); + CASE (P208); + CASE (V208); + CASE (V408); + default: + break; + } +#undef CASE + + return "Unknown"; +} diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11format.h b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11format.h index 01935954e5..e2f6b4fb3e 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11format.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11format.h @@ -54,12 +54,12 @@ struct _GstD3D11Format /* formats for texture processing */ DXGI_FORMAT resource_format[GST_VIDEO_MAX_PLANES]; - /*< private >*/ - gpointer _gst_reserved[GST_PADDING]; -}; + /* extra format used for unordered access view */ + DXGI_FORMAT uav_format[GST_VIDEO_MAX_PLANES]; -GST_D3D11_API -guint gst_d3d11_dxgi_format_n_planes (DXGI_FORMAT format); + /* cached flags */ + D3D11_FORMAT_SUPPORT support_flags; +}; GST_D3D11_API gboolean gst_d3d11_dxgi_format_get_size (DXGI_FORMAT format, @@ -76,6 +76,16 @@ GstVideoFormat gst_d3d11_dxgi_format_to_gst (DXGI_FORMAT format); GST_D3D11_API void gst_d3d11_format_init (GstD3D11Format * format); +GST_D3D11_API +guint gst_d3d11_dxgi_format_get_resource_format (DXGI_FORMAT format, + DXGI_FORMAT resource_format[GST_VIDEO_MAX_PLANES]); + +GST_D3D11_API +guint gst_d3d11_dxgi_format_get_alignment (DXGI_FORMAT format); + +GST_D3D11_API +const gchar * gst_d3d11_dxgi_format_to_string (DXGI_FORMAT format); + G_END_DECLS #endif /* __GST_D3D11_FORMAT_H__ */ diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.cpp index a457373dd2..9c64da7b15 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.cpp @@ -731,51 +731,16 @@ create_shader_resource_views (GstD3D11Memory * mem) device_handle = gst_d3d11_device_get_device_handle (mem->device); - switch (priv->desc.Format) { - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R10G10B10A2_UNORM: - case DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_R16G16_UNORM: - case DXGI_FORMAT_G8R8_G8B8_UNORM: - case DXGI_FORMAT_R8G8_B8G8_UNORM: - case DXGI_FORMAT_R16G16B16A16_UNORM: - num_views = 1; - formats[0] = priv->desc.Format; - break; - case DXGI_FORMAT_AYUV: - case DXGI_FORMAT_YUY2: - num_views = 1; - formats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; - break; - case DXGI_FORMAT_NV12: - num_views = 2; - formats[0] = DXGI_FORMAT_R8_UNORM; - formats[1] = DXGI_FORMAT_R8G8_UNORM; - break; - case DXGI_FORMAT_P010: - case DXGI_FORMAT_P016: - num_views = 2; - formats[0] = DXGI_FORMAT_R16_UNORM; - formats[1] = DXGI_FORMAT_R16G16_UNORM; - break; - case DXGI_FORMAT_Y210: - num_views = 1; - formats[0] = DXGI_FORMAT_R16G16B16A16_UNORM; - break; - case DXGI_FORMAT_Y410: - num_views = 1; - formats[0] = DXGI_FORMAT_R10G10B10A2_UNORM; - break; - default: - g_assert_not_reached (); - return FALSE; + num_views = gst_d3d11_dxgi_format_get_resource_format (priv->desc.Format, + formats); + if (!num_views) { + GST_ERROR_OBJECT (GST_MEMORY_CAST (mem)->allocator, + "Unknown resource formats for DXGI format %s (%d)", + gst_d3d11_dxgi_format_to_string (priv->desc.Format), priv->desc.Format); + return FALSE; } - if ((priv->desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) == - D3D11_BIND_SHADER_RESOURCE) { + if ((priv->desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) != 0) { resource_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; resource_desc.Texture2D.MipLevels = 1; @@ -786,7 +751,9 @@ create_shader_resource_views (GstD3D11Memory * mem) if (!gst_d3d11_result (hr, mem->device)) { GST_ERROR_OBJECT (GST_MEMORY_CAST (mem)->allocator, - "Failed to create %dth resource view (0x%x)", i, (guint) hr); + "Failed to create resource DXGI format %s (%d) for plane %d" + " view (0x%x)", gst_d3d11_dxgi_format_to_string (formats[i]), + formats[i], i, (guint) hr); goto error; } } @@ -902,39 +869,16 @@ create_render_target_views (GstD3D11Memory * mem) device_handle = gst_d3d11_device_get_device_handle (mem->device); - switch (priv->desc.Format) { - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R10G10B10A2_UNORM: - case DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_R16G16_UNORM: - num_views = 1; - formats[0] = priv->desc.Format; - break; - case DXGI_FORMAT_AYUV: - num_views = 1; - formats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; - break; - case DXGI_FORMAT_NV12: - num_views = 2; - formats[0] = DXGI_FORMAT_R8_UNORM; - formats[1] = DXGI_FORMAT_R8G8_UNORM; - break; - case DXGI_FORMAT_P010: - case DXGI_FORMAT_P016: - num_views = 2; - formats[0] = DXGI_FORMAT_R16_UNORM; - formats[1] = DXGI_FORMAT_R16G16_UNORM; - break; - default: - g_assert_not_reached (); - return FALSE; + num_views = gst_d3d11_dxgi_format_get_resource_format (priv->desc.Format, + formats); + if (!num_views) { + GST_ERROR_OBJECT (GST_MEMORY_CAST (mem)->allocator, + "Unknown resource formats for DXGI format %s (%d)", + gst_d3d11_dxgi_format_to_string (priv->desc.Format), priv->desc.Format); + return FALSE; } - if ((priv->desc.BindFlags & D3D11_BIND_RENDER_TARGET) == - D3D11_BIND_RENDER_TARGET) { + if ((priv->desc.BindFlags & D3D11_BIND_RENDER_TARGET) != 0) { render_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; render_desc.Texture2D.MipSlice = 0; @@ -945,7 +889,9 @@ create_render_target_views (GstD3D11Memory * mem) &priv->render_target_view[i]); if (!gst_d3d11_result (hr, mem->device)) { GST_ERROR_OBJECT (GST_MEMORY_CAST (mem)->allocator, - "Failed to create %dth render target view (0x%x)", i, (guint) hr); + "Failed to create resource DXGI format %s (%d) for plane %d" + " view (0x%x)", gst_d3d11_dxgi_format_to_string (formats[i]), + formats[i], i, (guint) hr); goto error; } } diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11stagingbufferpool.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11stagingbufferpool.cpp index 9bab4d5192..cc8d2314d9 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11stagingbufferpool.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11stagingbufferpool.cpp @@ -169,22 +169,19 @@ gst_d3d11_staging_buffer_pool_set_config (GstBufferPool * pool, } } else { guint width, height; + guint align; desc = &priv->desc[0]; width = GST_VIDEO_INFO_WIDTH (&info); height = GST_VIDEO_INFO_HEIGHT (&info); + align = gst_d3d11_dxgi_format_get_alignment (format.dxgi_format); + /* resolution of semi-planar formats must be multiple of 2 */ - switch (format.dxgi_format) { - case DXGI_FORMAT_NV12: - case DXGI_FORMAT_P010: - case DXGI_FORMAT_P016: - width = GST_ROUND_UP_2 (width); - height = GST_ROUND_UP_2 (height); - break; - default: - break; + if (align != 0) { + width = GST_ROUND_UP_N (width, align); + height = GST_ROUND_UP_N (height, align); } desc->Width = width;