From 6fcb5f6ae760672aafc6f6415609e4494f6988ad Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Sun, 23 Jun 2024 22:13:32 +0900 Subject: [PATCH] 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: --- .../gst-libs/gst/d3d12/gstd3d12-private.h | 7 +- .../gst/d3d12/gstd3d12converter-pack.cpp | 21 ++- .../gst/d3d12/gstd3d12converter-unpack.cpp | 15 ++ .../gst-libs/gst/d3d12/gstd3d12device.cpp | 20 ++- .../converter-hlsl/PSMain_converter.hlsl | 144 ++++++++++++++++++ .../gst/d3dshader/gstd3dshadercache.cpp | 20 +++ 6 files changed, 221 insertions(+), 6 deletions(-) diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12-private.h b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12-private.h index f47ad5c542..674e7d10d4 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12-private.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12-private.h @@ -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 " }" diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12converter-pack.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12converter-pack.cpp index fa013f69ee..cbdaccbd1a 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12converter-pack.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12converter-pack.cpp @@ -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; } diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12converter-unpack.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12converter-unpack.cpp index 5f04cbe41b..15dc873a81 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12converter-unpack.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12converter-unpack.cpp @@ -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; } diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device.cpp index df3578b5a4..826ed17849 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device.cpp @@ -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* */ diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3dshader/converter-hlsl/PSMain_converter.hlsl b/subprojects/gst-plugins-bad/gst-libs/gst/d3dshader/converter-hlsl/PSMain_converter.hlsl index 8cec5a08a6..c7d9daf895 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3dshader/converter-hlsl/PSMain_converter.hlsl +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3dshader/converter-hlsl/PSMain_converter.hlsl @@ -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" diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3dshader/gstd3dshadercache.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3dshader/gstd3dshadercache.cpp index a739811a47..babdc70229 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3dshader/gstd3dshadercache.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3dshader/gstd3dshadercache.cpp @@ -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;