Video Common: Improve texture dumping to work with fifoci and
fifo_comparer
This commit is contained in:
parent
53684701fa
commit
a129a53e56
|
@ -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();
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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();
|
else
|
||||||
if (result.has_value())
|
{
|
||||||
{
|
ShutdownFrameDumping();
|
||||||
auto raw_data = result.value();
|
|
||||||
DumpFrameData(raw_data.data, raw_data.width, raw_data.height, raw_data.stride,
|
|
||||||
AVIDump::FetchState(ticks));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue