21 #include "../../SDL_internal.h"
26 #if SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED
28 #include "../../core/windows/SDL_windows.h"
35 #include "../SDL_sysrender.h"
36 #include "../SDL_d3dmath.h"
37 #include "../../video/windows/SDL_windowsvideo.h"
39 #if SDL_VIDEO_RENDER_D3D
40 #define D3D_DEBUG_INFO
57 LPDIRECT3DPIXELSHADER9
shader;
69 D3DPRESENT_PARAMETERS pparams;
73 D3DTEXTUREFILTERTYPE scaleMode[8];
74 IDirect3DSurface9 *defaultRenderTarget;
75 IDirect3DSurface9 *currentRenderTarget;
78 LPDIRECT3DVERTEXBUFFER9 vertexBuffers[8];
79 size_t vertexBufferSize[8];
80 int currentVertexBuffer;
82 D3D_DrawStateCache drawstate;
93 IDirect3DTexture9 *staging;
99 D3DTEXTUREFILTERTYPE scaleMode;
103 D3D_TextureRep utexture;
104 D3D_TextureRep vtexture;
118 D3D_SetError(
const char *prefix, HRESULT
result)
123 case D3DERR_WRONGTEXTUREFORMAT:
124 error =
"WRONGTEXTUREFORMAT";
126 case D3DERR_UNSUPPORTEDCOLOROPERATION:
127 error =
"UNSUPPORTEDCOLOROPERATION";
129 case D3DERR_UNSUPPORTEDCOLORARG:
130 error =
"UNSUPPORTEDCOLORARG";
132 case D3DERR_UNSUPPORTEDALPHAOPERATION:
133 error =
"UNSUPPORTEDALPHAOPERATION";
135 case D3DERR_UNSUPPORTEDALPHAARG:
136 error =
"UNSUPPORTEDALPHAARG";
138 case D3DERR_TOOMANYOPERATIONS:
139 error =
"TOOMANYOPERATIONS";
141 case D3DERR_CONFLICTINGTEXTUREFILTER:
142 error =
"CONFLICTINGTEXTUREFILTER";
144 case D3DERR_UNSUPPORTEDFACTORVALUE:
145 error =
"UNSUPPORTEDFACTORVALUE";
147 case D3DERR_CONFLICTINGRENDERSTATE:
148 error =
"CONFLICTINGRENDERSTATE";
150 case D3DERR_UNSUPPORTEDTEXTUREFILTER:
151 error =
"UNSUPPORTEDTEXTUREFILTER";
153 case D3DERR_CONFLICTINGTEXTUREPALETTE:
154 error =
"CONFLICTINGTEXTUREPALETTE";
156 case D3DERR_DRIVERINTERNALERROR:
157 error =
"DRIVERINTERNALERROR";
159 case D3DERR_NOTFOUND:
162 case D3DERR_MOREDATA:
165 case D3DERR_DEVICELOST:
166 error =
"DEVICELOST";
168 case D3DERR_DEVICENOTRESET:
169 error =
"DEVICENOTRESET";
171 case D3DERR_NOTAVAILABLE:
172 error =
"NOTAVAILABLE";
174 case D3DERR_OUTOFVIDEOMEMORY:
175 error =
"OUTOFVIDEOMEMORY";
177 case D3DERR_INVALIDDEVICE:
178 error =
"INVALIDDEVICE";
180 case D3DERR_INVALIDCALL:
181 error =
"INVALIDCALL";
183 case D3DERR_DRIVERINVALIDCALL:
184 error =
"DRIVERINVALIDCALL";
186 case D3DERR_WASSTILLDRAWING:
187 error =
"WASSTILLDRAWING";
201 return D3DFMT_R5G6B5;
203 return D3DFMT_X8R8G8B8;
205 return D3DFMT_A8R8G8B8;
212 return D3DFMT_UNKNOWN;
217 D3DFMTToPixelFormat(D3DFORMAT
format)
222 case D3DFMT_X8R8G8B8:
224 case D3DFMT_A8R8G8B8:
232 D3D_InitRenderState(D3D_RenderData *
data)
237 IDirect3DDevice9_SetPixelShader(
device,
NULL);
241 IDirect3DDevice9_SetFVF(
device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
242 IDirect3DDevice9_SetVertexShader(
device,
NULL);
243 IDirect3DDevice9_SetRenderState(
device, D3DRS_ZENABLE, D3DZB_FALSE);
244 IDirect3DDevice9_SetRenderState(
device, D3DRS_CULLMODE, D3DCULL_NONE);
245 IDirect3DDevice9_SetRenderState(
device, D3DRS_LIGHTING,
FALSE);
248 IDirect3DDevice9_SetTextureStageState(
device, 0, D3DTSS_COLOROP,
250 IDirect3DDevice9_SetTextureStageState(
device, 0, D3DTSS_COLORARG1,
252 IDirect3DDevice9_SetTextureStageState(
device, 0, D3DTSS_COLORARG2,
256 IDirect3DDevice9_SetTextureStageState(
device, 0, D3DTSS_ALPHAOP,
258 IDirect3DDevice9_SetTextureStageState(
device, 0, D3DTSS_ALPHAARG1,
260 IDirect3DDevice9_SetTextureStageState(
device, 0, D3DTSS_ALPHAARG2,
264 if (
data->enableSeparateAlphaBlend) {
265 IDirect3DDevice9_SetRenderState(
device, D3DRS_SEPARATEALPHABLENDENABLE,
TRUE);
269 IDirect3DDevice9_SetTextureStageState(
device, 1, D3DTSS_COLOROP,
271 IDirect3DDevice9_SetTextureStageState(
device, 1, D3DTSS_ALPHAOP,
280 IDirect3DDevice9_SetTransform(
device, D3DTS_WORLD, &
matrix);
281 IDirect3DDevice9_SetTransform(
device, D3DTS_VIEW, &
matrix);
304 data->pparams.BackBufferWidth =
w;
305 data->pparams.BackBufferHeight =
h;
310 data->pparams.BackBufferFormat = PixelFormatToD3DFMT(fullscreen_mode.
format);
314 data->pparams.BackBufferFormat = D3DFMT_UNKNOWN;
315 data->pparams.FullScreen_RefreshRateInHz = 0;
323 if (
data->beginScene) {
324 result = IDirect3DDevice9_BeginScene(
data->device);
325 if (
result == D3DERR_DEVICELOST) {
329 result = IDirect3DDevice9_BeginScene(
data->device);
332 return D3D_SetError(
"BeginScene()",
result);
353 return D3DBLEND_ZERO;
357 return D3DBLEND_SRCCOLOR;
359 return D3DBLEND_INVSRCCOLOR;
361 return D3DBLEND_SRCALPHA;
363 return D3DBLEND_INVSRCALPHA;
365 return D3DBLEND_DESTCOLOR;
367 return D3DBLEND_INVDESTCOLOR;
369 return D3DBLEND_DESTALPHA;
371 return D3DBLEND_INVDESTALPHA;
388 if (!GetBlendFunc(srcColorFactor) || !GetBlendFunc(srcAlphaFactor) ||
389 !GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor)) {
392 if ((srcColorFactor != srcAlphaFactor || dstColorFactor != dstAlphaFactor) && !
data->enableSeparateAlphaBlend) {
414 PixelFormatToD3DFMT(
format),
417 return D3D_SetError(
"CreateTexture(D3DPOOL_DEFAULT)",
result);
432 return D3D_SetError(
"CreateTexture(D3DPOOL_SYSTEMMEM)",
result);
442 IDirect3DTexture9_Release(
texture->texture);
446 IDirect3DTexture9_AddDirtyRect(
texture->staging,
NULL);
456 D3DLOCKED_RECT locked;
467 d3drect.right =
x +
w;
469 d3drect.bottom =
y +
h;
471 result = IDirect3DTexture9_LockRect(
texture->staging, 0, &locked, &d3drect, 0);
473 return D3D_SetError(
"LockRect()",
result);
485 if (
length > locked.Pitch) {
496 return D3D_SetError(
"UnlockRect()",
result);
504 D3D_DestroyTextureRep(D3D_TextureRep *
texture)
507 IDirect3DTexture9_Release(
texture->texture);
511 IDirect3DTexture9_Release(
texture->staging);
520 D3D_TextureData *texturedata;
523 texturedata = (D3D_TextureData *)
SDL_calloc(1,
sizeof(*texturedata));
529 texture->driverdata = texturedata;
532 usage = D3DUSAGE_RENDERTARGET;
560 D3D_TextureData *texturedata = (D3D_TextureData *)
texture->driverdata;
566 if (D3D_RecreateTextureRep(
data->device, &texturedata->texture) < 0) {
570 if (texturedata->yuv) {
571 if (D3D_RecreateTextureRep(
data->device, &texturedata->utexture) < 0) {
575 if (D3D_RecreateTextureRep(
data->device, &texturedata->vtexture) < 0) {
587 D3D_TextureData *texturedata = (D3D_TextureData *)
texture->driverdata;
598 if (texturedata->yuv) {
618 const Uint8 *Yplane,
int Ypitch,
619 const Uint8 *Uplane,
int Upitch,
620 const Uint8 *Vplane,
int Vpitch)
623 D3D_TextureData *texturedata = (D3D_TextureData *)
texture->driverdata;
630 if (D3D_UpdateTextureRep(
data->device, &texturedata->texture,
rect->
x,
rect->
y,
rect->
w,
rect->
h, Yplane, Ypitch) < 0) {
633 if (D3D_UpdateTextureRep(
data->device, &texturedata->utexture,
rect->
x / 2,
rect->
y / 2, (
rect->
w + 1) / 2, (
rect->
h + 1) / 2, Uplane, Upitch) < 0) {
636 if (D3D_UpdateTextureRep(
data->device, &texturedata->vtexture,
rect->
x / 2,
rect->
y / 2, (
rect->
w + 1) / 2, (
rect->
h + 1) / 2, Vplane, Vpitch) < 0) {
647 D3D_TextureData *texturedata = (D3D_TextureData *)
texture->driverdata;
655 texturedata->locked_rect = *
rect;
657 if (texturedata->yuv) {
659 if (!texturedata->pixels) {
662 if (!texturedata->pixels) {
667 (
void *) ((
Uint8 *) texturedata->pixels +
rect->
y * texturedata->pitch +
669 *pitch = texturedata->pitch;
672 D3DLOCKED_RECT locked;
675 if (D3D_CreateStagingTexture(
device, &texturedata->texture) < 0) {
679 d3drect.left =
rect->
x;
681 d3drect.top =
rect->
y;
684 result = IDirect3DTexture9_LockRect(texturedata->texture.staging, 0, &locked, &d3drect, 0);
686 return D3D_SetError(
"LockRect()",
result);
689 *pitch = locked.Pitch;
698 D3D_TextureData *texturedata = (D3D_TextureData *)
texture->driverdata;
704 if (texturedata->yuv) {
707 (
void *) ((
Uint8 *) texturedata->pixels +
rect->
y * texturedata->pitch +
711 IDirect3DTexture9_UnlockRect(texturedata->texture.staging, 0);
712 texturedata->texture.dirty =
SDL_TRUE;
716 IDirect3DDevice9_SetPixelShader(
data->device,
NULL);
717 IDirect3DDevice9_SetTexture(
data->device, 0,
NULL);
718 if (texturedata->yuv) {
719 IDirect3DDevice9_SetTexture(
data->device, 1,
NULL);
720 IDirect3DDevice9_SetTexture(
data->device, 2,
NULL);
729 D3D_TextureData *texturedata = (D3D_TextureData *)
texture->driverdata;
742 D3D_TextureData *texturedata;
743 D3D_TextureRep *texturerep;
749 IDirect3DSurface9_Release(
data->currentRenderTarget);
754 IDirect3DDevice9_SetRenderTarget(
data->device, 0,
data->defaultRenderTarget);
758 texturedata = (D3D_TextureData *)
texture->driverdata;
765 texturerep = &texturedata->texture;
766 if (texturerep->dirty && texturerep->staging) {
767 if (!texturerep->texture) {
768 result = IDirect3DDevice9_CreateTexture(
device, texturerep->w, texturerep->h, 1, texturerep->usage,
769 PixelFormatToD3DFMT(texturerep->format), D3DPOOL_DEFAULT, &texturerep->texture,
NULL);
771 return D3D_SetError(
"CreateTexture(D3DPOOL_DEFAULT)",
result);
775 result = IDirect3DDevice9_UpdateTexture(
device, (IDirect3DBaseTexture9 *)texturerep->staging, (IDirect3DBaseTexture9 *)texturerep->texture);
777 return D3D_SetError(
"UpdateTexture()",
result);
782 result = IDirect3DTexture9_GetSurfaceLevel(texturedata->texture.texture, 0, &
data->currentRenderTarget);
784 return D3D_SetError(
"GetSurfaceLevel()",
result);
786 result = IDirect3DDevice9_SetRenderTarget(
data->device, 0,
data->currentRenderTarget);
788 return D3D_SetError(
"SetRenderTarget()",
result);
797 if (D3D_ActivateRenderer(
renderer) < 0) {
815 const size_t vertslen =
count *
sizeof (Vertex);
829 verts->color =
color;
839 const size_t vertslen =
count *
sizeof (Vertex) * 4;
852 const float minx =
rect->
x;
854 const float miny =
rect->
y;
859 verts->color =
color;
864 verts->color =
color;
869 verts->color =
color;
874 verts->color =
color;
886 float minx, miny, maxx, maxy;
887 float minu, maxu, minv, maxv;
888 const size_t vertslen =
sizeof (Vertex) * 4;
897 minx = dstrect->
x - 0.5f;
898 miny = dstrect->
y - 0.5f;
899 maxx = dstrect->
x + dstrect->
w - 0.5f;
900 maxy = dstrect->
y + dstrect->
h - 0.5f;
902 minu = (float) srcrect->
x /
texture->w;
903 maxu = (
float) (srcrect->
x + srcrect->
w) /
texture->w;
904 minv = (
float) srcrect->
y /
texture->h;
905 maxv = (float) (srcrect->
y + srcrect->
h) /
texture->h;
910 verts->color =
color;
918 verts->color =
color;
926 verts->color =
color;
934 verts->color =
color;
948 float minx, miny, maxx, maxy;
949 float minu, maxu, minv, maxv;
950 const size_t vertslen =
sizeof (Vertex) * 5;
960 maxx = dstrect->
w - center->
x;
962 maxy = dstrect->
h - center->
y;
965 minu = (float) (srcquad->
x + srcquad->
w) /
texture->w;
966 maxu = (float) srcquad->
x /
texture->w;
968 minu = (float) srcquad->
x /
texture->w;
969 maxu = (
float) (srcquad->
x + srcquad->
w) /
texture->w;
973 minv = (float) (srcquad->
y + srcquad->
h) /
texture->h;
974 maxv = (float) srcquad->
y /
texture->h;
976 minv = (float) srcquad->
y /
texture->h;
977 maxv = (
float) (srcquad->
y + srcquad->
h) /
texture->h;
983 verts->color =
color;
991 verts->color =
color;
999 verts->color =
color;
1007 verts->color =
color;
1012 verts->x = dstrect->
x + center->
x - 0.5f;
1013 verts->y = dstrect->
y + center->
y - 0.5f;
1014 verts->z = (float)(M_PI * (
float)
angle / 180.0f);
1032 return D3D_SetError(
"CreateTexture(D3DPOOL_DEFAULT)",
result);
1036 result = IDirect3DDevice9_UpdateTexture(
device, (IDirect3DBaseTexture9 *)
texture->staging, (IDirect3DBaseTexture9 *)
texture->texture);
1038 return D3D_SetError(
"UpdateTexture()",
result);
1052 return D3D_SetError(
"SetTexture()",
result);
1058 UpdateTextureScaleMode(D3D_RenderData *
data, D3D_TextureData *texturedata,
unsigned index)
1060 if (texturedata->scaleMode !=
data->scaleMode[
index]) {
1061 IDirect3DDevice9_SetSamplerState(
data->device,
index, D3DSAMP_MINFILTER,
1062 texturedata->scaleMode);
1063 IDirect3DDevice9_SetSamplerState(
data->device,
index, D3DSAMP_MAGFILTER,
1064 texturedata->scaleMode);
1065 IDirect3DDevice9_SetSamplerState(
data->device,
index, D3DSAMP_ADDRESSU,
1067 IDirect3DDevice9_SetSamplerState(
data->device,
index, D3DSAMP_ADDRESSV,
1069 data->scaleMode[
index] = texturedata->scaleMode;
1076 D3D_TextureData *texturedata = (D3D_TextureData *)
texture->driverdata;
1085 UpdateTextureScaleMode(
data, texturedata, 0);
1087 if (BindTextureRep(
data->device, &texturedata->texture, 0) < 0) {
1091 if (texturedata->yuv) {
1103 return SDL_SetError(
"Unsupported YUV conversion mode");
1106 UpdateTextureScaleMode(
data, texturedata, 1);
1107 UpdateTextureScaleMode(
data, texturedata, 2);
1109 if (BindTextureRep(
data->device, &texturedata->utexture, 1) < 0) {
1112 if (BindTextureRep(
data->device, &texturedata->vtexture, 2) < 0) {
1122 const SDL_bool was_copy_ex =
data->drawstate.is_copy_ex;
1128 D3D_TextureData *oldtexturedata =
data->drawstate.texture ? (D3D_TextureData *)
data->drawstate.texture->driverdata :
NULL;
1129 D3D_TextureData *newtexturedata =
texture ? (D3D_TextureData *)
texture->driverdata :
NULL;
1134 IDirect3DDevice9_SetTexture(
data->device, 0,
NULL);
1136 if ((!newtexturedata || !newtexturedata->yuv) && (oldtexturedata && oldtexturedata->yuv)) {
1137 IDirect3DDevice9_SetTexture(
data->device, 1,
NULL);
1138 IDirect3DDevice9_SetTexture(
data->device, 2,
NULL);
1145 const HRESULT
result = IDirect3DDevice9_SetPixelShader(
data->device,
shader);
1147 return D3D_SetError(
"IDirect3DDevice9_SetPixelShader()",
result);
1154 D3D_TextureData *texturedata = (D3D_TextureData *)
texture->driverdata;
1155 UpdateDirtyTexture(
data->device, &texturedata->texture);
1156 if (texturedata->yuv) {
1157 UpdateDirtyTexture(
data->device, &texturedata->utexture);
1158 UpdateDirtyTexture(
data->device, &texturedata->vtexture);
1162 if (blend !=
data->drawstate.blend) {
1164 IDirect3DDevice9_SetRenderState(
data->device, D3DRS_ALPHABLENDENABLE,
FALSE);
1166 IDirect3DDevice9_SetRenderState(
data->device, D3DRS_ALPHABLENDENABLE,
TRUE);
1167 IDirect3DDevice9_SetRenderState(
data->device, D3DRS_SRCBLEND,
1169 IDirect3DDevice9_SetRenderState(
data->device, D3DRS_DESTBLEND,
1171 if (
data->enableSeparateAlphaBlend) {
1172 IDirect3DDevice9_SetRenderState(
data->device, D3DRS_SRCBLENDALPHA,
1174 IDirect3DDevice9_SetRenderState(
data->device, D3DRS_DESTBLENDALPHA,
1179 data->drawstate.blend = blend;
1182 if (is_copy_ex != was_copy_ex) {
1184 const Float4X4 d3dmatrix = MatrixIdentity();
1185 IDirect3DDevice9_SetTransform(
data->device, D3DTS_VIEW, (D3DMATRIX*) &d3dmatrix);
1187 data->drawstate.is_copy_ex = is_copy_ex;
1190 if (
data->drawstate.viewport_dirty) {
1193 IDirect3DDevice9_SetViewport(
data->device, &d3dviewport);
1197 D3DMATRIX d3dmatrix;
1200 d3dmatrix.m[1][1] = -2.0f /
viewport->
h;
1201 d3dmatrix.m[2][2] = 1.0f;
1202 d3dmatrix.m[3][0] = -1.0f;
1203 d3dmatrix.m[3][1] = 1.0f;
1204 d3dmatrix.m[3][3] = 1.0f;
1205 IDirect3DDevice9_SetTransform(
data->device, D3DTS_PROJECTION, &d3dmatrix);
1211 if (
data->drawstate.cliprect_enabled_dirty) {
1212 IDirect3DDevice9_SetRenderState(
data->device, D3DRS_SCISSORTESTENABLE,
data->drawstate.cliprect_enabled ?
TRUE :
FALSE);
1216 if (
data->drawstate.cliprect_dirty) {
1220 IDirect3DDevice9_SetScissorRect(
data->device, &d3drect);
1231 const int vboidx =
data->currentVertexBuffer;
1232 IDirect3DVertexBuffer9 *vbo =
NULL;
1241 vbo =
data->vertexBuffers[vboidx];
1242 if (
data->vertexBufferSize[vboidx] < vertsize) {
1243 const DWORD
usage = D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY;
1244 const DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1;
1246 IDirect3DVertexBuffer9_Release(vbo);
1249 if (
FAILED(IDirect3DDevice9_CreateVertexBuffer(
data->device, (UINT) vertsize,
usage, fvf, D3DPOOL_DEFAULT, &vbo,
NULL))) {
1252 data->vertexBuffers[vboidx] = vbo;
1253 data->vertexBufferSize[vboidx] = vbo ? vertsize : 0;
1258 if (
FAILED(IDirect3DVertexBuffer9_Lock(vbo, 0, (UINT) vertsize, &
ptr, D3DLOCK_DISCARD))) {
1262 if (
FAILED(IDirect3DVertexBuffer9_Unlock(vbo))) {
1270 data->currentVertexBuffer++;
1272 data->currentVertexBuffer = 0;
1274 }
else if (!
data->reportedVboProblem) {
1282 IDirect3DDevice9_SetStreamSource(
data->device, 0, vbo, 0, sizeof (Vertex));
1322 if (
data->drawstate.cliprect_enabled) {
1323 IDirect3DDevice9_SetRenderState(
data->device, D3DRS_SCISSORTESTENABLE,
FALSE);
1329 IDirect3DDevice9_Clear(
data->device, 0,
NULL, D3DCLEAR_TARGET,
color, 0.0f, 0);
1332 const D3DVIEWPORT9 wholeviewport = { 0, 0, backw, backh, 0.0f, 1.0f };
1333 IDirect3DDevice9_SetViewport(
data->device, &wholeviewport);
1335 IDirect3DDevice9_Clear(
data->device, 0,
NULL, D3DCLEAR_TARGET,
color, 0.0f, 0);
1346 IDirect3DDevice9_DrawPrimitive(
data->device, D3DPT_POINTLIST, (UINT) (
first / sizeof (Vertex)), (UINT)
count);
1348 const Vertex *verts = (Vertex *) (((
Uint8 *) vertices) +
first);
1349 IDirect3DDevice9_DrawPrimitiveUP(
data->device, D3DPT_POINTLIST, (UINT)
count, verts, sizeof (Vertex));
1357 const Vertex *verts = (Vertex *) (((
Uint8 *) vertices) +
first);
1366 IDirect3DDevice9_DrawPrimitive(
data->device, D3DPT_LINESTRIP, (UINT) (
first / sizeof (Vertex)), (UINT) (
count - 1));
1367 if (close_endpoint) {
1368 IDirect3DDevice9_DrawPrimitive(
data->device, D3DPT_POINTLIST, (UINT) ((
first / sizeof (Vertex)) + (
count - 1)), 1);
1371 IDirect3DDevice9_DrawPrimitiveUP(
data->device, D3DPT_LINESTRIP, (UINT) (
count - 1), verts, sizeof (Vertex));
1372 if (close_endpoint) {
1373 IDirect3DDevice9_DrawPrimitiveUP(
data->device, D3DPT_POINTLIST, 1, &verts[
count-1], sizeof (Vertex));
1386 IDirect3DDevice9_DrawPrimitive(
data->device, D3DPT_TRIANGLEFAN, (UINT) ((
first / sizeof (Vertex)) +
offset), 2);
1389 const Vertex *verts = (Vertex *) (((
Uint8 *) vertices) +
first);
1390 for (
i = 0;
i <
count; ++
i, verts += 4) {
1391 IDirect3DDevice9_DrawPrimitiveUP(
data->device, D3DPT_TRIANGLEFAN, 2, verts, sizeof (Vertex));
1404 IDirect3DDevice9_DrawPrimitive(
data->device, D3DPT_TRIANGLEFAN, (UINT) ((
first / sizeof (Vertex)) +
offset), 2);
1407 const Vertex *verts = (Vertex *) (((
Uint8 *) vertices) +
first);
1408 for (
i = 0;
i <
count; ++
i, verts += 4) {
1409 IDirect3DDevice9_DrawPrimitiveUP(
data->device, D3DPT_TRIANGLEFAN, 2, verts, sizeof (Vertex));
1417 const Vertex *verts = (Vertex *) (((
Uint8 *) vertices) +
first);
1418 const Vertex *transvert = verts + 4;
1419 const float translatex = transvert->x;
1420 const float translatey = transvert->y;
1421 const float rotation = transvert->z;
1422 const Float4X4 d3dmatrix = MatrixMultiply(MatrixRotationZ(rotation), MatrixTranslation(translatex, translatey, 0));
1425 IDirect3DDevice9_SetTransform(
data->device, D3DTS_VIEW, (D3DMATRIX*)&d3dmatrix);
1428 IDirect3DDevice9_DrawPrimitive(
data->device, D3DPT_TRIANGLEFAN, (UINT) (
first / sizeof (Vertex)), 2);
1430 IDirect3DDevice9_DrawPrimitiveUP(
data->device, D3DPT_TRIANGLEFAN, 2, verts, sizeof (Vertex));
1451 D3DSURFACE_DESC desc;
1452 LPDIRECT3DSURFACE9 backBuffer;
1455 D3DLOCKED_RECT locked;
1458 if (
data->currentRenderTarget) {
1459 backBuffer =
data->currentRenderTarget;
1461 backBuffer =
data->defaultRenderTarget;
1464 result = IDirect3DSurface9_GetDesc(backBuffer, &desc);
1466 return D3D_SetError(
"GetDesc()",
result);
1469 result = IDirect3DDevice9_CreateOffscreenPlainSurface(
data->device, desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &
surface,
NULL);
1471 return D3D_SetError(
"CreateOffscreenPlainSurface()",
result);
1474 result = IDirect3DDevice9_GetRenderTargetData(
data->device, backBuffer,
surface);
1476 IDirect3DSurface9_Release(
surface);
1477 return D3D_SetError(
"GetRenderTargetData()",
result);
1480 d3drect.left =
rect->
x;
1482 d3drect.top =
rect->
y;
1485 result = IDirect3DSurface9_LockRect(
surface, &locked, &d3drect, D3DLOCK_READONLY);
1487 IDirect3DSurface9_Release(
surface);
1488 return D3D_SetError(
"LockRect()",
result);
1492 D3DFMTToPixelFormat(desc.Format), locked.pBits, locked.Pitch,
1495 IDirect3DSurface9_UnlockRect(
surface);
1497 IDirect3DSurface9_Release(
surface);
1509 IDirect3DDevice9_EndScene(
data->device);
1513 result = IDirect3DDevice9_TestCooperativeLevel(
data->device);
1514 if (
result == D3DERR_DEVICELOST) {
1518 if (
result == D3DERR_DEVICENOTRESET) {
1523 D3D_SetError(
"Present()",
result);
1531 D3D_TextureData *
data = (D3D_TextureData *)
texture->driverdata;
1533 if (renderdata->drawstate.texture ==
texture) {
1534 renderdata->drawstate.texture =
NULL;
1535 renderdata->drawstate.shader =
NULL;
1536 IDirect3DDevice9_SetPixelShader(renderdata->device,
NULL);
1537 IDirect3DDevice9_SetTexture(renderdata->device, 0,
NULL);
1539 IDirect3DDevice9_SetTexture(renderdata->device, 1,
NULL);
1540 IDirect3DDevice9_SetTexture(renderdata->device, 2,
NULL);
1548 D3D_DestroyTextureRep(&
data->texture);
1549 D3D_DestroyTextureRep(&
data->utexture);
1550 D3D_DestroyTextureRep(&
data->vtexture);
1565 if (
data->defaultRenderTarget) {
1566 IDirect3DSurface9_Release(
data->defaultRenderTarget);
1569 if (
data->currentRenderTarget !=
NULL) {
1570 IDirect3DSurface9_Release(
data->currentRenderTarget);
1574 if (
data->shaders[
i]) {
1575 IDirect3DPixelShader9_Release(
data->shaders[
i]);
1581 if (
data->vertexBuffers[
i]) {
1582 IDirect3DVertexBuffer9_Release(
data->vertexBuffers[
i]);
1587 IDirect3DDevice9_Release(
data->device);
1591 IDirect3D9_Release(
data->d3d);
1603 const Float4X4 d3dmatrix = MatrixIdentity();
1609 if (
data->defaultRenderTarget) {
1610 IDirect3DSurface9_Release(
data->defaultRenderTarget);
1613 if (
data->currentRenderTarget !=
NULL) {
1614 IDirect3DSurface9_Release(
data->currentRenderTarget);
1629 if (
data->vertexBuffers[
i]) {
1630 IDirect3DVertexBuffer9_Release(
data->vertexBuffers[
i]);
1633 data->vertexBufferSize[
i] = 0;
1638 if (
result == D3DERR_DEVICELOST) {
1642 return D3D_SetError(
"Reset()",
result);
1653 IDirect3DDevice9_GetRenderTarget(
data->device, 0, &
data->defaultRenderTarget);
1654 D3D_InitRenderState(
data);
1663 IDirect3DDevice9_SetTransform(
data->device, D3DTS_VIEW, (D3DMATRIX*)&d3dmatrix);
1679 D3D_RenderData *
data;
1682 D3DPRESENT_PARAMETERS pparams;
1683 IDirect3DSwapChain9 *chain;
1744 pparams.hDeviceWindow = windowinfo.
info.win.
window;
1745 pparams.BackBufferWidth =
w;
1746 pparams.BackBufferHeight =
h;
1747 pparams.BackBufferCount = 1;
1748 pparams.SwapEffect = D3DSWAPEFFECT_DISCARD;
1751 pparams.Windowed =
FALSE;
1752 pparams.BackBufferFormat = PixelFormatToD3DFMT(fullscreen_mode.
format);
1753 pparams.FullScreen_RefreshRateInHz = fullscreen_mode.
refresh_rate;
1755 pparams.Windowed =
TRUE;
1756 pparams.BackBufferFormat = D3DFMT_UNKNOWN;
1757 pparams.FullScreen_RefreshRateInHz = 0;
1760 pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
1762 pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
1769 IDirect3D9_GetDeviceCaps(
data->d3d,
data->adapter, D3DDEVTYPE_HAL, &caps);
1771 device_flags = D3DCREATE_FPU_PRESERVE;
1772 if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) {
1773 device_flags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
1775 device_flags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
1779 device_flags |= D3DCREATE_MULTITHREADED;
1784 pparams.hDeviceWindow,
1786 &pparams, &
data->device);
1789 D3D_SetError(
"CreateDevice()",
result);
1794 result = IDirect3DDevice9_GetSwapChain(
data->device, 0, &chain);
1797 D3D_SetError(
"GetSwapChain()",
result);
1800 result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams);
1802 IDirect3DSwapChain9_Release(chain);
1804 D3D_SetError(
"GetPresentParameters()",
result);
1807 IDirect3DSwapChain9_Release(chain);
1808 if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) {
1811 data->pparams = pparams;
1813 IDirect3DDevice9_GetDeviceCaps(
data->device, &caps);
1816 if (caps.NumSimultaneousRTs >= 2) {
1820 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND) {
1825 IDirect3DDevice9_GetRenderTarget(
data->device, 0, &
data->defaultRenderTarget);
1829 D3D_InitRenderState(
data);
1831 if (caps.MaxSimultaneousTextures >= 3) {
1836 D3D_SetError(
"CreatePixelShader()",
result);
1869 #if SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED
1880 IDirect3DDevice9_AddRef(
device);