Fixed bugs 2677 and 2625, made it possible to lock render targets in D3D
authorSam Lantinga
Sat, 16 Aug 2014 23:17:47 -0700
changeset 907486a6f6d92960
parent 9073 98d13a381299
child 9075 257a6793aaf5
Fixed bugs 2677 and 2625, made it possible to lock render targets in D3D
src/render/direct3d/SDL_render_d3d.c
     1.1 --- a/src/render/direct3d/SDL_render_d3d.c	Sat Aug 16 15:18:21 2014 -0700
     1.2 +++ b/src/render/direct3d/SDL_render_d3d.c	Sat Aug 16 23:17:47 2014 -0700
     1.3 @@ -193,6 +193,9 @@
     1.4  typedef struct
     1.5  {
     1.6      SDL_bool dirty;
     1.7 +    int w, h;
     1.8 +    DWORD usage;
     1.9 +    Uint32 format;
    1.10      IDirect3DTexture9 *texture;
    1.11      IDirect3DTexture9 *staging;
    1.12  } D3D_TextureRep;
    1.13 @@ -819,6 +822,10 @@
    1.14      HRESULT result;
    1.15  
    1.16      texture->dirty = SDL_FALSE;
    1.17 +    texture->w = w;
    1.18 +    texture->h = h;
    1.19 +    texture->usage = usage;
    1.20 +    texture->format = format;
    1.21  
    1.22      result = IDirect3DDevice9_CreateTexture(device, w, h, 1, usage,
    1.23          PixelFormatToD3DFMT(format),
    1.24 @@ -826,10 +833,18 @@
    1.25      if (FAILED(result)) {
    1.26          return D3D_SetError("CreateTexture(D3DPOOL_DEFAULT)", result);
    1.27      }
    1.28 +    return 0;
    1.29 +}
    1.30  
    1.31 -    if (usage != D3DUSAGE_RENDERTARGET) {
    1.32 -        result = IDirect3DDevice9_CreateTexture(device, w, h, 1, usage,
    1.33 -            PixelFormatToD3DFMT(format),
    1.34 +
    1.35 +static int
    1.36 +D3D_CreateStagingTexture(IDirect3DDevice9 *device, D3D_TextureRep *texture)
    1.37 +{
    1.38 +    HRESULT result;
    1.39 +
    1.40 +    if (texture->staging == NULL) {
    1.41 +        result = IDirect3DDevice9_CreateTexture(device, texture->w, texture->h, 1, texture->usage,
    1.42 +            PixelFormatToD3DFMT(texture->format),
    1.43              D3DPOOL_SYSTEMMEM, &texture->staging, NULL);
    1.44          if (FAILED(result)) {
    1.45              return D3D_SetError("CreateTexture(D3DPOOL_SYSTEMMEM)", result);
    1.46 @@ -845,14 +860,8 @@
    1.47  
    1.48      if (texture->dirty && texture->staging) {
    1.49          if (!texture->texture) {
    1.50 -            D3DSURFACE_DESC desc;
    1.51 -            result = IDirect3DTexture9_GetLevelDesc(texture->staging, 0, &desc);
    1.52 -            if (FAILED(result)) {
    1.53 -                return D3D_SetError("GetLevelDesc", result);
    1.54 -            }
    1.55 -
    1.56 -            result = IDirect3DDevice9_CreateTexture(device, desc.Width, desc.Height, 1, 0,
    1.57 -                desc.Format, D3DPOOL_DEFAULT, &texture->texture, NULL);
    1.58 +            result = IDirect3DDevice9_CreateTexture(device, texture->w, texture->h, 1, texture->usage,
    1.59 +                PixelFormatToD3DFMT(texture->format), D3DPOOL_DEFAULT, &texture->texture, NULL);
    1.60              if (FAILED(result)) {
    1.61                  return D3D_SetError("CreateTexture(D3DPOOL_DEFAULT)", result);
    1.62              }
    1.63 @@ -878,8 +887,10 @@
    1.64          IDirect3DTexture9_Release(texture->texture);
    1.65          texture->texture = NULL;
    1.66      }
    1.67 -    IDirect3DTexture9_AddDirtyRect(texture->staging, NULL);
    1.68 -    texture->dirty = SDL_TRUE;
    1.69 +    if (texture->staging) {
    1.70 +        IDirect3DTexture9_AddDirtyRect(texture->staging, NULL);
    1.71 +        texture->dirty = SDL_TRUE;
    1.72 +    }
    1.73      return 0;
    1.74  }
    1.75  
    1.76 @@ -893,10 +904,15 @@
    1.77      int row, length;
    1.78      HRESULT result;
    1.79  
    1.80 +    if (D3D_CreateStagingTexture(device, texture) < 0) {
    1.81 +        return -1;
    1.82 +    }
    1.83 +
    1.84      d3drect.left = x;
    1.85      d3drect.right = x + w;
    1.86      d3drect.top = y;
    1.87      d3drect.bottom = y + h;
    1.88 +    
    1.89      result = IDirect3DTexture9_LockRect(texture->staging, 0, &locked, &d3drect, 0);
    1.90      if (FAILED(result)) {
    1.91          return D3D_SetError("LockRect()", result);
    1.92 @@ -1068,7 +1084,9 @@
    1.93  D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
    1.94                  const SDL_Rect * rect, void **pixels, int *pitch)
    1.95  {
    1.96 +    D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata;
    1.97      D3D_TextureData *texturedata = (D3D_TextureData *)texture->driverdata;
    1.98 +    IDirect3DDevice9 *device = data->device;
    1.99  
   1.100      if (!texturedata) {
   1.101          SDL_SetError("Texture is not currently available");
   1.102 @@ -1095,6 +1113,10 @@
   1.103          D3DLOCKED_RECT locked;
   1.104          HRESULT result;
   1.105  
   1.106 +        if (D3D_CreateStagingTexture(device, &texturedata->texture) < 0) {
   1.107 +            return -1;
   1.108 +        }
   1.109 +
   1.110          d3drect.left = rect->x;
   1.111          d3drect.right = rect->x + rect->w;
   1.112          d3drect.top = rect->y;
   1.113 @@ -1137,7 +1159,9 @@
   1.114  {
   1.115      D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
   1.116      D3D_TextureData *texturedata;
   1.117 +    D3D_TextureRep *texturerep;
   1.118      HRESULT result;
   1.119 +    IDirect3DDevice9 *device = data->device;
   1.120  
   1.121      /* Release the previous render target if it wasn't the default one */
   1.122      if (data->currentRenderTarget != NULL) {
   1.123 @@ -1156,6 +1180,24 @@
   1.124          return -1;
   1.125      }
   1.126  
   1.127 +    /* Make sure the render target is updated if it was locked and written to */
   1.128 +    texturerep = &texturedata->texture;
   1.129 +    if (texturerep->dirty && texturerep->staging) {
   1.130 +        if (!texturerep->texture) {
   1.131 +            result = IDirect3DDevice9_CreateTexture(device, texturerep->w, texturerep->h, 1, texturerep->usage,
   1.132 +                PixelFormatToD3DFMT(texturerep->format), D3DPOOL_DEFAULT, &texturerep->texture, NULL);
   1.133 +            if (FAILED(result)) {
   1.134 +                return D3D_SetError("CreateTexture(D3DPOOL_DEFAULT)", result);
   1.135 +            }
   1.136 +        }
   1.137 +
   1.138 +        result = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texturerep->staging, (IDirect3DBaseTexture9 *)texturerep->texture);
   1.139 +        if (FAILED(result)) {
   1.140 +            return D3D_SetError("UpdateTexture()", result);
   1.141 +        }
   1.142 +        texturerep->dirty = SDL_FALSE;
   1.143 +    }
   1.144 +
   1.145      result = IDirect3DTexture9_GetSurfaceLevel(texturedata->texture.texture, 0, &data->currentRenderTarget);
   1.146      if(FAILED(result)) {
   1.147          return D3D_SetError("GetSurfaceLevel()", result);