1 | /* |
2 | Simple DirectMedia Layer |
3 | Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org> |
4 | |
5 | This software is provided 'as-is', without any express or implied |
6 | warranty. In no event will the authors be held liable for any damages |
7 | arising from the use of this software. |
8 | |
9 | Permission is granted to anyone to use this software for any purpose, |
10 | including commercial applications, and to alter it and redistribute it |
11 | freely, subject to the following restrictions: |
12 | |
13 | 1. The origin of this software must not be misrepresented; you must not |
14 | claim that you wrote the original software. If you use this software |
15 | in a product, an acknowledgment in the product documentation would be |
16 | appreciated but is not required. |
17 | 2. Altered source versions must be plainly marked as such, and must not be |
18 | misrepresented as being the original software. |
19 | 3. This notice may not be removed or altered from any source distribution. |
20 | */ |
21 | #include "../../SDL_internal.h" |
22 | |
23 | #include "SDL_render.h" |
24 | #include "SDL_system.h" |
25 | |
26 | #if SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED |
27 | |
28 | #include "../../core/windows/SDL_windows.h" |
29 | |
30 | #include <d3d9.h> |
31 | |
32 | #include "SDL_shaders_d3d.h" |
33 | |
34 | /* The shaders here were compiled with: |
35 | |
36 | fxc /T ps_2_0 /Fo"<OUTPUT FILE>" "<INPUT FILE>" |
37 | |
38 | Shader object code was converted to a list of DWORDs via the following |
39 | *nix style command (available separately from Windows + MSVC): |
40 | |
41 | hexdump -v -e '6/4 "0x%08.8x, " "\n"' <FILE> |
42 | */ |
43 | |
44 | /* --- D3D9_PixelShader_YUV_JPEG.hlsl --- |
45 | Texture2D theTextureY : register(t0); |
46 | Texture2D theTextureU : register(t1); |
47 | Texture2D theTextureV : register(t2); |
48 | SamplerState theSampler = sampler_state |
49 | { |
50 | addressU = Clamp; |
51 | addressV = Clamp; |
52 | mipfilter = NONE; |
53 | minfilter = LINEAR; |
54 | magfilter = LINEAR; |
55 | }; |
56 | |
57 | struct PixelShaderInput |
58 | { |
59 | float4 pos : SV_POSITION; |
60 | float2 tex : TEXCOORD0; |
61 | float4 color : COLOR0; |
62 | }; |
63 | |
64 | float4 main(PixelShaderInput input) : SV_TARGET |
65 | { |
66 | const float3 offset = {0.0, -0.501960814, -0.501960814}; |
67 | const float3 Rcoeff = {1.0000, 0.0000, 1.4020}; |
68 | const float3 Gcoeff = {1.0000, -0.3441, -0.7141}; |
69 | const float3 Bcoeff = {1.0000, 1.7720, 0.0000}; |
70 | |
71 | float4 Output; |
72 | |
73 | float3 yuv; |
74 | yuv.x = theTextureY.Sample(theSampler, input.tex).r; |
75 | yuv.y = theTextureU.Sample(theSampler, input.tex).r; |
76 | yuv.z = theTextureV.Sample(theSampler, input.tex).r; |
77 | |
78 | yuv += offset; |
79 | Output.r = dot(yuv, Rcoeff); |
80 | Output.g = dot(yuv, Gcoeff); |
81 | Output.b = dot(yuv, Bcoeff); |
82 | Output.a = 1.0f; |
83 | |
84 | return Output * input.color; |
85 | } |
86 | */ |
87 | static const DWORD D3D9_PixelShader_YUV_JPEG[] = { |
88 | 0xffff0200, 0x0044fffe, 0x42415443, 0x0000001c, 0x000000d7, 0xffff0200, |
89 | 0x00000003, 0x0000001c, 0x00000100, 0x000000d0, 0x00000058, 0x00010003, |
90 | 0x00000001, 0x00000070, 0x00000000, 0x00000080, 0x00020003, 0x00000001, |
91 | 0x00000098, 0x00000000, 0x000000a8, 0x00000003, 0x00000001, 0x000000c0, |
92 | 0x00000000, 0x53656874, 0x6c706d61, 0x742b7265, 0x65546568, 0x72757478, |
93 | 0xab005565, 0x00070004, 0x00040001, 0x00000001, 0x00000000, 0x53656874, |
94 | 0x6c706d61, 0x742b7265, 0x65546568, 0x72757478, 0xab005665, 0x00070004, |
95 | 0x00040001, 0x00000001, 0x00000000, 0x53656874, 0x6c706d61, 0x742b7265, |
96 | 0x65546568, 0x72757478, 0xab005965, 0x00070004, 0x00040001, 0x00000001, |
97 | 0x00000000, 0x325f7370, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, |
98 | 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e362072, |
99 | 0x36392e33, 0x312e3030, 0x34383336, 0xababab00, 0x05000051, 0xa00f0000, |
100 | 0x00000000, 0xbf008081, 0xbf008081, 0x3f800000, 0x05000051, 0xa00f0001, |
101 | 0x3f800000, 0x00000000, 0x3fb374bc, 0x00000000, 0x05000051, 0xa00f0002, |
102 | 0x3f800000, 0xbeb02de0, 0xbf36cf42, 0x00000000, 0x05000051, 0xa00f0003, |
103 | 0x3f800000, 0x3fe2d0e5, 0x00000000, 0x00000000, 0x0200001f, 0x80000000, |
104 | 0xb0030000, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, 0x90000000, |
105 | 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f, 0x90000000, |
106 | 0xa00f0802, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042, |
107 | 0x800f0001, 0xb0e40000, 0xa0e40801, 0x03000042, 0x800f0002, 0xb0e40000, |
108 | 0xa0e40802, 0x02000001, 0x80020000, 0x80000001, 0x02000001, 0x80040000, |
109 | 0x80000002, 0x03000002, 0x80070000, 0x80e40000, 0xa0e40000, 0x03000008, |
110 | 0x80010001, 0x80e40000, 0xa0e40001, 0x03000008, 0x80020001, 0x80e40000, |
111 | 0xa0e40002, 0x0400005a, 0x80040001, 0x80e40000, 0xa0e40003, 0xa0aa0003, |
112 | 0x02000001, 0x80080001, 0xa0ff0000, 0x03000005, 0x800f0000, 0x80e40001, |
113 | 0x90e40000, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff |
114 | }; |
115 | |
116 | /* --- D3D9_PixelShader_YUV_BT601.hlsl --- |
117 | Texture2D theTextureY : register(t0); |
118 | Texture2D theTextureU : register(t1); |
119 | Texture2D theTextureV : register(t2); |
120 | SamplerState theSampler = sampler_state |
121 | { |
122 | addressU = Clamp; |
123 | addressV = Clamp; |
124 | mipfilter = NONE; |
125 | minfilter = LINEAR; |
126 | magfilter = LINEAR; |
127 | }; |
128 | |
129 | struct PixelShaderInput |
130 | { |
131 | float4 pos : SV_POSITION; |
132 | float2 tex : TEXCOORD0; |
133 | float4 color : COLOR0; |
134 | }; |
135 | |
136 | float4 main(PixelShaderInput input) : SV_TARGET |
137 | { |
138 | const float3 offset = {-0.0627451017, -0.501960814, -0.501960814}; |
139 | const float3 Rcoeff = {1.1644, 0.0000, 1.5960}; |
140 | const float3 Gcoeff = {1.1644, -0.3918, -0.8130}; |
141 | const float3 Bcoeff = {1.1644, 2.0172, 0.0000}; |
142 | |
143 | float4 Output; |
144 | |
145 | float3 yuv; |
146 | yuv.x = theTextureY.Sample(theSampler, input.tex).r; |
147 | yuv.y = theTextureU.Sample(theSampler, input.tex).r; |
148 | yuv.z = theTextureV.Sample(theSampler, input.tex).r; |
149 | |
150 | yuv += offset; |
151 | Output.r = dot(yuv, Rcoeff); |
152 | Output.g = dot(yuv, Gcoeff); |
153 | Output.b = dot(yuv, Bcoeff); |
154 | Output.a = 1.0f; |
155 | |
156 | return Output * input.color; |
157 | } |
158 | */ |
159 | static const DWORD D3D9_PixelShader_YUV_BT601[] = { |
160 | 0xffff0200, 0x0044fffe, 0x42415443, 0x0000001c, 0x000000d7, 0xffff0200, |
161 | 0x00000003, 0x0000001c, 0x00000100, 0x000000d0, 0x00000058, 0x00010003, |
162 | 0x00000001, 0x00000070, 0x00000000, 0x00000080, 0x00020003, 0x00000001, |
163 | 0x00000098, 0x00000000, 0x000000a8, 0x00000003, 0x00000001, 0x000000c0, |
164 | 0x00000000, 0x53656874, 0x6c706d61, 0x742b7265, 0x65546568, 0x72757478, |
165 | 0xab005565, 0x00070004, 0x00040001, 0x00000001, 0x00000000, 0x53656874, |
166 | 0x6c706d61, 0x742b7265, 0x65546568, 0x72757478, 0xab005665, 0x00070004, |
167 | 0x00040001, 0x00000001, 0x00000000, 0x53656874, 0x6c706d61, 0x742b7265, |
168 | 0x65546568, 0x72757478, 0xab005965, 0x00070004, 0x00040001, 0x00000001, |
169 | 0x00000000, 0x325f7370, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, |
170 | 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e362072, |
171 | 0x36392e33, 0x312e3030, 0x34383336, 0xababab00, 0x05000051, 0xa00f0000, |
172 | 0xbd808081, 0xbf008081, 0xbf008081, 0x3f800000, 0x05000051, 0xa00f0001, |
173 | 0x3f950b0f, 0x00000000, 0x3fcc49ba, 0x00000000, 0x05000051, 0xa00f0002, |
174 | 0x3f950b0f, 0xbec89a02, 0xbf5020c5, 0x00000000, 0x05000051, 0xa00f0003, |
175 | 0x3f950b0f, 0x400119ce, 0x00000000, 0x00000000, 0x0200001f, 0x80000000, |
176 | 0xb0030000, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, 0x90000000, |
177 | 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f, 0x90000000, |
178 | 0xa00f0802, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042, |
179 | 0x800f0001, 0xb0e40000, 0xa0e40801, 0x03000042, 0x800f0002, 0xb0e40000, |
180 | 0xa0e40802, 0x02000001, 0x80020000, 0x80000001, 0x02000001, 0x80040000, |
181 | 0x80000002, 0x03000002, 0x80070000, 0x80e40000, 0xa0e40000, 0x03000008, |
182 | 0x80010001, 0x80e40000, 0xa0e40001, 0x03000008, 0x80020001, 0x80e40000, |
183 | 0xa0e40002, 0x0400005a, 0x80040001, 0x80e40000, 0xa0e40003, 0xa0aa0003, |
184 | 0x02000001, 0x80080001, 0xa0ff0000, 0x03000005, 0x800f0000, 0x80e40001, |
185 | 0x90e40000, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff |
186 | }; |
187 | |
188 | /* --- D3D9_PixelShader_YUV_BT709.hlsl --- |
189 | Texture2D theTextureY : register(t0); |
190 | Texture2D theTextureU : register(t1); |
191 | Texture2D theTextureV : register(t2); |
192 | SamplerState theSampler = sampler_state |
193 | { |
194 | addressU = Clamp; |
195 | addressV = Clamp; |
196 | mipfilter = NONE; |
197 | minfilter = LINEAR; |
198 | magfilter = LINEAR; |
199 | }; |
200 | |
201 | struct PixelShaderInput |
202 | { |
203 | float4 pos : SV_POSITION; |
204 | float2 tex : TEXCOORD0; |
205 | float4 color : COLOR0; |
206 | }; |
207 | |
208 | float4 main(PixelShaderInput input) : SV_TARGET |
209 | { |
210 | const float3 offset = {-0.0627451017, -0.501960814, -0.501960814}; |
211 | const float3 Rcoeff = {1.1644, 0.0000, 1.7927}; |
212 | const float3 Gcoeff = {1.1644, -0.2132, -0.5329}; |
213 | const float3 Bcoeff = {1.1644, 2.1124, 0.0000}; |
214 | |
215 | float4 Output; |
216 | |
217 | float3 yuv; |
218 | yuv.x = theTextureY.Sample(theSampler, input.tex).r; |
219 | yuv.y = theTextureU.Sample(theSampler, input.tex).r; |
220 | yuv.z = theTextureV.Sample(theSampler, input.tex).r; |
221 | |
222 | yuv += offset; |
223 | Output.r = dot(yuv, Rcoeff); |
224 | Output.g = dot(yuv, Gcoeff); |
225 | Output.b = dot(yuv, Bcoeff); |
226 | Output.a = 1.0f; |
227 | |
228 | return Output * input.color; |
229 | } |
230 | */ |
231 | static const DWORD D3D9_PixelShader_YUV_BT709[] = { |
232 | 0xffff0200, 0x0044fffe, 0x42415443, 0x0000001c, 0x000000d7, 0xffff0200, |
233 | 0x00000003, 0x0000001c, 0x00000100, 0x000000d0, 0x00000058, 0x00010003, |
234 | 0x00000001, 0x00000070, 0x00000000, 0x00000080, 0x00020003, 0x00000001, |
235 | 0x00000098, 0x00000000, 0x000000a8, 0x00000003, 0x00000001, 0x000000c0, |
236 | 0x00000000, 0x53656874, 0x6c706d61, 0x742b7265, 0x65546568, 0x72757478, |
237 | 0xab005565, 0x00070004, 0x00040001, 0x00000001, 0x00000000, 0x53656874, |
238 | 0x6c706d61, 0x742b7265, 0x65546568, 0x72757478, 0xab005665, 0x00070004, |
239 | 0x00040001, 0x00000001, 0x00000000, 0x53656874, 0x6c706d61, 0x742b7265, |
240 | 0x65546568, 0x72757478, 0xab005965, 0x00070004, 0x00040001, 0x00000001, |
241 | 0x00000000, 0x325f7370, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, |
242 | 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e362072, |
243 | 0x36392e33, 0x312e3030, 0x34383336, 0xababab00, 0x05000051, 0xa00f0000, |
244 | 0xbd808081, 0xbf008081, 0xbf008081, 0x3f800000, 0x05000051, 0xa00f0001, |
245 | 0x3f950b0f, 0x00000000, 0x3fe57732, 0x00000000, 0x05000051, 0xa00f0002, |
246 | 0x3f950b0f, 0xbe5a511a, 0xbf086c22, 0x00000000, 0x05000051, 0xa00f0003, |
247 | 0x3f950b0f, 0x40073190, 0x00000000, 0x00000000, 0x0200001f, 0x80000000, |
248 | 0xb0030000, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, 0x90000000, |
249 | 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f, 0x90000000, |
250 | 0xa00f0802, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042, |
251 | 0x800f0001, 0xb0e40000, 0xa0e40801, 0x03000042, 0x800f0002, 0xb0e40000, |
252 | 0xa0e40802, 0x02000001, 0x80020000, 0x80000001, 0x02000001, 0x80040000, |
253 | 0x80000002, 0x03000002, 0x80070000, 0x80e40000, 0xa0e40000, 0x03000008, |
254 | 0x80010001, 0x80e40000, 0xa0e40001, 0x03000008, 0x80020001, 0x80e40000, |
255 | 0xa0e40002, 0x0400005a, 0x80040001, 0x80e40000, 0xa0e40003, 0xa0aa0003, |
256 | 0x02000001, 0x80080001, 0xa0ff0000, 0x03000005, 0x800f0000, 0x80e40001, |
257 | 0x90e40000, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff |
258 | }; |
259 | |
260 | |
261 | static const DWORD *D3D9_shaders[] = { |
262 | D3D9_PixelShader_YUV_JPEG, |
263 | D3D9_PixelShader_YUV_BT601, |
264 | D3D9_PixelShader_YUV_BT709, |
265 | }; |
266 | |
267 | HRESULT D3D9_CreatePixelShader(IDirect3DDevice9 *d3dDevice, D3D9_Shader shader, IDirect3DPixelShader9 **pixelShader) |
268 | { |
269 | return IDirect3DDevice9_CreatePixelShader(d3dDevice, D3D9_shaders[shader], pixelShader); |
270 | } |
271 | |
272 | #endif /* SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED */ |
273 | |
274 | /* vi: set ts=4 sw=4 expandtab: */ |
275 | |