21 #include "../../SDL_internal.h" 26 #if SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED 28 #include "../../core/windows/SDL_windows.h" 33 #include "../SDL_sysrender.h" 34 #include "../SDL_d3dmath.h" 35 #include "../../video/windows/SDL_windowsvideo.h" 37 #if SDL_VIDEO_RENDER_D3D 38 #define D3D_DEBUG_INFO 58 const Uint8 *Yplane,
int Ypitch,
59 const Uint8 *Uplane,
int Upitch,
60 const Uint8 *Vplane,
int Vpitch);
105 D3DPRESENT_PARAMETERS pparams;
109 D3DTEXTUREFILTERTYPE scaleMode[8];
110 IDirect3DSurface9 *defaultRenderTarget;
111 IDirect3DSurface9 *currentRenderTarget;
124 IDirect3DTexture9 *staging;
130 D3DTEXTUREFILTERTYPE scaleMode;
134 D3D_TextureRep utexture;
135 D3D_TextureRep vtexture;
149 D3D_SetError(
const char *prefix, HRESULT
result)
154 case D3DERR_WRONGTEXTUREFORMAT:
155 error =
"WRONGTEXTUREFORMAT";
157 case D3DERR_UNSUPPORTEDCOLOROPERATION:
158 error =
"UNSUPPORTEDCOLOROPERATION";
160 case D3DERR_UNSUPPORTEDCOLORARG:
161 error =
"UNSUPPORTEDCOLORARG";
163 case D3DERR_UNSUPPORTEDALPHAOPERATION:
164 error =
"UNSUPPORTEDALPHAOPERATION";
166 case D3DERR_UNSUPPORTEDALPHAARG:
167 error =
"UNSUPPORTEDALPHAARG";
169 case D3DERR_TOOMANYOPERATIONS:
170 error =
"TOOMANYOPERATIONS";
172 case D3DERR_CONFLICTINGTEXTUREFILTER:
173 error =
"CONFLICTINGTEXTUREFILTER";
175 case D3DERR_UNSUPPORTEDFACTORVALUE:
176 error =
"UNSUPPORTEDFACTORVALUE";
178 case D3DERR_CONFLICTINGRENDERSTATE:
179 error =
"CONFLICTINGRENDERSTATE";
181 case D3DERR_UNSUPPORTEDTEXTUREFILTER:
182 error =
"UNSUPPORTEDTEXTUREFILTER";
184 case D3DERR_CONFLICTINGTEXTUREPALETTE:
185 error =
"CONFLICTINGTEXTUREPALETTE";
187 case D3DERR_DRIVERINTERNALERROR:
188 error =
"DRIVERINTERNALERROR";
190 case D3DERR_NOTFOUND:
193 case D3DERR_MOREDATA:
196 case D3DERR_DEVICELOST:
197 error =
"DEVICELOST";
199 case D3DERR_DEVICENOTRESET:
200 error =
"DEVICENOTRESET";
202 case D3DERR_NOTAVAILABLE:
203 error =
"NOTAVAILABLE";
205 case D3DERR_OUTOFVIDEOMEMORY:
206 error =
"OUTOFVIDEOMEMORY";
208 case D3DERR_INVALIDDEVICE:
209 error =
"INVALIDDEVICE";
211 case D3DERR_INVALIDCALL:
212 error =
"INVALIDCALL";
214 case D3DERR_DRIVERINVALIDCALL:
215 error =
"DRIVERINVALIDCALL";
217 case D3DERR_WASSTILLDRAWING:
218 error =
"WASSTILLDRAWING";
232 return D3DFMT_R5G6B5;
234 return D3DFMT_X8R8G8B8;
236 return D3DFMT_A8R8G8B8;
243 return D3DFMT_UNKNOWN;
248 D3DFMTToPixelFormat(D3DFORMAT format)
253 case D3DFMT_X8R8G8B8:
255 case D3DFMT_A8R8G8B8:
263 D3D_InitRenderState(D3D_RenderData *
data)
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);
276 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP,
278 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1,
280 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2,
284 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP,
286 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1,
288 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG2,
292 if (data->enableSeparateAlphaBlend) {
293 IDirect3DDevice9_SetRenderState(device, D3DRS_SEPARATEALPHABLENDENABLE,
TRUE);
297 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP,
299 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP,
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);
323 SDL_memset(data->scaleMode, 0xFF,
sizeof(data->scaleMode));
332 D3D_RenderData *data = (D3D_RenderData *) renderer->
driverdata;
337 if (data->defaultRenderTarget) {
338 IDirect3DSurface9_Release(data->defaultRenderTarget);
339 data->defaultRenderTarget =
NULL;
341 if (data->currentRenderTarget !=
NULL) {
342 IDirect3DSurface9_Release(data->currentRenderTarget);
343 data->currentRenderTarget =
NULL;
349 D3D_DestroyTexture(renderer,
texture);
351 D3D_RecreateTexture(renderer,
texture);
355 result = IDirect3DDevice9_Reset(data->device, &data->pparams);
357 if (result == D3DERR_DEVICELOST) {
361 return D3D_SetError(
"Reset()", result);
368 D3D_CreateTexture(renderer,
texture);
372 IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget);
373 D3D_InitRenderState(data);
374 D3D_SetRenderTargetInternal(renderer, renderer->
target);
375 D3D_UpdateViewport(renderer);
390 D3D_RenderData *data = (D3D_RenderData *) renderer->
driverdata;
393 if (data->updateSize) {
399 data->pparams.BackBufferWidth =
w;
400 data->pparams.BackBufferHeight =
h;
404 data->pparams.Windowed =
FALSE;
405 data->pparams.BackBufferFormat = PixelFormatToD3DFMT(fullscreen_mode.
format);
406 data->pparams.FullScreen_RefreshRateInHz = fullscreen_mode.
refresh_rate;
408 data->pparams.Windowed =
TRUE;
409 data->pparams.BackBufferFormat = D3DFMT_UNKNOWN;
410 data->pparams.FullScreen_RefreshRateInHz = 0;
412 if (D3D_Reset(renderer) < 0) {
418 if (data->beginScene) {
419 result = IDirect3DDevice9_BeginScene(data->device);
420 if (result == D3DERR_DEVICELOST) {
421 if (D3D_Reset(renderer) < 0) {
424 result = IDirect3DDevice9_BeginScene(data->device);
427 return D3D_SetError(
"BeginScene()", result);
438 D3D_RenderData *
data;
441 D3DPRESENT_PARAMETERS pparams;
442 IDirect3DSwapChain9 *chain;
456 data = (D3D_RenderData *)
SDL_calloc(1,
sizeof(*data));
490 renderer->
info = D3D_RenderDriver.
info;
502 pparams.hDeviceWindow = windowinfo.
info.win.
window;
503 pparams.BackBufferWidth =
w;
504 pparams.BackBufferHeight =
h;
505 pparams.BackBufferCount = 1;
506 pparams.SwapEffect = D3DSWAPEFFECT_DISCARD;
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;
513 pparams.Windowed =
TRUE;
514 pparams.BackBufferFormat = D3DFMT_UNKNOWN;
515 pparams.FullScreen_RefreshRateInHz = 0;
518 pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
520 pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
527 IDirect3D9_GetDeviceCaps(data->d3d, data->adapter, D3DDEVTYPE_HAL, &caps);
529 device_flags = D3DCREATE_FPU_PRESERVE;
530 if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) {
531 device_flags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
533 device_flags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
537 device_flags |= D3DCREATE_MULTITHREADED;
540 result = IDirect3D9_CreateDevice(data->d3d, data->adapter,
542 pparams.hDeviceWindow,
544 &pparams, &data->device);
546 D3D_DestroyRenderer(renderer);
547 D3D_SetError(
"CreateDevice()", result);
552 result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain);
554 D3D_DestroyRenderer(renderer);
555 D3D_SetError(
"GetSwapChain()", result);
558 result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams);
560 IDirect3DSwapChain9_Release(chain);
561 D3D_DestroyRenderer(renderer);
562 D3D_SetError(
"GetPresentParameters()", result);
565 IDirect3DSwapChain9_Release(chain);
566 if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) {
569 data->pparams = pparams;
571 IDirect3DDevice9_GetDeviceCaps(data->device, &caps);
574 if (caps.NumSimultaneousRTs >= 2) {
578 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND) {
579 data->enableSeparateAlphaBlend =
SDL_TRUE;
583 IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget);
584 data->currentRenderTarget =
NULL;
587 D3D_InitRenderState(data);
589 if (caps.MaxSimultaneousTextures >= 3) {
594 D3D_SetError(
"CreatePixelShader()", result);
608 D3D_RenderData *data = (D3D_RenderData *) renderer->
driverdata;
619 return D3DBLEND_ZERO;
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;
646 D3D_RenderData *data = (D3D_RenderData *) renderer->
driverdata;
654 if (!GetBlendFunc(srcColorFactor) || !GetBlendFunc(srcAlphaFactor) ||
655 !GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor)) {
658 if ((srcColorFactor != srcAlphaFactor || dstColorFactor != dstAlphaFactor) && !data->enableSeparateAlphaBlend) {
667 static D3DTEXTUREFILTERTYPE
672 if (!hint || *hint ==
'0' ||
SDL_strcasecmp(hint,
"nearest") == 0) {
673 return D3DTEXF_POINT;
675 return D3DTEXF_LINEAR;
687 texture->usage =
usage;
689 texture->d3dfmt = d3dfmt;
691 result = IDirect3DDevice9_CreateTexture(device, w, h, 1, usage,
692 PixelFormatToD3DFMT(format),
693 D3DPOOL_DEFAULT, &texture->texture,
NULL);
695 return D3D_SetError(
"CreateTexture(D3DPOOL_DEFAULT)", result);
706 if (texture->staging ==
NULL) {
707 result = IDirect3DDevice9_CreateTexture(device, texture->w, texture->h, 1, 0,
708 texture->d3dfmt, D3DPOOL_SYSTEMMEM, &texture->staging,
NULL);
710 return D3D_SetError(
"CreateTexture(D3DPOOL_SYSTEMMEM)", result);
721 if (texture->dirty && texture->staging) {
722 if (!texture->texture) {
723 result = IDirect3DDevice9_CreateTexture(device, texture->w, texture->h, 1, texture->usage,
724 PixelFormatToD3DFMT(texture->format), D3DPOOL_DEFAULT, &texture->texture,
NULL);
726 return D3D_SetError(
"CreateTexture(D3DPOOL_DEFAULT)", result);
730 result = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture->staging, (IDirect3DBaseTexture9 *)texture->texture);
732 return D3D_SetError(
"UpdateTexture()", result);
736 result = IDirect3DDevice9_SetTexture(device, sampler, (IDirect3DBaseTexture9 *)texture->texture);
738 return D3D_SetError(
"SetTexture()", result);
746 if (texture->texture) {
747 IDirect3DTexture9_Release(texture->texture);
748 texture->texture =
NULL;
750 if (texture->staging) {
751 IDirect3DTexture9_AddDirtyRect(texture->staging,
NULL);
758 D3D_UpdateTextureRep(
IDirect3DDevice9 *device, D3D_TextureRep *texture,
int x,
int y,
int w,
int h,
const void *
pixels,
int pitch)
761 D3DLOCKED_RECT locked;
767 if (D3D_CreateStagingTexture(device, texture) < 0) {
772 d3drect.right = x +
w;
774 d3drect.bottom = y +
h;
776 result = IDirect3DTexture9_LockRect(texture->staging, 0, &locked, &d3drect, 0);
778 return D3D_SetError(
"LockRect()", result);
781 src = (
const Uint8 *)pixels;
782 dst = (
Uint8 *)locked.pBits;
784 if (length == pitch && length == locked.Pitch) {
787 if (length > pitch) {
790 if (length > locked.Pitch) {
791 length = locked.Pitch;
793 for (row = 0; row <
h; ++
row) {
799 result = IDirect3DTexture9_UnlockRect(texture->staging, 0);
801 return D3D_SetError(
"UnlockRect()", result);
809 D3D_DestroyTextureRep(D3D_TextureRep *texture)
811 if (texture->texture) {
812 IDirect3DTexture9_Release(texture->texture);
813 texture->texture =
NULL;
815 if (texture->staging) {
816 IDirect3DTexture9_Release(texture->staging);
817 texture->staging =
NULL;
824 D3D_RenderData *data = (D3D_RenderData *) renderer->
driverdata;
825 D3D_TextureData *texturedata;
828 texturedata = (D3D_TextureData *)
SDL_calloc(1,
sizeof(*texturedata));
837 usage = D3DUSAGE_RENDERTARGET;
842 if (D3D_CreateTextureRep(data->device, &texturedata->texture, usage, texture->
format, PixelFormatToD3DFMT(texture->
format), texture->
w, texture->
h) < 0) {
850 if (D3D_CreateTextureRep(data->device, &texturedata->utexture, usage, texture->
format, PixelFormatToD3DFMT(texture->
format), (texture->
w + 1) / 2, (texture->
h + 1) / 2) < 0) {
854 if (D3D_CreateTextureRep(data->device, &texturedata->vtexture, usage, texture->
format, PixelFormatToD3DFMT(texture->
format), (texture->
w + 1) / 2, (texture->
h + 1) / 2) < 0) {
864 D3D_RenderData *data = (D3D_RenderData *)renderer->
driverdata;
865 D3D_TextureData *texturedata = (D3D_TextureData *)texture->
driverdata;
871 if (D3D_RecreateTextureRep(data->device, &texturedata->texture) < 0) {
875 if (texturedata->yuv) {
876 if (D3D_RecreateTextureRep(data->device, &texturedata->utexture) < 0) {
880 if (D3D_RecreateTextureRep(data->device, &texturedata->vtexture) < 0) {
891 D3D_RenderData *data = (D3D_RenderData *)renderer->
driverdata;
892 D3D_TextureData *texturedata = (D3D_TextureData *) texture->
driverdata;
899 if (D3D_UpdateTextureRep(data->device, &texturedata->texture, rect->
x, rect->
y, rect->
w, rect->
h, pixels, pitch) < 0) {
903 if (texturedata->yuv) {
905 pixels = (
const void*)((
const Uint8*)pixels + rect->
h * pitch);
907 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) {
912 pixels = (
const void*)((
const Uint8*)pixels + ((rect->
h + 1) / 2) * ((pitch + 1) / 2));
913 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) {
923 const Uint8 *Yplane,
int Ypitch,
924 const Uint8 *Uplane,
int Upitch,
925 const Uint8 *Vplane,
int Vpitch)
927 D3D_RenderData *data = (D3D_RenderData *)renderer->
driverdata;
928 D3D_TextureData *texturedata = (D3D_TextureData *) texture->
driverdata;
935 if (D3D_UpdateTextureRep(data->device, &texturedata->texture, rect->
x, rect->
y, rect->
w, rect->
h, Yplane, Ypitch) < 0) {
938 if (D3D_UpdateTextureRep(data->device, &texturedata->utexture, rect->
x / 2, rect->
y / 2, (rect->
w + 1) / 2, (rect->
h + 1) / 2, Uplane, Upitch) < 0) {
941 if (D3D_UpdateTextureRep(data->device, &texturedata->vtexture, rect->
x / 2, rect->
y / 2, (rect->
w + 1) / 2, (rect->
h + 1) / 2, Vplane, Vpitch) < 0) {
949 const SDL_Rect * rect,
void **pixels,
int *pitch)
951 D3D_RenderData *data = (D3D_RenderData *)renderer->
driverdata;
952 D3D_TextureData *texturedata = (D3D_TextureData *)texture->
driverdata;
960 texturedata->locked_rect = *
rect;
962 if (texturedata->yuv) {
964 if (!texturedata->pixels) {
965 texturedata->pitch = texture->
w;
966 texturedata->pixels = (
Uint8 *)
SDL_malloc((texture->
h * texturedata->pitch * 3) / 2);
967 if (!texturedata->pixels) {
972 (
void *) ((
Uint8 *) texturedata->pixels + rect->
y * texturedata->pitch +
974 *pitch = texturedata->pitch;
977 D3DLOCKED_RECT locked;
980 if (D3D_CreateStagingTexture(device, &texturedata->texture) < 0) {
984 d3drect.left = rect->
x;
985 d3drect.right = rect->
x + rect->
w;
986 d3drect.top = rect->
y;
987 d3drect.bottom = rect->
y + rect->
h;
989 result = IDirect3DTexture9_LockRect(texturedata->texture.staging, 0, &locked, &d3drect, 0);
991 return D3D_SetError(
"LockRect()", result);
993 *pixels = locked.pBits;
994 *pitch = locked.Pitch;
1003 D3D_TextureData *texturedata = (D3D_TextureData *)texture->
driverdata;
1009 if (texturedata->yuv) {
1010 const SDL_Rect *rect = &texturedata->locked_rect;
1012 (
void *) ((
Uint8 *) texturedata->pixels + rect->
y * texturedata->pitch +
1014 D3D_UpdateTexture(renderer, texture, rect, pixels, texturedata->pitch);
1016 IDirect3DTexture9_UnlockRect(texturedata->texture.staging, 0);
1017 texturedata->texture.dirty =
SDL_TRUE;
1024 D3D_RenderData *data = (D3D_RenderData *) renderer->
driverdata;
1025 D3D_TextureData *texturedata;
1026 D3D_TextureRep *texturerep;
1031 if (data->currentRenderTarget !=
NULL) {
1032 IDirect3DSurface9_Release(data->currentRenderTarget);
1033 data->currentRenderTarget =
NULL;
1036 if (texture ==
NULL) {
1037 IDirect3DDevice9_SetRenderTarget(data->device, 0, data->defaultRenderTarget);
1041 texturedata = (D3D_TextureData *)texture->
driverdata;
1048 texturerep = &texturedata->texture;
1049 if (texturerep->dirty && texturerep->staging) {
1050 if (!texturerep->texture) {
1051 result = IDirect3DDevice9_CreateTexture(device, texturerep->w, texturerep->h, 1, texturerep->usage,
1052 PixelFormatToD3DFMT(texturerep->format), D3DPOOL_DEFAULT, &texturerep->texture,
NULL);
1054 return D3D_SetError(
"CreateTexture(D3DPOOL_DEFAULT)", result);
1058 result = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texturerep->staging, (IDirect3DBaseTexture9 *)texturerep->texture);
1060 return D3D_SetError(
"UpdateTexture()", result);
1065 result = IDirect3DTexture9_GetSurfaceLevel(texturedata->texture.texture, 0, &data->currentRenderTarget);
1067 return D3D_SetError(
"GetSurfaceLevel()", result);
1069 result = IDirect3DDevice9_SetRenderTarget(data->device, 0, data->currentRenderTarget);
1071 return D3D_SetError(
"SetRenderTarget()", result);
1080 if (D3D_ActivateRenderer(renderer) < 0) {
1084 return D3D_SetRenderTargetInternal(renderer, texture);
1090 D3D_RenderData *data = (D3D_RenderData *) renderer->
driverdata;
1101 IDirect3DDevice9_SetViewport(data->device, &
viewport);
1105 matrix.m[0][0] = 2.0f / renderer->
viewport.
w;
1106 matrix.m[0][1] = 0.0f;
1107 matrix.m[0][2] = 0.0f;
1108 matrix.m[0][3] = 0.0f;
1109 matrix.m[1][0] = 0.0f;
1110 matrix.m[1][1] = -2.0f / renderer->
viewport.
h;
1111 matrix.m[1][2] = 0.0f;
1112 matrix.m[1][3] = 0.0f;
1113 matrix.m[2][0] = 0.0f;
1114 matrix.m[2][1] = 0.0f;
1115 matrix.m[2][2] = 1.0f;
1116 matrix.m[2][3] = 0.0f;
1117 matrix.m[3][0] = -1.0f;
1118 matrix.m[3][1] = 1.0f;
1119 matrix.m[3][2] = 0.0f;
1120 matrix.m[3][3] = 1.0f;
1121 IDirect3DDevice9_SetTransform(data->device, D3DTS_PROJECTION, &matrix);
1130 D3D_RenderData *data = (D3D_RenderData *) renderer->
driverdata;
1137 IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE,
TRUE);
1140 r.right = renderer->
viewport.
x + rect->
x + rect->
w;
1141 r.bottom = renderer->
viewport.
y + rect->
y + rect->
h;
1143 result = IDirect3DDevice9_SetScissorRect(data->device, &r);
1144 if (result != D3D_OK) {
1145 D3D_SetError(
"SetScissor()", result);
1149 IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE,
FALSE);
1157 D3D_RenderData *data = (D3D_RenderData *) renderer->
driverdata;
1160 int BackBufferWidth, BackBufferHeight;
1162 if (D3D_ActivateRenderer(renderer) < 0) {
1166 color = D3DCOLOR_ARGB(renderer->
a, renderer->
r, renderer->
g, renderer->
b);
1169 BackBufferWidth = renderer->
target->
w;
1170 BackBufferHeight = renderer->
target->
h;
1172 BackBufferWidth = data->pparams.BackBufferWidth;
1173 BackBufferHeight = data->pparams.BackBufferHeight;
1177 IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE,
FALSE);
1182 renderer->
viewport.
w == BackBufferWidth &&
1183 renderer->
viewport.
h == BackBufferHeight) {
1184 result = IDirect3DDevice9_Clear(data->device, 0,
NULL, D3DCLEAR_TARGET,
color, 0.0f, 0);
1191 viewport.Width = BackBufferWidth;
1192 viewport.Height = BackBufferHeight;
1193 viewport.MinZ = 0.0f;
1194 viewport.MaxZ = 1.0f;
1195 IDirect3DDevice9_SetViewport(data->device, &viewport);
1197 result = IDirect3DDevice9_Clear(data->device, 0,
NULL, D3DCLEAR_TARGET,
color, 0.0f, 0);
1204 viewport.MinZ = 0.0f;
1205 viewport.MaxZ = 1.0f;
1206 IDirect3DDevice9_SetViewport(data->device, &viewport);
1210 IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE,
TRUE);
1214 return D3D_SetError(
"Clear()", result);
1220 D3D_SetBlendMode(D3D_RenderData * data,
SDL_BlendMode blendMode)
1223 IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
FALSE);
1225 IDirect3DDevice9_SetRenderState(data->device, D3DRS_ALPHABLENDENABLE,
TRUE);
1226 IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLEND,
1228 IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
1230 if (data->enableSeparateAlphaBlend) {
1231 IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLENDALPHA,
1233 IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLENDALPHA,
1243 D3D_RenderData *data = (D3D_RenderData *) renderer->
driverdata;
1249 if (D3D_ActivateRenderer(renderer) < 0) {
1253 D3D_SetBlendMode(data, renderer->
blendMode);
1256 IDirect3DDevice9_SetTexture(data->device, 0,
1257 (IDirect3DBaseTexture9 *) 0);
1259 return D3D_SetError(
"SetTexture()", result);
1262 color = D3DCOLOR_ARGB(renderer->
a, renderer->
r, renderer->
g, renderer->
b);
1265 for (i = 0; i <
count; ++
i) {
1266 vertices[
i].x = points[
i].
x;
1267 vertices[
i].y = points[
i].
y;
1268 vertices[
i].z = 0.0f;
1269 vertices[
i].color =
color;
1270 vertices[
i].u = 0.0f;
1271 vertices[
i].v = 0.0f;
1274 IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, count,
1275 vertices,
sizeof(*vertices));
1278 return D3D_SetError(
"DrawPrimitiveUP()", result);
1287 D3D_RenderData *data = (D3D_RenderData *) renderer->
driverdata;
1293 if (D3D_ActivateRenderer(renderer) < 0) {
1297 D3D_SetBlendMode(data, renderer->
blendMode);
1300 IDirect3DDevice9_SetTexture(data->device, 0,
1301 (IDirect3DBaseTexture9 *) 0);
1303 return D3D_SetError(
"SetTexture()", result);
1306 color = D3DCOLOR_ARGB(renderer->
a, renderer->
r, renderer->
g, renderer->
b);
1309 for (i = 0; i <
count; ++
i) {
1310 vertices[
i].x = points[
i].
x;
1311 vertices[
i].y = points[
i].
y;
1312 vertices[
i].z = 0.0f;
1313 vertices[
i].color =
color;
1314 vertices[
i].u = 0.0f;
1315 vertices[
i].v = 0.0f;
1318 IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_LINESTRIP, count-1,
1319 vertices,
sizeof(*vertices));
1324 points[0].x != points[count-1].x || points[0].y != points[count-1].y) {
1325 vertices[0].x = points[count-1].
x;
1326 vertices[0].y = points[count-1].
y;
1327 result = IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, 1, vertices,
sizeof(*vertices));
1332 return D3D_SetError(
"DrawPrimitiveUP()", result);
1341 D3D_RenderData *data = (D3D_RenderData *) renderer->
driverdata;
1344 float minx, miny, maxx, maxy;
1348 if (D3D_ActivateRenderer(renderer) < 0) {
1352 D3D_SetBlendMode(data, renderer->
blendMode);
1355 IDirect3DDevice9_SetTexture(data->device, 0,
1356 (IDirect3DBaseTexture9 *) 0);
1358 return D3D_SetError(
"SetTexture()", result);
1361 color = D3DCOLOR_ARGB(renderer->
a, renderer->
r, renderer->
g, renderer->
b);
1363 for (i = 0; i <
count; ++
i) {
1368 maxx = rect->
x + rect->
w;
1369 maxy = rect->
y + rect->
h;
1371 vertices[0].x = minx;
1372 vertices[0].y = miny;
1373 vertices[0].z = 0.0f;
1374 vertices[0].color =
color;
1375 vertices[0].u = 0.0f;
1376 vertices[0].v = 0.0f;
1378 vertices[1].x = maxx;
1379 vertices[1].y = miny;
1380 vertices[1].z = 0.0f;
1381 vertices[1].color =
color;
1382 vertices[1].u = 0.0f;
1383 vertices[1].v = 0.0f;
1385 vertices[2].x = maxx;
1386 vertices[2].y = maxy;
1387 vertices[2].z = 0.0f;
1388 vertices[2].color =
color;
1389 vertices[2].u = 0.0f;
1390 vertices[2].v = 0.0f;
1392 vertices[3].x = minx;
1393 vertices[3].y = maxy;
1394 vertices[3].z = 0.0f;
1395 vertices[3].color =
color;
1396 vertices[3].u = 0.0f;
1397 vertices[3].v = 0.0f;
1400 IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN,
1401 2, vertices,
sizeof(*vertices));
1403 return D3D_SetError(
"DrawPrimitiveUP()", result);
1410 D3D_UpdateTextureScaleMode(D3D_RenderData *data, D3D_TextureData *texturedata,
unsigned index)
1412 if (texturedata->scaleMode != data->scaleMode[index]) {
1413 IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_MINFILTER,
1414 texturedata->scaleMode);
1415 IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_MAGFILTER,
1416 texturedata->scaleMode);
1417 IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_ADDRESSU,
1419 IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_ADDRESSV,
1421 data->scaleMode[
index] = texturedata->scaleMode;
1428 D3D_RenderData *data = (D3D_RenderData *) renderer->
driverdata;
1429 D3D_TextureData *texturedata;
1433 texturedata = (D3D_TextureData *)texture->
driverdata;
1439 D3D_UpdateTextureScaleMode(data, texturedata, 0);
1441 if (D3D_BindTextureRep(data->device, &texturedata->texture, 0) < 0) {
1445 if (texturedata->yuv) {
1457 return SDL_SetError(
"Unsupported YUV conversion mode");
1460 D3D_UpdateTextureScaleMode(data, texturedata, 1);
1461 D3D_UpdateTextureScaleMode(data, texturedata, 2);
1463 if (D3D_BindTextureRep(data->device, &texturedata->utexture, 1) < 0) {
1466 if (D3D_BindTextureRep(data->device, &texturedata->vtexture, 2) < 0) {
1477 D3D_RenderData *data = (D3D_RenderData *) renderer->
driverdata;
1478 LPDIRECT3DPIXELSHADER9 shader;
1479 float minx, miny, maxx, maxy;
1480 float minu, maxu, minv, maxv;
1485 if (D3D_ActivateRenderer(renderer) < 0) {
1489 minx = dstrect->
x - 0.5f;
1490 miny = dstrect->
y - 0.5f;
1491 maxx = dstrect->
x + dstrect->
w - 0.5f;
1492 maxy = dstrect->
y + dstrect->
h - 0.5f;
1494 minu = (float) srcrect->
x / texture->
w;
1495 maxu = (
float) (srcrect->
x + srcrect->
w) / texture->
w;
1496 minv = (
float) srcrect->
y / texture->
h;
1497 maxv = (float) (srcrect->
y + srcrect->
h) / texture->
h;
1499 color = D3DCOLOR_ARGB(texture->
a, texture->
r, texture->
g, texture->
b);
1501 vertices[0].x = minx;
1502 vertices[0].y = miny;
1503 vertices[0].z = 0.0f;
1504 vertices[0].color =
color;
1505 vertices[0].u = minu;
1506 vertices[0].v = minv;
1508 vertices[1].x = maxx;
1509 vertices[1].y = miny;
1510 vertices[1].z = 0.0f;
1511 vertices[1].color =
color;
1512 vertices[1].u = maxu;
1513 vertices[1].v = minv;
1515 vertices[2].x = maxx;
1516 vertices[2].y = maxy;
1517 vertices[2].z = 0.0f;
1518 vertices[2].color =
color;
1519 vertices[2].u = maxu;
1520 vertices[2].v = maxv;
1522 vertices[3].x = minx;
1523 vertices[3].y = maxy;
1524 vertices[3].z = 0.0f;
1525 vertices[3].color =
color;
1526 vertices[3].u = minu;
1527 vertices[3].v = maxv;
1529 D3D_SetBlendMode(data, texture->
blendMode);
1531 if (D3D_RenderSetupTextureState(renderer, texture, &shader) < 0) {
1536 result = IDirect3DDevice9_SetPixelShader(data->device, shader);
1538 return D3D_SetError(
"SetShader()", result);
1541 result = IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2,
1542 vertices,
sizeof(*vertices));
1544 D3D_SetError(
"DrawPrimitiveUP()", result);
1547 IDirect3DDevice9_SetPixelShader(data->device,
NULL);
1549 return FAILED(result) ? -1 : 0;
1558 D3D_RenderData *data = (D3D_RenderData *) renderer->
driverdata;
1559 LPDIRECT3DPIXELSHADER9 shader =
NULL;
1560 float minx, miny, maxx, maxy;
1561 float minu, maxu, minv, maxv;
1562 float centerx, centery;
1565 Float4X4 modelMatrix;
1568 if (D3D_ActivateRenderer(renderer) < 0) {
1572 centerx = center->
x;
1573 centery = center->
y;
1576 maxx = dstrect->
w - centerx;
1578 maxy = dstrect->
h - centery;
1580 minu = (float) srcrect->
x / texture->
w;
1581 maxu = (
float) (srcrect->
x + srcrect->
w) / texture->
w;
1582 minv = (
float) srcrect->
y / texture->
h;
1583 maxv = (float) (srcrect->
y + srcrect->
h) / texture->
h;
1596 color = D3DCOLOR_ARGB(texture->
a, texture->
r, texture->
g, texture->
b);
1598 vertices[0].x = minx;
1599 vertices[0].y = miny;
1600 vertices[0].z = 0.0f;
1601 vertices[0].color =
color;
1602 vertices[0].u = minu;
1603 vertices[0].v = minv;
1605 vertices[1].x = maxx;
1606 vertices[1].y = miny;
1607 vertices[1].z = 0.0f;
1608 vertices[1].color =
color;
1609 vertices[1].u = maxu;
1610 vertices[1].v = minv;
1612 vertices[2].x = maxx;
1613 vertices[2].y = maxy;
1614 vertices[2].z = 0.0f;
1615 vertices[2].color =
color;
1616 vertices[2].u = maxu;
1617 vertices[2].v = maxv;
1619 vertices[3].x = minx;
1620 vertices[3].y = maxy;
1621 vertices[3].z = 0.0f;
1622 vertices[3].color =
color;
1623 vertices[3].u = minu;
1624 vertices[3].v = maxv;
1626 D3D_SetBlendMode(data, texture->
blendMode);
1628 if (D3D_RenderSetupTextureState(renderer, texture, &shader) < 0) {
1633 modelMatrix = MatrixMultiply(
1634 MatrixRotationZ((
float)(M_PI * (
float) angle / 180.0
f)),
1635 MatrixTranslation(dstrect->
x + center->
x - 0.5f, dstrect->
y + center->
y - 0.5f, 0));
1636 IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, (D3DMATRIX*)&modelMatrix);
1639 result = IDirect3DDevice9_SetPixelShader(data->device, shader);
1641 D3D_SetError(
"SetShader()", result);
1645 result = IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2,
1646 vertices,
sizeof(*vertices));
1648 D3D_SetError(
"DrawPrimitiveUP()", result);
1652 IDirect3DDevice9_SetPixelShader(data->device,
NULL);
1655 modelMatrix = MatrixIdentity();
1656 IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, (D3DMATRIX*)&modelMatrix);
1658 return FAILED(result) ? -1 : 0;
1663 Uint32 format,
void * pixels,
int pitch)
1665 D3D_RenderData *data = (D3D_RenderData *) renderer->
driverdata;
1666 D3DSURFACE_DESC desc;
1667 LPDIRECT3DSURFACE9 backBuffer;
1670 D3DLOCKED_RECT locked;
1673 if (data->currentRenderTarget) {
1674 backBuffer = data->currentRenderTarget;
1676 backBuffer = data->defaultRenderTarget;
1679 result = IDirect3DSurface9_GetDesc(backBuffer, &desc);
1681 IDirect3DSurface9_Release(backBuffer);
1682 return D3D_SetError(
"GetDesc()", result);
1685 result = IDirect3DDevice9_CreateOffscreenPlainSurface(data->device, desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &
surface,
NULL);
1687 IDirect3DSurface9_Release(backBuffer);
1688 return D3D_SetError(
"CreateOffscreenPlainSurface()", result);
1691 result = IDirect3DDevice9_GetRenderTargetData(data->device, backBuffer,
surface);
1693 IDirect3DSurface9_Release(
surface);
1694 IDirect3DSurface9_Release(backBuffer);
1695 return D3D_SetError(
"GetRenderTargetData()", result);
1698 d3drect.left = rect->
x;
1699 d3drect.right = rect->
x + rect->
w;
1700 d3drect.top = rect->
y;
1701 d3drect.bottom = rect->
y + rect->
h;
1703 result = IDirect3DSurface9_LockRect(
surface, &locked, &d3drect, D3DLOCK_READONLY);
1705 IDirect3DSurface9_Release(
surface);
1706 IDirect3DSurface9_Release(backBuffer);
1707 return D3D_SetError(
"LockRect()", result);
1711 D3DFMTToPixelFormat(desc.Format), locked.pBits, locked.Pitch,
1712 format, pixels, pitch);
1714 IDirect3DSurface9_UnlockRect(
surface);
1716 IDirect3DSurface9_Release(
surface);
1724 D3D_RenderData *data = (D3D_RenderData *) renderer->
driverdata;
1727 if (!data->beginScene) {
1728 IDirect3DDevice9_EndScene(data->device);
1732 result = IDirect3DDevice9_TestCooperativeLevel(data->device);
1733 if (result == D3DERR_DEVICELOST) {
1737 if (result == D3DERR_DEVICENOTRESET) {
1738 D3D_Reset(renderer);
1742 D3D_SetError(
"Present()", result);
1749 D3D_TextureData *data = (D3D_TextureData *) texture->
driverdata;
1754 D3D_DestroyTextureRep(&data->texture);
1755 D3D_DestroyTextureRep(&data->utexture);
1756 D3D_DestroyTextureRep(&data->vtexture);
1765 D3D_RenderData *data = (D3D_RenderData *) renderer->
driverdata;
1771 if (data->defaultRenderTarget) {
1772 IDirect3DSurface9_Release(data->defaultRenderTarget);
1773 data->defaultRenderTarget =
NULL;
1775 if (data->currentRenderTarget !=
NULL) {
1776 IDirect3DSurface9_Release(data->currentRenderTarget);
1777 data->currentRenderTarget =
NULL;
1780 if (data->shaders[i]) {
1781 IDirect3DPixelShader9_Release(data->shaders[i]);
1782 data->shaders[
i] =
NULL;
1786 IDirect3DDevice9_Release(data->device);
1787 data->device =
NULL;
1790 IDirect3D9_Release(data->d3d);
1806 #if SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED 1807 D3D_RenderData *data = (D3D_RenderData *) renderer->
driverdata;
1815 device = data->device;
1817 IDirect3DDevice9_AddRef(device);
SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode)
SDL_BlendFactor
The normalized factor used to multiply pixel components.
int(* RenderDrawLines)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
struct IDirect3D9 IDirect3D9
GLdouble GLdouble GLdouble r
int(* RenderDrawPoints)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
#define SDL_GetWindowDisplayIndex
HRESULT D3D9_CreatePixelShader(IDirect3DDevice9 *d3dDevice, D3D9_Shader shader, IDirect3DPixelShader9 **pixelShader)
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
GLint GLint GLint GLint GLint x
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
SDL_bool(* SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode)
GLuint GLuint GLsizei count
#define SDL_HINT_RENDER_SCALE_QUALITY
A variable controlling the scaling quality.
GLfloat GLfloat GLfloat GLfloat h
Uint32 texture_formats[16]
The structure that defines a display mode.
SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode)
#define SDL_GetWindowFlags
SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode)
#define SDL_BYTESPERPIXEL(X)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
int(* RenderFillRects)(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
GLsizei GLsizei GLuint * shaders
SDL_BlendOperation
The blend operation used when combining source and destination pixel components.
int(* RenderClear)(SDL_Renderer *renderer)
void(* DestroyRenderer)(SDL_Renderer *renderer)
GLfixed GLfixed GLint GLint GLfixed points
#define SDL_GetHintBoolean
#define SDL_VERSION(x)
Macro to determine SDL version program was compiled against.
int SDL_Direct3D9GetAdapterIndex(int displayIndex)
Returns the D3D9 adapter index that matches the specified display index.
static SDL_BlendMode blendMode
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
static SDL_AudioDeviceID device
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)
#define SDL_GetWindowSize
GLsizeiptr const void GLenum usage
GLenum GLenum GLuint texture
#define SDL_GetWindowDisplayMode
SDL_BlendOperation SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode)
static int GetScaleQuality(void)
static SDL_Renderer * renderer
#define SDL_stack_alloc(type, count)
GLubyte GLubyte GLubyte GLubyte w
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
GLint GLint GLint GLint GLint GLint y
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* UpdateViewport)(SDL_Renderer *renderer)
SDL_RenderDriver D3D_RenderDriver
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
SDL_bool D3D_LoadDLL(void **pD3DDLL, IDirect3D9 **pDirect3D9Interface)
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
#define SDL_HINT_RENDER_DIRECT3D_THREADSAFE
A variable controlling whether the Direct3D device is initialized for thread-safe operations...
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)
int(* RenderCopy)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
Window state change event data (event.window.*)
#define SDL_GetWindowWMInfo
#define SDL_OutOfMemory()
SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode)
int(* RenderCopyEx)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
EGLSurface EGLNativeWindowType * window
The type used to identify a window.
SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode)
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
Uint32 num_texture_formats
union SDL_SysWMinfo::@18 info
#define SDL_arraysize(array)
#define SDL_ConvertPixels
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
void(* RenderPresent)(SDL_Renderer *renderer)
EGLSurface EGLint * rects
#define SDL_stack_free(data)
#define SDL_GetYUVConversionModeForResolution
GLuint GLsizei GLsizei * length
int(* UpdateClipRect)(SDL_Renderer *renderer)
IDirect3DDevice9 * SDL_RenderGetD3D9Device(SDL_Renderer *renderer)
Returns the D3D device associated with a renderer, or NULL if it's not a D3D renderer.
SDL_bool clipping_enabled
A rectangle, with the origin at the upper left.
struct IDirect3DDevice9 IDirect3DDevice9