b95fddca89040e1b855d5912fcd3ba8207f43e2a
[platform/upstream/SDL.git] / src / render / direct3d / SDL_shaders_d3d.c
1 /*
2   Simple DirectMedia Layer
3   Copyright (C) 1997-2018 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: */