SDL  2.0
SDL_render_d3d.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 #include "SDL_render.h"
24 #include "SDL_system.h"
25 
26 #if SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED
27 
28 #include "../../core/windows/SDL_windows.h"
29 
30 #include "SDL_hints.h"
31 #include "SDL_loadso.h"
32 #include "SDL_syswm.h"
33 #include "SDL_log.h"
34 #include "SDL_assert.h"
35 #include "../SDL_sysrender.h"
36 #include "../SDL_d3dmath.h"
37 #include "../../video/windows/SDL_windowsvideo.h"
38 
39 #if SDL_VIDEO_RENDER_D3D
40 #define D3D_DEBUG_INFO
41 #include <d3d9.h>
42 #endif
43 
44 #include "SDL_shaders_d3d.h"
45 
46 typedef struct
47 {
49  SDL_bool viewport_dirty;
51  SDL_BlendMode blend;
52  SDL_bool cliprect_enabled;
53  SDL_bool cliprect_enabled_dirty;
54  SDL_Rect cliprect;
55  SDL_bool cliprect_dirty;
56  SDL_bool is_copy_ex;
57  LPDIRECT3DPIXELSHADER9 shader;
58 } D3D_DrawStateCache;
59 
60 
61 /* Direct3D renderer implementation */
62 
63 typedef struct
64 {
65  void* d3dDLL;
66  IDirect3D9 *d3d;
68  UINT adapter;
69  D3DPRESENT_PARAMETERS pparams;
70  SDL_bool updateSize;
71  SDL_bool beginScene;
72  SDL_bool enableSeparateAlphaBlend;
73  D3DTEXTUREFILTERTYPE scaleMode[8];
74  IDirect3DSurface9 *defaultRenderTarget;
75  IDirect3DSurface9 *currentRenderTarget;
76  void* d3dxDLL;
77  LPDIRECT3DPIXELSHADER9 shaders[NUM_SHADERS];
78  LPDIRECT3DVERTEXBUFFER9 vertexBuffers[8];
79  size_t vertexBufferSize[8];
80  int currentVertexBuffer;
81  SDL_bool reportedVboProblem;
82  D3D_DrawStateCache drawstate;
83 } D3D_RenderData;
84 
85 typedef struct
86 {
87  SDL_bool dirty;
88  int w, h;
89  DWORD usage;
90  Uint32 format;
91  D3DFORMAT d3dfmt;
92  IDirect3DTexture9 *texture;
93  IDirect3DTexture9 *staging;
94 } D3D_TextureRep;
95 
96 typedef struct
97 {
98  D3D_TextureRep texture;
99  D3DTEXTUREFILTERTYPE scaleMode;
100 
101  /* YV12 texture support */
102  SDL_bool yuv;
103  D3D_TextureRep utexture;
104  D3D_TextureRep vtexture;
105  Uint8 *pixels;
106  int pitch;
107  SDL_Rect locked_rect;
108 } D3D_TextureData;
109 
110 typedef struct
111 {
112  float x, y, z;
113  DWORD color;
114  float u, v;
115 } Vertex;
116 
117 static int
118 D3D_SetError(const char *prefix, HRESULT result)
119 {
120  const char *error;
121 
122  switch (result) {
123  case D3DERR_WRONGTEXTUREFORMAT:
124  error = "WRONGTEXTUREFORMAT";
125  break;
126  case D3DERR_UNSUPPORTEDCOLOROPERATION:
127  error = "UNSUPPORTEDCOLOROPERATION";
128  break;
129  case D3DERR_UNSUPPORTEDCOLORARG:
130  error = "UNSUPPORTEDCOLORARG";
131  break;
132  case D3DERR_UNSUPPORTEDALPHAOPERATION:
133  error = "UNSUPPORTEDALPHAOPERATION";
134  break;
135  case D3DERR_UNSUPPORTEDALPHAARG:
136  error = "UNSUPPORTEDALPHAARG";
137  break;
138  case D3DERR_TOOMANYOPERATIONS:
139  error = "TOOMANYOPERATIONS";
140  break;
141  case D3DERR_CONFLICTINGTEXTUREFILTER:
142  error = "CONFLICTINGTEXTUREFILTER";
143  break;
144  case D3DERR_UNSUPPORTEDFACTORVALUE:
145  error = "UNSUPPORTEDFACTORVALUE";
146  break;
147  case D3DERR_CONFLICTINGRENDERSTATE:
148  error = "CONFLICTINGRENDERSTATE";
149  break;
150  case D3DERR_UNSUPPORTEDTEXTUREFILTER:
151  error = "UNSUPPORTEDTEXTUREFILTER";
152  break;
153  case D3DERR_CONFLICTINGTEXTUREPALETTE:
154  error = "CONFLICTINGTEXTUREPALETTE";
155  break;
156  case D3DERR_DRIVERINTERNALERROR:
157  error = "DRIVERINTERNALERROR";
158  break;
159  case D3DERR_NOTFOUND:
160  error = "NOTFOUND";
161  break;
162  case D3DERR_MOREDATA:
163  error = "MOREDATA";
164  break;
165  case D3DERR_DEVICELOST:
166  error = "DEVICELOST";
167  break;
168  case D3DERR_DEVICENOTRESET:
169  error = "DEVICENOTRESET";
170  break;
171  case D3DERR_NOTAVAILABLE:
172  error = "NOTAVAILABLE";
173  break;
174  case D3DERR_OUTOFVIDEOMEMORY:
175  error = "OUTOFVIDEOMEMORY";
176  break;
177  case D3DERR_INVALIDDEVICE:
178  error = "INVALIDDEVICE";
179  break;
180  case D3DERR_INVALIDCALL:
181  error = "INVALIDCALL";
182  break;
183  case D3DERR_DRIVERINVALIDCALL:
184  error = "DRIVERINVALIDCALL";
185  break;
186  case D3DERR_WASSTILLDRAWING:
187  error = "WASSTILLDRAWING";
188  break;
189  default:
190  error = "UNKNOWN";
191  break;
192  }
193  return SDL_SetError("%s: %s", prefix, error);
194 }
195 
196 static D3DFORMAT
197 PixelFormatToD3DFMT(Uint32 format)
198 {
199  switch (format) {
201  return D3DFMT_R5G6B5;
203  return D3DFMT_X8R8G8B8;
205  return D3DFMT_A8R8G8B8;
210  return D3DFMT_L8;
211  default:
212  return D3DFMT_UNKNOWN;
213  }
214 }
215 
216 static Uint32
217 D3DFMTToPixelFormat(D3DFORMAT format)
218 {
219  switch (format) {
220  case D3DFMT_R5G6B5:
221  return SDL_PIXELFORMAT_RGB565;
222  case D3DFMT_X8R8G8B8:
223  return SDL_PIXELFORMAT_RGB888;
224  case D3DFMT_A8R8G8B8:
226  default:
228  }
229 }
230 
231 static void
232 D3D_InitRenderState(D3D_RenderData *data)
233 {
234  D3DMATRIX matrix;
235 
236  IDirect3DDevice9 *device = data->device;
237  IDirect3DDevice9_SetPixelShader(device, NULL);
238  IDirect3DDevice9_SetTexture(device, 0, NULL);
239  IDirect3DDevice9_SetTexture(device, 1, NULL);
240  IDirect3DDevice9_SetTexture(device, 2, NULL);
241  IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
242  IDirect3DDevice9_SetVertexShader(device, NULL);
243  IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
244  IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
245  IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
246 
247  /* Enable color modulation by diffuse color */
248  IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP,
249  D3DTOP_MODULATE);
250  IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1,
251  D3DTA_TEXTURE);
252  IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2,
253  D3DTA_DIFFUSE);
254 
255  /* Enable alpha modulation by diffuse alpha */
256  IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP,
257  D3DTOP_MODULATE);
258  IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1,
259  D3DTA_TEXTURE);
260  IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG2,
261  D3DTA_DIFFUSE);
262 
263  /* Enable separate alpha blend function, if possible */
264  if (data->enableSeparateAlphaBlend) {
265  IDirect3DDevice9_SetRenderState(device, D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
266  }
267 
268  /* Disable second texture stage, since we're done */
269  IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP,
270  D3DTOP_DISABLE);
271  IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP,
272  D3DTOP_DISABLE);
273 
274  /* Set an identity world and view matrix */
275  SDL_zero(matrix);
276  matrix.m[0][0] = 1.0f;
277  matrix.m[1][1] = 1.0f;
278  matrix.m[2][2] = 1.0f;
279  matrix.m[3][3] = 1.0f;
280  IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &matrix);
281  IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &matrix);
282 
283  /* Reset our current scale mode */
284  SDL_memset(data->scaleMode, 0xFF, sizeof(data->scaleMode));
285 
286  /* Start the render with beginScene */
287  data->beginScene = SDL_TRUE;
288 }
289 
290 static int D3D_Reset(SDL_Renderer * renderer);
291 
292 static int
293 D3D_ActivateRenderer(SDL_Renderer * renderer)
294 {
295  D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
296  HRESULT result;
297 
298  if (data->updateSize) {
300  int w, h;
301  Uint32 window_flags = SDL_GetWindowFlags(window);
302 
304  data->pparams.BackBufferWidth = w;
305  data->pparams.BackBufferHeight = h;
306  if (window_flags & SDL_WINDOW_FULLSCREEN && (window_flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
307  SDL_DisplayMode fullscreen_mode;
308  SDL_GetWindowDisplayMode(window, &fullscreen_mode);
309  data->pparams.Windowed = FALSE;
310  data->pparams.BackBufferFormat = PixelFormatToD3DFMT(fullscreen_mode.format);
311  data->pparams.FullScreen_RefreshRateInHz = fullscreen_mode.refresh_rate;
312  } else {
313  data->pparams.Windowed = TRUE;
314  data->pparams.BackBufferFormat = D3DFMT_UNKNOWN;
315  data->pparams.FullScreen_RefreshRateInHz = 0;
316  }
317  if (D3D_Reset(renderer) < 0) {
318  return -1;
319  }
320 
321  data->updateSize = SDL_FALSE;
322  }
323  if (data->beginScene) {
324  result = IDirect3DDevice9_BeginScene(data->device);
325  if (result == D3DERR_DEVICELOST) {
326  if (D3D_Reset(renderer) < 0) {
327  return -1;
328  }
329  result = IDirect3DDevice9_BeginScene(data->device);
330  }
331  if (FAILED(result)) {
332  return D3D_SetError("BeginScene()", result);
333  }
334  data->beginScene = SDL_FALSE;
335  }
336  return 0;
337 }
338 
339 static void
340 D3D_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
341 {
342  D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
343 
345  data->updateSize = SDL_TRUE;
346  }
347 }
348 
349 static D3DBLEND GetBlendFunc(SDL_BlendFactor factor)
350 {
351  switch (factor) {
353  return D3DBLEND_ZERO;
354  case SDL_BLENDFACTOR_ONE:
355  return D3DBLEND_ONE;
357  return D3DBLEND_SRCCOLOR;
359  return D3DBLEND_INVSRCCOLOR;
361  return D3DBLEND_SRCALPHA;
363  return D3DBLEND_INVSRCALPHA;
365  return D3DBLEND_DESTCOLOR;
367  return D3DBLEND_INVDESTCOLOR;
369  return D3DBLEND_DESTALPHA;
371  return D3DBLEND_INVDESTALPHA;
372  default:
373  return (D3DBLEND)0;
374  }
375 }
376 
377 static SDL_bool
378 D3D_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
379 {
380  D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
387 
388  if (!GetBlendFunc(srcColorFactor) || !GetBlendFunc(srcAlphaFactor) ||
389  !GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor)) {
390  return SDL_FALSE;
391  }
392  if ((srcColorFactor != srcAlphaFactor || dstColorFactor != dstAlphaFactor) && !data->enableSeparateAlphaBlend) {
393  return SDL_FALSE;
394  }
395  if (colorOperation != SDL_BLENDOPERATION_ADD || alphaOperation != SDL_BLENDOPERATION_ADD) {
396  return SDL_FALSE;
397  }
398  return SDL_TRUE;
399 }
400 
401 static int
402 D3D_CreateTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, DWORD usage, Uint32 format, D3DFORMAT d3dfmt, int w, int h)
403 {
404  HRESULT result;
405 
406  texture->dirty = SDL_FALSE;
407  texture->w = w;
408  texture->h = h;
409  texture->usage = usage;
410  texture->format = format;
411  texture->d3dfmt = d3dfmt;
412 
413  result = IDirect3DDevice9_CreateTexture(device, w, h, 1, usage,
414  PixelFormatToD3DFMT(format),
415  D3DPOOL_DEFAULT, &texture->texture, NULL);
416  if (FAILED(result)) {
417  return D3D_SetError("CreateTexture(D3DPOOL_DEFAULT)", result);
418  }
419  return 0;
420 }
421 
422 
423 static int
424 D3D_CreateStagingTexture(IDirect3DDevice9 *device, D3D_TextureRep *texture)
425 {
426  HRESULT result;
427 
428  if (texture->staging == NULL) {
429  result = IDirect3DDevice9_CreateTexture(device, texture->w, texture->h, 1, 0,
430  texture->d3dfmt, D3DPOOL_SYSTEMMEM, &texture->staging, NULL);
431  if (FAILED(result)) {
432  return D3D_SetError("CreateTexture(D3DPOOL_SYSTEMMEM)", result);
433  }
434  }
435  return 0;
436 }
437 
438 static int
439 D3D_RecreateTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture)
440 {
441  if (texture->texture) {
442  IDirect3DTexture9_Release(texture->texture);
443  texture->texture = NULL;
444  }
445  if (texture->staging) {
446  IDirect3DTexture9_AddDirtyRect(texture->staging, NULL);
447  texture->dirty = SDL_TRUE;
448  }
449  return 0;
450 }
451 
452 static int
453 D3D_UpdateTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, int x, int y, int w, int h, const void *pixels, int pitch)
454 {
455  RECT d3drect;
456  D3DLOCKED_RECT locked;
457  const Uint8 *src;
458  Uint8 *dst;
459  int row, length;
460  HRESULT result;
461 
462  if (D3D_CreateStagingTexture(device, texture) < 0) {
463  return -1;
464  }
465 
466  d3drect.left = x;
467  d3drect.right = x + w;
468  d3drect.top = y;
469  d3drect.bottom = y + h;
470 
471  result = IDirect3DTexture9_LockRect(texture->staging, 0, &locked, &d3drect, 0);
472  if (FAILED(result)) {
473  return D3D_SetError("LockRect()", result);
474  }
475 
476  src = (const Uint8 *)pixels;
477  dst = (Uint8 *)locked.pBits;
478  length = w * SDL_BYTESPERPIXEL(texture->format);
479  if (length == pitch && length == locked.Pitch) {
481  } else {
482  if (length > pitch) {
483  length = pitch;
484  }
485  if (length > locked.Pitch) {
486  length = locked.Pitch;
487  }
488  for (row = 0; row < h; ++row) {
490  src += pitch;
491  dst += locked.Pitch;
492  }
493  }
494  result = IDirect3DTexture9_UnlockRect(texture->staging, 0);
495  if (FAILED(result)) {
496  return D3D_SetError("UnlockRect()", result);
497  }
498  texture->dirty = SDL_TRUE;
499 
500  return 0;
501 }
502 
503 static void
504 D3D_DestroyTextureRep(D3D_TextureRep *texture)
505 {
506  if (texture->texture) {
507  IDirect3DTexture9_Release(texture->texture);
508  texture->texture = NULL;
509  }
510  if (texture->staging) {
511  IDirect3DTexture9_Release(texture->staging);
512  texture->staging = NULL;
513  }
514 }
515 
516 static int
517 D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
518 {
519  D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
520  D3D_TextureData *texturedata;
521  DWORD usage;
522 
523  texturedata = (D3D_TextureData *) SDL_calloc(1, sizeof(*texturedata));
524  if (!texturedata) {
525  return SDL_OutOfMemory();
526  }
527  texturedata->scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? D3DTEXF_POINT : D3DTEXF_LINEAR;
528 
529  texture->driverdata = texturedata;
530 
531  if (texture->access == SDL_TEXTUREACCESS_TARGET) {
532  usage = D3DUSAGE_RENDERTARGET;
533  } else {
534  usage = 0;
535  }
536 
537  if (D3D_CreateTextureRep(data->device, &texturedata->texture, usage, texture->format, PixelFormatToD3DFMT(texture->format), texture->w, texture->h) < 0) {
538  return -1;
539  }
540 
541  if (texture->format == SDL_PIXELFORMAT_YV12 ||
542  texture->format == SDL_PIXELFORMAT_IYUV) {
543  texturedata->yuv = SDL_TRUE;
544 
545  if (D3D_CreateTextureRep(data->device, &texturedata->utexture, usage, texture->format, PixelFormatToD3DFMT(texture->format), (texture->w + 1) / 2, (texture->h + 1) / 2) < 0) {
546  return -1;
547  }
548 
549  if (D3D_CreateTextureRep(data->device, &texturedata->vtexture, usage, texture->format, PixelFormatToD3DFMT(texture->format), (texture->w + 1) / 2, (texture->h + 1) / 2) < 0) {
550  return -1;
551  }
552  }
553  return 0;
554 }
555 
556 static int
557 D3D_RecreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
558 {
559  D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata;
560  D3D_TextureData *texturedata = (D3D_TextureData *)texture->driverdata;
561 
562  if (!texturedata) {
563  return 0;
564  }
565 
566  if (D3D_RecreateTextureRep(data->device, &texturedata->texture) < 0) {
567  return -1;
568  }
569 
570  if (texturedata->yuv) {
571  if (D3D_RecreateTextureRep(data->device, &texturedata->utexture) < 0) {
572  return -1;
573  }
574 
575  if (D3D_RecreateTextureRep(data->device, &texturedata->vtexture) < 0) {
576  return -1;
577  }
578  }
579  return 0;
580 }
581 
582 static int
583 D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
584  const SDL_Rect * rect, const void *pixels, int pitch)
585 {
586  D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata;
587  D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata;
588 
589  if (!texturedata) {
590  SDL_SetError("Texture is not currently available");
591  return -1;
592  }
593 
594  if (D3D_UpdateTextureRep(data->device, &texturedata->texture, rect->x, rect->y, rect->w, rect->h, pixels, pitch) < 0) {
595  return -1;
596  }
597 
598  if (texturedata->yuv) {
599  /* Skip to the correct offset into the next texture */
600  pixels = (const void*)((const Uint8*)pixels + rect->h * pitch);
601 
602  if (D3D_UpdateTextureRep(data->device, texture->format == SDL_PIXELFORMAT_YV12 ? &texturedata->vtexture : &texturedata->utexture, rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, pixels, (pitch + 1) / 2) < 0) {
603  return -1;
604  }
605 
606  /* Skip to the correct offset into the next texture */
607  pixels = (const void*)((const Uint8*)pixels + ((rect->h + 1) / 2) * ((pitch + 1) / 2));
608  if (D3D_UpdateTextureRep(data->device, texture->format == SDL_PIXELFORMAT_YV12 ? &texturedata->utexture : &texturedata->vtexture, rect->x / 2, (rect->y + 1) / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, pixels, (pitch + 1) / 2) < 0) {
609  return -1;
610  }
611  }
612  return 0;
613 }
614 
615 static int
616 D3D_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
617  const SDL_Rect * rect,
618  const Uint8 *Yplane, int Ypitch,
619  const Uint8 *Uplane, int Upitch,
620  const Uint8 *Vplane, int Vpitch)
621 {
622  D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata;
623  D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata;
624 
625  if (!texturedata) {
626  SDL_SetError("Texture is not currently available");
627  return -1;
628  }
629 
630  if (D3D_UpdateTextureRep(data->device, &texturedata->texture, rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch) < 0) {
631  return -1;
632  }
633  if (D3D_UpdateTextureRep(data->device, &texturedata->utexture, rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, Uplane, Upitch) < 0) {
634  return -1;
635  }
636  if (D3D_UpdateTextureRep(data->device, &texturedata->vtexture, rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, Vplane, Vpitch) < 0) {
637  return -1;
638  }
639  return 0;
640 }
641 
642 static int
643 D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
644  const SDL_Rect * rect, void **pixels, int *pitch)
645 {
646  D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata;
647  D3D_TextureData *texturedata = (D3D_TextureData *)texture->driverdata;
648  IDirect3DDevice9 *device = data->device;
649 
650  if (!texturedata) {
651  SDL_SetError("Texture is not currently available");
652  return -1;
653  }
654 
655  texturedata->locked_rect = *rect;
656 
657  if (texturedata->yuv) {
658  /* It's more efficient to upload directly... */
659  if (!texturedata->pixels) {
660  texturedata->pitch = texture->w;
661  texturedata->pixels = (Uint8 *)SDL_malloc((texture->h * texturedata->pitch * 3) / 2);
662  if (!texturedata->pixels) {
663  return SDL_OutOfMemory();
664  }
665  }
666  *pixels =
667  (void *) ((Uint8 *) texturedata->pixels + rect->y * texturedata->pitch +
668  rect->x * SDL_BYTESPERPIXEL(texture->format));
669  *pitch = texturedata->pitch;
670  } else {
671  RECT d3drect;
672  D3DLOCKED_RECT locked;
673  HRESULT result;
674 
675  if (D3D_CreateStagingTexture(device, &texturedata->texture) < 0) {
676  return -1;
677  }
678 
679  d3drect.left = rect->x;
680  d3drect.right = rect->x + rect->w;
681  d3drect.top = rect->y;
682  d3drect.bottom = rect->y + rect->h;
683 
684  result = IDirect3DTexture9_LockRect(texturedata->texture.staging, 0, &locked, &d3drect, 0);
685  if (FAILED(result)) {
686  return D3D_SetError("LockRect()", result);
687  }
688  *pixels = locked.pBits;
689  *pitch = locked.Pitch;
690  }
691  return 0;
692 }
693 
694 static void
695 D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
696 {
697  D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata;
698  D3D_TextureData *texturedata = (D3D_TextureData *)texture->driverdata;
699 
700  if (!texturedata) {
701  return;
702  }
703 
704  if (texturedata->yuv) {
705  const SDL_Rect *rect = &texturedata->locked_rect;
706  void *pixels =
707  (void *) ((Uint8 *) texturedata->pixels + rect->y * texturedata->pitch +
708  rect->x * SDL_BYTESPERPIXEL(texture->format));
709  D3D_UpdateTexture(renderer, texture, rect, pixels, texturedata->pitch);
710  } else {
711  IDirect3DTexture9_UnlockRect(texturedata->texture.staging, 0);
712  texturedata->texture.dirty = SDL_TRUE;
713  if (data->drawstate.texture == texture) {
714  data->drawstate.texture = NULL;
715  data->drawstate.shader = NULL;
716  IDirect3DDevice9_SetPixelShader(data->device, NULL);
717  IDirect3DDevice9_SetTexture(data->device, 0, NULL);
718  if (texturedata->yuv) {
719  IDirect3DDevice9_SetTexture(data->device, 1, NULL);
720  IDirect3DDevice9_SetTexture(data->device, 2, NULL);
721  }
722  }
723  }
724 }
725 
726 static void
727 D3D_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_ScaleMode scaleMode)
728 {
729  D3D_TextureData *texturedata = (D3D_TextureData *)texture->driverdata;
730 
731  if (!texturedata) {
732  return;
733  }
734 
735  texturedata->scaleMode = (scaleMode == SDL_ScaleModeNearest) ? D3DTEXF_POINT : D3DTEXF_LINEAR;
736 }
737 
738 static int
739 D3D_SetRenderTargetInternal(SDL_Renderer * renderer, SDL_Texture * texture)
740 {
741  D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
742  D3D_TextureData *texturedata;
743  D3D_TextureRep *texturerep;
744  HRESULT result;
745  IDirect3DDevice9 *device = data->device;
746 
747  /* Release the previous render target if it wasn't the default one */
748  if (data->currentRenderTarget != NULL) {
749  IDirect3DSurface9_Release(data->currentRenderTarget);
750  data->currentRenderTarget = NULL;
751  }
752 
753  if (texture == NULL) {
754  IDirect3DDevice9_SetRenderTarget(data->device, 0, data->defaultRenderTarget);
755  return 0;
756  }
757 
758  texturedata = (D3D_TextureData *)texture->driverdata;
759  if (!texturedata) {
760  SDL_SetError("Texture is not currently available");
761  return -1;
762  }
763 
764  /* Make sure the render target is updated if it was locked and written to */
765  texturerep = &texturedata->texture;
766  if (texturerep->dirty && texturerep->staging) {
767  if (!texturerep->texture) {
768  result = IDirect3DDevice9_CreateTexture(device, texturerep->w, texturerep->h, 1, texturerep->usage,
769  PixelFormatToD3DFMT(texturerep->format), D3DPOOL_DEFAULT, &texturerep->texture, NULL);
770  if (FAILED(result)) {
771  return D3D_SetError("CreateTexture(D3DPOOL_DEFAULT)", result);
772  }
773  }
774 
775  result = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texturerep->staging, (IDirect3DBaseTexture9 *)texturerep->texture);
776  if (FAILED(result)) {
777  return D3D_SetError("UpdateTexture()", result);
778  }
779  texturerep->dirty = SDL_FALSE;
780  }
781 
782  result = IDirect3DTexture9_GetSurfaceLevel(texturedata->texture.texture, 0, &data->currentRenderTarget);
783  if(FAILED(result)) {
784  return D3D_SetError("GetSurfaceLevel()", result);
785  }
786  result = IDirect3DDevice9_SetRenderTarget(data->device, 0, data->currentRenderTarget);
787  if(FAILED(result)) {
788  return D3D_SetError("SetRenderTarget()", result);
789  }
790 
791  return 0;
792 }
793 
794 static int
795 D3D_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
796 {
797  if (D3D_ActivateRenderer(renderer) < 0) {
798  return -1;
799  }
800 
801  return D3D_SetRenderTargetInternal(renderer, texture);
802 }
803 
804 
805 static int
806 D3D_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd)
807 {
808  return 0; /* nothing to do in this backend. */
809 }
810 
811 static int
812 D3D_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
813 {
814  const DWORD color = D3DCOLOR_ARGB(cmd->data.draw.a, cmd->data.draw.r, cmd->data.draw.g, cmd->data.draw.b);
815  const size_t vertslen = count * sizeof (Vertex);
816  Vertex *verts = (Vertex *) SDL_AllocateRenderVertices(renderer, vertslen, 0, &cmd->data.draw.first);
817  int i;
818 
819  if (!verts) {
820  return -1;
821  }
822 
823  SDL_memset(verts, '\0', vertslen);
824  cmd->data.draw.count = count;
825 
826  for (i = 0; i < count; i++, verts++, points++) {
827  verts->x = points->x;
828  verts->y = points->y;
829  verts->color = color;
830  }
831 
832  return 0;
833 }
834 
835 static int
836 D3D_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
837 {
838  const DWORD color = D3DCOLOR_ARGB(cmd->data.draw.a, cmd->data.draw.r, cmd->data.draw.g, cmd->data.draw.b);
839  const size_t vertslen = count * sizeof (Vertex) * 4;
840  Vertex *verts = (Vertex *) SDL_AllocateRenderVertices(renderer, vertslen, 0, &cmd->data.draw.first);
841  int i;
842 
843  if (!verts) {
844  return -1;
845  }
846 
847  SDL_memset(verts, '\0', vertslen);
848  cmd->data.draw.count = count;
849 
850  for (i = 0; i < count; i++) {
851  const SDL_FRect *rect = &rects[i];
852  const float minx = rect->x;
853  const float maxx = rect->x + rect->w;
854  const float miny = rect->y;
855  const float maxy = rect->y + rect->h;
856 
857  verts->x = minx;
858  verts->y = miny;
859  verts->color = color;
860  verts++;
861 
862  verts->x = maxx;
863  verts->y = miny;
864  verts->color = color;
865  verts++;
866 
867  verts->x = maxx;
868  verts->y = maxy;
869  verts->color = color;
870  verts++;
871 
872  verts->x = minx;
873  verts->y = maxy;
874  verts->color = color;
875  verts++;
876  }
877 
878  return 0;
879 }
880 
881 static int
883  const SDL_Rect * srcrect, const SDL_FRect * dstrect)
884 {
885  const DWORD color = D3DCOLOR_ARGB(cmd->data.draw.a, cmd->data.draw.r, cmd->data.draw.g, cmd->data.draw.b);
886  float minx, miny, maxx, maxy;
887  float minu, maxu, minv, maxv;
888  const size_t vertslen = sizeof (Vertex) * 4;
889  Vertex *verts = (Vertex *) SDL_AllocateRenderVertices(renderer, vertslen, 0, &cmd->data.draw.first);
890 
891  if (!verts) {
892  return -1;
893  }
894 
895  cmd->data.draw.count = 1;
896 
897  minx = dstrect->x - 0.5f;
898  miny = dstrect->y - 0.5f;
899  maxx = dstrect->x + dstrect->w - 0.5f;
900  maxy = dstrect->y + dstrect->h - 0.5f;
901 
902  minu = (float) srcrect->x / texture->w;
903  maxu = (float) (srcrect->x + srcrect->w) / texture->w;
904  minv = (float) srcrect->y / texture->h;
905  maxv = (float) (srcrect->y + srcrect->h) / texture->h;
906 
907  verts->x = minx;
908  verts->y = miny;
909  verts->z = 0.0f;
910  verts->color = color;
911  verts->u = minu;
912  verts->v = minv;
913  verts++;
914 
915  verts->x = maxx;
916  verts->y = miny;
917  verts->z = 0.0f;
918  verts->color = color;
919  verts->u = maxu;
920  verts->v = minv;
921  verts++;
922 
923  verts->x = maxx;
924  verts->y = maxy;
925  verts->z = 0.0f;
926  verts->color = color;
927  verts->u = maxu;
928  verts->v = maxv;
929  verts++;
930 
931  verts->x = minx;
932  verts->y = maxy;
933  verts->z = 0.0f;
934  verts->color = color;
935  verts->u = minu;
936  verts->v = maxv;
937  verts++;
938 
939  return 0;
940 }
941 
942 static int
943 D3D_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
944  const SDL_Rect * srcquad, const SDL_FRect * dstrect,
945  const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
946 {
947  const DWORD color = D3DCOLOR_ARGB(cmd->data.draw.a, cmd->data.draw.r, cmd->data.draw.g, cmd->data.draw.b);
948  float minx, miny, maxx, maxy;
949  float minu, maxu, minv, maxv;
950  const size_t vertslen = sizeof (Vertex) * 5;
951  Vertex *verts = (Vertex *) SDL_AllocateRenderVertices(renderer, vertslen, 0, &cmd->data.draw.first);
952 
953  if (!verts) {
954  return -1;
955  }
956 
957  cmd->data.draw.count = 1;
958 
959  minx = -center->x;
960  maxx = dstrect->w - center->x;
961  miny = -center->y;
962  maxy = dstrect->h - center->y;
963 
964  if (flip & SDL_FLIP_HORIZONTAL) {
965  minu = (float) (srcquad->x + srcquad->w) / texture->w;
966  maxu = (float) srcquad->x / texture->w;
967  } else {
968  minu = (float) srcquad->x / texture->w;
969  maxu = (float) (srcquad->x + srcquad->w) / texture->w;
970  }
971 
972  if (flip & SDL_FLIP_VERTICAL) {
973  minv = (float) (srcquad->y + srcquad->h) / texture->h;
974  maxv = (float) srcquad->y / texture->h;
975  } else {
976  minv = (float) srcquad->y / texture->h;
977  maxv = (float) (srcquad->y + srcquad->h) / texture->h;
978  }
979 
980  verts->x = minx;
981  verts->y = miny;
982  verts->z = 0.0f;
983  verts->color = color;
984  verts->u = minu;
985  verts->v = minv;
986  verts++;
987 
988  verts->x = maxx;
989  verts->y = miny;
990  verts->z = 0.0f;
991  verts->color = color;
992  verts->u = maxu;
993  verts->v = minv;
994  verts++;
995 
996  verts->x = maxx;
997  verts->y = maxy;
998  verts->z = 0.0f;
999  verts->color = color;
1000  verts->u = maxu;
1001  verts->v = maxv;
1002  verts++;
1003 
1004  verts->x = minx;
1005  verts->y = maxy;
1006  verts->z = 0.0f;
1007  verts->color = color;
1008  verts->u = minu;
1009  verts->v = maxv;
1010  verts++;
1011 
1012  verts->x = dstrect->x + center->x - 0.5f; /* X translation */
1013  verts->y = dstrect->y + center->y - 0.5f; /* Y translation */
1014  verts->z = (float)(M_PI * (float) angle / 180.0f); /* rotation */
1015  verts->color = 0;
1016  verts->u = 0.0f;
1017  verts->v = 0.0f;
1018  verts++;
1019 
1020  return 0;
1021 }
1022 
1023 static int
1024 UpdateDirtyTexture(IDirect3DDevice9 *device, D3D_TextureRep *texture)
1025 {
1026  if (texture->dirty && texture->staging) {
1027  HRESULT result;
1028  if (!texture->texture) {
1029  result = IDirect3DDevice9_CreateTexture(device, texture->w, texture->h, 1, texture->usage,
1030  PixelFormatToD3DFMT(texture->format), D3DPOOL_DEFAULT, &texture->texture, NULL);
1031  if (FAILED(result)) {
1032  return D3D_SetError("CreateTexture(D3DPOOL_DEFAULT)", result);
1033  }
1034  }
1035 
1036  result = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture->staging, (IDirect3DBaseTexture9 *)texture->texture);
1037  if (FAILED(result)) {
1038  return D3D_SetError("UpdateTexture()", result);
1039  }
1040  texture->dirty = SDL_FALSE;
1041  }
1042  return 0;
1043 }
1044 
1045 static int
1046 BindTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, DWORD sampler)
1047 {
1048  HRESULT result;
1049  UpdateDirtyTexture(device, texture);
1050  result = IDirect3DDevice9_SetTexture(device, sampler, (IDirect3DBaseTexture9 *)texture->texture);
1051  if (FAILED(result)) {
1052  return D3D_SetError("SetTexture()", result);
1053  }
1054  return 0;
1055 }
1056 
1057 static void
1058 UpdateTextureScaleMode(D3D_RenderData *data, D3D_TextureData *texturedata, unsigned index)
1059 {
1060  if (texturedata->scaleMode != data->scaleMode[index]) {
1061  IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_MINFILTER,
1062  texturedata->scaleMode);
1063  IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_MAGFILTER,
1064  texturedata->scaleMode);
1065  IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_ADDRESSU,
1066  D3DTADDRESS_CLAMP);
1067  IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_ADDRESSV,
1068  D3DTADDRESS_CLAMP);
1069  data->scaleMode[index] = texturedata->scaleMode;
1070  }
1071 }
1072 
1073 static int
1074 SetupTextureState(D3D_RenderData *data, SDL_Texture * texture, LPDIRECT3DPIXELSHADER9 *shader)
1075 {
1076  D3D_TextureData *texturedata = (D3D_TextureData *)texture->driverdata;
1077 
1078  SDL_assert(*shader == NULL);
1079 
1080  if (!texturedata) {
1081  SDL_SetError("Texture is not currently available");
1082  return -1;
1083  }
1084 
1085  UpdateTextureScaleMode(data, texturedata, 0);
1086 
1087  if (BindTextureRep(data->device, &texturedata->texture, 0) < 0) {
1088  return -1;
1089  }
1090 
1091  if (texturedata->yuv) {
1094  *shader = data->shaders[SHADER_YUV_JPEG];
1095  break;
1097  *shader = data->shaders[SHADER_YUV_BT601];
1098  break;
1100  *shader = data->shaders[SHADER_YUV_BT709];
1101  break;
1102  default:
1103  return SDL_SetError("Unsupported YUV conversion mode");
1104  }
1105 
1106  UpdateTextureScaleMode(data, texturedata, 1);
1107  UpdateTextureScaleMode(data, texturedata, 2);
1108 
1109  if (BindTextureRep(data->device, &texturedata->utexture, 1) < 0) {
1110  return -1;
1111  }
1112  if (BindTextureRep(data->device, &texturedata->vtexture, 2) < 0) {
1113  return -1;
1114  }
1115  }
1116  return 0;
1117 }
1118 
1119 static int
1120 SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
1121 {
1122  const SDL_bool was_copy_ex = data->drawstate.is_copy_ex;
1123  const SDL_bool is_copy_ex = (cmd->command == SDL_RENDERCMD_COPY_EX);
1124  SDL_Texture *texture = cmd->data.draw.texture;
1125  const SDL_BlendMode blend = cmd->data.draw.blend;
1126 
1127  if (texture != data->drawstate.texture) {
1128  D3D_TextureData *oldtexturedata = data->drawstate.texture ? (D3D_TextureData *) data->drawstate.texture->driverdata : NULL;
1129  D3D_TextureData *newtexturedata = texture ? (D3D_TextureData *) texture->driverdata : NULL;
1130  LPDIRECT3DPIXELSHADER9 shader = NULL;
1131 
1132  /* disable any enabled textures we aren't going to use, let SetupTextureState() do the rest. */
1133  if (texture == NULL) {
1134  IDirect3DDevice9_SetTexture(data->device, 0, NULL);
1135  }
1136  if ((!newtexturedata || !newtexturedata->yuv) && (oldtexturedata && oldtexturedata->yuv)) {
1137  IDirect3DDevice9_SetTexture(data->device, 1, NULL);
1138  IDirect3DDevice9_SetTexture(data->device, 2, NULL);
1139  }
1140  if (texture && SetupTextureState(data, texture, &shader) < 0) {
1141  return -1;
1142  }
1143 
1144  if (shader != data->drawstate.shader) {
1145  const HRESULT result = IDirect3DDevice9_SetPixelShader(data->device, shader);
1146  if (FAILED(result)) {
1147  return D3D_SetError("IDirect3DDevice9_SetPixelShader()", result);
1148  }
1149  data->drawstate.shader = shader;
1150  }
1151 
1152  data->drawstate.texture = texture;
1153  } else if (texture) {
1154  D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata;
1155  UpdateDirtyTexture(data->device, &texturedata->texture);
1156  if (texturedata->yuv) {
1157  UpdateDirtyTexture(data->device, &texturedata->utexture);
1158  UpdateDirtyTexture(data->device, &texturedata->vtexture);
1159  }
1160  }
1161 
1162  if (blend != data->drawstate.blend) {
1163  if (blend == SDL_BLENDMODE_NONE) {
1164  IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE, FALSE);
1165  } else {
1166  IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE, TRUE);
1167  IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND,
1168  GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blend)));
1169  IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
1170  GetBlendFunc(SDL_GetBlendModeDstColorFactor(blend)));
1171  if (data->enableSeparateAlphaBlend) {
1172  IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLENDALPHA,
1173  GetBlendFunc(SDL_GetBlendModeSrcAlphaFactor(blend)));
1174  IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLENDALPHA,
1175  GetBlendFunc(SDL_GetBlendModeDstAlphaFactor(blend)));
1176  }
1177  }
1178 
1179  data->drawstate.blend = blend;
1180  }
1181 
1182  if (is_copy_ex != was_copy_ex) {
1183  if (!is_copy_ex) { /* SDL_RENDERCMD_COPY_EX will set this, we only want to reset it here if necessary. */
1184  const Float4X4 d3dmatrix = MatrixIdentity();
1185  IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, (D3DMATRIX*) &d3dmatrix);
1186  }
1187  data->drawstate.is_copy_ex = is_copy_ex;
1188  }
1189 
1190  if (data->drawstate.viewport_dirty) {
1191  const SDL_Rect *viewport = &data->drawstate.viewport;
1192  const D3DVIEWPORT9 d3dviewport = { viewport->x, viewport->y, viewport->w, viewport->h, 0.0f, 1.0f };
1193  IDirect3DDevice9_SetViewport(data->device, &d3dviewport);
1194 
1195  /* Set an orthographic projection matrix */
1196  if (viewport->w && viewport->h) {
1197  D3DMATRIX d3dmatrix;
1198  SDL_zero(d3dmatrix);
1199  d3dmatrix.m[0][0] = 2.0f / viewport->w;
1200  d3dmatrix.m[1][1] = -2.0f / viewport->h;
1201  d3dmatrix.m[2][2] = 1.0f;
1202  d3dmatrix.m[3][0] = -1.0f;
1203  d3dmatrix.m[3][1] = 1.0f;
1204  d3dmatrix.m[3][3] = 1.0f;
1205  IDirect3DDevice9_SetTransform(data->device, D3DTS_PROJECTION, &d3dmatrix);
1206  }
1207 
1208  data->drawstate.viewport_dirty = SDL_FALSE;
1209  }
1210 
1211  if (data->drawstate.cliprect_enabled_dirty) {
1212  IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE, data->drawstate.cliprect_enabled ? TRUE : FALSE);
1213  data->drawstate.cliprect_enabled_dirty = SDL_FALSE;
1214  }
1215 
1216  if (data->drawstate.cliprect_dirty) {
1217  const SDL_Rect *viewport = &data->drawstate.viewport;
1218  const SDL_Rect *rect = &data->drawstate.cliprect;
1219  const RECT d3drect = { viewport->x + rect->x, viewport->y + rect->y, viewport->x + rect->x + rect->w, viewport->y + rect->y + rect->h };
1220  IDirect3DDevice9_SetScissorRect(data->device, &d3drect);
1221  data->drawstate.cliprect_dirty = SDL_FALSE;
1222  }
1223 
1224  return 0;
1225 }
1226 
1227 static int
1228 D3D_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
1229 {
1230  D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
1231  const int vboidx = data->currentVertexBuffer;
1232  IDirect3DVertexBuffer9 *vbo = NULL;
1233  const SDL_bool istarget = renderer->target != NULL;
1234  size_t i;
1235 
1236  if (D3D_ActivateRenderer(renderer) < 0) {
1237  return -1;
1238  }
1239 
1240  /* upload the new VBO data for this set of commands. */
1241  vbo = data->vertexBuffers[vboidx];
1242  if (data->vertexBufferSize[vboidx] < vertsize) {
1243  const DWORD usage = D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY;
1244  const DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1;
1245  if (vbo) {
1246  IDirect3DVertexBuffer9_Release(vbo);
1247  }
1248 
1249  if (FAILED(IDirect3DDevice9_CreateVertexBuffer(data->device, (UINT) vertsize, usage, fvf, D3DPOOL_DEFAULT, &vbo, NULL))) {
1250  vbo = NULL;
1251  }
1252  data->vertexBuffers[vboidx] = vbo;
1253  data->vertexBufferSize[vboidx] = vbo ? vertsize : 0;
1254  }
1255 
1256  if (vbo) {
1257  void *ptr;
1258  if (FAILED(IDirect3DVertexBuffer9_Lock(vbo, 0, (UINT) vertsize, &ptr, D3DLOCK_DISCARD))) {
1259  vbo = NULL; /* oh well, we'll do immediate mode drawing. :( */
1260  } else {
1261  SDL_memcpy(ptr, vertices, vertsize);
1262  if (FAILED(IDirect3DVertexBuffer9_Unlock(vbo))) {
1263  vbo = NULL; /* oh well, we'll do immediate mode drawing. :( */
1264  }
1265  }
1266  }
1267 
1268  /* cycle through a few VBOs so D3D has some time with the data before we replace it. */
1269  if (vbo) {
1270  data->currentVertexBuffer++;
1271  if (data->currentVertexBuffer >= SDL_arraysize(data->vertexBuffers)) {
1272  data->currentVertexBuffer = 0;
1273  }
1274  } else if (!data->reportedVboProblem) {
1275  SDL_LogError(SDL_LOG_CATEGORY_RENDER, "SDL failed to get a vertex buffer for this Direct3D 9 rendering batch!");
1276  SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Dropping back to a slower method.");
1277  SDL_LogError(SDL_LOG_CATEGORY_RENDER, "This might be a brief hiccup, but if performance is bad, this is probably why.");
1278  SDL_LogError(SDL_LOG_CATEGORY_RENDER, "This error will not be logged again for this renderer.");
1279  data->reportedVboProblem = SDL_TRUE;
1280  }
1281 
1282  IDirect3DDevice9_SetStreamSource(data->device, 0, vbo, 0, sizeof (Vertex));
1283 
1284  while (cmd) {
1285  switch (cmd->command) {
1287  /* currently this is sent with each vertex, but if we move to
1288  shaders, we can put this in a uniform here and reduce vertex
1289  buffer bandwidth */
1290  break;
1291  }
1292 
1294  SDL_Rect *viewport = &data->drawstate.viewport;
1295  if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) {
1296  SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect));
1297  data->drawstate.viewport_dirty = SDL_TRUE;
1298  }
1299  break;
1300  }
1301 
1303  const SDL_Rect *rect = &cmd->data.cliprect.rect;
1304  if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) {
1305  data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled;
1306  data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
1307  }
1308 
1309  if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) {
1310  SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect));
1311  data->drawstate.cliprect_dirty = SDL_TRUE;
1312  }
1313  break;
1314  }
1315 
1316  case SDL_RENDERCMD_CLEAR: {
1317  const DWORD color = D3DCOLOR_ARGB(cmd->data.color.a, cmd->data.color.r, cmd->data.color.g, cmd->data.color.b);
1318  const SDL_Rect *viewport = &data->drawstate.viewport;
1319  const int backw = istarget ? renderer->target->w : data->pparams.BackBufferWidth;
1320  const int backh = istarget ? renderer->target->h : data->pparams.BackBufferHeight;
1321 
1322  if (data->drawstate.cliprect_enabled) {
1323  IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE, FALSE);
1324  data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
1325  }
1326 
1327  /* Don't reset the viewport if we don't have to! */
1328  if (!viewport->x && !viewport->y && (viewport->w == backw) && (viewport->h == backh)) {
1329  IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0);
1330  } else {
1331  /* Clear is defined to clear the entire render target */
1332  const D3DVIEWPORT9 wholeviewport = { 0, 0, backw, backh, 0.0f, 1.0f };
1333  IDirect3DDevice9_SetViewport(data->device, &wholeviewport);
1334  data->drawstate.viewport_dirty = SDL_TRUE;
1335  IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0);
1336  }
1337 
1338  break;
1339  }
1340 
1342  const size_t count = cmd->data.draw.count;
1343  const size_t first = cmd->data.draw.first;
1344  SetDrawState(data, cmd);
1345  if (vbo) {
1346  IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_POINTLIST, (UINT) (first / sizeof (Vertex)), (UINT) count);
1347  } else {
1348  const Vertex *verts = (Vertex *) (((Uint8 *) vertices) + first);
1349  IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, (UINT) count, verts, sizeof (Vertex));
1350  }
1351  break;
1352  }
1353 
1354  case SDL_RENDERCMD_DRAW_LINES: {
1355  const size_t count = cmd->data.draw.count;
1356  const size_t first = cmd->data.draw.first;
1357  const Vertex *verts = (Vertex *) (((Uint8 *) vertices) + first);
1358 
1359  /* DirectX 9 has the same line rasterization semantics as GDI,
1360  so we need to close the endpoint of the line with a second draw call. */
1361  const SDL_bool close_endpoint = ((count == 2) || (verts[0].x != verts[count-1].x) || (verts[0].y != verts[count-1].y));
1362 
1363  SetDrawState(data, cmd);
1364 
1365  if (vbo) {
1366  IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_LINESTRIP, (UINT) (first / sizeof (Vertex)), (UINT) (count - 1));
1367  if (close_endpoint) {
1368  IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_POINTLIST, (UINT) ((first / sizeof (Vertex)) + (count - 1)), 1);
1369  }
1370  } else {
1371  IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_LINESTRIP, (UINT) (count - 1), verts, sizeof (Vertex));
1372  if (close_endpoint) {
1373  IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, 1, &verts[count-1], sizeof (Vertex));
1374  }
1375  }
1376  break;
1377  }
1378 
1379  case SDL_RENDERCMD_FILL_RECTS: {
1380  const size_t count = cmd->data.draw.count;
1381  const size_t first = cmd->data.draw.first;
1382  SetDrawState(data, cmd);
1383  if (vbo) {
1384  size_t offset = 0;
1385  for (i = 0; i < count; ++i, offset += 4) {
1386  IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_TRIANGLEFAN, (UINT) ((first / sizeof (Vertex)) + offset), 2);
1387  }
1388  } else {
1389  const Vertex *verts = (Vertex *) (((Uint8 *) vertices) + first);
1390  for (i = 0; i < count; ++i, verts += 4) {
1391  IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2, verts, sizeof (Vertex));
1392  }
1393  }
1394  break;
1395  }
1396 
1397  case SDL_RENDERCMD_COPY: {
1398  const size_t count = cmd->data.draw.count;
1399  const size_t first = cmd->data.draw.first;
1400  SetDrawState(data, cmd);
1401  if (vbo) {
1402  size_t offset = 0;
1403  for (i = 0; i < count; ++i, offset += 4) {
1404  IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_TRIANGLEFAN, (UINT) ((first / sizeof (Vertex)) + offset), 2);
1405  }
1406  } else {
1407  const Vertex *verts = (Vertex *) (((Uint8 *) vertices) + first);
1408  for (i = 0; i < count; ++i, verts += 4) {
1409  IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2, verts, sizeof (Vertex));
1410  }
1411  }
1412  break;
1413  }
1414 
1415  case SDL_RENDERCMD_COPY_EX: {
1416  const size_t first = cmd->data.draw.first;
1417  const Vertex *verts = (Vertex *) (((Uint8 *) vertices) + first);
1418  const Vertex *transvert = verts + 4;
1419  const float translatex = transvert->x;
1420  const float translatey = transvert->y;
1421  const float rotation = transvert->z;
1422  const Float4X4 d3dmatrix = MatrixMultiply(MatrixRotationZ(rotation), MatrixTranslation(translatex, translatey, 0));
1423  SetDrawState(data, cmd);
1424 
1425  IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, (D3DMATRIX*)&d3dmatrix);
1426 
1427  if (vbo) {
1428  IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_TRIANGLEFAN, (UINT) (first / sizeof (Vertex)), 2);
1429  } else {
1430  IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2, verts, sizeof (Vertex));
1431  }
1432  break;
1433  }
1434 
1435  case SDL_RENDERCMD_NO_OP:
1436  break;
1437  }
1438 
1439  cmd = cmd->next;
1440  }
1441 
1442  return 0;
1443 }
1444 
1445 
1446 static int
1447 D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
1448  Uint32 format, void * pixels, int pitch)
1449 {
1450  D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
1451  D3DSURFACE_DESC desc;
1452  LPDIRECT3DSURFACE9 backBuffer;
1453  LPDIRECT3DSURFACE9 surface;
1454  RECT d3drect;
1455  D3DLOCKED_RECT locked;
1456  HRESULT result;
1457 
1458  if (data->currentRenderTarget) {
1459  backBuffer = data->currentRenderTarget;
1460  } else {
1461  backBuffer = data->defaultRenderTarget;
1462  }
1463 
1464  result = IDirect3DSurface9_GetDesc(backBuffer, &desc);
1465  if (FAILED(result)) {
1466  return D3D_SetError("GetDesc()", result);
1467  }
1468 
1469  result = IDirect3DDevice9_CreateOffscreenPlainSurface(data->device, desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surface, NULL);
1470  if (FAILED(result)) {
1471  return D3D_SetError("CreateOffscreenPlainSurface()", result);
1472  }
1473 
1474  result = IDirect3DDevice9_GetRenderTargetData(data->device, backBuffer, surface);
1475  if (FAILED(result)) {
1476  IDirect3DSurface9_Release(surface);
1477  return D3D_SetError("GetRenderTargetData()", result);
1478  }
1479 
1480  d3drect.left = rect->x;
1481  d3drect.right = rect->x + rect->w;
1482  d3drect.top = rect->y;
1483  d3drect.bottom = rect->y + rect->h;
1484 
1485  result = IDirect3DSurface9_LockRect(surface, &locked, &d3drect, D3DLOCK_READONLY);
1486  if (FAILED(result)) {
1487  IDirect3DSurface9_Release(surface);
1488  return D3D_SetError("LockRect()", result);
1489  }
1490 
1492  D3DFMTToPixelFormat(desc.Format), locked.pBits, locked.Pitch,
1493  format, pixels, pitch);
1494 
1495  IDirect3DSurface9_UnlockRect(surface);
1496 
1497  IDirect3DSurface9_Release(surface);
1498 
1499  return 0;
1500 }
1501 
1502 static void
1503 D3D_RenderPresent(SDL_Renderer * renderer)
1504 {
1505  D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
1506  HRESULT result;
1507 
1508  if (!data->beginScene) {
1509  IDirect3DDevice9_EndScene(data->device);
1510  data->beginScene = SDL_TRUE;
1511  }
1512 
1513  result = IDirect3DDevice9_TestCooperativeLevel(data->device);
1514  if (result == D3DERR_DEVICELOST) {
1515  /* We'll reset later */
1516  return;
1517  }
1518  if (result == D3DERR_DEVICENOTRESET) {
1519  D3D_Reset(renderer);
1520  }
1521  result = IDirect3DDevice9_Present(data->device, NULL, NULL, NULL, NULL);
1522  if (FAILED(result)) {
1523  D3D_SetError("Present()", result);
1524  }
1525 }
1526 
1527 static void
1528 D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
1529 {
1530  D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata;
1531  D3D_TextureData *data = (D3D_TextureData *) texture->driverdata;
1532 
1533  if (renderdata->drawstate.texture == texture) {
1534  renderdata->drawstate.texture = NULL;
1535  renderdata->drawstate.shader = NULL;
1536  IDirect3DDevice9_SetPixelShader(renderdata->device, NULL);
1537  IDirect3DDevice9_SetTexture(renderdata->device, 0, NULL);
1538  if (data->yuv) {
1539  IDirect3DDevice9_SetTexture(renderdata->device, 1, NULL);
1540  IDirect3DDevice9_SetTexture(renderdata->device, 2, NULL);
1541  }
1542  }
1543 
1544  if (!data) {
1545  return;
1546  }
1547 
1548  D3D_DestroyTextureRep(&data->texture);
1549  D3D_DestroyTextureRep(&data->utexture);
1550  D3D_DestroyTextureRep(&data->vtexture);
1551  SDL_free(data->pixels);
1552  SDL_free(data);
1553  texture->driverdata = NULL;
1554 }
1555 
1556 static void
1557 D3D_DestroyRenderer(SDL_Renderer * renderer)
1558 {
1559  D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
1560 
1561  if (data) {
1562  int i;
1563 
1564  /* Release the render target */
1565  if (data->defaultRenderTarget) {
1566  IDirect3DSurface9_Release(data->defaultRenderTarget);
1567  data->defaultRenderTarget = NULL;
1568  }
1569  if (data->currentRenderTarget != NULL) {
1570  IDirect3DSurface9_Release(data->currentRenderTarget);
1571  data->currentRenderTarget = NULL;
1572  }
1573  for (i = 0; i < SDL_arraysize(data->shaders); ++i) {
1574  if (data->shaders[i]) {
1575  IDirect3DPixelShader9_Release(data->shaders[i]);
1576  data->shaders[i] = NULL;
1577  }
1578  }
1579  /* Release all vertex buffers */
1580  for (i = 0; i < SDL_arraysize(data->vertexBuffers); ++i) {
1581  if (data->vertexBuffers[i]) {
1582  IDirect3DVertexBuffer9_Release(data->vertexBuffers[i]);
1583  }
1584  data->vertexBuffers[i] = NULL;
1585  }
1586  if (data->device) {
1587  IDirect3DDevice9_Release(data->device);
1588  data->device = NULL;
1589  }
1590  if (data->d3d) {
1591  IDirect3D9_Release(data->d3d);
1592  SDL_UnloadObject(data->d3dDLL);
1593  }
1594  SDL_free(data);
1595  }
1596  SDL_free(renderer);
1597 }
1598 
1599 static int
1600 D3D_Reset(SDL_Renderer * renderer)
1601 {
1602  D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
1603  const Float4X4 d3dmatrix = MatrixIdentity();
1604  HRESULT result;
1606  int i;
1607 
1608  /* Release the default render target before reset */
1609  if (data->defaultRenderTarget) {
1610  IDirect3DSurface9_Release(data->defaultRenderTarget);
1611  data->defaultRenderTarget = NULL;
1612  }
1613  if (data->currentRenderTarget != NULL) {
1614  IDirect3DSurface9_Release(data->currentRenderTarget);
1615  data->currentRenderTarget = NULL;
1616  }
1617 
1618  /* Release application render targets */
1620  if (texture->access == SDL_TEXTUREACCESS_TARGET) {
1621  D3D_DestroyTexture(renderer, texture);
1622  } else {
1623  D3D_RecreateTexture(renderer, texture);
1624  }
1625  }
1626 
1627  /* Release all vertex buffers */
1628  for (i = 0; i < SDL_arraysize(data->vertexBuffers); ++i) {
1629  if (data->vertexBuffers[i]) {
1630  IDirect3DVertexBuffer9_Release(data->vertexBuffers[i]);
1631  }
1632  data->vertexBuffers[i] = NULL;
1633  data->vertexBufferSize[i] = 0;
1634  }
1635 
1636  result = IDirect3DDevice9_Reset(data->device, &data->pparams);
1637  if (FAILED(result)) {
1638  if (result == D3DERR_DEVICELOST) {
1639  /* Don't worry about it, we'll reset later... */
1640  return 0;
1641  } else {
1642  return D3D_SetError("Reset()", result);
1643  }
1644  }
1645 
1646  /* Allocate application render targets */
1648  if (texture->access == SDL_TEXTUREACCESS_TARGET) {
1649  D3D_CreateTexture(renderer, texture);
1650  }
1651  }
1652 
1653  IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget);
1654  D3D_InitRenderState(data);
1655  D3D_SetRenderTargetInternal(renderer, renderer->target);
1656  data->drawstate.viewport_dirty = SDL_TRUE;
1657  data->drawstate.cliprect_dirty = SDL_TRUE;
1658  data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
1659  data->drawstate.texture = NULL;
1660  data->drawstate.shader = NULL;
1661  data->drawstate.blend = SDL_BLENDMODE_INVALID;
1662  data->drawstate.is_copy_ex = SDL_FALSE;
1663  IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, (D3DMATRIX*)&d3dmatrix);
1664 
1665  /* Let the application know that render targets were reset */
1666  {
1667  SDL_Event event;
1668  event.type = SDL_RENDER_TARGETS_RESET;
1669  SDL_PushEvent(&event);
1670  }
1671 
1672  return 0;
1673 }
1674 
1675 SDL_Renderer *
1676 D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
1677 {
1679  D3D_RenderData *data;
1680  SDL_SysWMinfo windowinfo;
1681  HRESULT result;
1682  D3DPRESENT_PARAMETERS pparams;
1683  IDirect3DSwapChain9 *chain;
1684  D3DCAPS9 caps;
1685  DWORD device_flags;
1686  Uint32 window_flags;
1687  int w, h;
1688  SDL_DisplayMode fullscreen_mode;
1689  int displayIndex;
1690 
1691  renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
1692  if (!renderer) {
1693  SDL_OutOfMemory();
1694  return NULL;
1695  }
1696 
1697  data = (D3D_RenderData *) SDL_calloc(1, sizeof(*data));
1698  if (!data) {
1699  SDL_free(renderer);
1700  SDL_OutOfMemory();
1701  return NULL;
1702  }
1703 
1704  if (!D3D_LoadDLL(&data->d3dDLL, &data->d3d)) {
1705  SDL_free(renderer);
1706  SDL_free(data);
1707  SDL_SetError("Unable to create Direct3D interface");
1708  return NULL;
1709  }
1710 
1711  renderer->WindowEvent = D3D_WindowEvent;
1712  renderer->SupportsBlendMode = D3D_SupportsBlendMode;
1713  renderer->CreateTexture = D3D_CreateTexture;
1714  renderer->UpdateTexture = D3D_UpdateTexture;
1715  renderer->UpdateTextureYUV = D3D_UpdateTextureYUV;
1716  renderer->LockTexture = D3D_LockTexture;
1717  renderer->UnlockTexture = D3D_UnlockTexture;
1718  renderer->SetTextureScaleMode = D3D_SetTextureScaleMode;
1719  renderer->SetRenderTarget = D3D_SetRenderTarget;
1720  renderer->QueueSetViewport = D3D_QueueSetViewport;
1721  renderer->QueueSetDrawColor = D3D_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
1722  renderer->QueueDrawPoints = D3D_QueueDrawPoints;
1723  renderer->QueueDrawLines = D3D_QueueDrawPoints; /* lines and points queue vertices the same way. */
1724  renderer->QueueFillRects = D3D_QueueFillRects;
1725  renderer->QueueCopy = D3D_QueueCopy;
1726  renderer->QueueCopyEx = D3D_QueueCopyEx;
1727  renderer->RunCommandQueue = D3D_RunCommandQueue;
1728  renderer->RenderReadPixels = D3D_RenderReadPixels;
1729  renderer->RenderPresent = D3D_RenderPresent;
1730  renderer->DestroyTexture = D3D_DestroyTexture;
1731  renderer->DestroyRenderer = D3D_DestroyRenderer;
1735 
1736  SDL_VERSION(&windowinfo.version);
1737  SDL_GetWindowWMInfo(window, &windowinfo);
1738 
1739  window_flags = SDL_GetWindowFlags(window);
1740  SDL_GetWindowSize(window, &w, &h);
1741  SDL_GetWindowDisplayMode(window, &fullscreen_mode);
1742 
1743  SDL_zero(pparams);
1744  pparams.hDeviceWindow = windowinfo.info.win.window;
1745  pparams.BackBufferWidth = w;
1746  pparams.BackBufferHeight = h;
1747  pparams.BackBufferCount = 1;
1748  pparams.SwapEffect = D3DSWAPEFFECT_DISCARD;
1749 
1750  if (window_flags & SDL_WINDOW_FULLSCREEN && (window_flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
1751  pparams.Windowed = FALSE;
1752  pparams.BackBufferFormat = PixelFormatToD3DFMT(fullscreen_mode.format);
1753  pparams.FullScreen_RefreshRateInHz = fullscreen_mode.refresh_rate;
1754  } else {
1755  pparams.Windowed = TRUE;
1756  pparams.BackBufferFormat = D3DFMT_UNKNOWN;
1757  pparams.FullScreen_RefreshRateInHz = 0;
1758  }
1760  pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
1761  } else {
1762  pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
1763  }
1764 
1765  /* Get the adapter for the display that the window is on */
1766  displayIndex = SDL_GetWindowDisplayIndex(window);
1767  data->adapter = SDL_Direct3D9GetAdapterIndex(displayIndex);
1768 
1769  IDirect3D9_GetDeviceCaps(data->d3d, data->adapter, D3DDEVTYPE_HAL, &caps);
1770 
1771  device_flags = D3DCREATE_FPU_PRESERVE;
1772  if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) {
1773  device_flags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
1774  } else {
1775  device_flags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
1776  }
1777 
1779  device_flags |= D3DCREATE_MULTITHREADED;
1780  }
1781 
1782  result = IDirect3D9_CreateDevice(data->d3d, data->adapter,
1783  D3DDEVTYPE_HAL,
1784  pparams.hDeviceWindow,
1785  device_flags,
1786  &pparams, &data->device);
1787  if (FAILED(result)) {
1788  D3D_DestroyRenderer(renderer);
1789  D3D_SetError("CreateDevice()", result);
1790  return NULL;
1791  }
1792 
1793  /* Get presentation parameters to fill info */
1794  result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain);
1795  if (FAILED(result)) {
1796  D3D_DestroyRenderer(renderer);
1797  D3D_SetError("GetSwapChain()", result);
1798  return NULL;
1799  }
1800  result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams);
1801  if (FAILED(result)) {
1802  IDirect3DSwapChain9_Release(chain);
1803  D3D_DestroyRenderer(renderer);
1804  D3D_SetError("GetPresentParameters()", result);
1805  return NULL;
1806  }
1807  IDirect3DSwapChain9_Release(chain);
1808  if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) {
1810  }
1811  data->pparams = pparams;
1812 
1813  IDirect3DDevice9_GetDeviceCaps(data->device, &caps);
1814  renderer->info.max_texture_width = caps.MaxTextureWidth;
1815  renderer->info.max_texture_height = caps.MaxTextureHeight;
1816  if (caps.NumSimultaneousRTs >= 2) {
1818  }
1819 
1820  if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND) {
1821  data->enableSeparateAlphaBlend = SDL_TRUE;
1822  }
1823 
1824  /* Store the default render target */
1825  IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget);
1826  data->currentRenderTarget = NULL;
1827 
1828  /* Set up parameters for rendering */
1829  D3D_InitRenderState(data);
1830 
1831  if (caps.MaxSimultaneousTextures >= 3) {
1832  int i;
1833  for (i = 0; i < SDL_arraysize(data->shaders); ++i) {
1834  result = D3D9_CreatePixelShader(data->device, (D3D9_Shader)i, &data->shaders[i]);
1835  if (FAILED(result)) {
1836  D3D_SetError("CreatePixelShader()", result);
1837  }
1838  }
1839  if (data->shaders[SHADER_YUV_JPEG] && data->shaders[SHADER_YUV_BT601] && data->shaders[SHADER_YUV_BT709]) {
1842  }
1843  }
1844 
1845  data->drawstate.blend = SDL_BLENDMODE_INVALID;
1846 
1847  return renderer;
1848 }
1849 
1851  D3D_CreateRenderer,
1852  {
1853  "direct3d",
1855  1,
1857  0,
1858  0}
1859 };
1860 #endif /* SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED */
1861 
1862 #ifdef __WIN32__
1863 /* This function needs to always exist on Windows, for the Dynamic API. */
1866 {
1868 
1869 #if SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED
1870  D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
1871 
1872  /* Make sure that this is a D3D renderer */
1873  if (renderer->DestroyRenderer != D3D_DestroyRenderer) {
1874  SDL_SetError("Renderer is not a D3D renderer");
1875  return NULL;
1876  }
1877 
1878  device = data->device;
1879  if (device) {
1880  IDirect3DDevice9_AddRef(device);
1881  }
1882 #endif /* SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED */
1883 
1884  return device;
1885 }
1886 #endif /* __WIN32__ */
1887 
1888 /* vi: set ts=4 sw=4 expandtab: */
SDL_zero
#define SDL_zero(x)
Definition: SDL_stdinc.h:418
SDL_GetWindowDisplayIndex
#define SDL_GetWindowDisplayIndex
Definition: SDL_dynapi_overrides.h:510
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
SDL_memset
#define SDL_memset
Definition: SDL_dynapi_overrides.h:386
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_DisplayMode::format
Uint32 format
Definition: SDL_video.h:55
offset
GLintptr offset
Definition: SDL_opengl_glext.h:541
SDL_render.h
D3D9_CreatePixelShader
HRESULT D3D9_CreatePixelShader(IDirect3DDevice9 *d3dDevice, D3D9_Shader shader, IDirect3DPixelShader9 **pixelShader)
blendMode
static SDL_BlendMode blendMode
Definition: testdraw2.c:34
SDL_BLENDOPERATION_ADD
@ SDL_BLENDOPERATION_ADD
Definition: SDL_blendmode.h:67
SDL_BLENDFACTOR_SRC_ALPHA
@ SDL_BLENDFACTOR_SRC_ALPHA
Definition: SDL_blendmode.h:84
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA
@ SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA
Definition: SDL_blendmode.h:85
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
IDirect3D9
struct IDirect3D9 IDirect3D9
Definition: SDL_windowsvideo.h:194
SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR
@ SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR
Definition: SDL_blendmode.h:87
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
surface
EGLSurface surface
Definition: eglext.h:248
SDL_Renderer::SetRenderTarget
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:143
SDL_Texture::w
int w
Definition: SDL_sysrender.h:41
TRUE
#define TRUE
Definition: edid-parse.c:33
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:201
SDL_log.h
count
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1571
SDL_GetWindowFlags
#define SDL_GetWindowFlags
Definition: SDL_dynapi_overrides.h:518
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_BlendOperation
SDL_BlendOperation
The blend operation used when combining source and destination pixel components.
Definition: SDL_blendmode.h:65
SDL_WINDOW_FULLSCREEN
@ SDL_WINDOW_FULLSCREEN
Definition: SDL_video.h:99
SDL_SysWMinfo::window
Window window
Definition: SDL_syswm.h:225
viewport
static SDL_Rect viewport
Definition: testviewport.c:28
SDL_WINDOW_FULLSCREEN_DESKTOP
@ SDL_WINDOW_FULLSCREEN_DESKTOP
Definition: SDL_video.h:110
z
GLdouble GLdouble z
Definition: SDL_opengl_glext.h:407
SDL_RenderDriver
Definition: SDL_sysrender.h:222
SDL_UnloadObject
#define SDL_UnloadObject
Definition: SDL_dynapi_overrides.h:234
SDL_FRect::x
float x
Definition: SDL_rect.h:89
IDirect3DDevice9
struct IDirect3DDevice9 IDirect3DDevice9
Definition: SDL_system.h:60
shaders
GLsizei GLsizei GLuint * shaders
Definition: SDL_opengl_glext.h:674
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_PIXELFORMAT_RGB565
@ SDL_PIXELFORMAT_RGB565
Definition: SDL_pixels.h:227
index
GLuint index
Definition: SDL_opengl_glext.h:663
SDL_FPoint::y
float y
Definition: SDL_rect.h:63
v
const GLdouble * v
Definition: SDL_opengl.h:2064
h
GLfloat GLfloat GLfloat GLfloat h
Definition: SDL_opengl_glext.h:1949
SDL_RendererFlip
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
Definition: SDL_render.h:121
length
GLuint GLsizei GLsizei * length
Definition: SDL_opengl_glext.h:672
SDL_Rect::x
int x
Definition: SDL_rect.h:79
SDL_RENDERCMD_COPY
@ SDL_RENDERCMD_COPY
Definition: SDL_sysrender.h:76
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_LogError
#define SDL_LogError
Definition: SDL_dynapi_overrides.h:36
SDL_PIXELFORMAT_IYUV
@ SDL_PIXELFORMAT_IYUV
Definition: SDL_pixels.h:282
SDL_ScaleModeNearest
@ SDL_ScaleModeNearest
Definition: SDL_render.h:93
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
D3D_LoadDLL
SDL_bool D3D_LoadDLL(void **pD3DDLL, IDirect3D9 **pDirect3D9Interface)
SDL_Rect::w
int w
Definition: SDL_rect.h:80
SDL_RENDER_TARGETS_RESET
@ SDL_RENDER_TARGETS_RESET
Definition: SDL_events.h:154
row
GLenum GLenum void * row
Definition: SDL_opengl_glext.h:3141
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:74
SDL_DisplayMode
The structure that defines a display mode.
Definition: SDL_video.h:53
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_BLENDFACTOR_ONE_MINUS_SRC_COLOR
@ SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR
Definition: SDL_blendmode.h:83
SDL_BLENDMODE_NONE
@ SDL_BLENDMODE_NONE
Definition: SDL_blendmode.h:42
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
SDL_GetWindowDisplayMode
#define SDL_GetWindowDisplayMode
Definition: SDL_dynapi_overrides.h:512
SDL_Renderer
Definition: SDL_sysrender.h:109
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_Renderer::QueueSetDrawColor
int(* QueueSetDrawColor)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
Definition: SDL_sysrender.h:118
usage
GLsizeiptr const void GLenum usage
Definition: SDL_opengl_glext.h:540
SDL_FPoint
The structure that defines a point (floating point)
Definition: SDL_rect.h:60
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_shaders_d3d.h
SDL_FRect::w
float w
Definition: SDL_rect.h:91
SDL_FLIP_HORIZONTAL
@ SDL_FLIP_HORIZONTAL
Definition: SDL_render.h:124
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
D3D_RenderDriver
SDL_RenderDriver D3D_RenderDriver
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_Rect::h
int h
Definition: SDL_rect.h:80
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
SDL_PushEvent
#define SDL_PushEvent
Definition: SDL_dynapi_overrides.h:125
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_DisplayMode::refresh_rate
int refresh_rate
Definition: SDL_video.h:58
SDL_RENDERER_PRESENTVSYNC
@ SDL_RENDERER_PRESENTVSYNC
Definition: SDL_render.h:69
SDL_Direct3D9GetAdapterIndex
int SDL_Direct3D9GetAdapterIndex(int displayIndex)
Returns the D3D9 adapter index that matches the specified display index.
SDL_RENDERCMD_DRAW_POINTS
@ SDL_RENDERCMD_DRAW_POINTS
Definition: SDL_sysrender.h:73
SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA
@ SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA
Definition: SDL_blendmode.h:89
rect
SDL_Rect rect
Definition: testrelative.c:27
SDL_Texture::h
int h
Definition: SDL_sysrender.h:42
SDL_BlendFactor
SDL_BlendFactor
The normalized factor used to multiply pixel components.
Definition: SDL_blendmode.h:78
SDL_assert.h
SetDrawState
static void SetDrawState(SDL_Surface *surface, SW_DrawStateCache *drawstate)
Definition: SDL_render_sw.c:589
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_HINT_RENDER_DIRECT3D_THREADSAFE
#define SDL_HINT_RENDER_DIRECT3D_THREADSAFE
A variable controlling whether the Direct3D device is initialized for thread-safe operations.
Definition: SDL_hints.h:107
SDL_RenderCommand::command
SDL_RenderCommandType command
Definition: SDL_sysrender.h:82
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
SDL_assert
#define SDL_assert(condition)
Definition: SDL_assert.h:169
SDL_BLENDFACTOR_ZERO
@ SDL_BLENDFACTOR_ZERO
Definition: SDL_blendmode.h:80
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_BLENDFACTOR_DST_COLOR
@ SDL_BLENDFACTOR_DST_COLOR
Definition: SDL_blendmode.h:86
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
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
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_arraysize
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
SDL_BLENDMODE_INVALID
@ SDL_BLENDMODE_INVALID
Definition: SDL_blendmode.h:56
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_RenderCommand
Definition: SDL_sysrender.h:80
src
GLenum src
Definition: SDL_opengl_glext.h:1740
renderer
static SDL_Renderer * renderer
Definition: testaudiocapture.c:21
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
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_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
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_Rect
A rectangle, with the origin at the upper left (integer).
Definition: SDL_rect.h:77
SDL_RendererInfo::max_texture_width
int max_texture_width
Definition: SDL_render.h:84
SDL_system.h
SDL_BLENDFACTOR_SRC_COLOR
@ SDL_BLENDFACTOR_SRC_COLOR
Definition: SDL_blendmode.h:82
SDL_Texture
Definition: SDL_sysrender.h:36
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_RenderGetD3D9Device
IDirect3DDevice9 * SDL_RenderGetD3D9Device(SDL_Renderer *renderer)
Returns the D3D device associated with a renderer, or NULL if it's not a D3D renderer.
SDL_hints.h
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:195
SDL_FRect
A rectangle, with the origin at the upper left (floating point).
Definition: SDL_rect.h:87
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
SDL_SysWMinfo::info
union SDL_SysWMinfo::@10 info
angle
GLfloat angle
Definition: SDL_opengl_glext.h:6100
SDL_BLENDFACTOR_DST_ALPHA
@ SDL_BLENDFACTOR_DST_ALPHA
Definition: SDL_blendmode.h:88
SDL_FLIP_VERTICAL
@ SDL_FLIP_VERTICAL
Definition: SDL_render.h:125
SDL_GetYUVConversionModeForResolution
#define SDL_GetYUVConversionModeForResolution
Definition: SDL_dynapi_overrides.h:665
SDL_ScaleMode
SDL_ScaleMode
The scaling mode for a texture.
Definition: SDL_render.h:91
SDL_Event
General event structure.
Definition: SDL_events.h:558
SDL_Renderer::QueueDrawPoints
int(* QueueDrawPoints)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
Definition: SDL_sysrender.h:119
SDL_BLENDFACTOR_ONE
@ SDL_BLENDFACTOR_ONE
Definition: SDL_blendmode.h:81
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::texture_formats
Uint32 texture_formats[16]
Definition: SDL_render.h:83
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_Renderer::target
SDL_Texture * target
Definition: SDL_sysrender.h:194
texture
GLenum GLenum GLuint texture
Definition: SDL_opengl_glext.h:1181
NUM_SHADERS
@ NUM_SHADERS
Definition: SDL_shaders_d3d.h:29
device
static SDL_AudioDeviceID device
Definition: loopwave.c:37
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
ptr
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF ptr
Definition: pixman-arm-simd-asm.h:171
SDL_BlendMode
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
Definition: SDL_blendmode.h:40
SDL_loadso.h
SDL_RenderCommand::draw
struct SDL_RenderCommand::@23::@26 draw
SDL_LOG_CATEGORY_RENDER
@ SDL_LOG_CATEGORY_RENDER
Definition: SDL_log.h:72
SDL_GetBlendModeSrcColorFactor
SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:3363
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
FALSE
#define FALSE
Definition: edid-parse.c:34
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:161
SDL_Renderer::UnlockTexture
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:141
SDL_RendererInfo::num_texture_formats
Uint32 num_texture_formats
Definition: SDL_render.h:82
D3D9_Shader
D3D9_Shader
Definition: SDL_shaders_d3d.h:25
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
SHADER_YUV_BT709
@ SHADER_YUV_BT709
Definition: SDL_shaders_d3d.h:28
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179