diff --git a/src/xenia/gpu/d3d12/d3d12_command_processor.cc b/src/xenia/gpu/d3d12/d3d12_command_processor.cc index cfc894a36..b253d0dbb 100644 --- a/src/xenia/gpu/d3d12/d3d12_command_processor.cc +++ b/src/xenia/gpu/d3d12/d3d12_command_processor.cc @@ -31,11 +31,25 @@ void D3D12CommandProcessor::ClearCaches() { bool D3D12CommandProcessor::SetupContext() { if (!CommandProcessor::SetupContext()) { - XELOGE("Unable to initialize base command processor context"); + XELOGE("Failed to initialize base command processor context"); return false; } auto context = GetD3D12Context(); + auto provider = context->GetD3D12Provider(); + auto device = provider->GetDevice(); + auto direct_queue = provider->GetDirectQueue(); + + for (uint32_t i = 0; i < ui::d3d12::D3D12Context::kQueuedFrames; ++i) { + command_lists_setup_[i] = ui::d3d12::CommandList::Create( + device, direct_queue, D3D12_COMMAND_LIST_TYPE_DIRECT); + command_lists_[i] = ui::d3d12::CommandList::Create( + device, direct_queue, D3D12_COMMAND_LIST_TYPE_DIRECT); + if (command_lists_setup_[i] == nullptr || command_lists_[i] == nullptr) { + XELOGE("Failed to create the command lists"); + return false; + } + } pipeline_cache_ = std::make_unique(register_file_, context); @@ -48,6 +62,11 @@ void D3D12CommandProcessor::ShutdownContext() { pipeline_cache_.reset(); + for (uint32_t i = 0; i < ui::d3d12::D3D12Context::kQueuedFrames; ++i) { + command_lists_[i].reset(); + command_lists_setup_[i].reset(); + } + CommandProcessor::ShutdownContext(); } @@ -56,9 +75,7 @@ void D3D12CommandProcessor::PerformSwap(uint32_t frontbuffer_ptr, uint32_t frontbuffer_height) { SCOPE_profile_cpu_f("gpu"); - if (current_queue_frame_ != UINT32_MAX) { - EndFrame(); - } + EndFrame(); if (cache_clear_requested_) { cache_clear_requested_ = false; @@ -116,11 +133,7 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type, return true; } - bool full_update = false; - if (current_queue_frame_ == UINT32_MAX) { - BeginFrame(); - full_update = true; - } + bool full_update = BeginFrame(); auto pipeline_status = pipeline_cache_->ConfigurePipeline( vertex_shader, pixel_shader, primitive_type); @@ -133,22 +146,35 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type, bool D3D12CommandProcessor::IssueCopy() { return true; } -void D3D12CommandProcessor::BeginFrame() { - assert_true(current_queue_frame_ == UINT32_MAX); +bool D3D12CommandProcessor::BeginFrame() { + if (current_queue_frame_ != UINT32_MAX) { + return false; + } + auto context = GetD3D12Context(); - context->BeginSwap(); - current_queue_frame_ = context->GetCurrentQueueFrame(); + + command_lists_setup_[current_queue_frame_]->BeginRecording(); + command_lists_[current_queue_frame_]->BeginRecording(); + + return true; } -void D3D12CommandProcessor::EndFrame() { - assert_true(current_queue_frame_ != UINT32_MAX); +bool D3D12CommandProcessor::EndFrame() { + if (current_queue_frame_ == UINT32_MAX) { + return false; + } + + // TODO(Triang3l): Don't execute the setup command list if it's empty. + command_lists_setup_[current_queue_frame_]->Execute(); + command_lists_[current_queue_frame_]->Execute(); + auto context = GetD3D12Context(); - context->EndSwap(); - current_queue_frame_ = UINT32_MAX; + + return true; } } // namespace d3d12 diff --git a/src/xenia/gpu/d3d12/d3d12_command_processor.h b/src/xenia/gpu/d3d12/d3d12_command_processor.h index 8f7856655..d56cb62fd 100644 --- a/src/xenia/gpu/d3d12/d3d12_command_processor.h +++ b/src/xenia/gpu/d3d12/d3d12_command_processor.h @@ -17,6 +17,7 @@ #include "xenia/gpu/d3d12/pipeline_cache.h" #include "xenia/gpu/xenos.h" #include "xenia/kernel/kernel_state.h" +#include "xenia/ui/d3d12/command_list.h" #include "xenia/ui/d3d12/d3d12_context.h" namespace xe { @@ -52,11 +53,18 @@ class D3D12CommandProcessor : public CommandProcessor { bool IssueCopy() override; private: - void BeginFrame(); - void EndFrame(); + // Returns true if a new frame was started. + bool BeginFrame(); + // Returns true if an open frame was ended. + bool EndFrame(); bool cache_clear_requested_ = false; + std::unique_ptr + command_lists_setup_[ui::d3d12::D3D12Context::kQueuedFrames] = {}; + std::unique_ptr + command_lists_[ui::d3d12::D3D12Context::kQueuedFrames] = {}; + std::unique_ptr pipeline_cache_; uint32_t current_queue_frame_ = UINT32_MAX;