diff --git a/src/xenia/gpu/d3d12/d3d12_command_processor.cc b/src/xenia/gpu/d3d12/d3d12_command_processor.cc index 74170139b..e9831347d 100644 --- a/src/xenia/gpu/d3d12/d3d12_command_processor.cc +++ b/src/xenia/gpu/d3d12/d3d12_command_processor.cc @@ -80,7 +80,7 @@ void D3D12CommandProcessor::InitializeShaderStorage( void D3D12CommandProcessor::RequestFrameTrace( const std::filesystem::path& root_path) { // Capture with PIX if attached. - if (GetD3D12Context()->GetD3D12Provider()->GetGraphicsAnalysis() != nullptr) { + if (GetD3D12Context().GetD3D12Provider().GetGraphicsAnalysis() != nullptr) { pix_capture_requested_.store(true, std::memory_order_relaxed); return; } @@ -377,7 +377,7 @@ ID3D12RootSignature* D3D12CommandProcessor::GetRootSignature( } ID3D12RootSignature* root_signature = ui::d3d12::util::CreateRootSignature( - GetD3D12Context()->GetD3D12Provider(), desc); + GetD3D12Context().GetD3D12Provider(), desc); if (root_signature == nullptr) { XELOGE( "Failed to create a root signature with {} pixel textures, {} pixel " @@ -448,10 +448,10 @@ uint64_t D3D12CommandProcessor::RequestViewBindfulDescriptors( deferred_command_list_->SetDescriptorHeaps(view_bindful_heap_current_, sampler_bindful_heap_current_); } - auto provider = GetD3D12Context()->GetD3D12Provider(); - cpu_handle_out = provider->OffsetViewDescriptor( + auto& provider = GetD3D12Context().GetD3D12Provider(); + cpu_handle_out = provider.OffsetViewDescriptor( view_bindful_heap_pool_->GetLastRequestHeapCPUStart(), descriptor_index); - gpu_handle_out = provider->OffsetViewDescriptor( + gpu_handle_out = provider.OffsetViewDescriptor( view_bindful_heap_pool_->GetLastRequestHeapGPUStart(), descriptor_index); return current_heap_index; } @@ -482,7 +482,7 @@ bool D3D12CommandProcessor::RequestOneUseSingleViewDescriptors( return true; } assert_not_null(handles_out); - auto provider = GetD3D12Context()->GetD3D12Provider(); + auto& provider = GetD3D12Context().GetD3D12Provider(); if (bindless_resources_used_) { // Request separate bindless descriptors that will be freed when this // submission is completed by the GPU. @@ -501,9 +501,9 @@ bool D3D12CommandProcessor::RequestOneUseSingleViewDescriptors( view_bindless_one_use_descriptors_.push_back( std::make_pair(descriptor_index, submission_current_)); handles_out[i] = - std::make_pair(provider->OffsetViewDescriptor( + std::make_pair(provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, descriptor_index), - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_gpu_start_, descriptor_index)); } } else { @@ -518,8 +518,8 @@ bool D3D12CommandProcessor::RequestOneUseSingleViewDescriptors( } for (uint32_t i = 0; i < count; ++i) { handles_out[i] = - std::make_pair(provider->OffsetViewDescriptor(cpu_handle_start, i), - provider->OffsetViewDescriptor(gpu_handle_start, i)); + std::make_pair(provider.OffsetViewDescriptor(cpu_handle_start, i), + provider.OffsetViewDescriptor(gpu_handle_start, i)); } } return true; @@ -529,10 +529,10 @@ ui::d3d12::util::DescriptorCPUGPUHandlePair D3D12CommandProcessor::GetSystemBindlessViewHandlePair( SystemBindlessView view) const { assert_true(bindless_resources_used_); - auto provider = GetD3D12Context()->GetD3D12Provider(); - return std::make_pair(provider->OffsetViewDescriptor( + auto& provider = GetD3D12Context().GetD3D12Provider(); + return std::make_pair(provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(view)), - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_gpu_start_, uint32_t(view))); } @@ -619,11 +619,11 @@ uint64_t D3D12CommandProcessor::RequestSamplerBindfulDescriptors( deferred_command_list_->SetDescriptorHeaps(view_bindful_heap_current_, sampler_bindful_heap_current_); } - auto provider = GetD3D12Context()->GetD3D12Provider(); - cpu_handle_out = provider->OffsetSamplerDescriptor( + auto& provider = GetD3D12Context().GetD3D12Provider(); + cpu_handle_out = provider.OffsetSamplerDescriptor( sampler_bindful_heap_pool_->GetLastRequestHeapCPUStart(), descriptor_index); - gpu_handle_out = provider->OffsetSamplerDescriptor( + gpu_handle_out = provider.OffsetSamplerDescriptor( sampler_bindful_heap_pool_->GetLastRequestHeapGPUStart(), descriptor_index); return current_heap_index; @@ -646,7 +646,7 @@ ID3D12Resource* D3D12CommandProcessor::RequestScratchGPUBuffer( size = xe::align(size, kScratchBufferSizeIncrement); - auto device = GetD3D12Context()->GetD3D12Provider()->GetDevice(); + auto device = GetD3D12Context().GetD3D12Provider().GetDevice(); D3D12_RESOURCE_DESC buffer_desc; ui::d3d12::util::FillBufferResourceDesc( buffer_desc, size, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); @@ -690,8 +690,8 @@ void D3D12CommandProcessor::SetSamplePositions( // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/nf-d3d12-id3d12graphicscommandlist1-setsamplepositions if (cvars::d3d12_ssaa_custom_sample_positions && !edram_rov_used_ && command_list_1_) { - auto provider = GetD3D12Context()->GetD3D12Provider(); - auto tier = provider->GetProgrammableSamplePositionsTier(); + auto& provider = GetD3D12Context().GetD3D12Provider(); + auto tier = provider.GetProgrammableSamplePositionsTier(); if (tier >= D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_2) { // Depth buffer transitions are affected by sample positions. SubmitBarriers(); @@ -830,9 +830,9 @@ bool D3D12CommandProcessor::SetupContext() { return false; } - auto provider = GetD3D12Context()->GetD3D12Provider(); - auto device = provider->GetDevice(); - auto direct_queue = provider->GetDirectQueue(); + auto& provider = GetD3D12Context().GetD3D12Provider(); + auto device = provider.GetDevice(); + auto direct_queue = provider.GetDirectQueue(); submission_open_ = false; submission_current_ = 1; @@ -879,13 +879,13 @@ bool D3D12CommandProcessor::SetupContext() { command_list_->Close(); // Optional - added in Creators Update (SDK 10.0.15063.0). command_list_->QueryInterface(IID_PPV_ARGS(&command_list_1_)); - deferred_command_list_ = std::make_unique(this); + deferred_command_list_ = std::make_unique(*this); bindless_resources_used_ = cvars::d3d12_bindless && - provider->GetResourceBindingTier() >= D3D12_RESOURCE_BINDING_TIER_2; + provider.GetResourceBindingTier() >= D3D12_RESOURCE_BINDING_TIER_2; edram_rov_used_ = - cvars::d3d12_edram_rov && provider->AreRasterizerOrderedViewsSupported(); + cvars::d3d12_edram_rov && provider.AreRasterizerOrderedViewsSupported(); // Initialize resource binding. constant_buffer_pool_ = @@ -1145,29 +1145,29 @@ bool D3D12CommandProcessor::SetupContext() { } shared_memory_ = - std::make_unique(this, memory_, &trace_writer_); + std::make_unique(*this, *memory_, trace_writer_); if (!shared_memory_->Initialize()) { XELOGE("Failed to initialize shared memory"); return false; } texture_cache_ = std::make_unique( - this, register_file_, bindless_resources_used_, shared_memory_.get()); + *this, *register_file_, bindless_resources_used_, *shared_memory_); if (!texture_cache_->Initialize(edram_rov_used_)) { XELOGE("Failed to initialize the texture cache"); return false; } render_target_cache_ = std::make_unique( - this, register_file_, &trace_writer_, bindless_resources_used_, + *this, *register_file_, trace_writer_, bindless_resources_used_, edram_rov_used_); - if (!render_target_cache_->Initialize(texture_cache_.get())) { + if (!render_target_cache_->Initialize(*texture_cache_)) { XELOGE("Failed to initialize the render target cache"); return false; } pipeline_cache_ = std::make_unique( - this, register_file_, bindless_resources_used_, edram_rov_used_, + *this, *register_file_, bindless_resources_used_, edram_rov_used_, texture_cache_->IsResolutionScale2X() ? 2 : 1); if (!pipeline_cache_->Initialize()) { XELOGE("Failed to initialize the graphics pipeline state cache"); @@ -1175,7 +1175,7 @@ bool D3D12CommandProcessor::SetupContext() { } primitive_converter_ = std::make_unique( - this, register_file_, memory_, &trace_writer_); + *this, *register_file_, *memory_, trace_writer_); if (!primitive_converter_->Initialize()) { XELOGE("Failed to initialize the geometric primitive converter"); return false; @@ -1317,7 +1317,7 @@ bool D3D12CommandProcessor::SetupContext() { null_srv_desc.Texture2DArray.ResourceMinLODClamp = 0.0f; device->CreateShaderResourceView( nullptr, &null_srv_desc, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kNullTexture2DArray))); // kNullTexture3D. @@ -1327,7 +1327,7 @@ bool D3D12CommandProcessor::SetupContext() { null_srv_desc.Texture3D.ResourceMinLODClamp = 0.0f; device->CreateShaderResourceView( nullptr, &null_srv_desc, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kNullTexture3D))); // kNullTextureCube. @@ -1337,101 +1337,101 @@ bool D3D12CommandProcessor::SetupContext() { null_srv_desc.TextureCube.ResourceMinLODClamp = 0.0f; device->CreateShaderResourceView( nullptr, &null_srv_desc, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kNullTextureCube))); // kSharedMemoryRawSRV. - shared_memory_->WriteRawSRVDescriptor(provider->OffsetViewDescriptor( + shared_memory_->WriteRawSRVDescriptor(provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kSharedMemoryRawSRV))); // kSharedMemoryR32UintSRV. shared_memory_->WriteUintPow2SRVDescriptor( - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kSharedMemoryR32UintSRV)), 2); // kSharedMemoryR32G32UintSRV. shared_memory_->WriteUintPow2SRVDescriptor( - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kSharedMemoryR32G32UintSRV)), 3); // kSharedMemoryR32G32B32A32UintSRV. shared_memory_->WriteUintPow2SRVDescriptor( - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kSharedMemoryR32G32B32A32UintSRV)), 4); // kSharedMemoryRawUAV. - shared_memory_->WriteRawUAVDescriptor(provider->OffsetViewDescriptor( + shared_memory_->WriteRawUAVDescriptor(provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kSharedMemoryRawUAV))); // kSharedMemoryR32UintUAV. shared_memory_->WriteUintPow2UAVDescriptor( - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kSharedMemoryR32UintUAV)), 2); // kSharedMemoryR32G32UintUAV. shared_memory_->WriteUintPow2UAVDescriptor( - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kSharedMemoryR32G32UintUAV)), 3); // kSharedMemoryR32G32B32A32UintUAV. shared_memory_->WriteUintPow2UAVDescriptor( - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kSharedMemoryR32G32B32A32UintUAV)), 4); // kEdramRawSRV. render_target_cache_->WriteEdramRawSRVDescriptor( - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kEdramRawSRV))); // kEdramR32UintSRV. render_target_cache_->WriteEdramUintPow2SRVDescriptor( - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kEdramR32UintSRV)), 2); // kEdramR32G32UintSRV. render_target_cache_->WriteEdramUintPow2SRVDescriptor( - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kEdramR32G32UintSRV)), 3); // kEdramR32G32B32A32UintSRV. render_target_cache_->WriteEdramUintPow2SRVDescriptor( - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kEdramR32G32B32A32UintSRV)), 4); // kEdramRawUAV. render_target_cache_->WriteEdramRawUAVDescriptor( - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kEdramRawUAV))); // kEdramR32UintUAV. render_target_cache_->WriteEdramUintPow2UAVDescriptor( - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kEdramR32UintUAV)), 2); // kEdramR32G32B32A32UintUAV. render_target_cache_->WriteEdramUintPow2UAVDescriptor( - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kEdramR32G32B32A32UintUAV)), 4); // kGammaRampNormalSRV. WriteGammaRampSRV(false, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kGammaRampNormalSRV))); // kGammaRampPWLSRV. WriteGammaRampSRV(true, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( view_bindless_heap_cpu_start_, uint32_t(SystemBindlessView::kGammaRampPWLSRV))); } @@ -1599,7 +1599,7 @@ void D3D12CommandProcessor::PerformSwap(uint32_t frontbuffer_ptr, // In case the swap command is the only one in the frame. BeginSubmission(true); - auto device = GetD3D12Context()->GetD3D12Provider()->GetDevice(); + auto device = GetD3D12Context().GetD3D12Provider().GetDevice(); // Upload the new gamma ramps, using the upload buffer for the current frame // (will close the frame after this anyway, so can't write multiple times per @@ -1770,7 +1770,7 @@ bool D3D12CommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type, uint32_t index_count, IndexBufferInfo* index_buffer_info, bool major_mode_explicit) { - auto device = GetD3D12Context()->GetD3D12Provider()->GetDevice(); + auto device = GetD3D12Context().GetD3D12Provider().GetDevice(); auto& regs = *register_file_; #if FINE_GRAINED_DRAW_SCOPES @@ -2522,7 +2522,7 @@ void D3D12CommandProcessor::BeginSubmission(bool is_guest_command) { pix_capture_requested_.exchange(false, std::memory_order_relaxed); if (pix_capturing_) { IDXGraphicsAnalysis* graphics_analysis = - GetD3D12Context()->GetD3D12Provider()->GetGraphicsAnalysis(); + GetD3D12Context().GetD3D12Provider().GetGraphicsAnalysis(); if (graphics_analysis != nullptr) { graphics_analysis->BeginCapture(); } @@ -2535,12 +2535,12 @@ void D3D12CommandProcessor::BeginSubmission(bool is_guest_command) { } bool D3D12CommandProcessor::EndSubmission(bool is_swap) { - auto provider = GetD3D12Context()->GetD3D12Provider(); + auto& provider = GetD3D12Context().GetD3D12Provider(); // Make sure there is a command allocator to write commands to. if (submission_open_ && !command_allocator_writable_first_) { ID3D12CommandAllocator* command_allocator; - if (FAILED(provider->GetDevice()->CreateCommandAllocator( + if (FAILED(provider.GetDevice()->CreateCommandAllocator( D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&command_allocator)))) { XELOGE("Failed to create a command allocator"); @@ -2570,7 +2570,7 @@ bool D3D12CommandProcessor::EndSubmission(bool is_swap) { // destroyed between frames. SubmitBarriers(); - auto direct_queue = provider->GetDirectQueue(); + auto direct_queue = provider.GetDirectQueue(); // Submit the command list. ID3D12CommandAllocator* command_allocator = @@ -2604,7 +2604,7 @@ bool D3D12CommandProcessor::EndSubmission(bool is_swap) { if (is_closing_frame) { // Close the capture after submitting. if (pix_capturing_) { - IDXGraphicsAnalysis* graphics_analysis = provider->GetGraphicsAnalysis(); + IDXGraphicsAnalysis* graphics_analysis = provider.GetGraphicsAnalysis(); if (graphics_analysis != nullptr) { graphics_analysis->EndCapture(); } @@ -2665,7 +2665,7 @@ bool D3D12CommandProcessor::CanEndSubmissionImmediately() const { void D3D12CommandProcessor::AwaitAllSubmissionsCompletion() { // May be called if shutting down without everything set up. if ((submission_completed_ + 1) >= submission_current_ || - !submission_fence_ || GetD3D12Context()->WasLost()) { + !submission_fence_ || GetD3D12Context().WasLost()) { return; } submission_fence_->SetEventOnCompletion(submission_current_ - 1, @@ -3462,8 +3462,8 @@ void D3D12CommandProcessor::UpdateSystemConstantValues( bool D3D12CommandProcessor::UpdateBindings( const D3D12Shader* vertex_shader, const D3D12Shader* pixel_shader, ID3D12RootSignature* root_signature) { - auto provider = GetD3D12Context()->GetD3D12Provider(); - auto device = provider->GetDevice(); + auto& provider = GetD3D12Context().GetD3D12Provider(); + auto device = provider.GetDevice(); auto& regs = *register_file_; #if FINE_GRAINED_DRAW_SCOPES @@ -3830,7 +3830,7 @@ bool D3D12CommandProcessor::UpdateBindings( sampler_index = sampler_bindless_heap_allocated_++; texture_cache_->WriteSampler( sampler_parameters, - provider->OffsetSamplerDescriptor( + provider.OffsetSamplerDescriptor( sampler_bindless_heap_cpu_start_, sampler_index)); texture_cache_bindless_sampler_map_.insert( {sampler_parameters.value, sampler_index}); @@ -3862,7 +3862,7 @@ bool D3D12CommandProcessor::UpdateBindings( sampler_index = sampler_bindless_heap_allocated_++; texture_cache_->WriteSampler( sampler_parameters, - provider->OffsetSamplerDescriptor( + provider.OffsetSamplerDescriptor( sampler_bindless_heap_cpu_start_, sampler_index)); texture_cache_bindless_sampler_map_.insert( {sampler_parameters.value, sampler_index}); @@ -3994,7 +3994,7 @@ bool D3D12CommandProcessor::UpdateBindings( } D3D12_CPU_DESCRIPTOR_HANDLE view_cpu_handle; D3D12_GPU_DESCRIPTOR_HANDLE view_gpu_handle; - uint32_t descriptor_size_view = provider->GetViewDescriptorSize(); + uint32_t descriptor_size_view = provider.GetViewDescriptorSize(); uint64_t view_heap_index = RequestViewBindfulDescriptors( draw_view_bindful_heap_index_, view_count_partial_update, view_count_full_update, view_cpu_handle, view_gpu_handle); @@ -4011,7 +4011,7 @@ bool D3D12CommandProcessor::UpdateBindings( } D3D12_CPU_DESCRIPTOR_HANDLE sampler_cpu_handle = {}; D3D12_GPU_DESCRIPTOR_HANDLE sampler_gpu_handle = {}; - uint32_t descriptor_size_sampler = provider->GetSamplerDescriptorSize(); + uint32_t descriptor_size_sampler = provider.GetSamplerDescriptorSize(); uint64_t sampler_heap_index = ui::d3d12::DescriptorHeapPool::kHeapIndexInvalid; if (sampler_count_vertex != 0 || sampler_count_pixel != 0) { @@ -4286,7 +4286,7 @@ ID3D12Resource* D3D12CommandProcessor::RequestReadbackBuffer(uint32_t size) { } size = xe::align(size, kReadbackBufferSizeIncrement); if (size > readback_buffer_size_) { - auto device = GetD3D12Context()->GetD3D12Provider()->GetDevice(); + auto device = GetD3D12Context().GetD3D12Provider().GetDevice(); D3D12_RESOURCE_DESC buffer_desc; ui::d3d12::util::FillBufferResourceDesc(buffer_desc, size, D3D12_RESOURCE_FLAG_NONE); @@ -4308,7 +4308,7 @@ ID3D12Resource* D3D12CommandProcessor::RequestReadbackBuffer(uint32_t size) { void D3D12CommandProcessor::WriteGammaRampSRV( bool is_pwl, D3D12_CPU_DESCRIPTOR_HANDLE handle) const { - auto device = GetD3D12Context()->GetD3D12Provider()->GetDevice(); + auto device = GetD3D12Context().GetD3D12Provider().GetDevice(); D3D12_SHADER_RESOURCE_VIEW_DESC desc; desc.Format = DXGI_FORMAT_R10G10B10A2_UNORM; desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D; diff --git a/src/xenia/gpu/d3d12/d3d12_command_processor.h b/src/xenia/gpu/d3d12/d3d12_command_processor.h index e23453589..4921d0e44 100644 --- a/src/xenia/gpu/d3d12/d3d12_command_processor.h +++ b/src/xenia/gpu/d3d12/d3d12_command_processor.h @@ -58,14 +58,14 @@ class D3D12CommandProcessor : public CommandProcessor { void RestoreEdramSnapshot(const void* snapshot) override; // Needed by everything that owns transient objects. - ui::d3d12::D3D12Context* GetD3D12Context() const { - return static_cast(context_.get()); + ui::d3d12::D3D12Context& GetD3D12Context() const { + return static_cast(*context_); } // Returns the deferred drawing command list for the currently open // submission. - DeferredCommandList* GetDeferredCommandList() { - return deferred_command_list_.get(); + DeferredCommandList& GetDeferredCommandList() { + return *deferred_command_list_; } uint64_t GetCurrentSubmission() const { return submission_current_; } @@ -97,8 +97,8 @@ class D3D12CommandProcessor : public CommandProcessor { ID3D12RootSignature* GetRootSignature(const D3D12Shader* vertex_shader, const D3D12Shader* pixel_shader); - ui::d3d12::UploadBufferPool* GetConstantBufferPool() const { - return constant_buffer_pool_.get(); + ui::d3d12::UploadBufferPool& GetConstantBufferPool() const { + return *constant_buffer_pool_; } D3D12_CPU_DESCRIPTOR_HANDLE GetViewBindlessHeapCPUStart() const { diff --git a/src/xenia/gpu/d3d12/d3d12_graphics_system.cc b/src/xenia/gpu/d3d12/d3d12_graphics_system.cc index ca056e65e..30b322f87 100644 --- a/src/xenia/gpu/d3d12/d3d12_graphics_system.cc +++ b/src/xenia/gpu/d3d12/d3d12_graphics_system.cc @@ -96,7 +96,7 @@ X_STATUS D3D12GraphicsSystem::Setup(cpu::Processor* processor, stretch_root_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS; stretch_root_signature_ = - ui::d3d12::util::CreateRootSignature(d3d12_provider, stretch_root_desc); + ui::d3d12::util::CreateRootSignature(*d3d12_provider, stretch_root_desc); if (stretch_root_signature_ == nullptr) { XELOGE("Failed to create the front buffer stretch root signature"); return X_STATUS_UNSUCCESSFUL; @@ -123,7 +123,7 @@ X_STATUS D3D12GraphicsSystem::Setup(cpu::Processor* processor, stretch_root_desc.NumParameters = 3; stretch_root_desc.pParameters = stretch_root_parameters; stretch_gamma_root_signature_ = - ui::d3d12::util::CreateRootSignature(d3d12_provider, stretch_root_desc); + ui::d3d12::util::CreateRootSignature(*d3d12_provider, stretch_root_desc); if (stretch_gamma_root_signature_ == nullptr) { XELOGE( "Failed to create the gamma-correcting front buffer stretch root " diff --git a/src/xenia/gpu/d3d12/deferred_command_list.cc b/src/xenia/gpu/d3d12/deferred_command_list.cc index 1a05f0137..f6eede18b 100644 --- a/src/xenia/gpu/d3d12/deferred_command_list.cc +++ b/src/xenia/gpu/d3d12/deferred_command_list.cc @@ -18,7 +18,7 @@ namespace gpu { namespace d3d12 { DeferredCommandList::DeferredCommandList( - D3D12CommandProcessor* command_processor, size_t initial_size) + D3D12CommandProcessor& command_processor, size_t initial_size) : command_processor_(command_processor) { command_stream_.reserve(initial_size); } @@ -205,7 +205,7 @@ void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list, } break; case Command::kSetPipelineStateHandle: { current_pipeline_state = - command_processor_->GetD3D12PipelineStateByHandle( + command_processor_.GetD3D12PipelineStateByHandle( *reinterpret_cast(stream)); if (current_pipeline_state) { command_list->SetPipelineState(current_pipeline_state); diff --git a/src/xenia/gpu/d3d12/deferred_command_list.h b/src/xenia/gpu/d3d12/deferred_command_list.h index 8438024e1..78f1b605b 100644 --- a/src/xenia/gpu/d3d12/deferred_command_list.h +++ b/src/xenia/gpu/d3d12/deferred_command_list.h @@ -25,7 +25,7 @@ class D3D12CommandProcessor; class DeferredCommandList { public: - DeferredCommandList(D3D12CommandProcessor* command_processor, + DeferredCommandList(D3D12CommandProcessor& command_processor, size_t initial_size = 256 * 1024); void Reset(); @@ -462,7 +462,7 @@ class DeferredCommandList { void* WriteCommand(Command command, size_t arguments_size); - D3D12CommandProcessor* command_processor_; + D3D12CommandProcessor& command_processor_; std::vector command_stream_; }; diff --git a/src/xenia/gpu/d3d12/pipeline_cache.cc b/src/xenia/gpu/d3d12/pipeline_cache.cc index 9e351c1be..e9af039d2 100644 --- a/src/xenia/gpu/d3d12/pipeline_cache.cc +++ b/src/xenia/gpu/d3d12/pipeline_cache.cc @@ -68,8 +68,8 @@ namespace d3d12 { #include "xenia/gpu/d3d12/shaders/dxbc/primitive_rectangle_list_gs.h" #include "xenia/gpu/d3d12/shaders/dxbc/tessellation_vs.h" -PipelineCache::PipelineCache(D3D12CommandProcessor* command_processor, - RegisterFile* register_file, +PipelineCache::PipelineCache(D3D12CommandProcessor& command_processor, + const RegisterFile& register_file, bool bindless_resources_used, bool edram_rov_used, uint32_t resolution_scale) : command_processor_(command_processor), @@ -77,11 +77,11 @@ PipelineCache::PipelineCache(D3D12CommandProcessor* command_processor, bindless_resources_used_(bindless_resources_used), edram_rov_used_(edram_rov_used), resolution_scale_(resolution_scale) { - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); shader_translator_ = std::make_unique( - provider->GetAdapterVendorID(), bindless_resources_used_, edram_rov_used_, - provider->GetGraphicsAnalysis() != nullptr); + provider.GetAdapterVendorID(), bindless_resources_used_, edram_rov_used_, + provider.GetGraphicsAnalysis() != nullptr); if (edram_rov_used_) { depth_only_pixel_shader_ = @@ -92,27 +92,27 @@ PipelineCache::PipelineCache(D3D12CommandProcessor* command_processor, PipelineCache::~PipelineCache() { Shutdown(); } bool PipelineCache::Initialize() { - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); // Initialize the command processor thread DXIL objects. dxbc_converter_ = nullptr; dxc_utils_ = nullptr; dxc_compiler_ = nullptr; if (cvars::d3d12_dxbc_disasm_dxilconv) { - if (FAILED(provider->DxbcConverterCreateInstance( + if (FAILED(provider.DxbcConverterCreateInstance( CLSID_DxbcConverter, IID_PPV_ARGS(&dxbc_converter_)))) { XELOGE( "Failed to create DxbcConverter, converted DXIL disassembly for " "debugging will be unavailable"); } - if (FAILED(provider->DxcCreateInstance(CLSID_DxcUtils, - IID_PPV_ARGS(&dxc_utils_)))) { + if (FAILED(provider.DxcCreateInstance(CLSID_DxcUtils, + IID_PPV_ARGS(&dxc_utils_)))) { XELOGE( "Failed to create DxcUtils, converted DXIL disassembly for debugging " "will be unavailable"); } - if (FAILED(provider->DxcCreateInstance(CLSID_DxcCompiler, - IID_PPV_ARGS(&dxc_compiler_)))) { + if (FAILED(provider.DxcCreateInstance(CLSID_DxcCompiler, + IID_PPV_ARGS(&dxc_compiler_)))) { XELOGE( "Failed to create DxcCompiler, converted DXIL disassembly for " "debugging will be unavailable"); @@ -216,7 +216,7 @@ void PipelineCache::ClearCache(bool shutting_down) { COUNT_profile_set("gpu/pipeline_cache/pipeline_states", 0); // Destroy all shaders. - command_processor_->NotifyShaderBindingsLayoutUIDsInvalidated(); + command_processor_.NotifyShaderBindingsLayoutUIDsInvalidated(); if (bindless_resources_used_) { bindless_sampler_layout_map_.clear(); bindless_sampler_layouts_.clear(); @@ -307,10 +307,10 @@ void PipelineCache::InitializeShaderStorage( std::mutex shaders_failed_to_translate_mutex; std::vector shaders_failed_to_translate; auto shader_translation_thread_function = [&]() { - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); DxbcShaderTranslator translator( - provider->GetAdapterVendorID(), bindless_resources_used_, - edram_rov_used_, provider->GetGraphicsAnalysis() != nullptr); + provider.GetAdapterVendorID(), bindless_resources_used_, + edram_rov_used_, provider.GetGraphicsAnalysis() != nullptr); // If needed and possible, create objects needed for DXIL conversion and // disassembly on this thread. IDxbcConverter* dxbc_converter = nullptr; @@ -318,11 +318,11 @@ void PipelineCache::InitializeShaderStorage( IDxcCompiler* dxc_compiler = nullptr; if (cvars::d3d12_dxbc_disasm_dxilconv && dxbc_converter_ && dxc_utils_ && dxc_compiler_) { - provider->DxbcConverterCreateInstance(CLSID_DxbcConverter, - IID_PPV_ARGS(&dxbc_converter)); - provider->DxcCreateInstance(CLSID_DxcUtils, IID_PPV_ARGS(&dxc_utils)); - provider->DxcCreateInstance(CLSID_DxcCompiler, - IID_PPV_ARGS(&dxc_compiler)); + provider.DxbcConverterCreateInstance(CLSID_DxbcConverter, + IID_PPV_ARGS(&dxbc_converter)); + provider.DxcCreateInstance(CLSID_DxcUtils, IID_PPV_ARGS(&dxc_utils)); + provider.DxcCreateInstance(CLSID_DxcCompiler, + IID_PPV_ARGS(&dxc_compiler)); } for (;;) { std::pair shader_to_translate; @@ -342,7 +342,7 @@ void PipelineCache::InitializeShaderStorage( } assert_not_null(shader_to_translate.second); if (!TranslateShader( - translator, shader_to_translate.second, + translator, *shader_to_translate.second, shader_to_translate.first.sq_program_cntl, dxbc_converter, dxc_utils, dxc_compiler, shader_to_translate.first.host_vertex_shader_type)) { @@ -598,7 +598,7 @@ void PipelineCache::InitializeShaderStorage( pipeline_runtime_description.pixel_shader = nullptr; } pipeline_runtime_description.root_signature = - command_processor_->GetRootSignature( + command_processor_.GetRootSignature( pipeline_runtime_description.vertex_shader, pipeline_runtime_description.pixel_shader); if (!pipeline_runtime_description.root_signature) { @@ -803,7 +803,7 @@ Shader::HostVertexShaderType PipelineCache::GetHostVertexShaderTypeIfValid() // started to return a valid value (in this case the shader wouldn't be cached // in the first place). Otherwise games will not be able to locate shaders for // draws for which the host vertex shader type has changed! - auto& regs = *register_file_; + const auto& regs = register_file_; auto vgt_draw_initiator = regs.Get(); if (!xenos::IsMajorModeExplicit(vgt_draw_initiator.major_mode, vgt_draw_initiator.prim_type)) { @@ -874,7 +874,7 @@ Shader::HostVertexShaderType PipelineCache::GetHostVertexShaderTypeIfValid() bool PipelineCache::EnsureShadersTranslated( D3D12Shader* vertex_shader, D3D12Shader* pixel_shader, Shader::HostVertexShaderType host_vertex_shader_type) { - auto& regs = *register_file_; + const auto& regs = register_file_; auto sq_program_cntl = regs.Get(); // Edge flags are not supported yet (because polygon primitives are not). @@ -885,7 +885,7 @@ bool PipelineCache::EnsureShadersTranslated( assert_false(sq_program_cntl.gen_index_vtx); if (!vertex_shader->is_translated()) { - if (!TranslateShader(*shader_translator_, vertex_shader, sq_program_cntl, + if (!TranslateShader(*shader_translator_, *vertex_shader, sq_program_cntl, dxbc_converter_, dxc_utils_, dxc_compiler_, host_vertex_shader_type)) { XELOGE("Failed to translate the vertex shader!"); @@ -904,7 +904,7 @@ bool PipelineCache::EnsureShadersTranslated( } if (pixel_shader != nullptr && !pixel_shader->is_translated()) { - if (!TranslateShader(*shader_translator_, pixel_shader, sq_program_cntl, + if (!TranslateShader(*shader_translator_, *pixel_shader, sq_program_cntl, dxbc_converter_, dxc_utils_, dxc_compiler_)) { XELOGE("Failed to translate the pixel shader!"); return false; @@ -1015,21 +1015,21 @@ bool PipelineCache::ConfigurePipeline( } bool PipelineCache::TranslateShader( - DxbcShaderTranslator& translator, D3D12Shader* shader, + DxbcShaderTranslator& translator, D3D12Shader& shader, reg::SQ_PROGRAM_CNTL cntl, IDxbcConverter* dxbc_converter, IDxcUtils* dxc_utils, IDxcCompiler* dxc_compiler, Shader::HostVertexShaderType host_vertex_shader_type) { // Perform translation. // If this fails the shader will be marked as invalid and ignored later. - if (!translator.Translate(shader, cntl, host_vertex_shader_type)) { + if (!translator.Translate(&shader, cntl, host_vertex_shader_type)) { XELOGE("Shader {:016X} translation failed; marking as ignored", - shader->ucode_data_hash()); + shader.ucode_data_hash()); return false; } const char* host_shader_type; - if (shader->type() == xenos::ShaderType::kVertex) { - switch (shader->host_vertex_shader_type()) { + if (shader.type() == xenos::ShaderType::kVertex) { + switch (shader.host_vertex_shader_type()) { case Shader::HostVertexShaderType::kLineDomainCPIndexed: host_shader_type = "control-point-indexed line domain"; break; @@ -1055,8 +1055,8 @@ bool PipelineCache::TranslateShader( host_shader_type = "pixel"; } XELOGGPU("Generated {} shader ({}b) - hash {:016X}:\n{}\n", host_shader_type, - shader->ucode_dword_count() * 4, shader->ucode_data_hash(), - shader->ucode_disassembly().c_str()); + shader.ucode_dword_count() * 4, shader.ucode_data_hash(), + shader.ucode_disassembly().c_str()); // Set up texture and sampler bindings. uint32_t texture_binding_count; @@ -1065,15 +1065,15 @@ bool PipelineCache::TranslateShader( uint32_t sampler_binding_count; const DxbcShaderTranslator::SamplerBinding* sampler_bindings = translator.GetSamplerBindings(sampler_binding_count); - shader->SetTexturesAndSamplers(translator_texture_bindings, - texture_binding_count, sampler_bindings, - sampler_binding_count); + shader.SetTexturesAndSamplers(translator_texture_bindings, + texture_binding_count, sampler_bindings, + sampler_binding_count); assert_false(bindless_resources_used_ && texture_binding_count + sampler_binding_count > D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * 4); // Get hashable texture bindings, without translator-specific info. const D3D12Shader::TextureBinding* texture_bindings = - shader->GetTextureBindings(texture_binding_count); + shader.GetTextureBindings(texture_binding_count); size_t texture_binding_layout_bytes = texture_binding_count * sizeof(*texture_bindings); uint64_t texture_binding_layout_hash = 0; @@ -1184,37 +1184,37 @@ bool PipelineCache::TranslateShader( } } } - shader->SetTextureBindingLayoutUserUID(texture_binding_layout_uid); - shader->SetSamplerBindingLayoutUserUID(sampler_binding_layout_uid); + shader.SetTextureBindingLayoutUserUID(texture_binding_layout_uid); + shader.SetSamplerBindingLayoutUserUID(sampler_binding_layout_uid); // Create a version of the shader with early depth/stencil forced by Xenia // itself when it's safe to do so or when EARLY_Z_ENABLE is set in // RB_DEPTHCONTROL. - if (shader->type() == xenos::ShaderType::kPixel && !edram_rov_used_ && - !shader->writes_depth()) { - shader->SetForcedEarlyZShaderObject( + if (shader.type() == xenos::ShaderType::kPixel && !edram_rov_used_ && + !shader.writes_depth()) { + shader.SetForcedEarlyZShaderObject( std::move(DxbcShaderTranslator::ForceEarlyDepthStencil( - shader->translated_binary().data()))); + shader.translated_binary().data()))); } // Disassemble the shader for dumping. - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); if (cvars::d3d12_dxbc_disasm_dxilconv) { - shader->DisassembleDxbc(*provider, cvars::d3d12_dxbc_disasm, dxbc_converter, - dxc_utils, dxc_compiler); + shader.DisassembleDxbc(provider, cvars::d3d12_dxbc_disasm, dxbc_converter, + dxc_utils, dxc_compiler); } else { - shader->DisassembleDxbc(*provider, cvars::d3d12_dxbc_disasm); + shader.DisassembleDxbc(provider, cvars::d3d12_dxbc_disasm); } // Dump shader files if desired. if (!cvars::dump_shaders.empty()) { - shader->Dump(cvars::dump_shaders, - (shader->type() == xenos::ShaderType::kPixel) - ? (edram_rov_used_ ? "d3d12_rov" : "d3d12_rtv") - : "d3d12"); + shader.Dump(cvars::dump_shaders, + (shader.type() == xenos::ShaderType::kPixel) + ? (edram_rov_used_ ? "d3d12_rov" : "d3d12_rtv") + : "d3d12"); } - return shader->is_valid(); + return shader.is_valid(); } bool PipelineCache::GetCurrentStateDescription( @@ -1225,7 +1225,7 @@ bool PipelineCache::GetCurrentStateDescription( PipelineRuntimeDescription& runtime_description_out) { PipelineDescription& description_out = runtime_description_out.description; - auto& regs = *register_file_; + const auto& regs = register_file_; auto pa_su_sc_mode_cntl = regs.Get(); // Initialize all unused fields to zero for comparison/hashing. @@ -1233,7 +1233,7 @@ bool PipelineCache::GetCurrentStateDescription( // Root signature. runtime_description_out.root_signature = - command_processor_->GetRootSignature(vertex_shader, pixel_shader); + command_processor_.GetRootSignature(vertex_shader, pixel_shader); if (runtime_description_out.root_signature == nullptr) { return false; } @@ -1483,7 +1483,7 @@ bool PipelineCache::GetCurrentStateDescription( // Render targets and blending state. 32 because of 0x1F mask, for safety // (all unknown to zero). - uint32_t color_mask = command_processor_->GetCurrentColorMask(pixel_shader); + uint32_t color_mask = command_processor_.GetCurrentColorMask(pixel_shader); static const PipelineBlendFactor kBlendFactorMap[32] = { /* 0 */ PipelineBlendFactor::kZero, /* 1 */ PipelineBlendFactor::kOne, @@ -1895,7 +1895,7 @@ ID3D12PipelineState* PipelineCache::CreateD3D12PipelineState( // Create the pipeline state object. auto device = - command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); + command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice(); ID3D12PipelineState* state; if (FAILED(device->CreateGraphicsPipelineState(&state_desc, IID_PPV_ARGS(&state)))) { diff --git a/src/xenia/gpu/d3d12/pipeline_cache.h b/src/xenia/gpu/d3d12/pipeline_cache.h index 0511d43aa..30fd68a4e 100644 --- a/src/xenia/gpu/d3d12/pipeline_cache.h +++ b/src/xenia/gpu/d3d12/pipeline_cache.h @@ -40,8 +40,8 @@ class PipelineCache { public: static constexpr size_t kLayoutUIDEmpty = 0; - PipelineCache(D3D12CommandProcessor* command_processor, - RegisterFile* register_file, bool bindless_resources_used, + PipelineCache(D3D12CommandProcessor& command_processor, + const RegisterFile& register_file, bool bindless_resources_used, bool edram_rov_used, uint32_t resolution_scale); ~PipelineCache(); @@ -222,7 +222,7 @@ class PipelineCache { }; // Can be called from multiple threads. - bool TranslateShader(DxbcShaderTranslator& translator, D3D12Shader* shader, + bool TranslateShader(DxbcShaderTranslator& translator, D3D12Shader& shader, reg::SQ_PROGRAM_CNTL cntl, IDxbcConverter* dxbc_converter = nullptr, IDxcUtils* dxc_utils = nullptr, @@ -240,8 +240,8 @@ class PipelineCache { ID3D12PipelineState* CreateD3D12PipelineState( const PipelineRuntimeDescription& runtime_description); - D3D12CommandProcessor* command_processor_; - RegisterFile* register_file_; + D3D12CommandProcessor& command_processor_; + const RegisterFile& register_file_; bool bindless_resources_used_; bool edram_rov_used_; uint32_t resolution_scale_; diff --git a/src/xenia/gpu/d3d12/primitive_converter.cc b/src/xenia/gpu/d3d12/primitive_converter.cc index 2d7a6d5a6..4884865d0 100644 --- a/src/xenia/gpu/d3d12/primitive_converter.cc +++ b/src/xenia/gpu/d3d12/primitive_converter.cc @@ -33,10 +33,10 @@ namespace xe { namespace gpu { namespace d3d12 { -PrimitiveConverter::PrimitiveConverter(D3D12CommandProcessor* command_processor, - RegisterFile* register_file, - Memory* memory, - TraceWriter* trace_writer) +PrimitiveConverter::PrimitiveConverter(D3D12CommandProcessor& command_processor, + const RegisterFile& register_file, + Memory& memory, + TraceWriter& trace_writer) : command_processor_(command_processor), register_file_(register_file), memory_(memory), @@ -48,7 +48,7 @@ PrimitiveConverter::~PrimitiveConverter() { Shutdown(); } bool PrimitiveConverter::Initialize() { auto device = - command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); + command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice(); // There can be at most 65535 indices in a Xenos draw call, but they can be up // to 4 bytes large, and conversion can add more indices (almost triple the @@ -119,7 +119,7 @@ bool PrimitiveConverter::Initialize() { memory_regions_invalidated_.store(0ull, std::memory_order_relaxed); memory_invalidation_callback_handle_ = - memory_->RegisterPhysicalMemoryInvalidationCallback( + memory_.RegisterPhysicalMemoryInvalidationCallback( MemoryInvalidationCallbackThunk, this); return true; @@ -127,7 +127,7 @@ bool PrimitiveConverter::Initialize() { void PrimitiveConverter::Shutdown() { if (memory_invalidation_callback_handle_ != nullptr) { - memory_->UnregisterPhysicalMemoryInvalidationCallback( + memory_.UnregisterPhysicalMemoryInvalidationCallback( memory_invalidation_callback_handle_); memory_invalidation_callback_handle_ = nullptr; } @@ -139,7 +139,7 @@ void PrimitiveConverter::Shutdown() { void PrimitiveConverter::ClearCache() { buffer_pool_->ClearCache(); } void PrimitiveConverter::CompletedSubmissionUpdated() { - if (static_ib_upload_ && command_processor_->GetCompletedSubmission() >= + if (static_ib_upload_ && command_processor_.GetCompletedSubmission() >= static_ib_upload_submission_) { // Completely uploaded - release the upload buffer. static_ib_upload_->Release(); @@ -151,17 +151,17 @@ void PrimitiveConverter::BeginSubmission() { // Got a command list now - upload and transition the static index buffer if // needed. if (static_ib_upload_ && static_ib_upload_submission_ == UINT64_MAX) { - command_processor_->GetDeferredCommandList()->D3DCopyResource( + command_processor_.GetDeferredCommandList().D3DCopyResource( static_ib_, static_ib_upload_); - command_processor_->PushTransitionBarrier( - static_ib_, D3D12_RESOURCE_STATE_COPY_DEST, - D3D12_RESOURCE_STATE_INDEX_BUFFER); - static_ib_upload_submission_ = command_processor_->GetCurrentSubmission(); + command_processor_.PushTransitionBarrier(static_ib_, + D3D12_RESOURCE_STATE_COPY_DEST, + D3D12_RESOURCE_STATE_INDEX_BUFFER); + static_ib_upload_submission_ = command_processor_.GetCurrentSubmission(); } } void PrimitiveConverter::BeginFrame() { - buffer_pool_->Reclaim(command_processor_->GetCompletedFrame()); + buffer_pool_->Reclaim(command_processor_.GetCompletedFrame()); converted_indices_cache_.clear(); memory_regions_used_ = 0; } @@ -189,7 +189,7 @@ PrimitiveConverter::ConversionResult PrimitiveConverter::ConvertPrimitives( xenos::IndexFormat index_format, xenos::Endian index_endianness, D3D12_GPU_VIRTUAL_ADDRESS& gpu_address_out, uint32_t& index_count_out) { bool index_32bit = index_format == xenos::IndexFormat::kInt32; - auto& regs = *register_file_; + const auto& regs = register_file_; bool reset = regs.Get().multi_prim_ib_ena; // Swap the reset index because we will be comparing unswapped values to it. uint32_t reset_index = xenos::GpuSwap( @@ -291,7 +291,7 @@ PrimitiveConverter::ConversionResult PrimitiveConverter::ConvertPrimitives( const uint32_t* source_32; uintptr_t source_uintptr; }; - source = memory_->TranslatePhysical(address); + source = memory_.TranslatePhysical(address); // Calculate the new index count, and also check if there's nothing to convert // in the buffer (for instance, if not using actually primitive reset). @@ -304,7 +304,7 @@ PrimitiveConverter::ConversionResult PrimitiveConverter::ConvertPrimitives( if (source_type == xenos::PrimitiveType::kTriangleFan) { // Triangle fans are not supported by Direct3D 12 at all. conversion_needed = true; - trace_writer_->WriteMemoryRead(address, index_buffer_size); + trace_writer_.WriteMemoryRead(address, index_buffer_size); if (reset) { uint32_t current_fan_index_count = 0; for (uint32_t i = 0; i < index_count; ++i) { @@ -328,7 +328,7 @@ PrimitiveConverter::ConversionResult PrimitiveConverter::ConvertPrimitives( // Check if the restart index is used at all in this buffer because reading // vertices from a default heap is faster than from an upload heap. conversion_needed = false; - trace_writer_->WriteMemoryRead(address, index_buffer_size); + trace_writer_.WriteMemoryRead(address, index_buffer_size); #if XE_ARCH_AMD64 // Will use SIMD to copy 16-byte blocks using _mm_or_si128. simd = true; @@ -414,7 +414,7 @@ PrimitiveConverter::ConversionResult PrimitiveConverter::ConvertPrimitives( #endif // XE_ARCH_AMD64 } else if (source_type == xenos::PrimitiveType::kLineLoop) { conversion_needed = true; - trace_writer_->WriteMemoryRead(address, index_buffer_size); + trace_writer_.WriteMemoryRead(address, index_buffer_size); if (reset) { reset_actually_used = false; uint32_t current_strip_index_count = 0; @@ -441,7 +441,7 @@ PrimitiveConverter::ConversionResult PrimitiveConverter::ConvertPrimitives( } } else if (source_type == xenos::PrimitiveType::kQuadList) { conversion_needed = true; - trace_writer_->WriteMemoryRead(address, index_buffer_size); + trace_writer_.WriteMemoryRead(address, index_buffer_size); converted_index_count = (index_count >> 2) * 6; } converted_indices.converted_index_count = converted_index_count; @@ -695,8 +695,8 @@ void* PrimitiveConverter::AllocateIndices( } D3D12_GPU_VIRTUAL_ADDRESS gpu_address; uint8_t* mapping = - buffer_pool_->Request(command_processor_->GetCurrentFrame(), size, - nullptr, nullptr, &gpu_address); + buffer_pool_->Request(command_processor_.GetCurrentFrame(), size, nullptr, + nullptr, &gpu_address); if (mapping == nullptr) { XELOGE("Failed to allocate space for {} converted {}-bit vertex indices", count, format == xenos::IndexFormat::kInt32 ? 32 : 16); diff --git a/src/xenia/gpu/d3d12/primitive_converter.h b/src/xenia/gpu/d3d12/primitive_converter.h index 9b063e6d1..8da664ed2 100644 --- a/src/xenia/gpu/d3d12/primitive_converter.h +++ b/src/xenia/gpu/d3d12/primitive_converter.h @@ -37,9 +37,9 @@ class D3D12CommandProcessor; // alternative to the geometry shader). class PrimitiveConverter { public: - PrimitiveConverter(D3D12CommandProcessor* command_processor, - RegisterFile* register_file, Memory* memory, - TraceWriter* trace_writer); + PrimitiveConverter(D3D12CommandProcessor& command_processor, + const RegisterFile& register_file, Memory& memory, + TraceWriter& trace_writer); ~PrimitiveConverter(); bool Initialize(); @@ -102,10 +102,10 @@ class PrimitiveConverter { void* context_ptr, uint32_t physical_address_start, uint32_t length, bool exact_range); - D3D12CommandProcessor* command_processor_; - RegisterFile* register_file_; - Memory* memory_; - TraceWriter* trace_writer_; + D3D12CommandProcessor& command_processor_; + const RegisterFile& register_file_; + Memory& memory_; + TraceWriter& trace_writer_; std::unique_ptr buffer_pool_ = nullptr; diff --git a/src/xenia/gpu/d3d12/render_target_cache.cc b/src/xenia/gpu/d3d12/render_target_cache.cc index 47c3df932..bd25b738a 100644 --- a/src/xenia/gpu/d3d12/render_target_cache.cc +++ b/src/xenia/gpu/d3d12/render_target_cache.cc @@ -113,9 +113,9 @@ const std::pair {resolve_full_128bpp_2xres_cs, sizeof(resolve_full_128bpp_2xres_cs)}, }; -RenderTargetCache::RenderTargetCache(D3D12CommandProcessor* command_processor, - RegisterFile* register_file, - TraceWriter* trace_writer, +RenderTargetCache::RenderTargetCache(D3D12CommandProcessor& command_processor, + const RegisterFile& register_file, + TraceWriter& trace_writer, bool bindless_resources_used, bool edram_rov_used) : command_processor_(command_processor), @@ -126,13 +126,13 @@ RenderTargetCache::RenderTargetCache(D3D12CommandProcessor* command_processor, RenderTargetCache::~RenderTargetCache() { Shutdown(); } -bool RenderTargetCache::Initialize(const TextureCache* texture_cache) { +bool RenderTargetCache::Initialize(const TextureCache& texture_cache) { // EDRAM buffer size depends on this. - resolution_scale_2x_ = texture_cache->IsResolutionScale2X(); + resolution_scale_2x_ = texture_cache.IsResolutionScale2X(); assert_false(resolution_scale_2x_ && !edram_rov_used_); - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); - auto device = provider->GetDevice(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); + auto device = provider.GetDevice(); uint32_t edram_buffer_size = GetEdramBufferSize(); @@ -176,43 +176,43 @@ bool RenderTargetCache::Initialize(const TextureCache* texture_cache) { edram_buffer_descriptor_heap_->GetCPUDescriptorHandleForHeapStart(); ui::d3d12::util::CreateBufferRawSRV( device, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( edram_buffer_descriptor_heap_start_, uint32_t(EdramBufferDescriptorIndex::kRawSRV)), edram_buffer_, edram_buffer_size); ui::d3d12::util::CreateBufferTypedSRV( device, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( edram_buffer_descriptor_heap_start_, uint32_t(EdramBufferDescriptorIndex::kR32UintSRV)), edram_buffer_, DXGI_FORMAT_R32_UINT, edram_buffer_size >> 2); ui::d3d12::util::CreateBufferTypedSRV( device, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( edram_buffer_descriptor_heap_start_, uint32_t(EdramBufferDescriptorIndex::kR32G32UintSRV)), edram_buffer_, DXGI_FORMAT_R32G32_UINT, edram_buffer_size >> 3); ui::d3d12::util::CreateBufferTypedSRV( device, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( edram_buffer_descriptor_heap_start_, uint32_t(EdramBufferDescriptorIndex::kR32G32B32A32UintSRV)), edram_buffer_, DXGI_FORMAT_R32G32B32A32_UINT, edram_buffer_size >> 4); ui::d3d12::util::CreateBufferRawUAV( device, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( edram_buffer_descriptor_heap_start_, uint32_t(EdramBufferDescriptorIndex::kRawUAV)), edram_buffer_, edram_buffer_size); ui::d3d12::util::CreateBufferTypedUAV( device, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( edram_buffer_descriptor_heap_start_, uint32_t(EdramBufferDescriptorIndex::kR32UintUAV)), edram_buffer_, DXGI_FORMAT_R32_UINT, edram_buffer_size >> 2); ui::d3d12::util::CreateBufferTypedUAV( device, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( edram_buffer_descriptor_heap_start_, uint32_t(EdramBufferDescriptorIndex::kR32G32B32A32UintUAV)), edram_buffer_, DXGI_FORMAT_R32G32B32A32_UINT, edram_buffer_size >> 4); @@ -501,7 +501,7 @@ void RenderTargetCache::ClearCache() { void RenderTargetCache::CompletedSubmissionUpdated() { if (edram_snapshot_restore_pool_) { edram_snapshot_restore_pool_->Reclaim( - command_processor_->GetCompletedSubmission()); + command_processor_.GetCompletedSubmission()); } } @@ -600,7 +600,7 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) { // currently or previously used render targets, and it doesn't require a // bigger size. - auto& regs = *register_file_; + const auto& regs = register_file_; #if FINE_GRAINED_DRAW_SCOPES SCOPE_profile_cpu_f("gpu"); @@ -623,7 +623,7 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) { uint32_t edram_bases[5]; uint32_t formats[5]; bool formats_are_64bpp[5]; - uint32_t color_mask = command_processor_->GetCurrentColorMask(pixel_shader); + uint32_t color_mask = command_processor_.GetCurrentColorMask(pixel_shader); for (uint32_t i = 0; i < 4; ++i) { enabled[i] = (color_mask & (0xF << (i * 4))) != 0; auto color_info = regs.Get( @@ -871,7 +871,7 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) { #if 0 auto device = - command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); + command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice(); #endif // Allocate new render targets and add them to the bindings list. @@ -932,8 +932,8 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) { heap_usage[heap_page_first / kHeap4MBPages] += heap_page_count; // Inform Direct3D that we're reusing the heap for this render target. - command_processor_->PushAliasingBarrier( - nullptr, binding.render_target->resource); + command_processor_.PushAliasingBarrier(nullptr, + binding.render_target->resource); #else // If multiple render targets have the same format, assign different // instance numbers to them. @@ -956,7 +956,7 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) { if (!edram_rov_used_) { // Sample positions when loading depth must match sample positions when // drawing. - command_processor_->SetSamplePositions(current_msaa_samples_); + command_processor_.SetSamplePositions(current_msaa_samples_); sample_positions_set = true; // Load the contents of the new render targets from the EDRAM buffer (will @@ -997,7 +997,7 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) { } XELOGGPU("RT Color {}: base {}, format {}", i, edram_bases[i], formats[i]); - command_processor_->PushTransitionBarrier( + command_processor_.PushTransitionBarrier( render_target->resource, render_target->state, D3D12_RESOURCE_STATE_RENDER_TARGET); render_target->state = D3D12_RESOURCE_STATE_RENDER_TARGET; @@ -1015,7 +1015,7 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) { current_pipeline_render_targets_[4].guest_render_target = 4; if (depth_binding.is_bound && depth_render_target != nullptr) { XELOGGPU("RT Depth: base {}, format {}", edram_bases[4], formats[4]); - command_processor_->PushTransitionBarrier( + command_processor_.PushTransitionBarrier( depth_render_target->resource, depth_render_target->state, D3D12_RESOURCE_STATE_DEPTH_WRITE); depth_render_target->state = D3D12_RESOURCE_STATE_DEPTH_WRITE; @@ -1024,7 +1024,7 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) { } else { current_pipeline_render_targets_[4].format = DXGI_FORMAT_UNKNOWN; } - command_processor_->SubmitBarriers(); + command_processor_.SubmitBarriers(); apply_to_command_list_ = true; } } @@ -1034,7 +1034,7 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) { if (!edram_rov_used_ && apply_to_command_list_) { apply_to_command_list_ = false; if (!sample_positions_set) { - command_processor_->SetSamplePositions(current_msaa_samples_); + command_processor_.SetSamplePositions(current_msaa_samples_); } D3D12_CPU_DESCRIPTOR_HANDLE rtv_handles[4]; uint32_t rtv_count; @@ -1053,7 +1053,7 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) { current_pipeline_render_targets_[4].format != DXGI_FORMAT_UNKNOWN ? &depth_binding.render_target->handle : nullptr; - command_processor_->GetDeferredCommandList()->D3DOMSetRenderTargets( + command_processor_.GetDeferredCommandList().D3DOMSetRenderTargets( rtv_count, rtv_handles, FALSE, dsv_handle); } @@ -1091,7 +1091,7 @@ bool RenderTargetCache::Resolve(const Memory& memory, uint32_t resolution_scale = resolution_scale_2x_ ? 2 : 1; draw_util::ResolveInfo resolve_info; if (!draw_util::GetResolveInfo( - *register_file_, memory, *trace_writer_, resolution_scale, + register_file_, memory, trace_writer_, resolution_scale, !edram_rov_used_ && !cvars::d3d12_16bit_rtv_full_range, resolve_info)) { return false; @@ -1112,7 +1112,7 @@ bool RenderTargetCache::Resolve(const Memory& memory, ClearBindings(); } - auto command_list = command_processor_->GetDeferredCommandList(); + auto& command_list = command_processor_.GetDeferredCommandList(); // Copying. bool copied = false; @@ -1144,7 +1144,7 @@ bool RenderTargetCache::Resolve(const Memory& memory, ui::d3d12::util::DescriptorCPUGPUHandlePair descriptor_dest; ui::d3d12::util::DescriptorCPUGPUHandlePair descriptor_source; ui::d3d12::util::DescriptorCPUGPUHandlePair descriptors[2]; - if (command_processor_->RequestOneUseSingleViewDescriptors( + if (command_processor_.RequestOneUseSingleViewDescriptors( bindless_resources_used_ ? (resolution_scale_2x_ ? 1 : 0) : 2, descriptors)) { if (bindless_resources_used_) { @@ -1153,16 +1153,16 @@ bool RenderTargetCache::Resolve(const Memory& memory, } else { descriptor_dest = command_processor_ - ->GetSharedMemoryUintPow2BindlessUAVHandlePair( + .GetSharedMemoryUintPow2BindlessUAVHandlePair( copy_shader_info.dest_bpe_log2); } if (copy_shader_info.source_is_raw) { descriptor_source = - command_processor_->GetSystemBindlessViewHandlePair( + command_processor_.GetSystemBindlessViewHandlePair( D3D12CommandProcessor::SystemBindlessView::kEdramRawSRV); } else { descriptor_source = - command_processor_->GetEdramUintPow2BindlessSRVHandlePair( + command_processor_.GetEdramUintPow2BindlessSRVHandlePair( copy_shader_info.source_bpe_log2); } } else { @@ -1190,26 +1190,25 @@ bool RenderTargetCache::Resolve(const Memory& memory, TransitionEdramBuffer(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); // Submit the resolve. - command_list->D3DSetComputeRootSignature( - resolve_copy_root_signature_); - command_list->D3DSetComputeRootDescriptorTable( + command_list.D3DSetComputeRootSignature(resolve_copy_root_signature_); + command_list.D3DSetComputeRootDescriptorTable( 2, descriptor_source.second); - command_list->D3DSetComputeRootDescriptorTable( - 1, descriptor_dest.second); + command_list.D3DSetComputeRootDescriptorTable(1, + descriptor_dest.second); if (resolution_scale_2x_) { - command_list->D3DSetComputeRoot32BitConstants( + command_list.D3DSetComputeRoot32BitConstants( 0, sizeof(copy_shader_constants.dest_relative) / sizeof(uint32_t), ©_shader_constants.dest_relative, 0); } else { - command_list->D3DSetComputeRoot32BitConstants( + command_list.D3DSetComputeRoot32BitConstants( 0, sizeof(copy_shader_constants) / sizeof(uint32_t), ©_shader_constants, 0); } - command_processor_->SetComputePipelineState( + command_processor_.SetComputePipelineState( resolve_copy_pipeline_states_[size_t(copy_shader)]); - command_processor_->SubmitBarriers(); - command_list->D3DDispatch(copy_group_count_x, copy_group_count_y, 1); + command_processor_.SubmitBarriers(); + command_list.D3DDispatch(copy_group_count_x, copy_group_count_y, 1); // Order the resolve with other work using the destination as a UAV. if (resolution_scale_2x_) { @@ -1241,12 +1240,12 @@ bool RenderTargetCache::Resolve(const Memory& memory, ui::d3d12::util::DescriptorCPUGPUHandlePair descriptor_edram; bool descriptor_edram_obtained; if (bindless_resources_used_) { - descriptor_edram = command_processor_->GetSystemBindlessViewHandlePair( + descriptor_edram = command_processor_.GetSystemBindlessViewHandlePair( D3D12CommandProcessor::SystemBindlessView::kEdramR32G32B32A32UintUAV); descriptor_edram_obtained = true; } else { descriptor_edram_obtained = - command_processor_->RequestOneUseSingleViewDescriptors( + command_processor_.RequestOneUseSingleViewDescriptors( 1, &descriptor_edram); if (descriptor_edram_obtained) { WriteEdramUintPow2UAVDescriptor(descriptor_edram.first, 4); @@ -1258,9 +1257,8 @@ bool RenderTargetCache::Resolve(const Memory& memory, // to copy for some reason, for instance), overlap of the depth and the // color ranges is highly unlikely. CommitEdramBufferUAVWrites(false); - command_list->D3DSetComputeRootSignature(resolve_clear_root_signature_); - command_list->D3DSetComputeRootDescriptorTable(1, - descriptor_edram.second); + command_list.D3DSetComputeRootSignature(resolve_clear_root_signature_); + command_list.D3DSetComputeRootDescriptorTable(1, descriptor_edram.second); std::pair clear_group_count = resolve_info.GetClearShaderGroupCount(); assert_true(clear_group_count.first && clear_group_count.second); @@ -1274,38 +1272,38 @@ bool RenderTargetCache::Resolve(const Memory& memory, draw_util::ResolveClearShaderConstants depth_clear_constants; resolve_info.GetDepthClearShaderConstants(clear_float32_depth, depth_clear_constants); - command_list->D3DSetComputeRoot32BitConstants( + command_list.D3DSetComputeRoot32BitConstants( 0, sizeof(depth_clear_constants) / sizeof(uint32_t), &depth_clear_constants, 0); - command_processor_->SetComputePipelineState( + command_processor_.SetComputePipelineState( clear_float32_depth ? resolve_clear_depth_24_32_pipeline_state_ : resolve_clear_32bpp_pipeline_state_); - command_processor_->SubmitBarriers(); - command_list->D3DDispatch(clear_group_count.first, - clear_group_count.second, 1); + command_processor_.SubmitBarriers(); + command_list.D3DDispatch(clear_group_count.first, + clear_group_count.second, 1); } if (clear_color) { draw_util::ResolveClearShaderConstants color_clear_constants; resolve_info.GetColorClearShaderConstants(color_clear_constants); if (clear_depth) { // Non-RT-specific constants have already been set. - command_list->D3DSetComputeRoot32BitConstants( + command_list.D3DSetComputeRoot32BitConstants( 0, sizeof(color_clear_constants.rt_specific) / sizeof(uint32_t), &color_clear_constants.rt_specific, offsetof(draw_util::ResolveClearShaderConstants, rt_specific) / sizeof(uint32_t)); } else { - command_list->D3DSetComputeRoot32BitConstants( + command_list.D3DSetComputeRoot32BitConstants( 0, sizeof(color_clear_constants) / sizeof(uint32_t), &color_clear_constants, 0); } - command_processor_->SetComputePipelineState( + command_processor_.SetComputePipelineState( resolve_info.color_edram_info.format_is_64bpp ? resolve_clear_64bpp_pipeline_state_ : resolve_clear_32bpp_pipeline_state_); - command_processor_->SubmitBarriers(); - command_list->D3DDispatch(clear_group_count.first, - clear_group_count.second, 1); + command_processor_.SubmitBarriers(); + command_list.D3DDispatch(clear_group_count.first, + clear_group_count.second, 1); } assert_true(edram_buffer_state_ == D3D12_RESOURCE_STATE_UNORDERED_ACCESS); edram_buffer_modified_ = true; @@ -1328,11 +1326,11 @@ void RenderTargetCache::FlushAndUnbindRenderTargets() { void RenderTargetCache::WriteEdramRawSRVDescriptor( D3D12_CPU_DESCRIPTOR_HANDLE handle) { - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); - auto device = provider->GetDevice(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); + auto device = provider.GetDevice(); device->CopyDescriptorsSimple( 1, handle, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( edram_buffer_descriptor_heap_start_, uint32_t(EdramBufferDescriptorIndex::kRawSRV)), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); @@ -1340,11 +1338,11 @@ void RenderTargetCache::WriteEdramRawSRVDescriptor( void RenderTargetCache::WriteEdramRawUAVDescriptor( D3D12_CPU_DESCRIPTOR_HANDLE handle) { - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); - auto device = provider->GetDevice(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); + auto device = provider.GetDevice(); device->CopyDescriptorsSimple( 1, handle, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( edram_buffer_descriptor_heap_start_, uint32_t(EdramBufferDescriptorIndex::kRawUAV)), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); @@ -1367,12 +1365,12 @@ void RenderTargetCache::WriteEdramUintPow2SRVDescriptor( assert_unhandled_case(element_size_bytes_pow2); return; } - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); - auto device = provider->GetDevice(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); + auto device = provider.GetDevice(); device->CopyDescriptorsSimple( 1, handle, - provider->OffsetViewDescriptor(edram_buffer_descriptor_heap_start_, - uint32_t(descriptor_index)), + provider.OffsetViewDescriptor(edram_buffer_descriptor_heap_start_, + uint32_t(descriptor_index)), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); } @@ -1391,12 +1389,12 @@ void RenderTargetCache::WriteEdramUintPow2UAVDescriptor( assert_unhandled_case(element_size_bytes_pow2); return; } - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); - auto device = provider->GetDevice(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); + auto device = provider.GetDevice(); device->CopyDescriptorsSimple( 1, handle, - provider->OffsetViewDescriptor(edram_buffer_descriptor_heap_start_, - uint32_t(descriptor_index)), + provider.OffsetViewDescriptor(edram_buffer_descriptor_heap_start_, + uint32_t(descriptor_index)), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); } @@ -1454,7 +1452,7 @@ bool RenderTargetCache::InitializeTraceSubmitDownloads() { xenos::kEdramSizeBytes, D3D12_RESOURCE_FLAG_NONE); auto device = - command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); + command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice(); if (FAILED(device->CreateCommittedResource( &ui::d3d12::util::kHeapPropertiesReadback, D3D12_HEAP_FLAG_NONE, &edram_snapshot_download_buffer_desc, @@ -1464,11 +1462,11 @@ bool RenderTargetCache::InitializeTraceSubmitDownloads() { return false; } } - auto command_list = command_processor_->GetDeferredCommandList(); + auto& command_list = command_processor_.GetDeferredCommandList(); TransitionEdramBuffer(D3D12_RESOURCE_STATE_COPY_SOURCE); - command_processor_->SubmitBarriers(); - command_list->D3DCopyBufferRegion(edram_snapshot_download_buffer_, 0, - edram_buffer_, 0, xenos::kEdramSizeBytes); + command_processor_.SubmitBarriers(); + command_list.D3DCopyBufferRegion(edram_snapshot_download_buffer_, 0, + edram_buffer_, 0, xenos::kEdramSizeBytes); return true; } @@ -1479,7 +1477,7 @@ void RenderTargetCache::InitializeTraceCompleteDownloads() { void* download_mapping; if (SUCCEEDED(edram_snapshot_download_buffer_->Map(0, nullptr, &download_mapping))) { - trace_writer_->WriteEdramSnapshot(download_mapping); + trace_writer_.WriteEdramSnapshot(download_mapping); D3D12_RANGE download_write_range = {}; edram_snapshot_download_buffer_->Unmap(0, &download_write_range); } else { @@ -1494,8 +1492,8 @@ void RenderTargetCache::RestoreEdramSnapshot(const void* snapshot) { // No 1:1 mapping. return; } - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); - auto device = provider->GetDevice(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); + auto device = provider.GetDevice(); if (!edram_snapshot_restore_pool_) { edram_snapshot_restore_pool_ = std::make_unique(device, @@ -1504,19 +1502,19 @@ void RenderTargetCache::RestoreEdramSnapshot(const void* snapshot) { ID3D12Resource* upload_buffer; uint32_t upload_buffer_offset; void* upload_buffer_mapping = edram_snapshot_restore_pool_->Request( - command_processor_->GetCurrentSubmission(), xenos::kEdramSizeBytes, + command_processor_.GetCurrentSubmission(), xenos::kEdramSizeBytes, &upload_buffer, &upload_buffer_offset, nullptr); if (!upload_buffer_mapping) { XELOGE("Failed to get a buffer for restoring a EDRAM snapshot"); return; } std::memcpy(upload_buffer_mapping, snapshot, xenos::kEdramSizeBytes); - auto command_list = command_processor_->GetDeferredCommandList(); + auto& command_list = command_processor_.GetDeferredCommandList(); TransitionEdramBuffer(D3D12_RESOURCE_STATE_COPY_DEST); - command_processor_->SubmitBarriers(); - command_list->D3DCopyBufferRegion(edram_buffer_, 0, upload_buffer, - upload_buffer_offset, - xenos::kEdramSizeBytes); + command_processor_.SubmitBarriers(); + command_list.D3DCopyBufferRegion(edram_buffer_, 0, upload_buffer, + upload_buffer_offset, + xenos::kEdramSizeBytes); if (!edram_rov_used_) { // Clear and ignore the old 32-bit float depth - the non-ROV path is // inaccurate anyway, and this is backend-specific, not a part of a guest @@ -1526,11 +1524,11 @@ void RenderTargetCache::RestoreEdramSnapshot(const void* snapshot) { if (bindless_resources_used_) { edram_shader_visible_r32_uav_obtained = true; edram_shader_visible_r32_uav = - command_processor_->GetSystemBindlessViewHandlePair( + command_processor_.GetSystemBindlessViewHandlePair( D3D12CommandProcessor::SystemBindlessView::kEdramR32UintUAV); } else { edram_shader_visible_r32_uav_obtained = - command_processor_->RequestOneUseSingleViewDescriptors( + command_processor_.RequestOneUseSingleViewDescriptors( 1, &edram_shader_visible_r32_uav); if (edram_shader_visible_r32_uav_obtained) { WriteEdramUintPow2UAVDescriptor(edram_shader_visible_r32_uav.first, 2); @@ -1544,12 +1542,12 @@ void RenderTargetCache::RestoreEdramSnapshot(const void* snapshot) { clear_rect.right = (xenos::kEdramSizeBytes >> 2) << 1; clear_rect.bottom = 1; TransitionEdramBuffer(D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - command_processor_->SubmitBarriers(); + command_processor_.SubmitBarriers(); // ClearUnorderedAccessView takes a shader-visible GPU descriptor and a // non-shader-visible CPU descriptor. - command_list->D3DClearUnorderedAccessViewUint( + command_list.D3DClearUnorderedAccessViewUint( edram_shader_visible_r32_uav.second, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( edram_buffer_descriptor_heap_start_, uint32_t(EdramBufferDescriptorIndex::kR32UintUAV)), edram_buffer_, clear_value, 1, &clear_rect); @@ -1572,8 +1570,8 @@ uint32_t RenderTargetCache::GetEdramBufferSize() const { } void RenderTargetCache::TransitionEdramBuffer(D3D12_RESOURCE_STATES new_state) { - command_processor_->PushTransitionBarrier(edram_buffer_, edram_buffer_state_, - new_state); + command_processor_.PushTransitionBarrier(edram_buffer_, edram_buffer_state_, + new_state); edram_buffer_state_ = new_state; if (new_state != D3D12_RESOURCE_STATE_UNORDERED_ACCESS) { edram_buffer_modified_ = false; @@ -1583,7 +1581,7 @@ void RenderTargetCache::TransitionEdramBuffer(D3D12_RESOURCE_STATES new_state) { void RenderTargetCache::CommitEdramBufferUAVWrites(bool force) { if ((edram_buffer_modified_ || force) && edram_buffer_state_ == D3D12_RESOURCE_STATE_UNORDERED_ACCESS) { - command_processor_->PushUAVBarrier(edram_buffer_); + command_processor_.PushUAVBarrier(edram_buffer_); } edram_buffer_modified_ = false; } @@ -1606,7 +1604,7 @@ bool RenderTargetCache::MakeHeapResident(uint32_t heap_index) { return true; } auto device = - command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); + command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice(); D3D12_HEAP_DESC heap_desc = {}; heap_desc.SizeInBytes = kHeap4MBPages << 22; heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT; @@ -1630,7 +1628,7 @@ bool RenderTargetCache::EnsureRTVHeapAvailable(bool is_depth) { return true; } auto device = - command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); + command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice(); D3D12_DESCRIPTOR_HEAP_DESC heap_desc; heap_desc.Type = is_depth ? D3D12_DESCRIPTOR_HEAP_TYPE_DSV : D3D12_DESCRIPTOR_HEAP_TYPE_RTV; @@ -1712,8 +1710,8 @@ RenderTargetCache::RenderTarget* RenderTargetCache::FindOrCreateRenderTarget( return nullptr; } - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); - auto device = provider->GetDevice(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); + auto device = provider.GetDevice(); #if 0 // Get the number of heap pages needed for the render target. @@ -1772,9 +1770,9 @@ RenderTargetCache::RenderTarget* RenderTargetCache::FindOrCreateRenderTarget( // Create the descriptor for the render target. D3D12_CPU_DESCRIPTOR_HANDLE descriptor_handle; if (key.is_depth) { - descriptor_handle = provider->OffsetDSVDescriptor( - descriptor_heaps_depth_->start_handle, - descriptor_heaps_depth_->descriptors_used); + descriptor_handle = + provider.OffsetDSVDescriptor(descriptor_heaps_depth_->start_handle, + descriptor_heaps_depth_->descriptors_used); D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc; dsv_desc.Format = resource_desc.Format; dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; @@ -1783,9 +1781,9 @@ RenderTargetCache::RenderTarget* RenderTargetCache::FindOrCreateRenderTarget( device->CreateDepthStencilView(resource, &dsv_desc, descriptor_handle); ++descriptor_heaps_depth_->descriptors_used; } else { - descriptor_handle = provider->OffsetRTVDescriptor( - descriptor_heaps_color_->start_handle, - descriptor_heaps_color_->descriptors_used); + descriptor_handle = + provider.OffsetRTVDescriptor(descriptor_heaps_color_->start_handle, + descriptor_heaps_color_->descriptors_used); D3D12_RENDER_TARGET_VIEW_DESC rtv_desc; rtv_desc.Format = resource_desc.Format; rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; @@ -1854,7 +1852,7 @@ void RenderTargetCache::StoreRenderTargetsToEdram() { return; } - auto command_list = command_processor_->GetDeferredCommandList(); + auto& command_list = command_processor_.GetDeferredCommandList(); // Extract only the render targets that need to be stored, transition them to // copy sources and calculate copy buffer size. @@ -1880,16 +1878,16 @@ void RenderTargetCache::StoreRenderTargetsToEdram() { ui::d3d12::util::DescriptorCPUGPUHandlePair descriptor_edram; ui::d3d12::util::DescriptorCPUGPUHandlePair descriptor_source; if (bindless_resources_used_) { - if (!command_processor_->RequestOneUseSingleViewDescriptors( + if (!command_processor_.RequestOneUseSingleViewDescriptors( 1, &descriptor_source)) { return; } - descriptor_edram = command_processor_->GetSystemBindlessViewHandlePair( + descriptor_edram = command_processor_.GetSystemBindlessViewHandlePair( D3D12CommandProcessor::SystemBindlessView::kEdramRawUAV); } else { ui::d3d12::util::DescriptorCPUGPUHandlePair descriptors[2]; - if (!command_processor_->RequestOneUseSingleViewDescriptors(2, - descriptors)) { + if (!command_processor_.RequestOneUseSingleViewDescriptors(2, + descriptors)) { return; } descriptor_edram = descriptors[0]; @@ -1899,7 +1897,7 @@ void RenderTargetCache::StoreRenderTargetsToEdram() { // Get the buffer for copying. D3D12_RESOURCE_STATES copy_buffer_state = D3D12_RESOURCE_STATE_COPY_DEST; - ID3D12Resource* copy_buffer = command_processor_->RequestScratchGPUBuffer( + ID3D12Resource* copy_buffer = command_processor_.RequestScratchGPUBuffer( copy_buffer_size, copy_buffer_state); if (copy_buffer == nullptr) { return; @@ -1910,21 +1908,21 @@ void RenderTargetCache::StoreRenderTargetsToEdram() { for (uint32_t i = 0; i < store_binding_count; ++i) { RenderTarget* render_target = current_bindings_[store_bindings[i]].render_target; - command_processor_->PushTransitionBarrier(render_target->resource, - render_target->state, - D3D12_RESOURCE_STATE_COPY_SOURCE); + command_processor_.PushTransitionBarrier(render_target->resource, + render_target->state, + D3D12_RESOURCE_STATE_COPY_SOURCE); render_target->state = D3D12_RESOURCE_STATE_COPY_SOURCE; } TransitionEdramBuffer(D3D12_RESOURCE_STATE_UNORDERED_ACCESS); // Set up the bindings. auto device = - command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); - command_list->D3DSetComputeRootSignature(edram_load_store_root_signature_); + command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice(); + command_list.D3DSetComputeRootSignature(edram_load_store_root_signature_); ui::d3d12::util::CreateBufferRawSRV(device, descriptor_source.first, copy_buffer, copy_buffer_size); - command_list->D3DSetComputeRootDescriptorTable(2, descriptor_source.second); - command_list->D3DSetComputeRootDescriptorTable(1, descriptor_edram.second); + command_list.D3DSetComputeRootDescriptorTable(2, descriptor_source.second); + command_list.D3DSetComputeRootDescriptorTable(1, descriptor_edram.second); // Sort the bindings in ascending order of EDRAM base so data in the render // targets placed farther in EDRAM isn't lost in case of overlap. @@ -1959,10 +1957,10 @@ void RenderTargetCache::StoreRenderTargetsToEdram() { bool is_64bpp = false; // Transition the copy buffer to copy destination. - command_processor_->PushTransitionBarrier(copy_buffer, copy_buffer_state, - D3D12_RESOURCE_STATE_COPY_DEST); + command_processor_.PushTransitionBarrier(copy_buffer, copy_buffer_state, + D3D12_RESOURCE_STATE_COPY_DEST); copy_buffer_state = D3D12_RESOURCE_STATE_COPY_DEST; - command_processor_->SubmitBarriers(); + command_processor_.SubmitBarriers(); // Copy from the render target planes and set up the layout. D3D12_TEXTURE_COPY_LOCATION location_source, location_dest; @@ -1973,7 +1971,7 @@ void RenderTargetCache::StoreRenderTargetsToEdram() { location_dest.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; location_dest.PlacedFootprint = render_target->footprints[0]; // TODO(Triang3l): Box for color render targets. - command_list->CopyTexture(location_dest, location_source); + command_list.CopyTexture(location_dest, location_source); EdramLoadStoreRootConstants root_constants; uint32_t rt_pitch_tiles = surface_pitch_tiles; if (!render_target->key.is_depth && @@ -1992,7 +1990,7 @@ void RenderTargetCache::StoreRenderTargetsToEdram() { root_constants.base_samples_2x_depth_pitch |= 1 << 15; location_source.SubresourceIndex = 1; location_dest.PlacedFootprint = render_target->footprints[1]; - command_list->CopyTexture(location_dest, location_source); + command_list.CopyTexture(location_dest, location_source); root_constants.rt_stencil_offset = uint32_t(location_dest.PlacedFootprint.Offset); root_constants.rt_stencil_pitch = @@ -2000,27 +1998,27 @@ void RenderTargetCache::StoreRenderTargetsToEdram() { } // Transition the copy buffer to SRV. - command_processor_->PushTransitionBarrier( + command_processor_.PushTransitionBarrier( copy_buffer, copy_buffer_state, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); copy_buffer_state = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; - command_processor_->SubmitBarriers(); + command_processor_.SubmitBarriers(); // Store the data. - command_list->D3DSetComputeRoot32BitConstants( + command_list.D3DSetComputeRoot32BitConstants( 0, sizeof(root_constants) / sizeof(uint32_t), &root_constants, 0); EdramLoadStoreMode mode = GetLoadStoreMode(render_target->key.is_depth, render_target->key.format); - command_processor_->SetComputePipelineState( + command_processor_.SetComputePipelineState( edram_store_pipelines_[size_t(mode)]); // 1 group per 80x16 samples. - command_list->D3DDispatch(surface_pitch_tiles, binding.edram_dirty_rows, 1); + command_list.D3DDispatch(surface_pitch_tiles, binding.edram_dirty_rows, 1); // Commit the UAV write. CommitEdramBufferUAVWrites(true); } - command_processor_->ReleaseScratchGPUBuffer(copy_buffer, copy_buffer_state); + command_processor_.ReleaseScratchGPUBuffer(copy_buffer, copy_buffer_state); } void RenderTargetCache::LoadRenderTargetsFromEdram( @@ -2031,21 +2029,21 @@ void RenderTargetCache::LoadRenderTargetsFromEdram( return; } - auto command_list = command_processor_->GetDeferredCommandList(); + auto& command_list = command_processor_.GetDeferredCommandList(); // Allocate descriptors for the buffers. ui::d3d12::util::DescriptorCPUGPUHandlePair descriptor_dest, descriptor_edram; if (bindless_resources_used_) { - if (!command_processor_->RequestOneUseSingleViewDescriptors( + if (!command_processor_.RequestOneUseSingleViewDescriptors( 1, &descriptor_dest)) { return; } - descriptor_edram = command_processor_->GetSystemBindlessViewHandlePair( + descriptor_edram = command_processor_.GetSystemBindlessViewHandlePair( D3D12CommandProcessor::SystemBindlessView::kEdramRawSRV); } else { ui::d3d12::util::DescriptorCPUGPUHandlePair descriptors[2]; - if (!command_processor_->RequestOneUseSingleViewDescriptors(2, - descriptors)) { + if (!command_processor_.RequestOneUseSingleViewDescriptors(2, + descriptors)) { return; } descriptor_dest = descriptors[0]; @@ -2061,7 +2059,7 @@ void RenderTargetCache::LoadRenderTargetsFromEdram( } D3D12_RESOURCE_STATES copy_buffer_state = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; - ID3D12Resource* copy_buffer = command_processor_->RequestScratchGPUBuffer( + ID3D12Resource* copy_buffer = command_processor_.RequestScratchGPUBuffer( copy_buffer_size, copy_buffer_state); if (copy_buffer == nullptr) { return; @@ -2071,21 +2069,21 @@ void RenderTargetCache::LoadRenderTargetsFromEdram( // a SRV. for (uint32_t i = 0; i < render_target_count; ++i) { RenderTarget* render_target = render_targets[i]; - command_processor_->PushTransitionBarrier(render_target->resource, - render_target->state, - D3D12_RESOURCE_STATE_COPY_DEST); + command_processor_.PushTransitionBarrier(render_target->resource, + render_target->state, + D3D12_RESOURCE_STATE_COPY_DEST); render_target->state = D3D12_RESOURCE_STATE_COPY_DEST; } TransitionEdramBuffer(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); // Set up the bindings. auto device = - command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); - command_list->D3DSetComputeRootSignature(edram_load_store_root_signature_); - command_list->D3DSetComputeRootDescriptorTable(2, descriptor_edram.second); + command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice(); + command_list.D3DSetComputeRootSignature(edram_load_store_root_signature_); + command_list.D3DSetComputeRootDescriptorTable(2, descriptor_edram.second); ui::d3d12::util::CreateBufferRawUAV(device, descriptor_dest.first, copy_buffer, copy_buffer_size); - command_list->D3DSetComputeRootDescriptorTable(1, descriptor_dest.second); + command_list.D3DSetComputeRootDescriptorTable(1, descriptor_dest.second); // Load each render target. for (uint32_t i = 0; i < render_target_count; ++i) { @@ -2111,12 +2109,12 @@ void RenderTargetCache::LoadRenderTargetsFromEdram( } // Transition the copy buffer back to UAV if it's not the first load. - command_processor_->PushTransitionBarrier( + command_processor_.PushTransitionBarrier( copy_buffer, copy_buffer_state, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); copy_buffer_state = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; // Load the data. - command_processor_->SubmitBarriers(); + command_processor_.SubmitBarriers(); EdramLoadStoreRootConstants root_constants; // TODO(Triang3l): log2(sample count, resolution scale). root_constants.base_samples_2x_depth_pitch = @@ -2132,24 +2130,23 @@ void RenderTargetCache::LoadRenderTargetsFromEdram( root_constants.rt_stencil_pitch = render_target->footprints[1].Footprint.RowPitch; } - command_list->D3DSetComputeRoot32BitConstants( + command_list.D3DSetComputeRoot32BitConstants( 0, sizeof(root_constants) / sizeof(uint32_t), &root_constants, 0); EdramLoadStoreMode mode = GetLoadStoreMode(render_target->key.is_depth, render_target->key.format); - command_processor_->SetComputePipelineState( + command_processor_.SetComputePipelineState( edram_load_pipelines_[size_t(mode)]); // 1 group per 80x16 samples. - command_list->D3DDispatch(render_target->key.width_ss_div_80, edram_rows, - 1); + command_list.D3DDispatch(render_target->key.width_ss_div_80, edram_rows, 1); // Commit the UAV write and transition the copy buffer to copy source now. - command_processor_->PushUAVBarrier(copy_buffer); - command_processor_->PushTransitionBarrier(copy_buffer, copy_buffer_state, - D3D12_RESOURCE_STATE_COPY_SOURCE); + command_processor_.PushUAVBarrier(copy_buffer); + command_processor_.PushTransitionBarrier(copy_buffer, copy_buffer_state, + D3D12_RESOURCE_STATE_COPY_SOURCE); copy_buffer_state = D3D12_RESOURCE_STATE_COPY_SOURCE; // Copy to the render target planes. - command_processor_->SubmitBarriers(); + command_processor_.SubmitBarriers(); D3D12_TEXTURE_COPY_LOCATION location_source, location_dest; location_source.pResource = copy_buffer; location_source.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; @@ -2157,15 +2154,15 @@ void RenderTargetCache::LoadRenderTargetsFromEdram( location_dest.pResource = render_target->resource; location_dest.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; location_dest.SubresourceIndex = 0; - command_list->CopyTexture(location_dest, location_source); + command_list.CopyTexture(location_dest, location_source); if (render_target->key.is_depth) { location_source.PlacedFootprint = render_target->footprints[1]; location_dest.SubresourceIndex = 1; - command_list->CopyTexture(location_dest, location_source); + command_list.CopyTexture(location_dest, location_source); } } - command_processor_->ReleaseScratchGPUBuffer(copy_buffer, copy_buffer_state); + command_processor_.ReleaseScratchGPUBuffer(copy_buffer, copy_buffer_state); } } // namespace d3d12 diff --git a/src/xenia/gpu/d3d12/render_target_cache.h b/src/xenia/gpu/d3d12/render_target_cache.h index f5bbd25c7..e343c6991 100644 --- a/src/xenia/gpu/d3d12/render_target_cache.h +++ b/src/xenia/gpu/d3d12/render_target_cache.h @@ -250,12 +250,13 @@ class RenderTargetCache { DXGI_FORMAT format; }; - RenderTargetCache(D3D12CommandProcessor* command_processor, - RegisterFile* register_file, TraceWriter* trace_writer, - bool bindless_resources_used, bool edram_rov_used); + RenderTargetCache(D3D12CommandProcessor& command_processor, + const RegisterFile& register_file, + TraceWriter& trace_writer, bool bindless_resources_used, + bool edram_rov_used); ~RenderTargetCache(); - bool Initialize(const TextureCache* texture_cache); + bool Initialize(const TextureCache& texture_cache); void Shutdown(); void ClearCache(); @@ -483,9 +484,9 @@ class RenderTargetCache { DXGI_FORMAT format); #endif - D3D12CommandProcessor* command_processor_; - RegisterFile* register_file_; - TraceWriter* trace_writer_; + D3D12CommandProcessor& command_processor_; + const RegisterFile& register_file_; + TraceWriter& trace_writer_; bool bindless_resources_used_; bool edram_rov_used_; diff --git a/src/xenia/gpu/d3d12/shared_memory.cc b/src/xenia/gpu/d3d12/shared_memory.cc index 1eac97183..f2d2e6296 100644 --- a/src/xenia/gpu/d3d12/shared_memory.cc +++ b/src/xenia/gpu/d3d12/shared_memory.cc @@ -34,8 +34,8 @@ namespace xe { namespace gpu { namespace d3d12 { -SharedMemory::SharedMemory(D3D12CommandProcessor* command_processor, - Memory* memory, TraceWriter* trace_writer) +SharedMemory::SharedMemory(D3D12CommandProcessor& command_processor, + Memory& memory, TraceWriter& trace_writer) : command_processor_(command_processor), memory_(memory), trace_writer_(trace_writer) { @@ -46,8 +46,8 @@ SharedMemory::SharedMemory(D3D12CommandProcessor* command_processor, SharedMemory::~SharedMemory() { Shutdown(); } bool SharedMemory::Initialize() { - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); - auto device = provider->GetDevice(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); + auto device = provider.GetDevice(); D3D12_RESOURCE_DESC buffer_desc; ui::d3d12::util::FillBufferResourceDesc( @@ -65,7 +65,7 @@ bool SharedMemory::Initialize() { "Direct3D 12 tiled resources are not used for shared memory " "emulation - video memory usage may increase significantly " "because a full 512 MB buffer will be created!"); - if (provider->GetGraphicsAnalysis() != nullptr) { + if (provider.GetGraphicsAnalysis() != nullptr) { // As of October 8th, 2018, PIX doesn't support tiled buffers. // FIXME(Triang3l): Re-enable tiled resources with PIX once fixed. XELOGGPU( @@ -104,47 +104,47 @@ bool SharedMemory::Initialize() { buffer_descriptor_heap_->GetCPUDescriptorHandleForHeapStart(); ui::d3d12::util::CreateBufferRawSRV( device, - provider->OffsetViewDescriptor(buffer_descriptor_heap_start_, - uint32_t(BufferDescriptorIndex::kRawSRV)), + provider.OffsetViewDescriptor(buffer_descriptor_heap_start_, + uint32_t(BufferDescriptorIndex::kRawSRV)), buffer_, kBufferSize); ui::d3d12::util::CreateBufferTypedSRV( device, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( buffer_descriptor_heap_start_, uint32_t(BufferDescriptorIndex::kR32UintSRV)), buffer_, DXGI_FORMAT_R32_UINT, kBufferSize >> 2); ui::d3d12::util::CreateBufferTypedSRV( device, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( buffer_descriptor_heap_start_, uint32_t(BufferDescriptorIndex::kR32G32UintSRV)), buffer_, DXGI_FORMAT_R32G32_UINT, kBufferSize >> 3); ui::d3d12::util::CreateBufferTypedSRV( device, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( buffer_descriptor_heap_start_, uint32_t(BufferDescriptorIndex::kR32G32B32A32UintSRV)), buffer_, DXGI_FORMAT_R32G32B32A32_UINT, kBufferSize >> 4); ui::d3d12::util::CreateBufferRawUAV( device, - provider->OffsetViewDescriptor(buffer_descriptor_heap_start_, - uint32_t(BufferDescriptorIndex::kRawUAV)), + provider.OffsetViewDescriptor(buffer_descriptor_heap_start_, + uint32_t(BufferDescriptorIndex::kRawUAV)), buffer_, kBufferSize); ui::d3d12::util::CreateBufferTypedUAV( device, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( buffer_descriptor_heap_start_, uint32_t(BufferDescriptorIndex::kR32UintUAV)), buffer_, DXGI_FORMAT_R32_UINT, kBufferSize >> 2); ui::d3d12::util::CreateBufferTypedUAV( device, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( buffer_descriptor_heap_start_, uint32_t(BufferDescriptorIndex::kR32G32UintUAV)), buffer_, DXGI_FORMAT_R32G32_UINT, kBufferSize >> 3); ui::d3d12::util::CreateBufferTypedUAV( device, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( buffer_descriptor_heap_start_, uint32_t(BufferDescriptorIndex::kR32G32B32A32UintUAV)), buffer_, DXGI_FORMAT_R32G32B32A32_UINT, kBufferSize >> 4); @@ -157,7 +157,7 @@ bool SharedMemory::Initialize() { xe::align(uint32_t(4 * 1024 * 1024), uint32_t(1) << page_size_log2_)); memory_invalidation_callback_handle_ = - memory_->RegisterPhysicalMemoryInvalidationCallback( + memory_.RegisterPhysicalMemoryInvalidationCallback( MemoryInvalidationCallbackThunk, this); ResetTraceGPUWrittenBuffer(); @@ -186,7 +186,7 @@ void SharedMemory::Shutdown() { watch_range_pools_.clear(); if (memory_invalidation_callback_handle_ != nullptr) { - memory_->UnregisterPhysicalMemoryInvalidationCallback( + memory_.UnregisterPhysicalMemoryInvalidationCallback( memory_invalidation_callback_handle_); memory_invalidation_callback_handle_ = nullptr; } @@ -238,7 +238,7 @@ void SharedMemory::ClearCache() { } void SharedMemory::CompletedSubmissionUpdated() { - upload_buffer_pool_->Reclaim(command_processor_->GetCompletedSubmission()); + upload_buffer_pool_->Reclaim(command_processor_.GetCompletedSubmission()); } SharedMemory::GlobalWatchHandle SharedMemory::RegisterGlobalWatch( @@ -364,9 +364,9 @@ bool SharedMemory::EnsureTilesResident(uint32_t start, uint32_t length) { if (heaps_[i] != nullptr) { continue; } - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); - auto device = provider->GetDevice(); - auto direct_queue = provider->GetDirectQueue(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); + auto device = provider.GetDevice(); + auto direct_queue = provider.GetDirectQueue(); D3D12_HEAP_DESC heap_desc = {}; heap_desc.SizeInBytes = kHeapSize; heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT; @@ -412,7 +412,7 @@ bool SharedMemory::RequestRange(uint32_t start, uint32_t length) { } uint32_t last = start + length - 1; - auto command_list = command_processor_->GetDeferredCommandList(); + auto& command_list = command_processor_.GetDeferredCommandList(); #if FINE_GRAINED_DRAW_SCOPES SCOPE_profile_cpu_f("gpu"); @@ -429,17 +429,17 @@ bool SharedMemory::RequestRange(uint32_t start, uint32_t length) { return true; } CommitUAVWritesAndTransitionBuffer(D3D12_RESOURCE_STATE_COPY_DEST); - command_processor_->SubmitBarriers(); + command_processor_.SubmitBarriers(); for (auto upload_range : upload_ranges_) { uint32_t upload_range_start = upload_range.first; uint32_t upload_range_length = upload_range.second; - trace_writer_->WriteMemoryRead(upload_range_start << page_size_log2_, - upload_range_length << page_size_log2_); + trace_writer_.WriteMemoryRead(upload_range_start << page_size_log2_, + upload_range_length << page_size_log2_); while (upload_range_length != 0) { ID3D12Resource* upload_buffer; uint32_t upload_buffer_offset, upload_buffer_size; uint8_t* upload_buffer_mapping = upload_buffer_pool_->RequestPartial( - command_processor_->GetCurrentSubmission(), + command_processor_.GetCurrentSubmission(), upload_range_length << page_size_log2_, &upload_buffer, &upload_buffer_offset, &upload_buffer_size, nullptr); if (upload_buffer_mapping == nullptr) { @@ -451,9 +451,9 @@ bool SharedMemory::RequestRange(uint32_t start, uint32_t length) { upload_buffer_pages << page_size_log2_, false); std::memcpy( upload_buffer_mapping, - memory_->TranslatePhysical(upload_range_start << page_size_log2_), + memory_.TranslatePhysical(upload_range_start << page_size_log2_), upload_buffer_size); - command_list->D3DCopyBufferRegion( + command_list.D3DCopyBufferRegion( buffer_, upload_range_start << page_size_log2_, upload_buffer, upload_buffer_offset, upload_buffer_size); upload_range_start += upload_buffer_pages; @@ -519,12 +519,12 @@ bool SharedMemory::AreTiledResourcesUsed() const { if (!cvars::d3d12_tiled_shared_memory) { return false; } - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); // As of October 8th, 2018, PIX doesn't support tiled buffers. // FIXME(Triang3l): Re-enable tiled resources with PIX once fixed. - return provider->GetTiledResourcesTier() != + return provider.GetTiledResourcesTier() != D3D12_TILED_RESOURCES_TIER_NOT_SUPPORTED && - provider->GetGraphicsAnalysis() == nullptr; + provider.GetGraphicsAnalysis() == nullptr; } void SharedMemory::MakeRangeValid(uint32_t start, uint32_t length, @@ -561,7 +561,7 @@ void SharedMemory::MakeRangeValid(uint32_t start, uint32_t length, } if (memory_invalidation_callback_handle_) { - memory_->EnablePhysicalMemoryAccessCallbacks( + memory_.EnablePhysicalMemoryAccessCallbacks( valid_page_first << page_size_log2_, (valid_page_last - valid_page_first + 1) << page_size_log2_, true, false); @@ -718,34 +718,34 @@ void SharedMemory::CommitUAVWritesAndTransitionBuffer( if (buffer_state_ == new_state) { if (new_state == D3D12_RESOURCE_STATE_UNORDERED_ACCESS && buffer_uav_writes_commit_needed_) { - command_processor_->PushUAVBarrier(buffer_); + command_processor_.PushUAVBarrier(buffer_); buffer_uav_writes_commit_needed_ = false; } return; } - command_processor_->PushTransitionBarrier(buffer_, buffer_state_, new_state); + command_processor_.PushTransitionBarrier(buffer_, buffer_state_, new_state); buffer_state_ = new_state; // "UAV -> anything" transition commits the writes implicitly. buffer_uav_writes_commit_needed_ = false; } void SharedMemory::WriteRawSRVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle) { - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); - auto device = provider->GetDevice(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); + auto device = provider.GetDevice(); device->CopyDescriptorsSimple( 1, handle, - provider->OffsetViewDescriptor(buffer_descriptor_heap_start_, - uint32_t(BufferDescriptorIndex::kRawSRV)), + provider.OffsetViewDescriptor(buffer_descriptor_heap_start_, + uint32_t(BufferDescriptorIndex::kRawSRV)), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); } void SharedMemory::WriteRawUAVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle) { - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); - auto device = provider->GetDevice(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); + auto device = provider.GetDevice(); device->CopyDescriptorsSimple( 1, handle, - provider->OffsetViewDescriptor(buffer_descriptor_heap_start_, - uint32_t(BufferDescriptorIndex::kRawUAV)), + provider.OffsetViewDescriptor(buffer_descriptor_heap_start_, + uint32_t(BufferDescriptorIndex::kRawUAV)), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); } @@ -766,12 +766,12 @@ void SharedMemory::WriteUintPow2SRVDescriptor( assert_unhandled_case(element_size_bytes_pow2); return; } - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); - auto device = provider->GetDevice(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); + auto device = provider.GetDevice(); device->CopyDescriptorsSimple( 1, handle, - provider->OffsetViewDescriptor(buffer_descriptor_heap_start_, - uint32_t(descriptor_index)), + provider.OffsetViewDescriptor(buffer_descriptor_heap_start_, + uint32_t(descriptor_index)), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); } @@ -792,12 +792,12 @@ void SharedMemory::WriteUintPow2UAVDescriptor( assert_unhandled_case(element_size_bytes_pow2); return; } - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); - auto device = provider->GetDevice(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); + auto device = provider.GetDevice(); device->CopyDescriptorsSimple( 1, handle, - provider->OffsetViewDescriptor(buffer_descriptor_heap_start_, - uint32_t(descriptor_index)), + provider.OffsetViewDescriptor(buffer_descriptor_heap_start_, + uint32_t(descriptor_index)), D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); } @@ -891,7 +891,7 @@ bool SharedMemory::InitializeTraceSubmitDownloads() { gpu_written_buffer_desc, gpu_written_page_count << page_size_log2_, D3D12_RESOURCE_FLAG_NONE); auto device = - command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); + command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice(); if (FAILED(device->CreateCommittedResource( &ui::d3d12::util::kHeapPropertiesReadback, D3D12_HEAP_FLAG_NONE, &gpu_written_buffer_desc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, @@ -903,9 +903,9 @@ bool SharedMemory::InitializeTraceSubmitDownloads() { ResetTraceGPUWrittenBuffer(); return false; } - auto command_list = command_processor_->GetDeferredCommandList(); + auto& command_list = command_processor_.GetDeferredCommandList(); UseAsCopySource(); - command_processor_->SubmitBarriers(); + command_processor_.SubmitBarriers(); uint32_t gpu_written_buffer_offset = 0; for (auto& gpu_written_submit_range : trace_gpu_written_ranges_) { // For cases like resolution scale, when the data may not be actually @@ -915,7 +915,7 @@ bool SharedMemory::InitializeTraceSubmitDownloads() { gpu_written_submit_range.second = 0; continue; } - command_list->D3DCopyBufferRegion( + command_list.D3DCopyBufferRegion( trace_gpu_written_buffer_, gpu_written_buffer_offset, buffer_, gpu_written_submit_range.first, gpu_written_submit_range.second); gpu_written_buffer_offset += gpu_written_submit_range.second; @@ -932,7 +932,7 @@ void SharedMemory::InitializeTraceCompleteDownloads() { trace_gpu_written_buffer_->Map(0, nullptr, &download_mapping))) { uint32_t gpu_written_buffer_offset = 0; for (auto gpu_written_submit_range : trace_gpu_written_ranges_) { - trace_writer_->WriteMemoryRead( + trace_writer_.WriteMemoryRead( gpu_written_submit_range.first, gpu_written_submit_range.second, reinterpret_cast(download_mapping) + gpu_written_buffer_offset); diff --git a/src/xenia/gpu/d3d12/shared_memory.h b/src/xenia/gpu/d3d12/shared_memory.h index 125245aa4..e1b48d0e6 100644 --- a/src/xenia/gpu/d3d12/shared_memory.h +++ b/src/xenia/gpu/d3d12/shared_memory.h @@ -31,8 +31,8 @@ class D3D12CommandProcessor; // system page size granularity. class SharedMemory { public: - SharedMemory(D3D12CommandProcessor* command_processor, Memory* memory, - TraceWriter* trace_writer); + SharedMemory(D3D12CommandProcessor& command_processor, Memory& memory, + TraceWriter& trace_writer); ~SharedMemory(); bool Initialize(); @@ -153,9 +153,9 @@ class SharedMemory { // Mark the memory range as updated and protect it. void MakeRangeValid(uint32_t start, uint32_t length, bool written_by_gpu); - D3D12CommandProcessor* command_processor_; - Memory* memory_; - TraceWriter* trace_writer_; + D3D12CommandProcessor& command_processor_; + Memory& memory_; + TraceWriter& trace_writer_; // The 512 MB tiled buffer. static constexpr uint32_t kBufferSizeLog2 = 29; diff --git a/src/xenia/gpu/d3d12/texture_cache.cc b/src/xenia/gpu/d3d12/texture_cache.cc index 1b4525e4d..0f096fb49 100644 --- a/src/xenia/gpu/d3d12/texture_cache.cc +++ b/src/xenia/gpu/d3d12/texture_cache.cc @@ -829,10 +829,10 @@ const TextureCache::LoadModeInfo TextureCache::load_mode_info_[] = { 4}, }; -TextureCache::TextureCache(D3D12CommandProcessor* command_processor, - RegisterFile* register_file, +TextureCache::TextureCache(D3D12CommandProcessor& command_processor, + const RegisterFile& register_file, bool bindless_resources_used, - SharedMemory* shared_memory) + SharedMemory& shared_memory) : command_processor_(command_processor), register_file_(register_file), bindless_resources_used_(bindless_resources_used), @@ -841,15 +841,15 @@ TextureCache::TextureCache(D3D12CommandProcessor* command_processor, TextureCache::~TextureCache() { Shutdown(); } bool TextureCache::Initialize(bool edram_rov_used) { - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); - auto device = provider->GetDevice(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); + auto device = provider.GetDevice(); // Try to create the tiled buffer 2x resolution scaling. // Not currently supported with the RTV/DSV output path for various reasons. if (cvars::d3d12_resolution_scale >= 2 && edram_rov_used && - provider->GetTiledResourcesTier() != + provider.GetTiledResourcesTier() != D3D12_TILED_RESOURCES_TIER_NOT_SUPPORTED && - provider->GetVirtualAddressBitsPerResource() >= + provider.GetVirtualAddressBitsPerResource() >= kScaledResolveBufferSizeLog2) { D3D12_RESOURCE_DESC scaled_resolve_buffer_desc; ui::d3d12::util::FillBufferResourceDesc( @@ -983,7 +983,7 @@ bool TextureCache::Initialize(bool edram_rov_used) { null_srv_desc.Texture2DArray.ResourceMinLODClamp = 0.0f; device->CreateShaderResourceView( nullptr, &null_srv_desc, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( null_srv_descriptor_heap_start_, uint32_t(NullSRVDescriptorIndex::k2DArray))); null_srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D; @@ -992,19 +992,19 @@ bool TextureCache::Initialize(bool edram_rov_used) { null_srv_desc.Texture3D.ResourceMinLODClamp = 0.0f; device->CreateShaderResourceView( nullptr, &null_srv_desc, - provider->OffsetViewDescriptor(null_srv_descriptor_heap_start_, - uint32_t(NullSRVDescriptorIndex::k3D))); + provider.OffsetViewDescriptor(null_srv_descriptor_heap_start_, + uint32_t(NullSRVDescriptorIndex::k3D))); null_srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE; null_srv_desc.TextureCube.MostDetailedMip = 0; null_srv_desc.TextureCube.MipLevels = 1; null_srv_desc.TextureCube.ResourceMinLODClamp = 0.0f; device->CreateShaderResourceView( nullptr, &null_srv_desc, - provider->OffsetViewDescriptor(null_srv_descriptor_heap_start_, - uint32_t(NullSRVDescriptorIndex::kCube))); + provider.OffsetViewDescriptor(null_srv_descriptor_heap_start_, + uint32_t(NullSRVDescriptorIndex::kCube))); if (IsResolutionScale2X()) { - scaled_resolve_global_watch_handle_ = shared_memory_->RegisterGlobalWatch( + scaled_resolve_global_watch_handle_ = shared_memory_.RegisterGlobalWatch( ScaledResolveGlobalWatchCallbackThunk, this); } @@ -1017,7 +1017,7 @@ void TextureCache::Shutdown() { ClearCache(); if (scaled_resolve_global_watch_handle_ != nullptr) { - shared_memory_->UnregisterGlobalWatch(scaled_resolve_global_watch_handle_); + shared_memory_.UnregisterGlobalWatch(scaled_resolve_global_watch_handle_); scaled_resolve_global_watch_handle_ = nullptr; } @@ -1046,13 +1046,13 @@ void TextureCache::ClearCache() { // Destroy all the textures. for (auto texture_pair : textures_) { Texture* texture = texture_pair.second; - shared_memory_->UnwatchMemoryRange(texture->base_watch_handle); - shared_memory_->UnwatchMemoryRange(texture->mip_watch_handle); + shared_memory_.UnwatchMemoryRange(texture->base_watch_handle); + shared_memory_.UnwatchMemoryRange(texture->mip_watch_handle); // Bindful descriptor cache will be cleared entirely now, so only release // bindless descriptors. if (bindless_resources_used_) { for (auto descriptor_pair : texture->srv_descriptors) { - command_processor_->ReleaseViewBindlessDescriptorImmediately( + command_processor_.ReleaseViewBindlessDescriptorImmediately( descriptor_pair.second); } } @@ -1090,7 +1090,7 @@ void TextureCache::BeginFrame() { texture_current_usage_time_ = xe::Clock::QueryHostUptimeMillis(); // If memory usage is too high, destroy unused textures. - uint64_t completed_frame = command_processor_->GetCompletedFrame(); + uint64_t completed_frame = command_processor_.GetCompletedFrame(); uint32_t limit_soft_mb = cvars::d3d12_texture_cache_limit_soft; uint32_t limit_hard_mb = cvars::d3d12_texture_cache_limit_hard; if (IsResolutionScale2X()) { @@ -1134,11 +1134,11 @@ void TextureCache::BeginFrame() { // Exclude the texture from the memory usage counter. textures_total_size_ -= texture->resource_size; // Destroy the texture. - shared_memory_->UnwatchMemoryRange(texture->base_watch_handle); - shared_memory_->UnwatchMemoryRange(texture->mip_watch_handle); + shared_memory_.UnwatchMemoryRange(texture->base_watch_handle); + shared_memory_.UnwatchMemoryRange(texture->mip_watch_handle); if (bindless_resources_used_) { for (auto descriptor_pair : texture->srv_descriptors) { - command_processor_->ReleaseViewBindlessDescriptorImmediately( + command_processor_.ReleaseViewBindlessDescriptorImmediately( descriptor_pair.second); } } else { @@ -1177,7 +1177,7 @@ void TextureCache::EndFrame() { } void TextureCache::RequestTextures(uint32_t used_texture_mask) { - auto& regs = *register_file_; + const auto& regs = register_file_; #if FINE_GRAINED_DRAW_SCOPES SCOPE_profile_cpu_f("gpu"); @@ -1315,7 +1315,7 @@ void TextureCache::RequestTextures(uint32_t used_texture_mask) { if (binding.texture != nullptr) { // Will be referenced by the command list, so mark as used. MarkTextureUsed(binding.texture); - command_processor_->PushTransitionBarrier( + command_processor_.PushTransitionBarrier( binding.texture->resource, binding.texture->state, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); @@ -1324,7 +1324,7 @@ void TextureCache::RequestTextures(uint32_t used_texture_mask) { } if (binding.texture_signed != nullptr) { MarkTextureUsed(binding.texture_signed); - command_processor_->PushTransitionBarrier( + command_processor_.PushTransitionBarrier( binding.texture_signed->resource, binding.texture_signed->state, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); @@ -1392,7 +1392,7 @@ void TextureCache::WriteActiveTextureBindfulSRV( } } } - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); D3D12_CPU_DESCRIPTOR_HANDLE source_handle; if (descriptor_index != UINT32_MAX) { assert_not_null(texture); @@ -1413,10 +1413,10 @@ void TextureCache::WriteActiveTextureBindfulSRV( host_shader_binding.dimension == xenos::FetchOpDimension::k2D); null_descriptor_index = NullSRVDescriptorIndex::k2DArray; } - source_handle = provider->OffsetViewDescriptor( + source_handle = provider.OffsetViewDescriptor( null_srv_descriptor_heap_start_, uint32_t(null_descriptor_index)); } - auto device = provider->GetDevice(); + auto device = provider.GetDevice(); { #if FINE_GRAINED_DRAW_SCOPES SCOPE_profile_cpu_i( @@ -1465,7 +1465,7 @@ uint32_t TextureCache::GetActiveTextureBindlessSRVIndex( TextureCache::SamplerParameters TextureCache::GetSamplerParameters( const D3D12Shader::SamplerBinding& binding) const { - auto& regs = *register_file_; + const auto& regs = register_file_; const auto& fetch = regs.Get( XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 + binding.fetch_constant * 6); @@ -1571,7 +1571,7 @@ void TextureCache::WriteSampler(SamplerParameters parameters, // Maximum mip level is in the texture resource itself. desc.MaxLOD = FLT_MAX; auto device = - command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); + command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice(); device->CreateSampler(&desc, handle); } @@ -1604,7 +1604,7 @@ void TextureCache::MarkRangeAsResolved(uint32_t start_unscaled, // Invalidate textures. Toggling individual textures between scaled and // unscaled also relies on invalidation through shared memory. - shared_memory_->RangeWrittenByGPU(start_unscaled, length_unscaled); + shared_memory_.RangeWrittenByGPU(start_unscaled, length_unscaled); } bool TextureCache::EnsureScaledResolveBufferResident(uint32_t start_unscaled, @@ -1627,9 +1627,9 @@ bool TextureCache::EnsureScaledResolveBufferResident(uint32_t start_unscaled, if (scaled_resolve_heaps_[i] != nullptr) { continue; } - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); - auto device = provider->GetDevice(); - auto direct_queue = provider->GetDirectQueue(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); + auto device = provider.GetDevice(); + auto direct_queue = provider.GetDirectQueue(); D3D12_HEAP_DESC heap_desc = {}; heap_desc.SizeInBytes = kScaledResolveHeapSize; heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT; @@ -1671,7 +1671,7 @@ bool TextureCache::EnsureScaledResolveBufferResident(uint32_t start_unscaled, void TextureCache::UseScaledResolveBufferForReading() { assert_true(IsResolutionScale2X()); - command_processor_->PushTransitionBarrier( + command_processor_.PushTransitionBarrier( scaled_resolve_buffer_, scaled_resolve_buffer_state_, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); scaled_resolve_buffer_state_ = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; @@ -1683,12 +1683,12 @@ void TextureCache::UseScaledResolveBufferForWriting() { assert_true(IsResolutionScale2X()); if (scaled_resolve_buffer_state_ == D3D12_RESOURCE_STATE_UNORDERED_ACCESS) { if (scaled_resolve_buffer_uav_writes_commit_needed_) { - command_processor_->PushUAVBarrier(scaled_resolve_buffer_); + command_processor_.PushUAVBarrier(scaled_resolve_buffer_); scaled_resolve_buffer_uav_writes_commit_needed_ = false; } return; } - command_processor_->PushTransitionBarrier( + command_processor_.PushTransitionBarrier( scaled_resolve_buffer_, scaled_resolve_buffer_state_, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); scaled_resolve_buffer_state_ = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; @@ -1699,7 +1699,7 @@ void TextureCache::CreateScaledResolveBufferUintPow2UAV( uint32_t guest_length_bytes, uint32_t element_size_bytes_pow2) { assert_true(IsResolutionScale2X()); ui::d3d12::util::CreateBufferTypedUAV( - command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(), + command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice(), handle, scaled_resolve_buffer_, ui::d3d12::util::GetUintPow2DXGIFormat(element_size_bytes_pow2), guest_length_bytes << 2 >> element_size_bytes_pow2, @@ -1709,7 +1709,7 @@ void TextureCache::CreateScaledResolveBufferUintPow2UAV( ID3D12Resource* TextureCache::RequestSwapTexture( D3D12_SHADER_RESOURCE_VIEW_DESC& srv_desc_out, xenos::TextureFormat& format_out) { - auto& regs = *register_file_; + const auto& regs = register_file_; const auto& fetch = regs.Get( XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0); TextureKey key; @@ -1727,7 +1727,7 @@ ID3D12Resource* TextureCache::RequestSwapTexture( // The swap texture is likely to be used only for the presentation pixel // shader, and not during emulation, where it'd be NON_PIXEL_SHADER_RESOURCE | // PIXEL_SHADER_RESOURCE. - command_processor_->PushTransitionBarrier( + command_processor_.PushTransitionBarrier( texture->resource, texture->state, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); texture->state = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; @@ -1954,7 +1954,7 @@ TextureCache::Texture* TextureCache::FindOrCreateTexture(TextureKey key) { // is not done that often. desc.Flags = D3D12_RESOURCE_FLAG_NONE; auto device = - command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); + command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice(); // Assuming untiling will be the next operation. D3D12_RESOURCE_STATES state = D3D12_RESOURCE_STATE_COPY_DEST; ID3D12Resource* resource; @@ -1972,7 +1972,7 @@ TextureCache::Texture* TextureCache::FindOrCreateTexture(TextureKey key) { texture->resource_size = device->GetResourceAllocationInfo(0, 1, &desc).SizeInBytes; texture->state = state; - texture->last_usage_frame = command_processor_->GetCurrentFrame(); + texture->last_usage_frame = command_processor_.GetCurrentFrame(); texture->last_usage_time = texture_current_usage_time_; texture->used_previous = texture_used_last_; texture->used_next = nullptr; @@ -2070,9 +2070,9 @@ bool TextureCache::LoadTextureData(Texture* texture) { return true; } - auto command_list = command_processor_->GetDeferredCommandList(); + auto& command_list = command_processor_.GetDeferredCommandList(); auto device = - command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); + command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice(); // Get the pipeline. LoadMode load_mode = GetLoadMode(texture->key); @@ -2095,14 +2095,14 @@ bool TextureCache::LoadTextureData(Texture* texture) { // its pages is invalidated, in this case we'll need the texture from the // shared memory to load the unscaled parts. if (!base_in_sync) { - if (!shared_memory_->RequestRange(texture->key.base_page << 12, - texture->base_size)) { + if (!shared_memory_.RequestRange(texture->key.base_page << 12, + texture->base_size)) { return false; } } if (!mips_in_sync) { - if (!shared_memory_->RequestRange(texture->key.mip_page << 12, - texture->mip_size)) { + if (!shared_memory_.RequestRange(texture->key.mip_page << 12, + texture->mip_size)) { return false; } } @@ -2205,7 +2205,7 @@ bool TextureCache::LoadTextureData(Texture* texture) { } D3D12_RESOURCE_STATES copy_buffer_state = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; - ID3D12Resource* copy_buffer = command_processor_->RequestScratchGPUBuffer( + ID3D12Resource* copy_buffer = command_processor_.RequestScratchGPUBuffer( uint32_t(host_slice_size), copy_buffer_state); if (copy_buffer == nullptr) { return false; @@ -2237,8 +2237,8 @@ bool TextureCache::LoadTextureData(Texture* texture) { } } ui::d3d12::util::DescriptorCPUGPUHandlePair descriptors[3]; - if (!command_processor_->RequestOneUseSingleViewDescriptors(descriptor_count, - descriptors)) { + if (!command_processor_.RequestOneUseSingleViewDescriptors(descriptor_count, + descriptors)) { return false; } uint32_t descriptor_write_index = 0; @@ -2285,30 +2285,30 @@ bool TextureCache::LoadTextureData(Texture* texture) { load_mode_info.srv_bpe_log2_2x); } } else { - shared_memory_->UseForReading(); + shared_memory_.UseForReading(); if (bindless_resources_used_) { descriptors_source[0] = - command_processor_->GetSharedMemoryUintPow2BindlessSRVHandlePair( + command_processor_.GetSharedMemoryUintPow2BindlessSRVHandlePair( load_mode_info.srv_bpe_log2); } else { assert_true(descriptor_write_index < descriptor_count); descriptors_source[0] = descriptors[descriptor_write_index++]; - shared_memory_->WriteUintPow2SRVDescriptor(descriptors_source[0].first, - load_mode_info.srv_bpe_log2); + shared_memory_.WriteUintPow2SRVDescriptor(descriptors_source[0].first, + load_mode_info.srv_bpe_log2); } } - command_processor_->SetComputePipelineState(pipeline_state); - command_list->D3DSetComputeRootSignature(load_root_signature_); - command_list->D3DSetComputeRootDescriptorTable(2, descriptor_dest.second); + command_processor_.SetComputePipelineState(pipeline_state); + command_list.D3DSetComputeRootSignature(load_root_signature_); + command_list.D3DSetComputeRootDescriptorTable(2, descriptor_dest.second); // Update LRU caching because the texture will be used by the command list. MarkTextureUsed(texture); // Submit commands. - command_processor_->PushTransitionBarrier(texture->resource, texture->state, - D3D12_RESOURCE_STATE_COPY_DEST); + command_processor_.PushTransitionBarrier(texture->resource, texture->state, + D3D12_RESOURCE_STATE_COPY_DEST); texture->state = D3D12_RESOURCE_STATE_COPY_DEST; - auto cbuffer_pool = command_processor_->GetConstantBufferPool(); + auto& cbuffer_pool = command_processor_.GetConstantBufferPool(); LoadConstants load_constants; load_constants.is_3d_endian = uint32_t(is_3d) | (uint32_t(texture->key.endianness) << 1); @@ -2323,7 +2323,7 @@ bool TextureCache::LoadTextureData(Texture* texture) { } uint32_t descriptor_source_last_index = UINT32_MAX; for (uint32_t slice = 0; slice < slice_count; ++slice) { - command_processor_->PushTransitionBarrier( + command_processor_.PushTransitionBarrier( copy_buffer, copy_buffer_state, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); copy_buffer_state = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; for (uint32_t loop_mip = loop_mip_first; loop_mip <= loop_mip_last; @@ -2393,33 +2393,33 @@ bool TextureCache::LoadTextureData(Texture* texture) { xe::next_pow2(load_constants.size_blocks[1]), uint32_t(32)); } D3D12_GPU_VIRTUAL_ADDRESS cbuffer_gpu_address; - uint8_t* cbuffer_mapping = cbuffer_pool->Request( - command_processor_->GetCurrentFrame(), + uint8_t* cbuffer_mapping = cbuffer_pool.Request( + command_processor_.GetCurrentFrame(), xe::align(uint32_t(sizeof(load_constants)), uint32_t(256)), nullptr, nullptr, &cbuffer_gpu_address); if (cbuffer_mapping == nullptr) { - command_processor_->ReleaseScratchGPUBuffer(copy_buffer, - copy_buffer_state); + command_processor_.ReleaseScratchGPUBuffer(copy_buffer, + copy_buffer_state); return false; } std::memcpy(cbuffer_mapping, &load_constants, sizeof(load_constants)); if (descriptor_source_last_index != descriptor_source_index) { descriptor_source_last_index = descriptor_source_index; - command_list->D3DSetComputeRootDescriptorTable( + command_list.D3DSetComputeRootDescriptorTable( 1, descriptors_source[descriptor_source_index].second); } - command_list->D3DSetComputeRootConstantBufferView(0, cbuffer_gpu_address); - command_processor_->SubmitBarriers(); + command_list.D3DSetComputeRootConstantBufferView(0, cbuffer_gpu_address); + command_processor_.SubmitBarriers(); // Each thread group processes 32x32x1 guest blocks. - command_list->D3DDispatch((load_constants.size_blocks[0] + 31) >> 5, - (load_constants.size_blocks[1] + 31) >> 5, - load_constants.size_blocks[2]); + command_list.D3DDispatch((load_constants.size_blocks[0] + 31) >> 5, + (load_constants.size_blocks[1] + 31) >> 5, + load_constants.size_blocks[2]); } - command_processor_->PushUAVBarrier(copy_buffer); - command_processor_->PushTransitionBarrier(copy_buffer, copy_buffer_state, - D3D12_RESOURCE_STATE_COPY_SOURCE); + command_processor_.PushUAVBarrier(copy_buffer); + command_processor_.PushTransitionBarrier(copy_buffer, copy_buffer_state, + D3D12_RESOURCE_STATE_COPY_SOURCE); copy_buffer_state = D3D12_RESOURCE_STATE_COPY_SOURCE; - command_processor_->SubmitBarriers(); + command_processor_.SubmitBarriers(); UINT slice_first_subresource = slice * texture_mip_count; for (uint32_t mip = mip_first; mip <= mip_last; ++mip) { D3D12_TEXTURE_COPY_LOCATION location_source, location_dest; @@ -2450,16 +2450,16 @@ bool TextureCache::LoadTextureData(Texture* texture) { xe::align(std::max(height >> mip, uint32_t(1)), host_block_height); source_box.back = source_box.front + std::max(depth >> mip, uint32_t(1)); - command_list->CopyTextureRegion(location_dest, 0, 0, 0, location_source, - source_box); + command_list.CopyTextureRegion(location_dest, 0, 0, 0, location_source, + source_box); } else { location_source.PlacedFootprint = host_layouts[mip - mip_first]; - command_list->CopyTexture(location_dest, location_source); + command_list.CopyTexture(location_dest, location_source); } } } - command_processor_->ReleaseScratchGPUBuffer(copy_buffer, copy_buffer_state); + command_processor_.ReleaseScratchGPUBuffer(copy_buffer, copy_buffer_state); // Mark the ranges as uploaded and watch them. This is needed for scaled // resolves as well to detect when the CPU wants to reuse the memory for a @@ -2470,12 +2470,12 @@ bool TextureCache::LoadTextureData(Texture* texture) { texture->base_in_sync = true; texture->mips_in_sync = true; if (!base_in_sync) { - texture->base_watch_handle = shared_memory_->WatchMemoryRange( + texture->base_watch_handle = shared_memory_.WatchMemoryRange( texture->key.base_page << 12, texture->base_size, WatchCallbackThunk, this, texture, 0); } if (!mips_in_sync) { - texture->mip_watch_handle = shared_memory_->WatchMemoryRange( + texture->mip_watch_handle = shared_memory_.WatchMemoryRange( texture->key.mip_page << 12, texture->mip_size, WatchCallbackThunk, this, texture, 1); } @@ -2552,11 +2552,11 @@ uint32_t TextureCache::FindOrCreateTextureDescriptor(Texture& texture, D3D12_SHADER_COMPONENT_MAPPING_ALWAYS_SET_BIT_AVOIDING_ZEROMEM_MISTAKES; auto device = - command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); + command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice(); uint32_t descriptor_index; if (bindless_resources_used_) { descriptor_index = - command_processor_->RequestPersistentViewBindlessDescriptor(); + command_processor_.RequestPersistentViewBindlessDescriptor(); if (descriptor_index == UINT32_MAX) { XELOGE( "Failed to create a texture descriptor - no free bindless view " @@ -2604,21 +2604,21 @@ uint32_t TextureCache::FindOrCreateTextureDescriptor(Texture& texture, D3D12_CPU_DESCRIPTOR_HANDLE TextureCache::GetTextureDescriptorCPUHandle( uint32_t descriptor_index) const { - auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); + auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider(); if (bindless_resources_used_) { - return provider->OffsetViewDescriptor( - command_processor_->GetViewBindlessHeapCPUStart(), descriptor_index); + return provider.OffsetViewDescriptor( + command_processor_.GetViewBindlessHeapCPUStart(), descriptor_index); } D3D12_CPU_DESCRIPTOR_HANDLE heap_start = srv_descriptor_cache_[descriptor_index / SRVDescriptorCachePage::kHeapSize] .heap_start; uint32_t heap_offset = descriptor_index % SRVDescriptorCachePage::kHeapSize; - return provider->OffsetViewDescriptor(heap_start, heap_offset); + return provider.OffsetViewDescriptor(heap_start, heap_offset); } void TextureCache::MarkTextureUsed(Texture* texture) { - uint64_t current_frame = command_processor_->GetCurrentFrame(); + uint64_t current_frame = command_processor_.GetCurrentFrame(); // This is called very frequently, don't relink unless needed for caching. if (texture->last_usage_frame != current_frame) { texture->last_usage_frame = current_frame; diff --git a/src/xenia/gpu/d3d12/texture_cache.h b/src/xenia/gpu/d3d12/texture_cache.h index 3a663716f..1047cabd0 100644 --- a/src/xenia/gpu/d3d12/texture_cache.h +++ b/src/xenia/gpu/d3d12/texture_cache.h @@ -167,9 +167,9 @@ class TextureCache { } }; - TextureCache(D3D12CommandProcessor* command_processor, - RegisterFile* register_file, bool bindless_resources_used, - SharedMemory* shared_memory); + TextureCache(D3D12CommandProcessor& command_processor, + const RegisterFile& register_file, bool bindless_resources_used, + SharedMemory& shared_memory); ~TextureCache(); bool Initialize(bool edram_rov_used); @@ -543,10 +543,10 @@ class TextureCache { static const char* const dimension_names_[4]; - D3D12CommandProcessor* command_processor_; - RegisterFile* register_file_; + D3D12CommandProcessor& command_processor_; + const RegisterFile& register_file_; bool bindless_resources_used_; - SharedMemory* shared_memory_; + SharedMemory& shared_memory_; static const LoadModeInfo load_mode_info_[]; ID3D12RootSignature* load_root_signature_ = nullptr; diff --git a/src/xenia/memory.cc b/src/xenia/memory.cc index 834091a07..7e60797f5 100644 --- a/src/xenia/memory.cc +++ b/src/xenia/memory.cc @@ -1145,12 +1145,38 @@ bool BaseHeap::Release(uint32_t base_address, uint32_t* out_region_size) { bool BaseHeap::Protect(uint32_t address, uint32_t size, uint32_t protect, uint32_t* old_protect) { - uint32_t page_count = xe::round_up(size, page_size_) / page_size_; + if (!size) { + XELOGE("BaseHeap::Protect failed due to zero size"); + return false; + } + + // From the VirtualProtect MSDN page: + // + // "The region of affected pages includes all pages containing one or more + // bytes in the range from the lpAddress parameter to (lpAddress+dwSize). + // This means that a 2-byte range straddling a page boundary causes the + // protection attributes of both pages to be changed." + // + // "The access protection value can be set only on committed pages. If the + // state of any page in the specified region is not committed, the function + // fails and returns without modifying the access protection of any pages in + // the specified region." + uint32_t start_page_number = (address - heap_base_) / page_size_; - uint32_t end_page_number = start_page_number + page_count - 1; - start_page_number = - std::min(uint32_t(page_table_.size()) - 1, start_page_number); - end_page_number = std::min(uint32_t(page_table_.size()) - 1, end_page_number); + if (start_page_number >= page_table_.size()) { + XELOGE("BaseHeap::Protect failed due to out-of-bounds base address {:08X}", + address); + return false; + } + uint32_t end_page_number = + uint32_t((uint64_t(address) + size - 1 - heap_base_) / page_size_); + if (end_page_number >= page_table_.size()) { + XELOGE( + "BaseHeap::Protect failed due to out-of-bounds range ({:08X} bytes " + "from {:08x})", + size, address); + return false; + } auto global_lock = global_critical_region_.Acquire(); @@ -1173,6 +1199,7 @@ bool BaseHeap::Protect(uint32_t address, uint32_t size, uint32_t protect, // Attempt host change (hopefully won't fail). // We can only do this if our size matches system page granularity. + uint32_t page_count = end_page_number - start_page_number + 1; if (page_size_ == xe::memory::page_size() || (((page_count * page_size_) % xe::memory::page_size() == 0) && ((start_page_number * page_size_) % xe::memory::page_size() == 0))) { diff --git a/src/xenia/ui/d3d12/d3d12_context.cc b/src/xenia/ui/d3d12/d3d12_context.cc index 96d043941..506ca6141 100644 --- a/src/xenia/ui/d3d12/d3d12_context.cc +++ b/src/xenia/ui/d3d12/d3d12_context.cc @@ -32,10 +32,10 @@ D3D12Context::D3D12Context(D3D12Provider* provider, Window* target_window) D3D12Context::~D3D12Context() { Shutdown(); } bool D3D12Context::Initialize() { - auto provider = GetD3D12Provider(); - auto dxgi_factory = provider->GetDXGIFactory(); - auto device = provider->GetDevice(); - auto direct_queue = provider->GetDirectQueue(); + auto& provider = GetD3D12Provider(); + auto dxgi_factory = provider.GetDXGIFactory(); + auto device = provider.GetDevice(); + auto direct_queue = provider.GetDirectQueue(); context_lost_ = false; @@ -74,7 +74,7 @@ bool D3D12Context::Initialize() { swap_chain_desc.Flags = 0; IDXGISwapChain1* swap_chain_1; if (FAILED(dxgi_factory->CreateSwapChainForHwnd( - provider->GetDirectQueue(), + provider.GetDirectQueue(), static_cast(target_window_->native_handle()), &swap_chain_desc, nullptr, nullptr, &swap_chain_1))) { XELOGE("Failed to create a DXGI swap chain"); @@ -131,7 +131,7 @@ bool D3D12Context::Initialize() { swap_command_list_->Close(); // Initialize the immediate mode drawer if not offscreen. - immediate_drawer_ = std::make_unique(this); + immediate_drawer_ = std::make_unique(*this); if (!immediate_drawer_->Initialize()) { Shutdown(); return false; @@ -155,7 +155,7 @@ bool D3D12Context::InitializeSwapChainBuffers() { swap_chain_back_buffer_index_ = swap_chain_->GetCurrentBackBufferIndex(); // Create RTV descriptors for the swap chain buffers. - auto device = GetD3D12Provider()->GetDevice(); + auto device = GetD3D12Provider().GetDevice(); D3D12_RENDER_TARGET_VIEW_DESC rtv_desc; rtv_desc.Format = kSwapChainFormat; rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; @@ -223,12 +223,6 @@ ImmediateDrawer* D3D12Context::immediate_drawer() { return immediate_drawer_.get(); } -bool D3D12Context::is_current() { return false; } - -bool D3D12Context::MakeCurrent() { return true; } - -void D3D12Context::ClearCurrent() {} - void D3D12Context::BeginSwap() { if (!target_window_ || context_lost_) { return; @@ -320,7 +314,7 @@ void D3D12Context::EndSwap() { return; } - auto direct_queue = GetD3D12Provider()->GetDirectQueue(); + auto direct_queue = GetD3D12Provider().GetDirectQueue(); // Switch the back buffer to presentation state. D3D12_RESOURCE_BARRIER barrier; @@ -358,8 +352,8 @@ std::unique_ptr D3D12Context::Capture() { D3D12_CPU_DESCRIPTOR_HANDLE D3D12Context::GetSwapChainBufferRTV( uint32_t buffer_index) const { - return GetD3D12Provider()->OffsetRTVDescriptor(swap_chain_rtv_heap_start_, - buffer_index); + return GetD3D12Provider().OffsetRTVDescriptor(swap_chain_rtv_heap_start_, + buffer_index); } } // namespace d3d12 diff --git a/src/xenia/ui/d3d12/d3d12_context.h b/src/xenia/ui/d3d12/d3d12_context.h index 2c20816a4..4cf13d87e 100644 --- a/src/xenia/ui/d3d12/d3d12_context.h +++ b/src/xenia/ui/d3d12/d3d12_context.h @@ -28,10 +28,6 @@ class D3D12Context : public GraphicsContext { ImmediateDrawer* immediate_drawer() override; - bool is_current() override; - bool MakeCurrent() override; - void ClearCurrent() override; - bool WasLost() override { return context_lost_; } void BeginSwap() override; @@ -39,11 +35,12 @@ class D3D12Context : public GraphicsContext { std::unique_ptr Capture() override; - D3D12Provider* GetD3D12Provider() const { - return static_cast(provider_); + D3D12Provider& GetD3D12Provider() const { + return static_cast(*provider_); } - static constexpr DXGI_FORMAT kSwapChainFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + // The format used by DWM. + static constexpr DXGI_FORMAT kSwapChainFormat = DXGI_FORMAT_B8G8R8A8_UNORM; ID3D12Resource* GetSwapChainBuffer(uint32_t buffer_index) const { return swap_chain_buffers_[buffer_index]; } diff --git a/src/xenia/ui/d3d12/d3d12_immediate_drawer.cc b/src/xenia/ui/d3d12/d3d12_immediate_drawer.cc index 2d293a44d..f91c79677 100644 --- a/src/xenia/ui/d3d12/d3d12_immediate_drawer.cc +++ b/src/xenia/ui/d3d12/d3d12_immediate_drawer.cc @@ -109,14 +109,14 @@ void D3D12ImmediateTexture::Transition( state_ = new_state; } -D3D12ImmediateDrawer::D3D12ImmediateDrawer(D3D12Context* graphics_context) - : ImmediateDrawer(graphics_context), context_(graphics_context) {} +D3D12ImmediateDrawer::D3D12ImmediateDrawer(D3D12Context& graphics_context) + : ImmediateDrawer(&graphics_context), context_(graphics_context) {} D3D12ImmediateDrawer::~D3D12ImmediateDrawer() { Shutdown(); } bool D3D12ImmediateDrawer::Initialize() { - auto provider = context_->GetD3D12Provider(); - auto device = provider->GetDevice(); + auto& provider = context_.GetD3D12Provider(); + auto device = provider.GetDevice(); // Create the root signature. D3D12_ROOT_PARAMETER root_parameters[size_t(RootParameter::kCount)]; @@ -247,7 +247,7 @@ bool D3D12ImmediateDrawer::Initialize() { } sampler_heap_cpu_start_ = sampler_heap_->GetCPUDescriptorHandleForHeapStart(); sampler_heap_gpu_start_ = sampler_heap_->GetGPUDescriptorHandleForHeapStart(); - uint32_t sampler_size = provider->GetSamplerDescriptorSize(); + uint32_t sampler_size = provider.GetSamplerDescriptorSize(); // Nearest neighbor, clamp. D3D12_SAMPLER_DESC sampler_desc; sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; @@ -326,7 +326,7 @@ std::unique_ptr D3D12ImmediateDrawer::CreateTexture( const uint8_t* data) { auto texture = std::make_unique(width, height, filter, repeat); - texture->Initialize(context_->GetD3D12Provider()->GetDevice()); + texture->Initialize(context_.GetD3D12Provider().GetDevice()); if (data != nullptr) { UpdateTexture(texture.get(), data); } @@ -343,7 +343,7 @@ void D3D12ImmediateDrawer::UpdateTexture(ImmediateTexture* texture, } uint32_t width = d3d_texture->width, height = d3d_texture->height; - auto device = context_->GetD3D12Provider()->GetDevice(); + auto device = context_.GetD3D12Provider().GetDevice(); // Create and fill the upload buffer. D3D12_RESOURCE_DESC texture_desc = texture_resource->GetDesc(); @@ -400,7 +400,7 @@ void D3D12ImmediateDrawer::UpdateTexture(ImmediateTexture* texture, &location_source, nullptr); SubmittedTextureUpload submitted_upload; submitted_upload.buffer = buffer; - submitted_upload.fence_value = context_->GetSwapCurrentFenceValue(); + submitted_upload.fence_value = context_.GetSwapCurrentFenceValue(); texture_uploads_submitted_.push_back(submitted_upload); } else { // Defer uploading to the next frame when there's a command list. @@ -413,13 +413,13 @@ void D3D12ImmediateDrawer::UpdateTexture(ImmediateTexture* texture, void D3D12ImmediateDrawer::Begin(int render_target_width, int render_target_height) { - auto device = context_->GetD3D12Provider()->GetDevice(); + auto device = context_.GetD3D12Provider().GetDevice(); // Use the compositing command list. - current_command_list_ = context_->GetSwapCommandList(); + current_command_list_ = context_.GetSwapCommandList(); - uint64_t completed_fence_value = context_->GetSwapCompletedFenceValue(); - uint64_t current_fence_value = context_->GetSwapCurrentFenceValue(); + uint64_t completed_fence_value = context_.GetSwapCompletedFenceValue(); + uint64_t current_fence_value = context_.GetSwapCurrentFenceValue(); // Remove temporary buffers for completed texture uploads. auto erase_uploads_end = texture_uploads_submitted_.begin(); @@ -494,7 +494,7 @@ void D3D12ImmediateDrawer::BeginDrawBatch(const ImmediateDrawBatch& batch) { if (current_command_list_ == nullptr) { return; } - uint64_t current_fence_value = context_->GetSwapCurrentFenceValue(); + uint64_t current_fence_value = context_.GetSwapCurrentFenceValue(); batch_open_ = false; @@ -549,8 +549,8 @@ void D3D12ImmediateDrawer::Draw(const ImmediateDraw& draw) { return; } - auto provider = context_->GetD3D12Provider(); - auto device = provider->GetDevice(); + auto& provider = context_.GetD3D12Provider(); + auto device = provider.GetDevice(); // Bind the texture. auto texture = reinterpret_cast(draw.texture_handle); @@ -565,7 +565,7 @@ void D3D12ImmediateDrawer::Draw(const ImmediateDraw& draw) { bool bind_texture = current_texture_ != texture; uint32_t texture_descriptor_index; uint64_t texture_heap_index = texture_descriptor_pool_->Request( - context_->GetSwapCurrentFenceValue(), texture_descriptor_pool_heap_index_, + context_.GetSwapCurrentFenceValue(), texture_descriptor_pool_heap_index_, bind_texture ? 1 : 0, 1, texture_descriptor_index); if (texture_heap_index == DescriptorHeapPool::kHeapIndexInvalid) { return; @@ -589,12 +589,12 @@ void D3D12ImmediateDrawer::Draw(const ImmediateDraw& draw) { texture_view_desc.Texture2D.ResourceMinLODClamp = 0.0f; device->CreateShaderResourceView( texture_resource, &texture_view_desc, - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( texture_descriptor_pool_->GetLastRequestHeapCPUStart(), texture_descriptor_index)); current_command_list_->SetGraphicsRootDescriptorTable( UINT(RootParameter::kTexture), - provider->OffsetViewDescriptor( + provider.OffsetViewDescriptor( texture_descriptor_pool_->GetLastRequestHeapGPUStart(), texture_descriptor_index)); current_texture_ = texture; @@ -616,8 +616,8 @@ void D3D12ImmediateDrawer::Draw(const ImmediateDraw& draw) { if (current_sampler_index_ != sampler_index) { current_command_list_->SetGraphicsRootDescriptorTable( UINT(RootParameter::kSampler), - provider->OffsetSamplerDescriptor(sampler_heap_gpu_start_, - uint32_t(sampler_index))); + provider.OffsetSamplerDescriptor(sampler_heap_gpu_start_, + uint32_t(sampler_index))); current_sampler_index_ = sampler_index; } diff --git a/src/xenia/ui/d3d12/d3d12_immediate_drawer.h b/src/xenia/ui/d3d12/d3d12_immediate_drawer.h index 5dcb86217..f2d5df829 100644 --- a/src/xenia/ui/d3d12/d3d12_immediate_drawer.h +++ b/src/xenia/ui/d3d12/d3d12_immediate_drawer.h @@ -26,7 +26,7 @@ class D3D12Context; class D3D12ImmediateDrawer : public ImmediateDrawer { public: - D3D12ImmediateDrawer(D3D12Context* graphics_context); + D3D12ImmediateDrawer(D3D12Context& graphics_context); ~D3D12ImmediateDrawer() override; bool Initialize(); @@ -46,7 +46,7 @@ class D3D12ImmediateDrawer : public ImmediateDrawer { void End() override; private: - D3D12Context* context_ = nullptr; + D3D12Context& context_; ID3D12RootSignature* root_signature_ = nullptr; enum class RootParameter { diff --git a/src/xenia/ui/d3d12/d3d12_util.cc b/src/xenia/ui/d3d12/d3d12_util.cc index 734d967f3..b139d9adb 100644 --- a/src/xenia/ui/d3d12/d3d12_util.cc +++ b/src/xenia/ui/d3d12/d3d12_util.cc @@ -23,10 +23,10 @@ const D3D12_HEAP_PROPERTIES kHeapPropertiesReadback = { D3D12_HEAP_TYPE_READBACK}; ID3D12RootSignature* CreateRootSignature( - D3D12Provider* provider, const D3D12_ROOT_SIGNATURE_DESC& desc) { + D3D12Provider& provider, const D3D12_ROOT_SIGNATURE_DESC& desc) { ID3DBlob* blob; ID3DBlob* error_blob = nullptr; - if (FAILED(provider->SerializeRootSignature( + if (FAILED(provider.SerializeRootSignature( &desc, D3D_ROOT_SIGNATURE_VERSION_1, &blob, &error_blob))) { XELOGE("Failed to serialize a root signature"); if (error_blob != nullptr) { @@ -40,9 +40,9 @@ ID3D12RootSignature* CreateRootSignature( error_blob->Release(); } ID3D12RootSignature* root_signature = nullptr; - provider->GetDevice()->CreateRootSignature(0, blob->GetBufferPointer(), - blob->GetBufferSize(), - IID_PPV_ARGS(&root_signature)); + provider.GetDevice()->CreateRootSignature(0, blob->GetBufferPointer(), + blob->GetBufferSize(), + IID_PPV_ARGS(&root_signature)); blob->Release(); return root_signature; } diff --git a/src/xenia/ui/d3d12/d3d12_util.h b/src/xenia/ui/d3d12/d3d12_util.h index 1193ad109..92dfb1535 100644 --- a/src/xenia/ui/d3d12/d3d12_util.h +++ b/src/xenia/ui/d3d12/d3d12_util.h @@ -36,7 +36,7 @@ inline bool ReleaseAndNull(T& object) { return false; }; -ID3D12RootSignature* CreateRootSignature(D3D12Provider* provider, +ID3D12RootSignature* CreateRootSignature(D3D12Provider& provider, const D3D12_ROOT_SIGNATURE_DESC& desc); ID3D12PipelineState* CreateComputePipelineState( diff --git a/src/xenia/ui/d3d12/d3d12_window_demo.cc b/src/xenia/ui/d3d12/d3d12_window_demo.cc new file mode 100644 index 000000000..d42e6cb0e --- /dev/null +++ b/src/xenia/ui/d3d12/d3d12_window_demo.cc @@ -0,0 +1,29 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2020 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include +#include + +#include "xenia/base/main.h" +#include "xenia/ui/d3d12/d3d12_provider.h" +#include "xenia/ui/window.h" + +namespace xe { +namespace ui { + +int window_demo_main(const std::vector& args); + +std::unique_ptr CreateDemoGraphicsProvider(Window* window) { + return xe::ui::d3d12::D3D12Provider::Create(window); +} + +} // namespace ui +} // namespace xe + +DEFINE_ENTRY_POINT("xenia-ui-window-d3d12-demo", xe::ui::window_demo_main, ""); diff --git a/src/xenia/ui/d3d12/premake5.lua b/src/xenia/ui/d3d12/premake5.lua index d99afa301..f301a94d2 100644 --- a/src/xenia/ui/d3d12/premake5.lua +++ b/src/xenia/ui/d3d12/premake5.lua @@ -14,3 +14,24 @@ project("xenia-ui-d3d12") files({ "shaders/bin/*.h", }) + +group("demos") +project("xenia-ui-window-d3d12-demo") + uuid("3b9686a7-0f04-4e17-8b00-aeb78ae1107c") + kind("WindowedApp") + language("C++") + links({ + "fmt", + "imgui", + "xenia-base", + "xenia-ui", + "xenia-ui-d3d12", + }) + files({ + "../window_demo.cc", + "d3d12_window_demo.cc", + project_root.."/src/xenia/base/main_"..platform_suffix..".cc", + }) + resincludedirs({ + project_root, + }) diff --git a/src/xenia/ui/graphics_context.cc b/src/xenia/ui/graphics_context.cc index 6fff1f7cb..73980cd37 100644 --- a/src/xenia/ui/graphics_context.cc +++ b/src/xenia/ui/graphics_context.cc @@ -20,5 +20,11 @@ GraphicsContext::GraphicsContext(GraphicsProvider* provider, GraphicsContext::~GraphicsContext() = default; +bool GraphicsContext::is_current() { return true; } + +bool GraphicsContext::MakeCurrent() { return true; } + +void GraphicsContext::ClearCurrent() {} + } // namespace ui } // namespace xe diff --git a/src/xenia/ui/graphics_context.h b/src/xenia/ui/graphics_context.h index ef352099f..383338770 100644 --- a/src/xenia/ui/graphics_context.h +++ b/src/xenia/ui/graphics_context.h @@ -41,15 +41,15 @@ class GraphicsContext { virtual ImmediateDrawer* immediate_drawer() = 0; - virtual bool is_current() = 0; - virtual bool MakeCurrent() = 0; - virtual void ClearCurrent() = 0; + virtual bool is_current(); + virtual bool MakeCurrent(); + virtual void ClearCurrent(); // Returns true if the OS took away our context because we caused a TDR or // some other outstanding error. When this happens, this context, as well as // any other shared contexts are junk. // This context must be made current in order for this call to work properly. - virtual bool WasLost() { return false; } + virtual bool WasLost() = 0; virtual void BeginSwap() = 0; virtual void EndSwap() = 0;