Video Common: Improve texture dumping to work with fifoci and

fifo_comparer
This commit is contained in:
iwubcode 2017-09-13 23:46:30 -05:00
parent 53684701fa
commit a129a53e56
5 changed files with 51 additions and 20 deletions

View File

@ -393,7 +393,7 @@ static void CpuThread()
s_is_started = false; s_is_started = false;
if (!_CoreParameter.bCPUThread) if (!_CoreParameter.bCPUThread)
g_video_backend->Video_Cleanup(); g_video_backend->Video_CleanupShared();
if (_CoreParameter.bFastmem) if (_CoreParameter.bFastmem)
EMM::UninstallExceptionHandler(); EMM::UninstallExceptionHandler();
@ -445,7 +445,7 @@ static void FifoPlayerThread()
} }
if (!_CoreParameter.bCPUThread) if (!_CoreParameter.bCPUThread)
g_video_backend->Video_Cleanup(); g_video_backend->Video_CleanupShared();
} }
// Initialize and create emulation thread // Initialize and create emulation thread
@ -654,7 +654,7 @@ static void EmuThread(std::unique_ptr<BootParameters> boot)
INFO_LOG(CONSOLE, "%s", StopMessage(true, "CPU thread stopped.").c_str()); INFO_LOG(CONSOLE, "%s", StopMessage(true, "CPU thread stopped.").c_str());
if (core_parameter.bCPUThread) if (core_parameter.bCPUThread)
g_video_backend->Video_Cleanup(); g_video_backend->Video_CleanupShared();
// If we shut down normally, the stop message does not need to be triggered. // If we shut down normally, the stop message does not need to be triggered.
stop_message_guard.Dismiss(); stop_message_guard.Dismiss();

View File

@ -45,6 +45,15 @@ void VideoBackendBase::Video_ExitLoop()
s_FifoShuttingDown.Set(); s_FifoShuttingDown.Set();
} }
void VideoBackendBase::Video_CleanupShared()
{
// First stop any framedumping, which might need to dump the last xfb frame. This process
// can require additional graphics sub-systems so it needs to be done first
g_renderer->ExitFramedumping();
Video_Cleanup();
}
// Run from the CPU thread (from VideoInterface.cpp) // Run from the CPU thread (from VideoInterface.cpp)
void VideoBackendBase::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, void VideoBackendBase::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
u64 ticks) u64 ticks)

View File

