d3d11: Reorganize format mapping table

... and handle GST <-> D3D11 format mapping in a single place to
make adding format easier

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1699>
This commit is contained in:
Seungha Yang 2022-02-13 20:32:48 +09:00 committed by GStreamer Marge Bot
parent dd906f9610
commit cb7e454b53
7 changed files with 421 additions and 335 deletions

View file

@ -25,6 +25,7 @@
#include <gst/d3d11/gstd3d11_fwd.h>
#include <d3d11_4.h>
#include <dxgi1_6.h>
#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__ */

View file

@ -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
{

View file

@ -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

View file

@ -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";
}

View file

@ -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__ */

View file

@ -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;
}
}

View file

@ -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;