D3D11: Fix screenshot aspect ratio.

Fixes issue 6527.
This commit is contained in:
Tony Wasserka 2013-09-16 12:13:58 +02:00
parent 0bcc20ca5b
commit 1b5f904438

View file

@ -168,9 +168,9 @@ void TeardownDeviceObjects()
s_television.Shutdown(); s_television.Shutdown();
} }
void CreateScreenshotTexture() void CreateScreenshotTexture(const TargetRectangle& rc)
{ {
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); D3D11_TEXTURE2D_DESC scrtex_desc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, rc.GetWidth(), rc.GetHeight(), 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); HRESULT hr = D3D::device->CreateTexture2D(&scrtex_desc, NULL, &s_screenshot_texture);
CHECK(hr==S_OK, "Create screenshot staging texture"); CHECK(hr==S_OK, "Create screenshot staging texture");
D3D::SetDebugObjectName((ID3D11DeviceChild*)s_screenshot_texture, "staging screenshot texture"); D3D::SetDebugObjectName((ID3D11DeviceChild*)s_screenshot_texture, "staging screenshot texture");
@ -721,21 +721,22 @@ 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) if (!s_screenshot_texture)
CreateScreenshotTexture(); CreateScreenshotTexture(rc);
// copy back buffer to system memory // copy back buffer to system memory
D3D::context->CopyResource(s_screenshot_texture, (ID3D11Resource*)D3D::GetBackBuffer()->GetTex()); D3D11_BOX box = CD3D11_BOX(rc.left, rc.top, 0, rc.right, rc.bottom, 1);
D3D::context->CopySubresourceRegion(s_screenshot_texture, 0, 0, 0, 0, (ID3D11Resource*)D3D::GetBackBuffer()->GetTex(), 0, &box);
// D3DX11SaveTextureToFileA doesn't allow us to ignore the alpha channel, so we need to strip it out ourselves // D3DX11SaveTextureToFileA doesn't allow us to ignore the alpha channel, so we need to strip it out ourselves
D3D11_MAPPED_SUBRESOURCE map; D3D11_MAPPED_SUBRESOURCE map;
D3D::context->Map(s_screenshot_texture, 0, D3D11_MAP_READ_WRITE, 0, &map); D3D::context->Map(s_screenshot_texture, 0, D3D11_MAP_READ_WRITE, 0, &map);
for (unsigned int y = 0; y < D3D::GetBackBufferHeight(); ++y) for (unsigned int y = 0; y < rc.GetHeight(); ++y)
{ {
u8* ptr = (u8*)map.pData + y * map.RowPitch + 3; u8* ptr = (u8*)map.pData + y * map.RowPitch + 3;
for (unsigned int x = 0; x < D3D::GetBackBufferWidth(); ++x) for (unsigned int x = 0; x < rc.GetWidth(); ++x)
{ {
*ptr = 0xFF; *ptr = 0xFF;
ptr += 4; ptr += 4;
@ -747,8 +748,8 @@ bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle
HRESULT hr = PD3DX11SaveTextureToFileA(D3D::context, s_screenshot_texture, D3DX11_IFF_PNG, filename.c_str()); HRESULT hr = PD3DX11SaveTextureToFileA(D3D::context, s_screenshot_texture, D3DX11_IFF_PNG, filename.c_str());
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
OSD::AddMessage(StringFromFormat("Saved %i x %i %s", D3D::GetBackBufferWidth(), OSD::AddMessage(StringFromFormat("Saved %i x %i %s", rc.GetWidth(),
D3D::GetBackBufferHeight(), filename.c_str())); rc.GetHeight(), filename.c_str()));
} }
else else
{ {
@ -906,9 +907,10 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
static int s_recordHeight; static int s_recordHeight;
if (!s_screenshot_texture) if (!s_screenshot_texture)
CreateScreenshotTexture(); CreateScreenshotTexture(GetTargetRectangle());
D3D::context->CopyResource(s_screenshot_texture, (ID3D11Resource*)D3D::GetBackBuffer()->GetTex()); D3D11_BOX box = CD3D11_BOX(GetTargetRectangle().left, GetTargetRectangle().top, 0, GetTargetRectangle().right, GetTargetRectangle().bottom, 1);
D3D::context->CopySubresourceRegion(s_screenshot_texture, 0, 0, 0, 0, (ID3D11Resource*)D3D::GetBackBuffer()->GetTex(), 0, &box);
if (!bLastFrameDumped) if (!bLastFrameDumped)
{ {
s_recordWidth = GetTargetRectangle().GetWidth(); s_recordWidth = GetTargetRectangle().GetWidth();
@ -937,8 +939,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
w = s_recordWidth; w = s_recordWidth;
h = s_recordHeight; h = s_recordHeight;
} }
auto source_ptr = (const u8*)map.pData + GetTargetRectangle().left*4 + GetTargetRectangle().top*map.RowPitch; formatBufferDump((u8*)map.pData, &frame_data[0], s_recordWidth, s_recordHeight, map.RowPitch);
formatBufferDump(source_ptr, &frame_data[0], s_recordWidth, s_recordHeight, map.RowPitch);
AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight);
D3D::context->Unmap(s_screenshot_texture, 0); D3D::context->Unmap(s_screenshot_texture, 0);
} }