2 Simple DirectMedia Layer
3 Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
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.
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:
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.
21 #include "../../SDL_internal.h"
23 #if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED
26 #include "../../core/windows/SDL_windows.h"
27 #include "SDL_hints.h"
28 #include "SDL_loadso.h"
29 #include "SDL_syswm.h"
30 #include "../SDL_sysrender.h"
31 #include "../SDL_d3dmath.h"
32 /* #include "SDL_log.h" */
39 #if NTDDI_VERSION > NTDDI_WIN8
43 #include "SDL_render_winrt.h"
45 #if WINAPI_FAMILY == WINAPI_FAMILY_APP
46 #include <windows.ui.xaml.media.dxinterop.h>
47 /* TODO, WinRT, XAML: get the ISwapChainBackgroundPanelNative from something other than a global var */
48 extern ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative;
49 #endif /* WINAPI_FAMILY == WINAPI_FAMILY_APP */
51 #endif /* __WINRT__ */
54 #define SAFE_RELEASE(X) if ((X)) { IUnknown_Release(SDL_static_cast(IUnknown*, X)); X = NULL; }
57 /* Vertex shader, common values */
61 Float4X4 projectionAndView;
62 } VertexShaderConstants;
70 } VertexPositionColor;
72 /* Per-texture data */
75 ID3D11Texture2D *mainTexture;
76 ID3D11ShaderResourceView *mainTextureResourceView;
77 ID3D11RenderTargetView *mainTextureRenderTargetView;
78 ID3D11Texture2D *stagingTexture;
79 int lockedTexturePositionX;
80 int lockedTexturePositionY;
81 D3D11_FILTER scaleMode;
83 /* YV12 texture support */
85 ID3D11Texture2D *mainTextureU;
86 ID3D11ShaderResourceView *mainTextureResourceViewU;
87 ID3D11Texture2D *mainTextureV;
88 ID3D11ShaderResourceView *mainTextureResourceViewV;
94 /* Private renderer data */
99 IDXGIFactory2 *dxgiFactory;
100 IDXGIAdapter *dxgiAdapter;
101 ID3D11Device1 *d3dDevice;
102 ID3D11DeviceContext1 *d3dContext;
103 IDXGISwapChain1 *swapChain;
104 DXGI_SWAP_EFFECT swapEffect;
105 ID3D11RenderTargetView *mainRenderTargetView;
106 ID3D11RenderTargetView *currentOffscreenRenderTargetView;
107 ID3D11InputLayout *inputLayout;
108 ID3D11Buffer *vertexBuffer;
109 ID3D11VertexShader *vertexShader;
110 ID3D11PixelShader *colorPixelShader;
111 ID3D11PixelShader *texturePixelShader;
112 ID3D11PixelShader *yuvPixelShader;
113 ID3D11BlendState *blendModeBlend;
114 ID3D11BlendState *blendModeAdd;
115 ID3D11BlendState *blendModeMod;
116 ID3D11SamplerState *nearestPixelSampler;
117 ID3D11SamplerState *linearSampler;
118 D3D_FEATURE_LEVEL featureLevel;
121 ID3D11RasterizerState *mainRasterizer;
122 ID3D11RasterizerState *clippedRasterizer;
124 /* Vertex buffer constants */
125 VertexShaderConstants vertexShaderConstantsData;
126 ID3D11Buffer *vertexShaderConstants;
128 /* Cached renderer properties */
129 DXGI_MODE_ROTATION rotation;
130 ID3D11RenderTargetView *currentRenderTargetView;
131 ID3D11RasterizerState *currentRasterizerState;
132 ID3D11BlendState *currentBlendState;
133 ID3D11PixelShader *currentShader;
134 ID3D11ShaderResourceView *currentShaderResource;
135 ID3D11SamplerState *currentSampler;
139 /* Defined here so we don't have to include uuid.lib */
140 static const GUID IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } };
141 static const GUID IID_IDXGIDevice1 = { 0x77db970f, 0x6276, 0x48ba, { 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c } };
142 static const GUID IID_IDXGIDevice3 = { 0x6007896c, 0x3244, 0x4afd, { 0xbf, 0x18, 0xa6, 0xd3, 0xbe, 0xda, 0x50, 0x23 } };
143 static const GUID IID_ID3D11Texture2D = { 0x6f15aaf2, 0xd208, 0x4e89, { 0x9a, 0xb4, 0x48, 0x95, 0x35, 0xd3, 0x4f, 0x9c } };
144 static const GUID IID_ID3D11Device1 = { 0xa04bfb29, 0x08ef, 0x43d6, { 0xa4, 0x9c, 0xa9, 0xbd, 0xbd, 0xcb, 0xe6, 0x86 } };
145 static const GUID IID_ID3D11DeviceContext1 = { 0xbb2c6faa, 0xb5fb, 0x4082, { 0x8e, 0x6b, 0x38, 0x8b, 0x8c, 0xfa, 0x90, 0xe1 } };
146 static const GUID IID_ID3D11Debug = { 0x79cf2233, 0x7536, 0x4948, { 0x9d, 0x36, 0x1e, 0x46, 0x92, 0xdc, 0x57, 0x60 } };
148 /* Direct3D 11.x shaders
150 SDL's shaders are compiled into SDL itself, to simplify distribution.
152 All Direct3D 11.x shaders were compiled with the following:
154 fxc /E"main" /T "<TYPE>" /Fo"<OUTPUT FILE>" "<INPUT FILE>"
157 - <TYPE>: the type of shader. A table of utilized shader types is
159 - <OUTPUT FILE>: where to store compiled output
160 - <INPUT FILE>: where to read shader source code from
163 - ps_4_0_level_9_1: Pixel shader for Windows 8+, including Windows RT
164 - vs_4_0_level_9_1: Vertex shader for Windows 8+, including Windows RT
165 - ps_4_0_level_9_3: Pixel shader for Windows Phone 8
166 - vs_4_0_level_9_3: Vertex shader for Windows Phone 8
169 Shader object code was converted to a list of DWORDs via the following
170 *nix style command (available separately from Windows + MSVC):
172 hexdump -v -e '6/4 "0x%08.8x, " "\n"' <FILE>
174 #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
175 #define D3D11_USE_SHADER_MODEL_4_0_level_9_3
177 #define D3D11_USE_SHADER_MODEL_4_0_level_9_1
180 /* The color-only-rendering pixel shader:
182 --- D3D11_PixelShader_Colors.hlsl ---
183 struct PixelShaderInput
185 float4 pos : SV_POSITION;
186 float2 tex : TEXCOORD0;
187 float4 color : COLOR0;
190 float4 main(PixelShaderInput input) : SV_TARGET
195 #if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1)
196 static const DWORD D3D11_PixelShader_Colors[] = {
197 0x43425844, 0xd74c28fe, 0xa1eb8804, 0x269d512a, 0x7699723d, 0x00000001,
198 0x00000240, 0x00000006, 0x00000038, 0x00000084, 0x000000c4, 0x00000140,
199 0x00000198, 0x0000020c, 0x396e6f41, 0x00000044, 0x00000044, 0xffff0200,
200 0x00000020, 0x00000024, 0x00240000, 0x00240000, 0x00240000, 0x00240000,
201 0x00240000, 0xffff0200, 0x0200001f, 0x80000000, 0xb00f0001, 0x02000001,
202 0x800f0800, 0xb0e40001, 0x0000ffff, 0x52444853, 0x00000038, 0x00000040,
203 0x0000000e, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, 0x001020f2,
204 0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000002,
205 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000, 0x00000000,
206 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
207 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
208 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000,
209 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
210 0x00000000, 0x00000000, 0x46454452, 0x00000050, 0x00000000, 0x00000000,
211 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d,
212 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072,
213 0x6c69706d, 0x39207265, 0x2e30332e, 0x30303239, 0x3336312e, 0xab003438,
214 0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000,
215 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
216 0x00000000, 0x00000003, 0x00000001, 0x00000003, 0x00000065, 0x00000000,
217 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f,
218 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f,
219 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
220 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054
222 #elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3)
223 static const DWORD D3D11_PixelShader_Colors[] = {
224 0x43425844, 0x93f6ccfc, 0x5f919270, 0x7a11aa4f, 0x9148e931, 0x00000001,
225 0x00000240, 0x00000006, 0x00000038, 0x00000084, 0x000000c4, 0x00000140,
226 0x00000198, 0x0000020c, 0x396e6f41, 0x00000044, 0x00000044, 0xffff0200,
227 0x00000020, 0x00000024, 0x00240000, 0x00240000, 0x00240000, 0x00240000,
228 0x00240000, 0xffff0201, 0x0200001f, 0x80000000, 0xb00f0001, 0x02000001,
229 0x800f0800, 0xb0e40001, 0x0000ffff, 0x52444853, 0x00000038, 0x00000040,
230 0x0000000e, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, 0x001020f2,
231 0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000002,
232 0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000, 0x00000000,
233 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
234 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
235 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000,
236 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
237 0x00000000, 0x00000000, 0x46454452, 0x00000050, 0x00000000, 0x00000000,
238 0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d,
239 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072,
240 0x6c69706d, 0x39207265, 0x2e30332e, 0x30303239, 0x3336312e, 0xab003438,
241 0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000,
242 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
243 0x00000000, 0x00000003, 0x00000001, 0x00000003, 0x00000065, 0x00000000,
244 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f,
245 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f,
246 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
247 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054
250 #error "An appropriate 'colors' pixel shader is not defined."
253 /* The texture-rendering pixel shader:
255 --- D3D11_PixelShader_Textures.hlsl ---
256 Texture2D theTexture : register(t0);
257 SamplerState theSampler : register(s0);
259 struct PixelShaderInput
261 float4 pos : SV_POSITION;
262 float2 tex : TEXCOORD0;
263 float4 color : COLOR0;
266 float4 main(PixelShaderInput input) : SV_TARGET
268 return theTexture.Sample(theSampler, input.tex) * input.color;
271 #if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1)
272 static const DWORD D3D11_PixelShader_Textures[] = {
273 0x43425844, 0x6299b59f, 0x155258f2, 0x873ab86a, 0xfcbb6dcd, 0x00000001,
274 0x00000330, 0x00000006, 0x00000038, 0x000000c0, 0x0000015c, 0x000001d8,
275 0x00000288, 0x000002fc, 0x396e6f41, 0x00000080, 0x00000080, 0xffff0200,
276 0x00000058, 0x00000028, 0x00280000, 0x00280000, 0x00280000, 0x00240001,
277 0x00280000, 0x00000000, 0xffff0200, 0x0200001f, 0x80000000, 0xb0030000,
278 0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f, 0x90000000, 0xa00f0800,
279 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000005, 0x800f0000,
280 0x80e40000, 0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff,
281 0x52444853, 0x00000094, 0x00000040, 0x00000025, 0x0300005a, 0x00106000,
282 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062,
283 0x00101032, 0x00000001, 0x03001062, 0x001010f2, 0x00000002, 0x03000065,
284 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x09000045, 0x001000f2,
285 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000,
286 0x00000000, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000,
287 0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, 0x00000003,
288 0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x00000000, 0x00000000,
289 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
290 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
291 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
292 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452, 0x000000a8,
293 0x00000000, 0x00000000, 0x00000002, 0x0000001c, 0xffff0400, 0x00000100,
294 0x00000072, 0x0000005c, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
295 0x00000000, 0x00000001, 0x00000001, 0x00000067, 0x00000002, 0x00000005,
296 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x53656874,
297 0x6c706d61, 0x74007265, 0x65546568, 0x72757478, 0x694d0065, 0x736f7263,
298 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43,
299 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, 0xababab00,
300 0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000,
301 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
302 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000065, 0x00000000,
303 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f,
304 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f,
305 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
306 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054
308 #elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3)
309 static const DWORD D3D11_PixelShader_Textures[] = {
310 0x43425844, 0x5876569a, 0x01b6c87e, 0x8447454f, 0xc7f3ef10, 0x00000001,
311 0x00000330, 0x00000006, 0x00000038, 0x000000c0, 0x0000015c, 0x000001d8,
312 0x00000288, 0x000002fc, 0x396e6f41, 0x00000080, 0x00000080, 0xffff0200,
313 0x00000058, 0x00000028, 0x00280000, 0x00280000, 0x00280000, 0x00240001,
314 0x00280000, 0x00000000, 0xffff0201, 0x0200001f, 0x80000000, 0xb0030000,
315 0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f, 0x90000000, 0xa00f0800,
316 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000005, 0x800f0000,
317 0x80e40000, 0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff,
318 0x52444853, 0x00000094, 0x00000040, 0x00000025, 0x0300005a, 0x00106000,
319 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062,
320 0x00101032, 0x00000001, 0x03001062, 0x001010f2, 0x00000002, 0x03000065,
321 0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x09000045, 0x001000f2,
322 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000,
323 0x00000000, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000,
324 0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, 0x00000003,
325 0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x00000000, 0x00000000,
326 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
327 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
328 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
329 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452, 0x000000a8,
330 0x00000000, 0x00000000, 0x00000002, 0x0000001c, 0xffff0400, 0x00000100,
331 0x00000072, 0x0000005c, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
332 0x00000000, 0x00000001, 0x00000001, 0x00000067, 0x00000002, 0x00000005,
333 0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x53656874,
334 0x6c706d61, 0x74007265, 0x65546568, 0x72757478, 0x694d0065, 0x736f7263,
335 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43,
336 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, 0xababab00,
337 0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000,
338 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
339 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000065, 0x00000000,
340 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f,
341 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f,
342 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
343 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054
346 #error "An appropriate 'textures' pixel shader is not defined"
349 /* The yuv-rendering pixel shader:
351 --- D3D11_PixelShader_YUV.hlsl ---
352 Texture2D theTextureY : register(t0);
353 Texture2D theTextureU : register(t1);
354 Texture2D theTextureV : register(t2);
355 SamplerState theSampler : register(s0);
357 struct PixelShaderInput
359 float4 pos : SV_POSITION;
360 float2 tex : TEXCOORD0;
361 float4 color : COLOR0;
364 float4 main(PixelShaderInput input) : SV_TARGET
366 const float3 offset = {-0.0627451017, -0.501960814, -0.501960814};
367 const float3 Rcoeff = {1.164, 0.000, 1.596};
368 const float3 Gcoeff = {1.164, -0.391, -0.813};
369 const float3 Bcoeff = {1.164, 2.018, 0.000};
374 yuv.x = theTextureY.Sample(theSampler, input.tex).r;
375 yuv.y = theTextureU.Sample(theSampler, input.tex).r;
376 yuv.z = theTextureV.Sample(theSampler, input.tex).r;
379 Output.r = dot(yuv, Rcoeff);
380 Output.g = dot(yuv, Gcoeff);
381 Output.b = dot(yuv, Bcoeff);
384 return Output * input.color;
388 #if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1)
389 static const DWORD D3D11_PixelShader_YUV[] = {
390 0x43425844, 0x2321c6c6, 0xf14df2d1, 0xc79d068d, 0x8e672abf, 0x00000001,
391 0x000005e8, 0x00000006, 0x00000038, 0x000001dc, 0x000003bc, 0x00000438,
392 0x00000540, 0x000005b4, 0x396e6f41, 0x0000019c, 0x0000019c, 0xffff0200,
393 0x0000016c, 0x00000030, 0x00300000, 0x00300000, 0x00300000, 0x00240003,
394 0x00300000, 0x00000000, 0x00010001, 0x00020002, 0xffff0200, 0x05000051,
395 0xa00f0000, 0xbd808081, 0xbf008081, 0xbf008081, 0x3f800000, 0x05000051,
396 0xa00f0001, 0x3f94fdf4, 0x3fcc49ba, 0x00000000, 0x00000000, 0x05000051,
397 0xa00f0002, 0x3f94fdf4, 0xbec83127, 0xbf5020c5, 0x00000000, 0x05000051,
398 0xa00f0003, 0x3f94fdf4, 0x400126e9, 0x00000000, 0x00000000, 0x0200001f,
399 0x80000000, 0xb0030000, 0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f,
400 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f,
401 0x90000000, 0xa00f0802, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,
402 0x03000042, 0x800f0001, 0xb0e40000, 0xa0e40801, 0x03000042, 0x800f0002,
403 0xb0e40000, 0xa0e40802, 0x02000001, 0x80020000, 0x80000001, 0x02000001,
404 0x80040000, 0x80000002, 0x03000002, 0x80070000, 0x80e40000, 0xa0e40000,
405 0x03000005, 0x80080000, 0x80000000, 0xa0000001, 0x04000004, 0x80010001,
406 0x80aa0000, 0xa0550001, 0x80ff0000, 0x03000008, 0x80020001, 0x80e40000,
407 0xa0e40002, 0x0400005a, 0x80040001, 0x80e40000, 0xa0e40003, 0xa0aa0003,
408 0x02000001, 0x80080001, 0xa0ff0000, 0x03000005, 0x800f0000, 0x80e40001,
409 0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, 0x52444853,
410 0x000001d8, 0x00000040, 0x00000076, 0x0300005a, 0x00106000, 0x00000000,
411 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000,
412 0x00000001, 0x00005555, 0x04001858, 0x00107000, 0x00000002, 0x00005555,
413 0x03001062, 0x00101032, 0x00000001, 0x03001062, 0x001010f2, 0x00000002,
414 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x09000045,
415 0x001000f2, 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000,
416 0x00106000, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00101046,
417 0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000000, 0x05000036,
418 0x00100022, 0x00000000, 0x0010000a, 0x00000001, 0x09000045, 0x001000f2,
419 0x00000001, 0x00101046, 0x00000001, 0x00107e46, 0x00000002, 0x00106000,
420 0x00000000, 0x05000036, 0x00100042, 0x00000000, 0x0010000a, 0x00000001,
421 0x0a000000, 0x00100072, 0x00000000, 0x00100246, 0x00000000, 0x00004002,
422 0xbd808081, 0xbf008081, 0xbf008081, 0x00000000, 0x0a00000f, 0x00100012,
423 0x00000001, 0x00100086, 0x00000000, 0x00004002, 0x3f94fdf4, 0x3fcc49ba,
424 0x00000000, 0x00000000, 0x0a000010, 0x00100022, 0x00000001, 0x00100246,
425 0x00000000, 0x00004002, 0x3f94fdf4, 0xbec83127, 0xbf5020c5, 0x00000000,
426 0x0a00000f, 0x00100042, 0x00000001, 0x00100046, 0x00000000, 0x00004002,
427 0x3f94fdf4, 0x400126e9, 0x00000000, 0x00000000, 0x05000036, 0x00100082,
428 0x00000001, 0x00004001, 0x3f800000, 0x07000038, 0x001020f2, 0x00000000,
429 0x00100e46, 0x00000001, 0x00101e46, 0x00000002, 0x0100003e, 0x54415453,
430 0x00000074, 0x0000000c, 0x00000002, 0x00000000, 0x00000003, 0x00000005,
431 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
432 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000,
433 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
434 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
435 0x46454452, 0x00000100, 0x00000000, 0x00000000, 0x00000004, 0x0000001c,
436 0xffff0400, 0x00000100, 0x000000cb, 0x0000009c, 0x00000003, 0x00000000,
437 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000a7,
438 0x00000002, 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001,
439 0x0000000d, 0x000000b3, 0x00000002, 0x00000005, 0x00000004, 0xffffffff,
440 0x00000001, 0x00000001, 0x0000000d, 0x000000bf, 0x00000002, 0x00000005,
441 0x00000004, 0xffffffff, 0x00000002, 0x00000001, 0x0000000d, 0x53656874,
442 0x6c706d61, 0x74007265, 0x65546568, 0x72757478, 0x74005965, 0x65546568,
443 0x72757478, 0x74005565, 0x65546568, 0x72757478, 0x4d005665, 0x6f726369,
444 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320,
445 0x656c6970, 0x2e362072, 0x36392e33, 0x312e3030, 0x34383336, 0xababab00,
446 0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000,
447 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
448 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000065, 0x00000000,
449 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f,
450 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f,
451 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
452 0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054
454 #elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3)
455 static const DWORD D3D11_PixelShader_YUV[] = {
456 0x43425844, 0x6ede7360, 0x45ff5f8a, 0x34ac92ba, 0xb865f5e0, 0x00000001,
457 0x000005c0, 0x00000006, 0x00000038, 0x000001b4, 0x00000394, 0x00000410,
458 0x00000518, 0x0000058c, 0x396e6f41, 0x00000174, 0x00000174, 0xffff0200,
459 0x00000144, 0x00000030, 0x00300000, 0x00300000, 0x00300000, 0x00240003,
460 0x00300000, 0x00000000, 0x00010001, 0x00020002, 0xffff0201, 0x05000051,
461 0xa00f0000, 0xbd808081, 0xbf008081, 0x3f800000, 0x00000000, 0x05000051,
462 0xa00f0001, 0x3f94fdf4, 0x3fcc49ba, 0x00000000, 0x400126e9, 0x05000051,
463 0xa00f0002, 0x3f94fdf4, 0xbec83127, 0xbf5020c5, 0x00000000, 0x0200001f,
464 0x80000000, 0xb0030000, 0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f,
465 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f,
466 0x90000000, 0xa00f0802, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40801,
467 0x03000042, 0x800f0001, 0xb0e40000, 0xa0e40800, 0x02000001, 0x80020001,
468 0x80000000, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40802, 0x02000001,
469 0x80040001, 0x80000000, 0x03000002, 0x80070000, 0x80e40001, 0xa0d40000,
470 0x0400005a, 0x80010001, 0x80e80000, 0xa0e40001, 0xa0aa0001, 0x03000008,
471 0x80020001, 0x80e40000, 0xa0e40002, 0x0400005a, 0x80040001, 0x80e40000,
472 0xa0ec0001, 0xa0aa0001, 0x02000001, 0x80080001, 0xa0aa0000, 0x03000005,
473 0x800f0000, 0x80e40001, 0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000,
474 0x0000ffff, 0x52444853, 0x000001d8, 0x00000040, 0x00000076, 0x0300005a,
475 0x00106000, 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555,
476 0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04001858, 0x00107000,
477 0x00000002, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03001062,
478 0x001010f2, 0x00000002, 0x03000065, 0x001020f2, 0x00000000, 0x02000068,
479 0x00000002, 0x09000045, 0x001000f2, 0x00000000, 0x00101046, 0x00000001,
480 0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x09000045, 0x001000f2,
481 0x00000001, 0x00101046, 0x00000001, 0x00107e46, 0x00000001, 0x00106000,
482 0x00000000, 0x05000036, 0x00100022, 0x00000000, 0x0010000a, 0x00000001,
483 0x09000045, 0x001000f2, 0x00000001, 0x00101046, 0x00000001, 0x00107e46,
484 0x00000002, 0x00106000, 0x00000000, 0x05000036, 0x00100042, 0x00000000,
485 0x0010000a, 0x00000001, 0x0a000000, 0x00100072, 0x00000000, 0x00100246,
486 0x00000000, 0x00004002, 0xbd808081, 0xbf008081, 0xbf008081, 0x00000000,
487 0x0a00000f, 0x00100012, 0x00000001, 0x00100086, 0x00000000, 0x00004002,
488 0x3f94fdf4, 0x3fcc49ba, 0x00000000, 0x00000000, 0x0a000010, 0x00100022,
489 0x00000001, 0x00100246, 0x00000000, 0x00004002, 0x3f94fdf4, 0xbec83127,
490 0xbf5020c5, 0x00000000, 0x0a00000f, 0x00100042, 0x00000001, 0x00100046,
491 0x00000000, 0x00004002, 0x3f94fdf4, 0x400126e9, 0x00000000, 0x00000000,
492 0x05000036, 0x00100082, 0x00000001, 0x00004001, 0x3f800000, 0x07000038,
493 0x001020f2, 0x00000000, 0x00100e46, 0x00000001, 0x00101e46, 0x00000002,
494 0x0100003e, 0x54415453, 0x00000074, 0x0000000c, 0x00000002, 0x00000000,
495 0x00000003, 0x00000005, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
496 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
497 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
498 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
499 0x00000000, 0x00000000, 0x46454452, 0x00000100, 0x00000000, 0x00000000,
500 0x00000004, 0x0000001c, 0xffff0400, 0x00000100, 0x000000cb, 0x0000009c,
501 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
502 0x00000001, 0x000000a7, 0x00000002, 0x00000005, 0x00000004, 0xffffffff,
503 0x00000000, 0x00000001, 0x0000000d, 0x000000b3, 0x00000002, 0x00000005,
504 0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000bf,
505 0x00000002, 0x00000005, 0x00000004, 0xffffffff, 0x00000002, 0x00000001,
506 0x0000000d, 0x53656874, 0x6c706d61, 0x74007265, 0x65546568, 0x72757478,
507 0x74005965, 0x65546568, 0x72757478, 0x74005565, 0x65546568, 0x72757478,
508 0x4d005665, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c,
509 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e362072, 0x36392e33, 0x312e3030,
510 0x34383336, 0xababab00, 0x4e475349, 0x0000006c, 0x00000003, 0x00000008,
511 0x00000050, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f,
512 0x0000005c, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000303,
513 0x00000065, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000f0f,
514 0x505f5653, 0x5449534f, 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300,
515 0xab00524f, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
516 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653,
517 0x45475241, 0xabab0054
520 #error "An appropriate 'yuv' pixel shader is not defined."
523 /* The sole vertex shader:
525 --- D3D11_VertexShader.hlsl ---
526 #pragma pack_matrix( row_major )
528 cbuffer VertexShaderConstants : register(b0)
531 matrix projectionAndView;
534 struct VertexShaderInput
536 float3 pos : POSITION;
537 float2 tex : TEXCOORD0;
538 float4 color : COLOR0;
541 struct VertexShaderOutput
543 float4 pos : SV_POSITION;
544 float2 tex : TEXCOORD0;
545 float4 color : COLOR0;
548 VertexShaderOutput main(VertexShaderInput input)
550 VertexShaderOutput output;
551 float4 pos = float4(input.pos, 1.0f);
553 // Transform the vertex position into projected space.
554 pos = mul(pos, model);
555 pos = mul(pos, projectionAndView);
558 // Pass through texture coordinates and color values without transformation
559 output.tex = input.tex;
560 output.color = input.color;
565 #if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1)
566 static const DWORD D3D11_VertexShader[] = {
567 0x43425844, 0x62dfae5f, 0x3e8bd8df, 0x9ec97127, 0x5044eefb, 0x00000001,
568 0x00000598, 0x00000006, 0x00000038, 0x0000016c, 0x00000334, 0x000003b0,
569 0x000004b4, 0x00000524, 0x396e6f41, 0x0000012c, 0x0000012c, 0xfffe0200,
570 0x000000f8, 0x00000034, 0x00240001, 0x00300000, 0x00300000, 0x00240000,
571 0x00300001, 0x00000000, 0x00010008, 0x00000000, 0x00000000, 0xfffe0200,
572 0x0200001f, 0x80000005, 0x900f0000, 0x0200001f, 0x80010005, 0x900f0001,
573 0x0200001f, 0x80020005, 0x900f0002, 0x03000005, 0x800f0000, 0x90550000,
574 0xa0e40002, 0x04000004, 0x800f0000, 0x90000000, 0xa0e40001, 0x80e40000,
575 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40003, 0x80e40000, 0x03000002,
576 0x800f0000, 0x80e40000, 0xa0e40004, 0x03000005, 0x800f0001, 0x80550000,
577 0xa0e40006, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40005, 0x80e40001,
578 0x04000004, 0x800f0001, 0x80aa0000, 0xa0e40007, 0x80e40001, 0x04000004,
579 0x800f0000, 0x80ff0000, 0xa0e40008, 0x80e40001, 0x04000004, 0xc0030000,
580 0x80ff0000, 0xa0e40000, 0x80e40000, 0x02000001, 0xc00c0000, 0x80e40000,
581 0x02000001, 0xe0030000, 0x90e40001, 0x02000001, 0xe00f0001, 0x90e40002,
582 0x0000ffff, 0x52444853, 0x000001c0, 0x00010040, 0x00000070, 0x04000059,
583 0x00208e46, 0x00000000, 0x00000008, 0x0300005f, 0x00101072, 0x00000000,
584 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x001010f2, 0x00000002,
585 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x00102032,
586 0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x02000068, 0x00000002,
587 0x08000038, 0x001000f2, 0x00000000, 0x00101556, 0x00000000, 0x00208e46,
588 0x00000000, 0x00000001, 0x0a000032, 0x001000f2, 0x00000000, 0x00101006,
589 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46, 0x00000000,
590 0x0a000032, 0x001000f2, 0x00000000, 0x00101aa6, 0x00000000, 0x00208e46,
591 0x00000000, 0x00000002, 0x00100e46, 0x00000000, 0x08000000, 0x001000f2,
592 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000003,
593 0x08000038, 0x001000f2, 0x00000001, 0x00100556, 0x00000000, 0x00208e46,
594 0x00000000, 0x00000005, 0x0a000032, 0x001000f2, 0x00000001, 0x00100006,
595 0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x00100e46, 0x00000001,
596 0x0a000032, 0x001000f2, 0x00000001, 0x00100aa6, 0x00000000, 0x00208e46,
597 0x00000000, 0x00000006, 0x00100e46, 0x00000001, 0x0a000032, 0x001020f2,
598 0x00000000, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000007,
599 0x00100e46, 0x00000001, 0x05000036, 0x00102032, 0x00000001, 0x00101046,
600 0x00000001, 0x05000036, 0x001020f2, 0x00000002, 0x00101e46, 0x00000002,
601 0x0100003e, 0x54415453, 0x00000074, 0x0000000b, 0x00000002, 0x00000000,
602 0x00000006, 0x00000003, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
603 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
604 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
605 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
606 0x00000000, 0x00000000, 0x46454452, 0x000000fc, 0x00000001, 0x00000054,
607 0x00000001, 0x0000001c, 0xfffe0400, 0x00000100, 0x000000c6, 0x0000003c,
608 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
609 0x00000001, 0x74726556, 0x68537865, 0x72656461, 0x736e6f43, 0x746e6174,
610 0xabab0073, 0x0000003c, 0x00000002, 0x0000006c, 0x00000080, 0x00000000,
611 0x00000000, 0x0000009c, 0x00000000, 0x00000040, 0x00000002, 0x000000a4,
612 0x00000000, 0x000000b4, 0x00000040, 0x00000040, 0x00000002, 0x000000a4,
613 0x00000000, 0x65646f6d, 0xabab006c, 0x00030002, 0x00040004, 0x00000000,
614 0x00000000, 0x6a6f7270, 0x69746365, 0x6e416e6f, 0x65695664, 0x694d0077,
615 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564,
616 0x706d6f43, 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336,
617 0xababab00, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050,
618 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000707, 0x00000059,
619 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000062,
620 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x49534f50,
621 0x4e4f4954, 0x58455400, 0x524f4f43, 0x4f430044, 0x00524f4c, 0x4e47534f,
622 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001,
623 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000,
624 0x00000003, 0x00000001, 0x00000c03, 0x00000065, 0x00000000, 0x00000000,
625 0x00000003, 0x00000002, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49,
626 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f
628 #elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3)
629 static const DWORD D3D11_VertexShader[] = {
630 0x43425844, 0x01a24e41, 0x696af551, 0x4b2a87d1, 0x82ea03f6, 0x00000001,
631 0x00000598, 0x00000006, 0x00000038, 0x0000016c, 0x00000334, 0x000003b0,
632 0x000004b4, 0x00000524, 0x396e6f41, 0x0000012c, 0x0000012c, 0xfffe0200,
633 0x000000f8, 0x00000034, 0x00240001, 0x00300000, 0x00300000, 0x00240000,
634 0x00300001, 0x00000000, 0x00010008, 0x00000000, 0x00000000, 0xfffe0201,
635 0x0200001f, 0x80000005, 0x900f0000, 0x0200001f, 0x80010005, 0x900f0001,
636 0x0200001f, 0x80020005, 0x900f0002, 0x03000005, 0x800f0000, 0x90550000,
637 0xa0e40002, 0x04000004, 0x800f0000, 0x90000000, 0xa0e40001, 0x80e40000,
638 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40003, 0x80e40000, 0x03000002,
639 0x800f0000, 0x80e40000, 0xa0e40004, 0x03000005, 0x800f0001, 0x80550000,
640 0xa0e40006, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40005, 0x80e40001,
641 0x04000004, 0x800f0001, 0x80aa0000, 0xa0e40007, 0x80e40001, 0x04000004,
642 0x800f0000, 0x80ff0000, 0xa0e40008, 0x80e40001, 0x04000004, 0xc0030000,
643 0x80ff0000, 0xa0e40000, 0x80e40000, 0x02000001, 0xc00c0000, 0x80e40000,
644 0x02000001, 0xe0030000, 0x90e40001, 0x02000001, 0xe00f0001, 0x90e40002,
645 0x0000ffff, 0x52444853, 0x000001c0, 0x00010040, 0x00000070, 0x04000059,
646 0x00208e46, 0x00000000, 0x00000008, 0x0300005f, 0x00101072, 0x00000000,
647 0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x001010f2, 0x00000002,
648 0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x00102032,
649 0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x02000068, 0x00000002,
650 0x08000038, 0x001000f2, 0x00000000, 0x00101556, 0x00000000, 0x00208e46,
651 0x00000000, 0x00000001, 0x0a000032, 0x001000f2, 0x00000000, 0x00101006,
652 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46, 0x00000000,
653 0x0a000032, 0x001000f2, 0x00000000, 0x00101aa6, 0x00000000, 0x00208e46,
654 0x00000000, 0x00000002, 0x00100e46, 0x00000000, 0x08000000, 0x001000f2,
655 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000003,
656 0x08000038, 0x001000f2, 0x00000001, 0x00100556, 0x00000000, 0x00208e46,
657 0x00000000, 0x00000005, 0x0a000032, 0x001000f2, 0x00000001, 0x00100006,
658 0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x00100e46, 0x00000001,
659 0x0a000032, 0x001000f2, 0x00000001, 0x00100aa6, 0x00000000, 0x00208e46,
660 0x00000000, 0x00000006, 0x00100e46, 0x00000001, 0x0a000032, 0x001020f2,
661 0x00000000, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000007,
662 0x00100e46, 0x00000001, 0x05000036, 0x00102032, 0x00000001, 0x00101046,
663 0x00000001, 0x05000036, 0x001020f2, 0x00000002, 0x00101e46, 0x00000002,
664 0x0100003e, 0x54415453, 0x00000074, 0x0000000b, 0x00000002, 0x00000000,
665 0x00000006, 0x00000003, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
666 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
667 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
668 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
669 0x00000000, 0x00000000, 0x46454452, 0x000000fc, 0x00000001, 0x00000054,
670 0x00000001, 0x0000001c, 0xfffe0400, 0x00000100, 0x000000c6, 0x0000003c,
671 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
672 0x00000001, 0x74726556, 0x68537865, 0x72656461, 0x736e6f43, 0x746e6174,
673 0xabab0073, 0x0000003c, 0x00000002, 0x0000006c, 0x00000080, 0x00000000,
674 0x00000000, 0x0000009c, 0x00000000, 0x00000040, 0x00000002, 0x000000a4,
675 0x00000000, 0x000000b4, 0x00000040, 0x00000040, 0x00000002, 0x000000a4,
676 0x00000000, 0x65646f6d, 0xabab006c, 0x00030002, 0x00040004, 0x00000000,
677 0x00000000, 0x6a6f7270, 0x69746365, 0x6e416e6f, 0x65695664, 0x694d0077,
678 0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564,
679 0x706d6f43, 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336,
680 0xababab00, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050,
681 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000707, 0x00000059,
682 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000062,
683 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x49534f50,
684 0x4e4f4954, 0x58455400, 0x524f4f43, 0x4f430044, 0x00524f4c, 0x4e47534f,
685 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001,
686 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000,
687 0x00000003, 0x00000001, 0x00000c03, 0x00000065, 0x00000000, 0x00000000,
688 0x00000003, 0x00000002, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49,
689 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f
692 #error "An appropriate vertex shader is not defined."
696 /* Direct3D 11.1 renderer implementation */
697 static SDL_Renderer *D3D11_CreateRenderer(SDL_Window * window, Uint32 flags);
698 static void D3D11_WindowEvent(SDL_Renderer * renderer,
699 const SDL_WindowEvent *event);
700 static int D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
701 static int D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
702 const SDL_Rect * rect, const void *srcPixels,
704 static int D3D11_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
705 const SDL_Rect * rect,
706 const Uint8 *Yplane, int Ypitch,
707 const Uint8 *Uplane, int Upitch,
708 const Uint8 *Vplane, int Vpitch);
709 static int D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
710 const SDL_Rect * rect, void **pixels, int *pitch);
711 static void D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
712 static int D3D11_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
713 static int D3D11_UpdateViewport(SDL_Renderer * renderer);
714 static int D3D11_UpdateClipRect(SDL_Renderer * renderer);
715 static int D3D11_RenderClear(SDL_Renderer * renderer);
716 static int D3D11_RenderDrawPoints(SDL_Renderer * renderer,
717 const SDL_FPoint * points, int count);
718 static int D3D11_RenderDrawLines(SDL_Renderer * renderer,
719 const SDL_FPoint * points, int count);
720 static int D3D11_RenderFillRects(SDL_Renderer * renderer,
721 const SDL_FRect * rects, int count);
722 static int D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
723 const SDL_Rect * srcrect, const SDL_FRect * dstrect);
724 static int D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
725 const SDL_Rect * srcrect, const SDL_FRect * dstrect,
726 const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip);
727 static int D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
728 Uint32 format, void * pixels, int pitch);
729 static void D3D11_RenderPresent(SDL_Renderer * renderer);
730 static void D3D11_DestroyTexture(SDL_Renderer * renderer,
731 SDL_Texture * texture);
732 static void D3D11_DestroyRenderer(SDL_Renderer * renderer);
734 /* Direct3D 11.1 Internal Functions */
735 static HRESULT D3D11_CreateDeviceResources(SDL_Renderer * renderer);
736 static HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer);
737 static HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer);
738 static HRESULT D3D11_HandleDeviceLost(SDL_Renderer * renderer);
739 static void D3D11_ReleaseMainRenderTargetView(SDL_Renderer * renderer);
741 SDL_RenderDriver D3D11_RenderDriver = {
742 D3D11_CreateRenderer,
746 SDL_RENDERER_ACCELERATED |
747 SDL_RENDERER_PRESENTVSYNC |
748 SDL_RENDERER_TARGETTEXTURE
749 ), /* flags. see SDL_RendererFlags */
750 4, /* num_texture_formats */
751 { /* texture_formats */
752 SDL_PIXELFORMAT_ARGB8888,
753 SDL_PIXELFORMAT_RGB888,
754 SDL_PIXELFORMAT_YV12,
757 0, /* max_texture_width: will be filled in later */
758 0 /* max_texture_height: will be filled in later */
764 D3D11_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat) {
765 switch (dxgiFormat) {
766 case DXGI_FORMAT_B8G8R8A8_UNORM:
767 return SDL_PIXELFORMAT_ARGB8888;
768 case DXGI_FORMAT_B8G8R8X8_UNORM:
769 return SDL_PIXELFORMAT_RGB888;
771 return SDL_PIXELFORMAT_UNKNOWN;
776 SDLPixelFormatToDXGIFormat(Uint32 sdlFormat)
779 case SDL_PIXELFORMAT_ARGB8888:
780 return DXGI_FORMAT_B8G8R8A8_UNORM;
781 case SDL_PIXELFORMAT_RGB888:
782 return DXGI_FORMAT_B8G8R8X8_UNORM;
783 case SDL_PIXELFORMAT_YV12:
784 case SDL_PIXELFORMAT_IYUV:
785 return DXGI_FORMAT_R8_UNORM;
787 return DXGI_FORMAT_UNKNOWN;
792 D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
794 SDL_Renderer *renderer;
795 D3D11_RenderData *data;
797 renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
803 data = (D3D11_RenderData *) SDL_calloc(1, sizeof(*data));
809 renderer->WindowEvent = D3D11_WindowEvent;
810 renderer->CreateTexture = D3D11_CreateTexture;
811 renderer->UpdateTexture = D3D11_UpdateTexture;
812 renderer->UpdateTextureYUV = D3D11_UpdateTextureYUV;
813 renderer->LockTexture = D3D11_LockTexture;
814 renderer->UnlockTexture = D3D11_UnlockTexture;
815 renderer->SetRenderTarget = D3D11_SetRenderTarget;
816 renderer->UpdateViewport = D3D11_UpdateViewport;
817 renderer->UpdateClipRect = D3D11_UpdateClipRect;
818 renderer->RenderClear = D3D11_RenderClear;
819 renderer->RenderDrawPoints = D3D11_RenderDrawPoints;
820 renderer->RenderDrawLines = D3D11_RenderDrawLines;
821 renderer->RenderFillRects = D3D11_RenderFillRects;
822 renderer->RenderCopy = D3D11_RenderCopy;
823 renderer->RenderCopyEx = D3D11_RenderCopyEx;
824 renderer->RenderReadPixels = D3D11_RenderReadPixels;
825 renderer->RenderPresent = D3D11_RenderPresent;
826 renderer->DestroyTexture = D3D11_DestroyTexture;
827 renderer->DestroyRenderer = D3D11_DestroyRenderer;
828 renderer->info = D3D11_RenderDriver.info;
829 renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
830 renderer->driverdata = data;
832 #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
833 /* VSync is required in Windows Phone, at least for Win Phone 8.0 and 8.1.
834 * Failure to use it seems to either result in:
836 * - with the D3D11 debug runtime turned OFF, vsync seemingly gets turned
837 * off (framerate doesn't get capped), but nothing appears on-screen
839 * - with the D3D11 debug runtime turned ON, vsync gets automatically
840 * turned back on, and the following gets output to the debug console:
842 * DXGI ERROR: IDXGISwapChain::Present: Interval 0 is not supported, changed to Interval 1. [ UNKNOWN ERROR #1024: ]
844 renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
846 if ((flags & SDL_RENDERER_PRESENTVSYNC)) {
847 renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
851 /* HACK: make sure the SDL_Renderer references the SDL_Window data now, in
852 * order to give init functions access to the underlying window handle:
854 renderer->window = window;
856 /* Initialize Direct3D resources */
857 if (FAILED(D3D11_CreateDeviceResources(renderer))) {
858 D3D11_DestroyRenderer(renderer);
861 if (FAILED(D3D11_CreateWindowSizeDependentResources(renderer))) {
862 D3D11_DestroyRenderer(renderer);
870 D3D11_ReleaseAll(SDL_Renderer * renderer)
872 D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
873 SDL_Texture *texture = NULL;
875 /* Release all textures */
876 for (texture = renderer->textures; texture; texture = texture->next) {
877 D3D11_DestroyTexture(renderer, texture);
880 /* Release/reset everything else */
882 SAFE_RELEASE(data->dxgiFactory);
883 SAFE_RELEASE(data->dxgiAdapter);
884 SAFE_RELEASE(data->d3dDevice);
885 SAFE_RELEASE(data->d3dContext);
886 SAFE_RELEASE(data->swapChain);
887 SAFE_RELEASE(data->mainRenderTargetView);
888 SAFE_RELEASE(data->currentOffscreenRenderTargetView);
889 SAFE_RELEASE(data->inputLayout);
890 SAFE_RELEASE(data->vertexBuffer);
891 SAFE_RELEASE(data->vertexShader);
892 SAFE_RELEASE(data->colorPixelShader);
893 SAFE_RELEASE(data->texturePixelShader);
894 SAFE_RELEASE(data->yuvPixelShader);
895 SAFE_RELEASE(data->blendModeBlend);
896 SAFE_RELEASE(data->blendModeAdd);
897 SAFE_RELEASE(data->blendModeMod);
898 SAFE_RELEASE(data->nearestPixelSampler);
899 SAFE_RELEASE(data->linearSampler);
900 SAFE_RELEASE(data->mainRasterizer);
901 SAFE_RELEASE(data->clippedRasterizer);
902 SAFE_RELEASE(data->vertexShaderConstants);
904 data->swapEffect = (DXGI_SWAP_EFFECT) 0;
905 data->rotation = DXGI_MODE_ROTATION_UNSPECIFIED;
906 data->currentRenderTargetView = NULL;
907 data->currentRasterizerState = NULL;
908 data->currentBlendState = NULL;
909 data->currentShader = NULL;
910 data->currentShaderResource = NULL;
911 data->currentSampler = NULL;
913 /* Unload the D3D libraries. This should be done last, in order
914 * to prevent IUnknown::Release() calls from crashing.
916 if (data->hD3D11Mod) {
917 SDL_UnloadObject(data->hD3D11Mod);
918 data->hD3D11Mod = NULL;
920 if (data->hDXGIMod) {
921 SDL_UnloadObject(data->hDXGIMod);
922 data->hDXGIMod = NULL;
928 D3D11_DestroyRenderer(SDL_Renderer * renderer)
930 D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
931 D3D11_ReleaseAll(renderer);
939 D3D11_CreateBlendMode(SDL_Renderer * renderer,
941 D3D11_BLEND srcBlend,
942 D3D11_BLEND destBlend,
943 D3D11_BLEND srcBlendAlpha,
944 D3D11_BLEND destBlendAlpha,
945 ID3D11BlendState ** blendStateOutput)
947 D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
948 HRESULT result = S_OK;
950 D3D11_BLEND_DESC blendDesc;
952 blendDesc.AlphaToCoverageEnable = FALSE;
953 blendDesc.IndependentBlendEnable = FALSE;
954 blendDesc.RenderTarget[0].BlendEnable = enableBlending;
955 blendDesc.RenderTarget[0].SrcBlend = srcBlend;
956 blendDesc.RenderTarget[0].DestBlend = destBlend;
957 blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
958 blendDesc.RenderTarget[0].SrcBlendAlpha = srcBlendAlpha;
959 blendDesc.RenderTarget[0].DestBlendAlpha = destBlendAlpha;
960 blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
961 blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
962 result = ID3D11Device_CreateBlendState(data->d3dDevice, &blendDesc, blendStateOutput);
963 if (FAILED(result)) {
964 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateBlendState", result);
971 /* Create resources that depend on the device. */
973 D3D11_CreateDeviceResources(SDL_Renderer * renderer)
975 typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory);
976 PFN_CREATE_DXGI_FACTORY CreateDXGIFactoryFunc;
977 D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
978 PFN_D3D11_CREATE_DEVICE D3D11CreateDeviceFunc;
979 IDXGIAdapter *d3dAdapter = NULL;
980 ID3D11Device *d3dDevice = NULL;
981 ID3D11DeviceContext *d3dContext = NULL;
982 IDXGIDevice1 *dxgiDevice = NULL;
983 HRESULT result = S_OK;
987 /* This array defines the set of DirectX hardware feature levels this app will support.
988 * Note the ordering should be preserved.
989 * Don't forget to declare your application's minimum required feature level in its
990 * description. All applications are assumed to support 9.1 unless otherwise stated.
992 D3D_FEATURE_LEVEL featureLevels[] =
994 D3D_FEATURE_LEVEL_11_1,
995 D3D_FEATURE_LEVEL_11_0,
996 D3D_FEATURE_LEVEL_10_1,
997 D3D_FEATURE_LEVEL_10_0,
998 D3D_FEATURE_LEVEL_9_3,
999 D3D_FEATURE_LEVEL_9_2,
1000 D3D_FEATURE_LEVEL_9_1
1003 /* Declare how the input layout for SDL's vertex shader will be setup: */
1004 const D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
1006 { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1007 { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1008 { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1011 D3D11_BUFFER_DESC constantBufferDesc;
1012 D3D11_SAMPLER_DESC samplerDesc;
1013 D3D11_RASTERIZER_DESC rasterDesc;
1016 CreateDXGIFactoryFunc = CreateDXGIFactory1;
1017 D3D11CreateDeviceFunc = D3D11CreateDevice;
1019 data->hDXGIMod = SDL_LoadObject("dxgi.dll");
1020 if (!data->hDXGIMod) {
1025 CreateDXGIFactoryFunc = (PFN_CREATE_DXGI_FACTORY)SDL_LoadFunction(data->hDXGIMod, "CreateDXGIFactory");
1026 if (!CreateDXGIFactoryFunc) {
1031 data->hD3D11Mod = SDL_LoadObject("d3d11.dll");
1032 if (!data->hD3D11Mod) {
1037 D3D11CreateDeviceFunc = (PFN_D3D11_CREATE_DEVICE)SDL_LoadFunction(data->hD3D11Mod, "D3D11CreateDevice");
1038 if (!D3D11CreateDeviceFunc) {
1042 #endif /* __WINRT__ */
1044 result = CreateDXGIFactoryFunc(&IID_IDXGIFactory2, &data->dxgiFactory);
1045 if (FAILED(result)) {
1046 WIN_SetErrorFromHRESULT(__FUNCTION__ ", CreateDXGIFactory", result);
1050 /* FIXME: Should we use the default adapter? */
1051 result = IDXGIFactory2_EnumAdapters(data->dxgiFactory, 0, &data->dxgiAdapter);
1052 if (FAILED(result)) {
1053 WIN_SetErrorFromHRESULT(__FUNCTION__ ", D3D11CreateDevice", result);
1057 /* This flag adds support for surfaces with a different color channel ordering
1058 * than the API default. It is required for compatibility with Direct2D.
1060 creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
1062 /* Make sure Direct3D's debugging feature gets used, if the app requests it. */
1063 hint = SDL_GetHint(SDL_HINT_RENDER_DIRECT3D11_DEBUG);
1064 if (hint && SDL_atoi(hint) > 0) {
1065 creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
1068 /* Create the Direct3D 11 API device object and a corresponding context. */
1069 result = D3D11CreateDeviceFunc(
1071 D3D_DRIVER_TYPE_UNKNOWN,
1073 creationFlags, /* Set set debug and Direct2D compatibility flags. */
1074 featureLevels, /* List of feature levels this app can support. */
1075 SDL_arraysize(featureLevels),
1076 D3D11_SDK_VERSION, /* Always set this to D3D11_SDK_VERSION for Windows Store apps. */
1077 &d3dDevice, /* Returns the Direct3D device created. */
1078 &data->featureLevel, /* Returns feature level of device created. */
1079 &d3dContext /* Returns the device immediate context. */
1081 if (FAILED(result)) {
1082 WIN_SetErrorFromHRESULT(__FUNCTION__ ", D3D11CreateDevice", result);
1086 result = ID3D11Device_QueryInterface(d3dDevice, &IID_ID3D11Device1, &data->d3dDevice);
1087 if (FAILED(result)) {
1088 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to ID3D11Device1", result);
1092 result = ID3D11DeviceContext_QueryInterface(d3dContext, &IID_ID3D11DeviceContext1, &data->d3dContext);
1093 if (FAILED(result)) {
1094 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext to ID3D11DeviceContext1", result);
1098 result = ID3D11Device_QueryInterface(d3dDevice, &IID_IDXGIDevice1, &dxgiDevice);
1099 if (FAILED(result)) {
1100 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to IDXGIDevice1", result);
1104 /* Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
1105 * ensures that the application will only render after each VSync, minimizing power consumption.
1107 result = IDXGIDevice1_SetMaximumFrameLatency(dxgiDevice, 1);
1108 if (FAILED(result)) {
1109 WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIDevice1::SetMaximumFrameLatency", result);
1113 /* Make note of the maximum texture size
1114 * Max texture sizes are documented on MSDN, at:
1115 * http://msdn.microsoft.com/en-us/library/windows/apps/ff476876.aspx
1117 switch (data->featureLevel) {
1118 case D3D_FEATURE_LEVEL_11_1:
1119 case D3D_FEATURE_LEVEL_11_0:
1120 renderer->info.max_texture_width = renderer->info.max_texture_height = 16384;
1123 case D3D_FEATURE_LEVEL_10_1:
1124 case D3D_FEATURE_LEVEL_10_0:
1125 renderer->info.max_texture_width = renderer->info.max_texture_height = 8192;
1128 case D3D_FEATURE_LEVEL_9_3:
1129 renderer->info.max_texture_width = renderer->info.max_texture_height = 4096;
1132 case D3D_FEATURE_LEVEL_9_2:
1133 case D3D_FEATURE_LEVEL_9_1:
1134 renderer->info.max_texture_width = renderer->info.max_texture_height = 2048;
1138 SDL_SetError(__FUNCTION__ ", Unexpected feature level: %d", data->featureLevel);
1143 /* Load in SDL's one and only vertex shader: */
1144 result = ID3D11Device_CreateVertexShader(data->d3dDevice,
1146 sizeof(D3D11_VertexShader),
1150 if (FAILED(result)) {
1151 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateVertexShader", result);
1155 /* Create an input layout for SDL's vertex shader: */
1156 result = ID3D11Device_CreateInputLayout(data->d3dDevice,
1158 ARRAYSIZE(vertexDesc),
1160 sizeof(D3D11_VertexShader),
1163 if (FAILED(result)) {
1164 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateInputLayout", result);
1168 /* Load in SDL's pixel shaders */
1169 result = ID3D11Device_CreatePixelShader(data->d3dDevice,
1170 D3D11_PixelShader_Colors,
1171 sizeof(D3D11_PixelShader_Colors),
1173 &data->colorPixelShader
1175 if (FAILED(result)) {
1176 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreatePixelShader ['color' shader]", result);
1180 result = ID3D11Device_CreatePixelShader(data->d3dDevice,
1181 D3D11_PixelShader_Textures,
1182 sizeof(D3D11_PixelShader_Textures),
1184 &data->texturePixelShader
1186 if (FAILED(result)) {
1187 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreatePixelShader ['textures' shader]", result);
1191 result = ID3D11Device_CreatePixelShader(data->d3dDevice,
1192 D3D11_PixelShader_YUV,
1193 sizeof(D3D11_PixelShader_YUV),
1195 &data->yuvPixelShader
1197 if (FAILED(result)) {
1198 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreatePixelShader ['yuv' shader]", result);
1202 /* Setup space to hold vertex shader constants: */
1203 SDL_zero(constantBufferDesc);
1204 constantBufferDesc.ByteWidth = sizeof(VertexShaderConstants);
1205 constantBufferDesc.Usage = D3D11_USAGE_DEFAULT;
1206 constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
1207 result = ID3D11Device_CreateBuffer(data->d3dDevice,
1208 &constantBufferDesc,
1210 &data->vertexShaderConstants
1212 if (FAILED(result)) {
1213 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateBuffer [vertex shader constants]", result);
1217 /* Create samplers to use when drawing textures: */
1218 SDL_zero(samplerDesc);
1219 samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
1220 samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
1221 samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
1222 samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
1223 samplerDesc.MipLODBias = 0.0f;
1224 samplerDesc.MaxAnisotropy = 1;
1225 samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
1226 samplerDesc.MinLOD = 0.0f;
1227 samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
1228 result = ID3D11Device_CreateSamplerState(data->d3dDevice,
1230 &data->nearestPixelSampler
1232 if (FAILED(result)) {
1233 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateSamplerState [nearest-pixel filter]", result);
1237 samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
1238 result = ID3D11Device_CreateSamplerState(data->d3dDevice,
1240 &data->linearSampler
1242 if (FAILED(result)) {
1243 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateSamplerState [linear filter]", result);
1247 /* Setup Direct3D rasterizer states */
1248 SDL_zero(rasterDesc);
1249 rasterDesc.AntialiasedLineEnable = FALSE;
1250 rasterDesc.CullMode = D3D11_CULL_NONE;
1251 rasterDesc.DepthBias = 0;
1252 rasterDesc.DepthBiasClamp = 0.0f;
1253 rasterDesc.DepthClipEnable = TRUE;
1254 rasterDesc.FillMode = D3D11_FILL_SOLID;
1255 rasterDesc.FrontCounterClockwise = FALSE;
1256 rasterDesc.MultisampleEnable = FALSE;
1257 rasterDesc.ScissorEnable = FALSE;
1258 rasterDesc.SlopeScaledDepthBias = 0.0f;
1259 result = ID3D11Device_CreateRasterizerState(data->d3dDevice, &rasterDesc, &data->mainRasterizer);
1260 if (FAILED(result)) {
1261 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRasterizerState [main rasterizer]", result);
1265 rasterDesc.ScissorEnable = TRUE;
1266 result = ID3D11Device_CreateRasterizerState(data->d3dDevice, &rasterDesc, &data->clippedRasterizer);
1267 if (FAILED(result)) {
1268 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRasterizerState [clipped rasterizer]", result);
1272 /* Create blending states: */
1273 result = D3D11_CreateBlendMode(
1276 D3D11_BLEND_SRC_ALPHA, /* srcBlend */
1277 D3D11_BLEND_INV_SRC_ALPHA, /* destBlend */
1278 D3D11_BLEND_ONE, /* srcBlendAlpha */
1279 D3D11_BLEND_INV_SRC_ALPHA, /* destBlendAlpha */
1280 &data->blendModeBlend);
1281 if (FAILED(result)) {
1282 /* D3D11_CreateBlendMode will set the SDL error, if it fails */
1286 result = D3D11_CreateBlendMode(
1289 D3D11_BLEND_SRC_ALPHA, /* srcBlend */
1290 D3D11_BLEND_ONE, /* destBlend */
1291 D3D11_BLEND_ZERO, /* srcBlendAlpha */
1292 D3D11_BLEND_ONE, /* destBlendAlpha */
1293 &data->blendModeAdd);
1294 if (FAILED(result)) {
1295 /* D3D11_CreateBlendMode will set the SDL error, if it fails */
1299 result = D3D11_CreateBlendMode(
1302 D3D11_BLEND_ZERO, /* srcBlend */
1303 D3D11_BLEND_SRC_COLOR, /* destBlend */
1304 D3D11_BLEND_ZERO, /* srcBlendAlpha */
1305 D3D11_BLEND_ONE, /* destBlendAlpha */
1306 &data->blendModeMod);
1307 if (FAILED(result)) {
1308 /* D3D11_CreateBlendMode will set the SDL error, if it fails */
1312 /* Setup render state that doesn't change */
1313 ID3D11DeviceContext_IASetInputLayout(data->d3dContext, data->inputLayout);
1314 ID3D11DeviceContext_VSSetShader(data->d3dContext, data->vertexShader, NULL, 0);
1315 ID3D11DeviceContext_VSSetConstantBuffers(data->d3dContext, 0, 1, &data->vertexShaderConstants);
1318 SAFE_RELEASE(d3dDevice);
1319 SAFE_RELEASE(d3dContext);
1320 SAFE_RELEASE(dxgiDevice);
1326 static DXGI_MODE_ROTATION
1327 D3D11_GetCurrentRotation()
1330 return DXGI_MODE_ROTATION_IDENTITY;
1333 #endif /* __WIN32__ */
1336 D3D11_IsDisplayRotated90Degrees(DXGI_MODE_ROTATION rotation)
1339 case DXGI_MODE_ROTATION_ROTATE90:
1340 case DXGI_MODE_ROTATION_ROTATE270:
1348 D3D11_GetRotationForCurrentRenderTarget(SDL_Renderer * renderer)
1350 D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
1351 if (data->currentOffscreenRenderTargetView) {
1352 return DXGI_MODE_ROTATION_IDENTITY;
1354 return data->rotation;
1359 D3D11_GetViewportAlignedD3DRect(SDL_Renderer * renderer, const SDL_Rect * sdlRect, D3D11_RECT * outRect, BOOL includeViewportOffset)
1361 D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
1362 const int rotation = D3D11_GetRotationForCurrentRenderTarget(renderer);
1364 case DXGI_MODE_ROTATION_IDENTITY:
1365 outRect->left = sdlRect->x;
1366 outRect->right = sdlRect->x + sdlRect->w;
1367 outRect->top = sdlRect->y;
1368 outRect->bottom = sdlRect->y + sdlRect->h;
1369 if (includeViewportOffset) {
1370 outRect->left += renderer->viewport.x;
1371 outRect->right += renderer->viewport.x;
1372 outRect->top += renderer->viewport.y;
1373 outRect->bottom += renderer->viewport.y;
1376 case DXGI_MODE_ROTATION_ROTATE270:
1377 outRect->left = sdlRect->y;
1378 outRect->right = sdlRect->y + sdlRect->h;
1379 outRect->top = renderer->viewport.w - sdlRect->x - sdlRect->w;
1380 outRect->bottom = renderer->viewport.w - sdlRect->x;
1382 case DXGI_MODE_ROTATION_ROTATE180:
1383 outRect->left = renderer->viewport.w - sdlRect->x - sdlRect->w;
1384 outRect->right = renderer->viewport.w - sdlRect->x;
1385 outRect->top = renderer->viewport.h - sdlRect->y - sdlRect->h;
1386 outRect->bottom = renderer->viewport.h - sdlRect->y;
1388 case DXGI_MODE_ROTATION_ROTATE90:
1389 outRect->left = renderer->viewport.h - sdlRect->y - sdlRect->h;
1390 outRect->right = renderer->viewport.h - sdlRect->y;
1391 outRect->top = sdlRect->x;
1392 outRect->bottom = sdlRect->x + sdlRect->h;
1395 return SDL_SetError("The physical display is in an unknown or unsupported rotation");
1401 D3D11_CreateSwapChain(SDL_Renderer * renderer, int w, int h)
1403 D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
1405 IUnknown *coreWindow = D3D11_GetCoreWindowFromSDLRenderer(renderer);
1406 const BOOL usingXAML = (coreWindow == NULL);
1408 IUnknown *coreWindow = NULL;
1409 const BOOL usingXAML = FALSE;
1411 HRESULT result = S_OK;
1413 /* Create a swap chain using the same adapter as the existing Direct3D device. */
1414 DXGI_SWAP_CHAIN_DESC1 swapChainDesc;
1415 SDL_zero(swapChainDesc);
1416 swapChainDesc.Width = w;
1417 swapChainDesc.Height = h;
1418 swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; /* This is the most common swap chain format. */
1419 swapChainDesc.Stereo = FALSE;
1420 swapChainDesc.SampleDesc.Count = 1; /* Don't use multi-sampling. */
1421 swapChainDesc.SampleDesc.Quality = 0;
1422 swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
1423 swapChainDesc.BufferCount = 2; /* Use double-buffering to minimize latency. */
1424 #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
1425 swapChainDesc.Scaling = DXGI_SCALING_STRETCH; /* On phone, only stretch and aspect-ratio stretch scaling are allowed. */
1426 swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; /* On phone, no swap effects are supported. */
1427 /* TODO, WinRT: see if Win 8.x DXGI_SWAP_CHAIN_DESC1 settings are available on Windows Phone 8.1, and if there's any advantage to having them on */
1430 swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
1432 swapChainDesc.Scaling = DXGI_SCALING_NONE;
1434 swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; /* All Windows Store apps must use this SwapEffect. */
1436 swapChainDesc.Flags = 0;
1439 result = IDXGIFactory2_CreateSwapChainForCoreWindow(data->dxgiFactory,
1440 (IUnknown *)data->d3dDevice,
1443 NULL, /* Allow on all displays. */
1446 if (FAILED(result)) {
1447 WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIFactory2::CreateSwapChainForCoreWindow", result);
1450 } else if (usingXAML) {
1451 result = IDXGIFactory2_CreateSwapChainForComposition(data->dxgiFactory,
1452 (IUnknown *)data->d3dDevice,
1456 if (FAILED(result)) {
1457 WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIFactory2::CreateSwapChainForComposition", result);
1461 #if WINAPI_FAMILY == WINAPI_FAMILY_APP
1462 result = ISwapChainBackgroundPanelNative_SetSwapChain(WINRT_GlobalSwapChainBackgroundPanelNative, (IDXGISwapChain *) data->swapChain);
1463 if (FAILED(result)) {
1464 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ISwapChainBackgroundPanelNative::SetSwapChain", result);
1468 SDL_SetError(__FUNCTION__ ", XAML support is not yet available for Windows Phone");
1474 SDL_SysWMinfo windowinfo;
1475 SDL_VERSION(&windowinfo.version);
1476 SDL_GetWindowWMInfo(renderer->window, &windowinfo);
1478 result = IDXGIFactory2_CreateSwapChainForHwnd(data->dxgiFactory,
1479 (IUnknown *)data->d3dDevice,
1480 windowinfo.info.win.window,
1483 NULL, /* Allow on all displays. */
1486 if (FAILED(result)) {
1487 WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIFactory2::CreateSwapChainForHwnd", result);
1491 IDXGIFactory_MakeWindowAssociation(data->dxgiFactory, windowinfo.info.win.window, DXGI_MWA_NO_WINDOW_CHANGES);
1493 SDL_SetError(__FUNCTION__", Unable to find something to attach a swap chain to");
1495 #endif /* ifdef __WIN32__ / else */
1497 data->swapEffect = swapChainDesc.SwapEffect;
1500 SAFE_RELEASE(coreWindow);
1505 /* Initialize all resources that change when the window's size changes. */
1507 D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
1509 D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
1510 ID3D11Texture2D *backBuffer = NULL;
1511 HRESULT result = S_OK;
1514 /* Release the previous render target view */
1515 D3D11_ReleaseMainRenderTargetView(renderer);
1517 /* The width and height of the swap chain must be based on the display's
1520 SDL_GetWindowSize(renderer->window, &w, &h);
1521 data->rotation = D3D11_GetCurrentRotation();
1522 /* SDL_Log("%s: windowSize={%d,%d}, orientation=%d\n", __FUNCTION__, w, h, (int)data->rotation); */
1523 if (D3D11_IsDisplayRotated90Degrees(data->rotation)) {
1529 if (data->swapChain) {
1530 /* IDXGISwapChain::ResizeBuffers is not available on Windows Phone 8. */
1531 #if !defined(__WINRT__) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
1532 /* If the swap chain already exists, resize it. */
1533 result = IDXGISwapChain_ResizeBuffers(data->swapChain,
1536 DXGI_FORMAT_UNKNOWN,
1539 if (result == DXGI_ERROR_DEVICE_REMOVED) {
1540 /* If the device was removed for any reason, a new device and swap chain will need to be created. */
1541 D3D11_HandleDeviceLost(renderer);
1543 /* Everything is set up now. Do not continue execution of this method. HandleDeviceLost will reenter this method
1544 * and correctly set up the new device.
1547 } else if (FAILED(result)) {
1548 WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain::ResizeBuffers", result);
1553 result = D3D11_CreateSwapChain(renderer, w, h);
1554 if (FAILED(result)) {
1559 #if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
1560 /* Set the proper rotation for the swap chain.
1562 * To note, the call for this, IDXGISwapChain1::SetRotation, is not necessary
1563 * on Windows Phone 8.0, nor is it supported there.
1565 * IDXGISwapChain1::SetRotation does seem to be available on Windows Phone 8.1,
1566 * however I've yet to find a way to make it work. It might have something to
1567 * do with IDXGISwapChain::ResizeBuffers appearing to not being available on
1568 * Windows Phone 8.1 (it wasn't on Windows Phone 8.0), but I'm not 100% sure of this.
1569 * The call doesn't appear to be entirely necessary though, and is a performance-related
1570 * call, at least according to the following page on MSDN:
1571 * http://code.msdn.microsoft.com/windowsapps/DXGI-swap-chain-rotation-21d13d71
1574 * TODO, WinRT: reexamine the docs for IDXGISwapChain1::SetRotation, see if might be available, usable, and prudent-to-call on WinPhone 8.1
1576 if (data->swapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL) {
1577 result = IDXGISwapChain1_SetRotation(data->swapChain, data->rotation);
1578 if (FAILED(result)) {
1579 WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::SetRotation", result);
1585 result = IDXGISwapChain_GetBuffer(data->swapChain,
1587 &IID_ID3D11Texture2D,
1590 if (FAILED(result)) {
1591 WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain::GetBuffer [back-buffer]", result);
1595 /* Create a render target view of the swap chain back buffer. */
1596 result = ID3D11Device_CreateRenderTargetView(data->d3dDevice,
1597 (ID3D11Resource *)backBuffer,
1599 &data->mainRenderTargetView
1601 if (FAILED(result)) {
1602 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device::CreateRenderTargetView", result);
1606 if (D3D11_UpdateViewport(renderer) != 0) {
1607 /* D3D11_UpdateViewport will set the SDL error if it fails. */
1613 SAFE_RELEASE(backBuffer);
1617 /* This method is called when the window's size changes. */
1619 D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer)
1621 D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
1622 return D3D11_CreateWindowSizeDependentResources(renderer);
1626 D3D11_HandleDeviceLost(SDL_Renderer * renderer)
1628 D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
1629 HRESULT result = S_OK;
1631 D3D11_ReleaseAll(renderer);
1633 result = D3D11_CreateDeviceResources(renderer);
1634 if (FAILED(result)) {
1635 /* D3D11_CreateDeviceResources will set the SDL error */
1639 result = D3D11_UpdateForWindowSizeChange(renderer);
1640 if (FAILED(result)) {
1641 /* D3D11_UpdateForWindowSizeChange will set the SDL error */
1645 /* Let the application know that the device has been reset */
1648 event.type = SDL_RENDER_DEVICE_RESET;
1649 SDL_PushEvent(&event);
1656 D3D11_Trim(SDL_Renderer * renderer)
1659 #if NTDDI_VERSION > NTDDI_WIN8
1660 D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
1661 HRESULT result = S_OK;
1662 IDXGIDevice3 *dxgiDevice = NULL;
1664 result = ID3D11Device_QueryInterface(data->d3dDevice, &IID_IDXGIDevice3, &dxgiDevice);
1665 if (FAILED(result)) {
1666 //WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to IDXGIDevice3", result);
1670 IDXGIDevice3_Trim(dxgiDevice);
1671 SAFE_RELEASE(dxgiDevice);
1677 D3D11_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
1679 if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
1680 D3D11_UpdateForWindowSizeChange(renderer);
1685 GetScaleQuality(void)
1687 const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
1688 if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
1689 return D3D11_FILTER_MIN_MAG_MIP_POINT;
1690 } else /* if (*hint == '1' || SDL_strcasecmp(hint, "linear") == 0) */ {
1691 return D3D11_FILTER_MIN_MAG_MIP_LINEAR;
1696 D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
1698 D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
1699 D3D11_TextureData *textureData;
1701 DXGI_FORMAT textureFormat = SDLPixelFormatToDXGIFormat(texture->format);
1702 D3D11_TEXTURE2D_DESC textureDesc;
1703 D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc;
1705 if (textureFormat == SDL_PIXELFORMAT_UNKNOWN) {
1706 return SDL_SetError("%s, An unsupported SDL pixel format (0x%x) was specified",
1707 __FUNCTION__, texture->format);
1710 textureData = (D3D11_TextureData*) SDL_calloc(1, sizeof(*textureData));
1715 textureData->scaleMode = GetScaleQuality();
1717 texture->driverdata = textureData;
1719 SDL_zero(textureDesc);
1720 textureDesc.Width = texture->w;
1721 textureDesc.Height = texture->h;
1722 textureDesc.MipLevels = 1;
1723 textureDesc.ArraySize = 1;
1724 textureDesc.Format = textureFormat;
1725 textureDesc.SampleDesc.Count = 1;
1726 textureDesc.SampleDesc.Quality = 0;
1727 textureDesc.MiscFlags = 0;
1729 if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
1730 textureDesc.Usage = D3D11_USAGE_DYNAMIC;
1731 textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
1733 textureDesc.Usage = D3D11_USAGE_DEFAULT;
1734 textureDesc.CPUAccessFlags = 0;
1737 if (texture->access == SDL_TEXTUREACCESS_TARGET) {
1738 textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
1740 textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
1743 result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
1746 &textureData->mainTexture
1748 if (FAILED(result)) {
1749 D3D11_DestroyTexture(renderer, texture);
1750 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D", result);
1754 if (texture->format == SDL_PIXELFORMAT_YV12 ||
1755 texture->format == SDL_PIXELFORMAT_IYUV) {
1756 textureData->yuv = SDL_TRUE;
1758 textureDesc.Width /= 2;
1759 textureDesc.Height /= 2;
1761 result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
1764 &textureData->mainTextureU
1766 if (FAILED(result)) {
1767 D3D11_DestroyTexture(renderer, texture);
1768 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D", result);
1772 result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
1775 &textureData->mainTextureV
1777 if (FAILED(result)) {
1778 D3D11_DestroyTexture(renderer, texture);
1779 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D", result);
1784 resourceViewDesc.Format = textureDesc.Format;
1785 resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
1786 resourceViewDesc.Texture2D.MostDetailedMip = 0;
1787 resourceViewDesc.Texture2D.MipLevels = textureDesc.MipLevels;
1788 result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice,
1789 (ID3D11Resource *)textureData->mainTexture,
1791 &textureData->mainTextureResourceView
1793 if (FAILED(result)) {
1794 D3D11_DestroyTexture(renderer, texture);
1795 WIN_SetErrorFromHRESULT(__FUNCTION__ "ID3D11Device1::CreateShaderResourceView", result);
1799 if (textureData->yuv) {
1800 result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice,
1801 (ID3D11Resource *)textureData->mainTextureU,
1803 &textureData->mainTextureResourceViewU
1805 if (FAILED(result)) {
1806 D3D11_DestroyTexture(renderer, texture);
1807 WIN_SetErrorFromHRESULT(__FUNCTION__ "ID3D11Device1::CreateShaderResourceView", result);
1810 result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice,
1811 (ID3D11Resource *)textureData->mainTextureV,
1813 &textureData->mainTextureResourceViewV
1815 if (FAILED(result)) {
1816 D3D11_DestroyTexture(renderer, texture);
1817 WIN_SetErrorFromHRESULT(__FUNCTION__ "ID3D11Device1::CreateShaderResourceView", result);
1822 if (texture->access & SDL_TEXTUREACCESS_TARGET) {
1823 D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
1824 renderTargetViewDesc.Format = textureDesc.Format;
1825 renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
1826 renderTargetViewDesc.Texture2D.MipSlice = 0;
1828 result = ID3D11Device_CreateRenderTargetView(rendererData->d3dDevice,
1829 (ID3D11Resource *)textureData->mainTexture,
1830 &renderTargetViewDesc,
1831 &textureData->mainTextureRenderTargetView);
1832 if (FAILED(result)) {
1833 D3D11_DestroyTexture(renderer, texture);
1834 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRenderTargetView", result);
1843 D3D11_DestroyTexture(SDL_Renderer * renderer,
1844 SDL_Texture * texture)
1846 D3D11_TextureData *data = (D3D11_TextureData *)texture->driverdata;
1852 SAFE_RELEASE(data->mainTexture);
1853 SAFE_RELEASE(data->mainTextureResourceView);
1854 SAFE_RELEASE(data->mainTextureRenderTargetView);
1855 SAFE_RELEASE(data->stagingTexture);
1856 SAFE_RELEASE(data->mainTextureU);
1857 SAFE_RELEASE(data->mainTextureResourceViewU);
1858 SAFE_RELEASE(data->mainTextureV);
1859 SAFE_RELEASE(data->mainTextureResourceViewV);
1860 SDL_free(data->pixels);
1862 texture->driverdata = NULL;
1866 D3D11_UpdateTextureInternal(D3D11_RenderData *rendererData, ID3D11Texture2D *texture, Uint32 format, int x, int y, int w, int h, const void *pixels, int pitch)
1868 ID3D11Texture2D *stagingTexture;
1874 D3D11_TEXTURE2D_DESC stagingTextureDesc;
1875 D3D11_MAPPED_SUBRESOURCE textureMemory;
1877 /* Create a 'staging' texture, which will be used to write to a portion of the main texture. */
1878 ID3D11Texture2D_GetDesc(texture, &stagingTextureDesc);
1879 stagingTextureDesc.Width = w;
1880 stagingTextureDesc.Height = h;
1881 stagingTextureDesc.BindFlags = 0;
1882 stagingTextureDesc.MiscFlags = 0;
1883 stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
1884 stagingTextureDesc.Usage = D3D11_USAGE_STAGING;
1885 result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
1886 &stagingTextureDesc,
1889 if (FAILED(result)) {
1890 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D [create staging texture]", result);
1894 /* Get a write-only pointer to data in the staging texture: */
1895 result = ID3D11DeviceContext_Map(rendererData->d3dContext,
1896 (ID3D11Resource *)stagingTexture,
1902 if (FAILED(result)) {
1903 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [map staging texture]", result);
1904 SAFE_RELEASE(stagingTexture);
1908 src = (const Uint8 *)pixels;
1909 dst = textureMemory.pData;
1910 length = w * SDL_BYTESPERPIXEL(format);
1911 if (length == pitch && length == textureMemory.RowPitch) {
1912 SDL_memcpy(dst, src, length*h);
1914 if (length > (UINT)pitch) {
1917 if (length > textureMemory.RowPitch) {
1918 length = textureMemory.RowPitch;
1920 for (row = 0; row < h; ++row) {
1921 SDL_memcpy(dst, src, length);
1923 dst += textureMemory.RowPitch;
1927 /* Commit the pixel buffer's changes back to the staging texture: */
1928 ID3D11DeviceContext_Unmap(rendererData->d3dContext,
1929 (ID3D11Resource *)stagingTexture,
1932 /* Copy the staging texture's contents back to the texture: */
1933 ID3D11DeviceContext_CopySubresourceRegion(rendererData->d3dContext,
1934 (ID3D11Resource *)texture,
1939 (ID3D11Resource *)stagingTexture,
1943 SAFE_RELEASE(stagingTexture);
1949 D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
1950 const SDL_Rect * rect, const void * srcPixels,
1953 D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata;
1954 D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata;
1957 SDL_SetError("Texture is not currently available");
1961 if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, texture->format, rect->x, rect->y, rect->w, rect->h, srcPixels, srcPitch) < 0) {
1965 if (textureData->yuv) {
1966 /* Skip to the correct offset into the next texture */
1967 srcPixels = (const void*)((const Uint8*)srcPixels + rect->h * srcPitch);
1969 if (D3D11_UpdateTextureInternal(rendererData, texture->format == SDL_PIXELFORMAT_YV12 ? textureData->mainTextureV : textureData->mainTextureU, texture->format, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, srcPixels, srcPitch / 2) < 0) {
1973 /* Skip to the correct offset into the next texture */
1974 srcPixels = (const void*)((const Uint8*)srcPixels + (rect->h * srcPitch) / 4);
1975 if (D3D11_UpdateTextureInternal(rendererData, texture->format == SDL_PIXELFORMAT_YV12 ? textureData->mainTextureU : textureData->mainTextureV, texture->format, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, srcPixels, srcPitch / 2) < 0) {
1983 D3D11_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
1984 const SDL_Rect * rect,
1985 const Uint8 *Yplane, int Ypitch,
1986 const Uint8 *Uplane, int Upitch,
1987 const Uint8 *Vplane, int Vpitch)
1989 D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata;
1990 D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata;
1993 SDL_SetError("Texture is not currently available");
1997 if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, texture->format, rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch) < 0) {
2000 if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTextureU, texture->format, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, Uplane, Upitch) < 0) {
2003 if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTextureV, texture->format, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, Vplane, Vpitch) < 0) {
2010 D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
2011 const SDL_Rect * rect, void **pixels, int *pitch)
2013 D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2014 D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
2015 HRESULT result = S_OK;
2016 D3D11_TEXTURE2D_DESC stagingTextureDesc;
2017 D3D11_MAPPED_SUBRESOURCE textureMemory;
2020 SDL_SetError("Texture is not currently available");
2024 if (textureData->yuv) {
2025 /* It's more efficient to upload directly... */
2026 if (!textureData->pixels) {
2027 textureData->pitch = texture->w;
2028 textureData->pixels = (Uint8 *)SDL_malloc((texture->h * textureData->pitch * 3) / 2);
2029 if (!textureData->pixels) {
2030 return SDL_OutOfMemory();
2033 textureData->locked_rect = *rect;
2035 (void *)((Uint8 *)textureData->pixels + rect->y * textureData->pitch +
2036 rect->x * SDL_BYTESPERPIXEL(texture->format));
2037 *pitch = textureData->pitch;
2041 if (textureData->stagingTexture) {
2042 return SDL_SetError("texture is already locked");
2045 /* Create a 'staging' texture, which will be used to write to a portion
2046 * of the main texture. This is necessary, as Direct3D 11.1 does not
2047 * have the ability to write a CPU-bound pixel buffer to a rectangular
2048 * subrect of a texture. Direct3D 11.1 can, however, write a pixel
2049 * buffer to an entire texture, hence the use of a staging texture.
2051 * TODO, WinRT: consider avoiding the use of a staging texture in D3D11_LockTexture if/when the entire texture is being updated
2053 ID3D11Texture2D_GetDesc(textureData->mainTexture, &stagingTextureDesc);
2054 stagingTextureDesc.Width = rect->w;
2055 stagingTextureDesc.Height = rect->h;
2056 stagingTextureDesc.BindFlags = 0;
2057 stagingTextureDesc.MiscFlags = 0;
2058 stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2059 stagingTextureDesc.Usage = D3D11_USAGE_STAGING;
2060 result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
2061 &stagingTextureDesc,
2063 &textureData->stagingTexture);
2064 if (FAILED(result)) {
2065 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D [create staging texture]", result);
2069 /* Get a write-only pointer to data in the staging texture: */
2070 result = ID3D11DeviceContext_Map(rendererData->d3dContext,
2071 (ID3D11Resource *)textureData->stagingTexture,
2077 if (FAILED(result)) {
2078 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [map staging texture]", result);
2079 SAFE_RELEASE(textureData->stagingTexture);
2083 /* Make note of where the staging texture will be written to
2084 * (on a call to SDL_UnlockTexture):
2086 textureData->lockedTexturePositionX = rect->x;
2087 textureData->lockedTexturePositionY = rect->y;
2089 /* Make sure the caller has information on the texture's pixel buffer,
2092 *pixels = textureMemory.pData;
2093 *pitch = textureMemory.RowPitch;
2098 D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
2100 D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2101 D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
2107 if (textureData->yuv) {
2108 const SDL_Rect *rect = &textureData->locked_rect;
2110 (void *) ((Uint8 *) textureData->pixels + rect->y * textureData->pitch +
2111 rect->x * SDL_BYTESPERPIXEL(texture->format));
2112 D3D11_UpdateTexture(renderer, texture, rect, pixels, textureData->pitch);
2116 /* Commit the pixel buffer's changes back to the staging texture: */
2117 ID3D11DeviceContext_Unmap(rendererData->d3dContext,
2118 (ID3D11Resource *)textureData->stagingTexture,
2121 /* Copy the staging texture's contents back to the main texture: */
2122 ID3D11DeviceContext_CopySubresourceRegion(rendererData->d3dContext,
2123 (ID3D11Resource *)textureData->mainTexture,
2125 textureData->lockedTexturePositionX,
2126 textureData->lockedTexturePositionY,
2128 (ID3D11Resource *)textureData->stagingTexture,
2132 SAFE_RELEASE(textureData->stagingTexture);
2136 D3D11_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
2138 D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2139 D3D11_TextureData *textureData = NULL;
2141 if (texture == NULL) {
2142 rendererData->currentOffscreenRenderTargetView = NULL;
2146 textureData = (D3D11_TextureData *) texture->driverdata;
2148 if (!textureData->mainTextureRenderTargetView) {
2149 return SDL_SetError("specified texture is not a render target");
2152 rendererData->currentOffscreenRenderTargetView = textureData->mainTextureRenderTargetView;
2158 D3D11_SetModelMatrix(SDL_Renderer *renderer, const Float4X4 *matrix)
2160 D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
2163 data->vertexShaderConstantsData.model = *matrix;
2165 data->vertexShaderConstantsData.model = MatrixIdentity();
2168 ID3D11DeviceContext_UpdateSubresource(data->d3dContext,
2169 (ID3D11Resource *)data->vertexShaderConstants,
2172 &data->vertexShaderConstantsData,
2179 D3D11_UpdateViewport(SDL_Renderer * renderer)
2181 D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
2182 Float4X4 projection;
2184 SDL_FRect orientationAlignedViewport;
2185 BOOL swapDimensions;
2186 D3D11_VIEWPORT viewport;
2187 const int rotation = D3D11_GetRotationForCurrentRenderTarget(renderer);
2189 if (renderer->viewport.w == 0 || renderer->viewport.h == 0) {
2190 /* If the viewport is empty, assume that it is because
2191 * SDL_CreateRenderer is calling it, and will call it again later
2192 * with a non-empty viewport.
2194 /* SDL_Log("%s, no viewport was set!\n", __FUNCTION__); */
2198 /* Make sure the SDL viewport gets rotated to that of the physical display's rotation.
2199 * Keep in mind here that the Y-axis will be been inverted (from Direct3D's
2200 * default coordinate system) so rotations will be done in the opposite
2201 * direction of the DXGI_MODE_ROTATION enumeration.
2204 case DXGI_MODE_ROTATION_IDENTITY:
2205 projection = MatrixIdentity();
2207 case DXGI_MODE_ROTATION_ROTATE270:
2208 projection = MatrixRotationZ(SDL_static_cast(float, M_PI * 0.5f));
2210 case DXGI_MODE_ROTATION_ROTATE180:
2211 projection = MatrixRotationZ(SDL_static_cast(float, M_PI));
2213 case DXGI_MODE_ROTATION_ROTATE90:
2214 projection = MatrixRotationZ(SDL_static_cast(float, -M_PI * 0.5f));
2217 return SDL_SetError("An unknown DisplayOrientation is being used");
2220 /* Update the view matrix */
2221 view.m[0][0] = 2.0f / renderer->viewport.w;
2222 view.m[0][1] = 0.0f;
2223 view.m[0][2] = 0.0f;
2224 view.m[0][3] = 0.0f;
2225 view.m[1][0] = 0.0f;
2226 view.m[1][1] = -2.0f / renderer->viewport.h;
2227 view.m[1][2] = 0.0f;
2228 view.m[1][3] = 0.0f;
2229 view.m[2][0] = 0.0f;
2230 view.m[2][1] = 0.0f;
2231 view.m[2][2] = 1.0f;
2232 view.m[2][3] = 0.0f;
2233 view.m[3][0] = -1.0f;
2234 view.m[3][1] = 1.0f;
2235 view.m[3][2] = 0.0f;
2236 view.m[3][3] = 1.0f;
2238 /* Combine the projection + view matrix together now, as both only get
2239 * set here (as of this writing, on Dec 26, 2013). When done, store it
2240 * for eventual transfer to the GPU.
2242 data->vertexShaderConstantsData.projectionAndView = MatrixMultiply(
2246 /* Reset the model matrix */
2247 D3D11_SetModelMatrix(renderer, NULL);
2249 /* Update the Direct3D viewport, which seems to be aligned to the
2250 * swap buffer's coordinate space, which is always in either
2251 * a landscape mode, for all Windows 8/RT devices, or a portrait mode,
2252 * for Windows Phone devices.
2254 swapDimensions = D3D11_IsDisplayRotated90Degrees(rotation);
2255 if (swapDimensions) {
2256 orientationAlignedViewport.x = (float) renderer->viewport.y;
2257 orientationAlignedViewport.y = (float) renderer->viewport.x;
2258 orientationAlignedViewport.w = (float) renderer->viewport.h;
2259 orientationAlignedViewport.h = (float) renderer->viewport.w;
2261 orientationAlignedViewport.x = (float) renderer->viewport.x;
2262 orientationAlignedViewport.y = (float) renderer->viewport.y;
2263 orientationAlignedViewport.w = (float) renderer->viewport.w;
2264 orientationAlignedViewport.h = (float) renderer->viewport.h;
2266 /* TODO, WinRT: get custom viewports working with non-Landscape modes (Portrait, PortraitFlipped, and LandscapeFlipped) */
2268 viewport.TopLeftX = orientationAlignedViewport.x;
2269 viewport.TopLeftY = orientationAlignedViewport.y;
2270 viewport.Width = orientationAlignedViewport.w;
2271 viewport.Height = orientationAlignedViewport.h;
2272 viewport.MinDepth = 0.0f;
2273 viewport.MaxDepth = 1.0f;
2274 /* SDL_Log("%s: D3D viewport = {%f,%f,%f,%f}\n", __FUNCTION__, viewport.TopLeftX, viewport.TopLeftY, viewport.Width, viewport.Height); */
2275 ID3D11DeviceContext_RSSetViewports(data->d3dContext, 1, &viewport);
2281 D3D11_UpdateClipRect(SDL_Renderer * renderer)
2283 D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
2285 if (!renderer->clipping_enabled) {
2286 ID3D11DeviceContext_RSSetScissorRects(data->d3dContext, 0, NULL);
2288 D3D11_RECT scissorRect;
2289 if (D3D11_GetViewportAlignedD3DRect(renderer, &renderer->clip_rect, &scissorRect, TRUE) != 0) {
2290 /* D3D11_GetViewportAlignedD3DRect will have set the SDL error */
2293 ID3D11DeviceContext_RSSetScissorRects(data->d3dContext, 1, &scissorRect);
2300 D3D11_ReleaseMainRenderTargetView(SDL_Renderer * renderer)
2302 D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
2303 ID3D11DeviceContext_OMSetRenderTargets(data->d3dContext, 0, NULL, NULL);
2304 SAFE_RELEASE(data->mainRenderTargetView);
2307 static ID3D11RenderTargetView *
2308 D3D11_GetCurrentRenderTargetView(SDL_Renderer * renderer)
2310 D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
2311 if (data->currentOffscreenRenderTargetView) {
2312 return data->currentOffscreenRenderTargetView;
2314 return data->mainRenderTargetView;
2319 D3D11_RenderClear(SDL_Renderer * renderer)
2321 D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
2322 const float colorRGBA[] = {
2323 (renderer->r / 255.0f),
2324 (renderer->g / 255.0f),
2325 (renderer->b / 255.0f),
2326 (renderer->a / 255.0f)
2328 ID3D11DeviceContext_ClearRenderTargetView(data->d3dContext,
2329 D3D11_GetCurrentRenderTargetView(renderer),
2336 D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
2337 const void * vertexData, size_t dataSizeInBytes)
2339 D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2340 D3D11_BUFFER_DESC vertexBufferDesc;
2341 HRESULT result = S_OK;
2342 D3D11_SUBRESOURCE_DATA vertexBufferData;
2343 const UINT stride = sizeof(VertexPositionColor);
2344 const UINT offset = 0;
2346 if (rendererData->vertexBuffer) {
2347 ID3D11Buffer_GetDesc(rendererData->vertexBuffer, &vertexBufferDesc);
2349 SDL_zero(vertexBufferDesc);
2352 if (rendererData->vertexBuffer && vertexBufferDesc.ByteWidth >= dataSizeInBytes) {
2353 D3D11_MAPPED_SUBRESOURCE mappedResource;
2354 result = ID3D11DeviceContext_Map(rendererData->d3dContext,
2355 (ID3D11Resource *)rendererData->vertexBuffer,
2357 D3D11_MAP_WRITE_DISCARD,
2361 if (FAILED(result)) {
2362 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [vertex buffer]", result);
2365 SDL_memcpy(mappedResource.pData, vertexData, dataSizeInBytes);
2366 ID3D11DeviceContext_Unmap(rendererData->d3dContext, (ID3D11Resource *)rendererData->vertexBuffer, 0);
2368 SAFE_RELEASE(rendererData->vertexBuffer);
2370 vertexBufferDesc.ByteWidth = (UINT) dataSizeInBytes;
2371 vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
2372 vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
2373 vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2375 SDL_zero(vertexBufferData);
2376 vertexBufferData.pSysMem = vertexData;
2377 vertexBufferData.SysMemPitch = 0;
2378 vertexBufferData.SysMemSlicePitch = 0;
2380 result = ID3D11Device_CreateBuffer(rendererData->d3dDevice,
2383 &rendererData->vertexBuffer
2385 if (FAILED(result)) {
2386 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateBuffer [vertex buffer]", result);
2390 ID3D11DeviceContext_IASetVertexBuffers(rendererData->d3dContext,
2393 &rendererData->vertexBuffer,
2403 D3D11_RenderStartDrawOp(SDL_Renderer * renderer)
2405 D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata;
2406 ID3D11RasterizerState *rasterizerState;
2407 ID3D11RenderTargetView *renderTargetView = D3D11_GetCurrentRenderTargetView(renderer);
2408 if (renderTargetView != rendererData->currentRenderTargetView) {
2409 ID3D11DeviceContext_OMSetRenderTargets(rendererData->d3dContext,
2414 rendererData->currentRenderTargetView = renderTargetView;
2417 if (!renderer->clipping_enabled) {
2418 rasterizerState = rendererData->mainRasterizer;
2420 rasterizerState = rendererData->clippedRasterizer;
2422 if (rasterizerState != rendererData->currentRasterizerState) {
2423 ID3D11DeviceContext_RSSetState(rendererData->d3dContext, rasterizerState);
2424 rendererData->currentRasterizerState = rasterizerState;
2429 D3D11_RenderSetBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
2431 D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata;
2432 ID3D11BlendState *blendState = NULL;
2433 switch (blendMode) {
2434 case SDL_BLENDMODE_BLEND:
2435 blendState = rendererData->blendModeBlend;
2437 case SDL_BLENDMODE_ADD:
2438 blendState = rendererData->blendModeAdd;
2440 case SDL_BLENDMODE_MOD:
2441 blendState = rendererData->blendModeMod;
2443 case SDL_BLENDMODE_NONE:
2447 if (blendState != rendererData->currentBlendState) {
2448 ID3D11DeviceContext_OMSetBlendState(rendererData->d3dContext, blendState, 0, 0xFFFFFFFF);
2449 rendererData->currentBlendState = blendState;
2454 D3D11_SetPixelShader(SDL_Renderer * renderer,
2455 ID3D11PixelShader * shader,
2456 int numShaderResources,
2457 ID3D11ShaderResourceView ** shaderResources,
2458 ID3D11SamplerState * sampler)
2460 D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2461 ID3D11ShaderResourceView *shaderResource;
2462 if (shader != rendererData->currentShader) {
2463 ID3D11DeviceContext_PSSetShader(rendererData->d3dContext, shader, NULL, 0);
2464 rendererData->currentShader = shader;
2466 if (numShaderResources > 0) {
2467 shaderResource = shaderResources[0];
2469 shaderResource = NULL;
2471 if (shaderResource != rendererData->currentShaderResource) {
2472 ID3D11DeviceContext_PSSetShaderResources(rendererData->d3dContext, 0, numShaderResources, shaderResources);
2473 rendererData->currentShaderResource = shaderResource;
2475 if (sampler != rendererData->currentSampler) {
2476 ID3D11DeviceContext_PSSetSamplers(rendererData->d3dContext, 0, 1, &sampler);
2477 rendererData->currentSampler = sampler;
2482 D3D11_RenderFinishDrawOp(SDL_Renderer * renderer,
2483 D3D11_PRIMITIVE_TOPOLOGY primitiveTopology,
2486 D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2488 ID3D11DeviceContext_IASetPrimitiveTopology(rendererData->d3dContext, primitiveTopology);
2489 ID3D11DeviceContext_Draw(rendererData->d3dContext, vertexCount, 0);
2493 D3D11_RenderDrawPoints(SDL_Renderer * renderer,
2494 const SDL_FPoint * points, int count)
2496 D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2498 VertexPositionColor *vertices;
2501 r = (float)(renderer->r / 255.0f);
2502 g = (float)(renderer->g / 255.0f);
2503 b = (float)(renderer->b / 255.0f);
2504 a = (float)(renderer->a / 255.0f);
2506 vertices = SDL_stack_alloc(VertexPositionColor, count);
2507 for (i = 0; i < count; ++i) {
2508 const VertexPositionColor v = { { points[i].x, points[i].y, 0.0f }, { 0.0f, 0.0f }, { r, g, b, a } };
2512 D3D11_RenderStartDrawOp(renderer);
2513 D3D11_RenderSetBlendMode(renderer, renderer->blendMode);
2514 if (D3D11_UpdateVertexBuffer(renderer, vertices, (unsigned int)count * sizeof(VertexPositionColor)) != 0) {
2515 SDL_stack_free(vertices);
2519 D3D11_SetPixelShader(
2521 rendererData->colorPixelShader,
2526 D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, count);
2527 SDL_stack_free(vertices);
2532 D3D11_RenderDrawLines(SDL_Renderer * renderer,
2533 const SDL_FPoint * points, int count)
2535 D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2537 VertexPositionColor *vertices;
2540 r = (float)(renderer->r / 255.0f);
2541 g = (float)(renderer->g / 255.0f);
2542 b = (float)(renderer->b / 255.0f);
2543 a = (float)(renderer->a / 255.0f);
2545 vertices = SDL_stack_alloc(VertexPositionColor, count);
2546 for (i = 0; i < count; ++i) {
2547 const VertexPositionColor v = { { points[i].x, points[i].y, 0.0f }, { 0.0f, 0.0f }, { r, g, b, a } };
2551 D3D11_RenderStartDrawOp(renderer);
2552 D3D11_RenderSetBlendMode(renderer, renderer->blendMode);
2553 if (D3D11_UpdateVertexBuffer(renderer, vertices, (unsigned int)count * sizeof(VertexPositionColor)) != 0) {
2554 SDL_stack_free(vertices);
2558 D3D11_SetPixelShader(
2560 rendererData->colorPixelShader,
2565 D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, count);
2566 SDL_stack_free(vertices);
2571 D3D11_RenderFillRects(SDL_Renderer * renderer,
2572 const SDL_FRect * rects, int count)
2574 D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2578 r = (float)(renderer->r / 255.0f);
2579 g = (float)(renderer->g / 255.0f);
2580 b = (float)(renderer->b / 255.0f);
2581 a = (float)(renderer->a / 255.0f);
2583 for (i = 0; i < count; ++i) {
2584 VertexPositionColor vertices[] = {
2585 { { rects[i].x, rects[i].y, 0.0f }, { 0.0f, 0.0f}, {r, g, b, a} },
2586 { { rects[i].x, rects[i].y + rects[i].h, 0.0f }, { 0.0f, 0.0f }, { r, g, b, a } },
2587 { { rects[i].x + rects[i].w, rects[i].y, 0.0f }, { 0.0f, 0.0f }, { r, g, b, a } },
2588 { { rects[i].x + rects[i].w, rects[i].y + rects[i].h, 0.0f }, { 0.0f, 0.0f }, { r, g, b, a } },
2591 D3D11_RenderStartDrawOp(renderer);
2592 D3D11_RenderSetBlendMode(renderer, renderer->blendMode);
2593 if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) {
2597 D3D11_SetPixelShader(
2599 rendererData->colorPixelShader,
2604 D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, SDL_arraysize(vertices));
2610 static ID3D11SamplerState *
2611 D3D11_RenderGetSampler(SDL_Renderer * renderer, SDL_Texture * texture)
2613 D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2614 D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
2616 switch (textureData->scaleMode) {
2617 case D3D11_FILTER_MIN_MAG_MIP_POINT:
2618 return rendererData->nearestPixelSampler;
2619 case D3D11_FILTER_MIN_MAG_MIP_LINEAR:
2620 return rendererData->linearSampler;
2627 D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
2628 const SDL_Rect * srcrect, const SDL_FRect * dstrect)
2630 D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2631 D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
2632 float minu, maxu, minv, maxv;
2634 VertexPositionColor vertices[4];
2635 ID3D11SamplerState *textureSampler;
2637 D3D11_RenderStartDrawOp(renderer);
2638 D3D11_RenderSetBlendMode(renderer, texture->blendMode);
2640 minu = (float) srcrect->x / texture->w;
2641 maxu = (float) (srcrect->x + srcrect->w) / texture->w;
2642 minv = (float) srcrect->y / texture->h;
2643 maxv = (float) (srcrect->y + srcrect->h) / texture->h;
2645 color.x = 1.0f; /* red */
2646 color.y = 1.0f; /* green */
2647 color.z = 1.0f; /* blue */
2648 color.w = 1.0f; /* alpha */
2649 if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
2650 color.x = (float)(texture->r / 255.0f); /* red */
2651 color.y = (float)(texture->g / 255.0f); /* green */
2652 color.z = (float)(texture->b / 255.0f); /* blue */
2654 if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) {
2655 color.w = (float)(texture->a / 255.0f); /* alpha */
2658 vertices[0].pos.x = dstrect->x;
2659 vertices[0].pos.y = dstrect->y;
2660 vertices[0].pos.z = 0.0f;
2661 vertices[0].tex.x = minu;
2662 vertices[0].tex.y = minv;
2663 vertices[0].color = color;
2665 vertices[1].pos.x = dstrect->x;
2666 vertices[1].pos.y = dstrect->y + dstrect->h;
2667 vertices[1].pos.z = 0.0f;
2668 vertices[1].tex.x = minu;
2669 vertices[1].tex.y = maxv;
2670 vertices[1].color = color;
2672 vertices[2].pos.x = dstrect->x + dstrect->w;
2673 vertices[2].pos.y = dstrect->y;
2674 vertices[2].pos.z = 0.0f;
2675 vertices[2].tex.x = maxu;
2676 vertices[2].tex.y = minv;
2677 vertices[2].color = color;
2679 vertices[3].pos.x = dstrect->x + dstrect->w;
2680 vertices[3].pos.y = dstrect->y + dstrect->h;
2681 vertices[3].pos.z = 0.0f;
2682 vertices[3].tex.x = maxu;
2683 vertices[3].tex.y = maxv;
2684 vertices[3].color = color;
2686 if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) {
2690 textureSampler = D3D11_RenderGetSampler(renderer, texture);
2691 if (textureData->yuv) {
2692 ID3D11ShaderResourceView *shaderResources[] = {
2693 textureData->mainTextureResourceView,
2694 textureData->mainTextureResourceViewU,
2695 textureData->mainTextureResourceViewV
2697 D3D11_SetPixelShader(
2699 rendererData->yuvPixelShader,
2700 SDL_arraysize(shaderResources),
2704 D3D11_SetPixelShader(
2706 rendererData->texturePixelShader,
2708 &textureData->mainTextureResourceView,
2712 D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor));
2718 D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
2719 const SDL_Rect * srcrect, const SDL_FRect * dstrect,
2720 const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip)
2722 D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2723 D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
2724 float minu, maxu, minv, maxv;
2726 Float4X4 modelMatrix;
2727 float minx, maxx, miny, maxy;
2728 VertexPositionColor vertices[4];
2729 ID3D11SamplerState *textureSampler;
2731 D3D11_RenderStartDrawOp(renderer);
2732 D3D11_RenderSetBlendMode(renderer, texture->blendMode);
2734 minu = (float) srcrect->x / texture->w;
2735 maxu = (float) (srcrect->x + srcrect->w) / texture->w;
2736 minv = (float) srcrect->y / texture->h;
2737 maxv = (float) (srcrect->y + srcrect->h) / texture->h;
2739 color.x = 1.0f; /* red */
2740 color.y = 1.0f; /* green */
2741 color.z = 1.0f; /* blue */
2742 color.w = 1.0f; /* alpha */
2743 if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
2744 color.x = (float)(texture->r / 255.0f); /* red */
2745 color.y = (float)(texture->g / 255.0f); /* green */
2746 color.z = (float)(texture->b / 255.0f); /* blue */
2748 if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) {
2749 color.w = (float)(texture->a / 255.0f); /* alpha */
2752 if (flip & SDL_FLIP_HORIZONTAL) {
2757 if (flip & SDL_FLIP_VERTICAL) {
2763 modelMatrix = MatrixMultiply(
2764 MatrixRotationZ((float)(M_PI * (float) angle / 180.0f)),
2765 MatrixTranslation(dstrect->x + center->x, dstrect->y + center->y, 0)
2767 D3D11_SetModelMatrix(renderer, &modelMatrix);
2770 maxx = dstrect->w - center->x;
2772 maxy = dstrect->h - center->y;
2774 vertices[0].pos.x = minx;
2775 vertices[0].pos.y = miny;
2776 vertices[0].pos.z = 0.0f;
2777 vertices[0].tex.x = minu;
2778 vertices[0].tex.y = minv;
2779 vertices[0].color = color;
2781 vertices[1].pos.x = minx;
2782 vertices[1].pos.y = maxy;
2783 vertices[1].pos.z = 0.0f;
2784 vertices[1].tex.x = minu;
2785 vertices[1].tex.y = maxv;
2786 vertices[1].color = color;
2788 vertices[2].pos.x = maxx;
2789 vertices[2].pos.y = miny;
2790 vertices[2].pos.z = 0.0f;
2791 vertices[2].tex.x = maxu;
2792 vertices[2].tex.y = minv;
2793 vertices[2].color = color;
2795 vertices[3].pos.x = maxx;
2796 vertices[3].pos.y = maxy;
2797 vertices[3].pos.z = 0.0f;
2798 vertices[3].tex.x = maxu;
2799 vertices[3].tex.y = maxv;
2800 vertices[3].color = color;
2802 if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) {
2806 textureSampler = D3D11_RenderGetSampler(renderer, texture);
2807 if (textureData->yuv) {
2808 ID3D11ShaderResourceView *shaderResources[] = {
2809 textureData->mainTextureResourceView,
2810 textureData->mainTextureResourceViewU,
2811 textureData->mainTextureResourceViewV
2813 D3D11_SetPixelShader(
2815 rendererData->yuvPixelShader,
2816 SDL_arraysize(shaderResources),
2820 D3D11_SetPixelShader(
2822 rendererData->texturePixelShader,
2824 &textureData->mainTextureResourceView,
2828 D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor));
2830 D3D11_SetModelMatrix(renderer, NULL);
2836 D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
2837 Uint32 format, void * pixels, int pitch)
2839 D3D11_RenderData * data = (D3D11_RenderData *) renderer->driverdata;
2840 ID3D11Texture2D *backBuffer = NULL;
2841 ID3D11Texture2D *stagingTexture = NULL;
2844 D3D11_TEXTURE2D_DESC stagingTextureDesc;
2847 D3D11_MAPPED_SUBRESOURCE textureMemory;
2849 /* Retrieve a pointer to the back buffer: */
2850 result = IDXGISwapChain_GetBuffer(data->swapChain,
2852 &IID_ID3D11Texture2D,
2855 if (FAILED(result)) {
2856 WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::GetBuffer [get back buffer]", result);
2860 /* Create a staging texture to copy the screen's data to: */
2861 ID3D11Texture2D_GetDesc(backBuffer, &stagingTextureDesc);
2862 stagingTextureDesc.Width = rect->w;
2863 stagingTextureDesc.Height = rect->h;
2864 stagingTextureDesc.BindFlags = 0;
2865 stagingTextureDesc.MiscFlags = 0;
2866 stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
2867 stagingTextureDesc.Usage = D3D11_USAGE_STAGING;
2868 result = ID3D11Device_CreateTexture2D(data->d3dDevice,
2869 &stagingTextureDesc,
2872 if (FAILED(result)) {
2873 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D [create staging texture]", result);
2877 /* Copy the desired portion of the back buffer to the staging texture: */
2878 if (D3D11_GetViewportAlignedD3DRect(renderer, rect, &srcRect, FALSE) != 0) {
2879 /* D3D11_GetViewportAlignedD3DRect will have set the SDL error */
2883 srcBox.left = srcRect.left;
2884 srcBox.right = srcRect.right;
2885 srcBox.top = srcRect.top;
2886 srcBox.bottom = srcRect.bottom;
2889 ID3D11DeviceContext_CopySubresourceRegion(data->d3dContext,
2890 (ID3D11Resource *)stagingTexture,
2893 (ID3D11Resource *)backBuffer,
2897 /* Map the staging texture's data to CPU-accessible memory: */
2898 result = ID3D11DeviceContext_Map(data->d3dContext,
2899 (ID3D11Resource *)stagingTexture,
2904 if (FAILED(result)) {
2905 WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [map staging texture]", result);
2909 /* Copy the data into the desired buffer, converting pixels to the
2910 * desired format at the same time:
2912 if (SDL_ConvertPixels(
2914 D3D11_DXGIFormatToSDLPixelFormat(stagingTextureDesc.Format),
2915 textureMemory.pData,
2916 textureMemory.RowPitch,
2920 /* When SDL_ConvertPixels fails, it'll have already set the format.
2921 * Get the error message, and attach some extra data to it.
2923 char errorMessage[1024];
2924 SDL_snprintf(errorMessage, sizeof(errorMessage), __FUNCTION__ ", Convert Pixels failed: %s", SDL_GetError());
2925 SDL_SetError("%s", errorMessage);
2929 /* Unmap the texture: */
2930 ID3D11DeviceContext_Unmap(data->d3dContext,
2931 (ID3D11Resource *)stagingTexture,
2937 SAFE_RELEASE(backBuffer);
2938 SAFE_RELEASE(stagingTexture);
2943 D3D11_RenderPresent(SDL_Renderer * renderer)
2945 D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
2949 DXGI_PRESENT_PARAMETERS parameters;
2951 SDL_zero(parameters);
2953 #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
2956 result = IDXGISwapChain_Present(data->swapChain, syncInterval, presentFlags);
2958 if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) {
2963 presentFlags = DXGI_PRESENT_DO_NOT_WAIT;
2966 /* The application may optionally specify "dirty" or "scroll"
2967 * rects to improve efficiency in certain scenarios.
2968 * This option is not available on Windows Phone 8, to note.
2970 result = IDXGISwapChain1_Present1(data->swapChain, syncInterval, presentFlags, ¶meters);
2973 /* Discard the contents of the render target.
2974 * This is a valid operation only when the existing contents will be entirely
2975 * overwritten. If dirty or scroll rects are used, this call should be removed.
2977 ID3D11DeviceContext1_DiscardView(data->d3dContext, (ID3D11View*)data->mainRenderTargetView);
2979 /* When the present flips, it unbinds the current view, so bind it again on the next draw call */
2980 data->currentRenderTargetView = NULL;
2982 if (FAILED(result) && result != DXGI_ERROR_WAS_STILL_DRAWING) {
2983 /* If the device was removed either by a disconnect or a driver upgrade, we
2984 * must recreate all device resources.
2986 * TODO, WinRT: consider throwing an exception if D3D11_RenderPresent fails, especially if there is a way to salvage debug info from users' machines
2988 if ( result == DXGI_ERROR_DEVICE_REMOVED ) {
2989 D3D11_HandleDeviceLost(renderer);
2990 } else if (result == DXGI_ERROR_INVALID_CALL) {
2991 /* We probably went through a fullscreen <-> windowed transition */
2992 D3D11_CreateWindowSizeDependentResources(renderer);
2994 WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain::Present", result);
2999 #endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */
3001 /* vi: set ts=4 sw=4 expandtab: */