d3d12: Add RGB{16,15} and BGR{16,15} format support

d3d12 device can support B5G6R5_UNORM and B5G5R5A1_UNORM formats
in pixel shader. If the format is not supported by device,
U16_UINT format with compute shader will be used, like d3d11converter

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7092>
This commit is contained in:
Seungha Yang 2024-06-23 22:13:32 +09:00
parent 94bb9fec58
commit 6fcb5f6ae7
6 changed files with 221 additions and 6 deletions

View file

@ -53,9 +53,14 @@
"I422_10LE, I420_10LE, Y444, BGRP, GBR, RGBP, xBGR, xRGB, Y42B, NV21, " \
"I420, YV12, GRAY16_LE, GRAY8"
/* pre/post processing required formats */
#define GST_D3D12_TIER_LAST_FORMATS \
"RGB16, BGR16, RGB15, BGR15"
#define GST_D3D12_COMMON_FORMATS \
GST_D3D12_TIER_0_FORMATS ", " \
GST_D3D12_TIER_1_FORMATS
GST_D3D12_TIER_1_FORMATS ", " \
GST_D3D12_TIER_LAST_FORMATS
#define GST_D3D12_ALL_FORMATS \
"{ " GST_D3D12_COMMON_FORMATS " }"

View file

@ -162,13 +162,26 @@ gst_d3d12_pack_new (GstD3D12Device * device,
conv_format = GST_VIDEO_FORMAT_AYUV64;
break;
case GST_VIDEO_FORMAT_BGR10A2_LE:
gst_video_info_set_format (&priv->in_info, GST_VIDEO_FORMAT_RGB10A2_LE,
converter_output_info->width, converter_output_info->height);
conv_format = GST_VIDEO_FORMAT_RGB10A2_LE;
break;
case GST_VIDEO_FORMAT_BGRA64_LE:
gst_video_info_set_format (&priv->in_info, GST_VIDEO_FORMAT_RGBA64_LE,
converter_output_info->width, converter_output_info->height);
conv_format = GST_VIDEO_FORMAT_RGBA64_LE;
break;
case GST_VIDEO_FORMAT_RGB16:
case GST_VIDEO_FORMAT_BGR16:
case GST_VIDEO_FORMAT_RGB15:
case GST_VIDEO_FORMAT_BGR15:
{
GstD3D12Format device_format;
gst_d3d12_device_get_format (device, format, &device_format);
if (device_format.dxgi_format == DXGI_FORMAT_R16_UINT) {
conv_format = GST_VIDEO_FORMAT_RGBA;
} else {
/* Device supports this format */
return self;
}
break;
}
default:
return self;
}

View file

@ -168,6 +168,21 @@ gst_d3d12_unpack_new (GstD3D12Device * device,
case GST_VIDEO_FORMAT_Y216_LE:
conv_format = GST_VIDEO_FORMAT_AYUV64;
break;
case GST_VIDEO_FORMAT_RGB16:
case GST_VIDEO_FORMAT_BGR16:
case GST_VIDEO_FORMAT_RGB15:
case GST_VIDEO_FORMAT_BGR15:
{
GstD3D12Format device_format;
gst_d3d12_device_get_format (device, format, &device_format);
if (device_format.dxgi_format == DXGI_FORMAT_R16_UINT) {
conv_format = GST_VIDEO_FORMAT_RGBA;
} else {
/* Device supports this format */
return self;
}
break;
}
default:
return self;
}

View file

@ -801,6 +801,18 @@ gst_d3d12_device_setup_format_table (GstD3D12Device * self)
if (SUCCEEDED (hr) && (support1 & format.support1) == format.support1 &&
(support2 & format.support2) == format.support2) {
supported = true;
} else if (dxgi_format == DXGI_FORMAT_B5G6R5_UNORM ||
dxgi_format == DXGI_FORMAT_B5G5R5A1_UNORM) {
/* This format may not be supported by old OS. Use R16_UINT
* with compute shader */
format.dxgi_format = DXGI_FORMAT_R16_UINT;
format.format_flags = GST_D3D12_FORMAT_FLAG_OUTPUT_UAV;
fs.FormatSupport (DXGI_FORMAT_R16_UINT, support1, support2);
format.support1 = support1;
format.support2 = support2;
format.resource_format[0] = DXGI_FORMAT_R16_UINT;
format.uav_format[0] = DXGI_FORMAT_R16_UINT;
supported = true;
} else {
format.dxgi_format = DXGI_FORMAT_UNKNOWN;
}
@ -1156,7 +1168,13 @@ gst_d3d12_device_new_internal (const GstD3D12DeviceConstructData * data)
D3D12_FORMAT_SUPPORT1_TEXTURE2D | D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE |
D3D12_FORMAT_SUPPORT1_RENDER_TARGET,
D3D12_FORMAT_SUPPORT2_NONE
}
},
{ DXGI_FORMAT_R16_UINT,
D3D12_FORMAT_SUPPORT1_TEXTURE2D |
D3D12_FORMAT_SUPPORT1_TYPED_UNORDERED_ACCESS_VIEW |
D3D12_FORMAT_SUPPORT1_SHADER_LOAD,
D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE
},
};
/* *INDENT-ON* */

View file

