diff --git a/src/xenia/gpu/d3d12/d3d12_command_processor.cc b/src/xenia/gpu/d3d12/d3d12_command_processor.cc index e686bc961..c702140e6 100644 --- a/src/xenia/gpu/d3d12/d3d12_command_processor.cc +++ b/src/xenia/gpu/d3d12/d3d12_command_processor.cc @@ -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); } diff --git a/src/xenia/gpu/gpu_flags.cc b/src/xenia/gpu/gpu_flags.cc index 99473584e..7dd9ac655 100644 --- a/src/xenia/gpu/gpu_flags.cc +++ b/src/xenia/gpu/gpu_flags.cc @@ -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"); diff --git a/src/xenia/gpu/vulkan/vulkan_command_processor.cc b/src/xenia/gpu/vulkan/vulkan_command_processor.cc index 90523f747..c50b0a73f 100644 --- a/src/xenia/gpu/vulkan/vulkan_command_processor.cc +++ b/src/xenia/gpu/vulkan/vulkan_command_processor.cc @@ -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(); diff --git a/src/xenia/gpu/vulkan/vulkan_command_processor.h b/src/xenia/gpu/vulkan/vulkan_command_processor.h index a1cb2bf08..baef87e80 100644 --- a/src/xenia/gpu/vulkan/vulkan_command_processor.h +++ b/src/xenia/gpu/vulkan/vulkan_command_processor.h @@ -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(); diff --git a/src/xenia/ui/config_helpers.h b/src/xenia/ui/config_helpers.h index fa0f395b2..30d3f4413 100644 --- a/src/xenia/ui/config_helpers.h +++ b/src/xenia/ui/config_helpers.h @@ -38,6 +38,10 @@ inline const std::vector& 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"},