summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/render/direct3d12/D3D12_PixelShader_Common.hlsli
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-12-27 12:03:39 -0800
committer3gg <3gg@shellblade.net>2025-12-27 12:03:39 -0800
commit5a079a2d114f96d4847d1ee305d5b7c16eeec50e (patch)
tree8926ab44f168acf787d8e19608857b3af0f82758 /contrib/SDL-3.2.8/src/render/direct3d12/D3D12_PixelShader_Common.hlsli
Initial commit
Diffstat (limited to 'contrib/SDL-3.2.8/src/render/direct3d12/D3D12_PixelShader_Common.hlsli')
-rw-r--r--contrib/SDL-3.2.8/src/render/direct3d12/D3D12_PixelShader_Common.hlsli236
1 files changed, 236 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/render/direct3d12/D3D12_PixelShader_Common.hlsli b/contrib/SDL-3.2.8/src/render/direct3d12/D3D12_PixelShader_Common.hlsli
new file mode 100644
index 0000000..ba32e0c
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/render/direct3d12/D3D12_PixelShader_Common.hlsli
@@ -0,0 +1,236 @@
1#include "D3D12_Shader_Common.hlsli"
2
3Texture2D texture0 : register(t0);
4Texture2D texture1 : register(t1);
5Texture2D texture2 : register(t2);
6SamplerState sampler0 : register(s0);
7
8struct PixelShaderInput
9{
10 float4 pos : SV_POSITION;
11 float2 tex : TEXCOORD0;
12 float4 color : COLOR0;
13};
14
15// These should mirror the definitions in SDL_render_d3d12.c
16static const float TONEMAP_NONE = 0;
17static const float TONEMAP_LINEAR = 1;
18static const float TONEMAP_CHROME = 2;
19
20static const float TEXTURETYPE_NONE = 0;
21static const float TEXTURETYPE_RGB = 1;
22static const float TEXTURETYPE_NV12 = 2;
23static const float TEXTURETYPE_NV21 = 3;
24static const float TEXTURETYPE_YUV = 4;
25
26static const float INPUTTYPE_UNSPECIFIED = 0;
27static const float INPUTTYPE_SRGB = 1;
28static const float INPUTTYPE_SCRGB = 2;
29static const float INPUTTYPE_HDR10 = 3;
30
31cbuffer Constants : register(b1)
32{
33 float scRGB_output;
34 float texture_type;
35 float input_type;
36 float color_scale;
37
38 float tonemap_method;
39 float tonemap_factor1;
40 float tonemap_factor2;
41 float sdr_white_point;
42
43 float4 Yoffset;
44 float4 Rcoeff;
45 float4 Gcoeff;
46 float4 Bcoeff;
47};
48
49static const float3x3 mat709to2020 = {
50 { 0.627404, 0.329283, 0.043313 },
51 { 0.069097, 0.919541, 0.011362 },
52 { 0.016391, 0.088013, 0.895595 }
53};
54
55static const float3x3 mat2020to709 = {
56 { 1.660496, -0.587656, -0.072840 },
57 { -0.124547, 1.132895, -0.008348 },
58 { -0.018154, -0.100597, 1.118751 }
59};
60
61float sRGBtoLinear(float v)
62{
63 if (v <= 0.04045) {
64 v = (v / 12.92);
65 } else {
66 v = pow(abs(v + 0.055) / 1.055, 2.4);
67 }
68 return v;
69}
70
71float sRGBfromLinear(float v)
72{
73 if (v <= 0.0031308) {
74 v = (v * 12.92);
75 } else {
76 v = (pow(abs(v), 1.0 / 2.4) * 1.055 - 0.055);
77 }
78 return v;
79}
80
81float3 PQtoLinear(float3 v)
82{
83 const float c1 = 0.8359375;
84 const float c2 = 18.8515625;
85 const float c3 = 18.6875;
86 const float oo_m1 = 1.0 / 0.1593017578125;
87 const float oo_m2 = 1.0 / 78.84375;
88
89 float3 num = max(pow(abs(v), oo_m2) - c1, 0.0);
90 float3 den = c2 - c3 * pow(abs(v), oo_m2);
91 return (10000.0 * pow(abs(num / den), oo_m1) / sdr_white_point);
92}
93
94float3 ApplyTonemap(float3 v)
95{
96 if (tonemap_method == TONEMAP_LINEAR) {
97 v *= tonemap_factor1;
98 } else if (tonemap_method == TONEMAP_CHROME) {
99 if (input_type == INPUTTYPE_SCRGB) {
100 // Convert to BT.2020 colorspace for tone mapping
101 v = mul(mat709to2020, v);
102 }
103
104 float vmax = max(v.r, max(v.g, v.b));
105 if (vmax > 0.0) {
106 float scale = (1.0 + tonemap_factor1 * vmax) / (1.0 + tonemap_factor2 * vmax);
107 v *= scale;
108 }
109
110 if (input_type == INPUTTYPE_SCRGB) {
111 // Convert to BT.709 colorspace after tone mapping
112 v = mul(mat2020to709, v);
113 }
114 }
115 return v;
116}
117
118float4 GetInputColor(PixelShaderInput input)
119{
120 float4 rgba;
121
122 if (texture_type == TEXTURETYPE_NONE) {
123 rgba = 1.0;
124 } else if (texture_type == TEXTURETYPE_RGB) {
125 rgba = texture0.Sample(sampler0, input.tex);
126 } else if (texture_type == TEXTURETYPE_NV12) {
127 float3 yuv;
128 yuv.x = texture0.Sample(sampler0, input.tex).r;
129 yuv.yz = texture1.Sample(sampler0, input.tex).rg;
130
131 yuv += Yoffset.xyz;
132 rgba.r = dot(yuv, Rcoeff.xyz);
133 rgba.g = dot(yuv, Gcoeff.xyz);
134 rgba.b = dot(yuv, Bcoeff.xyz);
135 rgba.a = 1.0;
136 } else if (texture_type == TEXTURETYPE_NV21) {
137 float3 yuv;
138 yuv.x = texture0.Sample(sampler0, input.tex).r;
139 yuv.yz = texture1.Sample(sampler0, input.tex).gr;
140
141 yuv += Yoffset.xyz;
142 rgba.r = dot(yuv, Rcoeff.xyz);
143 rgba.g = dot(yuv, Gcoeff.xyz);
144 rgba.b = dot(yuv, Bcoeff.xyz);
145 rgba.a = 1.0;
146 } else if (texture_type == TEXTURETYPE_YUV) {
147 float3 yuv;
148 yuv.x = texture0.Sample(sampler0, input.tex).r;
149 yuv.y = texture1.Sample(sampler0, input.tex).r;
150 yuv.z = texture2.Sample(sampler0, input.tex).r;
151
152 yuv += Yoffset.xyz;
153 rgba.r = dot(yuv, Rcoeff.xyz);
154 rgba.g = dot(yuv, Gcoeff.xyz);
155 rgba.b = dot(yuv, Bcoeff.xyz);
156 rgba.a = 1.0;
157 } else {
158 // Error!
159 rgba.r = 1.0;
160 rgba.g = 0.0;
161 rgba.b = 0.0;
162 rgba.a = 1.0;
163 }
164 return rgba;
165}
166
167float4 GetOutputColor(float4 rgba)
168{
169 float4 output;
170
171 output.rgb = rgba.rgb * color_scale;
172 output.a = rgba.a;
173
174 return output;
175}
176
177float3 GetOutputColorFromSRGB(float3 rgb)
178{
179 float3 output;
180
181 if (scRGB_output) {
182 rgb.r = sRGBtoLinear(rgb.r);
183 rgb.g = sRGBtoLinear(rgb.g);
184 rgb.b = sRGBtoLinear(rgb.b);
185 }
186
187 output.rgb = rgb * color_scale;
188
189 return output;
190}
191
192float3 GetOutputColorFromLinear(float3 rgb)
193{
194 float3 output;
195
196 output.rgb = rgb * color_scale;
197
198 if (!scRGB_output) {
199 output.r = sRGBfromLinear(output.r);
200 output.g = sRGBfromLinear(output.g);
201 output.b = sRGBfromLinear(output.b);
202 output.rgb = saturate(output.rgb);
203 }
204
205 return output;
206}
207
208float4 AdvancedPixelShader(PixelShaderInput input)
209{
210 float4 rgba = GetInputColor(input);
211 float4 output;
212
213 if (input_type == INPUTTYPE_HDR10) {
214 rgba.rgb = PQtoLinear(rgba.rgb);
215 }
216
217 if (tonemap_method != TONEMAP_NONE) {
218 rgba.rgb = ApplyTonemap(rgba.rgb);
219 }
220
221 if (input_type == INPUTTYPE_SRGB) {
222 output.rgb = GetOutputColorFromSRGB(rgba.rgb);
223 output.a = rgba.a;
224 } else if (input_type == INPUTTYPE_SCRGB) {
225 output.rgb = GetOutputColorFromLinear(rgba.rgb);
226 output.a = rgba.a;
227 } else if (input_type == INPUTTYPE_HDR10) {
228 rgba.rgb = mul(mat2020to709, rgba.rgb);
229 output.rgb = GetOutputColorFromLinear(rgba.rgb);
230 output.a = rgba.a;
231 } else {
232 output = GetOutputColor(rgba);
233 }
234
235 return output * input.color;
236}