Renderer: Merge screenshot logic into VideoCommon.
This commit is contained in:
parent
21e42c68c4
commit
64927a2f81
|
@ -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<std::mutex> guard(s_criticalScreenshot);
|
||||
|
||||
SaveScreenshot(s_sScreenshotName, GetTargetRectangle());
|
||||
s_sScreenshotName.clear();
|
||||
s_bScreenshot = false;
|
||||
s_screenshotCompleted.Set();
|
||||
}
|
||||
|
||||
// Dump frames
|
||||
if (IsFrameDumping())
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<u8*>(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<std::mutex> guard(s_criticalScreenshot);
|
||||
|
||||
SaveScreenshot(s_sScreenshotName, GetTargetRectangle());
|
||||
s_sScreenshotName.clear();
|
||||
s_bScreenshot = false;
|
||||
s_screenshotCompleted.Set();
|
||||
}
|
||||
|
||||
// Dump frames
|
||||
if (IsFrameDumping())
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -31,9 +31,5 @@ public:
|
|||
}
|
||||
|
||||
void ReinterpretPixelData(unsigned int convtype) override {}
|
||||
bool SaveScreenshot(const std::string& filename, const TargetRectangle& rc) override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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<std::mutex> 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<std::mutex> lk(s_criticalScreenshot);
|
||||
std::vector<u8> 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<u8[]> 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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++;
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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<const u8*>(m_screenshot_readback_texture->GetMapPointer()),
|
||||
static_cast<int>(m_screenshot_render_texture->GetWidth()),
|
||||
static_cast<int>(m_screenshot_render_texture->GetHeight()),
|
||||
static_cast<int>(m_screenshot_readback_texture->GetRowStride()));
|
||||
FinishFrameData();
|
||||
}
|
||||
DumpFrameData(reinterpret_cast<const u8*>(m_screenshot_readback_texture->GetMapPointer()),
|
||||
static_cast<int>(m_screenshot_render_texture->GetWidth()),
|
||||
static_cast<int>(m_screenshot_render_texture->GetHeight()),
|
||||
static_cast<int>(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<std::mutex> guard(s_criticalScreenshot);
|
||||
|
||||
if (!TextureToPng(reinterpret_cast<u8*>(m_screenshot_readback_texture->GetMapPointer()),
|
||||
static_cast<int>(m_screenshot_readback_texture->GetRowStride()),
|
||||
s_sScreenshotName, static_cast<int>(m_screenshot_render_texture->GetWidth()),
|
||||
static_cast<int>(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 &&
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<std::mutex> 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
|
||||
}
|
||||
|
||||
|
|
|
@ -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(); }
|
||||
|
|
Loading…
Reference in New Issue