SDL  2.0
SDL_render_d3d11.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22 
23 #if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED
24 
25 #define COBJMACROS
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" */
33 
34 #include <d3d11_1.h>
35 
36 
37 #ifdef __WINRT__
38 
39 #if NTDDI_VERSION > NTDDI_WIN8
40 #include <DXGI1_3.h>
41 #endif
42 
43 #include "SDL_render_winrt.h"
44 
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 */
50 
51 #endif /* __WINRT__ */
52 
53 
54 #define SDL_COMPOSE_ERROR(str) SDL_STRINGIFY_ARG(__FUNCTION__) ", " str
55 
56 #define SAFE_RELEASE(X) if ((X)) { IUnknown_Release(SDL_static_cast(IUnknown*, X)); X = NULL; }
57 
58 
59 /* Vertex shader, common values */
60 typedef struct
61 {
62  Float4X4 model;
63  Float4X4 projectionAndView;
64 } VertexShaderConstants;
65 
66 /* Per-vertex data */
67 typedef struct
68 {
69  Float3 pos;
70  Float2 tex;
71  Float4 color;
72 } VertexPositionColor;
73 
74 /* Per-texture data */
75 typedef struct
76 {
77  ID3D11Texture2D *mainTexture;
78  ID3D11ShaderResourceView *mainTextureResourceView;
79  ID3D11RenderTargetView *mainTextureRenderTargetView;
80  ID3D11Texture2D *stagingTexture;
81  int lockedTexturePositionX;
82  int lockedTexturePositionY;
83  D3D11_FILTER scaleMode;
84 
85  /* YV12 texture support */
86  SDL_bool yuv;
87  ID3D11Texture2D *mainTextureU;
88  ID3D11ShaderResourceView *mainTextureResourceViewU;
89  ID3D11Texture2D *mainTextureV;
90  ID3D11ShaderResourceView *mainTextureResourceViewV;
91  Uint8 *pixels;
92  int pitch;
93  SDL_Rect locked_rect;
94 } D3D11_TextureData;
95 
96 /* Blend mode data */
97 typedef struct
98 {
100  ID3D11BlendState *blendState;
101 } D3D11_BlendMode;
102 
103 /* Private renderer data */
104 typedef struct
105 {
106  void *hDXGIMod;
107  void *hD3D11Mod;
108  IDXGIFactory2 *dxgiFactory;
109  IDXGIAdapter *dxgiAdapter;
110  ID3D11Device1 *d3dDevice;
111  ID3D11DeviceContext1 *d3dContext;
112  IDXGISwapChain1 *swapChain;
113  DXGI_SWAP_EFFECT swapEffect;
114  ID3D11RenderTargetView *mainRenderTargetView;
115  ID3D11RenderTargetView *currentOffscreenRenderTargetView;
116  ID3D11InputLayout *inputLayout;
117  ID3D11Buffer *vertexBuffer;
118  ID3D11VertexShader *vertexShader;
119  ID3D11PixelShader *colorPixelShader;
120  ID3D11PixelShader *texturePixelShader;
121  ID3D11PixelShader *yuvPixelShader;
122  int blendModesCount;
123  D3D11_BlendMode *blendModes;
124  ID3D11SamplerState *nearestPixelSampler;
125  ID3D11SamplerState *linearSampler;
126  D3D_FEATURE_LEVEL featureLevel;
127 
128  /* Rasterizers */
129  ID3D11RasterizerState *mainRasterizer;
130  ID3D11RasterizerState *clippedRasterizer;
131 
132  /* Vertex buffer constants */
133  VertexShaderConstants vertexShaderConstantsData;
134  ID3D11Buffer *vertexShaderConstants;
135 
136  /* Cached renderer properties */
137  DXGI_MODE_ROTATION rotation;
138  ID3D11RenderTargetView *currentRenderTargetView;
139  ID3D11RasterizerState *currentRasterizerState;
140  ID3D11BlendState *currentBlendState;
141  ID3D11PixelShader *currentShader;
142  ID3D11ShaderResourceView *currentShaderResource;
143  ID3D11SamplerState *currentSampler;
144 } D3D11_RenderData;
145 
146 
147 /* Define D3D GUIDs here so we don't have to include uuid.lib.
148 *
149 * Fix for SDL bug https://bugzilla.libsdl.org/show_bug.cgi?id=3437:
150 * The extra 'SDL_' was added to the start of each IID's name, in order
151 * to prevent build errors on both MinGW-w64 and WinRT/UWP.
152 * (SDL bug https://bugzilla.libsdl.org/show_bug.cgi?id=3336 led to
153 * linker errors in WinRT/UWP builds.)
154 */
155 
156 #ifdef __GNUC__
157 #pragma GCC diagnostic push
158 #pragma GCC diagnostic ignored "-Wunused-const-variable"
159 #endif
160 
161 static const GUID SDL_IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } };
162 static const GUID SDL_IID_IDXGIDevice1 = { 0x77db970f, 0x6276, 0x48ba, { 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c } };
163 static const GUID SDL_IID_IDXGIDevice3 = { 0x6007896c, 0x3244, 0x4afd, { 0xbf, 0x18, 0xa6, 0xd3, 0xbe, 0xda, 0x50, 0x23 } };
164 static const GUID SDL_IID_ID3D11Texture2D = { 0x6f15aaf2, 0xd208, 0x4e89, { 0x9a, 0xb4, 0x48, 0x95, 0x35, 0xd3, 0x4f, 0x9c } };
165 static const GUID SDL_IID_ID3D11Device1 = { 0xa04bfb29, 0x08ef, 0x43d6, { 0xa4, 0x9c, 0xa9, 0xbd, 0xbd, 0xcb, 0xe6, 0x86 } };
166 static const GUID SDL_IID_ID3D11DeviceContext1 = { 0xbb2c6faa, 0xb5fb, 0x4082, { 0x8e, 0x6b, 0x38, 0x8b, 0x8c, 0xfa, 0x90, 0xe1 } };
167 static const GUID SDL_IID_ID3D11Debug = { 0x79cf2233, 0x7536, 0x4948, { 0x9d, 0x36, 0x1e, 0x46, 0x92, 0xdc, 0x57, 0x60 } };
168 
169 #ifdef __GNUC__
170 #pragma GCC diagnostic pop
171 #endif
172 
173 /* Direct3D 11.x shaders
174 
175  SDL's shaders are compiled into SDL itself, to simplify distribution.
176 
177  All Direct3D 11.x shaders were compiled with the following:
178 
179  fxc /E"main" /T "<TYPE>" /Fo"<OUTPUT FILE>" "<INPUT FILE>"
180 
181  Variables:
182  - <TYPE>: the type of shader. A table of utilized shader types is
183  listed below.
184  - <OUTPUT FILE>: where to store compiled output
185  - <INPUT FILE>: where to read shader source code from
186 
187  Shader types:
188  - ps_4_0_level_9_1: Pixel shader for Windows 8+, including Windows RT
189  - vs_4_0_level_9_1: Vertex shader for Windows 8+, including Windows RT
190  - ps_4_0_level_9_3: Pixel shader for Windows Phone 8
191  - vs_4_0_level_9_3: Vertex shader for Windows Phone 8
192 
193 
194  Shader object code was converted to a list of DWORDs via the following
195  *nix style command (available separately from Windows + MSVC):
196 
197  hexdump -v -e '6/4 "0x%08.8x, " "\n"' <FILE>
198  */
199 #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
200 #define D3D11_USE_SHADER_MODEL_4_0_level_9_3
201 #else
202 #define D3D11_USE_SHADER_MODEL_4_0_level_9_1
203 #endif
204 
205 /* The color-only-rendering pixel shader:
206 
207  --- D3D11_PixelShader_Colors.hlsl ---
208  struct PixelShaderInput
209  {
210  float4 pos : SV_POSITION;
211  float2 tex : TEXCOORD0;
212  float4 color : COLOR0;
213  };
214 
215  float4 main(PixelShaderInput input) : SV_TARGET
216  {
217  return input.color;
218  }
219 */
220 #if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1)
221 static const DWORD D3D11_PixelShader_Colors[] = {
222  0x43425844, 0xd74c28fe, 0xa1eb8804, 0x269d512a, 0x7699723d, 0x00000001,
223  0x00000240, 0x00000006, 0x00000038, 0x00000084, 0x000000c4, 0x00000140,
224  0x00000198, 0x0000020c, 0x396e6f41, 0x00000044, 0x00000044, 0xffff0200,
225  0x00000020, 0x00000024, 0x00240000, 0x00240000, 0x00240000, 0x00240000,
226  0x00240000, 0xffff0200, 0x0200001f, 0x80000000, 0xb00f0001, 0x02000001,
227  0x800f0800, 0xb0e40001, 0x0000ffff, 0x52444853, 0x00000038, 0x00000040,
228  0x0000000e, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, 0x001020f2,
229  0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000002,
230  0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000, 0x00000000,
231  0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
232  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
233  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000,
234  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
235  0x00000000, 0x00000000, 0x46454452, 0x00000050, 0x00000000, 0x00000000,
236  0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d,
237  0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072,
238  0x6c69706d, 0x39207265, 0x2e30332e, 0x30303239, 0x3336312e, 0xab003438,
239  0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000,
240  0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
241  0x00000000, 0x00000003, 0x00000001, 0x00000003, 0x00000065, 0x00000000,
242  0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f,
243  0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f,
244  0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
245  0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054
246 };
247 #elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3)
248 static const DWORD D3D11_PixelShader_Colors[] = {
249  0x43425844, 0x93f6ccfc, 0x5f919270, 0x7a11aa4f, 0x9148e931, 0x00000001,
250  0x00000240, 0x00000006, 0x00000038, 0x00000084, 0x000000c4, 0x00000140,
251  0x00000198, 0x0000020c, 0x396e6f41, 0x00000044, 0x00000044, 0xffff0200,
252  0x00000020, 0x00000024, 0x00240000, 0x00240000, 0x00240000, 0x00240000,
253  0x00240000, 0xffff0201, 0x0200001f, 0x80000000, 0xb00f0001, 0x02000001,
254  0x800f0800, 0xb0e40001, 0x0000ffff, 0x52444853, 0x00000038, 0x00000040,
255  0x0000000e, 0x03001062, 0x001010f2, 0x00000002, 0x03000065, 0x001020f2,
256  0x00000000, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000002,
257  0x0100003e, 0x54415453, 0x00000074, 0x00000002, 0x00000000, 0x00000000,
258  0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
259  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
260  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000,
261  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
262  0x00000000, 0x00000000, 0x46454452, 0x00000050, 0x00000000, 0x00000000,
263  0x00000000, 0x0000001c, 0xffff0400, 0x00000100, 0x0000001c, 0x7263694d,
264  0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168, 0x6f432072,
265  0x6c69706d, 0x39207265, 0x2e30332e, 0x30303239, 0x3336312e, 0xab003438,
266  0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000,
267  0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
268  0x00000000, 0x00000003, 0x00000001, 0x00000003, 0x00000065, 0x00000000,
269  0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f,
270  0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f,
271  0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
272  0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054
273 };
274 #else
275 #error "An appropriate 'colors' pixel shader is not defined."
276 #endif
277 
278 /* The texture-rendering pixel shader:
279 
280  --- D3D11_PixelShader_Textures.hlsl ---
281  Texture2D theTexture : register(t0);
282  SamplerState theSampler : register(s0);
283 
284  struct PixelShaderInput
285  {
286  float4 pos : SV_POSITION;
287  float2 tex : TEXCOORD0;
288  float4 color : COLOR0;
289  };
290 
291  float4 main(PixelShaderInput input) : SV_TARGET
292  {
293  return theTexture.Sample(theSampler, input.tex) * input.color;
294  }
295 */
296 #if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1)
297 static const DWORD D3D11_PixelShader_Textures[] = {
298  0x43425844, 0x6299b59f, 0x155258f2, 0x873ab86a, 0xfcbb6dcd, 0x00000001,
299  0x00000330, 0x00000006, 0x00000038, 0x000000c0, 0x0000015c, 0x000001d8,
300  0x00000288, 0x000002fc, 0x396e6f41, 0x00000080, 0x00000080, 0xffff0200,
301  0x00000058, 0x00000028, 0x00280000, 0x00280000, 0x00280000, 0x00240001,
302  0x00280000, 0x00000000, 0xffff0200, 0x0200001f, 0x80000000, 0xb0030000,
303  0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f, 0x90000000, 0xa00f0800,
304  0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000005, 0x800f0000,
305  0x80e40000, 0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff,
306  0x52444853, 0x00000094, 0x00000040, 0x00000025, 0x0300005a, 0x00106000,
307  0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062,
308  0x00101032, 0x00000001, 0x03001062, 0x001010f2, 0x00000002, 0x03000065,
309  0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x09000045, 0x001000f2,
310  0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000,
311  0x00000000, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000,
312  0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, 0x00000003,
313  0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x00000000, 0x00000000,
314  0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
315  0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
316  0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
317  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452, 0x000000a8,
318  0x00000000, 0x00000000, 0x00000002, 0x0000001c, 0xffff0400, 0x00000100,
319  0x00000072, 0x0000005c, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
320  0x00000000, 0x00000001, 0x00000001, 0x00000067, 0x00000002, 0x00000005,
321  0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x53656874,
322  0x6c706d61, 0x74007265, 0x65546568, 0x72757478, 0x694d0065, 0x736f7263,
323  0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43,
324  0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, 0xababab00,
325  0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000,
326  0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
327  0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000065, 0x00000000,
328  0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f,
329  0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f,
330  0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
331  0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054
332 };
333 #elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3)
334 static const DWORD D3D11_PixelShader_Textures[] = {
335  0x43425844, 0x5876569a, 0x01b6c87e, 0x8447454f, 0xc7f3ef10, 0x00000001,
336  0x00000330, 0x00000006, 0x00000038, 0x000000c0, 0x0000015c, 0x000001d8,
337  0x00000288, 0x000002fc, 0x396e6f41, 0x00000080, 0x00000080, 0xffff0200,
338  0x00000058, 0x00000028, 0x00280000, 0x00280000, 0x00280000, 0x00240001,
339  0x00280000, 0x00000000, 0xffff0201, 0x0200001f, 0x80000000, 0xb0030000,
340  0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f, 0x90000000, 0xa00f0800,
341  0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000005, 0x800f0000,
342  0x80e40000, 0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff,
343  0x52444853, 0x00000094, 0x00000040, 0x00000025, 0x0300005a, 0x00106000,
344  0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x03001062,
345  0x00101032, 0x00000001, 0x03001062, 0x001010f2, 0x00000002, 0x03000065,
346  0x001020f2, 0x00000000, 0x02000068, 0x00000001, 0x09000045, 0x001000f2,
347  0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000, 0x00106000,
348  0x00000000, 0x07000038, 0x001020f2, 0x00000000, 0x00100e46, 0x00000000,
349  0x00101e46, 0x00000002, 0x0100003e, 0x54415453, 0x00000074, 0x00000003,
350  0x00000001, 0x00000000, 0x00000003, 0x00000001, 0x00000000, 0x00000000,
351  0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
352  0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
353  0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
354  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x46454452, 0x000000a8,
355  0x00000000, 0x00000000, 0x00000002, 0x0000001c, 0xffff0400, 0x00000100,
356  0x00000072, 0x0000005c, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
357  0x00000000, 0x00000001, 0x00000001, 0x00000067, 0x00000002, 0x00000005,
358  0x00000004, 0xffffffff, 0x00000000, 0x00000001, 0x0000000d, 0x53656874,
359  0x6c706d61, 0x74007265, 0x65546568, 0x72757478, 0x694d0065, 0x736f7263,
360  0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564, 0x706d6f43,
361  0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336, 0xababab00,
362  0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000,
363  0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
364  0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000065, 0x00000000,
365  0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f,
366  0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f,
367  0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
368  0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054
369 };
370 #else
371 #error "An appropriate 'textures' pixel shader is not defined"
372 #endif
373 
374 /* The yuv-rendering pixel shader:
375 
376  --- D3D11_PixelShader_YUV.hlsl ---
377  Texture2D theTextureY : register(t0);
378  Texture2D theTextureU : register(t1);
379  Texture2D theTextureV : register(t2);
380  SamplerState theSampler : register(s0);
381 
382  struct PixelShaderInput
383  {
384  float4 pos : SV_POSITION;
385  float2 tex : TEXCOORD0;
386  float4 color : COLOR0;
387  };
388 
389  float4 main(PixelShaderInput input) : SV_TARGET
390  {
391  const float3 offset = {-0.0627451017, -0.501960814, -0.501960814};
392  const float3 Rcoeff = {1.164, 0.000, 1.596};
393  const float3 Gcoeff = {1.164, -0.391, -0.813};
394  const float3 Bcoeff = {1.164, 2.018, 0.000};
395 
396  float4 Output;
397 
398  float3 yuv;
399  yuv.x = theTextureY.Sample(theSampler, input.tex).r;
400  yuv.y = theTextureU.Sample(theSampler, input.tex).r;
401  yuv.z = theTextureV.Sample(theSampler, input.tex).r;
402 
403  yuv += offset;
404  Output.r = dot(yuv, Rcoeff);
405  Output.g = dot(yuv, Gcoeff);
406  Output.b = dot(yuv, Bcoeff);
407  Output.a = 1.0f;
408 
409  return Output * input.color;
410  }
411 
412 */
413 #if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1)
414 static const DWORD D3D11_PixelShader_YUV[] = {
415  0x43425844, 0x2321c6c6, 0xf14df2d1, 0xc79d068d, 0x8e672abf, 0x00000001,
416  0x000005e8, 0x00000006, 0x00000038, 0x000001dc, 0x000003bc, 0x00000438,
417  0x00000540, 0x000005b4, 0x396e6f41, 0x0000019c, 0x0000019c, 0xffff0200,
418  0x0000016c, 0x00000030, 0x00300000, 0x00300000, 0x00300000, 0x00240003,
419  0x00300000, 0x00000000, 0x00010001, 0x00020002, 0xffff0200, 0x05000051,
420  0xa00f0000, 0xbd808081, 0xbf008081, 0xbf008081, 0x3f800000, 0x05000051,
421  0xa00f0001, 0x3f94fdf4, 0x3fcc49ba, 0x00000000, 0x00000000, 0x05000051,
422  0xa00f0002, 0x3f94fdf4, 0xbec83127, 0xbf5020c5, 0x00000000, 0x05000051,
423  0xa00f0003, 0x3f94fdf4, 0x400126e9, 0x00000000, 0x00000000, 0x0200001f,
424  0x80000000, 0xb0030000, 0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f,
425  0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f,
426  0x90000000, 0xa00f0802, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,
427  0x03000042, 0x800f0001, 0xb0e40000, 0xa0e40801, 0x03000042, 0x800f0002,
428  0xb0e40000, 0xa0e40802, 0x02000001, 0x80020000, 0x80000001, 0x02000001,
429  0x80040000, 0x80000002, 0x03000002, 0x80070000, 0x80e40000, 0xa0e40000,
430  0x03000005, 0x80080000, 0x80000000, 0xa0000001, 0x04000004, 0x80010001,
431  0x80aa0000, 0xa0550001, 0x80ff0000, 0x03000008, 0x80020001, 0x80e40000,
432  0xa0e40002, 0x0400005a, 0x80040001, 0x80e40000, 0xa0e40003, 0xa0aa0003,
433  0x02000001, 0x80080001, 0xa0ff0000, 0x03000005, 0x800f0000, 0x80e40001,
434  0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff, 0x52444853,
435  0x000001d8, 0x00000040, 0x00000076, 0x0300005a, 0x00106000, 0x00000000,
436  0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04001858, 0x00107000,
437  0x00000001, 0x00005555, 0x04001858, 0x00107000, 0x00000002, 0x00005555,
438  0x03001062, 0x00101032, 0x00000001, 0x03001062, 0x001010f2, 0x00000002,
439  0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x09000045,
440  0x001000f2, 0x00000000, 0x00101046, 0x00000001, 0x00107e46, 0x00000000,
441  0x00106000, 0x00000000, 0x09000045, 0x001000f2, 0x00000001, 0x00101046,
442  0x00000001, 0x00107e46, 0x00000001, 0x00106000, 0x00000000, 0x05000036,
443  0x00100022, 0x00000000, 0x0010000a, 0x00000001, 0x09000045, 0x001000f2,
444  0x00000001, 0x00101046, 0x00000001, 0x00107e46, 0x00000002, 0x00106000,
445  0x00000000, 0x05000036, 0x00100042, 0x00000000, 0x0010000a, 0x00000001,
446  0x0a000000, 0x00100072, 0x00000000, 0x00100246, 0x00000000, 0x00004002,
447  0xbd808081, 0xbf008081, 0xbf008081, 0x00000000, 0x0a00000f, 0x00100012,
448  0x00000001, 0x00100086, 0x00000000, 0x00004002, 0x3f94fdf4, 0x3fcc49ba,
449  0x00000000, 0x00000000, 0x0a000010, 0x00100022, 0x00000001, 0x00100246,
450  0x00000000, 0x00004002, 0x3f94fdf4, 0xbec83127, 0xbf5020c5, 0x00000000,
451  0x0a00000f, 0x00100042, 0x00000001, 0x00100046, 0x00000000, 0x00004002,
452  0x3f94fdf4, 0x400126e9, 0x00000000, 0x00000000, 0x05000036, 0x00100082,
453  0x00000001, 0x00004001, 0x3f800000, 0x07000038, 0x001020f2, 0x00000000,
454  0x00100e46, 0x00000001, 0x00101e46, 0x00000002, 0x0100003e, 0x54415453,
455  0x00000074, 0x0000000c, 0x00000002, 0x00000000, 0x00000003, 0x00000005,
456  0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
457  0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000,
458  0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
459  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
460  0x46454452, 0x00000100, 0x00000000, 0x00000000, 0x00000004, 0x0000001c,
461  0xffff0400, 0x00000100, 0x000000cb, 0x0000009c, 0x00000003, 0x00000000,
462  0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x000000a7,
463  0x00000002, 0x00000005, 0x00000004, 0xffffffff, 0x00000000, 0x00000001,
464  0x0000000d, 0x000000b3, 0x00000002, 0x00000005, 0x00000004, 0xffffffff,
465  0x00000001, 0x00000001, 0x0000000d, 0x000000bf, 0x00000002, 0x00000005,
466  0x00000004, 0xffffffff, 0x00000002, 0x00000001, 0x0000000d, 0x53656874,
467  0x6c706d61, 0x74007265, 0x65546568, 0x72757478, 0x74005965, 0x65546568,
468  0x72757478, 0x74005565, 0x65546568, 0x72757478, 0x4d005665, 0x6f726369,
469  0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320,
470  0x656c6970, 0x2e362072, 0x36392e33, 0x312e3030, 0x34383336, 0xababab00,
471  0x4e475349, 0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000,
472  0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000,
473  0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000065, 0x00000000,
474  0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x505f5653, 0x5449534f,
475  0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f, 0x4e47534f,
476  0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
477  0x00000003, 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054
478 };
479 #elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3)
480 static const DWORD D3D11_PixelShader_YUV[] = {
481  0x43425844, 0x6ede7360, 0x45ff5f8a, 0x34ac92ba, 0xb865f5e0, 0x00000001,
482  0x000005c0, 0x00000006, 0x00000038, 0x000001b4, 0x00000394, 0x00000410,
483  0x00000518, 0x0000058c, 0x396e6f41, 0x00000174, 0x00000174, 0xffff0200,
484  0x00000144, 0x00000030, 0x00300000, 0x00300000, 0x00300000, 0x00240003,
485  0x00300000, 0x00000000, 0x00010001, 0x00020002, 0xffff0201, 0x05000051,
486  0xa00f0000, 0xbd808081, 0xbf008081, 0x3f800000, 0x00000000, 0x05000051,
487  0xa00f0001, 0x3f94fdf4, 0x3fcc49ba, 0x00000000, 0x400126e9, 0x05000051,
488  0xa00f0002, 0x3f94fdf4, 0xbec83127, 0xbf5020c5, 0x00000000, 0x0200001f,
489  0x80000000, 0xb0030000, 0x0200001f, 0x80000000, 0xb00f0001, 0x0200001f,
490  0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f,
491  0x90000000, 0xa00f0802, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40801,
492  0x03000042, 0x800f0001, 0xb0e40000, 0xa0e40800, 0x02000001, 0x80020001,
493  0x80000000, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40802, 0x02000001,
494  0x80040001, 0x80000000, 0x03000002, 0x80070000, 0x80e40001, 0xa0d40000,
495  0x0400005a, 0x80010001, 0x80e80000, 0xa0e40001, 0xa0aa0001, 0x03000008,
496  0x80020001, 0x80e40000, 0xa0e40002, 0x0400005a, 0x80040001, 0x80e40000,
497  0xa0ec0001, 0xa0aa0001, 0x02000001, 0x80080001, 0xa0aa0000, 0x03000005,
498  0x800f0000, 0x80e40001, 0xb0e40001, 0x02000001, 0x800f0800, 0x80e40000,
499  0x0000ffff, 0x52444853, 0x000001d8, 0x00000040, 0x00000076, 0x0300005a,
500  0x00106000, 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555,
501  0x04001858, 0x00107000, 0x00000001, 0x00005555, 0x04001858, 0x00107000,
502  0x00000002, 0x00005555, 0x03001062, 0x00101032, 0x00000001, 0x03001062,
503  0x001010f2, 0x00000002, 0x03000065, 0x001020f2, 0x00000000, 0x02000068,
504  0x00000002, 0x09000045, 0x001000f2, 0x00000000, 0x00101046, 0x00000001,
505  0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x09000045, 0x001000f2,
506  0x00000001, 0x00101046, 0x00000001, 0x00107e46, 0x00000001, 0x00106000,
507  0x00000000, 0x05000036, 0x00100022, 0x00000000, 0x0010000a, 0x00000001,
508  0x09000045, 0x001000f2, 0x00000001, 0x00101046, 0x00000001, 0x00107e46,
509  0x00000002, 0x00106000, 0x00000000, 0x05000036, 0x00100042, 0x00000000,
510  0x0010000a, 0x00000001, 0x0a000000, 0x00100072, 0x00000000, 0x00100246,
511  0x00000000, 0x00004002, 0xbd808081, 0xbf008081, 0xbf008081, 0x00000000,
512  0x0a00000f, 0x00100012, 0x00000001, 0x00100086, 0x00000000, 0x00004002,
513  0x3f94fdf4, 0x3fcc49ba, 0x00000000, 0x00000000, 0x0a000010, 0x00100022,
514  0x00000001, 0x00100246, 0x00000000, 0x00004002, 0x3f94fdf4, 0xbec83127,
515  0xbf5020c5, 0x00000000, 0x0a00000f, 0x00100042, 0x00000001, 0x00100046,
516  0x00000000, 0x00004002, 0x3f94fdf4, 0x400126e9, 0x00000000, 0x00000000,
517  0x05000036, 0x00100082, 0x00000001, 0x00004001, 0x3f800000, 0x07000038,
518  0x001020f2, 0x00000000, 0x00100e46, 0x00000001, 0x00101e46, 0x00000002,
519  0x0100003e, 0x54415453, 0x00000074, 0x0000000c, 0x00000002, 0x00000000,
520  0x00000003, 0x00000005, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
521  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
522  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
523  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
524  0x00000000, 0x00000000, 0x46454452, 0x00000100, 0x00000000, 0x00000000,
525  0x00000004, 0x0000001c, 0xffff0400, 0x00000100, 0x000000cb, 0x0000009c,
526  0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
527  0x00000001, 0x000000a7, 0x00000002, 0x00000005, 0x00000004, 0xffffffff,
528  0x00000000, 0x00000001, 0x0000000d, 0x000000b3, 0x00000002, 0x00000005,
529  0x00000004, 0xffffffff, 0x00000001, 0x00000001, 0x0000000d, 0x000000bf,
530  0x00000002, 0x00000005, 0x00000004, 0xffffffff, 0x00000002, 0x00000001,
531  0x0000000d, 0x53656874, 0x6c706d61, 0x74007265, 0x65546568, 0x72757478,
532  0x74005965, 0x65546568, 0x72757478, 0x74005565, 0x65546568, 0x72757478,
533  0x4d005665, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c,
534  0x72656461, 0x6d6f4320, 0x656c6970, 0x2e362072, 0x36392e33, 0x312e3030,
535  0x34383336, 0xababab00, 0x4e475349, 0x0000006c, 0x00000003, 0x00000008,
536  0x00000050, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f,
537  0x0000005c, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000303,
538  0x00000065, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000f0f,
539  0x505f5653, 0x5449534f, 0x004e4f49, 0x43584554, 0x44524f4f, 0x4c4f4300,
540  0xab00524f, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
541  0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x545f5653,
542  0x45475241, 0xabab0054
543 };
544 #else
545 #error "An appropriate 'yuv' pixel shader is not defined."
546 #endif
547 
548 /* The sole vertex shader:
549 
550  --- D3D11_VertexShader.hlsl ---
551  #pragma pack_matrix( row_major )
552 
553  cbuffer VertexShaderConstants : register(b0)
554  {
555  matrix model;
556  matrix projectionAndView;
557  };
558 
559  struct VertexShaderInput
560  {
561  float3 pos : POSITION;
562  float2 tex : TEXCOORD0;
563  float4 color : COLOR0;
564  };
565 
566  struct VertexShaderOutput
567  {
568  float4 pos : SV_POSITION;
569  float2 tex : TEXCOORD0;
570  float4 color : COLOR0;
571  };
572 
573  VertexShaderOutput main(VertexShaderInput input)
574  {
575  VertexShaderOutput output;
576  float4 pos = float4(input.pos, 1.0f);
577 
578  // Transform the vertex position into projected space.
579  pos = mul(pos, model);
580  pos = mul(pos, projectionAndView);
581  output.pos = pos;
582 
583  // Pass through texture coordinates and color values without transformation
584  output.tex = input.tex;
585  output.color = input.color;
586 
587  return output;
588  }
589 */
590 #if defined(D3D11_USE_SHADER_MODEL_4_0_level_9_1)
591 static const DWORD D3D11_VertexShader[] = {
592  0x43425844, 0x62dfae5f, 0x3e8bd8df, 0x9ec97127, 0x5044eefb, 0x00000001,
593  0x00000598, 0x00000006, 0x00000038, 0x0000016c, 0x00000334, 0x000003b0,
594  0x000004b4, 0x00000524, 0x396e6f41, 0x0000012c, 0x0000012c, 0xfffe0200,
595  0x000000f8, 0x00000034, 0x00240001, 0x00300000, 0x00300000, 0x00240000,
596  0x00300001, 0x00000000, 0x00010008, 0x00000000, 0x00000000, 0xfffe0200,
597  0x0200001f, 0x80000005, 0x900f0000, 0x0200001f, 0x80010005, 0x900f0001,
598  0x0200001f, 0x80020005, 0x900f0002, 0x03000005, 0x800f0000, 0x90550000,
599  0xa0e40002, 0x04000004, 0x800f0000, 0x90000000, 0xa0e40001, 0x80e40000,
600  0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40003, 0x80e40000, 0x03000002,
601  0x800f0000, 0x80e40000, 0xa0e40004, 0x03000005, 0x800f0001, 0x80550000,
602  0xa0e40006, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40005, 0x80e40001,
603  0x04000004, 0x800f0001, 0x80aa0000, 0xa0e40007, 0x80e40001, 0x04000004,
604  0x800f0000, 0x80ff0000, 0xa0e40008, 0x80e40001, 0x04000004, 0xc0030000,
605  0x80ff0000, 0xa0e40000, 0x80e40000, 0x02000001, 0xc00c0000, 0x80e40000,
606  0x02000001, 0xe0030000, 0x90e40001, 0x02000001, 0xe00f0001, 0x90e40002,
607  0x0000ffff, 0x52444853, 0x000001c0, 0x00010040, 0x00000070, 0x04000059,
608  0x00208e46, 0x00000000, 0x00000008, 0x0300005f, 0x00101072, 0x00000000,
609  0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x001010f2, 0x00000002,
610  0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x00102032,
611  0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x02000068, 0x00000002,
612  0x08000038, 0x001000f2, 0x00000000, 0x00101556, 0x00000000, 0x00208e46,
613  0x00000000, 0x00000001, 0x0a000032, 0x001000f2, 0x00000000, 0x00101006,
614  0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46, 0x00000000,
615  0x0a000032, 0x001000f2, 0x00000000, 0x00101aa6, 0x00000000, 0x00208e46,
616  0x00000000, 0x00000002, 0x00100e46, 0x00000000, 0x08000000, 0x001000f2,
617  0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000003,
618  0x08000038, 0x001000f2, 0x00000001, 0x00100556, 0x00000000, 0x00208e46,
619  0x00000000, 0x00000005, 0x0a000032, 0x001000f2, 0x00000001, 0x00100006,
620  0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x00100e46, 0x00000001,
621  0x0a000032, 0x001000f2, 0x00000001, 0x00100aa6, 0x00000000, 0x00208e46,
622  0x00000000, 0x00000006, 0x00100e46, 0x00000001, 0x0a000032, 0x001020f2,
623  0x00000000, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000007,
624  0x00100e46, 0x00000001, 0x05000036, 0x00102032, 0x00000001, 0x00101046,
625  0x00000001, 0x05000036, 0x001020f2, 0x00000002, 0x00101e46, 0x00000002,
626  0x0100003e, 0x54415453, 0x00000074, 0x0000000b, 0x00000002, 0x00000000,
627  0x00000006, 0x00000003, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
628  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
629  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
630  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
631  0x00000000, 0x00000000, 0x46454452, 0x000000fc, 0x00000001, 0x00000054,
632  0x00000001, 0x0000001c, 0xfffe0400, 0x00000100, 0x000000c6, 0x0000003c,
633  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
634  0x00000001, 0x74726556, 0x68537865, 0x72656461, 0x736e6f43, 0x746e6174,
635  0xabab0073, 0x0000003c, 0x00000002, 0x0000006c, 0x00000080, 0x00000000,
636  0x00000000, 0x0000009c, 0x00000000, 0x00000040, 0x00000002, 0x000000a4,
637  0x00000000, 0x000000b4, 0x00000040, 0x00000040, 0x00000002, 0x000000a4,
638  0x00000000, 0x65646f6d, 0xabab006c, 0x00030002, 0x00040004, 0x00000000,
639  0x00000000, 0x6a6f7270, 0x69746365, 0x6e416e6f, 0x65695664, 0x694d0077,
640  0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564,
641  0x706d6f43, 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336,
642  0xababab00, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050,
643  0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000707, 0x00000059,
644  0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000062,
645  0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x49534f50,
646  0x4e4f4954, 0x58455400, 0x524f4f43, 0x4f430044, 0x00524f4c, 0x4e47534f,
647  0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001,
648  0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000,
649  0x00000003, 0x00000001, 0x00000c03, 0x00000065, 0x00000000, 0x00000000,
650  0x00000003, 0x00000002, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49,
651  0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f
652 };
653 #elif defined(D3D11_USE_SHADER_MODEL_4_0_level_9_3)
654 static const DWORD D3D11_VertexShader[] = {
655  0x43425844, 0x01a24e41, 0x696af551, 0x4b2a87d1, 0x82ea03f6, 0x00000001,
656  0x00000598, 0x00000006, 0x00000038, 0x0000016c, 0x00000334, 0x000003b0,
657  0x000004b4, 0x00000524, 0x396e6f41, 0x0000012c, 0x0000012c, 0xfffe0200,
658  0x000000f8, 0x00000034, 0x00240001, 0x00300000, 0x00300000, 0x00240000,
659  0x00300001, 0x00000000, 0x00010008, 0x00000000, 0x00000000, 0xfffe0201,
660  0x0200001f, 0x80000005, 0x900f0000, 0x0200001f, 0x80010005, 0x900f0001,
661  0x0200001f, 0x80020005, 0x900f0002, 0x03000005, 0x800f0000, 0x90550000,
662  0xa0e40002, 0x04000004, 0x800f0000, 0x90000000, 0xa0e40001, 0x80e40000,
663  0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40003, 0x80e40000, 0x03000002,
664  0x800f0000, 0x80e40000, 0xa0e40004, 0x03000005, 0x800f0001, 0x80550000,
665  0xa0e40006, 0x04000004, 0x800f0001, 0x80000000, 0xa0e40005, 0x80e40001,
666  0x04000004, 0x800f0001, 0x80aa0000, 0xa0e40007, 0x80e40001, 0x04000004,
667  0x800f0000, 0x80ff0000, 0xa0e40008, 0x80e40001, 0x04000004, 0xc0030000,
668  0x80ff0000, 0xa0e40000, 0x80e40000, 0x02000001, 0xc00c0000, 0x80e40000,
669  0x02000001, 0xe0030000, 0x90e40001, 0x02000001, 0xe00f0001, 0x90e40002,
670  0x0000ffff, 0x52444853, 0x000001c0, 0x00010040, 0x00000070, 0x04000059,
671  0x00208e46, 0x00000000, 0x00000008, 0x0300005f, 0x00101072, 0x00000000,
672  0x0300005f, 0x00101032, 0x00000001, 0x0300005f, 0x001010f2, 0x00000002,
673  0x04000067, 0x001020f2, 0x00000000, 0x00000001, 0x03000065, 0x00102032,
674  0x00000001, 0x03000065, 0x001020f2, 0x00000002, 0x02000068, 0x00000002,
675  0x08000038, 0x001000f2, 0x00000000, 0x00101556, 0x00000000, 0x00208e46,
676  0x00000000, 0x00000001, 0x0a000032, 0x001000f2, 0x00000000, 0x00101006,
677  0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00100e46, 0x00000000,
678  0x0a000032, 0x001000f2, 0x00000000, 0x00101aa6, 0x00000000, 0x00208e46,
679  0x00000000, 0x00000002, 0x00100e46, 0x00000000, 0x08000000, 0x001000f2,
680  0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000003,
681  0x08000038, 0x001000f2, 0x00000001, 0x00100556, 0x00000000, 0x00208e46,
682  0x00000000, 0x00000005, 0x0a000032, 0x001000f2, 0x00000001, 0x00100006,
683  0x00000000, 0x00208e46, 0x00000000, 0x00000004, 0x00100e46, 0x00000001,
684  0x0a000032, 0x001000f2, 0x00000001, 0x00100aa6, 0x00000000, 0x00208e46,
685  0x00000000, 0x00000006, 0x00100e46, 0x00000001, 0x0a000032, 0x001020f2,
686  0x00000000, 0x00100ff6, 0x00000000, 0x00208e46, 0x00000000, 0x00000007,
687  0x00100e46, 0x00000001, 0x05000036, 0x00102032, 0x00000001, 0x00101046,
688  0x00000001, 0x05000036, 0x001020f2, 0x00000002, 0x00101e46, 0x00000002,
689  0x0100003e, 0x54415453, 0x00000074, 0x0000000b, 0x00000002, 0x00000000,
690  0x00000006, 0x00000003, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
691  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
692  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
693  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
694  0x00000000, 0x00000000, 0x46454452, 0x000000fc, 0x00000001, 0x00000054,
695  0x00000001, 0x0000001c, 0xfffe0400, 0x00000100, 0x000000c6, 0x0000003c,
696  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
697  0x00000001, 0x74726556, 0x68537865, 0x72656461, 0x736e6f43, 0x746e6174,
698  0xabab0073, 0x0000003c, 0x00000002, 0x0000006c, 0x00000080, 0x00000000,
699  0x00000000, 0x0000009c, 0x00000000, 0x00000040, 0x00000002, 0x000000a4,
700  0x00000000, 0x000000b4, 0x00000040, 0x00000040, 0x00000002, 0x000000a4,
701  0x00000000, 0x65646f6d, 0xabab006c, 0x00030002, 0x00040004, 0x00000000,
702  0x00000000, 0x6a6f7270, 0x69746365, 0x6e416e6f, 0x65695664, 0x694d0077,
703  0x736f7263, 0x2074666f, 0x20295228, 0x4c534c48, 0x61685320, 0x20726564,
704  0x706d6f43, 0x72656c69, 0x332e3920, 0x32392e30, 0x312e3030, 0x34383336,
705  0xababab00, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050,
706  0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000707, 0x00000059,
707  0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000303, 0x00000062,
708  0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000f0f, 0x49534f50,
709  0x4e4f4954, 0x58455400, 0x524f4f43, 0x4f430044, 0x00524f4c, 0x4e47534f,
710  0x0000006c, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001,
711  0x00000003, 0x00000000, 0x0000000f, 0x0000005c, 0x00000000, 0x00000000,
712  0x00000003, 0x00000001, 0x00000c03, 0x00000065, 0x00000000, 0x00000000,
713  0x00000003, 0x00000002, 0x0000000f, 0x505f5653, 0x5449534f, 0x004e4f49,
714  0x43584554, 0x44524f4f, 0x4c4f4300, 0xab00524f
715 };
716 #else
717 #error "An appropriate vertex shader is not defined."
718 #endif
719 
720 
721 /* Direct3D 11.1 renderer implementation */
722 static SDL_Renderer *D3D11_CreateRenderer(SDL_Window * window, Uint32 flags);
723 static void D3D11_WindowEvent(SDL_Renderer * renderer,
724  const SDL_WindowEvent *event);
725 static SDL_bool D3D11_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode);
726 static int D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
727 static int D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
728  const SDL_Rect * rect, const void *srcPixels,
729  int srcPitch);
730 static int D3D11_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
731  const SDL_Rect * rect,
732  const Uint8 *Yplane, int Ypitch,
733  const Uint8 *Uplane, int Upitch,
734  const Uint8 *Vplane, int Vpitch);
735 static int D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
736  const SDL_Rect * rect, void **pixels, int *pitch);
737 static void D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
738 static int D3D11_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
739 static int D3D11_UpdateViewport(SDL_Renderer * renderer);
740 static int D3D11_UpdateClipRect(SDL_Renderer * renderer);
741 static int D3D11_RenderClear(SDL_Renderer * renderer);
742 static int D3D11_RenderDrawPoints(SDL_Renderer * renderer,
743  const SDL_FPoint * points, int count);
744 static int D3D11_RenderDrawLines(SDL_Renderer * renderer,
745  const SDL_FPoint * points, int count);
746 static int D3D11_RenderFillRects(SDL_Renderer * renderer,
747  const SDL_FRect * rects, int count);
748 static int D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
749  const SDL_Rect * srcrect, const SDL_FRect * dstrect);
750 static int D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
751  const SDL_Rect * srcrect, const SDL_FRect * dstrect,
752  const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip);
753 static int D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
754  Uint32 format, void * pixels, int pitch);
755 static void D3D11_RenderPresent(SDL_Renderer * renderer);
756 static void D3D11_DestroyTexture(SDL_Renderer * renderer,
757  SDL_Texture * texture);
758 static void D3D11_DestroyRenderer(SDL_Renderer * renderer);
759 
760 /* Direct3D 11.1 Internal Functions */
761 static HRESULT D3D11_CreateDeviceResources(SDL_Renderer * renderer);
762 static HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer);
763 static HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer);
764 static HRESULT D3D11_HandleDeviceLost(SDL_Renderer * renderer);
765 static void D3D11_ReleaseMainRenderTargetView(SDL_Renderer * renderer);
766 
768  D3D11_CreateRenderer,
769  {
770  "direct3d11",
771  (
775  ), /* flags. see SDL_RendererFlags */
776  4, /* num_texture_formats */
777  { /* texture_formats */
782  },
783  0, /* max_texture_width: will be filled in later */
784  0 /* max_texture_height: will be filled in later */
785  }
786 };
787 
788 
789 Uint32
790 D3D11_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat) {
791  switch (dxgiFormat) {
792  case DXGI_FORMAT_B8G8R8A8_UNORM:
794  case DXGI_FORMAT_B8G8R8X8_UNORM:
795  return SDL_PIXELFORMAT_RGB888;
796  default:
798  }
799 }
800 
801 static DXGI_FORMAT
802 SDLPixelFormatToDXGIFormat(Uint32 sdlFormat)
803 {
804  switch (sdlFormat) {
806  return DXGI_FORMAT_B8G8R8A8_UNORM;
808  return DXGI_FORMAT_B8G8R8X8_UNORM;
811  return DXGI_FORMAT_R8_UNORM;
812  default:
813  return DXGI_FORMAT_UNKNOWN;
814  }
815 }
816 
817 SDL_Renderer *
818 D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
819 {
821  D3D11_RenderData *data;
822 
823  renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
824  if (!renderer) {
825  SDL_OutOfMemory();
826  return NULL;
827  }
828 
829  data = (D3D11_RenderData *) SDL_calloc(1, sizeof(*data));
830  if (!data) {
831  SDL_OutOfMemory();
832  return NULL;
833  }
834 
835  renderer->WindowEvent = D3D11_WindowEvent;
836  renderer->SupportsBlendMode = D3D11_SupportsBlendMode;
837  renderer->CreateTexture = D3D11_CreateTexture;
838  renderer->UpdateTexture = D3D11_UpdateTexture;
839  renderer->UpdateTextureYUV = D3D11_UpdateTextureYUV;
840  renderer->LockTexture = D3D11_LockTexture;
841  renderer->UnlockTexture = D3D11_UnlockTexture;
842  renderer->SetRenderTarget = D3D11_SetRenderTarget;
843  renderer->UpdateViewport = D3D11_UpdateViewport;
844  renderer->UpdateClipRect = D3D11_UpdateClipRect;
845  renderer->RenderClear = D3D11_RenderClear;
846  renderer->RenderDrawPoints = D3D11_RenderDrawPoints;
847  renderer->RenderDrawLines = D3D11_RenderDrawLines;
848  renderer->RenderFillRects = D3D11_RenderFillRects;
849  renderer->RenderCopy = D3D11_RenderCopy;
850  renderer->RenderCopyEx = D3D11_RenderCopyEx;
851  renderer->RenderReadPixels = D3D11_RenderReadPixels;
852  renderer->RenderPresent = D3D11_RenderPresent;
853  renderer->DestroyTexture = D3D11_DestroyTexture;
854  renderer->DestroyRenderer = D3D11_DestroyRenderer;
855  renderer->info = D3D11_RenderDriver.info;
857  renderer->driverdata = data;
858 
859 #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
860  /* VSync is required in Windows Phone, at least for Win Phone 8.0 and 8.1.
861  * Failure to use it seems to either result in:
862  *
863  * - with the D3D11 debug runtime turned OFF, vsync seemingly gets turned
864  * off (framerate doesn't get capped), but nothing appears on-screen
865  *
866  * - with the D3D11 debug runtime turned ON, vsync gets automatically
867  * turned back on, and the following gets output to the debug console:
868  *
869  * DXGI ERROR: IDXGISwapChain::Present: Interval 0 is not supported, changed to Interval 1. [ UNKNOWN ERROR #1024: ]
870  */
871  renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
872 #else
873  if ((flags & SDL_RENDERER_PRESENTVSYNC)) {
874  renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
875  }
876 #endif
877 
878  /* HACK: make sure the SDL_Renderer references the SDL_Window data now, in
879  * order to give init functions access to the underlying window handle:
880  */
881  renderer->window = window;
882 
883  /* Initialize Direct3D resources */
884  if (FAILED(D3D11_CreateDeviceResources(renderer))) {
885  D3D11_DestroyRenderer(renderer);
886  return NULL;
887  }
888  if (FAILED(D3D11_CreateWindowSizeDependentResources(renderer))) {
889  D3D11_DestroyRenderer(renderer);
890  return NULL;
891  }
892 
893  return renderer;
894 }
895 
896 static void
897 D3D11_ReleaseAll(SDL_Renderer * renderer)
898 {
899  D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
901 
902  /* Release all textures */
903  for (texture = renderer->textures; texture; texture = texture->next) {
904  D3D11_DestroyTexture(renderer, texture);
905  }
906 
907  /* Release/reset everything else */
908  if (data) {
909  int i;
910 
911  SAFE_RELEASE(data->dxgiFactory);
912  SAFE_RELEASE(data->dxgiAdapter);
913  SAFE_RELEASE(data->d3dDevice);
914  SAFE_RELEASE(data->d3dContext);
915  SAFE_RELEASE(data->swapChain);
916  SAFE_RELEASE(data->mainRenderTargetView);
917  SAFE_RELEASE(data->currentOffscreenRenderTargetView);
918  SAFE_RELEASE(data->inputLayout);
919  SAFE_RELEASE(data->vertexBuffer);
920  SAFE_RELEASE(data->vertexShader);
921  SAFE_RELEASE(data->colorPixelShader);
922  SAFE_RELEASE(data->texturePixelShader);
923  SAFE_RELEASE(data->yuvPixelShader);
924  if (data->blendModesCount > 0) {
925  for (i = 0; i < data->blendModesCount; ++i) {
926  SAFE_RELEASE(data->blendModes[i].blendState);
927  }
928  SDL_free(data->blendModes);
929 
930  data->blendModesCount = 0;
931  }
932  SAFE_RELEASE(data->nearestPixelSampler);
933  SAFE_RELEASE(data->linearSampler);
934  SAFE_RELEASE(data->mainRasterizer);
935  SAFE_RELEASE(data->clippedRasterizer);
936  SAFE_RELEASE(data->vertexShaderConstants);
937 
938  data->swapEffect = (DXGI_SWAP_EFFECT) 0;
939  data->rotation = DXGI_MODE_ROTATION_UNSPECIFIED;
940  data->currentRenderTargetView = NULL;
941  data->currentRasterizerState = NULL;
942  data->currentBlendState = NULL;
943  data->currentShader = NULL;
944  data->currentShaderResource = NULL;
945  data->currentSampler = NULL;
946 
947  /* Unload the D3D libraries. This should be done last, in order
948  * to prevent IUnknown::Release() calls from crashing.
949  */
950  if (data->hD3D11Mod) {
951  SDL_UnloadObject(data->hD3D11Mod);
952  data->hD3D11Mod = NULL;
953  }
954  if (data->hDXGIMod) {
955  SDL_UnloadObject(data->hDXGIMod);
956  data->hDXGIMod = NULL;
957  }
958  }
959 }
960 
961 static void
962 D3D11_DestroyRenderer(SDL_Renderer * renderer)
963 {
964  D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
965  D3D11_ReleaseAll(renderer);
966  if (data) {
967  SDL_free(data);
968  }
969  SDL_free(renderer);
970 }
971 
972 static D3D11_BLEND GetBlendFunc(SDL_BlendFactor factor)
973 {
974  switch (factor) {
976  return D3D11_BLEND_ZERO;
977  case SDL_BLENDFACTOR_ONE:
978  return D3D11_BLEND_ONE;
980  return D3D11_BLEND_SRC_COLOR;
982  return D3D11_BLEND_INV_SRC_COLOR;
984  return D3D11_BLEND_SRC_ALPHA;
986  return D3D11_BLEND_INV_SRC_ALPHA;
988  return D3D11_BLEND_DEST_COLOR;
990  return D3D11_BLEND_INV_DEST_COLOR;
992  return D3D11_BLEND_DEST_ALPHA;
994  return D3D11_BLEND_INV_DEST_ALPHA;
995  default:
996  return (D3D11_BLEND)0;
997  }
998 }
999 
1000 static D3D11_BLEND_OP GetBlendEquation(SDL_BlendOperation operation)
1001 {
1002  switch (operation) {
1004  return D3D11_BLEND_OP_ADD;
1006  return D3D11_BLEND_OP_SUBTRACT;
1008  return D3D11_BLEND_OP_REV_SUBTRACT;
1010  return D3D11_BLEND_OP_MIN;
1012  return D3D11_BLEND_OP_MAX;
1013  default:
1014  return (D3D11_BLEND_OP)0;
1015  }
1016 }
1017 
1018 static SDL_bool
1019 D3D11_CreateBlendState(SDL_Renderer * renderer, SDL_BlendMode blendMode)
1020 {
1021  D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
1022  SDL_BlendFactor srcColorFactor = SDL_GetBlendModeSrcColorFactor(blendMode);
1023  SDL_BlendFactor srcAlphaFactor = SDL_GetBlendModeSrcAlphaFactor(blendMode);
1024  SDL_BlendOperation colorOperation = SDL_GetBlendModeColorOperation(blendMode);
1025  SDL_BlendFactor dstColorFactor = SDL_GetBlendModeDstColorFactor(blendMode);
1026  SDL_BlendFactor dstAlphaFactor = SDL_GetBlendModeDstAlphaFactor(blendMode);
1027  SDL_BlendOperation alphaOperation = SDL_GetBlendModeAlphaOperation(blendMode);
1028  ID3D11BlendState *blendState = NULL;
1029  D3D11_BlendMode *blendModes;
1030  HRESULT result = S_OK;
1031 
1032  D3D11_BLEND_DESC blendDesc;
1033  SDL_zero(blendDesc);
1034  blendDesc.AlphaToCoverageEnable = FALSE;
1035  blendDesc.IndependentBlendEnable = FALSE;
1036  blendDesc.RenderTarget[0].BlendEnable = TRUE;
1037  blendDesc.RenderTarget[0].SrcBlend = GetBlendFunc(srcColorFactor);
1038  blendDesc.RenderTarget[0].DestBlend = GetBlendFunc(dstColorFactor);
1039  blendDesc.RenderTarget[0].BlendOp = GetBlendEquation(colorOperation);
1040  blendDesc.RenderTarget[0].SrcBlendAlpha = GetBlendFunc(srcAlphaFactor);
1041  blendDesc.RenderTarget[0].DestBlendAlpha = GetBlendFunc(dstAlphaFactor);
1042  blendDesc.RenderTarget[0].BlendOpAlpha = GetBlendEquation(alphaOperation);
1043  blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
1044  result = ID3D11Device_CreateBlendState(data->d3dDevice, &blendDesc, &blendState);
1045  if (FAILED(result)) {
1046  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBlendState"), result);
1047  return SDL_FALSE;
1048  }
1049 
1050  blendModes = (D3D11_BlendMode *)SDL_realloc(data->blendModes, (data->blendModesCount + 1) * sizeof(*blendModes));
1051  if (!blendModes) {
1052  SAFE_RELEASE(blendState);
1053  SDL_OutOfMemory();
1054  return SDL_FALSE;
1055  }
1056  blendModes[data->blendModesCount].blendMode = blendMode;
1057  blendModes[data->blendModesCount].blendState = blendState;
1058  data->blendModes = blendModes;
1059  ++data->blendModesCount;
1060 
1061  return SDL_TRUE;
1062 }
1063 
1064 /* Create resources that depend on the device. */
1065 static HRESULT
1066 D3D11_CreateDeviceResources(SDL_Renderer * renderer)
1067 {
1068  typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory);
1069  PFN_CREATE_DXGI_FACTORY CreateDXGIFactoryFunc;
1070  D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
1071  PFN_D3D11_CREATE_DEVICE D3D11CreateDeviceFunc;
1072  ID3D11Device *d3dDevice = NULL;
1073  ID3D11DeviceContext *d3dContext = NULL;
1074  IDXGIDevice1 *dxgiDevice = NULL;
1075  HRESULT result = S_OK;
1076  UINT creationFlags;
1077 
1078  /* This array defines the set of DirectX hardware feature levels this app will support.
1079  * Note the ordering should be preserved.
1080  * Don't forget to declare your application's minimum required feature level in its
1081  * description. All applications are assumed to support 9.1 unless otherwise stated.
1082  */
1083  D3D_FEATURE_LEVEL featureLevels[] =
1084  {
1085  D3D_FEATURE_LEVEL_11_1,
1086  D3D_FEATURE_LEVEL_11_0,
1087  D3D_FEATURE_LEVEL_10_1,
1088  D3D_FEATURE_LEVEL_10_0,
1089  D3D_FEATURE_LEVEL_9_3,
1090  D3D_FEATURE_LEVEL_9_2,
1091  D3D_FEATURE_LEVEL_9_1
1092  };
1093 
1094  /* Declare how the input layout for SDL's vertex shader will be setup: */
1095  const D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
1096  {
1097  { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1098  { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1099  { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1100  };
1101 
1102  D3D11_BUFFER_DESC constantBufferDesc;
1103  D3D11_SAMPLER_DESC samplerDesc;
1104  D3D11_RASTERIZER_DESC rasterDesc;
1105 
1106 #ifdef __WINRT__
1107  CreateDXGIFactoryFunc = CreateDXGIFactory1;
1108  D3D11CreateDeviceFunc = D3D11CreateDevice;
1109 #else
1110  data->hDXGIMod = SDL_LoadObject("dxgi.dll");
1111  if (!data->hDXGIMod) {
1112  result = E_FAIL;
1113  goto done;
1114  }
1115 
1116  CreateDXGIFactoryFunc = (PFN_CREATE_DXGI_FACTORY)SDL_LoadFunction(data->hDXGIMod, "CreateDXGIFactory");
1117  if (!CreateDXGIFactoryFunc) {
1118  result = E_FAIL;
1119  goto done;
1120  }
1121 
1122  data->hD3D11Mod = SDL_LoadObject("d3d11.dll");
1123  if (!data->hD3D11Mod) {
1124  result = E_FAIL;
1125  goto done;
1126  }
1127 
1128  D3D11CreateDeviceFunc = (PFN_D3D11_CREATE_DEVICE)SDL_LoadFunction(data->hD3D11Mod, "D3D11CreateDevice");
1129  if (!D3D11CreateDeviceFunc) {
1130  result = E_FAIL;
1131  goto done;
1132  }
1133 #endif /* __WINRT__ */
1134 
1135  result = CreateDXGIFactoryFunc(&SDL_IID_IDXGIFactory2, (void **)&data->dxgiFactory);
1136  if (FAILED(result)) {
1137  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("CreateDXGIFactory"), result);
1138  goto done;
1139  }
1140 
1141  /* FIXME: Should we use the default adapter? */
1142  result = IDXGIFactory2_EnumAdapters(data->dxgiFactory, 0, &data->dxgiAdapter);
1143  if (FAILED(result)) {
1144  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("D3D11CreateDevice"), result);
1145  goto done;
1146  }
1147 
1148  /* This flag adds support for surfaces with a different color channel ordering
1149  * than the API default. It is required for compatibility with Direct2D.
1150  */
1151  creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
1152 
1153  /* Make sure Direct3D's debugging feature gets used, if the app requests it. */
1155  creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
1156  }
1157 
1158  /* Create the Direct3D 11 API device object and a corresponding context. */
1159  result = D3D11CreateDeviceFunc(
1160  data->dxgiAdapter,
1161  D3D_DRIVER_TYPE_UNKNOWN,
1162  NULL,
1163  creationFlags, /* Set set debug and Direct2D compatibility flags. */
1164  featureLevels, /* List of feature levels this app can support. */
1165  SDL_arraysize(featureLevels),
1166  D3D11_SDK_VERSION, /* Always set this to D3D11_SDK_VERSION for Windows Store apps. */
1167  &d3dDevice, /* Returns the Direct3D device created. */
1168  &data->featureLevel, /* Returns feature level of device created. */
1169  &d3dContext /* Returns the device immediate context. */
1170  );
1171  if (FAILED(result)) {
1172  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("D3D11CreateDevice"), result);
1173  goto done;
1174  }
1175 
1176  result = ID3D11Device_QueryInterface(d3dDevice, &SDL_IID_ID3D11Device1, (void **)&data->d3dDevice);
1177  if (FAILED(result)) {
1178  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device to ID3D11Device1"), result);
1179  goto done;
1180  }
1181 
1182  result = ID3D11DeviceContext_QueryInterface(d3dContext, &SDL_IID_ID3D11DeviceContext1, (void **)&data->d3dContext);
1183  if (FAILED(result)) {
1184  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext to ID3D11DeviceContext1"), result);
1185  goto done;
1186  }
1187 
1188  result = ID3D11Device_QueryInterface(d3dDevice, &SDL_IID_IDXGIDevice1, (void **)&dxgiDevice);
1189  if (FAILED(result)) {
1190  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device to IDXGIDevice1"), result);
1191  goto done;
1192  }
1193 
1194  /* Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
1195  * ensures that the application will only render after each VSync, minimizing power consumption.
1196  */
1197  result = IDXGIDevice1_SetMaximumFrameLatency(dxgiDevice, 1);
1198  if (FAILED(result)) {
1199  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGIDevice1::SetMaximumFrameLatency"), result);
1200  goto done;
1201  }
1202 
1203  /* Make note of the maximum texture size
1204  * Max texture sizes are documented on MSDN, at:
1205  * http://msdn.microsoft.com/en-us/library/windows/apps/ff476876.aspx
1206  */
1207  switch (data->featureLevel) {
1208  case D3D_FEATURE_LEVEL_11_1:
1209  case D3D_FEATURE_LEVEL_11_0:
1210  renderer->info.max_texture_width = renderer->info.max_texture_height = 16384;
1211  break;
1212 
1213  case D3D_FEATURE_LEVEL_10_1:
1214  case D3D_FEATURE_LEVEL_10_0:
1215  renderer->info.max_texture_width = renderer->info.max_texture_height = 8192;
1216  break;
1217 
1218  case D3D_FEATURE_LEVEL_9_3:
1219  renderer->info.max_texture_width = renderer->info.max_texture_height = 4096;
1220  break;
1221 
1222  case D3D_FEATURE_LEVEL_9_2:
1223  case D3D_FEATURE_LEVEL_9_1:
1224  renderer->info.max_texture_width = renderer->info.max_texture_height = 2048;
1225  break;
1226 
1227  default:
1228  SDL_SetError("%s, Unexpected feature level: %d", __FUNCTION__, data->featureLevel);
1229  result = E_FAIL;
1230  goto done;
1231  }
1232 
1233  /* Load in SDL's one and only vertex shader: */
1234  result = ID3D11Device_CreateVertexShader(data->d3dDevice,
1235  D3D11_VertexShader,
1236  sizeof(D3D11_VertexShader),
1237  NULL,
1238  &data->vertexShader
1239  );
1240  if (FAILED(result)) {
1241  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateVertexShader"), result);
1242  goto done;
1243  }
1244 
1245  /* Create an input layout for SDL's vertex shader: */
1246  result = ID3D11Device_CreateInputLayout(data->d3dDevice,
1247  vertexDesc,
1248  ARRAYSIZE(vertexDesc),
1249  D3D11_VertexShader,
1250  sizeof(D3D11_VertexShader),
1251  &data->inputLayout
1252  );
1253  if (FAILED(result)) {
1254  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateInputLayout"), result);
1255  goto done;
1256  }
1257 
1258  /* Load in SDL's pixel shaders */
1259  result = ID3D11Device_CreatePixelShader(data->d3dDevice,
1260  D3D11_PixelShader_Colors,
1261  sizeof(D3D11_PixelShader_Colors),
1262  NULL,
1263  &data->colorPixelShader
1264  );
1265  if (FAILED(result)) {
1266  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreatePixelShader ['color' shader]"), result);
1267  goto done;
1268  }
1269 
1270  result = ID3D11Device_CreatePixelShader(data->d3dDevice,
1271  D3D11_PixelShader_Textures,
1272  sizeof(D3D11_PixelShader_Textures),
1273  NULL,
1274  &data->texturePixelShader
1275  );
1276  if (FAILED(result)) {
1277  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreatePixelShader ['textures' shader]"), result);
1278  goto done;
1279  }
1280 
1281  result = ID3D11Device_CreatePixelShader(data->d3dDevice,
1282  D3D11_PixelShader_YUV,
1283  sizeof(D3D11_PixelShader_YUV),
1284  NULL,
1285  &data->yuvPixelShader
1286  );
1287  if (FAILED(result)) {
1288  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreatePixelShader ['yuv' shader]"), result);
1289  goto done;
1290  }
1291 
1292  /* Setup space to hold vertex shader constants: */
1293  SDL_zero(constantBufferDesc);
1294  constantBufferDesc.ByteWidth = sizeof(VertexShaderConstants);
1295  constantBufferDesc.Usage = D3D11_USAGE_DEFAULT;
1296  constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
1297  result = ID3D11Device_CreateBuffer(data->d3dDevice,
1298  &constantBufferDesc,
1299  NULL,
1300  &data->vertexShaderConstants
1301  );
1302  if (FAILED(result)) {
1303  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBuffer [vertex shader constants]"), result);
1304  goto done;
1305  }
1306 
1307  /* Create samplers to use when drawing textures: */
1308  SDL_zero(samplerDesc);
1309  samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
1310  samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
1311  samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
1312  samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
1313  samplerDesc.MipLODBias = 0.0f;
1314  samplerDesc.MaxAnisotropy = 1;
1315  samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
1316  samplerDesc.MinLOD = 0.0f;
1317  samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
1318  result = ID3D11Device_CreateSamplerState(data->d3dDevice,
1319  &samplerDesc,
1320  &data->nearestPixelSampler
1321  );
1322  if (FAILED(result)) {
1323  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateSamplerState [nearest-pixel filter]"), result);
1324  goto done;
1325  }
1326 
1327  samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
1328  result = ID3D11Device_CreateSamplerState(data->d3dDevice,
1329  &samplerDesc,
1330  &data->linearSampler
1331  );
1332  if (FAILED(result)) {
1333  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateSamplerState [linear filter]"), result);
1334  goto done;
1335  }
1336 
1337  /* Setup Direct3D rasterizer states */
1338  SDL_zero(rasterDesc);
1339  rasterDesc.AntialiasedLineEnable = FALSE;
1340  rasterDesc.CullMode = D3D11_CULL_NONE;
1341  rasterDesc.DepthBias = 0;
1342  rasterDesc.DepthBiasClamp = 0.0f;
1343  rasterDesc.DepthClipEnable = TRUE;
1344  rasterDesc.FillMode = D3D11_FILL_SOLID;
1345  rasterDesc.FrontCounterClockwise = FALSE;
1346  rasterDesc.MultisampleEnable = FALSE;
1347  rasterDesc.ScissorEnable = FALSE;
1348  rasterDesc.SlopeScaledDepthBias = 0.0f;
1349  result = ID3D11Device_CreateRasterizerState(data->d3dDevice, &rasterDesc, &data->mainRasterizer);
1350  if (FAILED(result)) {
1351  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateRasterizerState [main rasterizer]"), result);
1352  goto done;
1353  }
1354 
1355  rasterDesc.ScissorEnable = TRUE;
1356  result = ID3D11Device_CreateRasterizerState(data->d3dDevice, &rasterDesc, &data->clippedRasterizer);
1357  if (FAILED(result)) {
1358  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateRasterizerState [clipped rasterizer]"), result);
1359  goto done;
1360  }
1361 
1362  /* Create blending states: */
1363  if (!D3D11_CreateBlendState(renderer, SDL_BLENDMODE_BLEND) ||
1364  !D3D11_CreateBlendState(renderer, SDL_BLENDMODE_ADD) ||
1365  !D3D11_CreateBlendState(renderer, SDL_BLENDMODE_MOD)) {
1366  /* D3D11_CreateBlendMode will set the SDL error, if it fails */
1367  goto done;
1368  }
1369 
1370  /* Setup render state that doesn't change */
1371  ID3D11DeviceContext_IASetInputLayout(data->d3dContext, data->inputLayout);
1372  ID3D11DeviceContext_VSSetShader(data->d3dContext, data->vertexShader, NULL, 0);
1373  ID3D11DeviceContext_VSSetConstantBuffers(data->d3dContext, 0, 1, &data->vertexShaderConstants);
1374 
1375 done:
1376  SAFE_RELEASE(d3dDevice);
1377  SAFE_RELEASE(d3dContext);
1378  SAFE_RELEASE(dxgiDevice);
1379  return result;
1380 }
1381 
1382 #ifdef __WIN32__
1383 
1384 static DXGI_MODE_ROTATION
1385 D3D11_GetCurrentRotation()
1386 {
1387  /* FIXME */
1388  return DXGI_MODE_ROTATION_IDENTITY;
1389 }
1390 
1391 #endif /* __WIN32__ */
1392 
1393 static BOOL
1394 D3D11_IsDisplayRotated90Degrees(DXGI_MODE_ROTATION rotation)
1395 {
1396  switch (rotation) {
1397  case DXGI_MODE_ROTATION_ROTATE90:
1398  case DXGI_MODE_ROTATION_ROTATE270:
1399  return TRUE;
1400  default:
1401  return FALSE;
1402  }
1403 }
1404 
1405 static int
1406 D3D11_GetRotationForCurrentRenderTarget(SDL_Renderer * renderer)
1407 {
1408  D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
1409  if (data->currentOffscreenRenderTargetView) {
1410  return DXGI_MODE_ROTATION_IDENTITY;
1411  } else {
1412  return data->rotation;
1413  }
1414 }
1415 
1416 static int
1417 D3D11_GetViewportAlignedD3DRect(SDL_Renderer * renderer, const SDL_Rect * sdlRect, D3D11_RECT * outRect, BOOL includeViewportOffset)
1418 {
1419  const int rotation = D3D11_GetRotationForCurrentRenderTarget(renderer);
1420  switch (rotation) {
1421  case DXGI_MODE_ROTATION_IDENTITY:
1422  outRect->left = sdlRect->x;
1423  outRect->right = sdlRect->x + sdlRect->w;
1424  outRect->top = sdlRect->y;
1425  outRect->bottom = sdlRect->y + sdlRect->h;
1426  if (includeViewportOffset) {
1427  outRect->left += renderer->viewport.x;
1428  outRect->right += renderer->viewport.x;
1429  outRect->top += renderer->viewport.y;
1430  outRect->bottom += renderer->viewport.y;
1431  }
1432  break;
1433  case DXGI_MODE_ROTATION_ROTATE270:
1434  outRect->left = sdlRect->y;
1435  outRect->right = sdlRect->y + sdlRect->h;
1436  outRect->top = renderer->viewport.w - sdlRect->x - sdlRect->w;
1437  outRect->bottom = renderer->viewport.w - sdlRect->x;
1438  break;
1439  case DXGI_MODE_ROTATION_ROTATE180:
1440  outRect->left = renderer->viewport.w - sdlRect->x - sdlRect->w;
1441  outRect->right = renderer->viewport.w - sdlRect->x;
1442  outRect->top = renderer->viewport.h - sdlRect->y - sdlRect->h;
1443  outRect->bottom = renderer->viewport.h - sdlRect->y;
1444  break;
1445  case DXGI_MODE_ROTATION_ROTATE90:
1446  outRect->left = renderer->viewport.h - sdlRect->y - sdlRect->h;
1447  outRect->right = renderer->viewport.h - sdlRect->y;
1448  outRect->top = sdlRect->x;
1449  outRect->bottom = sdlRect->x + sdlRect->h;
1450  break;
1451  default:
1452  return SDL_SetError("The physical display is in an unknown or unsupported rotation");
1453  }
1454  return 0;
1455 }
1456 
1457 static HRESULT
1458 D3D11_CreateSwapChain(SDL_Renderer * renderer, int w, int h)
1459 {
1460  D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
1461 #ifdef __WINRT__
1462  IUnknown *coreWindow = D3D11_GetCoreWindowFromSDLRenderer(renderer);
1463  const BOOL usingXAML = (coreWindow == NULL);
1464 #else
1465  IUnknown *coreWindow = NULL;
1466  const BOOL usingXAML = FALSE;
1467 #endif
1468  HRESULT result = S_OK;
1469 
1470  /* Create a swap chain using the same adapter as the existing Direct3D device. */
1471  DXGI_SWAP_CHAIN_DESC1 swapChainDesc;
1472  SDL_zero(swapChainDesc);
1473  swapChainDesc.Width = w;
1474  swapChainDesc.Height = h;
1475  swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; /* This is the most common swap chain format. */
1476  swapChainDesc.Stereo = FALSE;
1477  swapChainDesc.SampleDesc.Count = 1; /* Don't use multi-sampling. */
1478  swapChainDesc.SampleDesc.Quality = 0;
1479  swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
1480  swapChainDesc.BufferCount = 2; /* Use double-buffering to minimize latency. */
1481 #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
1482  swapChainDesc.Scaling = DXGI_SCALING_STRETCH; /* On phone, only stretch and aspect-ratio stretch scaling are allowed. */
1483  swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; /* On phone, no swap effects are supported. */
1484  /* 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 */
1485 #else
1486  if (usingXAML) {
1487  swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
1488  } else {
1489  swapChainDesc.Scaling = DXGI_SCALING_NONE;
1490  }
1491  swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; /* All Windows Store apps must use this SwapEffect. */
1492 #endif
1493  swapChainDesc.Flags = 0;
1494 
1495  if (coreWindow) {
1496  result = IDXGIFactory2_CreateSwapChainForCoreWindow(data->dxgiFactory,
1497  (IUnknown *)data->d3dDevice,
1498  coreWindow,
1499  &swapChainDesc,
1500  NULL, /* Allow on all displays. */
1501  &data->swapChain
1502  );
1503  if (FAILED(result)) {
1504  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGIFactory2::CreateSwapChainForCoreWindow"), result);
1505  goto done;
1506  }
1507  } else if (usingXAML) {
1508  result = IDXGIFactory2_CreateSwapChainForComposition(data->dxgiFactory,
1509  (IUnknown *)data->d3dDevice,
1510  &swapChainDesc,
1511  NULL,
1512  &data->swapChain);
1513  if (FAILED(result)) {
1514  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGIFactory2::CreateSwapChainForComposition"), result);
1515  goto done;
1516  }
1517 
1518 #if WINAPI_FAMILY == WINAPI_FAMILY_APP
1519  result = ISwapChainBackgroundPanelNative_SetSwapChain(WINRT_GlobalSwapChainBackgroundPanelNative, (IDXGISwapChain *) data->swapChain);
1520  if (FAILED(result)) {
1521  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ISwapChainBackgroundPanelNative::SetSwapChain"), result);
1522  goto done;
1523  }
1524 #else
1525  SDL_SetError(SDL_COMPOSE_ERROR("XAML support is not yet available for Windows Phone"));
1526  result = E_FAIL;
1527  goto done;
1528 #endif
1529  } else {
1530 #ifdef __WIN32__
1531  SDL_SysWMinfo windowinfo;
1532  SDL_VERSION(&windowinfo.version);
1533  SDL_GetWindowWMInfo(renderer->window, &windowinfo);
1534 
1535  result = IDXGIFactory2_CreateSwapChainForHwnd(data->dxgiFactory,
1536  (IUnknown *)data->d3dDevice,
1537  windowinfo.info.win.window,
1538  &swapChainDesc,
1539  NULL,
1540  NULL, /* Allow on all displays. */
1541  &data->swapChain
1542  );
1543  if (FAILED(result)) {
1544  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGIFactory2::CreateSwapChainForHwnd"), result);
1545  goto done;
1546  }
1547 
1548  IDXGIFactory_MakeWindowAssociation(data->dxgiFactory, windowinfo.info.win.window, DXGI_MWA_NO_WINDOW_CHANGES);
1549 #else
1550  SDL_SetError(__FUNCTION__", Unable to find something to attach a swap chain to");
1551  goto done;
1552 #endif /* ifdef __WIN32__ / else */
1553  }
1554  data->swapEffect = swapChainDesc.SwapEffect;
1555 
1556 done:
1557  SAFE_RELEASE(coreWindow);
1558  return result;
1559 }
1560 
1561 
1562 /* Initialize all resources that change when the window's size changes. */
1563 static HRESULT
1564 D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
1565 {
1566  D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
1567  ID3D11Texture2D *backBuffer = NULL;
1568  HRESULT result = S_OK;
1569  int w, h;
1570 
1571  /* Release the previous render target view */
1572  D3D11_ReleaseMainRenderTargetView(renderer);
1573 
1574  /* The width and height of the swap chain must be based on the display's
1575  * non-rotated size.
1576  */
1577  SDL_GetWindowSize(renderer->window, &w, &h);
1578  data->rotation = D3D11_GetCurrentRotation();
1579  /* SDL_Log("%s: windowSize={%d,%d}, orientation=%d\n", __FUNCTION__, w, h, (int)data->rotation); */
1580  if (D3D11_IsDisplayRotated90Degrees(data->rotation)) {
1581  int tmp = w;
1582  w = h;
1583  h = tmp;
1584  }
1585 
1586  if (data->swapChain) {
1587  /* IDXGISwapChain::ResizeBuffers is not available on Windows Phone 8. */
1588 #if !defined(__WINRT__) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
1589  /* If the swap chain already exists, resize it. */
1590  result = IDXGISwapChain_ResizeBuffers(data->swapChain,
1591  0,
1592  w, h,
1593  DXGI_FORMAT_UNKNOWN,
1594  0
1595  );
1596  if (result == DXGI_ERROR_DEVICE_REMOVED) {
1597  /* If the device was removed for any reason, a new device and swap chain will need to be created. */
1598  D3D11_HandleDeviceLost(renderer);
1599 
1600  /* Everything is set up now. Do not continue execution of this method. HandleDeviceLost will reenter this method
1601  * and correctly set up the new device.
1602  */
1603  goto done;
1604  } else if (FAILED(result)) {
1605  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::ResizeBuffers"), result);
1606  goto done;
1607  }
1608 #endif
1609  } else {
1610  result = D3D11_CreateSwapChain(renderer, w, h);
1611  if (FAILED(result)) {
1612  goto done;
1613  }
1614  }
1615 
1616 #if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
1617  /* Set the proper rotation for the swap chain.
1618  *
1619  * To note, the call for this, IDXGISwapChain1::SetRotation, is not necessary
1620  * on Windows Phone 8.0, nor is it supported there.
1621  *
1622  * IDXGISwapChain1::SetRotation does seem to be available on Windows Phone 8.1,
1623  * however I've yet to find a way to make it work. It might have something to
1624  * do with IDXGISwapChain::ResizeBuffers appearing to not being available on
1625  * Windows Phone 8.1 (it wasn't on Windows Phone 8.0), but I'm not 100% sure of this.
1626  * The call doesn't appear to be entirely necessary though, and is a performance-related
1627  * call, at least according to the following page on MSDN:
1628  * http://code.msdn.microsoft.com/windowsapps/DXGI-swap-chain-rotation-21d13d71
1629  * -- David L.
1630  *
1631  * TODO, WinRT: reexamine the docs for IDXGISwapChain1::SetRotation, see if might be available, usable, and prudent-to-call on WinPhone 8.1
1632  */
1633  if (data->swapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL) {
1634  result = IDXGISwapChain1_SetRotation(data->swapChain, data->rotation);
1635  if (FAILED(result)) {
1636  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain1::SetRotation"), result);
1637  goto done;
1638  }
1639  }
1640 #endif
1641 
1642  result = IDXGISwapChain_GetBuffer(data->swapChain,
1643  0,
1644  &SDL_IID_ID3D11Texture2D,
1645  (void **)&backBuffer
1646  );
1647  if (FAILED(result)) {
1648  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::GetBuffer [back-buffer]"), result);
1649  goto done;
1650  }
1651 
1652  /* Create a render target view of the swap chain back buffer. */
1653  result = ID3D11Device_CreateRenderTargetView(data->d3dDevice,
1654  (ID3D11Resource *)backBuffer,
1655  NULL,
1656  &data->mainRenderTargetView
1657  );
1658  if (FAILED(result)) {
1659  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device::CreateRenderTargetView"), result);
1660  goto done;
1661  }
1662 
1663  if (D3D11_UpdateViewport(renderer) != 0) {
1664  /* D3D11_UpdateViewport will set the SDL error if it fails. */
1665  result = E_FAIL;
1666  goto done;
1667  }
1668 
1669 done:
1670  SAFE_RELEASE(backBuffer);
1671  return result;
1672 }
1673 
1674 /* This method is called when the window's size changes. */
1675 static HRESULT
1676 D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer)
1677 {
1678  return D3D11_CreateWindowSizeDependentResources(renderer);
1679 }
1680 
1681 HRESULT
1682 D3D11_HandleDeviceLost(SDL_Renderer * renderer)
1683 {
1684  HRESULT result = S_OK;
1685 
1686  D3D11_ReleaseAll(renderer);
1687 
1688  result = D3D11_CreateDeviceResources(renderer);
1689  if (FAILED(result)) {
1690  /* D3D11_CreateDeviceResources will set the SDL error */
1691  return result;
1692  }
1693 
1694  result = D3D11_UpdateForWindowSizeChange(renderer);
1695  if (FAILED(result)) {
1696  /* D3D11_UpdateForWindowSizeChange will set the SDL error */
1697  return result;
1698  }
1699 
1700  /* Let the application know that the device has been reset */
1701  {
1702  SDL_Event event;
1703  event.type = SDL_RENDER_DEVICE_RESET;
1704  SDL_PushEvent(&event);
1705  }
1706 
1707  return S_OK;
1708 }
1709 
1710 void
1711 D3D11_Trim(SDL_Renderer * renderer)
1712 {
1713 #ifdef __WINRT__
1714 #if NTDDI_VERSION > NTDDI_WIN8
1715  D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
1716  HRESULT result = S_OK;
1717  IDXGIDevice3 *dxgiDevice = NULL;
1718 
1719  result = ID3D11Device_QueryInterface(data->d3dDevice, &SDL_IID_IDXGIDevice3, &dxgiDevice);
1720  if (FAILED(result)) {
1721  //WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to IDXGIDevice3", result);
1722  return;
1723  }
1724 
1725  IDXGIDevice3_Trim(dxgiDevice);
1726  SAFE_RELEASE(dxgiDevice);
1727 #endif
1728 #endif
1729 }
1730 
1731 static void
1732 D3D11_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
1733 {
1734  if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
1735  D3D11_UpdateForWindowSizeChange(renderer);
1736  }
1737 }
1738 
1739 static SDL_bool
1740 D3D11_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
1741 {
1742  SDL_BlendFactor srcColorFactor = SDL_GetBlendModeSrcColorFactor(blendMode);
1743  SDL_BlendFactor srcAlphaFactor = SDL_GetBlendModeSrcAlphaFactor(blendMode);
1744  SDL_BlendOperation colorOperation = SDL_GetBlendModeColorOperation(blendMode);
1745  SDL_BlendFactor dstColorFactor = SDL_GetBlendModeDstColorFactor(blendMode);
1746  SDL_BlendFactor dstAlphaFactor = SDL_GetBlendModeDstAlphaFactor(blendMode);
1747  SDL_BlendOperation alphaOperation = SDL_GetBlendModeAlphaOperation(blendMode);
1748 
1749  if (!GetBlendFunc(srcColorFactor) || !GetBlendFunc(srcAlphaFactor) ||
1750  !GetBlendEquation(colorOperation) ||
1751  !GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor) ||
1752  !GetBlendEquation(alphaOperation)) {
1753  return SDL_FALSE;
1754  }
1755  return SDL_TRUE;
1756 }
1757 
1758 static D3D11_FILTER
1759 GetScaleQuality(void)
1760 {
1761  const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
1762  if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
1763  return D3D11_FILTER_MIN_MAG_MIP_POINT;
1764  } else /* if (*hint == '1' || SDL_strcasecmp(hint, "linear") == 0) */ {
1765  return D3D11_FILTER_MIN_MAG_MIP_LINEAR;
1766  }
1767 }
1768 
1769 static int
1770 D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
1771 {
1772  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
1773  D3D11_TextureData *textureData;
1774  HRESULT result;
1775  DXGI_FORMAT textureFormat = SDLPixelFormatToDXGIFormat(texture->format);
1776  D3D11_TEXTURE2D_DESC textureDesc;
1777  D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc;
1778 
1779  if (textureFormat == DXGI_FORMAT_UNKNOWN) {
1780  return SDL_SetError("%s, An unsupported SDL pixel format (0x%x) was specified",
1781  __FUNCTION__, texture->format);
1782  }
1783 
1784  textureData = (D3D11_TextureData*) SDL_calloc(1, sizeof(*textureData));
1785  if (!textureData) {
1786  SDL_OutOfMemory();
1787  return -1;
1788  }
1789  textureData->scaleMode = GetScaleQuality();
1790 
1791  texture->driverdata = textureData;
1792 
1793  SDL_zero(textureDesc);
1794  textureDesc.Width = texture->w;
1795  textureDesc.Height = texture->h;
1796  textureDesc.MipLevels = 1;
1797  textureDesc.ArraySize = 1;
1798  textureDesc.Format = textureFormat;
1799  textureDesc.SampleDesc.Count = 1;
1800  textureDesc.SampleDesc.Quality = 0;
1801  textureDesc.MiscFlags = 0;
1802 
1803  if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
1804  textureDesc.Usage = D3D11_USAGE_DYNAMIC;
1805  textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
1806  } else {
1807  textureDesc.Usage = D3D11_USAGE_DEFAULT;
1808  textureDesc.CPUAccessFlags = 0;
1809  }
1810 
1811  if (texture->access == SDL_TEXTUREACCESS_TARGET) {
1812  textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
1813  } else {
1814  textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
1815  }
1816 
1817  result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
1818  &textureDesc,
1819  NULL,
1820  &textureData->mainTexture
1821  );
1822  if (FAILED(result)) {
1823  D3D11_DestroyTexture(renderer, texture);
1824  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
1825  return -1;
1826  }
1827 
1828  if (texture->format == SDL_PIXELFORMAT_YV12 ||
1829  texture->format == SDL_PIXELFORMAT_IYUV) {
1830  textureData->yuv = SDL_TRUE;
1831 
1832  textureDesc.Width /= 2;
1833  textureDesc.Height /= 2;
1834 
1835  result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
1836  &textureDesc,
1837  NULL,
1838  &textureData->mainTextureU
1839  );
1840  if (FAILED(result)) {
1841  D3D11_DestroyTexture(renderer, texture);
1842  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
1843  return -1;
1844  }
1845 
1846  result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
1847  &textureDesc,
1848  NULL,
1849  &textureData->mainTextureV
1850  );
1851  if (FAILED(result)) {
1852  D3D11_DestroyTexture(renderer, texture);
1853  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
1854  return -1;
1855  }
1856  }
1857 
1858  resourceViewDesc.Format = textureDesc.Format;
1859  resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
1860  resourceViewDesc.Texture2D.MostDetailedMip = 0;
1861  resourceViewDesc.Texture2D.MipLevels = textureDesc.MipLevels;
1862  result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice,
1863  (ID3D11Resource *)textureData->mainTexture,
1864  &resourceViewDesc,
1865  &textureData->mainTextureResourceView
1866  );
1867  if (FAILED(result)) {
1868  D3D11_DestroyTexture(renderer, texture);
1869  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
1870  return -1;
1871  }
1872 
1873  if (textureData->yuv) {
1874  result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice,
1875  (ID3D11Resource *)textureData->mainTextureU,
1876  &resourceViewDesc,
1877  &textureData->mainTextureResourceViewU
1878  );
1879  if (FAILED(result)) {
1880  D3D11_DestroyTexture(renderer, texture);
1881  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
1882  return -1;
1883  }
1884  result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice,
1885  (ID3D11Resource *)textureData->mainTextureV,
1886  &resourceViewDesc,
1887  &textureData->mainTextureResourceViewV
1888  );
1889  if (FAILED(result)) {
1890  D3D11_DestroyTexture(renderer, texture);
1891  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
1892  return -1;
1893  }
1894  }
1895 
1896  if (texture->access & SDL_TEXTUREACCESS_TARGET) {
1897  D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
1898  renderTargetViewDesc.Format = textureDesc.Format;
1899  renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
1900  renderTargetViewDesc.Texture2D.MipSlice = 0;
1901 
1902  result = ID3D11Device_CreateRenderTargetView(rendererData->d3dDevice,
1903  (ID3D11Resource *)textureData->mainTexture,
1904  &renderTargetViewDesc,
1905  &textureData->mainTextureRenderTargetView);
1906  if (FAILED(result)) {
1907  D3D11_DestroyTexture(renderer, texture);
1908  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateRenderTargetView"), result);
1909  return -1;
1910  }
1911  }
1912 
1913  return 0;
1914 }
1915 
1916 static void
1917 D3D11_DestroyTexture(SDL_Renderer * renderer,
1918  SDL_Texture * texture)
1919 {
1920  D3D11_TextureData *data = (D3D11_TextureData *)texture->driverdata;
1921 
1922  if (!data) {
1923  return;
1924  }
1925 
1926  SAFE_RELEASE(data->mainTexture);
1927  SAFE_RELEASE(data->mainTextureResourceView);
1928  SAFE_RELEASE(data->mainTextureRenderTargetView);
1929  SAFE_RELEASE(data->stagingTexture);
1930  SAFE_RELEASE(data->mainTextureU);
1931  SAFE_RELEASE(data->mainTextureResourceViewU);
1932  SAFE_RELEASE(data->mainTextureV);
1933  SAFE_RELEASE(data->mainTextureResourceViewV);
1934  SDL_free(data->pixels);
1935  SDL_free(data);
1936  texture->driverdata = NULL;
1937 }
1938 
1939 static int
1940 D3D11_UpdateTextureInternal(D3D11_RenderData *rendererData, ID3D11Texture2D *texture, Uint32 format, int x, int y, int w, int h, const void *pixels, int pitch)
1941 {
1942  ID3D11Texture2D *stagingTexture;
1943  const Uint8 *src;
1944  Uint8 *dst;
1945  int row;
1946  UINT length;
1947  HRESULT result;
1948  D3D11_TEXTURE2D_DESC stagingTextureDesc;
1949  D3D11_MAPPED_SUBRESOURCE textureMemory;
1950 
1951  /* Create a 'staging' texture, which will be used to write to a portion of the main texture. */
1952  ID3D11Texture2D_GetDesc(texture, &stagingTextureDesc);
1953  stagingTextureDesc.Width = w;
1954  stagingTextureDesc.Height = h;
1955  stagingTextureDesc.BindFlags = 0;
1956  stagingTextureDesc.MiscFlags = 0;
1957  stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
1958  stagingTextureDesc.Usage = D3D11_USAGE_STAGING;
1959  result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
1960  &stagingTextureDesc,
1961  NULL,
1962  &stagingTexture);
1963  if (FAILED(result)) {
1964  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result);
1965  return -1;
1966  }
1967 
1968  /* Get a write-only pointer to data in the staging texture: */
1969  result = ID3D11DeviceContext_Map(rendererData->d3dContext,
1970  (ID3D11Resource *)stagingTexture,
1971  0,
1972  D3D11_MAP_WRITE,
1973  0,
1974  &textureMemory
1975  );
1976  if (FAILED(result)) {
1977  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result);
1978  SAFE_RELEASE(stagingTexture);
1979  return -1;
1980  }
1981 
1982  src = (const Uint8 *)pixels;
1983  dst = textureMemory.pData;
1984  length = w * SDL_BYTESPERPIXEL(format);
1985  if (length == pitch && length == textureMemory.RowPitch) {
1986  SDL_memcpy(dst, src, length*h);
1987  } else {
1988  if (length > (UINT)pitch) {
1989  length = pitch;
1990  }
1991  if (length > textureMemory.RowPitch) {
1992  length = textureMemory.RowPitch;
1993  }
1994  for (row = 0; row < h; ++row) {
1995  SDL_memcpy(dst, src, length);
1996  src += pitch;
1997  dst += textureMemory.RowPitch;
1998  }
1999  }
2000 
2001  /* Commit the pixel buffer's changes back to the staging texture: */
2002  ID3D11DeviceContext_Unmap(rendererData->d3dContext,
2003  (ID3D11Resource *)stagingTexture,
2004  0);
2005 
2006  /* Copy the staging texture's contents back to the texture: */
2007  ID3D11DeviceContext_CopySubresourceRegion(rendererData->d3dContext,
2008  (ID3D11Resource *)texture,
2009  0,
2010  x,
2011  y,
2012  0,
2013  (ID3D11Resource *)stagingTexture,
2014  0,
2015  NULL);
2016 
2017  SAFE_RELEASE(stagingTexture);
2018 
2019  return 0;
2020 }
2021 
2022 static int
2023 D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
2024  const SDL_Rect * rect, const void * srcPixels,
2025  int srcPitch)
2026 {
2027  D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata;
2028  D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata;
2029 
2030  if (!textureData) {
2031  SDL_SetError("Texture is not currently available");
2032  return -1;
2033  }
2034 
2035  if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, texture->format, rect->x, rect->y, rect->w, rect->h, srcPixels, srcPitch) < 0) {
2036  return -1;
2037  }
2038 
2039  if (textureData->yuv) {
2040  /* Skip to the correct offset into the next texture */
2041  srcPixels = (const void*)((const Uint8*)srcPixels + rect->h * srcPitch);
2042 
2043  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) {
2044  return -1;
2045  }
2046 
2047  /* Skip to the correct offset into the next texture */
2048  srcPixels = (const void*)((const Uint8*)srcPixels + (rect->h * srcPitch) / 4);
2049  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) {
2050  return -1;
2051  }
2052  }
2053  return 0;
2054 }
2055 
2056 static int
2057 D3D11_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
2058  const SDL_Rect * rect,
2059  const Uint8 *Yplane, int Ypitch,
2060  const Uint8 *Uplane, int Upitch,
2061  const Uint8 *Vplane, int Vpitch)
2062 {
2063  D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata;
2064  D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata;
2065 
2066  if (!textureData) {
2067  SDL_SetError("Texture is not currently available");
2068  return -1;
2069  }
2070 
2071  if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, texture->format, rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch) < 0) {
2072  return -1;
2073  }
2074  if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTextureU, texture->format, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, Uplane, Upitch) < 0) {
2075  return -1;
2076  }
2077  if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTextureV, texture->format, rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, Vplane, Vpitch) < 0) {
2078  return -1;
2079  }
2080  return 0;
2081 }
2082 
2083 static int
2084 D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
2085  const SDL_Rect * rect, void **pixels, int *pitch)
2086 {
2087  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2088  D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
2089  HRESULT result = S_OK;
2090  D3D11_TEXTURE2D_DESC stagingTextureDesc;
2091  D3D11_MAPPED_SUBRESOURCE textureMemory;
2092 
2093  if (!textureData) {
2094  SDL_SetError("Texture is not currently available");
2095  return -1;
2096  }
2097 
2098  if (textureData->yuv) {
2099  /* It's more efficient to upload directly... */
2100  if (!textureData->pixels) {
2101  textureData->pitch = texture->w;
2102  textureData->pixels = (Uint8 *)SDL_malloc((texture->h * textureData->pitch * 3) / 2);
2103  if (!textureData->pixels) {
2104  return SDL_OutOfMemory();
2105  }
2106  }
2107  textureData->locked_rect = *rect;
2108  *pixels =
2109  (void *)((Uint8 *)textureData->pixels + rect->y * textureData->pitch +
2110  rect->x * SDL_BYTESPERPIXEL(texture->format));
2111  *pitch = textureData->pitch;
2112  return 0;
2113  }
2114 
2115  if (textureData->stagingTexture) {
2116  return SDL_SetError("texture is already locked");
2117  }
2118 
2119  /* Create a 'staging' texture, which will be used to write to a portion
2120  * of the main texture. This is necessary, as Direct3D 11.1 does not
2121  * have the ability to write a CPU-bound pixel buffer to a rectangular
2122  * subrect of a texture. Direct3D 11.1 can, however, write a pixel
2123  * buffer to an entire texture, hence the use of a staging texture.
2124  *
2125  * TODO, WinRT: consider avoiding the use of a staging texture in D3D11_LockTexture if/when the entire texture is being updated
2126  */
2127  ID3D11Texture2D_GetDesc(textureData->mainTexture, &stagingTextureDesc);
2128  stagingTextureDesc.Width = rect->w;
2129  stagingTextureDesc.Height = rect->h;
2130  stagingTextureDesc.BindFlags = 0;
2131  stagingTextureDesc.MiscFlags = 0;
2132  stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2133  stagingTextureDesc.Usage = D3D11_USAGE_STAGING;
2134  result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
2135  &stagingTextureDesc,
2136  NULL,
2137  &textureData->stagingTexture);
2138  if (FAILED(result)) {
2139  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result);
2140  return -1;
2141  }
2142 
2143  /* Get a write-only pointer to data in the staging texture: */
2144  result = ID3D11DeviceContext_Map(rendererData->d3dContext,
2145  (ID3D11Resource *)textureData->stagingTexture,
2146  0,
2147  D3D11_MAP_WRITE,
2148  0,
2149  &textureMemory
2150  );
2151  if (FAILED(result)) {
2152  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result);
2153  SAFE_RELEASE(textureData->stagingTexture);
2154  return -1;
2155  }
2156 
2157  /* Make note of where the staging texture will be written to
2158  * (on a call to SDL_UnlockTexture):
2159  */
2160  textureData->lockedTexturePositionX = rect->x;
2161  textureData->lockedTexturePositionY = rect->y;
2162 
2163  /* Make sure the caller has information on the texture's pixel buffer,
2164  * then return:
2165  */
2166  *pixels = textureMemory.pData;
2167  *pitch = textureMemory.RowPitch;
2168  return 0;
2169 }
2170 
2171 static void
2172 D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
2173 {
2174  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2175  D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
2176 
2177  if (!textureData) {
2178  return;
2179  }
2180 
2181  if (textureData->yuv) {
2182  const SDL_Rect *rect = &textureData->locked_rect;
2183  void *pixels =
2184  (void *) ((Uint8 *) textureData->pixels + rect->y * textureData->pitch +
2185  rect->x * SDL_BYTESPERPIXEL(texture->format));
2186  D3D11_UpdateTexture(renderer, texture, rect, pixels, textureData->pitch);
2187  return;
2188  }
2189 
2190  /* Commit the pixel buffer's changes back to the staging texture: */
2191  ID3D11DeviceContext_Unmap(rendererData->d3dContext,
2192  (ID3D11Resource *)textureData->stagingTexture,
2193  0);
2194 
2195  /* Copy the staging texture's contents back to the main texture: */
2196  ID3D11DeviceContext_CopySubresourceRegion(rendererData->d3dContext,
2197  (ID3D11Resource *)textureData->mainTexture,
2198  0,
2199  textureData->lockedTexturePositionX,
2200  textureData->lockedTexturePositionY,
2201  0,
2202  (ID3D11Resource *)textureData->stagingTexture,
2203  0,
2204  NULL);
2205 
2206  SAFE_RELEASE(textureData->stagingTexture);
2207 }
2208 
2209 static int
2210 D3D11_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
2211 {
2212  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2213  D3D11_TextureData *textureData = NULL;
2214 
2215  if (texture == NULL) {
2216  rendererData->currentOffscreenRenderTargetView = NULL;
2217  return 0;
2218  }
2219 
2220  textureData = (D3D11_TextureData *) texture->driverdata;
2221 
2222  if (!textureData->mainTextureRenderTargetView) {
2223  return SDL_SetError("specified texture is not a render target");
2224  }
2225 
2226  rendererData->currentOffscreenRenderTargetView = textureData->mainTextureRenderTargetView;
2227 
2228  return 0;
2229 }
2230 
2231 static void
2232 D3D11_SetModelMatrix(SDL_Renderer *renderer, const Float4X4 *matrix)
2233 {
2234  D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
2235 
2236  if (matrix) {
2237  data->vertexShaderConstantsData.model = *matrix;
2238  } else {
2239  data->vertexShaderConstantsData.model = MatrixIdentity();
2240  }
2241 
2242  ID3D11DeviceContext_UpdateSubresource(data->d3dContext,
2243  (ID3D11Resource *)data->vertexShaderConstants,
2244  0,
2245  NULL,
2246  &data->vertexShaderConstantsData,
2247  0,
2248  0
2249  );
2250 }
2251 
2252 static int
2253 D3D11_UpdateViewport(SDL_Renderer * renderer)
2254 {
2255  D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
2256  Float4X4 projection;
2257  Float4X4 view;
2258  SDL_FRect orientationAlignedViewport;
2259  BOOL swapDimensions;
2260  D3D11_VIEWPORT viewport;
2261  const int rotation = D3D11_GetRotationForCurrentRenderTarget(renderer);
2262 
2263  if (renderer->viewport.w == 0 || renderer->viewport.h == 0) {
2264  /* If the viewport is empty, assume that it is because
2265  * SDL_CreateRenderer is calling it, and will call it again later
2266  * with a non-empty viewport.
2267  */
2268  /* SDL_Log("%s, no viewport was set!\n", __FUNCTION__); */
2269  return 0;
2270  }
2271 
2272  /* Make sure the SDL viewport gets rotated to that of the physical display's rotation.
2273  * Keep in mind here that the Y-axis will be been inverted (from Direct3D's
2274  * default coordinate system) so rotations will be done in the opposite
2275  * direction of the DXGI_MODE_ROTATION enumeration.
2276  */
2277  switch (rotation) {
2278  case DXGI_MODE_ROTATION_IDENTITY:
2279  projection = MatrixIdentity();
2280  break;
2281  case DXGI_MODE_ROTATION_ROTATE270:
2282  projection = MatrixRotationZ(SDL_static_cast(float, M_PI * 0.5f));
2283  break;
2284  case DXGI_MODE_ROTATION_ROTATE180:
2285  projection = MatrixRotationZ(SDL_static_cast(float, M_PI));
2286  break;
2287  case DXGI_MODE_ROTATION_ROTATE90:
2288  projection = MatrixRotationZ(SDL_static_cast(float, -M_PI * 0.5f));
2289  break;
2290  default:
2291  return SDL_SetError("An unknown DisplayOrientation is being used");
2292  }
2293 
2294  /* Update the view matrix */
2295  view.m[0][0] = 2.0f / renderer->viewport.w;
2296  view.m[0][1] = 0.0f;
2297  view.m[0][2] = 0.0f;
2298  view.m[0][3] = 0.0f;
2299  view.m[1][0] = 0.0f;
2300  view.m[1][1] = -2.0f / renderer->viewport.h;
2301  view.m[1][2] = 0.0f;
2302  view.m[1][3] = 0.0f;
2303  view.m[2][0] = 0.0f;
2304  view.m[2][1] = 0.0f;
2305  view.m[2][2] = 1.0f;
2306  view.m[2][3] = 0.0f;
2307  view.m[3][0] = -1.0f;
2308  view.m[3][1] = 1.0f;
2309  view.m[3][2] = 0.0f;
2310  view.m[3][3] = 1.0f;
2311 
2312  /* Combine the projection + view matrix together now, as both only get
2313  * set here (as of this writing, on Dec 26, 2013). When done, store it
2314  * for eventual transfer to the GPU.
2315  */
2316  data->vertexShaderConstantsData.projectionAndView = MatrixMultiply(
2317  view,
2318  projection);
2319 
2320  /* Reset the model matrix */
2321  D3D11_SetModelMatrix(renderer, NULL);
2322 
2323  /* Update the Direct3D viewport, which seems to be aligned to the
2324  * swap buffer's coordinate space, which is always in either
2325  * a landscape mode, for all Windows 8/RT devices, or a portrait mode,
2326  * for Windows Phone devices.
2327  */
2328  swapDimensions = D3D11_IsDisplayRotated90Degrees(rotation);
2329  if (swapDimensions) {
2330  orientationAlignedViewport.x = (float) renderer->viewport.y;
2331  orientationAlignedViewport.y = (float) renderer->viewport.x;
2332  orientationAlignedViewport.w = (float) renderer->viewport.h;
2333  orientationAlignedViewport.h = (float) renderer->viewport.w;
2334  } else {
2335  orientationAlignedViewport.x = (float) renderer->viewport.x;
2336  orientationAlignedViewport.y = (float) renderer->viewport.y;
2337  orientationAlignedViewport.w = (float) renderer->viewport.w;
2338  orientationAlignedViewport.h = (float) renderer->viewport.h;
2339  }
2340  /* TODO, WinRT: get custom viewports working with non-Landscape modes (Portrait, PortraitFlipped, and LandscapeFlipped) */
2341 
2342  viewport.TopLeftX = orientationAlignedViewport.x;
2343  viewport.TopLeftY = orientationAlignedViewport.y;
2344  viewport.Width = orientationAlignedViewport.w;
2345  viewport.Height = orientationAlignedViewport.h;
2346  viewport.MinDepth = 0.0f;
2347  viewport.MaxDepth = 1.0f;
2348  /* SDL_Log("%s: D3D viewport = {%f,%f,%f,%f}\n", __FUNCTION__, viewport.TopLeftX, viewport.TopLeftY, viewport.Width, viewport.Height); */
2349  ID3D11DeviceContext_RSSetViewports(data->d3dContext, 1, &viewport);
2350 
2351  return 0;
2352 }
2353 
2354 static int
2355 D3D11_UpdateClipRect(SDL_Renderer * renderer)
2356 {
2357  D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
2358 
2359  if (!renderer->clipping_enabled) {
2360  ID3D11DeviceContext_RSSetScissorRects(data->d3dContext, 0, NULL);
2361  } else {
2362  D3D11_RECT scissorRect;
2363  if (D3D11_GetViewportAlignedD3DRect(renderer, &renderer->clip_rect, &scissorRect, TRUE) != 0) {
2364  /* D3D11_GetViewportAlignedD3DRect will have set the SDL error */
2365  return -1;
2366  }
2367  ID3D11DeviceContext_RSSetScissorRects(data->d3dContext, 1, &scissorRect);
2368  }
2369 
2370  return 0;
2371 }
2372 
2373 static void
2374 D3D11_ReleaseMainRenderTargetView(SDL_Renderer * renderer)
2375 {
2376  D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
2377  ID3D11DeviceContext_OMSetRenderTargets(data->d3dContext, 0, NULL, NULL);
2378  SAFE_RELEASE(data->mainRenderTargetView);
2379 }
2380 
2381 static ID3D11RenderTargetView *
2382 D3D11_GetCurrentRenderTargetView(SDL_Renderer * renderer)
2383 {
2384  D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
2385  if (data->currentOffscreenRenderTargetView) {
2386  return data->currentOffscreenRenderTargetView;
2387  } else {
2388  return data->mainRenderTargetView;
2389  }
2390 }
2391 
2392 static int
2393 D3D11_RenderClear(SDL_Renderer * renderer)
2394 {
2395  D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
2396  const float colorRGBA[] = {
2397  (renderer->r / 255.0f),
2398  (renderer->g / 255.0f),
2399  (renderer->b / 255.0f),
2400  (renderer->a / 255.0f)
2401  };
2402  ID3D11DeviceContext_ClearRenderTargetView(data->d3dContext,
2403  D3D11_GetCurrentRenderTargetView(renderer),
2404  colorRGBA
2405  );
2406  return 0;
2407 }
2408 
2409 static int
2410 D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
2411  const void * vertexData, size_t dataSizeInBytes)
2412 {
2413  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2414  D3D11_BUFFER_DESC vertexBufferDesc;
2415  HRESULT result = S_OK;
2416  D3D11_SUBRESOURCE_DATA vertexBufferData;
2417  const UINT stride = sizeof(VertexPositionColor);
2418  const UINT offset = 0;
2419 
2420  if (rendererData->vertexBuffer) {
2421  ID3D11Buffer_GetDesc(rendererData->vertexBuffer, &vertexBufferDesc);
2422  } else {
2423  SDL_zero(vertexBufferDesc);
2424  }
2425 
2426  if (rendererData->vertexBuffer && vertexBufferDesc.ByteWidth >= dataSizeInBytes) {
2427  D3D11_MAPPED_SUBRESOURCE mappedResource;
2428  result = ID3D11DeviceContext_Map(rendererData->d3dContext,
2429  (ID3D11Resource *)rendererData->vertexBuffer,
2430  0,
2431  D3D11_MAP_WRITE_DISCARD,
2432  0,
2433  &mappedResource
2434  );
2435  if (FAILED(result)) {
2436  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [vertex buffer]"), result);
2437  return -1;
2438  }
2439  SDL_memcpy(mappedResource.pData, vertexData, dataSizeInBytes);
2440  ID3D11DeviceContext_Unmap(rendererData->d3dContext, (ID3D11Resource *)rendererData->vertexBuffer, 0);
2441  } else {
2442  SAFE_RELEASE(rendererData->vertexBuffer);
2443 
2444  vertexBufferDesc.ByteWidth = (UINT) dataSizeInBytes;
2445  vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
2446  vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
2447  vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2448 
2449  SDL_zero(vertexBufferData);
2450  vertexBufferData.pSysMem = vertexData;
2451  vertexBufferData.SysMemPitch = 0;
2452  vertexBufferData.SysMemSlicePitch = 0;
2453 
2454  result = ID3D11Device_CreateBuffer(rendererData->d3dDevice,
2455  &vertexBufferDesc,
2456  &vertexBufferData,
2457  &rendererData->vertexBuffer
2458  );
2459  if (FAILED(result)) {
2460  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBuffer [vertex buffer]"), result);
2461  return -1;
2462  }
2463 
2464  ID3D11DeviceContext_IASetVertexBuffers(rendererData->d3dContext,
2465  0,
2466  1,
2467  &rendererData->vertexBuffer,
2468  &stride,
2469  &offset
2470  );
2471  }
2472 
2473  return 0;
2474 }
2475 
2476 static void
2477 D3D11_RenderStartDrawOp(SDL_Renderer * renderer)
2478 {
2479  D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata;
2480  ID3D11RasterizerState *rasterizerState;
2481  ID3D11RenderTargetView *renderTargetView = D3D11_GetCurrentRenderTargetView(renderer);
2482  if (renderTargetView != rendererData->currentRenderTargetView) {
2483  ID3D11DeviceContext_OMSetRenderTargets(rendererData->d3dContext,
2484  1,
2485  &renderTargetView,
2486  NULL
2487  );
2488  rendererData->currentRenderTargetView = renderTargetView;
2489  }
2490 
2491  if (!renderer->clipping_enabled) {
2492  rasterizerState = rendererData->mainRasterizer;
2493  } else {
2494  rasterizerState = rendererData->clippedRasterizer;
2495  }
2496  if (rasterizerState != rendererData->currentRasterizerState) {
2497  ID3D11DeviceContext_RSSetState(rendererData->d3dContext, rasterizerState);
2498  rendererData->currentRasterizerState = rasterizerState;
2499  }
2500 }
2501 
2502 static void
2503 D3D11_RenderSetBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
2504 {
2505  D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata;
2506  ID3D11BlendState *blendState = NULL;
2507  if (blendMode != SDL_BLENDMODE_NONE) {
2508  int i;
2509  for (i = 0; i < rendererData->blendModesCount; ++i) {
2510  if (blendMode == rendererData->blendModes[i].blendMode) {
2511  blendState = rendererData->blendModes[i].blendState;
2512  break;
2513  }
2514  }
2515  if (!blendState) {
2516  if (D3D11_CreateBlendState(renderer, blendMode)) {
2517  /* Successfully created the blend state, try again */
2518  D3D11_RenderSetBlendMode(renderer, blendMode);
2519  }
2520  return;
2521  }
2522  }
2523  if (blendState != rendererData->currentBlendState) {
2524  ID3D11DeviceContext_OMSetBlendState(rendererData->d3dContext, blendState, 0, 0xFFFFFFFF);
2525  rendererData->currentBlendState = blendState;
2526  }
2527 }
2528 
2529 static void
2530 D3D11_SetPixelShader(SDL_Renderer * renderer,
2531  ID3D11PixelShader * shader,
2532  int numShaderResources,
2533  ID3D11ShaderResourceView ** shaderResources,
2534  ID3D11SamplerState * sampler)
2535 {
2536  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2537  ID3D11ShaderResourceView *shaderResource;
2538  if (shader != rendererData->currentShader) {
2539  ID3D11DeviceContext_PSSetShader(rendererData->d3dContext, shader, NULL, 0);
2540  rendererData->currentShader = shader;
2541  }
2542  if (numShaderResources > 0) {
2543  shaderResource = shaderResources[0];
2544  } else {
2545  shaderResource = NULL;
2546  }
2547  if (shaderResource != rendererData->currentShaderResource) {
2548  ID3D11DeviceContext_PSSetShaderResources(rendererData->d3dContext, 0, numShaderResources, shaderResources);
2549  rendererData->currentShaderResource = shaderResource;
2550  }
2551  if (sampler != rendererData->currentSampler) {
2552  ID3D11DeviceContext_PSSetSamplers(rendererData->d3dContext, 0, 1, &sampler);
2553  rendererData->currentSampler = sampler;
2554  }
2555 }
2556 
2557 static void
2558 D3D11_RenderFinishDrawOp(SDL_Renderer * renderer,
2559  D3D11_PRIMITIVE_TOPOLOGY primitiveTopology,
2560  UINT vertexCount)
2561 {
2562  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2563 
2564  ID3D11DeviceContext_IASetPrimitiveTopology(rendererData->d3dContext, primitiveTopology);
2565  ID3D11DeviceContext_Draw(rendererData->d3dContext, vertexCount, 0);
2566 }
2567 
2568 static int
2569 D3D11_RenderDrawPoints(SDL_Renderer * renderer,
2570  const SDL_FPoint * points, int count)
2571 {
2572  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2573  float r, g, b, a;
2574  VertexPositionColor *vertices;
2575  int i;
2576 
2577  r = (float)(renderer->r / 255.0f);
2578  g = (float)(renderer->g / 255.0f);
2579  b = (float)(renderer->b / 255.0f);
2580  a = (float)(renderer->a / 255.0f);
2581 
2582  vertices = SDL_stack_alloc(VertexPositionColor, count);
2583  for (i = 0; i < count; ++i) {
2584  const VertexPositionColor v = { { points[i].x + 0.5f, points[i].y + 0.5f, 0.0f }, { 0.0f, 0.0f }, { r, g, b, a } };
2585  vertices[i] = v;
2586  }
2587 
2588  D3D11_RenderStartDrawOp(renderer);
2589  D3D11_RenderSetBlendMode(renderer, renderer->blendMode);
2590  if (D3D11_UpdateVertexBuffer(renderer, vertices, (unsigned int)count * sizeof(VertexPositionColor)) != 0) {
2591  SDL_stack_free(vertices);
2592  return -1;
2593  }
2594 
2595  D3D11_SetPixelShader(
2596  renderer,
2597  rendererData->colorPixelShader,
2598  0,
2599  NULL,
2600  NULL);
2601 
2602  D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, count);
2603  SDL_stack_free(vertices);
2604  return 0;
2605 }
2606 
2607 static int
2608 D3D11_RenderDrawLines(SDL_Renderer * renderer,
2609  const SDL_FPoint * points, int count)
2610 {
2611  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2612  float r, g, b, a;
2613  VertexPositionColor *vertices;
2614  int i;
2615 
2616  r = (float)(renderer->r / 255.0f);
2617  g = (float)(renderer->g / 255.0f);
2618  b = (float)(renderer->b / 255.0f);
2619  a = (float)(renderer->a / 255.0f);
2620 
2621  vertices = SDL_stack_alloc(VertexPositionColor, count);
2622  for (i = 0; i < count; ++i) {
2623  const VertexPositionColor v = { { points[i].x + 0.5f, points[i].y + 0.5f, 0.0f }, { 0.0f, 0.0f }, { r, g, b, a } };
2624  vertices[i] = v;
2625  }
2626 
2627  D3D11_RenderStartDrawOp(renderer);
2628  D3D11_RenderSetBlendMode(renderer, renderer->blendMode);
2629  if (D3D11_UpdateVertexBuffer(renderer, vertices, (unsigned int)count * sizeof(VertexPositionColor)) != 0) {
2630  SDL_stack_free(vertices);
2631  return -1;
2632  }
2633 
2634  D3D11_SetPixelShader(
2635  renderer,
2636  rendererData->colorPixelShader,
2637  0,
2638  NULL,
2639  NULL);
2640 
2641  D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, count);
2642 
2643  if (points[0].x != points[count - 1].x || points[0].y != points[count - 1].y) {
2644  ID3D11DeviceContext_IASetPrimitiveTopology(rendererData->d3dContext, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
2645  ID3D11DeviceContext_Draw(rendererData->d3dContext, 1, count - 1);
2646  }
2647 
2648  SDL_stack_free(vertices);
2649  return 0;
2650 }
2651 
2652 static int
2653 D3D11_RenderFillRects(SDL_Renderer * renderer,
2654  const SDL_FRect * rects, int count)
2655 {
2656  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2657  float r, g, b, a;
2658  int i;
2659 
2660  r = (float)(renderer->r / 255.0f);
2661  g = (float)(renderer->g / 255.0f);
2662  b = (float)(renderer->b / 255.0f);
2663  a = (float)(renderer->a / 255.0f);
2664 
2665  for (i = 0; i < count; ++i) {
2666  VertexPositionColor vertices[] = {
2667  { { rects[i].x, rects[i].y, 0.0f }, { 0.0f, 0.0f}, {r, g, b, a} },
2668  { { rects[i].x, rects[i].y + rects[i].h, 0.0f }, { 0.0f, 0.0f }, { r, g, b, a } },
2669  { { rects[i].x + rects[i].w, rects[i].y, 0.0f }, { 0.0f, 0.0f }, { r, g, b, a } },
2670  { { rects[i].x + rects[i].w, rects[i].y + rects[i].h, 0.0f }, { 0.0f, 0.0f }, { r, g, b, a } },
2671  };
2672 
2673  D3D11_RenderStartDrawOp(renderer);
2674  D3D11_RenderSetBlendMode(renderer, renderer->blendMode);
2675  if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) {
2676  return -1;
2677  }
2678 
2679  D3D11_SetPixelShader(
2680  renderer,
2681  rendererData->colorPixelShader,
2682  0,
2683  NULL,
2684  NULL);
2685 
2686  D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, SDL_arraysize(vertices));
2687  }
2688 
2689  return 0;
2690 }
2691 
2692 static ID3D11SamplerState *
2693 D3D11_RenderGetSampler(SDL_Renderer * renderer, SDL_Texture * texture)
2694 {
2695  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2696  D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
2697 
2698  switch (textureData->scaleMode) {
2699  case D3D11_FILTER_MIN_MAG_MIP_POINT:
2700  return rendererData->nearestPixelSampler;
2701  case D3D11_FILTER_MIN_MAG_MIP_LINEAR:
2702  return rendererData->linearSampler;
2703  default:
2704  return NULL;
2705  }
2706 }
2707 
2708 static int
2709 D3D11_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
2710  const SDL_Rect * srcrect, const SDL_FRect * dstrect)
2711 {
2712  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2713  D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
2714  float minu, maxu, minv, maxv;
2715  Float4 color;
2716  VertexPositionColor vertices[4];
2717  ID3D11SamplerState *textureSampler;
2718 
2719  D3D11_RenderStartDrawOp(renderer);
2720  D3D11_RenderSetBlendMode(renderer, texture->blendMode);
2721 
2722  minu = (float) srcrect->x / texture->w;
2723  maxu = (float) (srcrect->x + srcrect->w) / texture->w;
2724  minv = (float) srcrect->y / texture->h;
2725  maxv = (float) (srcrect->y + srcrect->h) / texture->h;
2726 
2727  color.x = 1.0f; /* red */
2728  color.y = 1.0f; /* green */
2729  color.z = 1.0f; /* blue */
2730  color.w = 1.0f; /* alpha */
2731  if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
2732  color.x = (float)(texture->r / 255.0f); /* red */
2733  color.y = (float)(texture->g / 255.0f); /* green */
2734  color.z = (float)(texture->b / 255.0f); /* blue */
2735  }
2736  if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) {
2737  color.w = (float)(texture->a / 255.0f); /* alpha */
2738  }
2739 
2740  vertices[0].pos.x = dstrect->x;
2741  vertices[0].pos.y = dstrect->y;
2742  vertices[0].pos.z = 0.0f;
2743  vertices[0].tex.x = minu;
2744  vertices[0].tex.y = minv;
2745  vertices[0].color = color;
2746 
2747  vertices[1].pos.x = dstrect->x;
2748  vertices[1].pos.y = dstrect->y + dstrect->h;
2749  vertices[1].pos.z = 0.0f;
2750  vertices[1].tex.x = minu;
2751  vertices[1].tex.y = maxv;
2752  vertices[1].color = color;
2753 
2754  vertices[2].pos.x = dstrect->x + dstrect->w;
2755  vertices[2].pos.y = dstrect->y;
2756  vertices[2].pos.z = 0.0f;
2757  vertices[2].tex.x = maxu;
2758  vertices[2].tex.y = minv;
2759  vertices[2].color = color;
2760 
2761  vertices[3].pos.x = dstrect->x + dstrect->w;
2762  vertices[3].pos.y = dstrect->y + dstrect->h;
2763  vertices[3].pos.z = 0.0f;
2764  vertices[3].tex.x = maxu;
2765  vertices[3].tex.y = maxv;
2766  vertices[3].color = color;
2767 
2768  if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) {
2769  return -1;
2770  }
2771 
2772  textureSampler = D3D11_RenderGetSampler(renderer, texture);
2773  if (textureData->yuv) {
2774  ID3D11ShaderResourceView *shaderResources[] = {
2775  textureData->mainTextureResourceView,
2776  textureData->mainTextureResourceViewU,
2777  textureData->mainTextureResourceViewV
2778  };
2779  D3D11_SetPixelShader(
2780  renderer,
2781  rendererData->yuvPixelShader,
2782  SDL_arraysize(shaderResources),
2783  shaderResources,
2784  textureSampler);
2785  } else {
2786  D3D11_SetPixelShader(
2787  renderer,
2788  rendererData->texturePixelShader,
2789  1,
2790  &textureData->mainTextureResourceView,
2791  textureSampler);
2792  }
2793 
2794  D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor));
2795 
2796  return 0;
2797 }
2798 
2799 static int
2800 D3D11_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
2801  const SDL_Rect * srcrect, const SDL_FRect * dstrect,
2802  const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip)
2803 {
2804  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2805  D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
2806  float minu, maxu, minv, maxv;
2807  Float4 color;
2808  Float4X4 modelMatrix;
2809  float minx, maxx, miny, maxy;
2810  VertexPositionColor vertices[4];
2811  ID3D11SamplerState *textureSampler;
2812 
2813  D3D11_RenderStartDrawOp(renderer);
2814  D3D11_RenderSetBlendMode(renderer, texture->blendMode);
2815 
2816  minu = (float) srcrect->x / texture->w;
2817  maxu = (float) (srcrect->x + srcrect->w) / texture->w;
2818  minv = (float) srcrect->y / texture->h;
2819  maxv = (float) (srcrect->y + srcrect->h) / texture->h;
2820 
2821  color.x = 1.0f; /* red */
2822  color.y = 1.0f; /* green */
2823  color.z = 1.0f; /* blue */
2824  color.w = 1.0f; /* alpha */
2825  if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
2826  color.x = (float)(texture->r / 255.0f); /* red */
2827  color.y = (float)(texture->g / 255.0f); /* green */
2828  color.z = (float)(texture->b / 255.0f); /* blue */
2829  }
2830  if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) {
2831  color.w = (float)(texture->a / 255.0f); /* alpha */
2832  }
2833 
2834  if (flip & SDL_FLIP_HORIZONTAL) {
2835  float tmp = maxu;
2836  maxu = minu;
2837  minu = tmp;
2838  }
2839  if (flip & SDL_FLIP_VERTICAL) {
2840  float tmp = maxv;
2841  maxv = minv;
2842  minv = tmp;
2843  }
2844 
2845  modelMatrix = MatrixMultiply(
2846  MatrixRotationZ((float)(M_PI * (float) angle / 180.0f)),
2847  MatrixTranslation(dstrect->x + center->x, dstrect->y + center->y, 0)
2848  );
2849  D3D11_SetModelMatrix(renderer, &modelMatrix);
2850 
2851  minx = -center->x;
2852  maxx = dstrect->w - center->x;
2853  miny = -center->y;
2854  maxy = dstrect->h - center->y;
2855 
2856  vertices[0].pos.x = minx;
2857  vertices[0].pos.y = miny;
2858  vertices[0].pos.z = 0.0f;
2859  vertices[0].tex.x = minu;
2860  vertices[0].tex.y = minv;
2861  vertices[0].color = color;
2862 
2863  vertices[1].pos.x = minx;
2864  vertices[1].pos.y = maxy;
2865  vertices[1].pos.z = 0.0f;
2866  vertices[1].tex.x = minu;
2867  vertices[1].tex.y = maxv;
2868  vertices[1].color = color;
2869 
2870  vertices[2].pos.x = maxx;
2871  vertices[2].pos.y = miny;
2872  vertices[2].pos.z = 0.0f;
2873  vertices[2].tex.x = maxu;
2874  vertices[2].tex.y = minv;
2875  vertices[2].color = color;
2876 
2877  vertices[3].pos.x = maxx;
2878  vertices[3].pos.y = maxy;
2879  vertices[3].pos.z = 0.0f;
2880  vertices[3].tex.x = maxu;
2881  vertices[3].tex.y = maxv;
2882  vertices[3].color = color;
2883 
2884  if (D3D11_UpdateVertexBuffer(renderer, vertices, sizeof(vertices)) != 0) {
2885  return -1;
2886  }
2887 
2888  textureSampler = D3D11_RenderGetSampler(renderer, texture);
2889  if (textureData->yuv) {
2890  ID3D11ShaderResourceView *shaderResources[] = {
2891  textureData->mainTextureResourceView,
2892  textureData->mainTextureResourceViewU,
2893  textureData->mainTextureResourceViewV
2894  };
2895  D3D11_SetPixelShader(
2896  renderer,
2897  rendererData->yuvPixelShader,
2898  SDL_arraysize(shaderResources),
2899  shaderResources,
2900  textureSampler);
2901  } else {
2902  D3D11_SetPixelShader(
2903  renderer,
2904  rendererData->texturePixelShader,
2905  1,
2906  &textureData->mainTextureResourceView,
2907  textureSampler);
2908  }
2909 
2910  D3D11_RenderFinishDrawOp(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, sizeof(vertices) / sizeof(VertexPositionColor));
2911 
2912  D3D11_SetModelMatrix(renderer, NULL);
2913 
2914  return 0;
2915 }
2916 
2917 static int
2918 D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
2919  Uint32 format, void * pixels, int pitch)
2920 {
2921  D3D11_RenderData * data = (D3D11_RenderData *) renderer->driverdata;
2922  ID3D11Texture2D *backBuffer = NULL;
2923  ID3D11Texture2D *stagingTexture = NULL;
2924  HRESULT result;
2925  int status = -1;
2926  D3D11_TEXTURE2D_DESC stagingTextureDesc;
2927  D3D11_RECT srcRect = {0, 0, 0, 0};
2928  D3D11_BOX srcBox;
2929  D3D11_MAPPED_SUBRESOURCE textureMemory;
2930 
2931  /* Retrieve a pointer to the back buffer: */
2932  result = IDXGISwapChain_GetBuffer(data->swapChain,
2933  0,
2934  &SDL_IID_ID3D11Texture2D,
2935  (void **)&backBuffer
2936  );
2937  if (FAILED(result)) {
2938  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain1::GetBuffer [get back buffer]"), result);
2939  goto done;
2940  }
2941 
2942  /* Create a staging texture to copy the screen's data to: */
2943  ID3D11Texture2D_GetDesc(backBuffer, &stagingTextureDesc);
2944  stagingTextureDesc.Width = rect->w;
2945  stagingTextureDesc.Height = rect->h;
2946  stagingTextureDesc.BindFlags = 0;
2947  stagingTextureDesc.MiscFlags = 0;
2948  stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
2949  stagingTextureDesc.Usage = D3D11_USAGE_STAGING;
2950  result = ID3D11Device_CreateTexture2D(data->d3dDevice,
2951  &stagingTextureDesc,
2952  NULL,
2953  &stagingTexture);
2954  if (FAILED(result)) {
2955  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result);
2956  goto done;
2957  }
2958 
2959  /* Copy the desired portion of the back buffer to the staging texture: */
2960  if (D3D11_GetViewportAlignedD3DRect(renderer, rect, &srcRect, FALSE) != 0) {
2961  /* D3D11_GetViewportAlignedD3DRect will have set the SDL error */
2962  goto done;
2963  }
2964 
2965  srcBox.left = srcRect.left;
2966  srcBox.right = srcRect.right;
2967  srcBox.top = srcRect.top;
2968  srcBox.bottom = srcRect.bottom;
2969  srcBox.front = 0;
2970  srcBox.back = 1;
2971  ID3D11DeviceContext_CopySubresourceRegion(data->d3dContext,
2972  (ID3D11Resource *)stagingTexture,
2973  0,
2974  0, 0, 0,
2975  (ID3D11Resource *)backBuffer,
2976  0,
2977  &srcBox);
2978 
2979  /* Map the staging texture's data to CPU-accessible memory: */
2980  result = ID3D11DeviceContext_Map(data->d3dContext,
2981  (ID3D11Resource *)stagingTexture,
2982  0,
2983  D3D11_MAP_READ,
2984  0,
2985  &textureMemory);
2986  if (FAILED(result)) {
2987  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result);
2988  goto done;
2989  }
2990 
2991  /* Copy the data into the desired buffer, converting pixels to the
2992  * desired format at the same time:
2993  */
2994  if (SDL_ConvertPixels(
2995  rect->w, rect->h,
2996  D3D11_DXGIFormatToSDLPixelFormat(stagingTextureDesc.Format),
2997  textureMemory.pData,
2998  textureMemory.RowPitch,
2999  format,
3000  pixels,
3001  pitch) != 0) {
3002  /* When SDL_ConvertPixels fails, it'll have already set the format.
3003  * Get the error message, and attach some extra data to it.
3004  */
3005  char errorMessage[1024];
3006  SDL_snprintf(errorMessage, sizeof(errorMessage), "%s, Convert Pixels failed: %s", __FUNCTION__, SDL_GetError());
3007  SDL_SetError("%s", errorMessage);
3008  goto done;
3009  }
3010 
3011  /* Unmap the texture: */
3012  ID3D11DeviceContext_Unmap(data->d3dContext,
3013  (ID3D11Resource *)stagingTexture,
3014  0);
3015 
3016  status = 0;
3017 
3018 done:
3019  SAFE_RELEASE(backBuffer);
3020  SAFE_RELEASE(stagingTexture);
3021  return status;
3022 }
3023 
3024 static void
3025 D3D11_RenderPresent(SDL_Renderer * renderer)
3026 {
3027  D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
3028  UINT syncInterval;
3029  UINT presentFlags;
3030  HRESULT result;
3031  DXGI_PRESENT_PARAMETERS parameters;
3032 
3033  SDL_zero(parameters);
3034 
3035 #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
3036  syncInterval = 1;
3037  presentFlags = 0;
3038  result = IDXGISwapChain_Present(data->swapChain, syncInterval, presentFlags);
3039 #else
3040  if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) {
3041  syncInterval = 1;
3042  presentFlags = 0;
3043  } else {
3044  syncInterval = 0;
3045  presentFlags = DXGI_PRESENT_DO_NOT_WAIT;
3046  }
3047 
3048  /* The application may optionally specify "dirty" or "scroll"
3049  * rects to improve efficiency in certain scenarios.
3050  * This option is not available on Windows Phone 8, to note.
3051  */
3052  result = IDXGISwapChain1_Present1(data->swapChain, syncInterval, presentFlags, &parameters);
3053 #endif
3054 
3055  /* Discard the contents of the render target.
3056  * This is a valid operation only when the existing contents will be entirely
3057  * overwritten. If dirty or scroll rects are used, this call should be removed.
3058  */
3059  ID3D11DeviceContext1_DiscardView(data->d3dContext, (ID3D11View*)data->mainRenderTargetView);
3060 
3061  /* When the present flips, it unbinds the current view, so bind it again on the next draw call */
3062  data->currentRenderTargetView = NULL;
3063 
3064  if (FAILED(result) && result != DXGI_ERROR_WAS_STILL_DRAWING) {
3065  /* If the device was removed either by a disconnect or a driver upgrade, we
3066  * must recreate all device resources.
3067  *
3068  * TODO, WinRT: consider throwing an exception if D3D11_RenderPresent fails, especially if there is a way to salvage debug info from users' machines
3069  */
3070  if ( result == DXGI_ERROR_DEVICE_REMOVED ) {
3071  D3D11_HandleDeviceLost(renderer);
3072  } else if (result == DXGI_ERROR_INVALID_CALL) {
3073  /* We probably went through a fullscreen <-> windowed transition */
3074  D3D11_CreateWindowSizeDependentResources(renderer);
3075  } else {
3076  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::Present"), result);
3077  }
3078  }
3079 }
3080 
3081 #endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */
3082 
3083 /* vi: set ts=4 sw=4 expandtab: */
SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:2143
SDL_BlendFactor
The normalized factor used to multiply pixel components.
Definition: SDL_blendmode.h:75
int(* RenderDrawLines)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
GLuint GLenum matrix
SDL_BlendMode blendMode
Definition: SDL_sysrender.h:57
GLsizei stride
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
int(* RenderDrawPoints)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_sysrender.h:98
#define SDL_GetError
GLuint64EXT * result
GLuint sampler
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
const GLdouble * v
Definition: SDL_opengl.h:2064
SDL_RendererInfo info
GLenum GLenum dst
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
Definition: SDL_blendmode.h:40
SDL_bool(* SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode)
Definition: SDL_sysrender.h:82
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1571
SDL_Rect rect
Definition: testrelative.c:27
#define SDL_HINT_RENDER_SCALE_QUALITY
A variable controlling the scaling quality.
Definition: SDL_hints.h:142
SDL_RenderDriver D3D11_RenderDriver
GLfloat GLfloat GLfloat GLfloat h
void * driverdata
int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr)
SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:2171
#define SDL_GetHint
SDL_version version
Definition: SDL_syswm.h:196
SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode)
Definition: SDL_render.c:2157
GLfloat f
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:128
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
int(* RenderFillRects)(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
GLintptr offset
SDL_Rect clip_rect
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:169
#define SDL_realloc
#define SDL_strcasecmp
GLenum src
#define SDL_LoadObject
SDL_Texture * textures
#define SDL_UnloadObject
int max_texture_height
Definition: SDL_render.h:85
SDL_BlendOperation
The blend operation used when combining source and destination pixel components.
Definition: SDL_blendmode.h:62
SDL_Window * window
SDL_RendererInfo info
int(* RenderClear)(SDL_Renderer *renderer)
#define SDL_HINT_RENDER_DIRECT3D11_DEBUG
A variable controlling whether to enable Direct3D 11+&#39;s Debug Layer.
Definition: SDL_hints.h:119
void(* DestroyRenderer)(SDL_Renderer *renderer)
GLfixed GLfixed GLint GLint GLfixed points
#define SDL_GetHintBoolean
#define SDL_VERSION(x)
Macro to determine SDL version program was compiled against.
Definition: SDL_version.h:79
static SDL_BlendMode blendMode
Definition: testdraw2.c:34
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_sysrender.h:90
int(* UpdateTextureYUV)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const Uint8 *Yplane, int Ypitch, const Uint8 *Uplane, int Upitch, const Uint8 *Vplane, int Vpitch)
Definition: SDL_sysrender.h:93
#define SDL_GetWindowSize
#define FAILED(x)
Definition: SDL_directx.h:54
SDL_Texture * next
Definition: SDL_sysrender.h:72
#define SDL_memcpy
GLenum GLenum GLuint texture
void * SDL_calloc(size_t nmemb, size_t size)
SDL_BlendOperation SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode)
Definition: SDL_render.c:2178
static int GetScaleQuality(void)
static SDL_Renderer * renderer
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:153
#define SDL_stack_alloc(type, count)
Definition: SDL_stdinc.h:338
struct _cl_event * event
SDL_BlendMode blendMode
void SDL_free(void *mem)
#define TRUE
Definition: edid-parse.c:33
int done
Definition: checkkeys.c:28
#define SDL_PushEvent
#define SDL_static_cast(type, expression)
Definition: SDL_stdinc.h:116
GLubyte GLubyte GLubyte GLubyte w
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
#define SDL_zero(x)
Definition: SDL_stdinc.h:369
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
int x
Definition: SDL_rect.h:66
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* UpdateViewport)(SDL_Renderer *renderer)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1572
#define S_OK
Definition: SDL_directx.h:47
int w
Definition: SDL_rect.h:67
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
Definition: SDL_render.h:111
ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
int(* RenderCopy)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
Window state change event data (event.window.*)
Definition: SDL_events.h:174
#define SDL_GetWindowWMInfo
Window window
Definition: SDL_syswm.h:218
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_bool
Definition: SDL_stdinc.h:139
SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:2164
#define SDL_SetError
GLbitfield flags
int(* RenderCopyEx)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
SDL_Rect viewport
int h
Definition: SDL_rect.h:67
The type used to identify a window.
Definition: SDL_sysvideo.h:73
SDL_Rect viewport
Definition: testviewport.c:28
SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:2150
GLuint color
#define E_FAIL
Definition: SDL_directx.h:58
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
Definition: SDL_sysrender.h:80
GLfloat angle
#define SDL_snprintf
Uint32 format
Definition: SDL_sysrender.h:52
union SDL_SysWMinfo::@18 info
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:93
void * driverdata
Definition: SDL_sysrender.h:69
General event structure.
Definition: SDL_events.h:525
#define SDL_malloc
#define SDL_ConvertPixels
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
void * SDL_LoadFunction(void *handle, const char *name)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:83
void(* RenderPresent)(SDL_Renderer *renderer)
EGLSurface EGLint * rects
Definition: eglext.h:282
#define SDL_stack_free(data)
Definition: SDL_stdinc.h:339
GLuint GLsizei GLsizei * length
#define FALSE
Definition: edid-parse.c:34
GLboolean GLboolean GLboolean GLboolean a
int(* UpdateClipRect)(SDL_Renderer *renderer)
GLboolean GLboolean g
GLboolean GLboolean GLboolean b
GLenum GLenum void * row
int y
Definition: SDL_rect.h:66
SDL_bool clipping_enabled
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:64
GLuint shader