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