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*/
87static 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*/
159static 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*/
231static 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
261static const DWORD *D3D9_shaders[] = {
262 D3D9_PixelShader_YUV_JPEG,
263 D3D9_PixelShader_YUV_BT601,
264 D3D9_PixelShader_YUV_BT709,
265};
266
267HRESULT 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