Skip to content

Commit

Permalink
Recreate render target textures when the D3D device is being reset, a…
Browse files Browse the repository at this point in the history
…nd notify the application using the SDL_RENDER_TARGETS_RESET event when this happens.
  • Loading branch information
slouken committed Feb 10, 2014
1 parent 9f2509d commit ae05f17
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 8 deletions.
3 changes: 3 additions & 0 deletions include/SDL_events.h
Expand Up @@ -134,6 +134,9 @@ typedef enum
/* Drag and drop events */
SDL_DROPFILE = 0x1000, /**< The system requests a file open */

/* Render events */
SDL_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset */

/** Events ::SDL_USEREVENT through ::SDL_LASTEVENT are for your use,
* and should be allocated with SDL_RegisterEvents()
*/
Expand Down
38 changes: 30 additions & 8 deletions src/render/direct3d/SDL_render_d3d.c
Expand Up @@ -474,13 +474,21 @@ D3D_Reset(SDL_Renderer * renderer)
{
D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
HRESULT result;
SDL_Texture *texture;

/* Release the default render target before reset */
if (data->defaultRenderTarget) {
IDirect3DSurface9_Release(data->defaultRenderTarget);
data->defaultRenderTarget = NULL;
}

/* Release application render targets */
for (texture = renderer->textures; texture; texture = texture->next) {
if (texture->access == SDL_TEXTUREACCESS_TARGET) {
D3D_DestroyTexture(renderer, texture);
}
}

result = IDirect3DDevice9_Reset(data->device, &data->pparams);
if (FAILED(result)) {
if (result == D3DERR_DEVICELOST) {
Expand All @@ -491,9 +499,24 @@ D3D_Reset(SDL_Renderer * renderer)
}
}

/* Allocate application render targets */
for (texture = renderer->textures; texture; texture = texture->next) {
if (texture->access == SDL_TEXTUREACCESS_TARGET) {
D3D_CreateTexture(renderer, texture);
}
}

IDirect3DDevice9_GetRenderTarget(data->device, 0, &data->defaultRenderTarget);
D3D_InitRenderState(data);
D3D_UpdateViewport(renderer);

/* Let the application know that render targets were reset */
{
SDL_Event event;
event.type = SDL_RENDER_TARGETS_RESET;
SDL_PushEvent(&event);
}

return 0;
}

Expand Down Expand Up @@ -570,7 +593,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
return NULL;
}

if( D3D_LoadDLL( &data->d3dDLL, &data->d3d ) ) {
if (D3D_LoadDLL(&data->d3dDLL, &data->d3d)) {
for (d3dxVersion=50;d3dxVersion>0;d3dxVersion--) {
LPTSTR dllName;
SDL_snprintf(d3dxDLLFile, sizeof(d3dxDLLFile), "D3DX9_%02d.dll", d3dxVersion);
Expand Down Expand Up @@ -644,13 +667,12 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
pparams.SwapEffect = D3DSWAPEFFECT_DISCARD;

if (window_flags & SDL_WINDOW_FULLSCREEN) {
if ( ( window_flags & SDL_WINDOW_FULLSCREEN_DESKTOP ) == SDL_WINDOW_FULLSCREEN_DESKTOP ) {
if ((window_flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
pparams.Windowed = TRUE;
pparams.FullScreen_RefreshRateInHz = 0;
} else {
pparams.Windowed = FALSE;
pparams.FullScreen_RefreshRateInHz =
fullscreen_mode.refresh_rate;
pparams.Windowed = FALSE;
pparams.FullScreen_RefreshRateInHz = fullscreen_mode.refresh_rate;
}
} else {
pparams.Windowed = TRUE;
Expand All @@ -663,8 +685,8 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
}

/* Get the adapter for the display that the window is on */
displayIndex = SDL_GetWindowDisplayIndex( window );
data->adapter = SDL_Direct3D9GetAdapterIndex( displayIndex );
displayIndex = SDL_GetWindowDisplayIndex(window);
data->adapter = SDL_Direct3D9GetAdapterIndex(displayIndex);

IDirect3D9_GetDeviceCaps(data->d3d, data->adapter, D3DDEVTYPE_HAL, &caps);

Expand Down Expand Up @@ -1912,7 +1934,7 @@ SDL_RenderGetD3D9Device(SDL_Renderer * renderer)

device = data->device;
if (device) {
IDirect3DDevice9_AddRef( device );
IDirect3DDevice9_AddRef(device);
}
#endif /* SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED */

Expand Down

0 comments on commit ae05f17

Please sign in to comment.