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
55 LPDIRECT3DPIXELSHADER9
shader;
67 D3DPRESENT_PARAMETERS pparams;
71 D3DTEXTUREFILTERTYPE scaleMode[8];
72 IDirect3DSurface9 *defaultRenderTarget;
73 IDirect3DSurface9 *currentRenderTarget;
76 LPDIRECT3DVERTEXBUFFER9 vertexBuffers[8];
77 size_t vertexBufferSize[8];
78 int currentVertexBuffer;
80 D3D_DrawStateCache drawstate;
91 IDirect3DTexture9 *staging;
97 D3DTEXTUREFILTERTYPE scaleMode;
101 D3D_TextureRep utexture;
102 D3D_TextureRep vtexture;
116 D3D_SetError(
const char *prefix, HRESULT
result)
121 case D3DERR_WRONGTEXTUREFORMAT:
122 error =
"WRONGTEXTUREFORMAT";
124 case D3DERR_UNSUPPORTEDCOLOROPERATION:
125 error =
"UNSUPPORTEDCOLOROPERATION";
127 case D3DERR_UNSUPPORTEDCOLORARG:
128 error =
"UNSUPPORTEDCOLORARG";
130 case D3DERR_UNSUPPORTEDALPHAOPERATION:
131 error =
"UNSUPPORTEDALPHAOPERATION";
133 case D3DERR_UNSUPPORTEDALPHAARG:
134 error =
"UNSUPPORTEDALPHAARG";
136 case D3DERR_TOOMANYOPERATIONS:
137 error =
"TOOMANYOPERATIONS";
139 case D3DERR_CONFLICTINGTEXTUREFILTER:
140 error =
"CONFLICTINGTEXTUREFILTER";
142 case D3DERR_UNSUPPORTEDFACTORVALUE:
143 error =
"UNSUPPORTEDFACTORVALUE";
145 case D3DERR_CONFLICTINGRENDERSTATE:
146 error =
"CONFLICTINGRENDERSTATE";
148 case D3DERR_UNSUPPORTEDTEXTUREFILTER:
149 error =
"UNSUPPORTEDTEXTUREFILTER";
151 case D3DERR_CONFLICTINGTEXTUREPALETTE:
152 error =
"CONFLICTINGTEXTUREPALETTE";
154 case D3DERR_DRIVERINTERNALERROR:
155 error =
"DRIVERINTERNALERROR";
157 case D3DERR_NOTFOUND:
160 case D3DERR_MOREDATA:
163 case D3DERR_DEVICELOST:
164 error =
"DEVICELOST";
166 case D3DERR_DEVICENOTRESET:
167 error =
"DEVICENOTRESET";
169 case D3DERR_NOTAVAILABLE:
170 error =
"NOTAVAILABLE";
172 case D3DERR_OUTOFVIDEOMEMORY:
173 error =
"OUTOFVIDEOMEMORY";
175 case D3DERR_INVALIDDEVICE:
176 error =
"INVALIDDEVICE";
178 case D3DERR_INVALIDCALL:
179 error =
"INVALIDCALL";
181 case D3DERR_DRIVERINVALIDCALL:
182 error =
"DRIVERINVALIDCALL";
184 case D3DERR_WASSTILLDRAWING:
185 error =
"WASSTILLDRAWING";
199 return D3DFMT_R5G6B5;
201 return D3DFMT_X8R8G8B8;
203 return D3DFMT_A8R8G8B8;
210 return D3DFMT_UNKNOWN;
215 D3DFMTToPixelFormat(D3DFORMAT
format)
220 case D3DFMT_X8R8G8B8:
222 case D3DFMT_A8R8G8B8:
230 D3D_InitRenderState(D3D_RenderData *
data)
235 IDirect3DDevice9_SetPixelShader(
device,
NULL);
239 IDirect3DDevice9_SetFVF(
device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
240 IDirect3DDevice9_SetVertexShader(
device,
NULL);
241 IDirect3DDevice9_SetRenderState(
device, D3DRS_ZENABLE, D3DZB_FALSE);
242 IDirect3DDevice9_SetRenderState(
device, D3DRS_CULLMODE, D3DCULL_NONE);
243 IDirect3DDevice9_SetRenderState(
device, D3DRS_LIGHTING,
FALSE);
246 IDirect3DDevice9_SetTextureStageState(
device, 0, D3DTSS_COLOROP,
248 IDirect3DDevice9_SetTextureStageState(
device, 0, D3DTSS_COLORARG1,
250 IDirect3DDevice9_SetTextureStageState(
device, 0, D3DTSS_COLORARG2,
254 IDirect3DDevice9_SetTextureStageState(
device, 0, D3DTSS_ALPHAOP,
256 IDirect3DDevice9_SetTextureStageState(
device, 0, D3DTSS_ALPHAARG1,
258 IDirect3DDevice9_SetTextureStageState(
device, 0, D3DTSS_ALPHAARG2,
262 if (
data->enableSeparateAlphaBlend) {
263 IDirect3DDevice9_SetRenderState(
device, D3DRS_SEPARATEALPHABLENDENABLE,
TRUE);
267 IDirect3DDevice9_SetTextureStageState(
device, 1, D3DTSS_COLOROP,
269 IDirect3DDevice9_SetTextureStageState(
device, 1, D3DTSS_ALPHAOP,
278 IDirect3DDevice9_SetTransform(
device, D3DTS_WORLD, &
matrix);
279 IDirect3DDevice9_SetTransform(
device, D3DTS_VIEW, &
matrix);
302 data->pparams.BackBufferWidth =
w;
303 data->pparams.BackBufferHeight =
h;
308 data->pparams.BackBufferFormat = PixelFormatToD3DFMT(fullscreen_mode.
format);
312 data->pparams.BackBufferFormat = D3DFMT_UNKNOWN;
313 data->pparams.FullScreen_RefreshRateInHz = 0;
321 if (
data->beginScene) {
322 result = IDirect3DDevice9_BeginScene(
data->device);
323 if (
result == D3DERR_DEVICELOST) {
327 result = IDirect3DDevice9_BeginScene(
data->device);
330 return D3D_SetError(
"BeginScene()",
result);
351 return D3DBLEND_ZERO;
355 return D3DBLEND_SRCCOLOR;
357 return D3DBLEND_INVSRCCOLOR;
359 return D3DBLEND_SRCALPHA;
361 return D3DBLEND_INVSRCALPHA;
363 return D3DBLEND_DESTCOLOR;
365 return D3DBLEND_INVDESTCOLOR;
367 return D3DBLEND_DESTALPHA;
369 return D3DBLEND_INVDESTALPHA;
386 if (!GetBlendFunc(srcColorFactor) || !GetBlendFunc(srcAlphaFactor) ||
387 !GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor)) {
390 if ((srcColorFactor != srcAlphaFactor || dstColorFactor != dstAlphaFactor) && !
data->enableSeparateAlphaBlend) {
412 PixelFormatToD3DFMT(
format),
415 return D3D_SetError(
"CreateTexture(D3DPOOL_DEFAULT)",
result);
430 return D3D_SetError(
"CreateTexture(D3DPOOL_SYSTEMMEM)",
result);
440 IDirect3DTexture9_Release(
texture->texture);
444 IDirect3DTexture9_AddDirtyRect(
texture->staging,
NULL);
454 D3DLOCKED_RECT locked;
465 d3drect.right =
x +
w;
467 d3drect.bottom =
y +
h;
469 result = IDirect3DTexture9_LockRect(
texture->staging, 0, &locked, &d3drect, 0);
471 return D3D_SetError(
"LockRect()",
result);
483 if (
length > locked.Pitch) {
494 return D3D_SetError(
"UnlockRect()",
result);
502 D3D_DestroyTextureRep(D3D_TextureRep *
texture)
505 IDirect3DTexture9_Release(
texture->texture);
509 IDirect3DTexture9_Release(
texture->staging);
518 D3D_TextureData *texturedata;
521 texturedata = (D3D_TextureData *)
SDL_calloc(1,
sizeof(*texturedata));
527 texture->driverdata = texturedata;
530 usage = D3DUSAGE_RENDERTARGET;
558 D3D_TextureData *texturedata = (D3D_TextureData *)
texture->driverdata;
564 if (D3D_RecreateTextureRep(
data->device, &texturedata->texture) < 0) {
568 if (texturedata->yuv) {
569 if (D3D_RecreateTextureRep(
data->device, &texturedata->utexture) < 0) {
573 if (D3D_RecreateTextureRep(
data->device, &texturedata->vtexture) < 0) {
585 D3D_TextureData *texturedata = (D3D_TextureData *)
texture->driverdata;
596 if (texturedata->yuv) {
616 const Uint8 *Yplane,
int Ypitch,
617 const Uint8 *Uplane,
int Upitch,
618 const Uint8 *Vplane,
int Vpitch)
621 D3D_TextureData *texturedata = (D3D_TextureData *)
texture->driverdata;
628 if (D3D_UpdateTextureRep(
data->device, &texturedata->texture,
rect->
x,
rect->
y,
rect->
w,
rect->
h, Yplane, Ypitch) < 0) {
631 if (D3D_UpdateTextureRep(
data->device, &texturedata->utexture,
rect->
x / 2,
rect->
y / 2, (
rect->
w + 1) / 2, (
rect->
h + 1) / 2, Uplane, Upitch) < 0) {
634 if (D3D_UpdateTextureRep(
data->device, &texturedata->vtexture,
rect->
x / 2,
rect->
y / 2, (
rect->
w + 1) / 2, (
rect->
h + 1) / 2, Vplane, Vpitch) < 0) {
645 D3D_TextureData *texturedata = (D3D_TextureData *)
texture->driverdata;
653 texturedata->locked_rect = *
rect;
655 if (texturedata->yuv) {
657 if (!texturedata->pixels) {
660 if (!texturedata->pixels) {
665 (
void *) ((
Uint8 *) texturedata->pixels +
rect->
y * texturedata->pitch +
667 *pitch = texturedata->pitch;
670 D3DLOCKED_RECT locked;
673 if (D3D_CreateStagingTexture(
device, &texturedata->texture) < 0) {
677 d3drect.left =
rect->
x;
679 d3drect.top =
rect->
y;
682 result = IDirect3DTexture9_LockRect(texturedata->texture.staging, 0, &locked, &d3drect, 0);
684 return D3D_SetError(
"LockRect()",
result);
687 *pitch = locked.Pitch;
696 D3D_TextureData *texturedata = (D3D_TextureData *)
texture->driverdata;
702 if (texturedata->yuv) {
705 (
void *) ((
Uint8 *) texturedata->pixels +
rect->
y * texturedata->pitch +
709 IDirect3DTexture9_UnlockRect(texturedata->texture.staging, 0);
710 texturedata->texture.dirty =
SDL_TRUE;
714 IDirect3DDevice9_SetPixelShader(
data->device,
NULL);
715 IDirect3DDevice9_SetTexture(
data->device, 0,
NULL);
716 if (texturedata->yuv) {
717 IDirect3DDevice9_SetTexture(
data->device, 1,
NULL);
718 IDirect3DDevice9_SetTexture(
data->device, 2,
NULL);
727 D3D_TextureData *texturedata = (D3D_TextureData *)
texture->driverdata;
740 D3D_TextureData *texturedata;
741 D3D_TextureRep *texturerep;
747 IDirect3DSurface9_Release(
data->currentRenderTarget);
752 IDirect3DDevice9_SetRenderTarget(
data->device, 0,
data->defaultRenderTarget);
756 texturedata = (D3D_TextureData *)
texture->driverdata;
763 texturerep = &texturedata->texture;
764 if (texturerep->dirty && texturerep->staging) {
765 if (!texturerep->texture) {
766 result = IDirect3DDevice9_CreateTexture(
device, texturerep->w, texturerep->h, 1, texturerep->usage,
767 PixelFormatToD3DFMT(texturerep->format), D3DPOOL_DEFAULT, &texturerep->texture,
NULL);
769 return D3D_SetError(
"CreateTexture(D3DPOOL_DEFAULT)",
result);
773 result = IDirect3DDevice9_UpdateTexture(
device, (IDirect3DBaseTexture9 *)texturerep->staging, (IDirect3DBaseTexture9 *)texturerep->texture);
775 return D3D_SetError(
"UpdateTexture()",
result);
780 result = IDirect3DTexture9_GetSurfaceLevel(texturedata->texture.texture, 0, &
data->currentRenderTarget);
782 return D3D_SetError(
"GetSurfaceLevel()",
result);
784 result = IDirect3DDevice9_SetRenderTarget(
data->device, 0,
data->currentRenderTarget);
786 return D3D_SetError(
"SetRenderTarget()",
result);
795 if (D3D_ActivateRenderer(
renderer) < 0) {
813 const size_t vertslen =
count *
sizeof (Vertex);
827 verts->color =
color;
837 const size_t vertslen =
count *
sizeof (Vertex) * 4;
850 const float minx =
rect->
x;
852 const float miny =
rect->
y;
857 verts->color =
color;
862 verts->color =
color;
867 verts->color =
color;
872 verts->color =
color;
884 float minx, miny, maxx, maxy;
885 float minu, maxu, minv, maxv;
886 const size_t vertslen =
sizeof (Vertex) * 4;
895 minx = dstrect->
x - 0.5f;
896 miny = dstrect->
y - 0.5f;
897 maxx = dstrect->
x + dstrect->
w - 0.5f;
898 maxy = dstrect->
y + dstrect->
h - 0.5f;
900 minu = (float) srcrect->
x /
texture->w;
901 maxu = (
float) (srcrect->
x + srcrect->
w) /
texture->w;
902 minv = (
float) srcrect->
y /
texture->h;
903 maxv = (float) (srcrect->
y + srcrect->
h) /
texture->h;
908 verts->color =
color;
916 verts->color =
color;
924 verts->color =
color;
932 verts->color =
color;
946 float minx, miny, maxx, maxy;
947 float minu, maxu, minv, maxv;
948 const size_t vertslen =
sizeof (Vertex) * 5;
958 maxx = dstrect->
w - center->
x;
960 maxy = dstrect->
h - center->
y;
963 minu = (float) (srcquad->
x + srcquad->
w) /
texture->w;
964 maxu = (float) srcquad->
x /
texture->w;
966 minu = (float) srcquad->
x /
texture->w;
967 maxu = (
float) (srcquad->
x + srcquad->
w) /
texture->w;
971 minv = (float) (srcquad->
y + srcquad->
h) /
texture->h;
972 maxv = (float) srcquad->
y /
texture->h;
974 minv = (float) srcquad->
y /
texture->h;
975 maxv = (
float) (srcquad->
y + srcquad->
h) /
texture->h;
981 verts->color =
color;
989 verts->color =
color;
997 verts->color =
color;
1005 verts->color =
color;
1010 verts->x = dstrect->
x + center->
x - 0.5f;
1011 verts->y = dstrect->
y + center->
y - 0.5f;
1012 verts->z = (float)(M_PI * (
float)
angle / 180.0f);
1030 return D3D_SetError(
"CreateTexture(D3DPOOL_DEFAULT)",
result);
1034 result = IDirect3DDevice9_UpdateTexture(
device, (IDirect3DBaseTexture9 *)
texture->staging, (IDirect3DBaseTexture9 *)
texture->texture);
1036 return D3D_SetError(
"UpdateTexture()",
result);
1050 return D3D_SetError(
"SetTexture()",
result);
1056 UpdateTextureScaleMode(D3D_RenderData *
data, D3D_TextureData *texturedata,
unsigned index)
1058 if (texturedata->scaleMode !=
data->scaleMode[
index]) {
1059 IDirect3DDevice9_SetSamplerState(
data->device,
index, D3DSAMP_MINFILTER,
1060 texturedata->scaleMode);
1061 IDirect3DDevice9_SetSamplerState(
data->device,
index, D3DSAMP_MAGFILTER,
1062 texturedata->scaleMode);
1063 IDirect3DDevice9_SetSamplerState(
data->device,
index, D3DSAMP_ADDRESSU,
1065 IDirect3DDevice9_SetSamplerState(
data->device,
index, D3DSAMP_ADDRESSV,
1067 data->scaleMode[
index] = texturedata->scaleMode;
1074 D3D_TextureData *texturedata = (D3D_TextureData *)
texture->driverdata;
1083 UpdateTextureScaleMode(
data, texturedata, 0);
1085 if (BindTextureRep(
data->device, &texturedata->texture, 0) < 0) {
1089 if (texturedata->yuv) {
1101 return SDL_SetError(
"Unsupported YUV conversion mode");
1104 UpdateTextureScaleMode(
data, texturedata, 1);
1105 UpdateTextureScaleMode(
data, texturedata, 2);
1107 if (BindTextureRep(
data->device, &texturedata->utexture, 1) < 0) {
1110 if (BindTextureRep(
data->device, &texturedata->vtexture, 2) < 0) {
1120 const SDL_bool was_copy_ex =
data->drawstate.is_copy_ex;
1126 D3D_TextureData *oldtexturedata =
data->drawstate.texture ? (D3D_TextureData *)
data->drawstate.texture->driverdata :
NULL;
1127 D3D_TextureData *newtexturedata =
texture ? (D3D_TextureData *)
texture->driverdata :
NULL;
1132 IDirect3DDevice9_SetTexture(
data->device, 0,
NULL);
1134 if ((!newtexturedata || !newtexturedata->yuv) && (oldtexturedata && oldtexturedata->yuv)) {
1135 IDirect3DDevice9_SetTexture(
data->device, 1,
NULL);
1136 IDirect3DDevice9_SetTexture(
data->device, 2,
NULL);
1143 const HRESULT
result = IDirect3DDevice9_SetPixelShader(
data->device,
shader);
1145 return D3D_SetError(
"IDirect3DDevice9_SetPixelShader()",
result);
1152 D3D_TextureData *texturedata = (D3D_TextureData *)
texture->driverdata;
1153 UpdateDirtyTexture(
data->device, &texturedata->texture);
1154 if (texturedata->yuv) {
1155 UpdateDirtyTexture(
data->device, &texturedata->utexture);
1156 UpdateDirtyTexture(
data->device, &texturedata->vtexture);
1160 if (blend !=
data->drawstate.blend) {
1162 IDirect3DDevice9_SetRenderState(
data->device, D3DRS_ALPHABLENDENABLE,
FALSE);
1164 IDirect3DDevice9_SetRenderState(
data->device, D3DRS_ALPHABLENDENABLE,
TRUE);
1165 IDirect3DDevice9_SetRenderState(
data->device, D3DRS_SRCBLEND,
1167 IDirect3DDevice9_SetRenderState(
data->device, D3DRS_DESTBLEND,
1169 if (
data->enableSeparateAlphaBlend) {
1170 IDirect3DDevice9_SetRenderState(
data->device, D3DRS_SRCBLENDALPHA,
1172 IDirect3DDevice9_SetRenderState(
data->device, D3DRS_DESTBLENDALPHA,
1177 data->drawstate.blend = blend;
1180 if (is_copy_ex != was_copy_ex) {
1182 const Float4X4 d3dmatrix = MatrixIdentity();
1183 IDirect3DDevice9_SetTransform(
data->device, D3DTS_VIEW, (D3DMATRIX*) &d3dmatrix);
1185 data->drawstate.is_copy_ex = is_copy_ex;
1188 if (
data->drawstate.viewport_dirty) {
1191 IDirect3DDevice9_SetViewport(
data->device, &d3dviewport);
1195 D3DMATRIX d3dmatrix;
1198 d3dmatrix.m[1][1] = -2.0f /
viewport->
h;
1199 d3dmatrix.m[2][2] = 1.0f;
1200 d3dmatrix.m[3][0] = -1.0f;
1201 d3dmatrix.m[3][1] = 1.0f;
1202 d3dmatrix.m[3][3] = 1.0f;
1203 IDirect3DDevice9_SetTransform(
data->device, D3DTS_PROJECTION, &d3dmatrix);
1209 if (
data->drawstate.cliprect_enabled_dirty) {
1210 IDirect3DDevice9_SetRenderState(
data->device, D3DRS_SCISSORTESTENABLE,
data->drawstate.cliprect_enabled ?
TRUE :
FALSE);
1214 if (
data->drawstate.cliprect_dirty) {
1218 IDirect3DDevice9_SetScissorRect(
data->device, &d3drect);
1229 const int vboidx =
data->currentVertexBuffer;
1230 IDirect3DVertexBuffer9 *vbo =
NULL;
1239 vbo =
data->vertexBuffers[vboidx];
1240 if (
data->vertexBufferSize[vboidx] < vertsize) {
1241 const DWORD
usage = D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY;
1242 const DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1;
1244 IDirect3DVertexBuffer9_Release(vbo);
1247 if (
FAILED(IDirect3DDevice9_CreateVertexBuffer(
data->device, (UINT) vertsize,
usage, fvf, D3DPOOL_DEFAULT, &vbo,
NULL))) {
1250 data->vertexBuffers[vboidx] = vbo;
1251 data->vertexBufferSize[vboidx] = vbo ? vertsize : 0;
1256 if (
FAILED(IDirect3DVertexBuffer9_Lock(vbo, 0, (UINT) vertsize, &
ptr, D3DLOCK_DISCARD))) {
1260 if (
FAILED(IDirect3DVertexBuffer9_Unlock(vbo))) {
1268 data->currentVertexBuffer++;
1270 data->currentVertexBuffer = 0;
1272 }
else if (!
data->reportedVboProblem) {
1280 IDirect3DDevice9_SetStreamSource(
data->device, 0, vbo, 0, sizeof (Vertex));
1320 if (
data->drawstate.cliprect_enabled) {
1321 IDirect3DDevice9_SetRenderState(
data->device, D3DRS_SCISSORTESTENABLE,
FALSE);
1327 IDirect3DDevice9_Clear(
data->device, 0,
NULL, D3DCLEAR_TARGET,
color, 0.0f, 0);
1330 const D3DVIEWPORT9 wholeviewport = { 0, 0, backw, backh, 0.0f, 1.0f };
1331 IDirect3DDevice9_SetViewport(
data->device, &wholeviewport);
1333 IDirect3DDevice9_Clear(
data->device, 0,
NULL, D3DCLEAR_TARGET,
color, 0.0f, 0);
1344 IDirect3DDevice9_DrawPrimitive(
data->device, D3DPT_POINTLIST, (UINT) (
first / sizeof (Vertex)), (UINT)
count);
1346 const Vertex *verts = (Vertex *) (((
Uint8 *) vertices) +
first);
1347 IDirect3DDevice9_DrawPrimitiveUP(
data->device, D3DPT_POINTLIST, (UINT)
count, verts, sizeof (Vertex));
1355 const Vertex *verts = (Vertex *) (((
Uint8 *) vertices) +
first);
1364 IDirect3DDevice9_DrawPrimitive(
data->device, D3DPT_LINESTRIP, (UINT) (
first / sizeof (Vertex)), (UINT) (
count - 1));
1365 if (close_endpoint) {
1366 IDirect3DDevice9_DrawPrimitive(
data->device, D3DPT_POINTLIST, (UINT) ((
first / sizeof (Vertex)) + (
count - 1)), 1);
1369 IDirect3DDevice9_DrawPrimitiveUP(
data->device, D3DPT_LINESTRIP, (UINT) (
count - 1), verts, sizeof (Vertex));
1370 if (close_endpoint) {
1371 IDirect3DDevice9_DrawPrimitiveUP(
data->device, D3DPT_POINTLIST, 1, &verts[
count-1], sizeof (Vertex));
1384 IDirect3DDevice9_DrawPrimitive(
data->device, D3DPT_TRIANGLEFAN, (UINT) ((
first / sizeof (Vertex)) +
offset), 2);
1387 const Vertex *verts = (Vertex *) (((
Uint8 *) vertices) +
first);
1388 for (
i = 0;
i <
count; ++
i, verts += 4) {
1389 IDirect3DDevice9_DrawPrimitiveUP(
data->device, D3DPT_TRIANGLEFAN, 2, verts, sizeof (Vertex));
1402 IDirect3DDevice9_DrawPrimitive(
data->device, D3DPT_TRIANGLEFAN, (UINT) ((
first / sizeof (Vertex)) +
offset), 2);
1405 const Vertex *verts = (Vertex *) (((
Uint8 *) vertices) +
first);
1406 for (
i = 0;
i <
count; ++
i, verts += 4) {
1407 IDirect3DDevice9_DrawPrimitiveUP(
data->device, D3DPT_TRIANGLEFAN, 2, verts, sizeof (Vertex));
1415 const Vertex *verts = (Vertex *) (((
Uint8 *) vertices) +
first);
1416 const Vertex *transvert = verts + 4;
1417 const float translatex = transvert->x;
1418 const float translatey = transvert->y;
1419 const float rotation = transvert->z;
1420 const Float4X4 d3dmatrix = MatrixMultiply(MatrixRotationZ(rotation), MatrixTranslation(translatex, translatey, 0));
1423 IDirect3DDevice9_SetTransform(
data->device, D3DTS_VIEW, (D3DMATRIX*)&d3dmatrix);
1426 IDirect3DDevice9_DrawPrimitive(
data->device, D3DPT_TRIANGLEFAN, (UINT) (
first / sizeof (Vertex)), 2);
1428 IDirect3DDevice9_DrawPrimitiveUP(
data->device, D3DPT_TRIANGLEFAN, 2, verts, sizeof (Vertex));
1449 D3DSURFACE_DESC desc;
1450 LPDIRECT3DSURFACE9 backBuffer;
1453 D3DLOCKED_RECT locked;
1456 if (
data->currentRenderTarget) {
1457 backBuffer =
data->currentRenderTarget;
1459 backBuffer =
data->defaultRenderTarget;
1462 result = IDirect3DSurface9_GetDesc(backBuffer, &desc);
1464 return D3D_SetError(
"GetDesc()",
result);
1467 result = IDirect3DDevice9_CreateOffscreenPlainSurface(
data->device, desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &
surface,
NULL);
1469 return D3D_SetError(
"CreateOffscreenPlainSurface()",
result);
1472 result = IDirect3DDevice9_GetRenderTargetData(
data->device, backBuffer,
surface);
1474 IDirect3DSurface9_Release(
surface);
1475 return D3D_SetError(
"GetRenderTargetData()",
result);
1478 d3drect.left =
rect->
x;
1480 d3drect.top =
rect->
y;
1483 result = IDirect3DSurface9_LockRect(
surface, &locked, &d3drect, D3DLOCK_READONLY);
1485 IDirect3DSurface9_Release(
surface);
1486 return D3D_SetError(
"LockRect()",
result);
1490 D3DFMTToPixelFormat(desc.Format), locked.pBits, locked.Pitch,
1493 IDirect3DSurface9_UnlockRect(
surface);
1495 IDirect3DSurface9_Release(
surface);
1507 IDirect3DDevice9_EndScene(
data->device);
1511 result = IDirect3DDevice9_TestCooperativeLevel(
data->device);
1512 if (
result == D3DERR_DEVICELOST) {
1516 if (
result == D3DERR_DEVICENOTRESET) {
1521 D3D_SetError(
"Present()",
result);
1529 D3D_TextureData *
data = (D3D_TextureData *)
texture->driverdata;
1531 if (renderdata->drawstate.texture ==
texture) {
1532 renderdata->drawstate.texture =
NULL;
1533 renderdata->drawstate.shader =
NULL;
1534 IDirect3DDevice9_SetPixelShader(renderdata->device,
NULL);
1535 IDirect3DDevice9_SetTexture(renderdata->device, 0,
NULL);
1537 IDirect3DDevice9_SetTexture(renderdata->device, 1,
NULL);
1538 IDirect3DDevice9_SetTexture(renderdata->device, 2,
NULL);
1546 D3D_DestroyTextureRep(&
data->texture);
1547 D3D_DestroyTextureRep(&
data->utexture);
1548 D3D_DestroyTextureRep(&
data->vtexture);
1563 if (
data->defaultRenderTarget) {
1564 IDirect3DSurface9_Release(
data->defaultRenderTarget);
1567 if (
data->currentRenderTarget !=
NULL) {
1568 IDirect3DSurface9_Release(
data->currentRenderTarget);
1572 if (
data->shaders[
i]) {
1573 IDirect3DPixelShader9_Release(
data->shaders[
i]);
1579 if (
data->vertexBuffers[
i]) {
1580 IDirect3DVertexBuffer9_Release(
data->vertexBuffers[
i]);
1585 IDirect3DDevice9_Release(
data->device);
1589 IDirect3D9_Release(
data->d3d);
1601 const Float4X4 d3dmatrix = MatrixIdentity();
1607 if (
data->defaultRenderTarget) {
1608 IDirect3DSurface9_Release(
data->defaultRenderTarget);
1611 if (
data->currentRenderTarget !=
NULL) {
1612 IDirect3DSurface9_Release(
data->currentRenderTarget);
1627 if (
data->vertexBuffers[
i]) {
1628 IDirect3DVertexBuffer9_Release(
data->vertexBuffers[
i]);
1631 data->vertexBufferSize[
i] = 0;
1636 if (
result == D3DERR_DEVICELOST) {
1640 return D3D_SetError(
"Reset()",
result);
1651 IDirect3DDevice9_GetRenderTarget(
data->device, 0, &
data->defaultRenderTarget);
1652 D3D_InitRenderState(
data);
1661 IDirect3DDevice9_SetTransform(
data->device, D3DTS_VIEW, (D3DMATRIX*)&d3dmatrix);
1677 D3D_RenderData *
data;
1680 D3DPRESENT_PARAMETERS pparams;
1681 IDirect3DSwapChain9 *chain;
1742 pparams.hDeviceWindow = windowinfo.
info.win.
window;
1743 pparams.BackBufferWidth =
w;
1744 pparams.BackBufferHeight =
h;
1745 pparams.BackBufferCount = 1;
1746 pparams.SwapEffect = D3DSWAPEFFECT_DISCARD;
1749 pparams.Windowed =
FALSE;
1750 pparams.BackBufferFormat = PixelFormatToD3DFMT(fullscreen_mode.
format);
1751 pparams.FullScreen_RefreshRateInHz = fullscreen_mode.
refresh_rate;
1753 pparams.Windowed =
TRUE;
1754 pparams.BackBufferFormat = D3DFMT_UNKNOWN;
1755 pparams.FullScreen_RefreshRateInHz = 0;
1758 pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
1760 pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
1767 IDirect3D9_GetDeviceCaps(
data->d3d,
data->adapter, D3DDEVTYPE_HAL, &caps);
1769 device_flags = D3DCREATE_FPU_PRESERVE;
1770 if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) {
1771 device_flags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
1773 device_flags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
1777 device_flags |= D3DCREATE_MULTITHREADED;
1782 pparams.hDeviceWindow,
1784 &pparams, &
data->device);
1787 D3D_SetError(
"CreateDevice()",
result);
1792 result = IDirect3DDevice9_GetSwapChain(
data->device, 0, &chain);
1795 D3D_SetError(
"GetSwapChain()",
result);
1798 result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams);
1800 IDirect3DSwapChain9_Release(chain);
1802 D3D_SetError(
"GetPresentParameters()",
result);
1805 IDirect3DSwapChain9_Release(chain);
1806 if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) {
1809 data->pparams = pparams;
1811 IDirect3DDevice9_GetDeviceCaps(
data->device, &caps);
1814 if (caps.NumSimultaneousRTs >= 2) {
1818 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND) {
1823 IDirect3DDevice9_GetRenderTarget(
data->device, 0, &
data->defaultRenderTarget);
1827 D3D_InitRenderState(
data);
1829 if (caps.MaxSimultaneousTextures >= 3) {
1834 D3D_SetError(
"CreatePixelShader()",
result);
1867 #if SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED
1878 IDirect3DDevice9_AddRef(
device);
#define SDL_assert(condition)
SDL_BlendOperation
The blend operation used when combining source and destination pixel components.
SDL_BlendFactor
The normalized factor used to multiply pixel components.
@ SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR
@ SDL_BLENDFACTOR_SRC_COLOR
@ SDL_BLENDFACTOR_SRC_ALPHA
@ SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR
@ SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA
@ SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA
@ SDL_BLENDFACTOR_DST_ALPHA
@ SDL_BLENDFACTOR_DST_COLOR
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
#define SDL_GetWindowSize
#define SDL_GetWindowFlags
#define SDL_GetYUVConversionModeForResolution
#define SDL_GetWindowDisplayIndex
#define SDL_GetWindowDisplayMode
#define SDL_GetHintBoolean
#define SDL_ConvertPixels
#define SDL_GetWindowWMInfo
#define SDL_OutOfMemory()
@ SDL_RENDER_TARGETS_RESET
#define SDL_HINT_RENDER_DIRECT3D_THREADSAFE
A variable controlling whether the Direct3D device is initialized for thread-safe operations.
@ SDL_LOG_CATEGORY_RENDER
GLint GLint GLint GLint GLint GLint y
GLuint GLuint GLsizei count
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLint GLint GLint GLint GLint x
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
GLfixed GLfixed GLint GLint GLfixed points
GLsizei GLsizei GLuint * shaders
GLenum GLenum GLuint texture
GLuint GLsizei GLsizei * length
GLfloat GLfloat GLfloat GLfloat h
GLubyte GLubyte GLubyte GLubyte w
GLsizeiptr const void GLenum usage
#define SDL_BYTESPERPIXEL(X)
@ SDL_PIXELFORMAT_ARGB8888
@ SDL_PIXELFORMAT_UNKNOWN
SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode)
SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode)
void * SDL_AllocateRenderVertices(SDL_Renderer *renderer, const size_t numbytes, const size_t alignment, size_t *offset)
SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode)
SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode)
SDL_BlendOperation SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode)
SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode)
@ SDL_RENDERER_ACCELERATED
@ SDL_RENDERER_PRESENTVSYNC
@ SDL_RENDERER_TARGETTEXTURE
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
@ SDL_TEXTUREACCESS_TARGET
SDL_ScaleMode
The scaling mode for a texture.
static void SetDrawState(SDL_Surface *surface, SW_DrawStateCache *drawstate)
HRESULT D3D9_CreatePixelShader(IDirect3DDevice9 *d3dDevice, D3D9_Shader shader, IDirect3DPixelShader9 **pixelShader)
#define SDL_arraysize(array)
@ SDL_YUV_CONVERSION_BT601
@ SDL_YUV_CONVERSION_JPEG
@ SDL_YUV_CONVERSION_BT709
SDL_RenderDriver D3D_RenderDriver
@ SDL_RENDERCMD_SETCLIPRECT
@ SDL_RENDERCMD_DRAW_LINES
@ SDL_RENDERCMD_SETVIEWPORT
@ SDL_RENDERCMD_DRAW_POINTS
@ SDL_RENDERCMD_FILL_RECTS
@ SDL_RENDERCMD_SETDRAWCOLOR
int SDL_Direct3D9GetAdapterIndex(int displayIndex)
Returns the D3D9 adapter index that matches the specified display index.
struct IDirect3DDevice9 IDirect3DDevice9
IDirect3DDevice9 * SDL_RenderGetD3D9Device(SDL_Renderer *renderer)
Returns the D3D device associated with a renderer, or NULL if it's not a D3D renderer.
#define SDL_VERSION(x)
Macro to determine SDL version program was compiled against.
@ SDL_WINDOW_FULLSCREEN_DESKTOP
@ SDL_WINDOWEVENT_SIZE_CHANGED
SDL_bool D3D_LoadDLL(void **pD3DDLL, IDirect3D9 **pDirect3D9Interface)
struct IDirect3D9 IDirect3D9
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)
EGLSurface EGLNativeWindowType * window
EGLSurface EGLint * rects
static SDL_AudioDeviceID device
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF ptr
The structure that defines a display mode.
The structure that defines a point (floating point)
A rectangle, with the origin at the upper left (floating point).
A rectangle, with the origin at the upper left (integer).
struct SDL_RenderCommand::@38::@42 color
struct SDL_RenderCommand * next
struct SDL_RenderCommand::@38::@39 viewport
struct SDL_RenderCommand::@38::@41 draw
SDL_RenderCommandType command
union SDL_RenderCommand::@38 data
struct SDL_RenderCommand::@38::@40 cliprect
int(* QueueCopy)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
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)
int(* QueueDrawLines)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
void(* SetTextureScaleMode)(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode)
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
void(* DestroyRenderer)(SDL_Renderer *renderer)
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
SDL_bool(* SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode)
void(* RenderPresent)(SDL_Renderer *renderer)
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
int(* QueueDrawPoints)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
int(* QueueFillRects)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects, int count)
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
int(* RunCommandQueue)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
int(* QueueCopyEx)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* QueueSetViewport)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
int(* QueueSetDrawColor)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
Uint32 texture_formats[16]
Uint32 num_texture_formats
union SDL_SysWMinfo::@10 info
Window state change event data (event.window.*)
The type used to identify a window.
static SDL_Renderer * renderer
static SDL_BlendMode blendMode