From db0509560e06a15655b2839e3fe6ce87f0e417fe Mon Sep 17 00:00:00 2001 From: degasus Date: Sat, 8 Oct 2016 16:23:04 +0200 Subject: [PATCH 1/3] AVIDump: Hard code rgba. --- Source/Core/VideoBackends/D3D/Render.cpp | 4 ++-- Source/Core/VideoBackends/D3D12/Render.cpp | 3 +-- Source/Core/VideoBackends/OGL/Render.cpp | 2 +- Source/Core/VideoBackends/Vulkan/Renderer.cpp | 3 +-- Source/Core/VideoCommon/AVIDump.cpp | 16 +++------------- Source/Core/VideoCommon/AVIDump.h | 8 +------- Source/Core/VideoCommon/RenderBase.cpp | 6 ++---- Source/Core/VideoCommon/RenderBase.h | 4 +--- 8 files changed, 12 insertions(+), 34 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 7ee261d912..d3a44e4dfa 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -870,8 +870,8 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, D3D11_MAPPED_SUBRESOURCE map; D3D::context->Map(s_screenshot_texture, 0, D3D11_MAP_READ, 0, &map); - DumpFrameData(reinterpret_cast(map.pData), source_width, source_height, map.RowPitch, - AVIDump::DumpFormat::FORMAT_RGBA); + DumpFrameData(reinterpret_cast(map.pData), source_width, source_height, + map.RowPitch); FinishFrameData(); D3D::context->Unmap(s_screenshot_texture, 0); diff --git a/Source/Core/VideoBackends/D3D12/Render.cpp b/Source/Core/VideoBackends/D3D12/Render.cpp index 53d6eb3d7f..1c1fd51ad6 100644 --- a/Source/Core/VideoBackends/D3D12/Render.cpp +++ b/Source/Core/VideoBackends/D3D12/Render.cpp @@ -848,8 +848,7 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height CheckHR(s_screenshot_texture->Map(0, &read_range, &screenshot_texture_map)); DumpFrameData(reinterpret_cast(screenshot_texture_map), source_width, source_height, - dst_location.PlacedFootprint.Footprint.RowPitch, - AVIDump::DumpFormat::FORMAT_RGBA); + dst_location.PlacedFootprint.Footprint.RowPitch); FinishFrameData(); D3D12_RANGE write_range = {}; diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index 4b8b638212..e6a264e394 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -1469,7 +1469,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, flipped_trc.GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, image.data()); DumpFrameData(image.data(), flipped_trc.GetWidth(), flipped_trc.GetHeight(), - flipped_trc.GetWidth() * 4, AVIDump::DumpFormat::FORMAT_RGBA, true); + flipped_trc.GetWidth() * 4, true); FinishFrameData(); } // Finish up the current frame, print some stats diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp index f164f132a7..12b425de2c 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp +++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp @@ -496,8 +496,7 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height 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()), - AVIDump::DumpFormat::FORMAT_RGBA); + static_cast(m_screenshot_readback_texture->GetRowStride())); FinishFrameData(); } } diff --git a/Source/Core/VideoCommon/AVIDump.cpp b/Source/Core/VideoCommon/AVIDump.cpp index ab5b99c993..80af9f8d84 100644 --- a/Source/Core/VideoCommon/AVIDump.cpp +++ b/Source/Core/VideoCommon/AVIDump.cpp @@ -47,7 +47,6 @@ static u64 s_last_pts; static int s_current_width; static int s_current_height; static int s_file_index = 0; -static AVIDump::DumpFormat s_current_format; static const u8* s_stored_frame_data; static int s_stored_frame_width; static int s_stored_frame_height; @@ -63,18 +62,9 @@ static void InitAVCodec() } } -bool AVIDump::Start(int w, int h, DumpFormat format) +bool AVIDump::Start(int w, int h) { - if (format == DumpFormat::FORMAT_BGR) - { - s_pix_fmt = AV_PIX_FMT_BGR24; - } - else - { - s_pix_fmt = AV_PIX_FMT_RGBA; - } - - s_current_format = format; + s_pix_fmt = AV_PIX_FMT_RGBA; s_width = w; s_height = h; @@ -320,7 +310,7 @@ void AVIDump::CheckResolution(int width, int height) int temp_file_index = s_file_index; Stop(); s_file_index = temp_file_index + 1; - Start(width, height, s_current_format); + Start(width, height); s_current_width = width; s_current_height = height; } diff --git a/Source/Core/VideoCommon/AVIDump.h b/Source/Core/VideoCommon/AVIDump.h index a3b2ef4bd5..2d1dc89185 100644 --- a/Source/Core/VideoCommon/AVIDump.h +++ b/Source/Core/VideoCommon/AVIDump.h @@ -15,13 +15,7 @@ private: static void StoreFrameData(const u8* data, int width, int height, int stride); public: - enum class DumpFormat - { - FORMAT_BGR, - FORMAT_RGBA - }; - - static bool Start(int w, int h, DumpFormat format); + static bool Start(int w, int h); static void AddFrame(const u8* data, int width, int height, int stride); static void Stop(); static void DoState(); diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index e523fd8a67..4c0abf318a 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -555,8 +555,7 @@ bool Renderer::IsFrameDumping() return false; } -void Renderer::DumpFrameData(const u8* data, int w, int h, int stride, AVIDump::DumpFormat format, - bool swap_upside_down) +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) @@ -564,7 +563,6 @@ void Renderer::DumpFrameData(const u8* data, int w, int h, int stride, AVIDump:: m_last_framedump_width = w; m_last_framedump_height = h; - m_last_framedump_format = format; m_last_framedump_stride = stride; // TODO: Refactor this. Right now it's needed for the implace flipping of the image. @@ -572,7 +570,7 @@ void Renderer::DumpFrameData(const u8* data, int w, int h, int stride, AVIDump:: if (!m_last_frame_dumped) { - m_AVI_dumping = AVIDump::Start(w, h, format); + m_AVI_dumping = AVIDump::Start(w, h); if (!m_AVI_dumping) { OSD::AddMessage("AVIDump Start failed", 2000); diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index 9a78ce4a4b..e509d10530 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -148,8 +148,7 @@ protected: static void RecordVideoMemory(); bool IsFrameDumping(); - void DumpFrameData(const u8* data, int w, int h, int stride, AVIDump::DumpFormat format, - bool swap_upside_down = false); + void DumpFrameData(const u8* data, int w, int h, int stride, bool swap_upside_down = false); void FinishFrameData(); static volatile bool s_bScreenshot; @@ -195,7 +194,6 @@ private: int m_last_framedump_width = 0; int m_last_framedump_height = 0; int m_last_framedump_stride = 0; - AVIDump::DumpFormat m_last_framedump_format; }; extern std::unique_ptr g_renderer; From 21e42c68c4ec1e9e9925f3cfeefed12054cc6b71 Mon Sep 17 00:00:00 2001 From: degasus Date: Sat, 8 Oct 2016 18:26:43 +0200 Subject: [PATCH 2/3] Renderer: Remove write-only variable. Sorry, merge failure. --- Source/Core/VideoCommon/RenderBase.cpp | 5 ----- Source/Core/VideoCommon/RenderBase.h | 3 --- 2 files changed, 8 deletions(-) diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 4c0abf318a..21bf1eeb54 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -546,7 +546,6 @@ bool Renderer::IsFrameDumping() { AVIDump::Stop(); std::vector().swap(m_frame_data); - m_last_framedump_width = m_last_framedump_height = 0; m_AVI_dumping = false; OSD::AddMessage("Stop dumping frames", 2000); } @@ -561,10 +560,6 @@ void Renderer::DumpFrameData(const u8* data, int w, int h, int stride, bool swap if (w == 0 || h == 0) return; - m_last_framedump_width = w; - m_last_framedump_height = h; - m_last_framedump_stride = stride; - // TODO: Refactor this. Right now it's needed for the implace flipping of the image. m_frame_data.assign(data, data + stride * h); diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index e509d10530..e8393721f9 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -191,9 +191,6 @@ private: std::vector m_frame_data; bool m_AVI_dumping = false; bool m_last_frame_dumped = false; - int m_last_framedump_width = 0; - int m_last_framedump_height = 0; - int m_last_framedump_stride = 0; }; extern std::unique_ptr g_renderer; From 64927a2f81fe64503060c949ead525995fd63a2a Mon Sep 17 00:00:00 2001 From: degasus Date: Sat, 8 Oct 2016 18:23:57 +0200 Subject: [PATCH 3/3] Renderer: Merge screenshot logic into VideoCommon. --- Source/Core/VideoBackends/D3D/Render.cpp | 45 ------------ Source/Core/VideoBackends/D3D/Render.h | 2 - Source/Core/VideoBackends/D3D12/Render.cpp | 69 ------------------- Source/Core/VideoBackends/D3D12/Render.h | 2 - Source/Core/VideoBackends/Null/Render.h | 4 -- Source/Core/VideoBackends/OGL/Render.cpp | 31 --------- Source/Core/VideoBackends/OGL/Render.h | 2 - .../Core/VideoBackends/OGL/VertexManager.cpp | 13 ---- .../Core/VideoBackends/Software/SWRenderer.h | 4 -- Source/Core/VideoBackends/Vulkan/Renderer.cpp | 40 ++--------- Source/Core/VideoBackends/Vulkan/Renderer.h | 6 -- Source/Core/VideoCommon/RenderBase.cpp | 61 ++++++++++------ Source/Core/VideoCommon/RenderBase.h | 2 - 13 files changed, 47 insertions(+), 234 deletions(-) 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(); }