Vulkan: Submit fewer command buffers in deferred EFB copies mode
This commit is contained in:
parent
8e2c063d62
commit
66b6e72c5e
|
@ -611,7 +611,7 @@ bool FramebufferManager::PopulateColorReadbackTexture()
|
||||||
{
|
{
|
||||||
// Can't be in our normal render pass.
|
// Can't be in our normal render pass.
|
||||||
StateTracker::GetInstance()->EndRenderPass();
|
StateTracker::GetInstance()->EndRenderPass();
|
||||||
StateTracker::GetInstance()->OnReadback();
|
StateTracker::GetInstance()->OnCPUEFBAccess();
|
||||||
|
|
||||||
// Issue a copy from framebuffer -> copy texture if we have >1xIR or MSAA on.
|
// Issue a copy from framebuffer -> copy texture if we have >1xIR or MSAA on.
|
||||||
VkRect2D src_region = {{0, 0}, {GetEFBWidth(), GetEFBHeight()}};
|
VkRect2D src_region = {{0, 0}, {GetEFBWidth(), GetEFBHeight()}};
|
||||||
|
@ -684,7 +684,7 @@ bool FramebufferManager::PopulateDepthReadbackTexture()
|
||||||
{
|
{
|
||||||
// Can't be in our normal render pass.
|
// Can't be in our normal render pass.
|
||||||
StateTracker::GetInstance()->EndRenderPass();
|
StateTracker::GetInstance()->EndRenderPass();
|
||||||
StateTracker::GetInstance()->OnReadback();
|
StateTracker::GetInstance()->OnCPUEFBAccess();
|
||||||
|
|
||||||
// Issue a copy from framebuffer -> copy texture if we have >1xIR or MSAA on.
|
// Issue a copy from framebuffer -> copy texture if we have >1xIR or MSAA on.
|
||||||
VkRect2D src_region = {{0, 0}, {GetEFBWidth(), GetEFBHeight()}};
|
VkRect2D src_region = {{0, 0}, {GetEFBWidth(), GetEFBHeight()}};
|
||||||
|
|
|
@ -513,7 +513,7 @@ void StateTracker::OnDraw()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StateTracker::OnReadback()
|
void StateTracker::OnCPUEFBAccess()
|
||||||
{
|
{
|
||||||
// Check this isn't another access without any draws inbetween.
|
// Check this isn't another access without any draws inbetween.
|
||||||
if (!m_cpu_accesses_this_frame.empty() && m_cpu_accesses_this_frame.back() == m_draw_counter)
|
if (!m_cpu_accesses_this_frame.empty() && m_cpu_accesses_this_frame.back() == m_draw_counter)
|
||||||
|
@ -523,9 +523,28 @@ void StateTracker::OnReadback()
|
||||||
m_cpu_accesses_this_frame.emplace_back(m_draw_counter);
|
m_cpu_accesses_this_frame.emplace_back(m_draw_counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StateTracker::OnEFBCopyToRAM()
|
||||||
|
{
|
||||||
|
// If we're not deferring, try to preempt it next frame.
|
||||||
|
if (!g_ActiveConfig.bDeferEFBCopies)
|
||||||
|
{
|
||||||
|
OnCPUEFBAccess();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, only execute if we have at least 10 objects between us and the last copy.
|
||||||
|
const u32 diff = m_draw_counter - m_last_efb_copy_draw_counter;
|
||||||
|
m_last_efb_copy_draw_counter = m_draw_counter;
|
||||||
|
if (diff < MINIMUM_DRAW_CALLS_PER_COMMAND_BUFFER_FOR_READBACK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Util::ExecuteCurrentCommandsAndRestoreState(true);
|
||||||
|
}
|
||||||
|
|
||||||
void StateTracker::OnEndFrame()
|
void StateTracker::OnEndFrame()
|
||||||
{
|
{
|
||||||
m_draw_counter = 0;
|
m_draw_counter = 0;
|
||||||
|
m_last_efb_copy_draw_counter = 0;
|
||||||
m_scheduled_command_buffer_kicks.clear();
|
m_scheduled_command_buffer_kicks.clear();
|
||||||
|
|
||||||
// If we have no CPU access at all, leave everything in the one command buffer for maximum
|
// If we have no CPU access at all, leave everything in the one command buffer for maximum
|
||||||
|
|
|
@ -86,8 +86,10 @@ public:
|
||||||
void OnDraw();
|
void OnDraw();
|
||||||
|
|
||||||
// Call after CPU access is requested.
|
// Call after CPU access is requested.
|
||||||
// This can be via EFBCache or EFB2RAM.
|
void OnCPUEFBAccess();
|
||||||
void OnReadback();
|
|
||||||
|
// Call after an EFB copy to RAM. If true, the current command buffer should be executed.
|
||||||
|
void OnEFBCopyToRAM();
|
||||||
|
|
||||||
// Call at the end of a frame.
|
// Call at the end of a frame.
|
||||||
void OnEndFrame();
|
void OnEndFrame();
|
||||||
|
@ -182,6 +184,7 @@ private:
|
||||||
|
|
||||||
// CPU access tracking
|
// CPU access tracking
|
||||||
u32 m_draw_counter = 0;
|
u32 m_draw_counter = 0;
|
||||||
|
u32 m_last_efb_copy_draw_counter = 0;
|
||||||
std::vector<u32> m_cpu_accesses_this_frame;
|
std::vector<u32> m_cpu_accesses_this_frame;
|
||||||
std::vector<u32> m_scheduled_command_buffer_kicks;
|
std::vector<u32> m_scheduled_command_buffer_kicks;
|
||||||
bool m_allow_background_execution = true;
|
bool m_allow_background_execution = true;
|
||||||
|
|
|
@ -126,7 +126,6 @@ void TextureCache::CopyEFB(AbstractStagingTexture* dst, const EFBCopyParams& par
|
||||||
// The barrier has to happen after the render pass, not inside it, as we are going to be
|
// The barrier has to happen after the render pass, not inside it, as we are going to be
|
||||||
// reading from the texture immediately afterwards.
|
// reading from the texture immediately afterwards.
|
||||||
StateTracker::GetInstance()->EndRenderPass();
|
StateTracker::GetInstance()->EndRenderPass();
|
||||||
StateTracker::GetInstance()->OnReadback();
|
|
||||||
|
|
||||||
// Transition to shader resource before reading.
|
// Transition to shader resource before reading.
|
||||||
VkImageLayout original_layout = src_texture->GetLayout();
|
VkImageLayout original_layout = src_texture->GetLayout();
|
||||||
|
@ -139,6 +138,8 @@ void TextureCache::CopyEFB(AbstractStagingTexture* dst, const EFBCopyParams& par
|
||||||
|
|
||||||
// Transition back to original state
|
// Transition back to original state
|
||||||
src_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), original_layout);
|
src_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), original_layout);
|
||||||
|
|
||||||
|
StateTracker::GetInstance()->OnEFBCopyToRAM();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextureCache::SupportsGPUTextureDecode(TextureFormat format, TLUTFormat palette_format)
|
bool TextureCache::SupportsGPUTextureDecode(TextureFormat format, TLUTFormat palette_format)
|
||||||
|
|
Loading…
Reference in New Issue