diff --git a/Source/Core/Core/Config/GraphicsSettings.cpp b/Source/Core/Core/Config/GraphicsSettings.cpp index 0229e8d006..8874f4def4 100644 --- a/Source/Core/Core/Config/GraphicsSettings.cpp +++ b/Source/Core/Core/Config/GraphicsSettings.cpp @@ -45,6 +45,7 @@ const ConfigInfo GFX_CONVERT_HIRES_TEXTURES{{System::GFX, "Settings", "Con const ConfigInfo GFX_CACHE_HIRES_TEXTURES{{System::GFX, "Settings", "CacheHiresTextures"}, false}; const ConfigInfo GFX_DUMP_EFB_TARGET{{System::GFX, "Settings", "DumpEFBTarget"}, false}; +const ConfigInfo GFX_DUMP_XFB_TARGET{ { System::GFX, "Settings", "DumpXFBTarget" }, false }; const ConfigInfo GFX_DUMP_FRAMES_AS_IMAGES{{System::GFX, "Settings", "DumpFramesAsImages"}, false}; const ConfigInfo GFX_FREE_LOOK{{System::GFX, "Settings", "FreeLook"}, false}; diff --git a/Source/Core/Core/Config/GraphicsSettings.h b/Source/Core/Core/Config/GraphicsSettings.h index a50ee253c0..4fd874a4fe 100644 --- a/Source/Core/Core/Config/GraphicsSettings.h +++ b/Source/Core/Core/Config/GraphicsSettings.h @@ -37,6 +37,7 @@ extern const ConfigInfo GFX_HIRES_TEXTURES; extern const ConfigInfo GFX_CONVERT_HIRES_TEXTURES; extern const ConfigInfo GFX_CACHE_HIRES_TEXTURES; extern const ConfigInfo GFX_DUMP_EFB_TARGET; +extern const ConfigInfo GFX_DUMP_XFB_TARGET; extern const ConfigInfo GFX_DUMP_FRAMES_AS_IMAGES; extern const ConfigInfo GFX_FREE_LOOK; extern const ConfigInfo GFX_USE_FFV1; diff --git a/Source/Core/DolphinWX/VideoConfigDiag.cpp b/Source/Core/DolphinWX/VideoConfigDiag.cpp index 08d2697514..051da17060 100644 --- a/Source/Core/DolphinWX/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/VideoConfigDiag.cpp @@ -250,6 +250,8 @@ static wxString cache_hires_textures_desc = "more RAM but fixes possible stuttering.\n\nIf unsure, leave this unchecked."); static wxString dump_efb_desc = wxTRANSLATE( "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( "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 " @@ -890,6 +892,8 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string& title) szr_utility->Add(CreateCheckBox(page_advanced, _("Dump EFB Target"), wxGetTranslation(dump_efb_desc), 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"), wxGetTranslation(free_look_desc), Config::GFX_FREE_LOOK)); #if defined(HAVE_FFMPEG) diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 4dddd6784d..e49dc4053a 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -181,31 +181,6 @@ static void TeardownDeviceObjects() 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) { // 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 D3D::SetLinearCopySampler(); auto* xfb_texture = static_cast(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, - xfb_texture->config.height, Gamma); + BlitScreen(source_rc, targetRc, xfb_texture->GetRawTexIdentifier(), xfb_texture->GetConfig().width, + xfb_texture->GetConfig().height, Gamma); // Reset viewport for drawing text D3D11_VIEWPORT vp = @@ -676,7 +651,7 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& rc, u64 ti g_texture_cache->OnConfigChanged(g_ActiveConfig); 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 fullscreen = D3D::GetFullscreenState(); diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index e6c90d8c7e..e426b97ef6 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -1344,8 +1344,8 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& rc, u64 ti TargetRectangle sourceRc = ConvertEFBRectangle(rc); sourceRc.left = 0; - sourceRc.right = xfb_texture->config.width; - sourceRc.top = xfb_texture->config.height; + sourceRc.right = xfb_texture->GetConfig().width; + sourceRc.top = xfb_texture->GetConfig().height; sourceRc.bottom = 0; ResetAPIState(); @@ -1358,7 +1358,7 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& rc, u64 ti // Copy the framebuffer to screen. 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. // 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 - 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 diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp index 020dd474f5..43eb0a7ec3 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp +++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp @@ -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. // 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. TextureCache::GetInstance()->Cleanup(frameCount); @@ -731,7 +731,7 @@ void Renderer::DrawScreen(VKTexture* xfb_texture) VK_SUBPASS_CONTENTS_INLINE); // 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()); // Draw OSD diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index fb30575a95..918e33bd64 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -1568,10 +1568,19 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, EFBCopyFormat dstF if (g_ActiveConfig.bDumpEFBTarget && !is_xfb_copy) { - static int count = 0; + static int efb_count = 0; entry->texture->Save(StringFromFormat("%sefb_frame_%i.png", 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); } diff --git a/Source/Core/VideoCommon/VideoCommon.vcxproj.filters b/Source/Core/VideoCommon/VideoCommon.vcxproj.filters index 7b3a5c6892..815fd86bbb 100644 --- a/Source/Core/VideoCommon/VideoCommon.vcxproj.filters +++ b/Source/Core/VideoCommon/VideoCommon.vcxproj.filters @@ -173,6 +173,9 @@ Base + + Base + Shader Generators @@ -344,6 +347,9 @@ Base + + Base + Util diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp index 5dbc3ef196..8288ae8a1f 100644 --- a/Source/Core/VideoCommon/VideoConfig.cpp +++ b/Source/Core/VideoCommon/VideoConfig.cpp @@ -81,6 +81,7 @@ void VideoConfig::Refresh() bConvertHiresTextures = Config::Get(Config::GFX_CONVERT_HIRES_TEXTURES); bCacheHiresTextures = Config::Get(Config::GFX_CACHE_HIRES_TEXTURES); 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); bFreeLook = Config::Get(Config::GFX_FREE_LOOK); bUseFFV1 = Config::Get(Config::GFX_USE_FFV1); diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h index ea5c64896c..4e0dc71b79 100644 --- a/Source/Core/VideoCommon/VideoConfig.h +++ b/Source/Core/VideoCommon/VideoConfig.h @@ -98,6 +98,7 @@ struct VideoConfig final bool bConvertHiresTextures; bool bCacheHiresTextures; bool bDumpEFBTarget; + bool bDumpXFBTarget; bool bDumpFramesAsImages; bool bUseFFV1; std::string sDumpCodec;