Fixed bugs 2677 and 2625, made it possible to lock render targets in D3D

main
Sam Lantinga 2014-08-16 23:17:47 -07:00
parent 384c204761
commit d673d8c389
1 changed files with 55 additions and 13 deletions

View File

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