Recreate screenshot texture whenever the backbuffer resolution changes. Fixes crashes when taking screenshots after changing window size or switching to/from fullscreen mode.

This commit is contained in:
NeoBrainX 2012-08-07 14:55:10 +02:00 committed by Pierre Bourdon
parent ec859009b7
commit c143e08b9a
1 changed files with 25 additions and 9 deletions

View File

@ -219,6 +219,7 @@ static const D3D11_TEXTURE_ADDRESS_MODE d3dClamps[4] =
D3D11_TEXTURE_ADDRESS_WRAP //reserved D3D11_TEXTURE_ADDRESS_WRAP //reserved
}; };
void SetupDeviceObjects() void SetupDeviceObjects()
{ {
s_television.Init(); s_television.Init();
@ -300,10 +301,7 @@ void SetupDeviceObjects()
CHECK(hr==S_OK, "Create rasterizer state for Renderer::ResetAPIState"); CHECK(hr==S_OK, "Create rasterizer state for Renderer::ResetAPIState");
D3D::SetDebugObjectName((ID3D11DeviceChild*)resetraststate, "rasterizer state for Renderer::ResetAPIState"); D3D::SetDebugObjectName((ID3D11DeviceChild*)resetraststate, "rasterizer state for Renderer::ResetAPIState");
D3D11_TEXTURE2D_DESC scrtex_desc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, D3D::GetBackBufferWidth(), D3D::GetBackBufferHeight(), 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ|D3D11_CPU_ACCESS_WRITE); s_screenshot_texture = NULL;
hr = D3D::device->CreateTexture2D(&scrtex_desc, NULL, &s_screenshot_texture);
CHECK(hr==S_OK, "Create screenshot staging texture");
D3D::SetDebugObjectName((ID3D11DeviceChild*)s_screenshot_texture, "staging screenshot texture");
} }
// Kill off all device objects // Kill off all device objects
@ -327,6 +325,14 @@ void TeardownDeviceObjects()
s_television.Shutdown(); s_television.Shutdown();
} }
void CreateScreenshotTexture()
{
D3D11_TEXTURE2D_DESC scrtex_desc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, D3D::GetBackBufferWidth(), D3D::GetBackBufferHeight(), 1, 1, 0, D3D11_USAGE_STAGING, D3D11_CPU_ACCESS_READ|D3D11_CPU_ACCESS_WRITE);
HRESULT hr = D3D::device->CreateTexture2D(&scrtex_desc, NULL, &s_screenshot_texture);
CHECK(hr==S_OK, "Create screenshot staging texture");
D3D::SetDebugObjectName((ID3D11DeviceChild*)s_screenshot_texture, "staging screenshot texture");
}
Renderer::Renderer() Renderer::Renderer()
{ {
int x, y, w_temp, h_temp; int x, y, w_temp, h_temp;
@ -847,6 +853,9 @@ void Renderer::SetBlendMode(bool forceUpdate)
bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle &rc) bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle &rc)
{ {
if (!s_screenshot_texture)
CreateScreenshotTexture();
// copy back buffer to system memory // copy back buffer to system memory
D3D::context->CopyResource(s_screenshot_texture, (ID3D11Resource*)D3D::GetBackBuffer()->GetTex()); D3D::context->CopyResource(s_screenshot_texture, (ID3D11Resource*)D3D::GetBackBuffer()->GetTex());
@ -1020,6 +1029,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
static int s_recordWidth; static int s_recordWidth;
static int s_recordHeight; static int s_recordHeight;
if (!s_screenshot_texture)
CreateScreenshotTexture();
D3D::context->CopyResource(s_screenshot_texture, (ID3D11Resource*)D3D::GetBackBuffer()->GetTex()); D3D::context->CopyResource(s_screenshot_texture, (ID3D11Resource*)D3D::GetBackBuffer()->GetTex());
if (!bLastFrameDumped) if (!bLastFrameDumped)
{ {
@ -1159,10 +1171,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
s_LastAA = g_ActiveConfig.iMultisampleMode; s_LastAA = g_ActiveConfig.iMultisampleMode;
PixelShaderCache::InvalidateMSAAShaders(); PixelShaderCache::InvalidateMSAAShaders();
// TODO: Aren't we still holding a reference to the back buffer right now? if (windowResized)
D3D::Reset(); {
s_backbuffer_width = D3D::GetBackBufferWidth(); // TODO: Aren't we still holding a reference to the back buffer right now?
s_backbuffer_height = D3D::GetBackBufferHeight(); D3D::Reset();
SAFE_RELEASE(s_screenshot_texture);
s_backbuffer_width = D3D::GetBackBufferWidth();
s_backbuffer_height = D3D::GetBackBufferHeight();
}
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect); ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);