Fixed bug 2162 - SDL_RenderClear not clearing entire render target
authorSam Lantinga <slouken@libsdl.org>
Sat, 19 Oct 2013 01:29:23 -0700
changeset 78372f2f0b3b4702
parent 7836 b7c1c84c33e3
child 7838 909b0d7fe4dd
Fixed bug 2162 - SDL_RenderClear not clearing entire render target

Kevin Wells

Overview:
SDL_RenderClear is only clearing part of a texture when it is the render target and a different size than the screen.

Steps to Reproduce:
1) This only occurs with the render driver set to direct3d, so: SDL_SetHint(SDL_HINT_RENDER_DRIVER,"direct3d")
Also, my window was 1280x720.

2) Create a texture for a render target with a resolution of 1024x1024:
texture=SDL_CreateTexture(main_window.renderer,SDL_PIXELFORMAT_RGBA8888,SDL_TEXTUREACCESS_TARGET,1024,1024);
SDL_SetTextureBlendMode(texture,SDL_BLENDMODE_BLEND);

3) Target the texture for rendering: SDL_SetRenderTarget(main_window.renderer,texture);

4) Set the draw color to whatever you want (problem occurs with both 0,0,0,0 and 0,0,0,255 among others) and then clear the render target:
SDL_SetRenderDrawColor(main_window.renderer,0,0,0,0);
SDL_RenderClear(main_window.renderer);

Actual Results:
Only about the top 3/4s of the texture gets cleared on calling SDL_RenderClear. The bottom 1/4 or so does not clear.

Expected Results:
Entire render target should be cleared.
src/render/direct3d/SDL_render_d3d.c
     1.1 --- a/src/render/direct3d/SDL_render_d3d.c	Fri Oct 18 10:56:45 2013 -0400
     1.2 +++ b/src/render/direct3d/SDL_render_d3d.c	Sat Oct 19 01:29:23 2013 -0700
     1.3 @@ -1216,6 +1216,7 @@
     1.4      D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
     1.5      DWORD color;
     1.6      HRESULT result;
     1.7 +    int BackBufferWidth, BackBufferHeight;
     1.8  
     1.9      if (D3D_ActivateRenderer(renderer) < 0) {
    1.10          return -1;
    1.11 @@ -1223,10 +1224,18 @@
    1.12  
    1.13      color = D3DCOLOR_ARGB(renderer->a, renderer->r, renderer->g, renderer->b);
    1.14  
    1.15 +    if (renderer->target) {
    1.16 +        BackBufferWidth = renderer->target->w;
    1.17 +        BackBufferHeight = renderer->target->h;
    1.18 +    } else {
    1.19 +        BackBufferWidth = data->pparams.BackBufferWidth;
    1.20 +        BackBufferHeight = data->pparams.BackBufferHeight;
    1.21 +    }
    1.22 +
    1.23      /* Don't reset the viewport if we don't have to! */
    1.24      if (!renderer->viewport.x && !renderer->viewport.y &&
    1.25 -        renderer->viewport.w == data->pparams.BackBufferWidth &&
    1.26 -        renderer->viewport.h == data->pparams.BackBufferHeight) {
    1.27 +        renderer->viewport.w == BackBufferWidth &&
    1.28 +        renderer->viewport.h == BackBufferHeight) {
    1.29          result = IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0);
    1.30      } else {
    1.31          D3DVIEWPORT9 viewport;
    1.32 @@ -1234,8 +1243,8 @@
    1.33          /* Clear is defined to clear the entire render target */
    1.34          viewport.X = 0;
    1.35          viewport.Y = 0;
    1.36 -        viewport.Width = data->pparams.BackBufferWidth;
    1.37 -        viewport.Height = data->pparams.BackBufferHeight;
    1.38 +        viewport.Width = BackBufferWidth;
    1.39 +        viewport.Height = BackBufferHeight;
    1.40          viewport.MinZ = 0.0f;
    1.41          viewport.MaxZ = 1.0f;
    1.42          IDirect3DDevice9_SetViewport(data->device, &viewport);