From ae05f178c237820ad183ef47a6c08e164988226f Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 10 Feb 2014 10:02:51 -0800 Subject: [PATCH] Recreate render target textures when the D3D device is being reset, and notify the application using the SDL_RENDER_TARGETS_RESET event when this happens. --- include/SDL_events.h | 3 +++ src/render/direct3d/SDL_render_d3d.c | 38 ++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/include/SDL_events.h b/include/SDL_events.h index 9be48c3a5..0b848b944 100644 --- a/include/SDL_events.h +++ b/include/SDL_events.h @@ -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() */ diff --git a/src/render/direct3d/SDL_render_d3d.c b/src/render/direct3d/SDL_render_d3d.c index 63dfff61c..cf8f3fe04 100644 --- a/src/render/direct3d/SDL_render_d3d.c +++ b/src/render/direct3d/SDL_render_d3d.c @@ -474,6 +474,7 @@ 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) { @@ -481,6 +482,13 @@ D3D_Reset(SDL_Renderer * renderer) 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) { @@ -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; } @@ -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); @@ -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; @@ -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); @@ -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 */