SDL  2.0
SDL_render_d3d11.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 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 
33 #include <d3d11_1.h>
34 
35 #include "SDL_shaders_d3d11.h"
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 /* !!! FIXME: vertex buffer bandwidth could be significantly lower; move color to a uniform, only use UV coords
60  !!! FIXME: when textures are needed, and don't ever pass Z, since it's always zero. */
61 
62 /* Vertex shader, common values */
63 typedef struct
64 {
65  Float4X4 model;
66  Float4X4 projectionAndView;
67 } VertexShaderConstants;
68 
69 /* Per-vertex data */
70 typedef struct
71 {
72  Float3 pos;
73  Float2 tex;
74  Float4 color;
75 } VertexPositionColor;
76 
77 /* Per-texture data */
78 typedef struct
79 {
80  ID3D11Texture2D *mainTexture;
81  ID3D11ShaderResourceView *mainTextureResourceView;
82  ID3D11RenderTargetView *mainTextureRenderTargetView;
83  ID3D11Texture2D *stagingTexture;
84  int lockedTexturePositionX;
85  int lockedTexturePositionY;
86  D3D11_FILTER scaleMode;
87 
88  /* YV12 texture support */
89  SDL_bool yuv;
90  ID3D11Texture2D *mainTextureU;
91  ID3D11ShaderResourceView *mainTextureResourceViewU;
92  ID3D11Texture2D *mainTextureV;
93  ID3D11ShaderResourceView *mainTextureResourceViewV;
94 
95  /* NV12 texture support */
96  SDL_bool nv12;
97  ID3D11Texture2D *mainTextureNV;
98  ID3D11ShaderResourceView *mainTextureResourceViewNV;
99 
100  Uint8 *pixels;
101  int pitch;
102  SDL_Rect locked_rect;
103 } D3D11_TextureData;
104 
105 /* Blend mode data */
106 typedef struct
107 {
109  ID3D11BlendState *blendState;
110 } D3D11_BlendMode;
111 
112 /* Private renderer data */
113 typedef struct
114 {
115  void *hDXGIMod;
116  void *hD3D11Mod;
117  IDXGIFactory2 *dxgiFactory;
118  IDXGIAdapter *dxgiAdapter;
119  ID3D11Device1 *d3dDevice;
120  ID3D11DeviceContext1 *d3dContext;
121  IDXGISwapChain1 *swapChain;
122  DXGI_SWAP_EFFECT swapEffect;
123  ID3D11RenderTargetView *mainRenderTargetView;
124  ID3D11RenderTargetView *currentOffscreenRenderTargetView;
125  ID3D11InputLayout *inputLayout;
126  ID3D11Buffer *vertexBuffers[8];
127  size_t vertexBufferSizes[8];
128  ID3D11VertexShader *vertexShader;
129  ID3D11PixelShader *pixelShaders[NUM_SHADERS];
130  int blendModesCount;
131  D3D11_BlendMode *blendModes;
132  ID3D11SamplerState *nearestPixelSampler;
133  ID3D11SamplerState *linearSampler;
134  D3D_FEATURE_LEVEL featureLevel;
135 
136  /* Rasterizers */
137  ID3D11RasterizerState *mainRasterizer;
138  ID3D11RasterizerState *clippedRasterizer;
139 
140  /* Vertex buffer constants */
141  VertexShaderConstants vertexShaderConstantsData;
142  ID3D11Buffer *vertexShaderConstants;
143 
144  /* Cached renderer properties */
145  DXGI_MODE_ROTATION rotation;
146  ID3D11RenderTargetView *currentRenderTargetView;
147  ID3D11RasterizerState *currentRasterizerState;
148  ID3D11BlendState *currentBlendState;
149  ID3D11PixelShader *currentShader;
150  ID3D11ShaderResourceView *currentShaderResource;
151  ID3D11SamplerState *currentSampler;
152  SDL_bool cliprectDirty;
153  SDL_bool currentCliprectEnabled;
154  SDL_Rect currentCliprect;
155  SDL_Rect currentViewport;
156  int currentViewportRotation;
157  SDL_bool viewportDirty;
158  Float4X4 identity;
159  int currentVertexBuffer;
160 } D3D11_RenderData;
161 
162 
163 /* Define D3D GUIDs here so we don't have to include uuid.lib.
164 *
165 * Fix for SDL bug https://bugzilla.libsdl.org/show_bug.cgi?id=3437:
166 * The extra 'SDL_' was added to the start of each IID's name, in order
167 * to prevent build errors on both MinGW-w64 and WinRT/UWP.
168 * (SDL bug https://bugzilla.libsdl.org/show_bug.cgi?id=3336 led to
169 * linker errors in WinRT/UWP builds.)
170 */
171 
172 #ifdef __GNUC__
173 #pragma GCC diagnostic push
174 #pragma GCC diagnostic ignored "-Wunused-const-variable"
175 #endif
176 
177 static const GUID SDL_IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } };
178 static const GUID SDL_IID_IDXGIDevice1 = { 0x77db970f, 0x6276, 0x48ba, { 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c } };
179 static const GUID SDL_IID_IDXGIDevice3 = { 0x6007896c, 0x3244, 0x4afd, { 0xbf, 0x18, 0xa6, 0xd3, 0xbe, 0xda, 0x50, 0x23 } };
180 static const GUID SDL_IID_ID3D11Texture2D = { 0x6f15aaf2, 0xd208, 0x4e89, { 0x9a, 0xb4, 0x48, 0x95, 0x35, 0xd3, 0x4f, 0x9c } };
181 static const GUID SDL_IID_ID3D11Device1 = { 0xa04bfb29, 0x08ef, 0x43d6, { 0xa4, 0x9c, 0xa9, 0xbd, 0xbd, 0xcb, 0xe6, 0x86 } };
182 static const GUID SDL_IID_ID3D11DeviceContext1 = { 0xbb2c6faa, 0xb5fb, 0x4082, { 0x8e, 0x6b, 0x38, 0x8b, 0x8c, 0xfa, 0x90, 0xe1 } };
183 static const GUID SDL_IID_ID3D11Debug = { 0x79cf2233, 0x7536, 0x4948, { 0x9d, 0x36, 0x1e, 0x46, 0x92, 0xdc, 0x57, 0x60 } };
184 
185 #ifdef __GNUC__
186 #pragma GCC diagnostic pop
187 #endif
188 
189 
190 
191 Uint32
192 D3D11_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat)
193 {
194  switch (dxgiFormat) {
195  case DXGI_FORMAT_B8G8R8A8_UNORM:
197  case DXGI_FORMAT_B8G8R8X8_UNORM:
198  return SDL_PIXELFORMAT_RGB888;
199  default:
201  }
202 }
203 
204 static DXGI_FORMAT
205 SDLPixelFormatToDXGIFormat(Uint32 sdlFormat)
206 {
207  switch (sdlFormat) {
209  return DXGI_FORMAT_B8G8R8A8_UNORM;
211  return DXGI_FORMAT_B8G8R8X8_UNORM;
214  case SDL_PIXELFORMAT_NV12: /* For the Y texture */
215  case SDL_PIXELFORMAT_NV21: /* For the Y texture */
216  return DXGI_FORMAT_R8_UNORM;
217  default:
218  return DXGI_FORMAT_UNKNOWN;
219  }
220 }
221 
222 static void D3D11_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
223 
224 static void
225 D3D11_ReleaseAll(SDL_Renderer * renderer)
226 {
227  D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
229 
230  /* Release all textures */
232  D3D11_DestroyTexture(renderer, texture);
233  }
234 
235  /* Release/reset everything else */
236  if (data) {
237  int i;
238 
239  SAFE_RELEASE(data->dxgiFactory);
240  SAFE_RELEASE(data->dxgiAdapter);
241  SAFE_RELEASE(data->d3dDevice);
242  SAFE_RELEASE(data->d3dContext);
243  SAFE_RELEASE(data->swapChain);
244  SAFE_RELEASE(data->mainRenderTargetView);
245  SAFE_RELEASE(data->currentOffscreenRenderTargetView);
246  SAFE_RELEASE(data->inputLayout);
247  for (i = 0; i < SDL_arraysize(data->vertexBuffers); ++i) {
248  SAFE_RELEASE(data->vertexBuffers[i]);
249  }
250  SAFE_RELEASE(data->vertexShader);
251  for (i = 0; i < SDL_arraysize(data->pixelShaders); ++i) {
252  SAFE_RELEASE(data->pixelShaders[i]);
253  }
254  if (data->blendModesCount > 0) {
255  for (i = 0; i < data->blendModesCount; ++i) {
256  SAFE_RELEASE(data->blendModes[i].blendState);
257  }
258  SDL_free(data->blendModes);
259 
260  data->blendModesCount = 0;
261  }
262  SAFE_RELEASE(data->nearestPixelSampler);
263  SAFE_RELEASE(data->linearSampler);
264  SAFE_RELEASE(data->mainRasterizer);
265  SAFE_RELEASE(data->clippedRasterizer);
266  SAFE_RELEASE(data->vertexShaderConstants);
267 
268  data->swapEffect = (DXGI_SWAP_EFFECT) 0;
269  data->rotation = DXGI_MODE_ROTATION_UNSPECIFIED;
270  data->currentRenderTargetView = NULL;
271  data->currentRasterizerState = NULL;
272  data->currentBlendState = NULL;
273  data->currentShader = NULL;
274  data->currentShaderResource = NULL;
275  data->currentSampler = NULL;
276 
277  /* Unload the D3D libraries. This should be done last, in order
278  * to prevent IUnknown::Release() calls from crashing.
279  */
280  if (data->hD3D11Mod) {
281  SDL_UnloadObject(data->hD3D11Mod);
282  data->hD3D11Mod = NULL;
283  }
284  if (data->hDXGIMod) {
285  SDL_UnloadObject(data->hDXGIMod);
286  data->hDXGIMod = NULL;
287  }
288  }
289 }
290 
291 static void
292 D3D11_DestroyRenderer(SDL_Renderer * renderer)
293 {
294  D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
295  D3D11_ReleaseAll(renderer);
296  if (data) {
297  SDL_free(data);
298  }
300 }
301 
302 static D3D11_BLEND GetBlendFunc(SDL_BlendFactor factor)
303 {
304  switch (factor) {
306  return D3D11_BLEND_ZERO;
307  case SDL_BLENDFACTOR_ONE:
308  return D3D11_BLEND_ONE;
310  return D3D11_BLEND_SRC_COLOR;
312  return D3D11_BLEND_INV_SRC_COLOR;
314  return D3D11_BLEND_SRC_ALPHA;
316  return D3D11_BLEND_INV_SRC_ALPHA;
318  return D3D11_BLEND_DEST_COLOR;
320  return D3D11_BLEND_INV_DEST_COLOR;
322  return D3D11_BLEND_DEST_ALPHA;
324  return D3D11_BLEND_INV_DEST_ALPHA;
325  default:
326  return (D3D11_BLEND)0;
327  }
328 }
329 
330 static D3D11_BLEND_OP GetBlendEquation(SDL_BlendOperation operation)
331 {
332  switch (operation) {
334  return D3D11_BLEND_OP_ADD;
336  return D3D11_BLEND_OP_SUBTRACT;
338  return D3D11_BLEND_OP_REV_SUBTRACT;
340  return D3D11_BLEND_OP_MIN;
342  return D3D11_BLEND_OP_MAX;
343  default:
344  return (D3D11_BLEND_OP)0;
345  }
346 }
347 
348 static ID3D11BlendState *
349 D3D11_CreateBlendState(SDL_Renderer * renderer, SDL_BlendMode blendMode)
350 {
351  D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
358  ID3D11BlendState *blendState = NULL;
359  D3D11_BlendMode *blendModes;
360  HRESULT result = S_OK;
361 
362  D3D11_BLEND_DESC blendDesc;
363  SDL_zero(blendDesc);
364  blendDesc.AlphaToCoverageEnable = FALSE;
365  blendDesc.IndependentBlendEnable = FALSE;
366  blendDesc.RenderTarget[0].BlendEnable = TRUE;
367  blendDesc.RenderTarget[0].SrcBlend = GetBlendFunc(srcColorFactor);
368  blendDesc.RenderTarget[0].DestBlend = GetBlendFunc(dstColorFactor);
369  blendDesc.RenderTarget[0].BlendOp = GetBlendEquation(colorOperation);
370  blendDesc.RenderTarget[0].SrcBlendAlpha = GetBlendFunc(srcAlphaFactor);
371  blendDesc.RenderTarget[0].DestBlendAlpha = GetBlendFunc(dstAlphaFactor);
372  blendDesc.RenderTarget[0].BlendOpAlpha = GetBlendEquation(alphaOperation);
373  blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
374  result = ID3D11Device_CreateBlendState(data->d3dDevice, &blendDesc, &blendState);
375  if (FAILED(result)) {
376  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBlendState"), result);
377  return NULL;
378  }
379 
380  blendModes = (D3D11_BlendMode *)SDL_realloc(data->blendModes, (data->blendModesCount + 1) * sizeof(*blendModes));
381  if (!blendModes) {
382  SAFE_RELEASE(blendState);
383  SDL_OutOfMemory();
384  return NULL;
385  }
386  blendModes[data->blendModesCount].blendMode = blendMode;
387  blendModes[data->blendModesCount].blendState = blendState;
388  data->blendModes = blendModes;
389  ++data->blendModesCount;
390 
391  return blendState;
392 }
393 
394 /* Create resources that depend on the device. */
395 static HRESULT
396 D3D11_CreateDeviceResources(SDL_Renderer * renderer)
397 {
398  typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory);
399  PFN_CREATE_DXGI_FACTORY CreateDXGIFactoryFunc;
400  D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
401  PFN_D3D11_CREATE_DEVICE D3D11CreateDeviceFunc;
402  ID3D11Device *d3dDevice = NULL;
403  ID3D11DeviceContext *d3dContext = NULL;
404  IDXGIDevice1 *dxgiDevice = NULL;
405  HRESULT result = S_OK;
406  UINT creationFlags;
407  int i;
408 
409  /* This array defines the set of DirectX hardware feature levels this app will support.
410  * Note the ordering should be preserved.
411  * Don't forget to declare your application's minimum required feature level in its
412  * description. All applications are assumed to support 9.1 unless otherwise stated.
413  */
414  D3D_FEATURE_LEVEL featureLevels[] =
415  {
416  D3D_FEATURE_LEVEL_11_1,
417  D3D_FEATURE_LEVEL_11_0,
418  D3D_FEATURE_LEVEL_10_1,
419  D3D_FEATURE_LEVEL_10_0,
420  D3D_FEATURE_LEVEL_9_3,
421  D3D_FEATURE_LEVEL_9_2,
422  D3D_FEATURE_LEVEL_9_1
423  };
424 
425  D3D11_BUFFER_DESC constantBufferDesc;
426  D3D11_SAMPLER_DESC samplerDesc;
427  D3D11_RASTERIZER_DESC rasterDesc;
428 
429 #ifdef __WINRT__
430  CreateDXGIFactoryFunc = CreateDXGIFactory1;
431  D3D11CreateDeviceFunc = D3D11CreateDevice;
432 #else
433  data->hDXGIMod = SDL_LoadObject("dxgi.dll");
434  if (!data->hDXGIMod) {
435  result = E_FAIL;
436  goto done;
437  }
438 
439  CreateDXGIFactoryFunc = (PFN_CREATE_DXGI_FACTORY)SDL_LoadFunction(data->hDXGIMod, "CreateDXGIFactory");
440  if (!CreateDXGIFactoryFunc) {
441  result = E_FAIL;
442  goto done;
443  }
444 
445  data->hD3D11Mod = SDL_LoadObject("d3d11.dll");
446  if (!data->hD3D11Mod) {
447  result = E_FAIL;
448  goto done;
449  }
450 
451  D3D11CreateDeviceFunc = (PFN_D3D11_CREATE_DEVICE)SDL_LoadFunction(data->hD3D11Mod, "D3D11CreateDevice");
452  if (!D3D11CreateDeviceFunc) {
453  result = E_FAIL;
454  goto done;
455  }
456 #endif /* __WINRT__ */
457 
458  result = CreateDXGIFactoryFunc(&SDL_IID_IDXGIFactory2, (void **)&data->dxgiFactory);
459  if (FAILED(result)) {
460  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("CreateDXGIFactory"), result);
461  goto done;
462  }
463 
464  /* FIXME: Should we use the default adapter? */
465  result = IDXGIFactory2_EnumAdapters(data->dxgiFactory, 0, &data->dxgiAdapter);
466  if (FAILED(result)) {
467  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("D3D11CreateDevice"), result);
468  goto done;
469  }
470 
471  /* This flag adds support for surfaces with a different color channel ordering
472  * than the API default. It is required for compatibility with Direct2D.
473  */
474  creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
475 
476  /* Make sure Direct3D's debugging feature gets used, if the app requests it. */
478  creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
479  }
480 
481  /* Create the Direct3D 11 API device object and a corresponding context. */
482  result = D3D11CreateDeviceFunc(
483  data->dxgiAdapter,
484  D3D_DRIVER_TYPE_UNKNOWN,
485  NULL,
486  creationFlags, /* Set set debug and Direct2D compatibility flags. */
487  featureLevels, /* List of feature levels this app can support. */
488  SDL_arraysize(featureLevels),
489  D3D11_SDK_VERSION, /* Always set this to D3D11_SDK_VERSION for Windows Store apps. */
490  &d3dDevice, /* Returns the Direct3D device created. */
491  &data->featureLevel, /* Returns feature level of device created. */
492  &d3dContext /* Returns the device immediate context. */
493  );
494  if (FAILED(result)) {
495  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("D3D11CreateDevice"), result);
496  goto done;
497  }
498 
499  result = ID3D11Device_QueryInterface(d3dDevice, &SDL_IID_ID3D11Device1, (void **)&data->d3dDevice);
500  if (FAILED(result)) {
501  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device to ID3D11Device1"), result);
502  goto done;
503  }
504 
505  result = ID3D11DeviceContext_QueryInterface(d3dContext, &SDL_IID_ID3D11DeviceContext1, (void **)&data->d3dContext);
506  if (FAILED(result)) {
507  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext to ID3D11DeviceContext1"), result);
508  goto done;
509  }
510 
511  result = ID3D11Device_QueryInterface(d3dDevice, &SDL_IID_IDXGIDevice1, (void **)&dxgiDevice);
512  if (FAILED(result)) {
513  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device to IDXGIDevice1"), result);
514  goto done;
515  }
516 
517  /* Ensure that DXGI does not queue more than one frame at a time. This both reduces latency and
518  * ensures that the application will only render after each VSync, minimizing power consumption.
519  */
520  result = IDXGIDevice1_SetMaximumFrameLatency(dxgiDevice, 1);
521  if (FAILED(result)) {
522  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGIDevice1::SetMaximumFrameLatency"), result);
523  goto done;
524  }
525 
526  /* Make note of the maximum texture size
527  * Max texture sizes are documented on MSDN, at:
528  * http://msdn.microsoft.com/en-us/library/windows/apps/ff476876.aspx
529  */
530  switch (data->featureLevel) {
531  case D3D_FEATURE_LEVEL_11_1:
532  case D3D_FEATURE_LEVEL_11_0:
534  break;
535 
536  case D3D_FEATURE_LEVEL_10_1:
537  case D3D_FEATURE_LEVEL_10_0:
539  break;
540 
541  case D3D_FEATURE_LEVEL_9_3:
543  break;
544 
545  case D3D_FEATURE_LEVEL_9_2:
546  case D3D_FEATURE_LEVEL_9_1:
548  break;
549 
550  default:
551  SDL_SetError("%s, Unexpected feature level: %d", __FUNCTION__, data->featureLevel);
552  result = E_FAIL;
553  goto done;
554  }
555 
556  if (D3D11_CreateVertexShader(data->d3dDevice, &data->vertexShader, &data->inputLayout) < 0) {
557  goto done;
558  }
559 
560  for (i = 0; i < SDL_arraysize(data->pixelShaders); ++i) {
561  if (D3D11_CreatePixelShader(data->d3dDevice, (D3D11_Shader)i, &data->pixelShaders[i]) < 0) {
562  goto done;
563  }
564  }
565 
566  /* Setup space to hold vertex shader constants: */
567  SDL_zero(constantBufferDesc);
568  constantBufferDesc.ByteWidth = sizeof(VertexShaderConstants);
569  constantBufferDesc.Usage = D3D11_USAGE_DEFAULT;
570  constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
571  result = ID3D11Device_CreateBuffer(data->d3dDevice,
572  &constantBufferDesc,
573  NULL,
574  &data->vertexShaderConstants
575  );
576  if (FAILED(result)) {
577  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBuffer [vertex shader constants]"), result);
578  goto done;
579  }
580 
581  /* Create samplers to use when drawing textures: */
582  SDL_zero(samplerDesc);
583  samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
584  samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
585  samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
586  samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
587  samplerDesc.MipLODBias = 0.0f;
588  samplerDesc.MaxAnisotropy = 1;
589  samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
590  samplerDesc.MinLOD = 0.0f;
591  samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
592  result = ID3D11Device_CreateSamplerState(data->d3dDevice,
593  &samplerDesc,
594  &data->nearestPixelSampler
595  );
596  if (FAILED(result)) {
597  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateSamplerState [nearest-pixel filter]"), result);
598  goto done;
599  }
600 
601  samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
602  result = ID3D11Device_CreateSamplerState(data->d3dDevice,
603  &samplerDesc,
604  &data->linearSampler
605  );
606  if (FAILED(result)) {
607  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateSamplerState [linear filter]"), result);
608  goto done;
609  }
610 
611  /* Setup Direct3D rasterizer states */
612  SDL_zero(rasterDesc);
613  rasterDesc.AntialiasedLineEnable = FALSE;
614  rasterDesc.CullMode = D3D11_CULL_NONE;
615  rasterDesc.DepthBias = 0;
616  rasterDesc.DepthBiasClamp = 0.0f;
617  rasterDesc.DepthClipEnable = TRUE;
618  rasterDesc.FillMode = D3D11_FILL_SOLID;
619  rasterDesc.FrontCounterClockwise = FALSE;
620  rasterDesc.MultisampleEnable = FALSE;
621  rasterDesc.ScissorEnable = FALSE;
622  rasterDesc.SlopeScaledDepthBias = 0.0f;
623  result = ID3D11Device_CreateRasterizerState(data->d3dDevice, &rasterDesc, &data->mainRasterizer);
624  if (FAILED(result)) {
625  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateRasterizerState [main rasterizer]"), result);
626  goto done;
627  }
628 
629  rasterDesc.ScissorEnable = TRUE;
630  result = ID3D11Device_CreateRasterizerState(data->d3dDevice, &rasterDesc, &data->clippedRasterizer);
631  if (FAILED(result)) {
632  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateRasterizerState [clipped rasterizer]"), result);
633  goto done;
634  }
635 
636  /* Create blending states: */
637  if (!D3D11_CreateBlendState(renderer, SDL_BLENDMODE_BLEND) ||
638  !D3D11_CreateBlendState(renderer, SDL_BLENDMODE_ADD) ||
639  !D3D11_CreateBlendState(renderer, SDL_BLENDMODE_MOD) ||
640  !D3D11_CreateBlendState(renderer, SDL_BLENDMODE_MUL)) {
641  /* D3D11_CreateBlendMode will set the SDL error, if it fails */
642  goto done;
643  }
644 
645  /* Setup render state that doesn't change */
646  ID3D11DeviceContext_IASetInputLayout(data->d3dContext, data->inputLayout);
647  ID3D11DeviceContext_VSSetShader(data->d3dContext, data->vertexShader, NULL, 0);
648  ID3D11DeviceContext_VSSetConstantBuffers(data->d3dContext, 0, 1, &data->vertexShaderConstants);
649 
650 done:
651  SAFE_RELEASE(d3dDevice);
652  SAFE_RELEASE(d3dContext);
653  SAFE_RELEASE(dxgiDevice);
654  return result;
655 }
656 
657 #ifdef __WIN32__
658 
659 static DXGI_MODE_ROTATION
660 D3D11_GetCurrentRotation()
661 {
662  /* FIXME */
663  return DXGI_MODE_ROTATION_IDENTITY;
664 }
665 
666 #endif /* __WIN32__ */
667 
668 static BOOL
669 D3D11_IsDisplayRotated90Degrees(DXGI_MODE_ROTATION rotation)
670 {
671  switch (rotation) {
672  case DXGI_MODE_ROTATION_ROTATE90:
673  case DXGI_MODE_ROTATION_ROTATE270:
674  return TRUE;
675  default:
676  return FALSE;
677  }
678 }
679 
680 static int
681 D3D11_GetRotationForCurrentRenderTarget(SDL_Renderer * renderer)
682 {
683  D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
684  if (data->currentOffscreenRenderTargetView) {
685  return DXGI_MODE_ROTATION_IDENTITY;
686  } else {
687  return data->rotation;
688  }
689 }
690 
691 static int
692 D3D11_GetViewportAlignedD3DRect(SDL_Renderer * renderer, const SDL_Rect * sdlRect, D3D11_RECT * outRect, BOOL includeViewportOffset)
693 {
694  const int rotation = D3D11_GetRotationForCurrentRenderTarget(renderer);
695  switch (rotation) {
696  case DXGI_MODE_ROTATION_IDENTITY:
697  outRect->left = sdlRect->x;
698  outRect->right = sdlRect->x + sdlRect->w;
699  outRect->top = sdlRect->y;
700  outRect->bottom = sdlRect->y + sdlRect->h;
701  if (includeViewportOffset) {
702  outRect->left += renderer->viewport.x;
703  outRect->right += renderer->viewport.x;
704  outRect->top += renderer->viewport.y;
705  outRect->bottom += renderer->viewport.y;
706  }
707  break;
708  case DXGI_MODE_ROTATION_ROTATE270:
709  outRect->left = sdlRect->y;
710  outRect->right = sdlRect->y + sdlRect->h;
711  outRect->top = renderer->viewport.w - sdlRect->x - sdlRect->w;
712  outRect->bottom = renderer->viewport.w - sdlRect->x;
713  break;
714  case DXGI_MODE_ROTATION_ROTATE180:
715  outRect->left = renderer->viewport.w - sdlRect->x - sdlRect->w;
716  outRect->right = renderer->viewport.w - sdlRect->x;
717  outRect->top = renderer->viewport.h - sdlRect->y - sdlRect->h;
718  outRect->bottom = renderer->viewport.h - sdlRect->y;
719  break;
720  case DXGI_MODE_ROTATION_ROTATE90:
721  outRect->left = renderer->viewport.h - sdlRect->y - sdlRect->h;
722  outRect->right = renderer->viewport.h - sdlRect->y;
723  outRect->top = sdlRect->x;
724  outRect->bottom = sdlRect->x + sdlRect->h;
725  break;
726  default:
727  return SDL_SetError("The physical display is in an unknown or unsupported rotation");
728  }
729  return 0;
730 }
731 
732 static HRESULT
733 D3D11_CreateSwapChain(SDL_Renderer * renderer, int w, int h)
734 {
735  D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
736 #ifdef __WINRT__
737  IUnknown *coreWindow = D3D11_GetCoreWindowFromSDLRenderer(renderer);
738  const BOOL usingXAML = (coreWindow == NULL);
739 #else
740  IUnknown *coreWindow = NULL;
741  const BOOL usingXAML = FALSE;
742 #endif
743  HRESULT result = S_OK;
744 
745  /* Create a swap chain using the same adapter as the existing Direct3D device. */
746  DXGI_SWAP_CHAIN_DESC1 swapChainDesc;
747  SDL_zero(swapChainDesc);
748  swapChainDesc.Width = w;
749  swapChainDesc.Height = h;
750  swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; /* This is the most common swap chain format. */
751  swapChainDesc.Stereo = FALSE;
752  swapChainDesc.SampleDesc.Count = 1; /* Don't use multi-sampling. */
753  swapChainDesc.SampleDesc.Quality = 0;
754  swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
755  swapChainDesc.BufferCount = 2; /* Use double-buffering to minimize latency. */
756 #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
757  swapChainDesc.Scaling = DXGI_SCALING_STRETCH; /* On phone, only stretch and aspect-ratio stretch scaling are allowed. */
758  swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; /* On phone, no swap effects are supported. */
759  /* 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 */
760 #else
761  if (usingXAML) {
762  swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
763  } else {
764  swapChainDesc.Scaling = DXGI_SCALING_NONE;
765  }
766  swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; /* All Windows Store apps must use this SwapEffect. */
767 #endif
768  swapChainDesc.Flags = 0;
769 
770  if (coreWindow) {
771  result = IDXGIFactory2_CreateSwapChainForCoreWindow(data->dxgiFactory,
772  (IUnknown *)data->d3dDevice,
773  coreWindow,
774  &swapChainDesc,
775  NULL, /* Allow on all displays. */
776  &data->swapChain
777  );
778  if (FAILED(result)) {
779  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGIFactory2::CreateSwapChainForCoreWindow"), result);
780  goto done;
781  }
782  } else if (usingXAML) {
783  result = IDXGIFactory2_CreateSwapChainForComposition(data->dxgiFactory,
784  (IUnknown *)data->d3dDevice,
785  &swapChainDesc,
786  NULL,
787  &data->swapChain);
788  if (FAILED(result)) {
789  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGIFactory2::CreateSwapChainForComposition"), result);
790  goto done;
791  }
792 
793 #if WINAPI_FAMILY == WINAPI_FAMILY_APP
794  result = ISwapChainBackgroundPanelNative_SetSwapChain(WINRT_GlobalSwapChainBackgroundPanelNative, (IDXGISwapChain *) data->swapChain);
795  if (FAILED(result)) {
796  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ISwapChainBackgroundPanelNative::SetSwapChain"), result);
797  goto done;
798  }
799 #else
800  SDL_SetError(SDL_COMPOSE_ERROR("XAML support is not yet available for Windows Phone"));
801  result = E_FAIL;
802  goto done;
803 #endif
804  } else {
805 #ifdef __WIN32__
806  SDL_SysWMinfo windowinfo;
807  SDL_VERSION(&windowinfo.version);
808  SDL_GetWindowWMInfo(renderer->window, &windowinfo);
809 
810  result = IDXGIFactory2_CreateSwapChainForHwnd(data->dxgiFactory,
811  (IUnknown *)data->d3dDevice,
812  windowinfo.info.win.window,
813  &swapChainDesc,
814  NULL,
815  NULL, /* Allow on all displays. */
816  &data->swapChain
817  );
818  if (FAILED(result)) {
819  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGIFactory2::CreateSwapChainForHwnd"), result);
820  goto done;
821  }
822 
823  IDXGIFactory_MakeWindowAssociation(data->dxgiFactory, windowinfo.info.win.window, DXGI_MWA_NO_WINDOW_CHANGES);
824 #else
825  SDL_SetError(__FUNCTION__", Unable to find something to attach a swap chain to");
826  goto done;
827 #endif /* ifdef __WIN32__ / else */
828  }
829  data->swapEffect = swapChainDesc.SwapEffect;
830 
831 done:
832  SAFE_RELEASE(coreWindow);
833  return result;
834 }
835 
836 static void
837 D3D11_ReleaseMainRenderTargetView(SDL_Renderer * renderer)
838 {
839  D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
840  ID3D11DeviceContext_OMSetRenderTargets(data->d3dContext, 0, NULL, NULL);
841  SAFE_RELEASE(data->mainRenderTargetView);
842 }
843 
844 static HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer);
845 
846 
847 HRESULT
848 D3D11_HandleDeviceLost(SDL_Renderer * renderer)
849 {
850  HRESULT result = S_OK;
851 
852  D3D11_ReleaseAll(renderer);
853 
854  result = D3D11_CreateDeviceResources(renderer);
855  if (FAILED(result)) {
856  /* D3D11_CreateDeviceResources will set the SDL error */
857  return result;
858  }
859 
860  result = D3D11_UpdateForWindowSizeChange(renderer);
861  if (FAILED(result)) {
862  /* D3D11_UpdateForWindowSizeChange will set the SDL error */
863  return result;
864  }
865 
866  /* Let the application know that the device has been reset */
867  {
869  event.type = SDL_RENDER_DEVICE_RESET;
871  }
872 
873  return S_OK;
874 }
875 
876 /* Initialize all resources that change when the window's size changes. */
877 static HRESULT
878 D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
879 {
880  D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
881  ID3D11Texture2D *backBuffer = NULL;
882  HRESULT result = S_OK;
883  int w, h;
884 
885  /* Release the previous render target view */
886  D3D11_ReleaseMainRenderTargetView(renderer);
887 
888  /* The width and height of the swap chain must be based on the display's
889  * non-rotated size.
890  */
892  data->rotation = D3D11_GetCurrentRotation();
893  /* SDL_Log("%s: windowSize={%d,%d}, orientation=%d\n", __FUNCTION__, w, h, (int)data->rotation); */
894  if (D3D11_IsDisplayRotated90Degrees(data->rotation)) {
895  int tmp = w;
896  w = h;
897  h = tmp;
898  }
899 
900  if (data->swapChain) {
901  /* IDXGISwapChain::ResizeBuffers is not available on Windows Phone 8. */
902 #if !defined(__WINRT__) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
903  /* If the swap chain already exists, resize it. */
904  result = IDXGISwapChain_ResizeBuffers(data->swapChain,
905  0,
906  w, h,
907  DXGI_FORMAT_UNKNOWN,
908  0
909  );
910  if (result == DXGI_ERROR_DEVICE_REMOVED) {
911  /* If the device was removed for any reason, a new device and swap chain will need to be created. */
912  D3D11_HandleDeviceLost(renderer);
913 
914  /* Everything is set up now. Do not continue execution of this method. HandleDeviceLost will reenter this method
915  * and correctly set up the new device.
916  */
917  goto done;
918  } else if (FAILED(result)) {
919  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::ResizeBuffers"), result);
920  goto done;
921  }
922 #endif
923  } else {
924  result = D3D11_CreateSwapChain(renderer, w, h);
925  if (FAILED(result)) {
926  goto done;
927  }
928  }
929 
930 #if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
931  /* Set the proper rotation for the swap chain.
932  *
933  * To note, the call for this, IDXGISwapChain1::SetRotation, is not necessary
934  * on Windows Phone 8.0, nor is it supported there.
935  *
936  * IDXGISwapChain1::SetRotation does seem to be available on Windows Phone 8.1,
937  * however I've yet to find a way to make it work. It might have something to
938  * do with IDXGISwapChain::ResizeBuffers appearing to not being available on
939  * Windows Phone 8.1 (it wasn't on Windows Phone 8.0), but I'm not 100% sure of this.
940  * The call doesn't appear to be entirely necessary though, and is a performance-related
941  * call, at least according to the following page on MSDN:
942  * http://code.msdn.microsoft.com/windowsapps/DXGI-swap-chain-rotation-21d13d71
943  * -- David L.
944  *
945  * TODO, WinRT: reexamine the docs for IDXGISwapChain1::SetRotation, see if might be available, usable, and prudent-to-call on WinPhone 8.1
946  */
947  if (data->swapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL) {
948  result = IDXGISwapChain1_SetRotation(data->swapChain, data->rotation);
949  if (FAILED(result)) {
950  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain1::SetRotation"), result);
951  goto done;
952  }
953  }
954 #endif
955 
956  result = IDXGISwapChain_GetBuffer(data->swapChain,
957  0,
958  &SDL_IID_ID3D11Texture2D,
959  (void **)&backBuffer
960  );
961  if (FAILED(result)) {
962  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::GetBuffer [back-buffer]"), result);
963  goto done;
964  }
965 
966  /* Create a render target view of the swap chain back buffer. */
967  result = ID3D11Device_CreateRenderTargetView(data->d3dDevice,
968  (ID3D11Resource *)backBuffer,
969  NULL,
970  &data->mainRenderTargetView
971  );
972  if (FAILED(result)) {
973  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device::CreateRenderTargetView"), result);
974  goto done;
975  }
976 
977  data->viewportDirty = SDL_TRUE;
978 
979 done:
980  SAFE_RELEASE(backBuffer);
981  return result;
982 }
983 
984 /* This method is called when the window's size changes. */
985 static HRESULT
986 D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer)
987 {
988  return D3D11_CreateWindowSizeDependentResources(renderer);
989 }
990 
991 void
992 D3D11_Trim(SDL_Renderer * renderer)
993 {
994 #ifdef __WINRT__
995 #if NTDDI_VERSION > NTDDI_WIN8
996  D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
997  HRESULT result = S_OK;
998  IDXGIDevice3 *dxgiDevice = NULL;
999 
1000  result = ID3D11Device_QueryInterface(data->d3dDevice, &SDL_IID_IDXGIDevice3, &dxgiDevice);
1001  if (FAILED(result)) {
1002  //WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to IDXGIDevice3", result);
1003  return;
1004  }
1005 
1006  IDXGIDevice3_Trim(dxgiDevice);
1007  SAFE_RELEASE(dxgiDevice);
1008 #endif
1009 #endif
1010 }
1011 
1012 static void
1013 D3D11_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
1014 {
1015  if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
1016  D3D11_UpdateForWindowSizeChange(renderer);
1017  }
1018 }
1019 
1020 static SDL_bool
1021 D3D11_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
1022 {
1029 
1030  if (!GetBlendFunc(srcColorFactor) || !GetBlendFunc(srcAlphaFactor) ||
1031  !GetBlendEquation(colorOperation) ||
1032  !GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor) ||
1033  !GetBlendEquation(alphaOperation)) {
1034  return SDL_FALSE;
1035  }
1036  return SDL_TRUE;
1037 }
1038 
1039 static int
1040 D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
1041 {
1042  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
1043  D3D11_TextureData *textureData;
1044  HRESULT result;
1045  DXGI_FORMAT textureFormat = SDLPixelFormatToDXGIFormat(texture->format);
1046  D3D11_TEXTURE2D_DESC textureDesc;
1047  D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc;
1048 
1049  if (textureFormat == DXGI_FORMAT_UNKNOWN) {
1050  return SDL_SetError("%s, An unsupported SDL pixel format (0x%x) was specified",
1051  __FUNCTION__, texture->format);
1052  }
1053 
1054  textureData = (D3D11_TextureData*) SDL_calloc(1, sizeof(*textureData));
1055  if (!textureData) {
1056  SDL_OutOfMemory();
1057  return -1;
1058  }
1059  textureData->scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? D3D11_FILTER_MIN_MAG_MIP_POINT : D3D11_FILTER_MIN_MAG_MIP_LINEAR;
1060 
1061  texture->driverdata = textureData;
1062 
1063  SDL_zero(textureDesc);
1064  textureDesc.Width = texture->w;
1065  textureDesc.Height = texture->h;
1066  textureDesc.MipLevels = 1;
1067  textureDesc.ArraySize = 1;
1068  textureDesc.Format = textureFormat;
1069  textureDesc.SampleDesc.Count = 1;
1070  textureDesc.SampleDesc.Quality = 0;
1071  textureDesc.MiscFlags = 0;
1072 
1073  if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
1074  textureDesc.Usage = D3D11_USAGE_DYNAMIC;
1075  textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
1076  } else {
1077  textureDesc.Usage = D3D11_USAGE_DEFAULT;
1078  textureDesc.CPUAccessFlags = 0;
1079  }
1080 
1081  if (texture->access == SDL_TEXTUREACCESS_TARGET) {
1082  textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
1083  } else {
1084  textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
1085  }
1086 
1087  result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
1088  &textureDesc,
1089  NULL,
1090  &textureData->mainTexture
1091  );
1092  if (FAILED(result)) {
1093  D3D11_DestroyTexture(renderer, texture);
1094  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
1095  return -1;
1096  }
1097 
1098  if (texture->format == SDL_PIXELFORMAT_YV12 ||
1099  texture->format == SDL_PIXELFORMAT_IYUV) {
1100  textureData->yuv = SDL_TRUE;
1101 
1102  textureDesc.Width = (textureDesc.Width + 1) / 2;
1103  textureDesc.Height = (textureDesc.Height + 1) / 2;
1104 
1105  result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
1106  &textureDesc,
1107  NULL,
1108  &textureData->mainTextureU
1109  );
1110  if (FAILED(result)) {
1111  D3D11_DestroyTexture(renderer, texture);
1112  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
1113  return -1;
1114  }
1115 
1116  result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
1117  &textureDesc,
1118  NULL,
1119  &textureData->mainTextureV
1120  );
1121  if (FAILED(result)) {
1122  D3D11_DestroyTexture(renderer, texture);
1123  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
1124  return -1;
1125  }
1126  }
1127 
1128  if (texture->format == SDL_PIXELFORMAT_NV12 ||
1129  texture->format == SDL_PIXELFORMAT_NV21) {
1130  D3D11_TEXTURE2D_DESC nvTextureDesc = textureDesc;
1131 
1132  textureData->nv12 = SDL_TRUE;
1133 
1134  nvTextureDesc.Format = DXGI_FORMAT_R8G8_UNORM;
1135  nvTextureDesc.Width = (textureDesc.Width + 1) / 2;
1136  nvTextureDesc.Height = (textureDesc.Height + 1) / 2;
1137 
1138  result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
1139  &nvTextureDesc,
1140  NULL,
1141  &textureData->mainTextureNV
1142  );
1143  if (FAILED(result)) {
1144  D3D11_DestroyTexture(renderer, texture);
1145  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
1146  return -1;
1147  }
1148  }
1149 
1150  resourceViewDesc.Format = textureDesc.Format;
1151  resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
1152  resourceViewDesc.Texture2D.MostDetailedMip = 0;
1153  resourceViewDesc.Texture2D.MipLevels = textureDesc.MipLevels;
1154  result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice,
1155  (ID3D11Resource *)textureData->mainTexture,
1156  &resourceViewDesc,
1157  &textureData->mainTextureResourceView
1158  );
1159  if (FAILED(result)) {
1160  D3D11_DestroyTexture(renderer, texture);
1161  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
1162  return -1;
1163  }
1164 
1165  if (textureData->yuv) {
1166  result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice,
1167  (ID3D11Resource *)textureData->mainTextureU,
1168  &resourceViewDesc,
1169  &textureData->mainTextureResourceViewU
1170  );
1171  if (FAILED(result)) {
1172  D3D11_DestroyTexture(renderer, texture);
1173  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
1174  return -1;
1175  }
1176  result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice,
1177  (ID3D11Resource *)textureData->mainTextureV,
1178  &resourceViewDesc,
1179  &textureData->mainTextureResourceViewV
1180  );
1181  if (FAILED(result)) {
1182  D3D11_DestroyTexture(renderer, texture);
1183  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
1184  return -1;
1185  }
1186  }
1187 
1188  if (textureData->nv12) {
1189  D3D11_SHADER_RESOURCE_VIEW_DESC nvResourceViewDesc = resourceViewDesc;
1190 
1191  nvResourceViewDesc.Format = DXGI_FORMAT_R8G8_UNORM;
1192 
1193  result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice,
1194  (ID3D11Resource *)textureData->mainTextureNV,
1195  &nvResourceViewDesc,
1196  &textureData->mainTextureResourceViewNV
1197  );
1198  if (FAILED(result)) {
1199  D3D11_DestroyTexture(renderer, texture);
1200  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
1201  return -1;
1202  }
1203  }
1204 
1205  if (texture->access & SDL_TEXTUREACCESS_TARGET) {
1206  D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
1207  renderTargetViewDesc.Format = textureDesc.Format;
1208  renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
1209  renderTargetViewDesc.Texture2D.MipSlice = 0;
1210 
1211  result = ID3D11Device_CreateRenderTargetView(rendererData->d3dDevice,
1212  (ID3D11Resource *)textureData->mainTexture,
1213  &renderTargetViewDesc,
1214  &textureData->mainTextureRenderTargetView);
1215  if (FAILED(result)) {
1216  D3D11_DestroyTexture(renderer, texture);
1217  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateRenderTargetView"), result);
1218  return -1;
1219  }
1220  }
1221 
1222  return 0;
1223 }
1224 
1225 static void
1226 D3D11_DestroyTexture(SDL_Renderer * renderer,
1227  SDL_Texture * texture)
1228 {
1229  D3D11_TextureData *data = (D3D11_TextureData *)texture->driverdata;
1230 
1231  if (!data) {
1232  return;
1233  }
1234 
1235  SAFE_RELEASE(data->mainTexture);
1236  SAFE_RELEASE(data->mainTextureResourceView);
1237  SAFE_RELEASE(data->mainTextureRenderTargetView);
1238  SAFE_RELEASE(data->stagingTexture);
1239  SAFE_RELEASE(data->mainTextureU);
1240  SAFE_RELEASE(data->mainTextureResourceViewU);
1241  SAFE_RELEASE(data->mainTextureV);
1242  SAFE_RELEASE(data->mainTextureResourceViewV);
1243  SDL_free(data->pixels);
1244  SDL_free(data);
1245  texture->driverdata = NULL;
1246 }
1247 
1248 static int
1249 D3D11_UpdateTextureInternal(D3D11_RenderData *rendererData, ID3D11Texture2D *texture, int bpp, int x, int y, int w, int h, const void *pixels, int pitch)
1250 {
1251  ID3D11Texture2D *stagingTexture;
1252  const Uint8 *src;
1253  Uint8 *dst;
1254  int row;
1255  UINT length;
1256  HRESULT result;
1257  D3D11_TEXTURE2D_DESC stagingTextureDesc;
1258  D3D11_MAPPED_SUBRESOURCE textureMemory;
1259 
1260  /* Create a 'staging' texture, which will be used to write to a portion of the main texture. */
1261  ID3D11Texture2D_GetDesc(texture, &stagingTextureDesc);
1262  stagingTextureDesc.Width = w;
1263  stagingTextureDesc.Height = h;
1264  stagingTextureDesc.BindFlags = 0;
1265  stagingTextureDesc.MiscFlags = 0;
1266  stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
1267  stagingTextureDesc.Usage = D3D11_USAGE_STAGING;
1268  result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
1269  &stagingTextureDesc,
1270  NULL,
1271  &stagingTexture);
1272  if (FAILED(result)) {
1273  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result);
1274  return -1;
1275  }
1276 
1277  /* Get a write-only pointer to data in the staging texture: */
1278  result = ID3D11DeviceContext_Map(rendererData->d3dContext,
1279  (ID3D11Resource *)stagingTexture,
1280  0,
1281  D3D11_MAP_WRITE,
1282  0,
1283  &textureMemory
1284  );
1285  if (FAILED(result)) {
1286  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result);
1287  SAFE_RELEASE(stagingTexture);
1288  return -1;
1289  }
1290 
1291  src = (const Uint8 *)pixels;
1292  dst = textureMemory.pData;
1293  length = w * bpp;
1294  if (length == pitch && length == textureMemory.RowPitch) {
1295  SDL_memcpy(dst, src, length*h);
1296  } else {
1297  if (length > (UINT)pitch) {
1298  length = pitch;
1299  }
1300  if (length > textureMemory.RowPitch) {
1301  length = textureMemory.RowPitch;
1302  }
1303  for (row = 0; row < h; ++row) {
1304  SDL_memcpy(dst, src, length);
1305  src += pitch;
1306  dst += textureMemory.RowPitch;
1307  }
1308  }
1309 
1310  /* Commit the pixel buffer's changes back to the staging texture: */
1311  ID3D11DeviceContext_Unmap(rendererData->d3dContext,
1312  (ID3D11Resource *)stagingTexture,
1313  0);
1314 
1315  /* Copy the staging texture's contents back to the texture: */
1316  ID3D11DeviceContext_CopySubresourceRegion(rendererData->d3dContext,
1317  (ID3D11Resource *)texture,
1318  0,
1319  x,
1320  y,
1321  0,
1322  (ID3D11Resource *)stagingTexture,
1323  0,
1324  NULL);
1325 
1326  SAFE_RELEASE(stagingTexture);
1327 
1328  return 0;
1329 }
1330 
1331 static int
1332 D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
1333  const SDL_Rect * rect, const void * srcPixels,
1334  int srcPitch)
1335 {
1336  D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata;
1337  D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata;
1338 
1339  if (!textureData) {
1340  SDL_SetError("Texture is not currently available");
1341  return -1;
1342  }
1343 
1344  if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, SDL_BYTESPERPIXEL(texture->format), rect->x, rect->y, rect->w, rect->h, srcPixels, srcPitch) < 0) {
1345  return -1;
1346  }
1347 
1348  if (textureData->yuv) {
1349  /* Skip to the correct offset into the next texture */
1350  srcPixels = (const void*)((const Uint8*)srcPixels + rect->h * srcPitch);
1351 
1352  if (D3D11_UpdateTextureInternal(rendererData, texture->format == SDL_PIXELFORMAT_YV12 ? textureData->mainTextureV : textureData->mainTextureU, SDL_BYTESPERPIXEL(texture->format), rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, srcPixels, (srcPitch + 1) / 2) < 0) {
1353  return -1;
1354  }
1355 
1356  /* Skip to the correct offset into the next texture */
1357  srcPixels = (const void*)((const Uint8*)srcPixels + ((rect->h + 1) / 2) * ((srcPitch + 1) / 2));
1358  if (D3D11_UpdateTextureInternal(rendererData, texture->format == SDL_PIXELFORMAT_YV12 ? textureData->mainTextureU : textureData->mainTextureV, SDL_BYTESPERPIXEL(texture->format), rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, srcPixels, (srcPitch + 1) / 2) < 0) {
1359  return -1;
1360  }
1361  }
1362 
1363  if (textureData->nv12) {
1364  /* Skip to the correct offset into the next texture */
1365  srcPixels = (const void*)((const Uint8*)srcPixels + rect->h * srcPitch);
1366 
1367  if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTextureNV, 2, rect->x / 2, rect->y / 2, ((rect->w + 1) / 2), (rect->h + 1) / 2, srcPixels, 2*((srcPitch + 1) / 2)) < 0) {
1368  return -1;
1369  }
1370  }
1371  return 0;
1372 }
1373 
1374 static int
1375 D3D11_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
1376  const SDL_Rect * rect,
1377  const Uint8 *Yplane, int Ypitch,
1378  const Uint8 *Uplane, int Upitch,
1379  const Uint8 *Vplane, int Vpitch)
1380 {
1381  D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata;
1382  D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata;
1383 
1384  if (!textureData) {
1385  SDL_SetError("Texture is not currently available");
1386  return -1;
1387  }
1388 
1389  if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, SDL_BYTESPERPIXEL(texture->format), rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch) < 0) {
1390  return -1;
1391  }
1392  if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTextureU, SDL_BYTESPERPIXEL(texture->format), rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, Uplane, Upitch) < 0) {
1393  return -1;
1394  }
1395  if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTextureV, SDL_BYTESPERPIXEL(texture->format), rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, Vplane, Vpitch) < 0) {
1396  return -1;
1397  }
1398  return 0;
1399 }
1400 
1401 static int
1402 D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
1403  const SDL_Rect * rect, void **pixels, int *pitch)
1404 {
1405  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
1406  D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
1407  HRESULT result = S_OK;
1408  D3D11_TEXTURE2D_DESC stagingTextureDesc;
1409  D3D11_MAPPED_SUBRESOURCE textureMemory;
1410 
1411  if (!textureData) {
1412  SDL_SetError("Texture is not currently available");
1413  return -1;
1414  }
1415 
1416  if (textureData->yuv || textureData->nv12) {
1417  /* It's more efficient to upload directly... */
1418  if (!textureData->pixels) {
1419  textureData->pitch = texture->w;
1420  textureData->pixels = (Uint8 *)SDL_malloc((texture->h * textureData->pitch * 3) / 2);
1421  if (!textureData->pixels) {
1422  return SDL_OutOfMemory();
1423  }
1424  }
1425  textureData->locked_rect = *rect;
1426  *pixels =
1427  (void *)((Uint8 *)textureData->pixels + rect->y * textureData->pitch +
1428  rect->x * SDL_BYTESPERPIXEL(texture->format));
1429  *pitch = textureData->pitch;
1430  return 0;
1431  }
1432 
1433  if (textureData->stagingTexture) {
1434  return SDL_SetError("texture is already locked");
1435  }
1436 
1437  /* Create a 'staging' texture, which will be used to write to a portion
1438  * of the main texture. This is necessary, as Direct3D 11.1 does not
1439  * have the ability to write a CPU-bound pixel buffer to a rectangular
1440  * subrect of a texture. Direct3D 11.1 can, however, write a pixel
1441  * buffer to an entire texture, hence the use of a staging texture.
1442  *
1443  * TODO, WinRT: consider avoiding the use of a staging texture in D3D11_LockTexture if/when the entire texture is being updated
1444  */
1445  ID3D11Texture2D_GetDesc(textureData->mainTexture, &stagingTextureDesc);
1446  stagingTextureDesc.Width = rect->w;
1447  stagingTextureDesc.Height = rect->h;
1448  stagingTextureDesc.BindFlags = 0;
1449  stagingTextureDesc.MiscFlags = 0;
1450  stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
1451  stagingTextureDesc.Usage = D3D11_USAGE_STAGING;
1452  result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
1453  &stagingTextureDesc,
1454  NULL,
1455  &textureData->stagingTexture);
1456  if (FAILED(result)) {
1457  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result);
1458  return -1;
1459  }
1460 
1461  /* Get a write-only pointer to data in the staging texture: */
1462  result = ID3D11DeviceContext_Map(rendererData->d3dContext,
1463  (ID3D11Resource *)textureData->stagingTexture,
1464  0,
1465  D3D11_MAP_WRITE,
1466  0,
1467  &textureMemory
1468  );
1469  if (FAILED(result)) {
1470  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result);
1471  SAFE_RELEASE(textureData->stagingTexture);
1472  return -1;
1473  }
1474 
1475  /* Make note of where the staging texture will be written to
1476  * (on a call to SDL_UnlockTexture):
1477  */
1478  textureData->lockedTexturePositionX = rect->x;
1479  textureData->lockedTexturePositionY = rect->y;
1480 
1481  /* Make sure the caller has information on the texture's pixel buffer,
1482  * then return:
1483  */
1484  *pixels = textureMemory.pData;
1485  *pitch = textureMemory.RowPitch;
1486  return 0;
1487 }
1488 
1489 static void
1490 D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
1491 {
1492  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
1493  D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
1494 
1495  if (!textureData) {
1496  return;
1497  }
1498 
1499  if (textureData->yuv || textureData->nv12) {
1500  const SDL_Rect *rect = &textureData->locked_rect;
1501  void *pixels =
1502  (void *) ((Uint8 *) textureData->pixels + rect->y * textureData->pitch +
1503  rect->x * SDL_BYTESPERPIXEL(texture->format));
1504  D3D11_UpdateTexture(renderer, texture, rect, pixels, textureData->pitch);
1505  return;
1506  }
1507 
1508  /* Commit the pixel buffer's changes back to the staging texture: */
1509  ID3D11DeviceContext_Unmap(rendererData->d3dContext,
1510  (ID3D11Resource *)textureData->stagingTexture,
1511  0);
1512 
1513  /* Copy the staging texture's contents back to the main texture: */
1514  ID3D11DeviceContext_CopySubresourceRegion(rendererData->d3dContext,
1515  (ID3D11Resource *)textureData->mainTexture,
1516  0,
1517  textureData->lockedTexturePositionX,
1518  textureData->lockedTexturePositionY,
1519  0,
1520  (ID3D11Resource *)textureData->stagingTexture,
1521  0,
1522  NULL);
1523 
1524  SAFE_RELEASE(textureData->stagingTexture);
1525 }
1526 
1527 static void
1528 D3D11_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_ScaleMode scaleMode)
1529 {
1530  D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
1531 
1532  if (!textureData) {
1533  return;
1534  }
1535 
1536  textureData->scaleMode = (scaleMode == SDL_ScaleModeNearest) ? D3D11_FILTER_MIN_MAG_MIP_POINT : D3D11_FILTER_MIN_MAG_MIP_LINEAR;
1537 }
1538 
1539 static int
1540 D3D11_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
1541 {
1542  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
1543  D3D11_TextureData *textureData = NULL;
1544 
1545  if (texture == NULL) {
1546  rendererData->currentOffscreenRenderTargetView = NULL;
1547  return 0;
1548  }
1549 
1550  textureData = (D3D11_TextureData *) texture->driverdata;
1551 
1552  if (!textureData->mainTextureRenderTargetView) {
1553  return SDL_SetError("specified texture is not a render target");
1554  }
1555 
1556  rendererData->currentOffscreenRenderTargetView = textureData->mainTextureRenderTargetView;
1557 
1558  return 0;
1559 }
1560 
1561 static int
1562 D3D11_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd)
1563 {
1564  return 0; /* nothing to do in this backend. */
1565 }
1566 
1567 static int
1568 D3D11_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
1569 {
1570  VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, count * sizeof (VertexPositionColor), 0, &cmd->data.draw.first);
1571  const float r = (float)(cmd->data.draw.r / 255.0f);
1572  const float g = (float)(cmd->data.draw.g / 255.0f);
1573  const float b = (float)(cmd->data.draw.b / 255.0f);
1574  const float a = (float)(cmd->data.draw.a / 255.0f);
1575  int i;
1576 
1577  if (!verts) {
1578  return -1;
1579  }
1580 
1581  cmd->data.draw.count = count;
1582 
1583  for (i = 0; i < count; i++) {
1584  verts->pos.x = points[i].x + 0.5f;
1585  verts->pos.y = points[i].y + 0.5f;
1586  verts->pos.z = 0.0f;
1587  verts->tex.x = 0.0f;
1588  verts->tex.y = 0.0f;
1589  verts->color.x = r;
1590  verts->color.y = g;
1591  verts->color.z = b;
1592  verts->color.w = a;
1593  verts++;
1594  }
1595 
1596  return 0;
1597 }
1598 
1599 static int
1600 D3D11_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
1601 {
1602  VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, count * 4 * sizeof (VertexPositionColor), 0, &cmd->data.draw.first);
1603  const float r = (float)(cmd->data.draw.r / 255.0f);
1604  const float g = (float)(cmd->data.draw.g / 255.0f);
1605  const float b = (float)(cmd->data.draw.b / 255.0f);
1606  const float a = (float)(cmd->data.draw.a / 255.0f);
1607  int i;
1608 
1609  if (!verts) {
1610  return -1;
1611  }
1612 
1613  cmd->data.draw.count = count;
1614 
1615  for (i = 0; i < count; i++) {
1616  verts->pos.x = rects[i].x;
1617  verts->pos.y = rects[i].y;
1618  verts->pos.z = 0.0f;
1619  verts->tex.x = 0.0f;
1620  verts->tex.y = 0.0f;
1621  verts->color.x = r;
1622  verts->color.y = g;
1623  verts->color.z = b;
1624  verts->color.w = a;
1625  verts++;
1626 
1627  verts->pos.x = rects[i].x;
1628  verts->pos.y = rects[i].y + rects[i].h;
1629  verts->pos.z = 0.0f;
1630  verts->tex.x = 0.0f;
1631  verts->tex.y = 0.0f;
1632  verts->color.x = r;
1633  verts->color.y = g;
1634  verts->color.z = b;
1635  verts->color.w = a;
1636  verts++;
1637 
1638  verts->pos.x = rects[i].x + rects[i].w;
1639  verts->pos.y = rects[i].y;
1640  verts->pos.z = 0.0f;
1641  verts->tex.x = 0.0f;
1642  verts->tex.y = 0.0f;
1643  verts->color.x = r;
1644  verts->color.y = g;
1645  verts->color.z = b;
1646  verts->color.w = a;
1647  verts++;
1648 
1649  verts->pos.x = rects[i].x + rects[i].w;
1650  verts->pos.y = rects[i].y + rects[i].h;
1651  verts->pos.z = 0.0f;
1652  verts->tex.x = 0.0f;
1653  verts->tex.y = 0.0f;
1654  verts->color.x = r;
1655  verts->color.y = g;
1656  verts->color.z = b;
1657  verts->color.w = a;
1658  verts++;
1659  }
1660 
1661  return 0;
1662 }
1663 
1664 static int
1665 D3D11_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
1666  const SDL_Rect * srcrect, const SDL_FRect * dstrect)
1667 {
1668  VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, 4 * sizeof (VertexPositionColor), 0, &cmd->data.draw.first);
1669  const float r = (float)(cmd->data.draw.r / 255.0f);
1670  const float g = (float)(cmd->data.draw.g / 255.0f);
1671  const float b = (float)(cmd->data.draw.b / 255.0f);
1672  const float a = (float)(cmd->data.draw.a / 255.0f);
1673  const float minu = (float) srcrect->x / texture->w;
1674  const float maxu = (float) (srcrect->x + srcrect->w) / texture->w;
1675  const float minv = (float) srcrect->y / texture->h;
1676  const float maxv = (float) (srcrect->y + srcrect->h) / texture->h;
1677 
1678  if (!verts) {
1679  return -1;
1680  }
1681 
1682  cmd->data.draw.count = 1;
1683 
1684  verts->pos.x = dstrect->x;
1685  verts->pos.y = dstrect->y;
1686  verts->pos.z = 0.0f;
1687  verts->tex.x = minu;
1688  verts->tex.y = minv;
1689  verts->color.x = r;
1690  verts->color.y = g;
1691  verts->color.z = b;
1692  verts->color.w = a;
1693  verts++;
1694 
1695  verts->pos.x = dstrect->x;
1696  verts->pos.y = dstrect->y + dstrect->h;
1697  verts->pos.z = 0.0f;
1698  verts->tex.x = minu;
1699  verts->tex.y = maxv;
1700  verts->color.x = r;
1701  verts->color.y = g;
1702  verts->color.z = b;
1703  verts->color.w = a;
1704  verts++;
1705 
1706  verts->pos.x = dstrect->x + dstrect->w;
1707  verts->pos.y = dstrect->y;
1708  verts->pos.z = 0.0f;
1709  verts->tex.x = maxu;
1710  verts->tex.y = minv;
1711  verts->color.x = r;
1712  verts->color.y = g;
1713  verts->color.z = b;
1714  verts->color.w = a;
1715  verts++;
1716 
1717  verts->pos.x = dstrect->x + dstrect->w;
1718  verts->pos.y = dstrect->y + dstrect->h;
1719  verts->pos.z = 0.0f;
1720  verts->tex.x = maxu;
1721  verts->tex.y = maxv;
1722  verts->color.x = r;
1723  verts->color.y = g;
1724  verts->color.z = b;
1725  verts->color.w = a;
1726  verts++;
1727 
1728  return 0;
1729 }
1730 
1731 static int
1732 D3D11_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
1733  const SDL_Rect * srcrect, const SDL_FRect * dstrect,
1734  const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
1735 {
1736  VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, 5 * sizeof (VertexPositionColor), 0, &cmd->data.draw.first);
1737  const float r = (float)(cmd->data.draw.r / 255.0f);
1738  const float g = (float)(cmd->data.draw.g / 255.0f);
1739  const float b = (float)(cmd->data.draw.b / 255.0f);
1740  const float a = (float)(cmd->data.draw.a / 255.0f);
1741  float minx, miny, maxx, maxy;
1742  float minu, maxu, minv, maxv;
1743 
1744  if (!verts) {
1745  return -1;
1746  }
1747 
1748  cmd->data.draw.count = 1;
1749 
1750  minx = -center->x;
1751  maxx = dstrect->w - center->x;
1752  miny = -center->y;
1753  maxy = dstrect->h - center->y;
1754 
1755  if (flip & SDL_FLIP_HORIZONTAL) {
1756  minu = (float) (srcrect->x + srcrect->w) / texture->w;
1757  maxu = (float) srcrect->x / texture->w;
1758  } else {
1759  minu = (float) srcrect->x / texture->w;
1760  maxu = (float) (srcrect->x + srcrect->w) / texture->w;
1761  }
1762 
1763  if (flip & SDL_FLIP_VERTICAL) {
1764  minv = (float) (srcrect->y + srcrect->h) / texture->h;
1765  maxv = (float) srcrect->y / texture->h;
1766  } else {
1767  minv = (float) srcrect->y / texture->h;
1768  maxv = (float) (srcrect->y + srcrect->h) / texture->h;
1769  }
1770 
1771 
1772 
1773  verts->pos.x = minx;
1774  verts->pos.y = miny;
1775  verts->pos.z = 0.0f;
1776  verts->color.x = r;
1777  verts->color.y = g;
1778  verts->color.z = b;
1779  verts->color.w = a;
1780  verts->tex.x = minu;
1781  verts->tex.y = minv;
1782  verts++;
1783 
1784  verts->pos.x = minx;
1785  verts->pos.y = maxy;
1786  verts->pos.z = 0.0f;
1787  verts->color.x = r;
1788  verts->color.y = g;
1789  verts->color.z = b;
1790  verts->color.w = a;
1791  verts->tex.x = minu;
1792  verts->tex.y = maxv;
1793  verts++;
1794 
1795  verts->pos.x = maxx;
1796  verts->pos.y = miny;
1797  verts->pos.z = 0.0f;
1798  verts->color.x = r;
1799  verts->color.y = g;
1800  verts->color.z = b;
1801  verts->color.w = a;
1802  verts->tex.x = maxu;
1803  verts->tex.y = minv;
1804  verts++;
1805 
1806  verts->pos.x = maxx;
1807  verts->pos.y = maxy;
1808  verts->pos.z = 0.0f;
1809  verts->color.x = r;
1810  verts->color.y = g;
1811  verts->color.z = b;
1812  verts->color.w = a;
1813  verts->tex.x = maxu;
1814  verts->tex.y = maxv;
1815  verts++;
1816 
1817  verts->pos.x = dstrect->x + center->x; /* X translation */
1818  verts->pos.y = dstrect->y + center->y; /* Y translation */
1819  verts->pos.z = (float)(M_PI * (float) angle / 180.0f); /* rotation */
1820  verts->color.x = 0;
1821  verts->color.y = 0;
1822  verts->color.z = 0;
1823  verts->color.w = 0;
1824  verts->tex.x = 0.0f;
1825  verts->tex.y = 0.0f;
1826  verts++;
1827 
1828  return 0;
1829 }
1830 
1831 
1832 static int
1833 D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
1834  const void * vertexData, size_t dataSizeInBytes)
1835 {
1836  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
1837  HRESULT result = S_OK;
1838  const int vbidx = rendererData->currentVertexBuffer;
1839  const UINT stride = sizeof(VertexPositionColor);
1840  const UINT offset = 0;
1841 
1842  if (dataSizeInBytes == 0) {
1843  return 0; /* nothing to do. */
1844  }
1845 
1846  if (rendererData->vertexBuffers[vbidx] && rendererData->vertexBufferSizes[vbidx] >= dataSizeInBytes) {
1847  D3D11_MAPPED_SUBRESOURCE mappedResource;
1848  result = ID3D11DeviceContext_Map(rendererData->d3dContext,
1849  (ID3D11Resource *)rendererData->vertexBuffers[vbidx],
1850  0,
1851  D3D11_MAP_WRITE_DISCARD,
1852  0,
1853  &mappedResource
1854  );
1855  if (FAILED(result)) {
1856  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [vertex buffer]"), result);
1857  return -1;
1858  }
1859  SDL_memcpy(mappedResource.pData, vertexData, dataSizeInBytes);
1860  ID3D11DeviceContext_Unmap(rendererData->d3dContext, (ID3D11Resource *)rendererData->vertexBuffers[vbidx], 0);
1861  } else {
1862  D3D11_BUFFER_DESC vertexBufferDesc;
1863  D3D11_SUBRESOURCE_DATA vertexBufferData;
1864 
1865  SAFE_RELEASE(rendererData->vertexBuffers[vbidx]);
1866 
1867  SDL_zero(vertexBufferDesc);
1868  vertexBufferDesc.ByteWidth = (UINT) dataSizeInBytes;
1869  vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
1870  vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
1871  vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
1872 
1873  SDL_zero(vertexBufferData);
1874  vertexBufferData.pSysMem = vertexData;
1875  vertexBufferData.SysMemPitch = 0;
1876  vertexBufferData.SysMemSlicePitch = 0;
1877 
1878  result = ID3D11Device_CreateBuffer(rendererData->d3dDevice,
1879  &vertexBufferDesc,
1880  &vertexBufferData,
1881  &rendererData->vertexBuffers[vbidx]
1882  );
1883  if (FAILED(result)) {
1884  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBuffer [vertex buffer]"), result);
1885  return -1;
1886  }
1887 
1888  rendererData->vertexBufferSizes[vbidx] = dataSizeInBytes;
1889  }
1890 
1891  ID3D11DeviceContext_IASetVertexBuffers(rendererData->d3dContext,
1892  0,
1893  1,
1894  &rendererData->vertexBuffers[vbidx],
1895  &stride,
1896  &offset
1897  );
1898 
1899  rendererData->currentVertexBuffer++;
1900  if (rendererData->currentVertexBuffer >= SDL_arraysize(rendererData->vertexBuffers)) {
1901  rendererData->currentVertexBuffer = 0;
1902  }
1903 
1904  return 0;
1905 }
1906 
1907 static int
1908 D3D11_UpdateViewport(SDL_Renderer * renderer)
1909 {
1910  D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
1911  const SDL_Rect *viewport = &data->currentViewport;
1912  Float4X4 projection;
1913  Float4X4 view;
1914  SDL_FRect orientationAlignedViewport;
1915  BOOL swapDimensions;
1916  D3D11_VIEWPORT d3dviewport;
1917  const int rotation = D3D11_GetRotationForCurrentRenderTarget(renderer);
1918 
1919  if (viewport->w == 0 || viewport->h == 0) {
1920  /* If the viewport is empty, assume that it is because
1921  * SDL_CreateRenderer is calling it, and will call it again later
1922  * with a non-empty viewport.
1923  */
1924  /* SDL_Log("%s, no viewport was set!\n", __FUNCTION__); */
1925  return -1;
1926  }
1927 
1928  /* Make sure the SDL viewport gets rotated to that of the physical display's rotation.
1929  * Keep in mind here that the Y-axis will be been inverted (from Direct3D's
1930  * default coordinate system) so rotations will be done in the opposite
1931  * direction of the DXGI_MODE_ROTATION enumeration.
1932  */
1933  switch (rotation) {
1934  case DXGI_MODE_ROTATION_IDENTITY:
1935  projection = MatrixIdentity();
1936  break;
1937  case DXGI_MODE_ROTATION_ROTATE270:
1938  projection = MatrixRotationZ(SDL_static_cast(float, M_PI * 0.5f));
1939  break;
1940  case DXGI_MODE_ROTATION_ROTATE180:
1941  projection = MatrixRotationZ(SDL_static_cast(float, M_PI));
1942  break;
1943  case DXGI_MODE_ROTATION_ROTATE90:
1944  projection = MatrixRotationZ(SDL_static_cast(float, -M_PI * 0.5f));
1945  break;
1946  default:
1947  return SDL_SetError("An unknown DisplayOrientation is being used");
1948  }
1949 
1950  /* Update the view matrix */
1951  SDL_zero(view);
1952  view.m[0][0] = 2.0f / viewport->w;
1953  view.m[1][1] = -2.0f / viewport->h;
1954  view.m[2][2] = 1.0f;
1955  view.m[3][0] = -1.0f;
1956  view.m[3][1] = 1.0f;
1957  view.m[3][3] = 1.0f;
1958 
1959  /* Combine the projection + view matrix together now, as both only get
1960  * set here (as of this writing, on Dec 26, 2013). When done, store it
1961  * for eventual transfer to the GPU.
1962  */
1963  data->vertexShaderConstantsData.projectionAndView = MatrixMultiply(
1964  view,
1965  projection);
1966 
1967  /* Update the Direct3D viewport, which seems to be aligned to the
1968  * swap buffer's coordinate space, which is always in either
1969  * a landscape mode, for all Windows 8/RT devices, or a portrait mode,
1970  * for Windows Phone devices.
1971  */
1972  swapDimensions = D3D11_IsDisplayRotated90Degrees(rotation);
1973  if (swapDimensions) {
1974  orientationAlignedViewport.x = (float) viewport->y;
1975  orientationAlignedViewport.y = (float) viewport->x;
1976  orientationAlignedViewport.w = (float) viewport->h;
1977  orientationAlignedViewport.h = (float) viewport->w;
1978  } else {
1979  orientationAlignedViewport.x = (float) viewport->x;
1980  orientationAlignedViewport.y = (float) viewport->y;
1981  orientationAlignedViewport.w = (float) viewport->w;
1982  orientationAlignedViewport.h = (float) viewport->h;
1983  }
1984  /* TODO, WinRT: get custom viewports working with non-Landscape modes (Portrait, PortraitFlipped, and LandscapeFlipped) */
1985 
1986  d3dviewport.TopLeftX = orientationAlignedViewport.x;
1987  d3dviewport.TopLeftY = orientationAlignedViewport.y;
1988  d3dviewport.Width = orientationAlignedViewport.w;
1989  d3dviewport.Height = orientationAlignedViewport.h;
1990  d3dviewport.MinDepth = 0.0f;
1991  d3dviewport.MaxDepth = 1.0f;
1992  /* SDL_Log("%s: D3D viewport = {%f,%f,%f,%f}\n", __FUNCTION__, d3dviewport.TopLeftX, d3dviewport.TopLeftY, d3dviewport.Width, d3dviewport.Height); */
1993  ID3D11DeviceContext_RSSetViewports(data->d3dContext, 1, &d3dviewport);
1994 
1995  data->viewportDirty = SDL_FALSE;
1996 
1997  return 0;
1998 }
1999 
2000 static ID3D11RenderTargetView *
2001 D3D11_GetCurrentRenderTargetView(SDL_Renderer * renderer)
2002 {
2003  D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata;
2004  if (data->currentOffscreenRenderTargetView) {
2005  return data->currentOffscreenRenderTargetView;
2006  }
2007  else {
2008  return data->mainRenderTargetView;
2009  }
2010 }
2011 
2012 static int
2013 D3D11_SetDrawState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, ID3D11PixelShader * shader,
2014  const int numShaderResources, ID3D11ShaderResourceView ** shaderResources,
2015  ID3D11SamplerState * sampler, const Float4X4 *matrix)
2016 
2017 {
2018  D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata;
2019  const Float4X4 *newmatrix = matrix ? matrix : &rendererData->identity;
2020  ID3D11RasterizerState *rasterizerState;
2021  ID3D11RenderTargetView *renderTargetView = D3D11_GetCurrentRenderTargetView(renderer);
2022  ID3D11ShaderResourceView *shaderResource;
2023  const SDL_BlendMode blendMode = cmd->data.draw.blend;
2024  ID3D11BlendState *blendState = NULL;
2025  SDL_bool updateSubresource = SDL_FALSE;
2026 
2027  if (renderTargetView != rendererData->currentRenderTargetView) {
2028  ID3D11DeviceContext_OMSetRenderTargets(rendererData->d3dContext,
2029  1,
2030  &renderTargetView,
2031  NULL
2032  );
2033  rendererData->currentRenderTargetView = renderTargetView;
2034  }
2035 
2036  if (rendererData->viewportDirty) {
2037  if (D3D11_UpdateViewport(renderer) == 0) {
2038  /* vertexShaderConstantsData.projectionAndView has changed */
2039  updateSubresource = SDL_TRUE;
2040  }
2041  }
2042 
2043  if (rendererData->cliprectDirty) {
2044  if (!rendererData->currentCliprectEnabled) {
2045  ID3D11DeviceContext_RSSetScissorRects(rendererData->d3dContext, 0, NULL);
2046  } else {
2047  D3D11_RECT scissorRect;
2048  if (D3D11_GetViewportAlignedD3DRect(renderer, &rendererData->currentCliprect, &scissorRect, TRUE) != 0) {
2049  /* D3D11_GetViewportAlignedD3DRect will have set the SDL error */
2050  return -1;
2051  }
2052  ID3D11DeviceContext_RSSetScissorRects(rendererData->d3dContext, 1, &scissorRect);
2053  }
2054  rendererData->cliprectDirty = SDL_FALSE;
2055  }
2056 
2057  if (!rendererData->currentCliprectEnabled) {
2058  rasterizerState = rendererData->mainRasterizer;
2059  } else {
2060  rasterizerState = rendererData->clippedRasterizer;
2061  }
2062  if (rasterizerState != rendererData->currentRasterizerState) {
2063  ID3D11DeviceContext_RSSetState(rendererData->d3dContext, rasterizerState);
2064  rendererData->currentRasterizerState = rasterizerState;
2065  }
2066 
2067  if (blendMode != SDL_BLENDMODE_NONE) {
2068  int i;
2069  for (i = 0; i < rendererData->blendModesCount; ++i) {
2070  if (blendMode == rendererData->blendModes[i].blendMode) {
2071  blendState = rendererData->blendModes[i].blendState;
2072  break;
2073  }
2074  }
2075  if (!blendState) {
2076  blendState = D3D11_CreateBlendState(renderer, blendMode);
2077  if (!blendState) {
2078  return -1;
2079  }
2080  }
2081  }
2082  if (blendState != rendererData->currentBlendState) {
2083  ID3D11DeviceContext_OMSetBlendState(rendererData->d3dContext, blendState, 0, 0xFFFFFFFF);
2084  rendererData->currentBlendState = blendState;
2085  }
2086 
2087  if (shader != rendererData->currentShader) {
2088  ID3D11DeviceContext_PSSetShader(rendererData->d3dContext, shader, NULL, 0);
2089  rendererData->currentShader = shader;
2090  }
2091  if (numShaderResources > 0) {
2092  shaderResource = shaderResources[0];
2093  } else {
2094  shaderResource = NULL;
2095  }
2096  if (shaderResource != rendererData->currentShaderResource) {
2097  ID3D11DeviceContext_PSSetShaderResources(rendererData->d3dContext, 0, numShaderResources, shaderResources);
2098  rendererData->currentShaderResource = shaderResource;
2099  }
2100  if (sampler != rendererData->currentSampler) {
2101  ID3D11DeviceContext_PSSetSamplers(rendererData->d3dContext, 0, 1, &sampler);
2102  rendererData->currentSampler = sampler;
2103  }
2104 
2105  if (updateSubresource == SDL_TRUE || SDL_memcmp(&rendererData->vertexShaderConstantsData.model, newmatrix, sizeof (*newmatrix)) != 0) {
2106  SDL_memcpy(&rendererData->vertexShaderConstantsData.model, newmatrix, sizeof (*newmatrix));
2107  ID3D11DeviceContext_UpdateSubresource(rendererData->d3dContext,
2108  (ID3D11Resource *)rendererData->vertexShaderConstants,
2109  0,
2110  NULL,
2111  &rendererData->vertexShaderConstantsData,
2112  0,
2113  0
2114  );
2115  }
2116 
2117  return 0;
2118 }
2119 
2120 static int
2121 D3D11_SetCopyState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, const Float4X4 *matrix)
2122 {
2123  SDL_Texture *texture = cmd->data.draw.texture;
2124  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2125  D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata;
2126  ID3D11SamplerState *textureSampler;
2127 
2128  switch (textureData->scaleMode) {
2129  case D3D11_FILTER_MIN_MAG_MIP_POINT:
2130  textureSampler = rendererData->nearestPixelSampler;
2131  break;
2132  case D3D11_FILTER_MIN_MAG_MIP_LINEAR:
2133  textureSampler = rendererData->linearSampler;
2134  break;
2135  default:
2136  return SDL_SetError("Unknown scale mode: %d\n", textureData->scaleMode);
2137  }
2138 
2139  if (textureData->yuv) {
2140  ID3D11ShaderResourceView *shaderResources[] = {
2141  textureData->mainTextureResourceView,
2142  textureData->mainTextureResourceViewU,
2143  textureData->mainTextureResourceViewV
2144  };
2146 
2150  break;
2153  break;
2156  break;
2157  default:
2158  return SDL_SetError("Unsupported YUV conversion mode");
2159  }
2160 
2161  return D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[shader],
2162  SDL_arraysize(shaderResources), shaderResources, textureSampler, matrix);
2163 
2164  } else if (textureData->nv12) {
2165  ID3D11ShaderResourceView *shaderResources[] = {
2166  textureData->mainTextureResourceView,
2167  textureData->mainTextureResourceViewNV,
2168  };
2170 
2174  break;
2177  break;
2180  break;
2181  default:
2182  return SDL_SetError("Unsupported YUV conversion mode");
2183  }
2184 
2185  return D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[shader],
2186  SDL_arraysize(shaderResources), shaderResources, textureSampler, matrix);
2187 
2188  }
2189 
2190  return D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_RGB],
2191  1, &textureData->mainTextureResourceView, textureSampler, matrix);
2192 }
2193 
2194 static void
2195 D3D11_DrawPrimitives(SDL_Renderer * renderer, D3D11_PRIMITIVE_TOPOLOGY primitiveTopology, const size_t vertexStart, const size_t vertexCount)
2196 {
2197  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2198  ID3D11DeviceContext_IASetPrimitiveTopology(rendererData->d3dContext, primitiveTopology);
2199  ID3D11DeviceContext_Draw(rendererData->d3dContext, (UINT) vertexCount, (UINT) vertexStart);
2200 }
2201 
2202 static int
2203 D3D11_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
2204 {
2205  D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata;
2206  const int viewportRotation = D3D11_GetRotationForCurrentRenderTarget(renderer);
2207  size_t i;
2208 
2209  if (rendererData->currentViewportRotation != viewportRotation) {
2210  rendererData->currentViewportRotation = viewportRotation;
2211  rendererData->viewportDirty = SDL_TRUE;
2212  }
2213 
2214  if (D3D11_UpdateVertexBuffer(renderer, vertices, vertsize) < 0) {
2215  return -1;
2216  }
2217 
2218  while (cmd) {
2219  switch (cmd->command) {
2221  break; /* this isn't currently used in this render backend. */
2222  }
2223 
2225  SDL_Rect *viewport = &rendererData->currentViewport;
2226  if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) {
2227  SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect));
2228  rendererData->viewportDirty = SDL_TRUE;
2229  }
2230  break;
2231  }
2232 
2234  const SDL_Rect *rect = &cmd->data.cliprect.rect;
2235  if (rendererData->currentCliprectEnabled != cmd->data.cliprect.enabled) {
2236  rendererData->currentCliprectEnabled = cmd->data.cliprect.enabled;
2237  rendererData->cliprectDirty = SDL_TRUE;
2238  }
2239  if (SDL_memcmp(&rendererData->currentCliprect, rect, sizeof (SDL_Rect)) != 0) {
2240  SDL_memcpy(&rendererData->currentCliprect, rect, sizeof (SDL_Rect));
2241  rendererData->cliprectDirty = SDL_TRUE;
2242  }
2243  break;
2244  }
2245 
2246  case SDL_RENDERCMD_CLEAR: {
2247  const float colorRGBA[] = {
2248  (cmd->data.color.r / 255.0f),
2249  (cmd->data.color.g / 255.0f),
2250  (cmd->data.color.b / 255.0f),
2251  (cmd->data.color.a / 255.0f)
2252  };
2253  ID3D11DeviceContext_ClearRenderTargetView(rendererData->d3dContext, D3D11_GetCurrentRenderTargetView(renderer), colorRGBA);
2254  break;
2255  }
2256 
2258  const size_t count = cmd->data.draw.count;
2259  const size_t first = cmd->data.draw.first;
2260  const size_t start = first / sizeof (VertexPositionColor);
2261  D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_SOLID], 0, NULL, NULL, NULL);
2262  D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, start, count);
2263  break;
2264  }
2265 
2266  case SDL_RENDERCMD_DRAW_LINES: {
2267  const size_t count = cmd->data.draw.count;
2268  const size_t first = cmd->data.draw.first;
2269  const size_t start = first / sizeof (VertexPositionColor);
2270  const VertexPositionColor *verts = (VertexPositionColor *) (((Uint8 *) vertices) + first);
2271  D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_SOLID], 0, NULL, NULL, NULL);
2272  D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, start, count);
2273  if (verts[0].pos.x != verts[count - 1].pos.x || verts[0].pos.y != verts[count - 1].pos.y) {
2274  D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, start + (count-1), 1);
2275  }
2276  break;
2277  }
2278 
2279  case SDL_RENDERCMD_FILL_RECTS: {
2280  const size_t count = cmd->data.draw.count;
2281  const size_t first = cmd->data.draw.first;
2282  const size_t start = first / sizeof (VertexPositionColor);
2283  size_t offset = 0;
2284  D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_SOLID], 0, NULL, NULL, NULL);
2285  for (i = 0; i < count; i++, offset += 4) {
2286  D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, start + offset, 4);
2287  }
2288  break;
2289  }
2290 
2291  case SDL_RENDERCMD_COPY: {
2292  const size_t first = cmd->data.draw.first;
2293  const size_t start = first / sizeof (VertexPositionColor);
2294  D3D11_SetCopyState(renderer, cmd, NULL);
2295  D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, start, 4);
2296  break;
2297  }
2298 
2299  case SDL_RENDERCMD_COPY_EX: {
2300  const size_t first = cmd->data.draw.first;
2301  const size_t start = first / sizeof (VertexPositionColor);
2302  const VertexPositionColor *verts = (VertexPositionColor *) (((Uint8 *) vertices) + first);
2303  const VertexPositionColor *transvert = verts + 4;
2304  const float translatex = transvert->pos.x;
2305  const float translatey = transvert->pos.y;
2306  const float rotation = transvert->pos.z;
2307  const Float4X4 matrix = MatrixMultiply(MatrixRotationZ(rotation), MatrixTranslation(translatex, translatey, 0));
2308  D3D11_SetCopyState(renderer, cmd, &matrix);
2309  D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, start, 4);
2310  break;
2311  }
2312 
2313  case SDL_RENDERCMD_NO_OP:
2314  break;
2315  }
2316 
2317  cmd = cmd->next;
2318  }
2319 
2320  return 0;
2321 }
2322 
2323 static int
2324 D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
2325  Uint32 format, void * pixels, int pitch)
2326 {
2327  D3D11_RenderData * data = (D3D11_RenderData *) renderer->driverdata;
2328  ID3D11Texture2D *backBuffer = NULL;
2329  ID3D11Texture2D *stagingTexture = NULL;
2330  HRESULT result;
2331  int status = -1;
2332  D3D11_TEXTURE2D_DESC stagingTextureDesc;
2333  D3D11_RECT srcRect = {0, 0, 0, 0};
2334  D3D11_BOX srcBox;
2335  D3D11_MAPPED_SUBRESOURCE textureMemory;
2336 
2337  /* Retrieve a pointer to the back buffer: */
2338  result = IDXGISwapChain_GetBuffer(data->swapChain,
2339  0,
2340  &SDL_IID_ID3D11Texture2D,
2341  (void **)&backBuffer
2342  );
2343  if (FAILED(result)) {
2344  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain1::GetBuffer [get back buffer]"), result);
2345  goto done;
2346  }
2347 
2348  /* Create a staging texture to copy the screen's data to: */
2349  ID3D11Texture2D_GetDesc(backBuffer, &stagingTextureDesc);
2350  stagingTextureDesc.Width = rect->w;
2351  stagingTextureDesc.Height = rect->h;
2352  stagingTextureDesc.BindFlags = 0;
2353  stagingTextureDesc.MiscFlags = 0;
2354  stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
2355  stagingTextureDesc.Usage = D3D11_USAGE_STAGING;
2356  result = ID3D11Device_CreateTexture2D(data->d3dDevice,
2357  &stagingTextureDesc,
2358  NULL,
2359  &stagingTexture);
2360  if (FAILED(result)) {
2361  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result);
2362  goto done;
2363  }
2364 
2365  /* Copy the desired portion of the back buffer to the staging texture: */
2366  if (D3D11_GetViewportAlignedD3DRect(renderer, rect, &srcRect, FALSE) != 0) {
2367  /* D3D11_GetViewportAlignedD3DRect will have set the SDL error */
2368  goto done;
2369  }
2370 
2371  srcBox.left = srcRect.left;
2372  srcBox.right = srcRect.right;
2373  srcBox.top = srcRect.top;
2374  srcBox.bottom = srcRect.bottom;
2375  srcBox.front = 0;
2376  srcBox.back = 1;
2377  ID3D11DeviceContext_CopySubresourceRegion(data->d3dContext,
2378  (ID3D11Resource *)stagingTexture,
2379  0,
2380  0, 0, 0,
2381  (ID3D11Resource *)backBuffer,
2382  0,
2383  &srcBox);
2384 
2385  /* Map the staging texture's data to CPU-accessible memory: */
2386  result = ID3D11DeviceContext_Map(data->d3dContext,
2387  (ID3D11Resource *)stagingTexture,
2388  0,
2389  D3D11_MAP_READ,
2390  0,
2391  &textureMemory);
2392  if (FAILED(result)) {
2393  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result);
2394  goto done;
2395  }
2396 
2397  /* Copy the data into the desired buffer, converting pixels to the
2398  * desired format at the same time:
2399  */
2400  if (SDL_ConvertPixels(
2401  rect->w, rect->h,
2402  D3D11_DXGIFormatToSDLPixelFormat(stagingTextureDesc.Format),
2403  textureMemory.pData,
2404  textureMemory.RowPitch,
2405  format,
2406  pixels,
2407  pitch) != 0) {
2408  /* When SDL_ConvertPixels fails, it'll have already set the format.
2409  * Get the error message, and attach some extra data to it.
2410  */
2411  char errorMessage[1024];
2412  SDL_snprintf(errorMessage, sizeof(errorMessage), "%s, Convert Pixels failed: %s", __FUNCTION__, SDL_GetError());
2413  SDL_SetError("%s", errorMessage);
2414  goto done;
2415  }
2416 
2417  /* Unmap the texture: */
2418  ID3D11DeviceContext_Unmap(data->d3dContext,
2419  (ID3D11Resource *)stagingTexture,
2420  0);
2421 
2422  status = 0;
2423 
2424 done:
2425  SAFE_RELEASE(backBuffer);
2426  SAFE_RELEASE(stagingTexture);
2427  return status;
2428 }
2429 
2430 static void
2431 D3D11_RenderPresent(SDL_Renderer * renderer)
2432 {
2433  D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata;
2434  UINT syncInterval;
2435  UINT presentFlags;
2436  HRESULT result;
2437  DXGI_PRESENT_PARAMETERS parameters;
2438 
2439  SDL_zero(parameters);
2440 
2441 #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
2442  syncInterval = 1;
2443  presentFlags = 0;
2444  result = IDXGISwapChain_Present(data->swapChain, syncInterval, presentFlags);
2445 #else
2447  syncInterval = 1;
2448  presentFlags = 0;
2449  } else {
2450  syncInterval = 0;
2451  presentFlags = DXGI_PRESENT_DO_NOT_WAIT;
2452  }
2453 
2454  /* The application may optionally specify "dirty" or "scroll"
2455  * rects to improve efficiency in certain scenarios.
2456  * This option is not available on Windows Phone 8, to note.
2457  */
2458  result = IDXGISwapChain1_Present1(data->swapChain, syncInterval, presentFlags, &parameters);
2459 #endif
2460 
2461  /* Discard the contents of the render target.
2462  * This is a valid operation only when the existing contents will be entirely
2463  * overwritten. If dirty or scroll rects are used, this call should be removed.
2464  */
2465  ID3D11DeviceContext1_DiscardView(data->d3dContext, (ID3D11View*)data->mainRenderTargetView);
2466 
2467  /* When the present flips, it unbinds the current view, so bind it again on the next draw call */
2468  data->currentRenderTargetView = NULL;
2469 
2470  if (FAILED(result) && result != DXGI_ERROR_WAS_STILL_DRAWING) {
2471  /* If the device was removed either by a disconnect or a driver upgrade, we
2472  * must recreate all device resources.
2473  *
2474  * TODO, WinRT: consider throwing an exception if D3D11_RenderPresent fails, especially if there is a way to salvage debug info from users' machines
2475  */
2476  if ( result == DXGI_ERROR_DEVICE_REMOVED ) {
2477  D3D11_HandleDeviceLost(renderer);
2478  } else if (result == DXGI_ERROR_INVALID_CALL) {
2479  /* We probably went through a fullscreen <-> windowed transition */
2480  D3D11_CreateWindowSizeDependentResources(renderer);
2481  } else {
2482  WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::Present"), result);
2483  }
2484  }
2485 }
2486 
2487 SDL_Renderer *
2488 D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
2489 {
2491  D3D11_RenderData *data;
2492 
2493  renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
2494  if (!renderer) {
2495  SDL_OutOfMemory();
2496  return NULL;
2497  }
2498 
2499  data = (D3D11_RenderData *) SDL_calloc(1, sizeof(*data));
2500  if (!data) {
2501  SDL_OutOfMemory();
2502  return NULL;
2503  }
2504 
2505  data->identity = MatrixIdentity();
2506 
2507  renderer->WindowEvent = D3D11_WindowEvent;
2508  renderer->SupportsBlendMode = D3D11_SupportsBlendMode;
2509  renderer->CreateTexture = D3D11_CreateTexture;
2510  renderer->UpdateTexture = D3D11_UpdateTexture;
2511  renderer->UpdateTextureYUV = D3D11_UpdateTextureYUV;
2512  renderer->LockTexture = D3D11_LockTexture;
2513  renderer->UnlockTexture = D3D11_UnlockTexture;
2514  renderer->SetTextureScaleMode = D3D11_SetTextureScaleMode;
2515  renderer->SetRenderTarget = D3D11_SetRenderTarget;
2516  renderer->QueueSetViewport = D3D11_QueueSetViewport;
2517  renderer->QueueSetDrawColor = D3D11_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
2518  renderer->QueueDrawPoints = D3D11_QueueDrawPoints;
2519  renderer->QueueDrawLines = D3D11_QueueDrawPoints; /* lines and points queue vertices the same way. */
2520  renderer->QueueFillRects = D3D11_QueueFillRects;
2521  renderer->QueueCopy = D3D11_QueueCopy;
2522  renderer->QueueCopyEx = D3D11_QueueCopyEx;
2523  renderer->RunCommandQueue = D3D11_RunCommandQueue;
2524  renderer->RenderReadPixels = D3D11_RenderReadPixels;
2525  renderer->RenderPresent = D3D11_RenderPresent;
2526  renderer->DestroyTexture = D3D11_DestroyTexture;
2527  renderer->DestroyRenderer = D3D11_DestroyRenderer;
2531 
2532 #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
2533  /* VSync is required in Windows Phone, at least for Win Phone 8.0 and 8.1.
2534  * Failure to use it seems to either result in:
2535  *
2536  * - with the D3D11 debug runtime turned OFF, vsync seemingly gets turned
2537  * off (framerate doesn't get capped), but nothing appears on-screen
2538  *
2539  * - with the D3D11 debug runtime turned ON, vsync gets automatically
2540  * turned back on, and the following gets output to the debug console:
2541  *
2542  * DXGI ERROR: IDXGISwapChain::Present: Interval 0 is not supported, changed to Interval 1. [ UNKNOWN ERROR #1024: ]
2543  */
2545 #else
2546  if ((flags & SDL_RENDERER_PRESENTVSYNC)) {
2548  }
2549 #endif
2550 
2551  /* HACK: make sure the SDL_Renderer references the SDL_Window data now, in
2552  * order to give init functions access to the underlying window handle:
2553  */
2554  renderer->window = window;
2555 
2556  /* Initialize Direct3D resources */
2557  if (FAILED(D3D11_CreateDeviceResources(renderer))) {
2558  D3D11_DestroyRenderer(renderer);
2559  return NULL;
2560  }
2561  if (FAILED(D3D11_CreateWindowSizeDependentResources(renderer))) {
2562  D3D11_DestroyRenderer(renderer);
2563  return NULL;
2564  }
2565 
2566  return renderer;
2567 }
2568 
2570  D3D11_CreateRenderer,
2571  {
2572  "direct3d11",
2573  (
2577  ), /* flags. see SDL_RendererFlags */
2578  6, /* num_texture_formats */
2579  { /* texture_formats */
2586  },
2587  0, /* max_texture_width: will be filled in later */
2588  0 /* max_texture_height: will be filled in later */
2589  }
2590 };
2591 
2592 #endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */
2593 
2594 /* vi: set ts=4 sw=4 expandtab: */
SHADER_NV12_JPEG
@ SHADER_NV12_JPEG
Definition: SDL_shaders_d3d11.h:31
SDL_zero
#define SDL_zero(x)
Definition: SDL_stdinc.h:418
format
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
points
GLfixed GLfixed GLint GLint GLfixed points
Definition: SDL_opengl_glext.h:4561
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179
SDL_BLENDOPERATION_ADD
@ SDL_BLENDOPERATION_ADD
Definition: SDL_blendmode.h:67
SDL_GetError
#define SDL_GetError
Definition: SDL_dynapi_overrides.h:113
SHADER_NV12_BT601
@ SHADER_NV12_BT601
Definition: SDL_shaders_d3d11.h:32
SDL_static_cast
#define SDL_static_cast(type, expression)
Definition: SDL_stdinc.h:138
offset
GLintptr offset
Definition: SDL_opengl_glext.h:541
SDL_BLENDFACTOR_DST_COLOR
@ SDL_BLENDFACTOR_DST_COLOR
Definition: SDL_blendmode.h:86
blendMode
static SDL_BlendMode blendMode
Definition: testdraw2.c:34
SDL_BLENDFACTOR_SRC_COLOR
@ SDL_BLENDFACTOR_SRC_COLOR
Definition: SDL_blendmode.h:82
SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR
@ SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR
Definition: SDL_blendmode.h:83
if
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
Definition: pixman-arm-neon-asm.h:469
SDL_Renderer::QueueCopyEx
int(* QueueCopyEx)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
Definition: SDL_sysrender.h:127
SDL_PIXELFORMAT_RGB888
@ SDL_PIXELFORMAT_RGB888
Definition: SDL_pixels.h:239
SDL_AllocateRenderVertices
void * SDL_AllocateRenderVertices(SDL_Renderer *renderer, const size_t numbytes, const size_t alignment, size_t *offset)
Definition: SDL_render.c:263
SDL_Renderer::RunCommandQueue
int(* RunCommandQueue)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
Definition: SDL_sysrender.h:130
SDL_PIXELFORMAT_NV21
@ SDL_PIXELFORMAT_NV21
Definition: SDL_pixels.h:292
SDL_FPoint::x
float x
Definition: SDL_rect.h:62
SDL_FRect::h
float h
Definition: SDL_rect.h:92
NULL
#define NULL
Definition: begin_code.h:167
b
GLboolean GLboolean GLboolean b
Definition: SDL_opengl_glext.h:1112
SDL_Renderer::SetRenderTarget
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:143
TRUE
#define TRUE
Definition: edid-parse.c:33
g
GLboolean GLboolean g
Definition: SDL_opengl_glext.h:1112
SDL_VERSION
#define SDL_VERSION(x)
Macro to determine SDL version program was compiled against.
Definition: SDL_version.h:79
SDL_SysWMinfo
Definition: SDL_syswm.h:202
SDL_BLENDFACTOR_SRC_ALPHA
@ SDL_BLENDFACTOR_SRC_ALPHA
Definition: SDL_blendmode.h:84
SDL_render_winrt.h
count
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1571
SDL_BLENDMODE_BLEND
@ SDL_BLENDMODE_BLEND
Definition: SDL_blendmode.h:44
SHADER_YUV_JPEG
@ SHADER_YUV_JPEG
Definition: SDL_shaders_d3d.h:26
SDL_RenderCommand::next
struct SDL_RenderCommand * next
Definition: SDL_sysrender.h:104
SDL_SysWMinfo::window
Window window
Definition: SDL_syswm.h:225
r
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
SDL_BlendOperation
SDL_BlendOperation
The blend operation used when combining source and destination pixel components.
Definition: SDL_blendmode.h:66
SDL_realloc
#define SDL_realloc
Definition: SDL_dynapi_overrides.h:376
viewport
static SDL_Rect viewport
Definition: testviewport.c:28
SDL_RenderDriver
Definition: SDL_sysrender.h:223
SDL_UnloadObject
#define SDL_UnloadObject
Definition: SDL_dynapi_overrides.h:234
SDL_FRect::x
float x
Definition: SDL_rect.h:89
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_Renderer::textures
SDL_Texture * textures
Definition: SDL_sysrender.h:193
SDL_Renderer::WindowEvent
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
Definition: SDL_sysrender.h:113
SDL_BlendFactor
SDL_BlendFactor
The normalized factor used to multiply pixel components.
Definition: SDL_blendmode.h:79
SDL_BLENDFACTOR_DST_ALPHA
@ SDL_BLENDFACTOR_DST_ALPHA
Definition: SDL_blendmode.h:88
SDL_FPoint::y
float y
Definition: SDL_rect.h:63
a
GLboolean GLboolean GLboolean GLboolean a
Definition: SDL_opengl_glext.h:1112
h
GLfloat GLfloat GLfloat GLfloat h
Definition: SDL_opengl_glext.h:1949
length
GLuint GLsizei GLsizei * length
Definition: SDL_opengl_glext.h:672
SDL_HINT_RENDER_DIRECT3D11_DEBUG
#define SDL_HINT_RENDER_DIRECT3D11_DEBUG
A variable controlling whether to enable Direct3D 11+'s Debug Layer.
Definition: SDL_hints.h:120
SDL_Rect::x
int x
Definition: SDL_rect.h:79
SDL_RENDERCMD_COPY
@ SDL_RENDERCMD_COPY
Definition: SDL_sysrender.h:76
SDL_BLENDFACTOR_ZERO
@ SDL_BLENDFACTOR_ZERO
Definition: SDL_blendmode.h:80
SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA
@ SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA
Definition: SDL_blendmode.h:89
shader
GLuint shader
Definition: SDL_opengl_glext.h:662
SDL_RENDERCMD_SETCLIPRECT
@ SDL_RENDERCMD_SETCLIPRECT
Definition: SDL_sysrender.h:70
result
GLuint64EXT * result
Definition: SDL_opengl_glext.h:9435
SDL_PIXELFORMAT_IYUV
@ SDL_PIXELFORMAT_IYUV
Definition: SDL_pixels.h:282
SDL_LoadObject
#define SDL_LoadObject
Definition: SDL_dynapi_overrides.h:232
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
SDL_Rect::w
int w
Definition: SDL_rect.h:80
SDL_BLENDOPERATION_MAXIMUM
@ SDL_BLENDOPERATION_MAXIMUM
Definition: SDL_blendmode.h:71
SDL_BLENDOPERATION_SUBTRACT
@ SDL_BLENDOPERATION_SUBTRACT
Definition: SDL_blendmode.h:68
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:75
row
GLenum GLenum void * row
Definition: SDL_opengl_glext.h:3141
SHADER_NV12_BT709
@ SHADER_NV12_BT709
Definition: SDL_shaders_d3d11.h:33
SDL_YUV_CONVERSION_JPEG
@ SDL_YUV_CONVERSION_JPEG
Definition: SDL_surface.h:106
dst
GLenum GLenum dst
Definition: SDL_opengl_glext.h:1740
SDL_GetWindowSize
#define SDL_GetWindowSize
Definition: SDL_dynapi_overrides.h:527
SDL_Renderer::viewport
SDL_Rect viewport
Definition: SDL_sysrender.h:174
SDL_memcpy
#define SDL_memcpy
Definition: SDL_dynapi_overrides.h:387
SDL_GetHintBoolean
#define SDL_GetHintBoolean
Definition: SDL_dynapi_overrides.h:608
event
struct _cl_event * event
Definition: SDL_opengl_glext.h:2652
D3D11_RenderDriver
SDL_RenderDriver D3D11_RenderDriver
SDL_Renderer
Definition: SDL_sysrender.h:110
done
int done
Definition: checkkeys.c:28
SDL_Renderer::QueueSetDrawColor
int(* QueueSetDrawColor)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
Definition: SDL_sysrender.h:118
SDL_FPoint
The structure that defines a point (floating point)
Definition: SDL_rect.h:61
SDL_Renderer::driverdata
void * driverdata
Definition: SDL_sysrender.h:218
SDL_FRect::y
float y
Definition: SDL_rect.h:90
SDL_RenderCommand::color
struct SDL_RenderCommand::@23::@27 color
SDL_FRect::w
float w
Definition: SDL_rect.h:91
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
color
GLuint color
Definition: SDL_opengl_glext.h:1151
window
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
SDL_Renderer::SetTextureScaleMode
void(* SetTextureScaleMode)(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode)
Definition: SDL_sysrender.h:142
SDL_RendererInfo::flags
Uint32 flags
Definition: SDL_render.h:81
SDL_Rect::y
int y
Definition: SDL_rect.h:79
SDL_memcmp
#define SDL_memcmp
Definition: SDL_dynapi_overrides.h:389
sampler
GLuint sampler
Definition: SDL_opengl_glext.h:1543
SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR
@ SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR
Definition: SDL_blendmode.h:87
SDL_Rect::h
int h
Definition: SDL_rect.h:80
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
f
GLfloat f
Definition: SDL_opengl_glext.h:1873
SDL_PushEvent
#define SDL_PushEvent
Definition: SDL_dynapi_overrides.h:125
SDL_BLENDMODE_NONE
@ SDL_BLENDMODE_NONE
Definition: SDL_blendmode.h:42
SDL_Renderer::SupportsBlendMode
SDL_bool(* SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode)
Definition: SDL_sysrender.h:115
SDL_RENDERCMD_SETVIEWPORT
@ SDL_RENDERCMD_SETVIEWPORT
Definition: SDL_sysrender.h:69
SDL_Renderer::QueueDrawLines
int(* QueueDrawLines)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
Definition: SDL_sysrender.h:121
SDL_RENDERER_PRESENTVSYNC
@ SDL_RENDERER_PRESENTVSYNC
Definition: SDL_render.h:69
SDL_ScaleMode
SDL_ScaleMode
The scaling mode for a texture.
Definition: SDL_render.h:92
SDL_RENDERCMD_DRAW_POINTS
@ SDL_RENDERCMD_DRAW_POINTS
Definition: SDL_sysrender.h:73
rect
SDL_Rect rect
Definition: testrelative.c:27
D3D11_Shader
D3D11_Shader
Definition: SDL_shaders_d3d11.h:25
SHADER_SOLID
@ SHADER_SOLID
Definition: SDL_shaders_d3d11.h:26
D3D11_CreateVertexShader
int D3D11_CreateVertexShader(ID3D11Device1 *d3dDevice, ID3D11VertexShader **vertexShader, ID3D11InputLayout **inputLayout)
SHADER_NV21_BT709
@ SHADER_NV21_BT709
Definition: SDL_shaders_d3d11.h:36
SDL_GetBlendModeDstAlphaFactor
SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:3391
SDL_Texture::next
SDL_Texture * next
Definition: SDL_sysrender.h:63
SDL_WINDOWEVENT_SIZE_CHANGED
@ SDL_WINDOWEVENT_SIZE_CHANGED
Definition: SDL_video.h:155
SDL_RenderCommand::command
SDL_RenderCommandType command
Definition: SDL_sysrender.h:82
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
SDL_RENDERCMD_NO_OP
@ SDL_RENDERCMD_NO_OP
Definition: SDL_sysrender.h:68
SDL_Renderer::QueueSetViewport
int(* QueueSetViewport)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
Definition: SDL_sysrender.h:117
SDL_PIXELFORMAT_ARGB8888
@ SDL_PIXELFORMAT_ARGB8888
Definition: SDL_pixels.h:251
WIN_SetErrorFromHRESULT
int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr)
SDL_shaders_d3d11.h
SDL_BLENDMODE_MUL
@ SDL_BLENDMODE_MUL
Definition: SDL_blendmode.h:53
start
GLuint start
Definition: SDL_opengl.h:1571
SDL_RENDERCMD_DRAW_LINES
@ SDL_RENDERCMD_DRAW_LINES
Definition: SDL_sysrender.h:74
pixels
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1572
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_FLIP_VERTICAL
@ SDL_FLIP_VERTICAL
Definition: SDL_render.h:125
SDL_Renderer::CreateTexture
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:116
SDL_RenderCommand::data
union SDL_RenderCommand::@23 data
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
bpp
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp
Definition: pixman-arm-neon-asm.h:146
SDL_RENDERCMD_FILL_RECTS
@ SDL_RENDERCMD_FILL_RECTS
Definition: SDL_sysrender.h:75
SDL_Renderer::DestroyRenderer
void(* DestroyRenderer)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:149
SDL_Renderer::LockTexture
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_sysrender.h:139
SDL_ScaleModeNearest
@ SDL_ScaleModeNearest
Definition: SDL_render.h:93
SDL_arraysize
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
first
const GLint * first
Definition: SDL_opengl_glext.h:371
SDL_Renderer::RenderReadPixels
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
Definition: SDL_sysrender.h:144
SDL_GetBlendModeSrcAlphaFactor
SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:3384
SDL_GetBlendModeColorOperation
SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode)
Definition: SDL_render.c:3377
SDL_RENDERCMD_COPY_EX
@ SDL_RENDERCMD_COPY_EX
Definition: SDL_sysrender.h:77
SDL_GetWindowWMInfo
#define SDL_GetWindowWMInfo
Definition: SDL_dynapi_overrides.h:473
SDL_BLENDOPERATION_REV_SUBTRACT
@ SDL_BLENDOPERATION_REV_SUBTRACT
Definition: SDL_blendmode.h:69
SDL_RenderCommand
Definition: SDL_sysrender.h:81
src
GLenum src
Definition: SDL_opengl_glext.h:1740
renderer
static SDL_Renderer * renderer
Definition: testaudiocapture.c:21
E_FAIL
#define E_FAIL
Definition: SDL_directx.h:58
SDL_GetBlendModeDstColorFactor
SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:3370
SDL_RenderCommand::cliprect
struct SDL_RenderCommand::@23::@25 cliprect
SDL_SysWMinfo::version
SDL_version version
Definition: SDL_syswm.h:203
SDL_BLENDFACTOR_ONE
@ SDL_BLENDFACTOR_ONE
Definition: SDL_blendmode.h:81
SDL_Renderer::info
SDL_RendererInfo info
Definition: SDL_sysrender.h:158
SDL_RENDERER_TARGETTEXTURE
@ SDL_RENDERER_TARGETTEXTURE
Definition: SDL_render.h:71
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
S_OK
#define S_OK
Definition: SDL_directx.h:47
SDL_Renderer::RenderPresent
void(* RenderPresent)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:146
SDL_BYTESPERPIXEL
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:128
SDL_snprintf
#define SDL_snprintf
Definition: SDL_dynapi_overrides.h:40
SDL_Rect
A rectangle, with the origin at the upper left (integer).
Definition: SDL_rect.h:78
SDL_LoadFunction
void * SDL_LoadFunction(void *handle, const char *name)
SDL_RendererInfo::max_texture_width
int max_texture_width
Definition: SDL_render.h:84
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA
@ SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA
Definition: SDL_blendmode.h:85
D3D11_CreatePixelShader
int D3D11_CreatePixelShader(ID3D11Device1 *d3dDevice, D3D11_Shader shader, ID3D11PixelShader **pixelShader)
SDL_Texture
Definition: SDL_sysrender.h:37
SDL_Renderer::QueueFillRects
int(* QueueFillRects)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects, int count)
Definition: SDL_sysrender.h:123
SDL_Renderer::UpdateTexture
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_sysrender.h:131
SDL_hints.h
SDL_RendererFlip
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
Definition: SDL_render.h:122
SDL_RENDER_DEVICE_RESET
@ SDL_RENDER_DEVICE_RESET
Definition: SDL_events.h:155
SDL_PIXELFORMAT_NV12
@ SDL_PIXELFORMAT_NV12
Definition: SDL_pixels.h:290
SDL_TEXTUREACCESS_TARGET
@ SDL_TEXTUREACCESS_TARGET
Definition: SDL_render.h:105
SDL_PIXELFORMAT_UNKNOWN
@ SDL_PIXELFORMAT_UNKNOWN
Definition: SDL_pixels.h:173
SDL_WindowEvent
Window state change event data (event.window.*)
Definition: SDL_events.h:196
WINRT_GlobalSwapChainBackgroundPanelNative
ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative
Definition: SDL_winrtapp_xaml.cpp:46
SDL_FRect
A rectangle, with the origin at the upper left (floating point).
Definition: SDL_rect.h:88
SDL_RenderDriver::info
SDL_RendererInfo info
Definition: SDL_sysrender.h:227
SDL_ConvertPixels
#define SDL_ConvertPixels
Definition: SDL_dynapi_overrides.h:465
FAILED
#define FAILED(x)
Definition: SDL_directx.h:54
SHADER_RGB
@ SHADER_RGB
Definition: SDL_shaders_d3d11.h:27
SDL_SysWMinfo::info
union SDL_SysWMinfo::@10 info
angle
GLfloat angle
Definition: SDL_opengl_glext.h:6100
stride
GLsizei stride
Definition: SDL_opengl_glext.h:381
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:162
SDL_GetYUVConversionModeForResolution
#define SDL_GetYUVConversionModeForResolution
Definition: SDL_dynapi_overrides.h:665
SDL_Event
General event structure.
Definition: SDL_events.h:559
SDL_Renderer::QueueDrawPoints
int(* QueueDrawPoints)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
Definition: SDL_sysrender.h:119
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
SHADER_YUV_BT601
@ SHADER_YUV_BT601
Definition: SDL_shaders_d3d.h:27
matrix
GLuint GLenum matrix
Definition: SDL_opengl_glext.h:9999
SDL_YUV_CONVERSION_BT709
@ SDL_YUV_CONVERSION_BT709
Definition: SDL_surface.h:108
SDL_malloc
#define SDL_malloc
Definition: SDL_dynapi_overrides.h:374
SDL_RENDERER_ACCELERATED
@ SDL_RENDERER_ACCELERATED
Definition: SDL_render.h:67
SDL_RendererInfo::max_texture_height
int max_texture_height
Definition: SDL_render.h:85
SDL_PIXELFORMAT_YV12
@ SDL_PIXELFORMAT_YV12
Definition: SDL_pixels.h:280
flags
GLbitfield flags
Definition: SDL_opengl_glext.h:1483
SDL_RENDERCMD_SETDRAWCOLOR
@ SDL_RENDERCMD_SETDRAWCOLOR
Definition: SDL_sysrender.h:71
SDL_Renderer::QueueCopy
int(* QueueCopy)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
Definition: SDL_sysrender.h:125
SDL_Renderer::window
SDL_Window * window
Definition: SDL_sysrender.h:161
SDL_TEXTUREACCESS_STREAMING
@ SDL_TEXTUREACCESS_STREAMING
Definition: SDL_render.h:104
texture
GLenum GLenum GLuint texture
Definition: SDL_opengl_glext.h:1181
NUM_SHADERS
@ NUM_SHADERS
Definition: SDL_shaders_d3d.h:29
SDL_RenderCommand::viewport
struct SDL_RenderCommand::@23::@24 viewport
rects
EGLSurface EGLint * rects
Definition: eglext.h:282
SDL_GetBlendModeAlphaOperation
SDL_BlendOperation SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode)
Definition: SDL_render.c:3398
SDL_loadso.h
SDL_BLENDOPERATION_MINIMUM
@ SDL_BLENDOPERATION_MINIMUM
Definition: SDL_blendmode.h:70
SDL_RenderCommand::draw
struct SDL_RenderCommand::@23::@26 draw
SHADER_NV21_JPEG
@ SHADER_NV21_JPEG
Definition: SDL_shaders_d3d11.h:34
SHADER_NV21_BT601
@ SHADER_NV21_BT601
Definition: SDL_shaders_d3d11.h:35
SDL_GetBlendModeSrcColorFactor
SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:3363
SDL_BLENDMODE_MOD
@ SDL_BLENDMODE_MOD
Definition: SDL_blendmode.h:50
i
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
SDL_RENDERCMD_CLEAR
@ SDL_RENDERCMD_CLEAR
Definition: SDL_sysrender.h:72
SDL_YUV_CONVERSION_BT601
@ SDL_YUV_CONVERSION_BT601
Definition: SDL_surface.h:107
SDL_BLENDMODE_ADD
@ SDL_BLENDMODE_ADD
Definition: SDL_blendmode.h:47
SDL_BlendMode
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
Definition: SDL_blendmode.h:41
FALSE
#define FALSE
Definition: edid-parse.c:34
SDL_Renderer::UnlockTexture
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:141
SDL_syswm.h
SDL_Renderer::DestroyTexture
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:147
SDL_Renderer::UpdateTextureYUV
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:134
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:734
SDL_FLIP_HORIZONTAL
@ SDL_FLIP_HORIZONTAL
Definition: SDL_render.h:124
SHADER_YUV_BT709
@ SHADER_YUV_BT709
Definition: SDL_shaders_d3d.h:28