mirror of https://github.com/libsdl-org/SDL.git
Fixed crashes handling D3D11/12 device lost in testsprite
You can test this using "dxcap -forcetdr"
This commit is contained in:
parent
e2254b1045
commit
315842cf71
|
|
@ -336,7 +336,7 @@ static void D3D11_ReleaseAll(SDL_Renderer *renderer)
|
||||||
SAFE_RELEASE(data->blendModes[i].blendState);
|
SAFE_RELEASE(data->blendModes[i].blendState);
|
||||||
}
|
}
|
||||||
SDL_free(data->blendModes);
|
SDL_free(data->blendModes);
|
||||||
|
data->blendModes = NULL;
|
||||||
data->blendModesCount = 0;
|
data->blendModesCount = 0;
|
||||||
}
|
}
|
||||||
for (i = 0; i < SDL_arraysize(data->pixelShaders); ++i) {
|
for (i = 0; i < SDL_arraysize(data->pixelShaders); ++i) {
|
||||||
|
|
@ -993,12 +993,14 @@ static HRESULT D3D11_HandleDeviceLost(SDL_Renderer *renderer)
|
||||||
result = D3D11_CreateDeviceResources(renderer);
|
result = D3D11_CreateDeviceResources(renderer);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
// D3D11_CreateDeviceResources will set the SDL error
|
// D3D11_CreateDeviceResources will set the SDL error
|
||||||
|
D3D11_ReleaseAll(renderer);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = D3D11_UpdateForWindowSizeChange(renderer);
|
result = D3D11_UpdateForWindowSizeChange(renderer);
|
||||||
if (FAILED(result)) {
|
if (FAILED(result)) {
|
||||||
// D3D11_UpdateForWindowSizeChange will set the SDL error
|
// D3D11_UpdateForWindowSizeChange will set the SDL error
|
||||||
|
D3D11_ReleaseAll(renderer);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2395,6 +2397,10 @@ static bool D3D11_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd
|
||||||
D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->internal;
|
D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->internal;
|
||||||
const int viewportRotation = D3D11_GetRotationForCurrentRenderTarget(renderer);
|
const int viewportRotation = D3D11_GetRotationForCurrentRenderTarget(renderer);
|
||||||
|
|
||||||
|
if (!rendererData->d3dDevice) {
|
||||||
|
return SDL_SetError("Device lost and couldn't be recovered");
|
||||||
|
}
|
||||||
|
|
||||||
if (rendererData->pixelSizeChanged) {
|
if (rendererData->pixelSizeChanged) {
|
||||||
D3D11_UpdateForWindowSizeChange(renderer);
|
D3D11_UpdateForWindowSizeChange(renderer);
|
||||||
rendererData->pixelSizeChanged = false;
|
rendererData->pixelSizeChanged = false;
|
||||||
|
|
@ -2613,6 +2619,10 @@ static bool D3D11_RenderPresent(SDL_Renderer *renderer)
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
DXGI_PRESENT_PARAMETERS parameters;
|
DXGI_PRESENT_PARAMETERS parameters;
|
||||||
|
|
||||||
|
if (!data->d3dDevice) {
|
||||||
|
return SDL_SetError("Device lost and couldn't be recovered");
|
||||||
|
}
|
||||||
|
|
||||||
SDL_zero(parameters);
|
SDL_zero(parameters);
|
||||||
|
|
||||||
/* The application may optionally specify "dirty" or "scroll"
|
/* The application may optionally specify "dirty" or "scroll"
|
||||||
|
|
@ -2634,10 +2644,15 @@ static bool D3D11_RenderPresent(SDL_Renderer *renderer)
|
||||||
* must recreate all device resources.
|
* must recreate all device resources.
|
||||||
*/
|
*/
|
||||||
if (result == DXGI_ERROR_DEVICE_REMOVED) {
|
if (result == DXGI_ERROR_DEVICE_REMOVED) {
|
||||||
D3D11_HandleDeviceLost(renderer);
|
if (SUCCEEDED(D3D11_HandleDeviceLost(renderer))) {
|
||||||
|
SDL_SetError("Present failed, device lost");
|
||||||
|
} else {
|
||||||
|
// Recovering from device lost failed, error is already set
|
||||||
|
}
|
||||||
} else if (result == DXGI_ERROR_INVALID_CALL) {
|
} else if (result == DXGI_ERROR_INVALID_CALL) {
|
||||||
// We probably went through a fullscreen <-> windowed transition
|
// We probably went through a fullscreen <-> windowed transition
|
||||||
D3D11_CreateWindowSizeDependentResources(renderer);
|
D3D11_CreateWindowSizeDependentResources(renderer);
|
||||||
|
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::Present"), result);
|
||||||
} else {
|
} else {
|
||||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::Present"), result);
|
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::Present"), result);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -414,6 +414,7 @@ static void D3D12_ReleaseAll(SDL_Renderer *renderer)
|
||||||
D3D_SAFE_RELEASE(data->pipelineStates[i].pipelineState);
|
D3D_SAFE_RELEASE(data->pipelineStates[i].pipelineState);
|
||||||
}
|
}
|
||||||
SDL_free(data->pipelineStates);
|
SDL_free(data->pipelineStates);
|
||||||
|
data->pipelineStates = NULL;
|
||||||
data->pipelineStateCount = 0;
|
data->pipelineStateCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2738,6 +2739,10 @@ static bool D3D12_SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE *textureSampler;
|
D3D12_CPU_DESCRIPTOR_HANDLE *textureSampler;
|
||||||
D3D12_PixelShaderConstants constants;
|
D3D12_PixelShaderConstants constants;
|
||||||
|
|
||||||
|
if (!textureData) {
|
||||||
|
return SDL_SetError("Texture is not currently available");
|
||||||
|
}
|
||||||
|
|
||||||
D3D12_SetupShaderConstants(renderer, cmd, texture, &constants);
|
D3D12_SetupShaderConstants(renderer, cmd, texture, &constants);
|
||||||
|
|
||||||
switch (textureData->scaleMode) {
|
switch (textureData->scaleMode) {
|
||||||
|
|
@ -3132,10 +3137,15 @@ static bool D3D12_RenderPresent(SDL_Renderer *renderer)
|
||||||
* must recreate all device resources.
|
* must recreate all device resources.
|
||||||
*/
|
*/
|
||||||
if (result == DXGI_ERROR_DEVICE_REMOVED) {
|
if (result == DXGI_ERROR_DEVICE_REMOVED) {
|
||||||
D3D12_HandleDeviceLost(renderer);
|
if (SUCCEEDED(D3D12_HandleDeviceLost(renderer))) {
|
||||||
|
SDL_SetError("Present failed, device lost");
|
||||||
|
} else {
|
||||||
|
// Recovering from device lost failed, error is already set
|
||||||
|
}
|
||||||
} else if (result == DXGI_ERROR_INVALID_CALL) {
|
} else if (result == DXGI_ERROR_INVALID_CALL) {
|
||||||
// We probably went through a fullscreen <-> windowed transition
|
// We probably went through a fullscreen <-> windowed transition
|
||||||
D3D12_CreateWindowSizeDependentResources(renderer);
|
D3D12_CreateWindowSizeDependentResources(renderer);
|
||||||
|
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::Present"), result);
|
||||||
} else {
|
} else {
|
||||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::Present"), result);
|
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::Present"), result);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#define MAX_SPEED 1
|
#define MAX_SPEED 1
|
||||||
|
|
||||||
static SDLTest_CommonState *state;
|
static SDLTest_CommonState *state;
|
||||||
|
static const char *icon = "icon.bmp";
|
||||||
static int num_sprites;
|
static int num_sprites;
|
||||||
static SDL_Texture **sprites;
|
static SDL_Texture **sprites;
|
||||||
static bool cycle_color;
|
static bool cycle_color;
|
||||||
|
|
@ -56,6 +57,9 @@ static int LoadSprite(const char *file)
|
||||||
|
|
||||||
for (i = 0; i < state->num_windows; ++i) {
|
for (i = 0; i < state->num_windows; ++i) {
|
||||||
/* This does the SDL_LoadBMP step repeatedly, but that's OK for test code. */
|
/* This does the SDL_LoadBMP step repeatedly, but that's OK for test code. */
|
||||||
|
if (sprites[i]) {
|
||||||
|
SDL_DestroyTexture(sprites[i]);
|
||||||
|
}
|
||||||
sprites[i] = LoadTexture(state->renderers[i], file, true, &w, &h);
|
sprites[i] = LoadTexture(state->renderers[i], file, true, &w, &h);
|
||||||
sprite_w = (float)w;
|
sprite_w = (float)w;
|
||||||
sprite_h = (float)h;
|
sprite_h = (float)h;
|
||||||
|
|
@ -390,7 +394,6 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||||
SDL_Rect safe_area;
|
SDL_Rect safe_area;
|
||||||
int i;
|
int i;
|
||||||
Uint64 seed;
|
Uint64 seed;
|
||||||
const char *icon = "icon.bmp";
|
|
||||||
|
|
||||||
/* Initialize parameters */
|
/* Initialize parameters */
|
||||||
num_sprites = NUM_SPRITES;
|
num_sprites = NUM_SPRITES;
|
||||||
|
|
@ -553,6 +556,9 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
|
||||||
|
|
||||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
|
||||||
{
|
{
|
||||||
|
if (event->type == SDL_EVENT_RENDER_DEVICE_RESET) {
|
||||||
|
LoadSprite(icon);
|
||||||
|
}
|
||||||
return SDLTest_CommonEventMainCallbacks(state, event);
|
return SDLTest_CommonEventMainCallbacks(state, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue