diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index d3a44e4dfa..ef923af20d 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -32,7 +32,6 @@ #include "VideoCommon/AVIDump.h" #include "VideoCommon/BPFunctions.h" #include "VideoCommon/Fifo.h" -#include "VideoCommon/ImageWrite.h" #include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/PixelEngine.h" #include "VideoCommon/PixelShaderManager.h" @@ -712,39 +711,6 @@ void Renderer::SetBlendMode(bool forceUpdate) } } -bool Renderer::SaveScreenshot(const std::string& filename, const TargetRectangle& rc) -{ - if (!s_screenshot_texture) - CreateScreenshotTexture(); - - // copy back buffer to system memory - D3D11_BOX source_box = GetScreenshotSourceBox(rc); - D3D::context->CopySubresourceRegion(s_screenshot_texture, 0, 0, 0, 0, - (ID3D11Resource*)D3D::GetBackBuffer()->GetTex(), 0, - &source_box); - - D3D11_MAPPED_SUBRESOURCE map; - D3D::context->Map(s_screenshot_texture, 0, D3D11_MAP_READ_WRITE, 0, &map); - - bool saved_png = - TextureToPng((u8*)map.pData, map.RowPitch, filename, source_box.right - source_box.left, - source_box.bottom - source_box.top, false); - - D3D::context->Unmap(s_screenshot_texture, 0); - - if (saved_png) - { - OSD::AddMessage( - StringFromFormat("Saved %i x %i %s", rc.GetWidth(), rc.GetHeight(), filename.c_str())); - } - else - { - OSD::AddMessage(StringFromFormat("Error saving %s", filename.c_str())); - } - - return saved_png; -} - // This function has the final picture. We adjust the aspect ratio here. void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc, float Gamma) @@ -843,17 +809,6 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, BlitScreen(sourceRc, targetRc, read_texture, GetTargetWidth(), GetTargetHeight(), Gamma); } - // done with drawing the game stuff, good moment to save a screenshot - if (s_bScreenshot) - { - std::lock_guard guard(s_criticalScreenshot); - - SaveScreenshot(s_sScreenshotName, GetTargetRectangle()); - s_sScreenshotName.clear(); - s_bScreenshot = false; - s_screenshotCompleted.Set(); - } - // Dump frames if (IsFrameDumping()) { diff --git a/Source/Core/VideoBackends/D3D/Render.h b/Source/Core/VideoBackends/D3D/Render.h index 6dec232d33..9119573655 100644 --- a/Source/Core/VideoBackends/D3D/Render.h +++ b/Source/Core/VideoBackends/D3D/Render.h @@ -54,8 +54,6 @@ public: void ReinterpretPixelData(unsigned int convtype) override; - bool SaveScreenshot(const std::string& filename, const TargetRectangle& rc) override; - static bool CheckForResize(); u32 GetMaxTextureSize() override; diff --git a/Source/Core/VideoBackends/D3D12/Render.cpp b/Source/Core/VideoBackends/D3D12/Render.cpp index 1c1fd51ad6..96dafa6179 100644 --- a/Source/Core/VideoBackends/D3D12/Render.cpp +++ b/Source/Core/VideoBackends/D3D12/Render.cpp @@ -34,7 +34,6 @@ #include "VideoCommon/AVIDump.h" #include "VideoCommon/BPFunctions.h" #include "VideoCommon/Fifo.h" -#include "VideoCommon/ImageWrite.h" #include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/PixelEngine.h" #include "VideoCommon/PixelShaderManager.h" @@ -631,63 +630,6 @@ void Renderer::SetBlendMode(bool force_update) D3D::command_list_mgr->SetCommandListDirtyState(COMMAND_LIST_STATE_PSO, true); } -bool Renderer::SaveScreenshot(const std::string& filename, const TargetRectangle& rc) -{ - if (!s_screenshot_texture) - CreateScreenshotTexture(); - - // copy back buffer to system memory - bool saved_png = false; - - D3D12_BOX source_box = GetScreenshotSourceBox(rc); - - D3D12_TEXTURE_COPY_LOCATION dst_location = {}; - dst_location.pResource = s_screenshot_texture; - dst_location.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; - dst_location.PlacedFootprint.Offset = 0; - dst_location.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - dst_location.PlacedFootprint.Footprint.Width = D3D::GetBackBufferWidth(); - dst_location.PlacedFootprint.Footprint.Height = D3D::GetBackBufferHeight(); - dst_location.PlacedFootprint.Footprint.Depth = 1; - dst_location.PlacedFootprint.Footprint.RowPitch = D3D::AlignValue( - dst_location.PlacedFootprint.Footprint.Width * 4, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); - - D3D12_TEXTURE_COPY_LOCATION src_location = {}; - src_location.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - src_location.SubresourceIndex = 0; - src_location.pResource = D3D::GetBackBuffer()->GetTex12(); - - D3D::GetBackBuffer()->TransitionToResourceState(D3D::current_command_list, - D3D12_RESOURCE_STATE_COPY_SOURCE); - D3D::current_command_list->CopyTextureRegion(&dst_location, 0, 0, 0, &src_location, &source_box); - - D3D::command_list_mgr->ExecuteQueuedWork(true); - - void* screenshot_texture_map; - D3D12_RANGE read_range = {0, dst_location.PlacedFootprint.Footprint.RowPitch * - (source_box.bottom - source_box.top)}; - CheckHR(s_screenshot_texture->Map(0, &read_range, &screenshot_texture_map)); - - saved_png = TextureToPng( - static_cast(screenshot_texture_map), dst_location.PlacedFootprint.Footprint.RowPitch, - filename, source_box.right - source_box.left, source_box.bottom - source_box.top, false); - - D3D12_RANGE write_range = {}; - s_screenshot_texture->Unmap(0, &write_range); - - if (saved_png) - { - OSD::AddMessage( - StringFromFormat("Saved %i x %i %s", rc.GetWidth(), rc.GetHeight(), filename.c_str())); - } - else - { - OSD::AddMessage(StringFromFormat("Error saving %s", filename.c_str())); - } - - return saved_png; -} - // This function has the final picture. We adjust the aspect ratio here. void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, const EFBRectangle& rc, float gamma) @@ -798,17 +740,6 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height BlitScreen(source_rc, target_rc, read_texture, GetTargetWidth(), GetTargetHeight(), gamma); } - // done with drawing the game stuff, good moment to save a screenshot - if (s_bScreenshot) - { - std::lock_guard guard(s_criticalScreenshot); - - SaveScreenshot(s_sScreenshotName, GetTargetRectangle()); - s_sScreenshotName.clear(); - s_bScreenshot = false; - s_screenshotCompleted.Set(); - } - // Dump frames if (IsFrameDumping()) { diff --git a/Source/Core/VideoBackends/D3D12/Render.h b/Source/Core/VideoBackends/D3D12/Render.h index 7d6a6ee82d..fabc1680f9 100644 --- a/Source/Core/VideoBackends/D3D12/Render.h +++ b/Source/Core/VideoBackends/D3D12/Render.h @@ -54,8 +54,6 @@ public: void ReinterpretPixelData(unsigned int conv_type) override; - bool SaveScreenshot(const std::string& filename, const TargetRectangle& rc) override; - static bool CheckForResize(); u32 GetMaxTextureSize() override; diff --git a/Source/Core/VideoBackends/Null/Render.h b/Source/Core/VideoBackends/Null/Render.h index 6ef5428185..73e35d886d 100644 --- a/Source/Core/VideoBackends/Null/Render.h +++ b/Source/Core/VideoBackends/Null/Render.h @@ -31,9 +31,5 @@ public: } void ReinterpretPixelData(unsigned int convtype) override {} - bool SaveScreenshot(const std::string& filename, const TargetRectangle& rc) override - { - return false; - } }; } diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index e6a264e394..f2f61dac9a 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -36,7 +36,6 @@ #include "VideoCommon/BPFunctions.h" #include "VideoCommon/DriverDetails.h" #include "VideoCommon/Fifo.h" -#include "VideoCommon/ImageWrite.h" #include "VideoCommon/IndexGenerator.h" #include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/PixelEngine.h" @@ -1445,23 +1444,8 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - // Save screenshot - if (s_bScreenshot) - { - std::lock_guard lk(s_criticalScreenshot); - - if (SaveScreenshot(s_sScreenshotName, flipped_trc)) - OSD::AddMessage("Screenshot saved to " + s_sScreenshotName); - - // Reset settings - s_sScreenshotName.clear(); - s_bScreenshot = false; - s_screenshotCompleted.Set(); - } - if (IsFrameDumping()) { - std::lock_guard lk(s_criticalScreenshot); std::vector image(flipped_trc.GetWidth() * flipped_trc.GetHeight() * 4); glPixelStorei(GL_PACK_ALIGNMENT, 1); @@ -1727,21 +1711,6 @@ void Renderer::SetInterlacingMode() namespace OGL { -bool Renderer::SaveScreenshot(const std::string& filename, const TargetRectangle& back_rc) -{ - u32 W = back_rc.GetWidth(); - u32 H = back_rc.GetHeight(); - std::unique_ptr data(new u8[W * 4 * H]); - glPixelStorei(GL_PACK_ALIGNMENT, 1); - - glReadPixels(back_rc.left, back_rc.bottom, W, H, GL_RGBA, GL_UNSIGNED_BYTE, data.get()); - - // Turn image upside down - FlipImageData(data.get(), W, H, 4); - - return TextureToPng(data.get(), W * 4, filename, W, H, false); -} - u32 Renderer::GetMaxTextureSize() { // Right now nvidia seems to do something very weird if we try to cache GL_MAX_TEXTURE_SIZE in diff --git a/Source/Core/VideoBackends/OGL/Render.h b/Source/Core/VideoBackends/OGL/Render.h index edfdd0090c..7fb14771b5 100644 --- a/Source/Core/VideoBackends/OGL/Render.h +++ b/Source/Core/VideoBackends/OGL/Render.h @@ -101,8 +101,6 @@ public: void ReinterpretPixelData(unsigned int convtype) override; - bool SaveScreenshot(const std::string& filename, const TargetRectangle& rc) override; - u32 GetMaxTextureSize() override; void ChangeSurface(void* new_surface_handle) override; diff --git a/Source/Core/VideoBackends/OGL/VertexManager.cpp b/Source/Core/VideoBackends/OGL/VertexManager.cpp index feb2351e49..6b18517555 100644 --- a/Source/Core/VideoBackends/OGL/VertexManager.cpp +++ b/Source/Core/VideoBackends/OGL/VertexManager.cpp @@ -220,19 +220,6 @@ void VertexManager::vFlush(bool useDstAlpha) OpenFStream(fvs, filename, std::ios_base::out); fvs << prog.shader.strvprog; } - - if (g_ActiveConfig.iLog & CONF_SAVETARGETS) - { - std::string filename = - StringFromFormat("%starg%.3d.png", File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), - g_ActiveConfig.iSaveTargetId); - TargetRectangle tr; - tr.left = 0; - tr.right = Renderer::GetTargetWidth(); - tr.top = 0; - tr.bottom = Renderer::GetTargetHeight(); - g_renderer->SaveScreenshot(filename, tr); - } #endif g_Config.iSaveTargetId++; diff --git a/Source/Core/VideoBackends/Software/SWRenderer.h b/Source/Core/VideoBackends/Software/SWRenderer.h index 73cc977b31..749a24e782 100644 --- a/Source/Core/VideoBackends/Software/SWRenderer.h +++ b/Source/Core/VideoBackends/Software/SWRenderer.h @@ -40,8 +40,4 @@ public: u32 color, u32 z) override; void ReinterpretPixelData(unsigned int convtype) override {} - bool SaveScreenshot(const std::string& filename, const TargetRectangle& rc) override - { - return true; - }; }; diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp index 12b425de2c..7192f93169 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp +++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp @@ -29,7 +29,6 @@ #include "VideoCommon/AVIDump.h" #include "VideoCommon/BPFunctions.h" #include "VideoCommon/BPMemory.h" -#include "VideoCommon/ImageWrite.h" #include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/PixelEngine.h" #include "VideoCommon/PixelShaderManager.h" @@ -482,23 +481,13 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); // Draw to the screenshot buffer if needed. - bool needs_framedump = IsFrameDumping(); - bool needs_screenshot = s_bScreenshot || needs_framedump; - if (needs_screenshot && DrawScreenshot(source_rc, efb_color_texture)) + if (IsFrameDumping() && DrawScreenshot(source_rc, efb_color_texture)) { - if (s_bScreenshot) - { - WriteScreenshot(); - } - - if (needs_framedump) - { - DumpFrameData(reinterpret_cast(m_screenshot_readback_texture->GetMapPointer()), - static_cast(m_screenshot_render_texture->GetWidth()), - static_cast(m_screenshot_render_texture->GetHeight()), - static_cast(m_screenshot_readback_texture->GetRowStride())); - FinishFrameData(); - } + DumpFrameData(reinterpret_cast(m_screenshot_readback_texture->GetMapPointer()), + static_cast(m_screenshot_render_texture->GetWidth()), + static_cast(m_screenshot_render_texture->GetHeight()), + static_cast(m_screenshot_readback_texture->GetRowStride())); + FinishFrameData(); } // Restore the EFB color texture to color attachment ready for rendering the next frame. @@ -759,23 +748,6 @@ void Renderer::DestroyScreenshotResources() m_screenshot_readback_texture.reset(); } -void Renderer::WriteScreenshot() -{ - std::lock_guard guard(s_criticalScreenshot); - - if (!TextureToPng(reinterpret_cast(m_screenshot_readback_texture->GetMapPointer()), - static_cast(m_screenshot_readback_texture->GetRowStride()), - s_sScreenshotName, static_cast(m_screenshot_render_texture->GetWidth()), - static_cast(m_screenshot_render_texture->GetHeight()), false)) - { - WARN_LOG(VIDEO, "Failed to write screenshot to %s", s_sScreenshotName.c_str()); - } - - s_sScreenshotName.clear(); - s_bScreenshot = false; - s_screenshotCompleted.Set(); -} - void Renderer::CheckForTargetResize(u32 fb_width, u32 fb_stride, u32 fb_height) { if (FramebufferManagerBase::LastXfbWidth() == fb_stride && diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.h b/Source/Core/VideoBackends/Vulkan/Renderer.h index b80b6c191b..c97ee50a06 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.h +++ b/Source/Core/VideoBackends/Vulkan/Renderer.h @@ -49,11 +49,6 @@ public: void ReinterpretPixelData(unsigned int convtype) override; - bool SaveScreenshot(const std::string& filename, const TargetRectangle& rc) override - { - return false; - } - void ApplyState(bool bUseDstAlpha) override; void ResetAPIState() override; @@ -99,7 +94,6 @@ private: const TargetRectangle& src_rect, const Texture2D* src_tex, bool linear_filter); bool ResizeScreenshotBuffer(u32 new_width, u32 new_height); void DestroyScreenshotResources(); - void WriteScreenshot(); FramebufferManager* m_framebuffer_mgr = nullptr; VkSemaphore m_image_available_semaphore = VK_NULL_HANDLE; diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 21bf1eeb54..9a81fa5e4d 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -41,6 +41,7 @@ #include "VideoCommon/Debugger.h" #include "VideoCommon/FPSCounter.h" #include "VideoCommon/FramebufferManagerBase.h" +#include "VideoCommon/ImageWrite.h" #include "VideoCommon/PostProcessing.h" #include "VideoCommon/RenderBase.h" #include "VideoCommon/Statistics.h" @@ -538,6 +539,9 @@ void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const bool Renderer::IsFrameDumping() { + if (s_bScreenshot) + return true; + #if defined(HAVE_LIBAV) || defined(_WIN32) if (SConfig::GetInstance().m_DumpFrames) return true; @@ -556,35 +560,52 @@ bool Renderer::IsFrameDumping() void Renderer::DumpFrameData(const u8* data, int w, int h, int stride, bool swap_upside_down) { -#if defined(HAVE_LIBAV) || defined(_WIN32) if (w == 0 || h == 0) return; // TODO: Refactor this. Right now it's needed for the implace flipping of the image. m_frame_data.assign(data, data + stride * h); + if (swap_upside_down) + FlipImageData(m_frame_data.data(), w, h, 4); - if (!m_last_frame_dumped) + // Save screenshot + if (s_bScreenshot) { - m_AVI_dumping = AVIDump::Start(w, h); - if (!m_AVI_dumping) - { - OSD::AddMessage("AVIDump Start failed", 2000); - } - else - { - OSD::AddMessage(StringFromFormat("Dumping Frames to \"%sframedump0.avi\" (%dx%d RGB24)", - File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), w, h), - 2000); - } - } - if (m_AVI_dumping) - { - if (swap_upside_down) - FlipImageData(m_frame_data.data(), w, h, 4); - AVIDump::AddFrame(m_frame_data.data(), w, h, stride); + std::lock_guard lk(s_criticalScreenshot); + + if (TextureToPng(m_frame_data.data(), stride, s_sScreenshotName, w, h, false)) + OSD::AddMessage("Screenshot saved to " + s_sScreenshotName); + + // Reset settings + s_sScreenshotName.clear(); + s_bScreenshot = false; + s_screenshotCompleted.Set(); } - m_last_frame_dumped = true; +#if defined(HAVE_LIBAV) || defined(_WIN32) + if (SConfig::GetInstance().m_DumpFrames) + { + if (!m_last_frame_dumped) + { + m_AVI_dumping = AVIDump::Start(w, h); + if (!m_AVI_dumping) + { + OSD::AddMessage("AVIDump Start failed", 2000); + } + else + { + OSD::AddMessage(StringFromFormat("Dumping Frames to \"%sframedump0.avi\" (%dx%d RGB24)", + File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), w, h), + 2000); + } + } + if (m_AVI_dumping) + { + AVIDump::AddFrame(m_frame_data.data(), w, h, stride); + } + + m_last_frame_dumped = true; + } #endif } diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index e8393721f9..f405ddc5eb 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -127,8 +127,6 @@ public: virtual void SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc, float Gamma = 1.0f) = 0; - virtual bool SaveScreenshot(const std::string& filename, const TargetRectangle& rc) = 0; - static PEControl::PixelFormat GetPrevPixelFormat() { return prev_efb_format; } static void StorePixelFormat(PEControl::PixelFormat new_format) { prev_efb_format = new_format; } PostProcessingShaderImplementation* GetPostProcessor() { return m_post_processor.get(); }