@ -97,11 +97,15 @@ Renderer::Renderer(int backbuffer_width, int backbuffer_height)
m_last_host_config_bits = ShaderHostConfig::GetCurrent().bits; m_last_host_config_bits = ShaderHostConfig::GetCurrent().bits;
} }
Renderer::~Renderer() Renderer::~Renderer() = default;
void Renderer::ExitFramedumping()
{ {
ShutdownFrameDumping(); ShutdownFrameDumping();
if (m_frame_dump_thread.joinable()) if (m_frame_dump_thread.joinable())
m_frame_dump_thread.join(); m_frame_dump_thread.join();
m_dump_texture.reset();
} }
void Renderer::RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbStride, u32 fbHeight, void Renderer::RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbStride, u32 fbHeight,
@ -625,20 +629,13 @@ void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const
m_aspect_wide = flush_count_anamorphic > 0.75 * flush_total; m_aspect_wide = flush_count_anamorphic > 0.75 * flush_total;
} }
// The FinishFrameData 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.
FinishFrameData();
if (IsFrameDumping() && m_last_xfb_texture) if (IsFrameDumping() && m_last_xfb_texture)
{ {
UpdateFrameDumpTexture(horizontal_scale); FinishFrameData();
auto result = m_dump_texture->Map();
if (result.has_value())
{
auto raw_data = result.value();
DumpFrameData(raw_data.data, raw_data.width, raw_data.height, raw_data.stride,
AVIDump::FetchState(ticks));
} }
else
{
ShutdownFrameDumping();
} }
bool update_frame_count = false; bool update_frame_count = false;
@ -653,12 +650,18 @@ void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const
{ {
m_last_xfb_texture = xfb_entry->texture.get(); m_last_xfb_texture = xfb_entry->texture.get();
m_last_xfb_id = xfb_entry->id; m_last_xfb_id = xfb_entry->id;
m_last_xfb_ticks = ticks;
m_last_xfb_horizontal_scale = horizontal_scale;
// TODO: merge more generic parts into VideoCommon // TODO: merge more generic parts into VideoCommon
g_renderer->SwapImpl(xfb_entry->texture.get(), rc, ticks, xfb_entry->gamma); g_renderer->SwapImpl(xfb_entry->texture.get(), rc, ticks, xfb_entry->gamma);
m_fps_counter.Update(); m_fps_counter.Update();
update_frame_count = true; update_frame_count = true;
if (IsFrameDumping())
{
DoDumpFrame();
}
} }
// Update our last xfb values // Update our last xfb values
@ -685,10 +688,22 @@ bool Renderer::IsFrameDumping()
if (SConfig::GetInstance().m_DumpFrames) if (SConfig::GetInstance().m_DumpFrames)
return true; return true;
ShutdownFrameDumping();
return false; return false;
} }
void Renderer::DoDumpFrame()
{
UpdateFrameDumpTexture(m_last_xfb_horizontal_scale);
auto result = m_dump_texture->Map();
if (result.has_value())
{
auto raw_data = result.value();
DumpFrameData(raw_data.data, raw_data.width, raw_data.height, raw_data.stride,
AVIDump::FetchState(m_last_xfb_ticks));
}
}
void Renderer::UpdateFrameDumpTexture(float horizontal_scale) void Renderer::UpdateFrameDumpTexture(float horizontal_scale)
{ {
int target_width, target_height; int target_width, target_height;

View File

@ -142,6 +142,8 @@ public:
virtual void ChangeSurface(void* new_surface_handle) {} virtual void ChangeSurface(void* new_surface_handle) {}
bool UseVertexDepthRange() const; bool UseVertexDepthRange() const;
void ExitFramedumping();
protected: protected:
std::tuple<int, int> CalculateTargetScale(int x, int y) const; std::tuple<int, int> CalculateTargetScale(int x, int y) const;
bool CalculateTargetSize(); bool CalculateTargetSize();
@ -179,6 +181,7 @@ protected:
u32 m_last_host_config_bits = 0; u32 m_last_host_config_bits = 0;
private: private:
void DoDumpFrame();
void RunFrameDumps(); void RunFrameDumps();
void ShutdownFrameDumping(); void ShutdownFrameDumping();
std::tuple<int, int> CalculateOutputDimensions(int width, int height); std::tuple<int, int> CalculateOutputDimensions(int width, int height);
@ -208,8 +211,10 @@ private:
AVIDump::Frame state; AVIDump::Frame state;
} m_frame_dump_config; } m_frame_dump_config;
AbstractTexture* m_last_xfb_texture; AbstractTexture* m_last_xfb_texture = nullptr;
u64 m_last_xfb_id = 0; u64 m_last_xfb_id = std::numeric_limits<u64>::max();
u64 m_last_xfb_ticks = 0;
float m_last_xfb_horizontal_scale = 0.0f;
std::unique_ptr<AbstractTexture> m_dump_texture; std::unique_ptr<AbstractTexture> m_dump_texture;

View File

@ -47,7 +47,9 @@ public:
virtual void Video_Prepare() = 0; virtual void Video_Prepare() = 0;
void Video_ExitLoop(); void Video_ExitLoop();
virtual void Video_Cleanup() = 0; // called from gl/d3d thread
void Video_CleanupShared(); // called from gl/d3d thread
virtual void Video_Cleanup() = 0;
void Video_BeginField(u32, u32, u32, u32, u64); void Video_BeginField(u32, u32, u32, u32, u64);