[D3D12] Submit command lists on primary buffer end

This commit is contained in:
Triang3l 2019-12-04 21:42:26 +03:00
parent 922f1f220a
commit c43ccc073d
6 changed files with 34 additions and 0 deletions

View File

@ -464,6 +464,8 @@ uint32_t CommandProcessor::ExecutePrimaryBuffer(uint32_t read_index,
} }
} while (reader.read_count()); } while (reader.read_count());
OnPrimaryBufferEnd();
trace_writer_.WritePrimaryBufferEnd(); trace_writer_.WritePrimaryBufferEnd();
return write_index; return write_index;

View File

@ -177,6 +177,7 @@ class CommandProcessor {
uint32_t frontbuffer_height) = 0; uint32_t frontbuffer_height) = 0;
uint32_t ExecutePrimaryBuffer(uint32_t start_index, uint32_t end_index); uint32_t ExecutePrimaryBuffer(uint32_t start_index, uint32_t end_index);
virtual void OnPrimaryBufferEnd() {}
void ExecuteIndirectBuffer(uint32_t ptr, uint32_t length); void ExecuteIndirectBuffer(uint32_t ptr, uint32_t length);
bool ExecutePacket(RingBuffer* reader); bool ExecutePacket(RingBuffer* reader);
bool ExecutePacketType0(RingBuffer* reader, uint32_t packet); bool ExecutePacketType0(RingBuffer* reader, uint32_t packet);

View File

@ -50,6 +50,10 @@ DEFINE_bool(d3d12_ssaa_custom_sample_positions, false,
"path where available instead of centers (experimental, not very " "path where available instead of centers (experimental, not very "
"high-quality).", "high-quality).",
"D3D12"); "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");
namespace xe { namespace xe {
namespace gpu { namespace gpu {
@ -1222,6 +1226,13 @@ void D3D12CommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
EndSubmission(true); EndSubmission(true);
} }
void D3D12CommandProcessor::OnPrimaryBufferEnd() {
if (cvars::d3d12_submit_on_primary_buffer_end && submission_open_ &&
CanEndSubmissionImmediately()) {
EndSubmission(false);
}
}
Shader* D3D12CommandProcessor::LoadShader(ShaderType shader_type, Shader* D3D12CommandProcessor::LoadShader(ShaderType shader_type,
uint32_t guest_address, uint32_t guest_address,
const uint32_t* host_address, const uint32_t* host_address,
@ -2073,6 +2084,10 @@ bool D3D12CommandProcessor::EndSubmission(bool is_swap) {
return true; return true;
} }
bool D3D12CommandProcessor::CanEndSubmissionImmediately() const {
return !submission_open_ || !pipeline_cache_->IsCreatingPipelines();
}
void D3D12CommandProcessor::AwaitAllSubmissionsCompletion() { void D3D12CommandProcessor::AwaitAllSubmissionsCompletion() {
// May be called if shutting down without everything set up. // May be called if shutting down without everything set up.
if ((submission_completed_ + 1) >= submission_current_ || if ((submission_completed_ + 1) >= submission_current_ ||

View File

@ -164,6 +164,8 @@ class D3D12CommandProcessor : public CommandProcessor {
void PerformSwap(uint32_t frontbuffer_ptr, uint32_t frontbuffer_width, void PerformSwap(uint32_t frontbuffer_ptr, uint32_t frontbuffer_width,
uint32_t frontbuffer_height) override; uint32_t frontbuffer_height) override;
void OnPrimaryBufferEnd() override;
Shader* LoadShader(ShaderType shader_type, uint32_t guest_address, Shader* LoadShader(ShaderType shader_type, uint32_t guest_address,
const uint32_t* host_address, const uint32_t* host_address,
uint32_t dword_count) override; uint32_t dword_count) override;
@ -235,6 +237,11 @@ class D3D12CommandProcessor : public CommandProcessor {
// clearing and stopping capturing. Returns whether the submission was done // clearing and stopping capturing. Returns whether the submission was done
// successfully, if it has failed, leaves it open. // successfully, if it has failed, leaves it open.
bool EndSubmission(bool is_swap); bool EndSubmission(bool is_swap);
// Checks if ending a submission right now would not cause potentially more
// delay than it would reduce by making the GPU start working earlier - such
// as when there are unfinished graphics pipeline state creation requests that
// would need to be fulfilled before actually submitting the command list.
bool CanEndSubmissionImmediately() const;
void AwaitAllSubmissionsCompletion(); void AwaitAllSubmissionsCompletion();
// Need to await submission completion before calling. // Need to await submission completion before calling.
void ClearCommandAllocatorCache(); void ClearCommandAllocatorCache();

View File

@ -172,6 +172,14 @@ void PipelineCache::EndSubmission() {
} }
} }
bool PipelineCache::IsCreatingPipelines() {
if (creation_threads_.empty()) {
return false;
}
std::lock_guard<std::mutex> lock(creation_request_lock_);
return !creation_queue_.empty() || creation_threads_busy_ != 0;
}
D3D12Shader* PipelineCache::LoadShader(ShaderType shader_type, D3D12Shader* PipelineCache::LoadShader(ShaderType shader_type,
uint32_t guest_address, uint32_t guest_address,
const uint32_t* host_address, const uint32_t* host_address,

View File

@ -43,6 +43,7 @@ class PipelineCache {
void ClearCache(); void ClearCache();
void EndSubmission(); void EndSubmission();
bool IsCreatingPipelines();
D3D12Shader* LoadShader(ShaderType shader_type, uint32_t guest_address, D3D12Shader* LoadShader(ShaderType shader_type, uint32_t guest_address,
const uint32_t* host_address, uint32_t dword_count); const uint32_t* host_address, uint32_t dword_count);