[Vulkan] Implement submit_on_primary_buffer_end optimization

This commit is contained in:
Herman S.
2025-12-01 21:38:10 +09:00
parent 7d2f5239ed
commit 1c670bf3a6
5 changed files with 31 additions and 6 deletions
@@ -33,12 +33,8 @@ DEFINE_bool(d3d12_bindless, true,
"but may make debugging more complicated.",
"D3D12");
DEFINE_bool(d3d12_submit_on_primary_buffer_end, true,
"Submit the command list when a PM4 primary buffer ends if it's "
"possible to submit immediately to try to reduce frame latency.",
"D3D12");
DECLARE_bool(clear_memory_page_state);
DECLARE_bool(submit_on_primary_buffer_end);
DECLARE_bool(readback_memexport_fast);
namespace xe {
@@ -2604,7 +2600,7 @@ void D3D12CommandProcessor::IssueSwap(uint32_t frontbuffer_ptr,
}
void D3D12CommandProcessor::OnPrimaryBufferEnd() {
if (cvars::d3d12_submit_on_primary_buffer_end && submission_open_ &&
if (cvars::submit_on_primary_buffer_end && submission_open_ &&
CanEndSubmissionImmediately()) {
EndSubmission(false);
}
+5
View File
@@ -95,3 +95,8 @@ DEFINE_string(
" Performance limited primarily by overdraw.\n"
" Maps to 'fsi' on Vulkan and 'rov' on D3D12.",
"GPU");
DEFINE_bool(submit_on_primary_buffer_end, true,
"Submit the command buffer when a PM4 primary buffer ends if it's "
"possible to submit immediately to try to reduce frame latency.",
"GPU");
@@ -37,6 +37,7 @@
DECLARE_bool(clear_memory_page_state);
DECLARE_bool(readback_memexport_fast);
DECLARE_bool(submit_on_primary_buffer_end);
namespace xe {
namespace gpu {
@@ -1707,6 +1708,14 @@ void VulkanCommandProcessor::IssueSwap(uint32_t frontbuffer_ptr,
EndSubmission(true);
}
void VulkanCommandProcessor::OnPrimaryBufferEnd() {
if (cvars::submit_on_primary_buffer_end && submission_open_ &&
!scratch_buffer_used_ && !active_occlusion_query_.valid &&
CanEndSubmissionImmediately()) {
EndSubmission(false);
}
}
bool VulkanCommandProcessor::PushBufferMemoryBarrier(
VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size,
VkPipelineStageFlags src_stage_mask, VkPipelineStageFlags dst_stage_mask,
@@ -3989,6 +3998,11 @@ bool VulkanCommandProcessor::BeginSubmission(bool is_guest_command) {
return true;
}
bool VulkanCommandProcessor::CanEndSubmissionImmediately() {
return !submission_open_ || !pipeline_cache_ ||
!pipeline_cache_->IsCreatingPipelines();
}
bool VulkanCommandProcessor::EndSubmission(bool is_swap) {
const ui::vulkan::VulkanDevice* const vulkan_device = GetVulkanDevice();
const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions();
@@ -277,6 +277,8 @@ class VulkanCommandProcessor final : public CommandProcessor {
void IssueSwap(uint32_t frontbuffer_ptr, uint32_t frontbuffer_width,
uint32_t frontbuffer_height) override;
void OnPrimaryBufferEnd() override;
Shader* LoadShader(xenos::ShaderType shader_type, uint32_t guest_address,
const uint32_t* host_address,
uint32_t dword_count) override;
@@ -431,6 +433,10 @@ class VulkanCommandProcessor final : public CommandProcessor {
// clearing and stopping capturing. Returns whether the submission was done
// successfully, if it has failed, leaves it open.
bool EndSubmission(bool is_swap);
// Checks if ending a submission right now would not cause potentially more
// delay than it would reduce - such as when there are unfinished graphics
// pipeline creation requests.
bool CanEndSubmissionImmediately();
bool AwaitAllQueueOperationsCompletion() {
CheckSubmissionFenceAndDeviceLoss(GetCurrentSubmission());
return !submission_open_ && submissions_in_flight_fences_.empty();
+4
View File
@@ -38,6 +38,10 @@ inline const std::vector<CvarAlias>& GetCvarAliases() {
{"render_target_path_vulkan", "fsi", "render_target_path", "accuracy"},
{"disable_doubleclick_fullscreen", "true", "disable_game_window_mouse",
"true"},
{"d3d12_submit_on_primary_buffer_end", "true",
"submit_on_primary_buffer_end", "true"},
{"d3d12_submit_on_primary_buffer_end", "false",
"submit_on_primary_buffer_end", "false"},
#if XE_PLATFORM_WIN32
{"gpu", "any", "gpu", "d3d12"},
{"apu", "any", "apu", "xaudio2"},