|
@@ -193,6 +193,9 @@ typedef struct |
|
|
typedef struct |
|
|
{ |
|
|
SDL_bool dirty; |
|
|
int w, h; |
|
|
DWORD usage; |
|
|
Uint32 format; |
|
|
IDirect3DTexture9 *texture; |
|
|
IDirect3DTexture9 *staging; |
|
|
} D3D_TextureRep; |
|
@@ -819,17 +822,29 @@ D3D_CreateTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, DWORD us |
|
|
HRESULT result; |
|
|
|
|
|
texture->dirty = SDL_FALSE; |
|
|
texture->w = w; |
|
|
texture->h = h; |
|
|
texture->usage = usage; |
|
|
texture->format = format; |
|
|
|
|
|
result = IDirect3DDevice9_CreateTexture(device, w, h, 1, usage, |
|
|
PixelFormatToD3DFMT(format), |
|
|
D3DPOOL_DEFAULT, &texture->texture, NULL); |
|
|
if (FAILED(result)) { |
|
|
return D3D_SetError("CreateTexture(D3DPOOL_DEFAULT)", result); |
|
|
} |
|
|
return 0; |
|
|
} |
|
|
|
|
|
|
|
|
static int |
|
|
D3D_CreateStagingTexture(IDirect3DDevice9 *device, D3D_TextureRep *texture) |
|
|
{ |
|
|
HRESULT result; |
|
|
|
|
|
if (usage != D3DUSAGE_RENDERTARGET) { |
|
|
result = IDirect3DDevice9_CreateTexture(device, w, h, 1, usage, |
|
|
PixelFormatToD3DFMT(format), |
|
|
if (texture->staging == NULL) { |
|
|
result = IDirect3DDevice9_CreateTexture(device, texture->w, texture->h, 1, texture->usage, |
|
|
PixelFormatToD3DFMT(texture->format), |
|
|
D3DPOOL_SYSTEMMEM, &texture->staging, NULL); |
|
|
if (FAILED(result)) { |
|
|
return D3D_SetError("CreateTexture(D3DPOOL_SYSTEMMEM)", result); |
|
@@ -845,14 +860,8 @@ D3D_BindTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, DWORD samp |
|
|
|
|
|
if (texture->dirty && texture->staging) { |
|
|
if (!texture->texture) { |
|
|
D3DSURFACE_DESC desc; |
|
|
result = IDirect3DTexture9_GetLevelDesc(texture->staging, 0, &desc); |
|
|
if (FAILED(result)) { |
|
|
return D3D_SetError("GetLevelDesc", result); |
|
|
} |
|
|
|
|
|
result = IDirect3DDevice9_CreateTexture(device, desc.Width, desc.Height, 1, 0, |
|
|
desc.Format, D3DPOOL_DEFAULT, &texture->texture, NULL); |
|
|
result = IDirect3DDevice9_CreateTexture(device, texture->w, texture->h, 1, texture->usage, |
|
|
PixelFormatToD3DFMT(texture->format), D3DPOOL_DEFAULT, &texture->texture, NULL); |
|
|
if (FAILED(result)) { |
|
|
return D3D_SetError("CreateTexture(D3DPOOL_DEFAULT)", result); |
|
|
} |
|
@@ -878,8 +887,10 @@ D3D_RecreateTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, Uint32 |
|
|
IDirect3DTexture9_Release(texture->texture); |
|
|
texture->texture = NULL; |
|
|
} |
|
|
IDirect3DTexture9_AddDirtyRect(texture->staging, NULL); |
|
|
texture->dirty = SDL_TRUE; |
|
|
if (texture->staging) { |
|
|
IDirect3DTexture9_AddDirtyRect(texture->staging, NULL); |
|
|
texture->dirty = SDL_TRUE; |
|
|
} |
|
|
return 0; |
|
|
} |
|
|
|
|
@@ -893,10 +904,15 @@ D3D_UpdateTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, Uint32 f |
|
|
int row, length; |
|
|
HRESULT result; |
|
|
|
|
|
if (D3D_CreateStagingTexture(device, texture) < 0) { |
|
|
return -1; |
|
|
} |
|
|
|
|
|
d3drect.left = x; |
|
|
d3drect.right = x + w; |
|
|
d3drect.top = y; |
|
|
d3drect.bottom = y + h; |
|
|
|
|
|
result = IDirect3DTexture9_LockRect(texture->staging, 0, &locked, &d3drect, 0); |
|
|
if (FAILED(result)) { |
|
|
return D3D_SetError("LockRect()", result); |
|
@@ -1068,7 +1084,9 @@ static int |
|
|
D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, |
|
|
const SDL_Rect * rect, void **pixels, int *pitch) |
|
|
{ |
|
|
D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata; |
|
|
D3D_TextureData *texturedata = (D3D_TextureData *)texture->driverdata; |
|
|
IDirect3DDevice9 *device = data->device; |
|
|
|
|
|
if (!texturedata) { |
|
|
SDL_SetError("Texture is not currently available"); |
|
@@ -1095,6 +1113,10 @@ D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, |
|
|
D3DLOCKED_RECT locked; |
|
|
HRESULT result; |
|
|
|
|
|
if (D3D_CreateStagingTexture(device, &texturedata->texture) < 0) { |
|
|
return -1; |
|
|
} |
|
|
|
|
|
d3drect.left = rect->x; |
|
|
d3drect.right = rect->x + rect->w; |
|
|
d3drect.top = rect->y; |
|
@@ -1137,7 +1159,9 @@ D3D_SetRenderTargetInternal(SDL_Renderer * renderer, SDL_Texture * texture) |
|
|
{ |
|
|
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; |
|
|
D3D_TextureData *texturedata; |
|
|
D3D_TextureRep *texturerep; |
|
|
HRESULT result; |
|
|
IDirect3DDevice9 *device = data->device; |
|
|
|
|
|
/* Release the previous render target if it wasn't the default one */ |
|
|
if (data->currentRenderTarget != NULL) { |
|
@@ -1156,6 +1180,24 @@ D3D_SetRenderTargetInternal(SDL_Renderer * renderer, SDL_Texture * texture) |
|
|
return -1; |
|
|
} |
|
|
|
|
|
/* Make sure the render target is updated if it was locked and written to */ |
|
|
texturerep = &texturedata->texture; |
|
|
if (texturerep->dirty && texturerep->staging) { |
|
|
if (!texturerep->texture) { |
|
|
result = IDirect3DDevice9_CreateTexture(device, texturerep->w, texturerep->h, 1, texturerep->usage, |
|
|
PixelFormatToD3DFMT(texturerep->format), D3DPOOL_DEFAULT, &texturerep->texture, NULL); |
|
|
if (FAILED(result)) { |
|
|
return D3D_SetError("CreateTexture(D3DPOOL_DEFAULT)", result); |
|
|
} |
|
|
} |
|
|
|
|
|
result = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texturerep->staging, (IDirect3DBaseTexture9 *)texturerep->texture); |
|
|
if (FAILED(result)) { |
|
|
return D3D_SetError("UpdateTexture()", result); |
|
|
} |
|
|
texturerep->dirty = SDL_FALSE; |
|
|
} |
|
|
|
|
|
result = IDirect3DTexture9_GetSurfaceLevel(texturedata->texture.texture, 0, &data->currentRenderTarget); |
|
|
if(FAILED(result)) { |
|
|
return D3D_SetError("GetSurfaceLevel()", result); |
|
|