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