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