From a475792163d3383d94e3bd21e4d3c22077ef63ab Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sun, 20 Nov 2016 02:51:53 +1000 Subject: [PATCH] Vulkan: Fix incorrect logic in readback preemption This could have been causing a large number of command buffer submissions per frame, depending on when the readbacks occured. --- Source/Core/VideoBackends/Vulkan/Constants.h | 3 +++ Source/Core/VideoBackends/Vulkan/StateTracker.cpp | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/Source/Core/VideoBackends/Vulkan/Constants.h b/Source/Core/VideoBackends/Vulkan/Constants.h index e5c774cfc5..fd66dcc32b 100644 --- a/Source/Core/VideoBackends/Vulkan/Constants.h +++ b/Source/Core/VideoBackends/Vulkan/Constants.h @@ -113,6 +113,9 @@ constexpr size_t TEXTURE_CONVERSION_TEXEL_BUFFER_SIZE = 8 * 1024 * 1024; // Push constant buffer size for utility shaders constexpr u32 PUSH_CONSTANT_BUFFER_SIZE = 128; +// Minimum number of draw calls per command buffer when attempting to preempt a readback operation. +constexpr u32 MINIMUM_DRAW_CALLS_PER_COMMAND_BUFFER_FOR_READBACK = 10; + // Rasterization state info union RasterizationState { BitField<0, 2, VkCullModeFlags> cull_mode; diff --git a/Source/Core/VideoBackends/Vulkan/StateTracker.cpp b/Source/Core/VideoBackends/Vulkan/StateTracker.cpp index ef2343564d..34ea98f41b 100644 --- a/Source/Core/VideoBackends/Vulkan/StateTracker.cpp +++ b/Source/Core/VideoBackends/Vulkan/StateTracker.cpp @@ -792,7 +792,12 @@ void StateTracker::OnEndFrame() u32 interval = static_cast(g_ActiveConfig.iCommandBufferExecuteInterval); for (u32 draw_counter : m_cpu_accesses_this_frame) { + // We don't want to waste executing command buffers for only a few draws, so set a minimum. + // Leave last_draw_counter as-is, so we get the correct number of draws between submissions. u32 draw_count = draw_counter - last_draw_counter; + if (draw_count < MINIMUM_DRAW_CALLS_PER_COMMAND_BUFFER_FOR_READBACK) + continue; + if (draw_count <= interval) { u32 mid_point = draw_count / 2; @@ -807,6 +812,8 @@ void StateTracker::OnEndFrame() counter += interval; } } + + last_draw_counter = draw_counter; } }