Add ability to dump xfb copies to texture for debugging purposes
This commit is contained in:
parent
a9f0d1783b
commit
198d3b69b4
|
@ -45,6 +45,7 @@ const ConfigInfo<bool> GFX_CONVERT_HIRES_TEXTURES{{System::GFX, "Settings", "Con
|
||||||
const ConfigInfo<bool> GFX_CACHE_HIRES_TEXTURES{{System::GFX, "Settings", "CacheHiresTextures"},
|
const ConfigInfo<bool> GFX_CACHE_HIRES_TEXTURES{{System::GFX, "Settings", "CacheHiresTextures"},
|
||||||
false};
|
false};
|
||||||
const ConfigInfo<bool> GFX_DUMP_EFB_TARGET{{System::GFX, "Settings", "DumpEFBTarget"}, false};
|
const ConfigInfo<bool> GFX_DUMP_EFB_TARGET{{System::GFX, "Settings", "DumpEFBTarget"}, false};
|
||||||
|
const ConfigInfo<bool> GFX_DUMP_XFB_TARGET{ { System::GFX, "Settings", "DumpXFBTarget" }, false };
|
||||||
const ConfigInfo<bool> GFX_DUMP_FRAMES_AS_IMAGES{{System::GFX, "Settings", "DumpFramesAsImages"},
|
const ConfigInfo<bool> GFX_DUMP_FRAMES_AS_IMAGES{{System::GFX, "Settings", "DumpFramesAsImages"},
|
||||||
false};
|
false};
|
||||||
const ConfigInfo<bool> GFX_FREE_LOOK{{System::GFX, "Settings", "FreeLook"}, false};
|
const ConfigInfo<bool> GFX_FREE_LOOK{{System::GFX, "Settings", "FreeLook"}, false};
|
||||||
|
|
|
@ -37,6 +37,7 @@ extern const ConfigInfo<bool> GFX_HIRES_TEXTURES;
|
||||||
extern const ConfigInfo<bool> GFX_CONVERT_HIRES_TEXTURES;
|
extern const ConfigInfo<bool> GFX_CONVERT_HIRES_TEXTURES;
|
||||||
extern const ConfigInfo<bool> GFX_CACHE_HIRES_TEXTURES;
|
extern const ConfigInfo<bool> GFX_CACHE_HIRES_TEXTURES;
|
||||||
extern const ConfigInfo<bool> GFX_DUMP_EFB_TARGET;
|
extern const ConfigInfo<bool> GFX_DUMP_EFB_TARGET;
|
||||||
|
extern const ConfigInfo<bool> GFX_DUMP_XFB_TARGET;
|
||||||
extern const ConfigInfo<bool> GFX_DUMP_FRAMES_AS_IMAGES;
|
extern const ConfigInfo<bool> GFX_DUMP_FRAMES_AS_IMAGES;
|
||||||
extern const ConfigInfo<bool> GFX_FREE_LOOK;
|
extern const ConfigInfo<bool> GFX_FREE_LOOK;
|
||||||
extern const ConfigInfo<bool> GFX_USE_FFV1;
|
extern const ConfigInfo<bool> GFX_USE_FFV1;
|
||||||
|
|
|
@ -250,6 +250,8 @@ static wxString cache_hires_textures_desc =
|
||||||
"more RAM but fixes possible stuttering.\n\nIf unsure, leave this unchecked.");
|
"more RAM but fixes possible stuttering.\n\nIf unsure, leave this unchecked.");
|
||||||
static wxString dump_efb_desc = wxTRANSLATE(
|
static wxString dump_efb_desc = wxTRANSLATE(
|
||||||
"Dump the contents of EFB copies to User/Dump/Textures/.\n\nIf unsure, leave this unchecked.");
|
"Dump the contents of EFB copies to User/Dump/Textures/.\n\nIf unsure, leave this unchecked.");
|
||||||
|
static wxString dump_xfb_desc = wxTRANSLATE(
|
||||||
|
"Dump the contents of XFB copies to User/Dump/Textures/.\n\nIf unsure, leave this unchecked.");
|
||||||
static wxString internal_resolution_frame_dumping_desc = wxTRANSLATE(
|
static wxString internal_resolution_frame_dumping_desc = wxTRANSLATE(
|
||||||
"Create frame dumps and screenshots at the internal resolution of the renderer, rather than "
|
"Create frame dumps and screenshots at the internal resolution of the renderer, rather than "
|
||||||
"the size of the window it is displayed within. If the aspect ratio is widescreen, the output "
|
"the size of the window it is displayed within. If the aspect ratio is widescreen, the output "
|
||||||
|
@ -890,6 +892,8 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string& title)
|
||||||
szr_utility->Add(CreateCheckBox(page_advanced, _("Dump EFB Target"),
|
szr_utility->Add(CreateCheckBox(page_advanced, _("Dump EFB Target"),
|
||||||
wxGetTranslation(dump_efb_desc),
|
wxGetTranslation(dump_efb_desc),
|
||||||
Config::GFX_DUMP_EFB_TARGET));
|
Config::GFX_DUMP_EFB_TARGET));
|
||||||
|
szr_utility->Add(CreateCheckBox(page_advanced, _("Dump XFB Target"),
|
||||||
|
wxGetTranslation(dump_xfb_desc), Config::GFX_DUMP_XFB_TARGET));
|
||||||
szr_utility->Add(CreateCheckBox(page_advanced, _("Free Look"),
|
szr_utility->Add(CreateCheckBox(page_advanced, _("Free Look"),
|
||||||
wxGetTranslation(free_look_desc), Config::GFX_FREE_LOOK));
|
wxGetTranslation(free_look_desc), Config::GFX_FREE_LOOK));
|
||||||
#if defined(HAVE_FFMPEG)
|
#if defined(HAVE_FFMPEG)
|
||||||
|
|
|
@ -181,31 +181,6 @@ static void TeardownDeviceObjects()
|
||||||
s_gx_state_cache.Clear();
|
s_gx_state_cache.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CreateScreenshotTexture()
|
|
||||||
{
|
|
||||||
// We can't render anything outside of the backbuffer anyway, so use the backbuffer size as the
|
|
||||||
// screenshot buffer size.
|
|
||||||
// This texture is released to be recreated when the window is resized in Renderer::SwapImpl.
|
|
||||||
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, nullptr, &s_screenshot_texture);
|
|
||||||
CHECK(hr == S_OK, "Create screenshot staging texture");
|
|
||||||
D3D::SetDebugObjectName(s_screenshot_texture, "staging screenshot texture");
|
|
||||||
}
|
|
||||||
|
|
||||||
static D3D11_BOX GetScreenshotSourceBox(const TargetRectangle& targetRc)
|
|
||||||
{
|
|
||||||
// Since the screenshot buffer is copied back to the CPU via Map(), we can't access pixels that
|
|
||||||
// fall outside the backbuffer bounds. Therefore, when crop is enabled and the target rect is
|
|
||||||
// off-screen to the top/left, we clamp the origin at zero, as well as the bottom/right
|
|
||||||
// coordinates at the backbuffer dimensions. This will result in a rectangle that can be
|
|
||||||
// smaller than the backbuffer, but never larger.
|
|
||||||
return CD3D11_BOX(std::max(targetRc.left, 0), std::max(targetRc.top, 0), 0,
|
|
||||||
std::min(D3D::GetBackBufferWidth(), (unsigned int)targetRc.right),
|
|
||||||
std::min(D3D::GetBackBufferHeight(), (unsigned int)targetRc.bottom), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Create3DVisionTexture(int width, int height)
|
static void Create3DVisionTexture(int width, int height)
|
||||||
{
|
{
|
||||||
// Create a staging texture for 3D vision with signature information in the last row.
|
// Create a staging texture for 3D vision with signature information in the last row.
|
||||||
|
@ -654,10 +629,10 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& rc, u64 ti
|
||||||
// activate linear filtering for the buffer copies
|
// activate linear filtering for the buffer copies
|
||||||
D3D::SetLinearCopySampler();
|
D3D::SetLinearCopySampler();
|
||||||
auto* xfb_texture = static_cast<DXTexture*>(texture);
|
auto* xfb_texture = static_cast<DXTexture*>(texture);
|
||||||
TargetRectangle source_rc = xfb_texture->config.Rect();
|
TargetRectangle source_rc = xfb_texture->GetConfig().GetRect();
|
||||||
|
|
||||||
BlitScreen(source_rc, targetRc, xfb_texture->GetRawTexIdentifier(), xfb_texture->config.width,
|
BlitScreen(source_rc, targetRc, xfb_texture->GetRawTexIdentifier(), xfb_texture->GetConfig().width,
|
||||||
xfb_texture->config.height, Gamma);
|
xfb_texture->GetConfig().height, Gamma);
|
||||||
|
|
||||||
// Reset viewport for drawing text
|
// Reset viewport for drawing text
|
||||||
D3D11_VIEWPORT vp =
|
D3D11_VIEWPORT vp =
|
||||||
|
@ -676,7 +651,7 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& rc, u64 ti
|
||||||
g_texture_cache->OnConfigChanged(g_ActiveConfig);
|
g_texture_cache->OnConfigChanged(g_ActiveConfig);
|
||||||
VertexShaderCache::RetreiveAsyncShaders();
|
VertexShaderCache::RetreiveAsyncShaders();
|
||||||
|
|
||||||
SetWindowSize(xfb_texture->config.width, xfb_texture->config.height);
|
SetWindowSize(xfb_texture->GetConfig().width, xfb_texture->GetConfig().height);
|
||||||
|
|
||||||
const bool window_resized = CheckForResize();
|
const bool window_resized = CheckForResize();
|
||||||
const bool fullscreen = D3D::GetFullscreenState();
|
const bool fullscreen = D3D::GetFullscreenState();
|
||||||
|
|
|
@ -1344,8 +1344,8 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& rc, u64 ti
|
||||||
|
|
||||||
TargetRectangle sourceRc = ConvertEFBRectangle(rc);
|
TargetRectangle sourceRc = ConvertEFBRectangle(rc);
|
||||||
sourceRc.left = 0;
|
sourceRc.left = 0;
|
||||||
sourceRc.right = xfb_texture->config.width;
|
sourceRc.right = xfb_texture->GetConfig().width;
|
||||||
sourceRc.top = xfb_texture->config.height;
|
sourceRc.top = xfb_texture->GetConfig().height;
|
||||||
sourceRc.bottom = 0;
|
sourceRc.bottom = 0;
|
||||||
|
|
||||||
ResetAPIState();
|
ResetAPIState();
|
||||||
|
@ -1358,7 +1358,7 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& rc, u64 ti
|
||||||
|
|
||||||
// Copy the framebuffer to screen.
|
// Copy the framebuffer to screen.
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
BlitScreen(sourceRc, flipped_trc, xfb_texture->GetRawTexIdentifier(), xfb_texture->config.width, xfb_texture->config.height);
|
BlitScreen(sourceRc, flipped_trc, xfb_texture->GetRawTexIdentifier(), xfb_texture->GetConfig().width, xfb_texture->GetConfig().height);
|
||||||
|
|
||||||
// The FlushFrameDump call here is necessary even after frame dumping is stopped.
|
// The FlushFrameDump call here is necessary even after frame dumping is stopped.
|
||||||
// If left out, screenshots are "one frame" behind, as an extra frame is dumped and buffered.
|
// If left out, screenshots are "one frame" behind, as an extra frame is dumped and buffered.
|
||||||
|
@ -1383,7 +1383,7 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& rc, u64 ti
|
||||||
|
|
||||||
// Finish up the current frame, print some stats
|
// Finish up the current frame, print some stats
|
||||||
|
|
||||||
SetWindowSize(xfb_texture->config.width, xfb_texture->config.height);
|
SetWindowSize(xfb_texture->GetConfig().width, xfb_texture->GetConfig().height);
|
||||||
|
|
||||||
GLInterface->Update(); // just updates the render window position and the backbuffer size
|
GLInterface->Update(); // just updates the render window position and the backbuffer size
|
||||||
|
|
||||||
|
|
|
@ -554,7 +554,7 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& rc, u64 ti
|
||||||
|
|
||||||
// Update the window size based on the frame that was just rendered.
|
// Update the window size based on the frame that was just rendered.
|
||||||
// Due to depending on guest state, we need to call this every frame.
|
// Due to depending on guest state, we need to call this every frame.
|
||||||
SetWindowSize(xfb_texture->config.width, xfb_texture->config.height);
|
SetWindowSize(xfb_texture->GetConfig().width, xfb_texture->GetConfig().height);
|
||||||
|
|
||||||
// Clean up stale textures.
|
// Clean up stale textures.
|
||||||
TextureCache::GetInstance()->Cleanup(frameCount);
|
TextureCache::GetInstance()->Cleanup(frameCount);
|
||||||
|
@ -731,7 +731,7 @@ void Renderer::DrawScreen(VKTexture* xfb_texture)
|
||||||
VK_SUBPASS_CONTENTS_INLINE);
|
VK_SUBPASS_CONTENTS_INLINE);
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
TargetRectangle source_rc = xfb_texture->config.Rect();
|
TargetRectangle source_rc = xfb_texture->GetConfig().GetRect();
|
||||||
BlitScreen(m_swap_chain->GetRenderPass(), GetTargetRectangle(), source_rc, xfb_texture->GetRawTexIdentifier());
|
BlitScreen(m_swap_chain->GetRenderPass(), GetTargetRectangle(), source_rc, xfb_texture->GetRawTexIdentifier());
|
||||||
|
|
||||||
// Draw OSD
|
// Draw OSD
|
||||||
|
|
|
@ -1568,10 +1568,19 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, EFBCopyFormat dstF
|
||||||
|
|
||||||
if (g_ActiveConfig.bDumpEFBTarget && !is_xfb_copy)
|
if (g_ActiveConfig.bDumpEFBTarget && !is_xfb_copy)
|
||||||
{
|
{
|
||||||
static int count = 0;
|
static int efb_count = 0;
|
||||||
entry->texture->Save(StringFromFormat("%sefb_frame_%i.png",
|
entry->texture->Save(StringFromFormat("%sefb_frame_%i.png",
|
||||||
File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(),
|
File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(),
|
||||||
count++),
|
efb_count++),
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_ActiveConfig.bDumpXFBTarget && is_xfb_copy)
|
||||||
|
{
|
||||||
|
static int xfb_count = 0;
|
||||||
|
entry->texture->Save(StringFromFormat("%sxfb_frame_%i.png",
|
||||||
|
File::GetUserPath(D_DUMPTEXTURES_IDX).c_str(),
|
||||||
|
xfb_count++),
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,9 @@
|
||||||
<ClCompile Include="AbstractTexture.cpp">
|
<ClCompile Include="AbstractTexture.cpp">
|
||||||
<Filter>Base</Filter>
|
<Filter>Base</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="AbstractRawTexture.cpp">
|
||||||
|
<Filter>Base</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="ShaderGenCommon.cpp">
|
<ClCompile Include="ShaderGenCommon.cpp">
|
||||||
<Filter>Shader Generators</Filter>
|
<Filter>Shader Generators</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -344,6 +347,9 @@
|
||||||
<ClInclude Include="AbstractTexture.h">
|
<ClInclude Include="AbstractTexture.h">
|
||||||
<Filter>Base</Filter>
|
<Filter>Base</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="AbstractRawTexture.h">
|
||||||
|
<Filter>Base</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="AsyncShaderCompiler.h">
|
<ClInclude Include="AsyncShaderCompiler.h">
|
||||||
<Filter>Util</Filter>
|
<Filter>Util</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -81,6 +81,7 @@ void VideoConfig::Refresh()
|
||||||
bConvertHiresTextures = Config::Get(Config::GFX_CONVERT_HIRES_TEXTURES);
|
bConvertHiresTextures = Config::Get(Config::GFX_CONVERT_HIRES_TEXTURES);
|
||||||
bCacheHiresTextures = Config::Get(Config::GFX_CACHE_HIRES_TEXTURES);
|
bCacheHiresTextures = Config::Get(Config::GFX_CACHE_HIRES_TEXTURES);
|
||||||
bDumpEFBTarget = Config::Get(Config::GFX_DUMP_EFB_TARGET);
|
bDumpEFBTarget = Config::Get(Config::GFX_DUMP_EFB_TARGET);
|
||||||
|
bDumpXFBTarget = Config::Get(Config::GFX_DUMP_XFB_TARGET);
|
||||||
bDumpFramesAsImages = Config::Get(Config::GFX_DUMP_FRAMES_AS_IMAGES);
|
bDumpFramesAsImages = Config::Get(Config::GFX_DUMP_FRAMES_AS_IMAGES);
|
||||||
bFreeLook = Config::Get(Config::GFX_FREE_LOOK);
|
bFreeLook = Config::Get(Config::GFX_FREE_LOOK);
|
||||||
bUseFFV1 = Config::Get(Config::GFX_USE_FFV1);
|
bUseFFV1 = Config::Get(Config::GFX_USE_FFV1);
|
||||||
|
|
|
@ -98,6 +98,7 @@ struct VideoConfig final
|
||||||
bool bConvertHiresTextures;
|
bool bConvertHiresTextures;
|
||||||
bool bCacheHiresTextures;
|
bool bCacheHiresTextures;
|
||||||
bool bDumpEFBTarget;
|
bool bDumpEFBTarget;
|
||||||
|
bool bDumpXFBTarget;
|
||||||
bool bDumpFramesAsImages;
|
bool bDumpFramesAsImages;
|
||||||
bool bUseFFV1;
|
bool bUseFFV1;
|
||||||
std::string sDumpCodec;
|
std::string sDumpCodec;
|
||||||
|
|
Loading…
Reference in New Issue