@ -515,6 +515,38 @@ class SamplerRBGAPremul : ISampler
}
};
class SamplerRGB16 : ISampler
{
float4 Execute (float2 uv)
{
return float4 (shaderTexture_0.Sample(samplerState, uv).rgb, 1.0);
}
};
class SamplerBGR16 : ISampler
{
float4 Execute (float2 uv)
{
return float4 (shaderTexture_0.Sample(samplerState, uv).bgr, 1.0);
}
};
class SamplerRGB15 : ISampler
{
float4 Execute (float2 uv)
{
return float4 (shaderTexture_0.Sample(samplerState, uv).rgb, 1.0);
}
};
class SamplerBGR15 : ISampler
{
float4 Execute (float2 uv)
{
return float4 (shaderTexture_0.Sample(samplerState, uv).bgr, 1.0);
}
};
interface IConverter
{
float4 Execute (float4 sample);
@ -1131,6 +1163,46 @@ class OutputRBGAPremul : IOutputPacked
}
};
class OutputRGB16 : IOutputPacked
{
PS_OUTPUT_PACKED Build (float4 sample)
{
PS_OUTPUT_PACKED output;
output.Plane0 = float4 (sample.rgb, 1.0);
return output;
}
};
class OutputBGR16 : IOutputPacked
{
PS_OUTPUT_PACKED Build (float4 sample)
{
PS_OUTPUT_PACKED output;
output.Plane0 = float4 (sample.bgr, 1.0);
return output;
}
};
class OutputRGB15 : IOutputPacked
{
PS_OUTPUT_PACKED Build (float4 sample)
{
PS_OUTPUT_PACKED output;
output.Plane0 = float4 (sample.rgb, 1.0);
return output;
}
};
class OutputBGR15 : IOutputPacked
{
PS_OUTPUT_PACKED Build (float4 sample)
{
PS_OUTPUT_PACKED output;
output.Plane0 = float4 (sample.bgr, 1.0);
return output;
}
};
OUTPUT_TYPE ENTRY_POINT (PS_INPUT input)
{
SAMPLER g_sampler;
@ -1637,6 +1709,38 @@ static const char str_PSMain_converter[] =
" }\n"
"};\n"
"\n"
"class SamplerRGB16 : ISampler\n"
"{\n"
" float4 Execute (float2 uv)\n"
" {\n"
" return float4 (shaderTexture_0.Sample(samplerState, uv).rgb, 1.0);\n"
" }\n"
"};\n"
"\n"
"class SamplerBGR16 : ISampler\n"
"{\n"
" float4 Execute (float2 uv)\n"
" {\n"
" return float4 (shaderTexture_0.Sample(samplerState, uv).bgr, 1.0);\n"
" }\n"
"};\n"
"\n"
"class SamplerRGB15 : ISampler\n"
"{\n"
" float4 Execute (float2 uv)\n"
" {\n"
" return float4 (shaderTexture_0.Sample(samplerState, uv).rgb, 1.0);\n"
" }\n"
"};\n"
"\n"
"class SamplerBGR15 : ISampler\n"
"{\n"
" float4 Execute (float2 uv)\n"
" {\n"
" return float4 (shaderTexture_0.Sample(samplerState, uv).bgr, 1.0);\n"
" }\n"
"};\n"
"\n"
"interface IConverter\n"
"{\n"
" float4 Execute (float4 sample);\n"
@ -2253,6 +2357,46 @@ static const char str_PSMain_converter[] =
" }\n"
"};\n"
"\n"
"class OutputRGB16 : IOutputPacked\n"
"{\n"
" PS_OUTPUT_PACKED Build (float4 sample)\n"
" {\n"
" PS_OUTPUT_PACKED output;\n"
" output.Plane0 = float4 (sample.rgb, 1.0);\n"
" return output;\n"
" }\n"
"};\n"
"\n"
"class OutputBGR16 : IOutputPacked\n"
"{\n"
" PS_OUTPUT_PACKED Build (float4 sample)\n"
" {\n"
" PS_OUTPUT_PACKED output;\n"
" output.Plane0 = float4 (sample.bgr, 1.0);\n"
" return output;\n"
" }\n"
"};\n"
"\n"
"class OutputRGB15 : IOutputPacked\n"
"{\n"
" PS_OUTPUT_PACKED Build (float4 sample)\n"
" {\n"
" PS_OUTPUT_PACKED output;\n"
" output.Plane0 = float4 (sample.rgb, 1.0);\n"
" return output;\n"
" }\n"
"};\n"
"\n"
"class OutputBGR15 : IOutputPacked\n"
"{\n"
" PS_OUTPUT_PACKED Build (float4 sample)\n"
" {\n"
" PS_OUTPUT_PACKED output;\n"
" output.Plane0 = float4 (sample.bgr, 1.0);\n"
" return output;\n"
" }\n"
"};\n"
"\n"
"OUTPUT_TYPE ENTRY_POINT (PS_INPUT input)\n"
"{\n"
" SAMPLER g_sampler;\n"

View file

@ -708,6 +708,14 @@ conv_ps_make_input (GstVideoFormat format, gboolean premul)
if (premul)
return "RBGAPremul";
return "RBGA";
case GST_VIDEO_FORMAT_RGB16:
return "RGB16";
case GST_VIDEO_FORMAT_BGR16:
return "BGR16";
case GST_VIDEO_FORMAT_RGB15:
return "RGB15";
case GST_VIDEO_FORMAT_BGR15:
return "BGR15";
default:
g_assert_not_reached ();
break;
@ -847,6 +855,18 @@ conv_ps_make_output (GstVideoFormat format, gboolean premul)
else
ret.push_back({PS_OUTPUT::PACKED, "RBGA"});
break;
case GST_VIDEO_FORMAT_RGB16:
ret.push_back({PS_OUTPUT::PACKED, "RGB16"});
break;
case GST_VIDEO_FORMAT_BGR16:
ret.push_back({PS_OUTPUT::PACKED, "BGR16"});
break;
case GST_VIDEO_FORMAT_RGB15:
ret.push_back({PS_OUTPUT::PACKED, "RGB15"});
break;
case GST_VIDEO_FORMAT_BGR15:
ret.push_back({PS_OUTPUT::PACKED, "BGR15"});
break;
default:
g_assert_not_reached ();
break;