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; } }