[D3D12] Change most subsystem pointers to references

This commit is contained in:
Triang3l 2020-08-30 22:07:35 +03:00
parent c5dd7403f0
commit 1e9ee8f43b
23 changed files with 532 additions and 538 deletions

View File

@ -80,7 +80,7 @@ void D3D12CommandProcessor::InitializeShaderStorage(
void D3D12CommandProcessor::RequestFrameTrace( void D3D12CommandProcessor::RequestFrameTrace(
const std::filesystem::path& root_path) { const std::filesystem::path& root_path) {
// Capture with PIX if attached. // Capture with PIX if attached.
if (GetD3D12Context()->GetD3D12Provider()->GetGraphicsAnalysis() != nullptr) { if (GetD3D12Context().GetD3D12Provider().GetGraphicsAnalysis() != nullptr) {
pix_capture_requested_.store(true, std::memory_order_relaxed); pix_capture_requested_.store(true, std::memory_order_relaxed);
return; return;
} }
@ -377,7 +377,7 @@ ID3D12RootSignature* D3D12CommandProcessor::GetRootSignature(
} }
ID3D12RootSignature* root_signature = ui::d3d12::util::CreateRootSignature( ID3D12RootSignature* root_signature = ui::d3d12::util::CreateRootSignature(
GetD3D12Context()->GetD3D12Provider(), desc); GetD3D12Context().GetD3D12Provider(), desc);
if (root_signature == nullptr) { if (root_signature == nullptr) {
XELOGE( XELOGE(
"Failed to create a root signature with {} pixel textures, {} pixel " "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_, deferred_command_list_->SetDescriptorHeaps(view_bindful_heap_current_,
sampler_bindful_heap_current_); sampler_bindful_heap_current_);
} }
auto provider = GetD3D12Context()->GetD3D12Provider(); auto& provider = GetD3D12Context().GetD3D12Provider();
cpu_handle_out = provider->OffsetViewDescriptor( cpu_handle_out = provider.OffsetViewDescriptor(
view_bindful_heap_pool_->GetLastRequestHeapCPUStart(), descriptor_index); view_bindful_heap_pool_->GetLastRequestHeapCPUStart(), descriptor_index);
gpu_handle_out = provider->OffsetViewDescriptor( gpu_handle_out = provider.OffsetViewDescriptor(
view_bindful_heap_pool_->GetLastRequestHeapGPUStart(), descriptor_index); view_bindful_heap_pool_->GetLastRequestHeapGPUStart(), descriptor_index);
return current_heap_index; return current_heap_index;
} }
@ -482,7 +482,7 @@ bool D3D12CommandProcessor::RequestOneUseSingleViewDescriptors(
return true; return true;
} }
assert_not_null(handles_out); assert_not_null(handles_out);
auto provider = GetD3D12Context()->GetD3D12Provider(); auto& provider = GetD3D12Context().GetD3D12Provider();
if (bindless_resources_used_) { if (bindless_resources_used_) {
// Request separate bindless descriptors that will be freed when this // Request separate bindless descriptors that will be freed when this
// submission is completed by the GPU. // submission is completed by the GPU.
@ -501,9 +501,9 @@ bool D3D12CommandProcessor::RequestOneUseSingleViewDescriptors(
view_bindless_one_use_descriptors_.push_back( view_bindless_one_use_descriptors_.push_back(
std::make_pair(descriptor_index, submission_current_)); std::make_pair(descriptor_index, submission_current_));
handles_out[i] = handles_out[i] =
std::make_pair(provider->OffsetViewDescriptor( std::make_pair(provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, descriptor_index), view_bindless_heap_cpu_start_, descriptor_index),
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_gpu_start_, descriptor_index)); view_bindless_heap_gpu_start_, descriptor_index));
} }
} else { } else {
@ -518,8 +518,8 @@ bool D3D12CommandProcessor::RequestOneUseSingleViewDescriptors(
} }
for (uint32_t i = 0; i < count; ++i) { for (uint32_t i = 0; i < count; ++i) {
handles_out[i] = handles_out[i] =
std::make_pair(provider->OffsetViewDescriptor(cpu_handle_start, i), std::make_pair(provider.OffsetViewDescriptor(cpu_handle_start, i),
provider->OffsetViewDescriptor(gpu_handle_start, i)); provider.OffsetViewDescriptor(gpu_handle_start, i));
} }
} }
return true; return true;
@ -529,10 +529,10 @@ ui::d3d12::util::DescriptorCPUGPUHandlePair
D3D12CommandProcessor::GetSystemBindlessViewHandlePair( D3D12CommandProcessor::GetSystemBindlessViewHandlePair(
SystemBindlessView view) const { SystemBindlessView view) const {
assert_true(bindless_resources_used_); assert_true(bindless_resources_used_);
auto provider = GetD3D12Context()->GetD3D12Provider(); auto& provider = GetD3D12Context().GetD3D12Provider();
return std::make_pair(provider->OffsetViewDescriptor( return std::make_pair(provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, uint32_t(view)), view_bindless_heap_cpu_start_, uint32_t(view)),
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_gpu_start_, uint32_t(view))); view_bindless_heap_gpu_start_, uint32_t(view)));
} }
@ -619,11 +619,11 @@ uint64_t D3D12CommandProcessor::RequestSamplerBindfulDescriptors(
deferred_command_list_->SetDescriptorHeaps(view_bindful_heap_current_, deferred_command_list_->SetDescriptorHeaps(view_bindful_heap_current_,
sampler_bindful_heap_current_); sampler_bindful_heap_current_);
} }
auto provider = GetD3D12Context()->GetD3D12Provider(); auto& provider = GetD3D12Context().GetD3D12Provider();
cpu_handle_out = provider->OffsetSamplerDescriptor( cpu_handle_out = provider.OffsetSamplerDescriptor(
sampler_bindful_heap_pool_->GetLastRequestHeapCPUStart(), sampler_bindful_heap_pool_->GetLastRequestHeapCPUStart(),
descriptor_index); descriptor_index);
gpu_handle_out = provider->OffsetSamplerDescriptor( gpu_handle_out = provider.OffsetSamplerDescriptor(
sampler_bindful_heap_pool_->GetLastRequestHeapGPUStart(), sampler_bindful_heap_pool_->GetLastRequestHeapGPUStart(),
descriptor_index); descriptor_index);
return current_heap_index; return current_heap_index;
@ -646,7 +646,7 @@ ID3D12Resource* D3D12CommandProcessor::RequestScratchGPUBuffer(
size = xe::align(size, kScratchBufferSizeIncrement); size = xe::align(size, kScratchBufferSizeIncrement);
auto device = GetD3D12Context()->GetD3D12Provider()->GetDevice(); auto device = GetD3D12Context().GetD3D12Provider().GetDevice();
D3D12_RESOURCE_DESC buffer_desc; D3D12_RESOURCE_DESC buffer_desc;
ui::d3d12::util::FillBufferResourceDesc( ui::d3d12::util::FillBufferResourceDesc(
buffer_desc, size, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); 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 // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/nf-d3d12-id3d12graphicscommandlist1-setsamplepositions
if (cvars::d3d12_ssaa_custom_sample_positions && !edram_rov_used_ && if (cvars::d3d12_ssaa_custom_sample_positions && !edram_rov_used_ &&
command_list_1_) { command_list_1_) {
auto provider = GetD3D12Context()->GetD3D12Provider(); auto& provider = GetD3D12Context().GetD3D12Provider();
auto tier = provider->GetProgrammableSamplePositionsTier(); auto tier = provider.GetProgrammableSamplePositionsTier();
if (tier >= D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_2) { if (tier >= D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_2) {
// Depth buffer transitions are affected by sample positions. // Depth buffer transitions are affected by sample positions.
SubmitBarriers(); SubmitBarriers();
@ -830,9 +830,9 @@ bool D3D12CommandProcessor::SetupContext() {
return false; return false;
} }
auto provider = GetD3D12Context()->GetD3D12Provider(); auto& provider = GetD3D12Context().GetD3D12Provider();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
auto direct_queue = provider->GetDirectQueue(); auto direct_queue = provider.GetDirectQueue();
submission_open_ = false; submission_open_ = false;
submission_current_ = 1; submission_current_ = 1;
@ -879,13 +879,13 @@ bool D3D12CommandProcessor::SetupContext() {
command_list_->Close(); command_list_->Close();
// Optional - added in Creators Update (SDK 10.0.15063.0). // Optional - added in Creators Update (SDK 10.0.15063.0).
command_list_->QueryInterface(IID_PPV_ARGS(&command_list_1_)); command_list_->QueryInterface(IID_PPV_ARGS(&command_list_1_));
deferred_command_list_ = std::make_unique<DeferredCommandList>(this); deferred_command_list_ = std::make_unique<DeferredCommandList>(*this);
bindless_resources_used_ = bindless_resources_used_ =
cvars::d3d12_bindless && cvars::d3d12_bindless &&
provider->GetResourceBindingTier() >= D3D12_RESOURCE_BINDING_TIER_2; provider.GetResourceBindingTier() >= D3D12_RESOURCE_BINDING_TIER_2;
edram_rov_used_ = edram_rov_used_ =
cvars::d3d12_edram_rov && provider->AreRasterizerOrderedViewsSupported(); cvars::d3d12_edram_rov && provider.AreRasterizerOrderedViewsSupported();
// Initialize resource binding. // Initialize resource binding.
constant_buffer_pool_ = constant_buffer_pool_ =
@ -1145,29 +1145,29 @@ bool D3D12CommandProcessor::SetupContext() {
} }
shared_memory_ = shared_memory_ =
std::make_unique<SharedMemory>(this, memory_, &trace_writer_); std::make_unique<SharedMemory>(*this, *memory_, trace_writer_);
if (!shared_memory_->Initialize()) { if (!shared_memory_->Initialize()) {
XELOGE("Failed to initialize shared memory"); XELOGE("Failed to initialize shared memory");
return false; return false;
} }
texture_cache_ = std::make_unique<TextureCache>( texture_cache_ = std::make_unique<TextureCache>(
this, register_file_, bindless_resources_used_, shared_memory_.get()); *this, *register_file_, bindless_resources_used_, *shared_memory_);
if (!texture_cache_->Initialize(edram_rov_used_)) { if (!texture_cache_->Initialize(edram_rov_used_)) {
XELOGE("Failed to initialize the texture cache"); XELOGE("Failed to initialize the texture cache");
return false; return false;
} }
render_target_cache_ = std::make_unique<RenderTargetCache>( render_target_cache_ = std::make_unique<RenderTargetCache>(
this, register_file_, &trace_writer_, bindless_resources_used_, *this, *register_file_, trace_writer_, bindless_resources_used_,
edram_rov_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"); XELOGE("Failed to initialize the render target cache");
return false; return false;
} }
pipeline_cache_ = std::make_unique<PipelineCache>( pipeline_cache_ = std::make_unique<PipelineCache>(
this, register_file_, bindless_resources_used_, edram_rov_used_, *this, *register_file_, bindless_resources_used_, edram_rov_used_,
texture_cache_->IsResolutionScale2X() ? 2 : 1); texture_cache_->IsResolutionScale2X() ? 2 : 1);
if (!pipeline_cache_->Initialize()) { if (!pipeline_cache_->Initialize()) {
XELOGE("Failed to initialize the graphics pipeline state cache"); XELOGE("Failed to initialize the graphics pipeline state cache");
@ -1175,7 +1175,7 @@ bool D3D12CommandProcessor::SetupContext() {
} }
primitive_converter_ = std::make_unique<PrimitiveConverter>( primitive_converter_ = std::make_unique<PrimitiveConverter>(
this, register_file_, memory_, &trace_writer_); *this, *register_file_, *memory_, trace_writer_);
if (!primitive_converter_->Initialize()) { if (!primitive_converter_->Initialize()) {
XELOGE("Failed to initialize the geometric primitive converter"); XELOGE("Failed to initialize the geometric primitive converter");
return false; return false;
@ -1317,7 +1317,7 @@ bool D3D12CommandProcessor::SetupContext() {
null_srv_desc.Texture2DArray.ResourceMinLODClamp = 0.0f; null_srv_desc.Texture2DArray.ResourceMinLODClamp = 0.0f;
device->CreateShaderResourceView( device->CreateShaderResourceView(
nullptr, &null_srv_desc, nullptr, &null_srv_desc,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kNullTexture2DArray))); uint32_t(SystemBindlessView::kNullTexture2DArray)));
// kNullTexture3D. // kNullTexture3D.
@ -1327,7 +1327,7 @@ bool D3D12CommandProcessor::SetupContext() {
null_srv_desc.Texture3D.ResourceMinLODClamp = 0.0f; null_srv_desc.Texture3D.ResourceMinLODClamp = 0.0f;
device->CreateShaderResourceView( device->CreateShaderResourceView(
nullptr, &null_srv_desc, nullptr, &null_srv_desc,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kNullTexture3D))); uint32_t(SystemBindlessView::kNullTexture3D)));
// kNullTextureCube. // kNullTextureCube.
@ -1337,101 +1337,101 @@ bool D3D12CommandProcessor::SetupContext() {
null_srv_desc.TextureCube.ResourceMinLODClamp = 0.0f; null_srv_desc.TextureCube.ResourceMinLODClamp = 0.0f;
device->CreateShaderResourceView( device->CreateShaderResourceView(
nullptr, &null_srv_desc, nullptr, &null_srv_desc,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kNullTextureCube))); uint32_t(SystemBindlessView::kNullTextureCube)));
// kSharedMemoryRawSRV. // kSharedMemoryRawSRV.
shared_memory_->WriteRawSRVDescriptor(provider->OffsetViewDescriptor( shared_memory_->WriteRawSRVDescriptor(provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kSharedMemoryRawSRV))); uint32_t(SystemBindlessView::kSharedMemoryRawSRV)));
// kSharedMemoryR32UintSRV. // kSharedMemoryR32UintSRV.
shared_memory_->WriteUintPow2SRVDescriptor( shared_memory_->WriteUintPow2SRVDescriptor(
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kSharedMemoryR32UintSRV)), uint32_t(SystemBindlessView::kSharedMemoryR32UintSRV)),
2); 2);
// kSharedMemoryR32G32UintSRV. // kSharedMemoryR32G32UintSRV.
shared_memory_->WriteUintPow2SRVDescriptor( shared_memory_->WriteUintPow2SRVDescriptor(
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kSharedMemoryR32G32UintSRV)), uint32_t(SystemBindlessView::kSharedMemoryR32G32UintSRV)),
3); 3);
// kSharedMemoryR32G32B32A32UintSRV. // kSharedMemoryR32G32B32A32UintSRV.
shared_memory_->WriteUintPow2SRVDescriptor( shared_memory_->WriteUintPow2SRVDescriptor(
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kSharedMemoryR32G32B32A32UintSRV)), uint32_t(SystemBindlessView::kSharedMemoryR32G32B32A32UintSRV)),
4); 4);
// kSharedMemoryRawUAV. // kSharedMemoryRawUAV.
shared_memory_->WriteRawUAVDescriptor(provider->OffsetViewDescriptor( shared_memory_->WriteRawUAVDescriptor(provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kSharedMemoryRawUAV))); uint32_t(SystemBindlessView::kSharedMemoryRawUAV)));
// kSharedMemoryR32UintUAV. // kSharedMemoryR32UintUAV.
shared_memory_->WriteUintPow2UAVDescriptor( shared_memory_->WriteUintPow2UAVDescriptor(
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kSharedMemoryR32UintUAV)), uint32_t(SystemBindlessView::kSharedMemoryR32UintUAV)),
2); 2);
// kSharedMemoryR32G32UintUAV. // kSharedMemoryR32G32UintUAV.
shared_memory_->WriteUintPow2UAVDescriptor( shared_memory_->WriteUintPow2UAVDescriptor(
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kSharedMemoryR32G32UintUAV)), uint32_t(SystemBindlessView::kSharedMemoryR32G32UintUAV)),
3); 3);
// kSharedMemoryR32G32B32A32UintUAV. // kSharedMemoryR32G32B32A32UintUAV.
shared_memory_->WriteUintPow2UAVDescriptor( shared_memory_->WriteUintPow2UAVDescriptor(
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kSharedMemoryR32G32B32A32UintUAV)), uint32_t(SystemBindlessView::kSharedMemoryR32G32B32A32UintUAV)),
4); 4);
// kEdramRawSRV. // kEdramRawSRV.
render_target_cache_->WriteEdramRawSRVDescriptor( render_target_cache_->WriteEdramRawSRVDescriptor(
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kEdramRawSRV))); uint32_t(SystemBindlessView::kEdramRawSRV)));
// kEdramR32UintSRV. // kEdramR32UintSRV.
render_target_cache_->WriteEdramUintPow2SRVDescriptor( render_target_cache_->WriteEdramUintPow2SRVDescriptor(
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kEdramR32UintSRV)), uint32_t(SystemBindlessView::kEdramR32UintSRV)),
2); 2);
// kEdramR32G32UintSRV. // kEdramR32G32UintSRV.
render_target_cache_->WriteEdramUintPow2SRVDescriptor( render_target_cache_->WriteEdramUintPow2SRVDescriptor(
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kEdramR32G32UintSRV)), uint32_t(SystemBindlessView::kEdramR32G32UintSRV)),
3); 3);
// kEdramR32G32B32A32UintSRV. // kEdramR32G32B32A32UintSRV.
render_target_cache_->WriteEdramUintPow2SRVDescriptor( render_target_cache_->WriteEdramUintPow2SRVDescriptor(
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kEdramR32G32B32A32UintSRV)), uint32_t(SystemBindlessView::kEdramR32G32B32A32UintSRV)),
4); 4);
// kEdramRawUAV. // kEdramRawUAV.
render_target_cache_->WriteEdramRawUAVDescriptor( render_target_cache_->WriteEdramRawUAVDescriptor(
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kEdramRawUAV))); uint32_t(SystemBindlessView::kEdramRawUAV)));
// kEdramR32UintUAV. // kEdramR32UintUAV.
render_target_cache_->WriteEdramUintPow2UAVDescriptor( render_target_cache_->WriteEdramUintPow2UAVDescriptor(
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kEdramR32UintUAV)), uint32_t(SystemBindlessView::kEdramR32UintUAV)),
2); 2);
// kEdramR32G32B32A32UintUAV. // kEdramR32G32B32A32UintUAV.
render_target_cache_->WriteEdramUintPow2UAVDescriptor( render_target_cache_->WriteEdramUintPow2UAVDescriptor(
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kEdramR32G32B32A32UintUAV)), uint32_t(SystemBindlessView::kEdramR32G32B32A32UintUAV)),
4); 4);
// kGammaRampNormalSRV. // kGammaRampNormalSRV.
WriteGammaRampSRV(false, WriteGammaRampSRV(false,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kGammaRampNormalSRV))); uint32_t(SystemBindlessView::kGammaRampNormalSRV)));
// kGammaRampPWLSRV. // kGammaRampPWLSRV.
WriteGammaRampSRV(true, WriteGammaRampSRV(true,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_, view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kGammaRampPWLSRV))); 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. // In case the swap command is the only one in the frame.
BeginSubmission(true); 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 // 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 // (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, uint32_t index_count,
IndexBufferInfo* index_buffer_info, IndexBufferInfo* index_buffer_info,
bool major_mode_explicit) { bool major_mode_explicit) {
auto device = GetD3D12Context()->GetD3D12Provider()->GetDevice(); auto device = GetD3D12Context().GetD3D12Provider().GetDevice();
auto& regs = *register_file_; auto& regs = *register_file_;
#if FINE_GRAINED_DRAW_SCOPES #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); pix_capture_requested_.exchange(false, std::memory_order_relaxed);
if (pix_capturing_) { if (pix_capturing_) {
IDXGraphicsAnalysis* graphics_analysis = IDXGraphicsAnalysis* graphics_analysis =
GetD3D12Context()->GetD3D12Provider()->GetGraphicsAnalysis(); GetD3D12Context().GetD3D12Provider().GetGraphicsAnalysis();
if (graphics_analysis != nullptr) { if (graphics_analysis != nullptr) {
graphics_analysis->BeginCapture(); graphics_analysis->BeginCapture();
} }
@ -2535,12 +2535,12 @@ void D3D12CommandProcessor::BeginSubmission(bool is_guest_command) {
} }
bool D3D12CommandProcessor::EndSubmission(bool is_swap) { 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. // Make sure there is a command allocator to write commands to.
if (submission_open_ && !command_allocator_writable_first_) { if (submission_open_ && !command_allocator_writable_first_) {
ID3D12CommandAllocator* command_allocator; ID3D12CommandAllocator* command_allocator;
if (FAILED(provider->GetDevice()->CreateCommandAllocator( if (FAILED(provider.GetDevice()->CreateCommandAllocator(
D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_LIST_TYPE_DIRECT,
IID_PPV_ARGS(&command_allocator)))) { IID_PPV_ARGS(&command_allocator)))) {
XELOGE("Failed to create a command allocator"); XELOGE("Failed to create a command allocator");
@ -2570,7 +2570,7 @@ bool D3D12CommandProcessor::EndSubmission(bool is_swap) {
// destroyed between frames. // destroyed between frames.
SubmitBarriers(); SubmitBarriers();
auto direct_queue = provider->GetDirectQueue(); auto direct_queue = provider.GetDirectQueue();
// Submit the command list. // Submit the command list.
ID3D12CommandAllocator* command_allocator = ID3D12CommandAllocator* command_allocator =
@ -2604,7 +2604,7 @@ bool D3D12CommandProcessor::EndSubmission(bool is_swap) {
if (is_closing_frame) { if (is_closing_frame) {
// Close the capture after submitting. // Close the capture after submitting.
if (pix_capturing_) { if (pix_capturing_) {
IDXGraphicsAnalysis* graphics_analysis = provider->GetGraphicsAnalysis(); IDXGraphicsAnalysis* graphics_analysis = provider.GetGraphicsAnalysis();
if (graphics_analysis != nullptr) { if (graphics_analysis != nullptr) {
graphics_analysis->EndCapture(); graphics_analysis->EndCapture();
} }
@ -2665,7 +2665,7 @@ bool D3D12CommandProcessor::CanEndSubmissionImmediately() const {
void D3D12CommandProcessor::AwaitAllSubmissionsCompletion() { void D3D12CommandProcessor::AwaitAllSubmissionsCompletion() {
// May be called if shutting down without everything set up. // May be called if shutting down without everything set up.
if ((submission_completed_ + 1) >= submission_current_ || if ((submission_completed_ + 1) >= submission_current_ ||
!submission_fence_ || GetD3D12Context()->WasLost()) { !submission_fence_ || GetD3D12Context().WasLost()) {
return; return;
} }
submission_fence_->SetEventOnCompletion(submission_current_ - 1, submission_fence_->SetEventOnCompletion(submission_current_ - 1,
@ -3462,8 +3462,8 @@ void D3D12CommandProcessor::UpdateSystemConstantValues(
bool D3D12CommandProcessor::UpdateBindings( bool D3D12CommandProcessor::UpdateBindings(
const D3D12Shader* vertex_shader, const D3D12Shader* pixel_shader, const D3D12Shader* vertex_shader, const D3D12Shader* pixel_shader,
ID3D12RootSignature* root_signature) { ID3D12RootSignature* root_signature) {
auto provider = GetD3D12Context()->GetD3D12Provider(); auto& provider = GetD3D12Context().GetD3D12Provider();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
auto& regs = *register_file_; auto& regs = *register_file_;
#if FINE_GRAINED_DRAW_SCOPES #if FINE_GRAINED_DRAW_SCOPES
@ -3830,7 +3830,7 @@ bool D3D12CommandProcessor::UpdateBindings(
sampler_index = sampler_bindless_heap_allocated_++; sampler_index = sampler_bindless_heap_allocated_++;
texture_cache_->WriteSampler( texture_cache_->WriteSampler(
sampler_parameters, sampler_parameters,
provider->OffsetSamplerDescriptor( provider.OffsetSamplerDescriptor(
sampler_bindless_heap_cpu_start_, sampler_index)); sampler_bindless_heap_cpu_start_, sampler_index));
texture_cache_bindless_sampler_map_.insert( texture_cache_bindless_sampler_map_.insert(
{sampler_parameters.value, sampler_index}); {sampler_parameters.value, sampler_index});
@ -3862,7 +3862,7 @@ bool D3D12CommandProcessor::UpdateBindings(
sampler_index = sampler_bindless_heap_allocated_++; sampler_index = sampler_bindless_heap_allocated_++;
texture_cache_->WriteSampler( texture_cache_->WriteSampler(
sampler_parameters, sampler_parameters,
provider->OffsetSamplerDescriptor( provider.OffsetSamplerDescriptor(
sampler_bindless_heap_cpu_start_, sampler_index)); sampler_bindless_heap_cpu_start_, sampler_index));
texture_cache_bindless_sampler_map_.insert( texture_cache_bindless_sampler_map_.insert(
{sampler_parameters.value, sampler_index}); {sampler_parameters.value, sampler_index});
@ -3994,7 +3994,7 @@ bool D3D12CommandProcessor::UpdateBindings(
} }
D3D12_CPU_DESCRIPTOR_HANDLE view_cpu_handle; D3D12_CPU_DESCRIPTOR_HANDLE view_cpu_handle;
D3D12_GPU_DESCRIPTOR_HANDLE view_gpu_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( uint64_t view_heap_index = RequestViewBindfulDescriptors(
draw_view_bindful_heap_index_, view_count_partial_update, draw_view_bindful_heap_index_, view_count_partial_update,
view_count_full_update, view_cpu_handle, view_gpu_handle); 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_CPU_DESCRIPTOR_HANDLE sampler_cpu_handle = {};
D3D12_GPU_DESCRIPTOR_HANDLE sampler_gpu_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 = uint64_t sampler_heap_index =
ui::d3d12::DescriptorHeapPool::kHeapIndexInvalid; ui::d3d12::DescriptorHeapPool::kHeapIndexInvalid;
if (sampler_count_vertex != 0 || sampler_count_pixel != 0) { if (sampler_count_vertex != 0 || sampler_count_pixel != 0) {
@ -4286,7 +4286,7 @@ ID3D12Resource* D3D12CommandProcessor::RequestReadbackBuffer(uint32_t size) {
} }
size = xe::align(size, kReadbackBufferSizeIncrement); size = xe::align(size, kReadbackBufferSizeIncrement);
if (size > readback_buffer_size_) { if (size > readback_buffer_size_) {
auto device = GetD3D12Context()->GetD3D12Provider()->GetDevice(); auto device = GetD3D12Context().GetD3D12Provider().GetDevice();
D3D12_RESOURCE_DESC buffer_desc; D3D12_RESOURCE_DESC buffer_desc;
ui::d3d12::util::FillBufferResourceDesc(buffer_desc, size, ui::d3d12::util::FillBufferResourceDesc(buffer_desc, size,
D3D12_RESOURCE_FLAG_NONE); D3D12_RESOURCE_FLAG_NONE);
@ -4308,7 +4308,7 @@ ID3D12Resource* D3D12CommandProcessor::RequestReadbackBuffer(uint32_t size) {
void D3D12CommandProcessor::WriteGammaRampSRV( void D3D12CommandProcessor::WriteGammaRampSRV(
bool is_pwl, D3D12_CPU_DESCRIPTOR_HANDLE handle) const { 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; D3D12_SHADER_RESOURCE_VIEW_DESC desc;
desc.Format = DXGI_FORMAT_R10G10B10A2_UNORM; desc.Format = DXGI_FORMAT_R10G10B10A2_UNORM;
desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D; desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D;

View File

@ -54,14 +54,14 @@ class D3D12CommandProcessor : public CommandProcessor {
void RestoreEdramSnapshot(const void* snapshot) override; void RestoreEdramSnapshot(const void* snapshot) override;
// Needed by everything that owns transient objects. // Needed by everything that owns transient objects.
ui::d3d12::D3D12Context* GetD3D12Context() const { ui::d3d12::D3D12Context& GetD3D12Context() const {
return static_cast<ui::d3d12::D3D12Context*>(context_.get()); return static_cast<ui::d3d12::D3D12Context&>(*context_);
} }
// Returns the deferred drawing command list for the currently open // Returns the deferred drawing command list for the currently open
// submission. // submission.
DeferredCommandList* GetDeferredCommandList() { DeferredCommandList& GetDeferredCommandList() {
return deferred_command_list_.get(); return *deferred_command_list_;
} }
uint64_t GetCurrentSubmission() const { return submission_current_; } uint64_t GetCurrentSubmission() const { return submission_current_; }
@ -93,8 +93,8 @@ class D3D12CommandProcessor : public CommandProcessor {
ID3D12RootSignature* GetRootSignature(const D3D12Shader* vertex_shader, ID3D12RootSignature* GetRootSignature(const D3D12Shader* vertex_shader,
const D3D12Shader* pixel_shader); const D3D12Shader* pixel_shader);
ui::d3d12::UploadBufferPool* GetConstantBufferPool() const { ui::d3d12::UploadBufferPool& GetConstantBufferPool() const {
return constant_buffer_pool_.get(); return *constant_buffer_pool_;
} }
D3D12_CPU_DESCRIPTOR_HANDLE GetViewBindlessHeapCPUStart() const { D3D12_CPU_DESCRIPTOR_HANDLE GetViewBindlessHeapCPUStart() const {

View File

@ -96,7 +96,7 @@ X_STATUS D3D12GraphicsSystem::Setup(cpu::Processor* processor,
stretch_root_desc.Flags = stretch_root_desc.Flags =
D3D12_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS; D3D12_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS;
stretch_root_signature_ = 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) { if (stretch_root_signature_ == nullptr) {
XELOGE("Failed to create the front buffer stretch root signature"); XELOGE("Failed to create the front buffer stretch root signature");
return X_STATUS_UNSUCCESSFUL; return X_STATUS_UNSUCCESSFUL;
@ -123,7 +123,7 @@ X_STATUS D3D12GraphicsSystem::Setup(cpu::Processor* processor,
stretch_root_desc.NumParameters = 3; stretch_root_desc.NumParameters = 3;
stretch_root_desc.pParameters = stretch_root_parameters; stretch_root_desc.pParameters = stretch_root_parameters;
stretch_gamma_root_signature_ = 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) { if (stretch_gamma_root_signature_ == nullptr) {
XELOGE( XELOGE(
"Failed to create the gamma-correcting front buffer stretch root " "Failed to create the gamma-correcting front buffer stretch root "

View File

@ -18,7 +18,7 @@ namespace gpu {
namespace d3d12 { namespace d3d12 {
DeferredCommandList::DeferredCommandList( DeferredCommandList::DeferredCommandList(
D3D12CommandProcessor* command_processor, size_t initial_size) D3D12CommandProcessor& command_processor, size_t initial_size)
: command_processor_(command_processor) { : command_processor_(command_processor) {
command_stream_.reserve(initial_size); command_stream_.reserve(initial_size);
} }
@ -205,7 +205,7 @@ void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list,
} break; } break;
case Command::kSetPipelineStateHandle: { case Command::kSetPipelineStateHandle: {
current_pipeline_state = current_pipeline_state =
command_processor_->GetD3D12PipelineStateByHandle( command_processor_.GetD3D12PipelineStateByHandle(
*reinterpret_cast<void* const*>(stream)); *reinterpret_cast<void* const*>(stream));
if (current_pipeline_state) { if (current_pipeline_state) {
command_list->SetPipelineState(current_pipeline_state); command_list->SetPipelineState(current_pipeline_state);

View File

@ -25,7 +25,7 @@ class D3D12CommandProcessor;
class DeferredCommandList { class DeferredCommandList {
public: public:
DeferredCommandList(D3D12CommandProcessor* command_processor, DeferredCommandList(D3D12CommandProcessor& command_processor,
size_t initial_size = 256 * 1024); size_t initial_size = 256 * 1024);
void Reset(); void Reset();
@ -462,7 +462,7 @@ class DeferredCommandList {
void* WriteCommand(Command command, size_t arguments_size); void* WriteCommand(Command command, size_t arguments_size);
D3D12CommandProcessor* command_processor_; D3D12CommandProcessor& command_processor_;
std::vector<uint8_t> command_stream_; std::vector<uint8_t> command_stream_;
}; };

View File

@ -68,8 +68,8 @@ namespace d3d12 {
#include "xenia/gpu/d3d12/shaders/dxbc/primitive_rectangle_list_gs.h" #include "xenia/gpu/d3d12/shaders/dxbc/primitive_rectangle_list_gs.h"
#include "xenia/gpu/d3d12/shaders/dxbc/tessellation_vs.h" #include "xenia/gpu/d3d12/shaders/dxbc/tessellation_vs.h"
PipelineCache::PipelineCache(D3D12CommandProcessor* command_processor, PipelineCache::PipelineCache(D3D12CommandProcessor& command_processor,
RegisterFile* register_file, const RegisterFile& register_file,
bool bindless_resources_used, bool edram_rov_used, bool bindless_resources_used, bool edram_rov_used,
uint32_t resolution_scale) uint32_t resolution_scale)
: command_processor_(command_processor), : command_processor_(command_processor),
@ -77,11 +77,11 @@ PipelineCache::PipelineCache(D3D12CommandProcessor* command_processor,
bindless_resources_used_(bindless_resources_used), bindless_resources_used_(bindless_resources_used),
edram_rov_used_(edram_rov_used), edram_rov_used_(edram_rov_used),
resolution_scale_(resolution_scale) { resolution_scale_(resolution_scale) {
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
shader_translator_ = std::make_unique<DxbcShaderTranslator>( shader_translator_ = std::make_unique<DxbcShaderTranslator>(
provider->GetAdapterVendorID(), bindless_resources_used_, edram_rov_used_, provider.GetAdapterVendorID(), bindless_resources_used_, edram_rov_used_,
provider->GetGraphicsAnalysis() != nullptr); provider.GetGraphicsAnalysis() != nullptr);
if (edram_rov_used_) { if (edram_rov_used_) {
depth_only_pixel_shader_ = depth_only_pixel_shader_ =
@ -92,27 +92,27 @@ PipelineCache::PipelineCache(D3D12CommandProcessor* command_processor,
PipelineCache::~PipelineCache() { Shutdown(); } PipelineCache::~PipelineCache() { Shutdown(); }
bool PipelineCache::Initialize() { bool PipelineCache::Initialize() {
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
// Initialize the command processor thread DXIL objects. // Initialize the command processor thread DXIL objects.
dxbc_converter_ = nullptr; dxbc_converter_ = nullptr;
dxc_utils_ = nullptr; dxc_utils_ = nullptr;
dxc_compiler_ = nullptr; dxc_compiler_ = nullptr;
if (cvars::d3d12_dxbc_disasm_dxilconv) { if (cvars::d3d12_dxbc_disasm_dxilconv) {
if (FAILED(provider->DxbcConverterCreateInstance( if (FAILED(provider.DxbcConverterCreateInstance(
CLSID_DxbcConverter, IID_PPV_ARGS(&dxbc_converter_)))) { CLSID_DxbcConverter, IID_PPV_ARGS(&dxbc_converter_)))) {
XELOGE( XELOGE(
"Failed to create DxbcConverter, converted DXIL disassembly for " "Failed to create DxbcConverter, converted DXIL disassembly for "
"debugging will be unavailable"); "debugging will be unavailable");
} }
if (FAILED(provider->DxcCreateInstance(CLSID_DxcUtils, if (FAILED(provider.DxcCreateInstance(CLSID_DxcUtils,
IID_PPV_ARGS(&dxc_utils_)))) { IID_PPV_ARGS(&dxc_utils_)))) {
XELOGE( XELOGE(
"Failed to create DxcUtils, converted DXIL disassembly for debugging " "Failed to create DxcUtils, converted DXIL disassembly for debugging "
"will be unavailable"); "will be unavailable");
} }
if (FAILED(provider->DxcCreateInstance(CLSID_DxcCompiler, if (FAILED(provider.DxcCreateInstance(CLSID_DxcCompiler,
IID_PPV_ARGS(&dxc_compiler_)))) { IID_PPV_ARGS(&dxc_compiler_)))) {
XELOGE( XELOGE(
"Failed to create DxcCompiler, converted DXIL disassembly for " "Failed to create DxcCompiler, converted DXIL disassembly for "
"debugging will be unavailable"); "debugging will be unavailable");
@ -216,7 +216,7 @@ void PipelineCache::ClearCache(bool shutting_down) {
COUNT_profile_set("gpu/pipeline_cache/pipeline_states", 0); COUNT_profile_set("gpu/pipeline_cache/pipeline_states", 0);
// Destroy all shaders. // Destroy all shaders.
command_processor_->NotifyShaderBindingsLayoutUIDsInvalidated(); command_processor_.NotifyShaderBindingsLayoutUIDsInvalidated();
if (bindless_resources_used_) { if (bindless_resources_used_) {
bindless_sampler_layout_map_.clear(); bindless_sampler_layout_map_.clear();
bindless_sampler_layouts_.clear(); bindless_sampler_layouts_.clear();
@ -307,10 +307,10 @@ void PipelineCache::InitializeShaderStorage(
std::mutex shaders_failed_to_translate_mutex; std::mutex shaders_failed_to_translate_mutex;
std::vector<D3D12Shader*> shaders_failed_to_translate; std::vector<D3D12Shader*> shaders_failed_to_translate;
auto shader_translation_thread_function = [&]() { auto shader_translation_thread_function = [&]() {
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
DxbcShaderTranslator translator( DxbcShaderTranslator translator(
provider->GetAdapterVendorID(), bindless_resources_used_, provider.GetAdapterVendorID(), bindless_resources_used_,
edram_rov_used_, provider->GetGraphicsAnalysis() != nullptr); edram_rov_used_, provider.GetGraphicsAnalysis() != nullptr);
// If needed and possible, create objects needed for DXIL conversion and // If needed and possible, create objects needed for DXIL conversion and
// disassembly on this thread. // disassembly on this thread.
IDxbcConverter* dxbc_converter = nullptr; IDxbcConverter* dxbc_converter = nullptr;
@ -318,11 +318,11 @@ void PipelineCache::InitializeShaderStorage(
IDxcCompiler* dxc_compiler = nullptr; IDxcCompiler* dxc_compiler = nullptr;
if (cvars::d3d12_dxbc_disasm_dxilconv && dxbc_converter_ && dxc_utils_ && if (cvars::d3d12_dxbc_disasm_dxilconv && dxbc_converter_ && dxc_utils_ &&
dxc_compiler_) { dxc_compiler_) {
provider->DxbcConverterCreateInstance(CLSID_DxbcConverter, provider.DxbcConverterCreateInstance(CLSID_DxbcConverter,
IID_PPV_ARGS(&dxbc_converter)); IID_PPV_ARGS(&dxbc_converter));
provider->DxcCreateInstance(CLSID_DxcUtils, IID_PPV_ARGS(&dxc_utils)); provider.DxcCreateInstance(CLSID_DxcUtils, IID_PPV_ARGS(&dxc_utils));
provider->DxcCreateInstance(CLSID_DxcCompiler, provider.DxcCreateInstance(CLSID_DxcCompiler,
IID_PPV_ARGS(&dxc_compiler)); IID_PPV_ARGS(&dxc_compiler));
} }
for (;;) { for (;;) {
std::pair<ShaderStoredHeader, D3D12Shader*> shader_to_translate; std::pair<ShaderStoredHeader, D3D12Shader*> shader_to_translate;
@ -342,7 +342,7 @@ void PipelineCache::InitializeShaderStorage(
} }
assert_not_null(shader_to_translate.second); assert_not_null(shader_to_translate.second);
if (!TranslateShader( if (!TranslateShader(
translator, shader_to_translate.second, translator, *shader_to_translate.second,
shader_to_translate.first.sq_program_cntl, dxbc_converter, shader_to_translate.first.sq_program_cntl, dxbc_converter,
dxc_utils, dxc_compiler, dxc_utils, dxc_compiler,
shader_to_translate.first.host_vertex_shader_type)) { shader_to_translate.first.host_vertex_shader_type)) {
@ -598,7 +598,7 @@ void PipelineCache::InitializeShaderStorage(
pipeline_runtime_description.pixel_shader = nullptr; pipeline_runtime_description.pixel_shader = nullptr;
} }
pipeline_runtime_description.root_signature = pipeline_runtime_description.root_signature =
command_processor_->GetRootSignature( command_processor_.GetRootSignature(
pipeline_runtime_description.vertex_shader, pipeline_runtime_description.vertex_shader,
pipeline_runtime_description.pixel_shader); pipeline_runtime_description.pixel_shader);
if (!pipeline_runtime_description.root_signature) { 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 // 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 // in the first place). Otherwise games will not be able to locate shaders for
// draws for which the host vertex shader type has changed! // 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<reg::VGT_DRAW_INITIATOR>(); auto vgt_draw_initiator = regs.Get<reg::VGT_DRAW_INITIATOR>();
if (!xenos::IsMajorModeExplicit(vgt_draw_initiator.major_mode, if (!xenos::IsMajorModeExplicit(vgt_draw_initiator.major_mode,
vgt_draw_initiator.prim_type)) { vgt_draw_initiator.prim_type)) {
@ -874,7 +874,7 @@ Shader::HostVertexShaderType PipelineCache::GetHostVertexShaderTypeIfValid()
bool PipelineCache::EnsureShadersTranslated( bool PipelineCache::EnsureShadersTranslated(
D3D12Shader* vertex_shader, D3D12Shader* pixel_shader, D3D12Shader* vertex_shader, D3D12Shader* pixel_shader,
Shader::HostVertexShaderType host_vertex_shader_type) { Shader::HostVertexShaderType host_vertex_shader_type) {
auto& regs = *register_file_; const auto& regs = register_file_;
auto sq_program_cntl = regs.Get<reg::SQ_PROGRAM_CNTL>(); auto sq_program_cntl = regs.Get<reg::SQ_PROGRAM_CNTL>();
// Edge flags are not supported yet (because polygon primitives are not). // 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); assert_false(sq_program_cntl.gen_index_vtx);
if (!vertex_shader->is_translated()) { 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_, dxbc_converter_, dxc_utils_, dxc_compiler_,
host_vertex_shader_type)) { host_vertex_shader_type)) {
XELOGE("Failed to translate the vertex shader!"); XELOGE("Failed to translate the vertex shader!");
@ -904,7 +904,7 @@ bool PipelineCache::EnsureShadersTranslated(
} }
if (pixel_shader != nullptr && !pixel_shader->is_translated()) { 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_)) { dxbc_converter_, dxc_utils_, dxc_compiler_)) {
XELOGE("Failed to translate the pixel shader!"); XELOGE("Failed to translate the pixel shader!");
return false; return false;
@ -1015,21 +1015,21 @@ bool PipelineCache::ConfigurePipeline(
} }
bool PipelineCache::TranslateShader( bool PipelineCache::TranslateShader(
DxbcShaderTranslator& translator, D3D12Shader* shader, DxbcShaderTranslator& translator, D3D12Shader& shader,
reg::SQ_PROGRAM_CNTL cntl, IDxbcConverter* dxbc_converter, reg::SQ_PROGRAM_CNTL cntl, IDxbcConverter* dxbc_converter,
IDxcUtils* dxc_utils, IDxcCompiler* dxc_compiler, IDxcUtils* dxc_utils, IDxcCompiler* dxc_compiler,
Shader::HostVertexShaderType host_vertex_shader_type) { Shader::HostVertexShaderType host_vertex_shader_type) {
// Perform translation. // Perform translation.
// If this fails the shader will be marked as invalid and ignored later. // 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", XELOGE("Shader {:016X} translation failed; marking as ignored",
shader->ucode_data_hash()); shader.ucode_data_hash());
return false; return false;
} }
const char* host_shader_type; const char* host_shader_type;
if (shader->type() == xenos::ShaderType::kVertex) { if (shader.type() == xenos::ShaderType::kVertex) {
switch (shader->host_vertex_shader_type()) { switch (shader.host_vertex_shader_type()) {
case Shader::HostVertexShaderType::kLineDomainCPIndexed: case Shader::HostVertexShaderType::kLineDomainCPIndexed:
host_shader_type = "control-point-indexed line domain"; host_shader_type = "control-point-indexed line domain";
break; break;
@ -1055,8 +1055,8 @@ bool PipelineCache::TranslateShader(
host_shader_type = "pixel"; host_shader_type = "pixel";
} }
XELOGGPU("Generated {} shader ({}b) - hash {:016X}:\n{}\n", host_shader_type, XELOGGPU("Generated {} shader ({}b) - hash {:016X}:\n{}\n", host_shader_type,
shader->ucode_dword_count() * 4, shader->ucode_data_hash(), shader.ucode_dword_count() * 4, shader.ucode_data_hash(),
shader->ucode_disassembly().c_str()); shader.ucode_disassembly().c_str());
// Set up texture and sampler bindings. // Set up texture and sampler bindings.
uint32_t texture_binding_count; uint32_t texture_binding_count;
@ -1065,15 +1065,15 @@ bool PipelineCache::TranslateShader(
uint32_t sampler_binding_count; uint32_t sampler_binding_count;
const DxbcShaderTranslator::SamplerBinding* sampler_bindings = const DxbcShaderTranslator::SamplerBinding* sampler_bindings =
translator.GetSamplerBindings(sampler_binding_count); translator.GetSamplerBindings(sampler_binding_count);
shader->SetTexturesAndSamplers(translator_texture_bindings, shader.SetTexturesAndSamplers(translator_texture_bindings,
texture_binding_count, sampler_bindings, texture_binding_count, sampler_bindings,
sampler_binding_count); sampler_binding_count);
assert_false(bindless_resources_used_ && assert_false(bindless_resources_used_ &&
texture_binding_count + sampler_binding_count > texture_binding_count + sampler_binding_count >
D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * 4); D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * 4);
// Get hashable texture bindings, without translator-specific info. // Get hashable texture bindings, without translator-specific info.
const D3D12Shader::TextureBinding* texture_bindings = const D3D12Shader::TextureBinding* texture_bindings =
shader->GetTextureBindings(texture_binding_count); shader.GetTextureBindings(texture_binding_count);
size_t texture_binding_layout_bytes = size_t texture_binding_layout_bytes =
texture_binding_count * sizeof(*texture_bindings); texture_binding_count * sizeof(*texture_bindings);
uint64_t texture_binding_layout_hash = 0; uint64_t texture_binding_layout_hash = 0;
@ -1184,37 +1184,37 @@ bool PipelineCache::TranslateShader(
} }
} }
} }
shader->SetTextureBindingLayoutUserUID(texture_binding_layout_uid); shader.SetTextureBindingLayoutUserUID(texture_binding_layout_uid);
shader->SetSamplerBindingLayoutUserUID(sampler_binding_layout_uid); shader.SetSamplerBindingLayoutUserUID(sampler_binding_layout_uid);
// Create a version of the shader with early depth/stencil forced by Xenia // 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 // itself when it's safe to do so or when EARLY_Z_ENABLE is set in
// RB_DEPTHCONTROL. // RB_DEPTHCONTROL.
if (shader->type() == xenos::ShaderType::kPixel && !edram_rov_used_ && if (shader.type() == xenos::ShaderType::kPixel && !edram_rov_used_ &&
!shader->writes_depth()) { !shader.writes_depth()) {
shader->SetForcedEarlyZShaderObject( shader.SetForcedEarlyZShaderObject(
std::move(DxbcShaderTranslator::ForceEarlyDepthStencil( std::move(DxbcShaderTranslator::ForceEarlyDepthStencil(
shader->translated_binary().data()))); shader.translated_binary().data())));
} }
// Disassemble the shader for dumping. // Disassemble the shader for dumping.
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
if (cvars::d3d12_dxbc_disasm_dxilconv) { if (cvars::d3d12_dxbc_disasm_dxilconv) {
shader->DisassembleDxbc(*provider, cvars::d3d12_dxbc_disasm, dxbc_converter, shader.DisassembleDxbc(provider, cvars::d3d12_dxbc_disasm, dxbc_converter,
dxc_utils, dxc_compiler); dxc_utils, dxc_compiler);
} else { } else {
shader->DisassembleDxbc(*provider, cvars::d3d12_dxbc_disasm); shader.DisassembleDxbc(provider, cvars::d3d12_dxbc_disasm);
} }
// Dump shader files if desired. // Dump shader files if desired.
if (!cvars::dump_shaders.empty()) { if (!cvars::dump_shaders.empty()) {
shader->Dump(cvars::dump_shaders, shader.Dump(cvars::dump_shaders,
(shader->type() == xenos::ShaderType::kPixel) (shader.type() == xenos::ShaderType::kPixel)
? (edram_rov_used_ ? "d3d12_rov" : "d3d12_rtv") ? (edram_rov_used_ ? "d3d12_rov" : "d3d12_rtv")
: "d3d12"); : "d3d12");
} }
return shader->is_valid(); return shader.is_valid();
} }
bool PipelineCache::GetCurrentStateDescription( bool PipelineCache::GetCurrentStateDescription(
@ -1225,7 +1225,7 @@ bool PipelineCache::GetCurrentStateDescription(
PipelineRuntimeDescription& runtime_description_out) { PipelineRuntimeDescription& runtime_description_out) {
PipelineDescription& description_out = runtime_description_out.description; PipelineDescription& description_out = runtime_description_out.description;
auto& regs = *register_file_; const auto& regs = register_file_;
auto pa_su_sc_mode_cntl = regs.Get<reg::PA_SU_SC_MODE_CNTL>(); auto pa_su_sc_mode_cntl = regs.Get<reg::PA_SU_SC_MODE_CNTL>();
// Initialize all unused fields to zero for comparison/hashing. // Initialize all unused fields to zero for comparison/hashing.
@ -1233,7 +1233,7 @@ bool PipelineCache::GetCurrentStateDescription(
// Root signature. // Root signature.
runtime_description_out.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) { if (runtime_description_out.root_signature == nullptr) {
return false; return false;
} }
@ -1483,7 +1483,7 @@ bool PipelineCache::GetCurrentStateDescription(
// Render targets and blending state. 32 because of 0x1F mask, for safety // Render targets and blending state. 32 because of 0x1F mask, for safety
// (all unknown to zero). // (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] = { static const PipelineBlendFactor kBlendFactorMap[32] = {
/* 0 */ PipelineBlendFactor::kZero, /* 0 */ PipelineBlendFactor::kZero,
/* 1 */ PipelineBlendFactor::kOne, /* 1 */ PipelineBlendFactor::kOne,
@ -1895,7 +1895,7 @@ ID3D12PipelineState* PipelineCache::CreateD3D12PipelineState(
// Create the pipeline state object. // Create the pipeline state object.
auto device = auto device =
command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice();
ID3D12PipelineState* state; ID3D12PipelineState* state;
if (FAILED(device->CreateGraphicsPipelineState(&state_desc, if (FAILED(device->CreateGraphicsPipelineState(&state_desc,
IID_PPV_ARGS(&state)))) { IID_PPV_ARGS(&state)))) {

View File

@ -40,8 +40,8 @@ class PipelineCache {
public: public:
static constexpr size_t kLayoutUIDEmpty = 0; static constexpr size_t kLayoutUIDEmpty = 0;
PipelineCache(D3D12CommandProcessor* command_processor, PipelineCache(D3D12CommandProcessor& command_processor,
RegisterFile* register_file, bool bindless_resources_used, const RegisterFile& register_file, bool bindless_resources_used,
bool edram_rov_used, uint32_t resolution_scale); bool edram_rov_used, uint32_t resolution_scale);
~PipelineCache(); ~PipelineCache();
@ -222,7 +222,7 @@ class PipelineCache {
}; };
// Can be called from multiple threads. // Can be called from multiple threads.
bool TranslateShader(DxbcShaderTranslator& translator, D3D12Shader* shader, bool TranslateShader(DxbcShaderTranslator& translator, D3D12Shader& shader,
reg::SQ_PROGRAM_CNTL cntl, reg::SQ_PROGRAM_CNTL cntl,
IDxbcConverter* dxbc_converter = nullptr, IDxbcConverter* dxbc_converter = nullptr,
IDxcUtils* dxc_utils = nullptr, IDxcUtils* dxc_utils = nullptr,
@ -240,8 +240,8 @@ class PipelineCache {
ID3D12PipelineState* CreateD3D12PipelineState( ID3D12PipelineState* CreateD3D12PipelineState(
const PipelineRuntimeDescription& runtime_description); const PipelineRuntimeDescription& runtime_description);
D3D12CommandProcessor* command_processor_; D3D12CommandProcessor& command_processor_;
RegisterFile* register_file_; const RegisterFile& register_file_;
bool bindless_resources_used_; bool bindless_resources_used_;
bool edram_rov_used_; bool edram_rov_used_;
uint32_t resolution_scale_; uint32_t resolution_scale_;

View File

@ -33,10 +33,10 @@ namespace xe {
namespace gpu { namespace gpu {
namespace d3d12 { namespace d3d12 {
PrimitiveConverter::PrimitiveConverter(D3D12CommandProcessor* command_processor, PrimitiveConverter::PrimitiveConverter(D3D12CommandProcessor& command_processor,
RegisterFile* register_file, const RegisterFile& register_file,
Memory* memory, Memory& memory,
TraceWriter* trace_writer) TraceWriter& trace_writer)
: command_processor_(command_processor), : command_processor_(command_processor),
register_file_(register_file), register_file_(register_file),
memory_(memory), memory_(memory),
@ -48,7 +48,7 @@ PrimitiveConverter::~PrimitiveConverter() { Shutdown(); }
bool PrimitiveConverter::Initialize() { bool PrimitiveConverter::Initialize() {
auto device = 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 // 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 // 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_regions_invalidated_.store(0ull, std::memory_order_relaxed);
memory_invalidation_callback_handle_ = memory_invalidation_callback_handle_ =
memory_->RegisterPhysicalMemoryInvalidationCallback( memory_.RegisterPhysicalMemoryInvalidationCallback(
MemoryInvalidationCallbackThunk, this); MemoryInvalidationCallbackThunk, this);
return true; return true;
@ -127,7 +127,7 @@ bool PrimitiveConverter::Initialize() {
void PrimitiveConverter::Shutdown() { void PrimitiveConverter::Shutdown() {
if (memory_invalidation_callback_handle_ != nullptr) { if (memory_invalidation_callback_handle_ != nullptr) {
memory_->UnregisterPhysicalMemoryInvalidationCallback( memory_.UnregisterPhysicalMemoryInvalidationCallback(
memory_invalidation_callback_handle_); memory_invalidation_callback_handle_);
memory_invalidation_callback_handle_ = nullptr; memory_invalidation_callback_handle_ = nullptr;
} }
@ -139,7 +139,7 @@ void PrimitiveConverter::Shutdown() {
void PrimitiveConverter::ClearCache() { buffer_pool_->ClearCache(); } void PrimitiveConverter::ClearCache() { buffer_pool_->ClearCache(); }
void PrimitiveConverter::CompletedSubmissionUpdated() { void PrimitiveConverter::CompletedSubmissionUpdated() {
if (static_ib_upload_ && command_processor_->GetCompletedSubmission() >= if (static_ib_upload_ && command_processor_.GetCompletedSubmission() >=
static_ib_upload_submission_) { static_ib_upload_submission_) {
// Completely uploaded - release the upload buffer. // Completely uploaded - release the upload buffer.
static_ib_upload_->Release(); static_ib_upload_->Release();
@ -151,17 +151,17 @@ void PrimitiveConverter::BeginSubmission() {
// Got a command list now - upload and transition the static index buffer if // Got a command list now - upload and transition the static index buffer if
// needed. // needed.
if (static_ib_upload_ && static_ib_upload_submission_ == UINT64_MAX) { if (static_ib_upload_ && static_ib_upload_submission_ == UINT64_MAX) {
command_processor_->GetDeferredCommandList()->D3DCopyResource( command_processor_.GetDeferredCommandList().D3DCopyResource(
static_ib_, static_ib_upload_); static_ib_, static_ib_upload_);
command_processor_->PushTransitionBarrier( command_processor_.PushTransitionBarrier(static_ib_,
static_ib_, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_DEST,
D3D12_RESOURCE_STATE_INDEX_BUFFER); D3D12_RESOURCE_STATE_INDEX_BUFFER);
static_ib_upload_submission_ = command_processor_->GetCurrentSubmission(); static_ib_upload_submission_ = command_processor_.GetCurrentSubmission();
} }
} }
void PrimitiveConverter::BeginFrame() { void PrimitiveConverter::BeginFrame() {
buffer_pool_->Reclaim(command_processor_->GetCompletedFrame()); buffer_pool_->Reclaim(command_processor_.GetCompletedFrame());
converted_indices_cache_.clear(); converted_indices_cache_.clear();
memory_regions_used_ = 0; memory_regions_used_ = 0;
} }
@ -189,7 +189,7 @@ PrimitiveConverter::ConversionResult PrimitiveConverter::ConvertPrimitives(
xenos::IndexFormat index_format, xenos::Endian index_endianness, xenos::IndexFormat index_format, xenos::Endian index_endianness,
D3D12_GPU_VIRTUAL_ADDRESS& gpu_address_out, uint32_t& index_count_out) { D3D12_GPU_VIRTUAL_ADDRESS& gpu_address_out, uint32_t& index_count_out) {
bool index_32bit = index_format == xenos::IndexFormat::kInt32; bool index_32bit = index_format == xenos::IndexFormat::kInt32;
auto& regs = *register_file_; const auto& regs = register_file_;
bool reset = regs.Get<reg::PA_SU_SC_MODE_CNTL>().multi_prim_ib_ena; bool reset = regs.Get<reg::PA_SU_SC_MODE_CNTL>().multi_prim_ib_ena;
// Swap the reset index because we will be comparing unswapped values to it. // Swap the reset index because we will be comparing unswapped values to it.
uint32_t reset_index = xenos::GpuSwap( uint32_t reset_index = xenos::GpuSwap(
@ -291,7 +291,7 @@ PrimitiveConverter::ConversionResult PrimitiveConverter::ConvertPrimitives(
const uint32_t* source_32; const uint32_t* source_32;
uintptr_t source_uintptr; 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 // 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). // 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) { if (source_type == xenos::PrimitiveType::kTriangleFan) {
// Triangle fans are not supported by Direct3D 12 at all. // Triangle fans are not supported by Direct3D 12 at all.
conversion_needed = true; conversion_needed = true;
trace_writer_->WriteMemoryRead(address, index_buffer_size); trace_writer_.WriteMemoryRead(address, index_buffer_size);
if (reset) { if (reset) {
uint32_t current_fan_index_count = 0; uint32_t current_fan_index_count = 0;
for (uint32_t i = 0; i < index_count; ++i) { 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 // 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. // vertices from a default heap is faster than from an upload heap.
conversion_needed = false; conversion_needed = false;
trace_writer_->WriteMemoryRead(address, index_buffer_size); trace_writer_.WriteMemoryRead(address, index_buffer_size);
#if XE_ARCH_AMD64 #if XE_ARCH_AMD64
// Will use SIMD to copy 16-byte blocks using _mm_or_si128. // Will use SIMD to copy 16-byte blocks using _mm_or_si128.
simd = true; simd = true;
@ -414,7 +414,7 @@ PrimitiveConverter::ConversionResult PrimitiveConverter::ConvertPrimitives(
#endif // XE_ARCH_AMD64 #endif // XE_ARCH_AMD64
} else if (source_type == xenos::PrimitiveType::kLineLoop) { } else if (source_type == xenos::PrimitiveType::kLineLoop) {
conversion_needed = true; conversion_needed = true;
trace_writer_->WriteMemoryRead(address, index_buffer_size); trace_writer_.WriteMemoryRead(address, index_buffer_size);
if (reset) { if (reset) {
reset_actually_used = false; reset_actually_used = false;
uint32_t current_strip_index_count = 0; uint32_t current_strip_index_count = 0;
@ -441,7 +441,7 @@ PrimitiveConverter::ConversionResult PrimitiveConverter::ConvertPrimitives(
} }
} else if (source_type == xenos::PrimitiveType::kQuadList) { } else if (source_type == xenos::PrimitiveType::kQuadList) {
conversion_needed = true; 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_index_count = (index_count >> 2) * 6;
} }
converted_indices.converted_index_count = converted_index_count; converted_indices.converted_index_count = converted_index_count;
@ -695,8 +695,8 @@ void* PrimitiveConverter::AllocateIndices(
} }
D3D12_GPU_VIRTUAL_ADDRESS gpu_address; D3D12_GPU_VIRTUAL_ADDRESS gpu_address;
uint8_t* mapping = uint8_t* mapping =
buffer_pool_->Request(command_processor_->GetCurrentFrame(), size, buffer_pool_->Request(command_processor_.GetCurrentFrame(), size, nullptr,
nullptr, nullptr, &gpu_address); nullptr, &gpu_address);
if (mapping == nullptr) { if (mapping == nullptr) {
XELOGE("Failed to allocate space for {} converted {}-bit vertex indices", XELOGE("Failed to allocate space for {} converted {}-bit vertex indices",
count, format == xenos::IndexFormat::kInt32 ? 32 : 16); count, format == xenos::IndexFormat::kInt32 ? 32 : 16);

View File

@ -37,9 +37,9 @@ class D3D12CommandProcessor;
// alternative to the geometry shader). // alternative to the geometry shader).
class PrimitiveConverter { class PrimitiveConverter {
public: public:
PrimitiveConverter(D3D12CommandProcessor* command_processor, PrimitiveConverter(D3D12CommandProcessor& command_processor,
RegisterFile* register_file, Memory* memory, const RegisterFile& register_file, Memory& memory,
TraceWriter* trace_writer); TraceWriter& trace_writer);
~PrimitiveConverter(); ~PrimitiveConverter();
bool Initialize(); bool Initialize();
@ -102,10 +102,10 @@ class PrimitiveConverter {
void* context_ptr, uint32_t physical_address_start, uint32_t length, void* context_ptr, uint32_t physical_address_start, uint32_t length,
bool exact_range); bool exact_range);
D3D12CommandProcessor* command_processor_; D3D12CommandProcessor& command_processor_;
RegisterFile* register_file_; const RegisterFile& register_file_;
Memory* memory_; Memory& memory_;
TraceWriter* trace_writer_; TraceWriter& trace_writer_;
std::unique_ptr<ui::d3d12::UploadBufferPool> buffer_pool_ = nullptr; std::unique_ptr<ui::d3d12::UploadBufferPool> buffer_pool_ = nullptr;

View File

@ -113,9 +113,9 @@ const std::pair<const uint8_t*, size_t>
{resolve_full_128bpp_2xres_cs, sizeof(resolve_full_128bpp_2xres_cs)}, {resolve_full_128bpp_2xres_cs, sizeof(resolve_full_128bpp_2xres_cs)},
}; };
RenderTargetCache::RenderTargetCache(D3D12CommandProcessor* command_processor, RenderTargetCache::RenderTargetCache(D3D12CommandProcessor& command_processor,
RegisterFile* register_file, const RegisterFile& register_file,
TraceWriter* trace_writer, TraceWriter& trace_writer,
bool bindless_resources_used, bool bindless_resources_used,
bool edram_rov_used) bool edram_rov_used)
: command_processor_(command_processor), : command_processor_(command_processor),
@ -126,13 +126,13 @@ RenderTargetCache::RenderTargetCache(D3D12CommandProcessor* command_processor,
RenderTargetCache::~RenderTargetCache() { Shutdown(); } RenderTargetCache::~RenderTargetCache() { Shutdown(); }
bool RenderTargetCache::Initialize(const TextureCache* texture_cache) { bool RenderTargetCache::Initialize(const TextureCache& texture_cache) {
// EDRAM buffer size depends on this. // 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_); assert_false(resolution_scale_2x_ && !edram_rov_used_);
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
uint32_t edram_buffer_size = GetEdramBufferSize(); uint32_t edram_buffer_size = GetEdramBufferSize();
@ -176,43 +176,43 @@ bool RenderTargetCache::Initialize(const TextureCache* texture_cache) {
edram_buffer_descriptor_heap_->GetCPUDescriptorHandleForHeapStart(); edram_buffer_descriptor_heap_->GetCPUDescriptorHandleForHeapStart();
ui::d3d12::util::CreateBufferRawSRV( ui::d3d12::util::CreateBufferRawSRV(
device, device,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
edram_buffer_descriptor_heap_start_, edram_buffer_descriptor_heap_start_,
uint32_t(EdramBufferDescriptorIndex::kRawSRV)), uint32_t(EdramBufferDescriptorIndex::kRawSRV)),
edram_buffer_, edram_buffer_size); edram_buffer_, edram_buffer_size);
ui::d3d12::util::CreateBufferTypedSRV( ui::d3d12::util::CreateBufferTypedSRV(
device, device,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
edram_buffer_descriptor_heap_start_, edram_buffer_descriptor_heap_start_,
uint32_t(EdramBufferDescriptorIndex::kR32UintSRV)), uint32_t(EdramBufferDescriptorIndex::kR32UintSRV)),
edram_buffer_, DXGI_FORMAT_R32_UINT, edram_buffer_size >> 2); edram_buffer_, DXGI_FORMAT_R32_UINT, edram_buffer_size >> 2);
ui::d3d12::util::CreateBufferTypedSRV( ui::d3d12::util::CreateBufferTypedSRV(
device, device,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
edram_buffer_descriptor_heap_start_, edram_buffer_descriptor_heap_start_,
uint32_t(EdramBufferDescriptorIndex::kR32G32UintSRV)), uint32_t(EdramBufferDescriptorIndex::kR32G32UintSRV)),
edram_buffer_, DXGI_FORMAT_R32G32_UINT, edram_buffer_size >> 3); edram_buffer_, DXGI_FORMAT_R32G32_UINT, edram_buffer_size >> 3);
ui::d3d12::util::CreateBufferTypedSRV( ui::d3d12::util::CreateBufferTypedSRV(
device, device,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
edram_buffer_descriptor_heap_start_, edram_buffer_descriptor_heap_start_,
uint32_t(EdramBufferDescriptorIndex::kR32G32B32A32UintSRV)), uint32_t(EdramBufferDescriptorIndex::kR32G32B32A32UintSRV)),
edram_buffer_, DXGI_FORMAT_R32G32B32A32_UINT, edram_buffer_size >> 4); edram_buffer_, DXGI_FORMAT_R32G32B32A32_UINT, edram_buffer_size >> 4);
ui::d3d12::util::CreateBufferRawUAV( ui::d3d12::util::CreateBufferRawUAV(
device, device,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
edram_buffer_descriptor_heap_start_, edram_buffer_descriptor_heap_start_,
uint32_t(EdramBufferDescriptorIndex::kRawUAV)), uint32_t(EdramBufferDescriptorIndex::kRawUAV)),
edram_buffer_, edram_buffer_size); edram_buffer_, edram_buffer_size);
ui::d3d12::util::CreateBufferTypedUAV( ui::d3d12::util::CreateBufferTypedUAV(
device, device,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
edram_buffer_descriptor_heap_start_, edram_buffer_descriptor_heap_start_,
uint32_t(EdramBufferDescriptorIndex::kR32UintUAV)), uint32_t(EdramBufferDescriptorIndex::kR32UintUAV)),
edram_buffer_, DXGI_FORMAT_R32_UINT, edram_buffer_size >> 2); edram_buffer_, DXGI_FORMAT_R32_UINT, edram_buffer_size >> 2);
ui::d3d12::util::CreateBufferTypedUAV( ui::d3d12::util::CreateBufferTypedUAV(
device, device,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
edram_buffer_descriptor_heap_start_, edram_buffer_descriptor_heap_start_,
uint32_t(EdramBufferDescriptorIndex::kR32G32B32A32UintUAV)), uint32_t(EdramBufferDescriptorIndex::kR32G32B32A32UintUAV)),
edram_buffer_, DXGI_FORMAT_R32G32B32A32_UINT, edram_buffer_size >> 4); edram_buffer_, DXGI_FORMAT_R32G32B32A32_UINT, edram_buffer_size >> 4);
@ -501,7 +501,7 @@ void RenderTargetCache::ClearCache() {
void RenderTargetCache::CompletedSubmissionUpdated() { void RenderTargetCache::CompletedSubmissionUpdated() {
if (edram_snapshot_restore_pool_) { if (edram_snapshot_restore_pool_) {
edram_snapshot_restore_pool_->Reclaim( 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 // currently or previously used render targets, and it doesn't require a
// bigger size. // bigger size.
auto& regs = *register_file_; const auto& regs = register_file_;
#if FINE_GRAINED_DRAW_SCOPES #if FINE_GRAINED_DRAW_SCOPES
SCOPE_profile_cpu_f("gpu"); SCOPE_profile_cpu_f("gpu");
@ -623,7 +623,7 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) {
uint32_t edram_bases[5]; uint32_t edram_bases[5];
uint32_t formats[5]; uint32_t formats[5];
bool formats_are_64bpp[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) { for (uint32_t i = 0; i < 4; ++i) {
enabled[i] = (color_mask & (0xF << (i * 4))) != 0; enabled[i] = (color_mask & (0xF << (i * 4))) != 0;
auto color_info = regs.Get<reg::RB_COLOR_INFO>( auto color_info = regs.Get<reg::RB_COLOR_INFO>(
@ -871,7 +871,7 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) {
#if 0 #if 0
auto device = auto device =
command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice();
#endif #endif
// Allocate new render targets and add them to the bindings list. // 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; heap_usage[heap_page_first / kHeap4MBPages] += heap_page_count;
// Inform Direct3D that we're reusing the heap for this render target. // Inform Direct3D that we're reusing the heap for this render target.
command_processor_->PushAliasingBarrier( command_processor_.PushAliasingBarrier(nullptr,
nullptr, binding.render_target->resource); binding.render_target->resource);
#else #else
// If multiple render targets have the same format, assign different // If multiple render targets have the same format, assign different
// instance numbers to them. // instance numbers to them.
@ -956,7 +956,7 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) {
if (!edram_rov_used_) { if (!edram_rov_used_) {
// Sample positions when loading depth must match sample positions when // Sample positions when loading depth must match sample positions when
// drawing. // drawing.
command_processor_->SetSamplePositions(current_msaa_samples_); command_processor_.SetSamplePositions(current_msaa_samples_);
sample_positions_set = true; sample_positions_set = true;
// Load the contents of the new render targets from the EDRAM buffer (will // 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], XELOGGPU("RT Color {}: base {}, format {}", i, edram_bases[i],
formats[i]); formats[i]);
command_processor_->PushTransitionBarrier( command_processor_.PushTransitionBarrier(
render_target->resource, render_target->state, render_target->resource, render_target->state,
D3D12_RESOURCE_STATE_RENDER_TARGET); D3D12_RESOURCE_STATE_RENDER_TARGET);
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; current_pipeline_render_targets_[4].guest_render_target = 4;
if (depth_binding.is_bound && depth_render_target != nullptr) { if (depth_binding.is_bound && depth_render_target != nullptr) {
XELOGGPU("RT Depth: base {}, format {}", edram_bases[4], formats[4]); XELOGGPU("RT Depth: base {}, format {}", edram_bases[4], formats[4]);
command_processor_->PushTransitionBarrier( command_processor_.PushTransitionBarrier(
depth_render_target->resource, depth_render_target->state, depth_render_target->resource, depth_render_target->state,
D3D12_RESOURCE_STATE_DEPTH_WRITE); D3D12_RESOURCE_STATE_DEPTH_WRITE);
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 { } else {
current_pipeline_render_targets_[4].format = DXGI_FORMAT_UNKNOWN; current_pipeline_render_targets_[4].format = DXGI_FORMAT_UNKNOWN;
} }
command_processor_->SubmitBarriers(); command_processor_.SubmitBarriers();
apply_to_command_list_ = true; apply_to_command_list_ = true;
} }
} }
@ -1034,7 +1034,7 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) {
if (!edram_rov_used_ && apply_to_command_list_) { if (!edram_rov_used_ && apply_to_command_list_) {
apply_to_command_list_ = false; apply_to_command_list_ = false;
if (!sample_positions_set) { if (!sample_positions_set) {
command_processor_->SetSamplePositions(current_msaa_samples_); command_processor_.SetSamplePositions(current_msaa_samples_);
} }
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handles[4]; D3D12_CPU_DESCRIPTOR_HANDLE rtv_handles[4];
uint32_t rtv_count; uint32_t rtv_count;
@ -1053,7 +1053,7 @@ bool RenderTargetCache::UpdateRenderTargets(const D3D12Shader* pixel_shader) {
current_pipeline_render_targets_[4].format != DXGI_FORMAT_UNKNOWN current_pipeline_render_targets_[4].format != DXGI_FORMAT_UNKNOWN
? &depth_binding.render_target->handle ? &depth_binding.render_target->handle
: nullptr; : nullptr;
command_processor_->GetDeferredCommandList()->D3DOMSetRenderTargets( command_processor_.GetDeferredCommandList().D3DOMSetRenderTargets(
rtv_count, rtv_handles, FALSE, dsv_handle); 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; uint32_t resolution_scale = resolution_scale_2x_ ? 2 : 1;
draw_util::ResolveInfo resolve_info; draw_util::ResolveInfo resolve_info;
if (!draw_util::GetResolveInfo( 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, !edram_rov_used_ && !cvars::d3d12_16bit_rtv_full_range,
resolve_info)) { resolve_info)) {
return false; return false;
@ -1112,7 +1112,7 @@ bool RenderTargetCache::Resolve(const Memory& memory,
ClearBindings(); ClearBindings();
} }
auto command_list = command_processor_->GetDeferredCommandList(); auto& command_list = command_processor_.GetDeferredCommandList();
// Copying. // Copying.
bool copied = false; bool copied = false;
@ -1144,7 +1144,7 @@ bool RenderTargetCache::Resolve(const Memory& memory,
ui::d3d12::util::DescriptorCPUGPUHandlePair descriptor_dest; ui::d3d12::util::DescriptorCPUGPUHandlePair descriptor_dest;
ui::d3d12::util::DescriptorCPUGPUHandlePair descriptor_source; ui::d3d12::util::DescriptorCPUGPUHandlePair descriptor_source;
ui::d3d12::util::DescriptorCPUGPUHandlePair descriptors[2]; ui::d3d12::util::DescriptorCPUGPUHandlePair descriptors[2];
if (command_processor_->RequestOneUseSingleViewDescriptors( if (command_processor_.RequestOneUseSingleViewDescriptors(
bindless_resources_used_ ? (resolution_scale_2x_ ? 1 : 0) : 2, bindless_resources_used_ ? (resolution_scale_2x_ ? 1 : 0) : 2,
descriptors)) { descriptors)) {
if (bindless_resources_used_) { if (bindless_resources_used_) {
@ -1153,16 +1153,16 @@ bool RenderTargetCache::Resolve(const Memory& memory,
} else { } else {
descriptor_dest = descriptor_dest =
command_processor_ command_processor_
->GetSharedMemoryUintPow2BindlessUAVHandlePair( .GetSharedMemoryUintPow2BindlessUAVHandlePair(
copy_shader_info.dest_bpe_log2); copy_shader_info.dest_bpe_log2);
} }
if (copy_shader_info.source_is_raw) { if (copy_shader_info.source_is_raw) {
descriptor_source = descriptor_source =
command_processor_->GetSystemBindlessViewHandlePair( command_processor_.GetSystemBindlessViewHandlePair(
D3D12CommandProcessor::SystemBindlessView::kEdramRawSRV); D3D12CommandProcessor::SystemBindlessView::kEdramRawSRV);
} else { } else {
descriptor_source = descriptor_source =
command_processor_->GetEdramUintPow2BindlessSRVHandlePair( command_processor_.GetEdramUintPow2BindlessSRVHandlePair(
copy_shader_info.source_bpe_log2); copy_shader_info.source_bpe_log2);
} }
} else { } else {
@ -1190,26 +1190,25 @@ bool RenderTargetCache::Resolve(const Memory& memory,
TransitionEdramBuffer(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); TransitionEdramBuffer(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
// Submit the resolve. // Submit the resolve.
command_list->D3DSetComputeRootSignature( command_list.D3DSetComputeRootSignature(resolve_copy_root_signature_);
resolve_copy_root_signature_); command_list.D3DSetComputeRootDescriptorTable(
command_list->D3DSetComputeRootDescriptorTable(
2, descriptor_source.second); 2, descriptor_source.second);
command_list->D3DSetComputeRootDescriptorTable( command_list.D3DSetComputeRootDescriptorTable(1,
1, descriptor_dest.second); descriptor_dest.second);
if (resolution_scale_2x_) { if (resolution_scale_2x_) {
command_list->D3DSetComputeRoot32BitConstants( command_list.D3DSetComputeRoot32BitConstants(
0, 0,
sizeof(copy_shader_constants.dest_relative) / sizeof(uint32_t), sizeof(copy_shader_constants.dest_relative) / sizeof(uint32_t),
&copy_shader_constants.dest_relative, 0); &copy_shader_constants.dest_relative, 0);
} else { } else {
command_list->D3DSetComputeRoot32BitConstants( command_list.D3DSetComputeRoot32BitConstants(
0, sizeof(copy_shader_constants) / sizeof(uint32_t), 0, sizeof(copy_shader_constants) / sizeof(uint32_t),
&copy_shader_constants, 0); &copy_shader_constants, 0);
} }
command_processor_->SetComputePipelineState( command_processor_.SetComputePipelineState(
resolve_copy_pipeline_states_[size_t(copy_shader)]); resolve_copy_pipeline_states_[size_t(copy_shader)]);
command_processor_->SubmitBarriers(); command_processor_.SubmitBarriers();
command_list->D3DDispatch(copy_group_count_x, copy_group_count_y, 1); command_list.D3DDispatch(copy_group_count_x, copy_group_count_y, 1);
// Order the resolve with other work using the destination as a UAV. // Order the resolve with other work using the destination as a UAV.
if (resolution_scale_2x_) { if (resolution_scale_2x_) {
@ -1241,12 +1240,12 @@ bool RenderTargetCache::Resolve(const Memory& memory,
ui::d3d12::util::DescriptorCPUGPUHandlePair descriptor_edram; ui::d3d12::util::DescriptorCPUGPUHandlePair descriptor_edram;
bool descriptor_edram_obtained; bool descriptor_edram_obtained;
if (bindless_resources_used_) { if (bindless_resources_used_) {
descriptor_edram = command_processor_->GetSystemBindlessViewHandlePair( descriptor_edram = command_processor_.GetSystemBindlessViewHandlePair(
D3D12CommandProcessor::SystemBindlessView::kEdramR32G32B32A32UintUAV); D3D12CommandProcessor::SystemBindlessView::kEdramR32G32B32A32UintUAV);
descriptor_edram_obtained = true; descriptor_edram_obtained = true;
} else { } else {
descriptor_edram_obtained = descriptor_edram_obtained =
command_processor_->RequestOneUseSingleViewDescriptors( command_processor_.RequestOneUseSingleViewDescriptors(
1, &descriptor_edram); 1, &descriptor_edram);
if (descriptor_edram_obtained) { if (descriptor_edram_obtained) {
WriteEdramUintPow2UAVDescriptor(descriptor_edram.first, 4); 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 // to copy for some reason, for instance), overlap of the depth and the
// color ranges is highly unlikely. // color ranges is highly unlikely.
CommitEdramBufferUAVWrites(false); CommitEdramBufferUAVWrites(false);
command_list->D3DSetComputeRootSignature(resolve_clear_root_signature_); command_list.D3DSetComputeRootSignature(resolve_clear_root_signature_);
command_list->D3DSetComputeRootDescriptorTable(1, command_list.D3DSetComputeRootDescriptorTable(1, descriptor_edram.second);
descriptor_edram.second);
std::pair<uint32_t, uint32_t> clear_group_count = std::pair<uint32_t, uint32_t> clear_group_count =
resolve_info.GetClearShaderGroupCount(); resolve_info.GetClearShaderGroupCount();
assert_true(clear_group_count.first && clear_group_count.second); 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; draw_util::ResolveClearShaderConstants depth_clear_constants;
resolve_info.GetDepthClearShaderConstants(clear_float32_depth, resolve_info.GetDepthClearShaderConstants(clear_float32_depth,
depth_clear_constants); depth_clear_constants);
command_list->D3DSetComputeRoot32BitConstants( command_list.D3DSetComputeRoot32BitConstants(
0, sizeof(depth_clear_constants) / sizeof(uint32_t), 0, sizeof(depth_clear_constants) / sizeof(uint32_t),
&depth_clear_constants, 0); &depth_clear_constants, 0);
command_processor_->SetComputePipelineState( command_processor_.SetComputePipelineState(
clear_float32_depth ? resolve_clear_depth_24_32_pipeline_state_ clear_float32_depth ? resolve_clear_depth_24_32_pipeline_state_
: resolve_clear_32bpp_pipeline_state_); : resolve_clear_32bpp_pipeline_state_);
command_processor_->SubmitBarriers(); command_processor_.SubmitBarriers();
command_list->D3DDispatch(clear_group_count.first, command_list.D3DDispatch(clear_group_count.first,
clear_group_count.second, 1); clear_group_count.second, 1);
} }
if (clear_color) { if (clear_color) {
draw_util::ResolveClearShaderConstants color_clear_constants; draw_util::ResolveClearShaderConstants color_clear_constants;
resolve_info.GetColorClearShaderConstants(color_clear_constants); resolve_info.GetColorClearShaderConstants(color_clear_constants);
if (clear_depth) { if (clear_depth) {
// Non-RT-specific constants have already been set. // Non-RT-specific constants have already been set.
command_list->D3DSetComputeRoot32BitConstants( command_list.D3DSetComputeRoot32BitConstants(
0, sizeof(color_clear_constants.rt_specific) / sizeof(uint32_t), 0, sizeof(color_clear_constants.rt_specific) / sizeof(uint32_t),
&color_clear_constants.rt_specific, &color_clear_constants.rt_specific,
offsetof(draw_util::ResolveClearShaderConstants, rt_specific) / offsetof(draw_util::ResolveClearShaderConstants, rt_specific) /
sizeof(uint32_t)); sizeof(uint32_t));
} else { } else {
command_list->D3DSetComputeRoot32BitConstants( command_list.D3DSetComputeRoot32BitConstants(
0, sizeof(color_clear_constants) / sizeof(uint32_t), 0, sizeof(color_clear_constants) / sizeof(uint32_t),
&color_clear_constants, 0); &color_clear_constants, 0);
} }
command_processor_->SetComputePipelineState( command_processor_.SetComputePipelineState(
resolve_info.color_edram_info.format_is_64bpp resolve_info.color_edram_info.format_is_64bpp
? resolve_clear_64bpp_pipeline_state_ ? resolve_clear_64bpp_pipeline_state_
: resolve_clear_32bpp_pipeline_state_); : resolve_clear_32bpp_pipeline_state_);
command_processor_->SubmitBarriers(); command_processor_.SubmitBarriers();
command_list->D3DDispatch(clear_group_count.first, command_list.D3DDispatch(clear_group_count.first,
clear_group_count.second, 1); clear_group_count.second, 1);
} }
assert_true(edram_buffer_state_ == D3D12_RESOURCE_STATE_UNORDERED_ACCESS); assert_true(edram_buffer_state_ == D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
edram_buffer_modified_ = true; edram_buffer_modified_ = true;
@ -1328,11 +1326,11 @@ void RenderTargetCache::FlushAndUnbindRenderTargets() {
void RenderTargetCache::WriteEdramRawSRVDescriptor( void RenderTargetCache::WriteEdramRawSRVDescriptor(
D3D12_CPU_DESCRIPTOR_HANDLE handle) { D3D12_CPU_DESCRIPTOR_HANDLE handle) {
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
device->CopyDescriptorsSimple( device->CopyDescriptorsSimple(
1, handle, 1, handle,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
edram_buffer_descriptor_heap_start_, edram_buffer_descriptor_heap_start_,
uint32_t(EdramBufferDescriptorIndex::kRawSRV)), uint32_t(EdramBufferDescriptorIndex::kRawSRV)),
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
@ -1340,11 +1338,11 @@ void RenderTargetCache::WriteEdramRawSRVDescriptor(
void RenderTargetCache::WriteEdramRawUAVDescriptor( void RenderTargetCache::WriteEdramRawUAVDescriptor(
D3D12_CPU_DESCRIPTOR_HANDLE handle) { D3D12_CPU_DESCRIPTOR_HANDLE handle) {
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
device->CopyDescriptorsSimple( device->CopyDescriptorsSimple(
1, handle, 1, handle,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
edram_buffer_descriptor_heap_start_, edram_buffer_descriptor_heap_start_,
uint32_t(EdramBufferDescriptorIndex::kRawUAV)), uint32_t(EdramBufferDescriptorIndex::kRawUAV)),
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
@ -1367,12 +1365,12 @@ void RenderTargetCache::WriteEdramUintPow2SRVDescriptor(
assert_unhandled_case(element_size_bytes_pow2); assert_unhandled_case(element_size_bytes_pow2);
return; return;
} }
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
device->CopyDescriptorsSimple( device->CopyDescriptorsSimple(
1, handle, 1, handle,
provider->OffsetViewDescriptor(edram_buffer_descriptor_heap_start_, provider.OffsetViewDescriptor(edram_buffer_descriptor_heap_start_,
uint32_t(descriptor_index)), uint32_t(descriptor_index)),
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
} }
@ -1391,12 +1389,12 @@ void RenderTargetCache::WriteEdramUintPow2UAVDescriptor(
assert_unhandled_case(element_size_bytes_pow2); assert_unhandled_case(element_size_bytes_pow2);
return; return;
} }
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
device->CopyDescriptorsSimple( device->CopyDescriptorsSimple(
1, handle, 1, handle,
provider->OffsetViewDescriptor(edram_buffer_descriptor_heap_start_, provider.OffsetViewDescriptor(edram_buffer_descriptor_heap_start_,
uint32_t(descriptor_index)), uint32_t(descriptor_index)),
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
} }
@ -1454,7 +1452,7 @@ bool RenderTargetCache::InitializeTraceSubmitDownloads() {
xenos::kEdramSizeBytes, xenos::kEdramSizeBytes,
D3D12_RESOURCE_FLAG_NONE); D3D12_RESOURCE_FLAG_NONE);
auto device = auto device =
command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice();
if (FAILED(device->CreateCommittedResource( if (FAILED(device->CreateCommittedResource(
&ui::d3d12::util::kHeapPropertiesReadback, D3D12_HEAP_FLAG_NONE, &ui::d3d12::util::kHeapPropertiesReadback, D3D12_HEAP_FLAG_NONE,
&edram_snapshot_download_buffer_desc, &edram_snapshot_download_buffer_desc,
@ -1464,11 +1462,11 @@ bool RenderTargetCache::InitializeTraceSubmitDownloads() {
return false; return false;
} }
} }
auto command_list = command_processor_->GetDeferredCommandList(); auto& command_list = command_processor_.GetDeferredCommandList();
TransitionEdramBuffer(D3D12_RESOURCE_STATE_COPY_SOURCE); TransitionEdramBuffer(D3D12_RESOURCE_STATE_COPY_SOURCE);
command_processor_->SubmitBarriers(); command_processor_.SubmitBarriers();
command_list->D3DCopyBufferRegion(edram_snapshot_download_buffer_, 0, command_list.D3DCopyBufferRegion(edram_snapshot_download_buffer_, 0,
edram_buffer_, 0, xenos::kEdramSizeBytes); edram_buffer_, 0, xenos::kEdramSizeBytes);
return true; return true;
} }
@ -1479,7 +1477,7 @@ void RenderTargetCache::InitializeTraceCompleteDownloads() {
void* download_mapping; void* download_mapping;
if (SUCCEEDED(edram_snapshot_download_buffer_->Map(0, nullptr, if (SUCCEEDED(edram_snapshot_download_buffer_->Map(0, nullptr,
&download_mapping))) { &download_mapping))) {
trace_writer_->WriteEdramSnapshot(download_mapping); trace_writer_.WriteEdramSnapshot(download_mapping);
D3D12_RANGE download_write_range = {}; D3D12_RANGE download_write_range = {};
edram_snapshot_download_buffer_->Unmap(0, &download_write_range); edram_snapshot_download_buffer_->Unmap(0, &download_write_range);
} else { } else {
@ -1494,8 +1492,8 @@ void RenderTargetCache::RestoreEdramSnapshot(const void* snapshot) {
// No 1:1 mapping. // No 1:1 mapping.
return; return;
} }
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
if (!edram_snapshot_restore_pool_) { if (!edram_snapshot_restore_pool_) {
edram_snapshot_restore_pool_ = edram_snapshot_restore_pool_ =
std::make_unique<ui::d3d12::UploadBufferPool>(device, std::make_unique<ui::d3d12::UploadBufferPool>(device,
@ -1504,19 +1502,19 @@ void RenderTargetCache::RestoreEdramSnapshot(const void* snapshot) {
ID3D12Resource* upload_buffer; ID3D12Resource* upload_buffer;
uint32_t upload_buffer_offset; uint32_t upload_buffer_offset;
void* upload_buffer_mapping = edram_snapshot_restore_pool_->Request( 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); &upload_buffer, &upload_buffer_offset, nullptr);
if (!upload_buffer_mapping) { if (!upload_buffer_mapping) {
XELOGE("Failed to get a buffer for restoring a EDRAM snapshot"); XELOGE("Failed to get a buffer for restoring a EDRAM snapshot");
return; return;
} }
std::memcpy(upload_buffer_mapping, snapshot, xenos::kEdramSizeBytes); 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); TransitionEdramBuffer(D3D12_RESOURCE_STATE_COPY_DEST);
command_processor_->SubmitBarriers(); command_processor_.SubmitBarriers();
command_list->D3DCopyBufferRegion(edram_buffer_, 0, upload_buffer, command_list.D3DCopyBufferRegion(edram_buffer_, 0, upload_buffer,
upload_buffer_offset, upload_buffer_offset,
xenos::kEdramSizeBytes); xenos::kEdramSizeBytes);
if (!edram_rov_used_) { if (!edram_rov_used_) {
// Clear and ignore the old 32-bit float depth - the non-ROV path is // 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 // 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_) { if (bindless_resources_used_) {
edram_shader_visible_r32_uav_obtained = true; edram_shader_visible_r32_uav_obtained = true;
edram_shader_visible_r32_uav = edram_shader_visible_r32_uav =
command_processor_->GetSystemBindlessViewHandlePair( command_processor_.GetSystemBindlessViewHandlePair(
D3D12CommandProcessor::SystemBindlessView::kEdramR32UintUAV); D3D12CommandProcessor::SystemBindlessView::kEdramR32UintUAV);
} else { } else {
edram_shader_visible_r32_uav_obtained = edram_shader_visible_r32_uav_obtained =
command_processor_->RequestOneUseSingleViewDescriptors( command_processor_.RequestOneUseSingleViewDescriptors(
1, &edram_shader_visible_r32_uav); 1, &edram_shader_visible_r32_uav);
if (edram_shader_visible_r32_uav_obtained) { if (edram_shader_visible_r32_uav_obtained) {
WriteEdramUintPow2UAVDescriptor(edram_shader_visible_r32_uav.first, 2); 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.right = (xenos::kEdramSizeBytes >> 2) << 1;
clear_rect.bottom = 1; clear_rect.bottom = 1;
TransitionEdramBuffer(D3D12_RESOURCE_STATE_UNORDERED_ACCESS); TransitionEdramBuffer(D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
command_processor_->SubmitBarriers(); command_processor_.SubmitBarriers();
// ClearUnorderedAccessView takes a shader-visible GPU descriptor and a // ClearUnorderedAccessView takes a shader-visible GPU descriptor and a
// non-shader-visible CPU descriptor. // non-shader-visible CPU descriptor.
command_list->D3DClearUnorderedAccessViewUint( command_list.D3DClearUnorderedAccessViewUint(
edram_shader_visible_r32_uav.second, edram_shader_visible_r32_uav.second,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
edram_buffer_descriptor_heap_start_, edram_buffer_descriptor_heap_start_,
uint32_t(EdramBufferDescriptorIndex::kR32UintUAV)), uint32_t(EdramBufferDescriptorIndex::kR32UintUAV)),
edram_buffer_, clear_value, 1, &clear_rect); edram_buffer_, clear_value, 1, &clear_rect);
@ -1572,8 +1570,8 @@ uint32_t RenderTargetCache::GetEdramBufferSize() const {
} }
void RenderTargetCache::TransitionEdramBuffer(D3D12_RESOURCE_STATES new_state) { void RenderTargetCache::TransitionEdramBuffer(D3D12_RESOURCE_STATES new_state) {
command_processor_->PushTransitionBarrier(edram_buffer_, edram_buffer_state_, command_processor_.PushTransitionBarrier(edram_buffer_, edram_buffer_state_,
new_state); new_state);
edram_buffer_state_ = new_state; edram_buffer_state_ = new_state;
if (new_state != D3D12_RESOURCE_STATE_UNORDERED_ACCESS) { if (new_state != D3D12_RESOURCE_STATE_UNORDERED_ACCESS) {
edram_buffer_modified_ = false; edram_buffer_modified_ = false;
@ -1583,7 +1581,7 @@ void RenderTargetCache::TransitionEdramBuffer(D3D12_RESOURCE_STATES new_state) {
void RenderTargetCache::CommitEdramBufferUAVWrites(bool force) { void RenderTargetCache::CommitEdramBufferUAVWrites(bool force) {
if ((edram_buffer_modified_ || force) && if ((edram_buffer_modified_ || force) &&
edram_buffer_state_ == D3D12_RESOURCE_STATE_UNORDERED_ACCESS) { edram_buffer_state_ == D3D12_RESOURCE_STATE_UNORDERED_ACCESS) {
command_processor_->PushUAVBarrier(edram_buffer_); command_processor_.PushUAVBarrier(edram_buffer_);
} }
edram_buffer_modified_ = false; edram_buffer_modified_ = false;
} }
@ -1606,7 +1604,7 @@ bool RenderTargetCache::MakeHeapResident(uint32_t heap_index) {
return true; return true;
} }
auto device = auto device =
command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice();
D3D12_HEAP_DESC heap_desc = {}; D3D12_HEAP_DESC heap_desc = {};
heap_desc.SizeInBytes = kHeap4MBPages << 22; heap_desc.SizeInBytes = kHeap4MBPages << 22;
heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT; heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT;
@ -1630,7 +1628,7 @@ bool RenderTargetCache::EnsureRTVHeapAvailable(bool is_depth) {
return true; return true;
} }
auto device = auto device =
command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice();
D3D12_DESCRIPTOR_HEAP_DESC heap_desc; D3D12_DESCRIPTOR_HEAP_DESC heap_desc;
heap_desc.Type = is_depth ? D3D12_DESCRIPTOR_HEAP_TYPE_DSV heap_desc.Type = is_depth ? D3D12_DESCRIPTOR_HEAP_TYPE_DSV
: D3D12_DESCRIPTOR_HEAP_TYPE_RTV; : D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
@ -1712,8 +1710,8 @@ RenderTargetCache::RenderTarget* RenderTargetCache::FindOrCreateRenderTarget(
return nullptr; return nullptr;
} }
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
#if 0 #if 0
// Get the number of heap pages needed for the render target. // 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. // Create the descriptor for the render target.
D3D12_CPU_DESCRIPTOR_HANDLE descriptor_handle; D3D12_CPU_DESCRIPTOR_HANDLE descriptor_handle;
if (key.is_depth) { if (key.is_depth) {
descriptor_handle = provider->OffsetDSVDescriptor( descriptor_handle =
descriptor_heaps_depth_->start_handle, provider.OffsetDSVDescriptor(descriptor_heaps_depth_->start_handle,
descriptor_heaps_depth_->descriptors_used); descriptor_heaps_depth_->descriptors_used);
D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc; D3D12_DEPTH_STENCIL_VIEW_DESC dsv_desc;
dsv_desc.Format = resource_desc.Format; dsv_desc.Format = resource_desc.Format;
dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; dsv_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
@ -1783,9 +1781,9 @@ RenderTargetCache::RenderTarget* RenderTargetCache::FindOrCreateRenderTarget(
device->CreateDepthStencilView(resource, &dsv_desc, descriptor_handle); device->CreateDepthStencilView(resource, &dsv_desc, descriptor_handle);
++descriptor_heaps_depth_->descriptors_used; ++descriptor_heaps_depth_->descriptors_used;
} else { } else {
descriptor_handle = provider->OffsetRTVDescriptor( descriptor_handle =
descriptor_heaps_color_->start_handle, provider.OffsetRTVDescriptor(descriptor_heaps_color_->start_handle,
descriptor_heaps_color_->descriptors_used); descriptor_heaps_color_->descriptors_used);
D3D12_RENDER_TARGET_VIEW_DESC rtv_desc; D3D12_RENDER_TARGET_VIEW_DESC rtv_desc;
rtv_desc.Format = resource_desc.Format; rtv_desc.Format = resource_desc.Format;
rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
@ -1854,7 +1852,7 @@ void RenderTargetCache::StoreRenderTargetsToEdram() {
return; 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 // Extract only the render targets that need to be stored, transition them to
// copy sources and calculate copy buffer size. // 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_edram;
ui::d3d12::util::DescriptorCPUGPUHandlePair descriptor_source; ui::d3d12::util::DescriptorCPUGPUHandlePair descriptor_source;
if (bindless_resources_used_) { if (bindless_resources_used_) {
if (!command_processor_->RequestOneUseSingleViewDescriptors( if (!command_processor_.RequestOneUseSingleViewDescriptors(
1, &descriptor_source)) { 1, &descriptor_source)) {
return; return;
} }
descriptor_edram = command_processor_->GetSystemBindlessViewHandlePair( descriptor_edram = command_processor_.GetSystemBindlessViewHandlePair(
D3D12CommandProcessor::SystemBindlessView::kEdramRawUAV); D3D12CommandProcessor::SystemBindlessView::kEdramRawUAV);
} else { } else {
ui::d3d12::util::DescriptorCPUGPUHandlePair descriptors[2]; ui::d3d12::util::DescriptorCPUGPUHandlePair descriptors[2];
if (!command_processor_->RequestOneUseSingleViewDescriptors(2, if (!command_processor_.RequestOneUseSingleViewDescriptors(2,
descriptors)) { descriptors)) {
return; return;
} }
descriptor_edram = descriptors[0]; descriptor_edram = descriptors[0];
@ -1899,7 +1897,7 @@ void RenderTargetCache::StoreRenderTargetsToEdram() {
// Get the buffer for copying. // Get the buffer for copying.
D3D12_RESOURCE_STATES copy_buffer_state = D3D12_RESOURCE_STATE_COPY_DEST; 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); copy_buffer_size, copy_buffer_state);
if (copy_buffer == nullptr) { if (copy_buffer == nullptr) {
return; return;
@ -1910,21 +1908,21 @@ void RenderTargetCache::StoreRenderTargetsToEdram() {
for (uint32_t i = 0; i < store_binding_count; ++i) { for (uint32_t i = 0; i < store_binding_count; ++i) {
RenderTarget* render_target = RenderTarget* render_target =
current_bindings_[store_bindings[i]].render_target; current_bindings_[store_bindings[i]].render_target;
command_processor_->PushTransitionBarrier(render_target->resource, command_processor_.PushTransitionBarrier(render_target->resource,
render_target->state, render_target->state,
D3D12_RESOURCE_STATE_COPY_SOURCE); D3D12_RESOURCE_STATE_COPY_SOURCE);
render_target->state = D3D12_RESOURCE_STATE_COPY_SOURCE; render_target->state = D3D12_RESOURCE_STATE_COPY_SOURCE;
} }
TransitionEdramBuffer(D3D12_RESOURCE_STATE_UNORDERED_ACCESS); TransitionEdramBuffer(D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
// Set up the bindings. // Set up the bindings.
auto device = auto device =
command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice();
command_list->D3DSetComputeRootSignature(edram_load_store_root_signature_); command_list.D3DSetComputeRootSignature(edram_load_store_root_signature_);
ui::d3d12::util::CreateBufferRawSRV(device, descriptor_source.first, ui::d3d12::util::CreateBufferRawSRV(device, descriptor_source.first,
copy_buffer, copy_buffer_size); copy_buffer, copy_buffer_size);
command_list->D3DSetComputeRootDescriptorTable(2, descriptor_source.second); command_list.D3DSetComputeRootDescriptorTable(2, descriptor_source.second);
command_list->D3DSetComputeRootDescriptorTable(1, descriptor_edram.second); command_list.D3DSetComputeRootDescriptorTable(1, descriptor_edram.second);
// Sort the bindings in ascending order of EDRAM base so data in the render // 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. // targets placed farther in EDRAM isn't lost in case of overlap.
@ -1959,10 +1957,10 @@ void RenderTargetCache::StoreRenderTargetsToEdram() {
bool is_64bpp = false; bool is_64bpp = false;
// Transition the copy buffer to copy destination. // Transition the copy buffer to copy destination.
command_processor_->PushTransitionBarrier(copy_buffer, copy_buffer_state, command_processor_.PushTransitionBarrier(copy_buffer, copy_buffer_state,
D3D12_RESOURCE_STATE_COPY_DEST); D3D12_RESOURCE_STATE_COPY_DEST);
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. // Copy from the render target planes and set up the layout.
D3D12_TEXTURE_COPY_LOCATION location_source, location_dest; 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.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
location_dest.PlacedFootprint = render_target->footprints[0]; location_dest.PlacedFootprint = render_target->footprints[0];
// TODO(Triang3l): Box for color render targets. // TODO(Triang3l): Box for color render targets.
command_list->CopyTexture(location_dest, location_source); command_list.CopyTexture(location_dest, location_source);
EdramLoadStoreRootConstants root_constants; EdramLoadStoreRootConstants root_constants;
uint32_t rt_pitch_tiles = surface_pitch_tiles; uint32_t rt_pitch_tiles = surface_pitch_tiles;
if (!render_target->key.is_depth && if (!render_target->key.is_depth &&
@ -1992,7 +1990,7 @@ void RenderTargetCache::StoreRenderTargetsToEdram() {
root_constants.base_samples_2x_depth_pitch |= 1 << 15; root_constants.base_samples_2x_depth_pitch |= 1 << 15;
location_source.SubresourceIndex = 1; location_source.SubresourceIndex = 1;
location_dest.PlacedFootprint = render_target->footprints[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 = root_constants.rt_stencil_offset =
uint32_t(location_dest.PlacedFootprint.Offset); uint32_t(location_dest.PlacedFootprint.Offset);
root_constants.rt_stencil_pitch = root_constants.rt_stencil_pitch =
@ -2000,27 +1998,27 @@ void RenderTargetCache::StoreRenderTargetsToEdram() {
} }
// Transition the copy buffer to SRV. // Transition the copy buffer to SRV.
command_processor_->PushTransitionBarrier( command_processor_.PushTransitionBarrier(
copy_buffer, copy_buffer_state, copy_buffer, copy_buffer_state,
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
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. // Store the data.
command_list->D3DSetComputeRoot32BitConstants( command_list.D3DSetComputeRoot32BitConstants(
0, sizeof(root_constants) / sizeof(uint32_t), &root_constants, 0); 0, sizeof(root_constants) / sizeof(uint32_t), &root_constants, 0);
EdramLoadStoreMode mode = GetLoadStoreMode(render_target->key.is_depth, EdramLoadStoreMode mode = GetLoadStoreMode(render_target->key.is_depth,
render_target->key.format); render_target->key.format);
command_processor_->SetComputePipelineState( command_processor_.SetComputePipelineState(
edram_store_pipelines_[size_t(mode)]); edram_store_pipelines_[size_t(mode)]);
// 1 group per 80x16 samples. // 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. // Commit the UAV write.
CommitEdramBufferUAVWrites(true); CommitEdramBufferUAVWrites(true);
} }
command_processor_->ReleaseScratchGPUBuffer(copy_buffer, copy_buffer_state); command_processor_.ReleaseScratchGPUBuffer(copy_buffer, copy_buffer_state);
} }
void RenderTargetCache::LoadRenderTargetsFromEdram( void RenderTargetCache::LoadRenderTargetsFromEdram(
@ -2031,21 +2029,21 @@ void RenderTargetCache::LoadRenderTargetsFromEdram(
return; return;
} }
auto command_list = command_processor_->GetDeferredCommandList(); auto& command_list = command_processor_.GetDeferredCommandList();
// Allocate descriptors for the buffers. // Allocate descriptors for the buffers.
ui::d3d12::util::DescriptorCPUGPUHandlePair descriptor_dest, descriptor_edram; ui::d3d12::util::DescriptorCPUGPUHandlePair descriptor_dest, descriptor_edram;
if (bindless_resources_used_) { if (bindless_resources_used_) {
if (!command_processor_->RequestOneUseSingleViewDescriptors( if (!command_processor_.RequestOneUseSingleViewDescriptors(
1, &descriptor_dest)) { 1, &descriptor_dest)) {
return; return;
} }
descriptor_edram = command_processor_->GetSystemBindlessViewHandlePair( descriptor_edram = command_processor_.GetSystemBindlessViewHandlePair(
D3D12CommandProcessor::SystemBindlessView::kEdramRawSRV); D3D12CommandProcessor::SystemBindlessView::kEdramRawSRV);
} else { } else {
ui::d3d12::util::DescriptorCPUGPUHandlePair descriptors[2]; ui::d3d12::util::DescriptorCPUGPUHandlePair descriptors[2];
if (!command_processor_->RequestOneUseSingleViewDescriptors(2, if (!command_processor_.RequestOneUseSingleViewDescriptors(2,
descriptors)) { descriptors)) {
return; return;
} }
descriptor_dest = descriptors[0]; descriptor_dest = descriptors[0];
@ -2061,7 +2059,7 @@ void RenderTargetCache::LoadRenderTargetsFromEdram(
} }
D3D12_RESOURCE_STATES copy_buffer_state = D3D12_RESOURCE_STATES copy_buffer_state =
D3D12_RESOURCE_STATE_UNORDERED_ACCESS; D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
ID3D12Resource* copy_buffer = command_processor_->RequestScratchGPUBuffer( ID3D12Resource* copy_buffer = command_processor_.RequestScratchGPUBuffer(
copy_buffer_size, copy_buffer_state); copy_buffer_size, copy_buffer_state);
if (copy_buffer == nullptr) { if (copy_buffer == nullptr) {
return; return;
@ -2071,21 +2069,21 @@ void RenderTargetCache::LoadRenderTargetsFromEdram(
// a SRV. // a SRV.
for (uint32_t i = 0; i < render_target_count; ++i) { for (uint32_t i = 0; i < render_target_count; ++i) {
RenderTarget* render_target = render_targets[i]; RenderTarget* render_target = render_targets[i];
command_processor_->PushTransitionBarrier(render_target->resource, command_processor_.PushTransitionBarrier(render_target->resource,
render_target->state, render_target->state,
D3D12_RESOURCE_STATE_COPY_DEST); D3D12_RESOURCE_STATE_COPY_DEST);
render_target->state = D3D12_RESOURCE_STATE_COPY_DEST; render_target->state = D3D12_RESOURCE_STATE_COPY_DEST;
} }
TransitionEdramBuffer(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); TransitionEdramBuffer(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
// Set up the bindings. // Set up the bindings.
auto device = auto device =
command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice();
command_list->D3DSetComputeRootSignature(edram_load_store_root_signature_); command_list.D3DSetComputeRootSignature(edram_load_store_root_signature_);
command_list->D3DSetComputeRootDescriptorTable(2, descriptor_edram.second); command_list.D3DSetComputeRootDescriptorTable(2, descriptor_edram.second);
ui::d3d12::util::CreateBufferRawUAV(device, descriptor_dest.first, ui::d3d12::util::CreateBufferRawUAV(device, descriptor_dest.first,
copy_buffer, copy_buffer_size); copy_buffer, copy_buffer_size);
command_list->D3DSetComputeRootDescriptorTable(1, descriptor_dest.second); command_list.D3DSetComputeRootDescriptorTable(1, descriptor_dest.second);
// Load each render target. // Load each render target.
for (uint32_t i = 0; i < render_target_count; ++i) { 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. // 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, copy_buffer_state, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
copy_buffer_state = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; copy_buffer_state = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
// Load the data. // Load the data.
command_processor_->SubmitBarriers(); command_processor_.SubmitBarriers();
EdramLoadStoreRootConstants root_constants; EdramLoadStoreRootConstants root_constants;
// TODO(Triang3l): log2(sample count, resolution scale). // TODO(Triang3l): log2(sample count, resolution scale).
root_constants.base_samples_2x_depth_pitch = root_constants.base_samples_2x_depth_pitch =
@ -2132,24 +2130,23 @@ void RenderTargetCache::LoadRenderTargetsFromEdram(
root_constants.rt_stencil_pitch = root_constants.rt_stencil_pitch =
render_target->footprints[1].Footprint.RowPitch; render_target->footprints[1].Footprint.RowPitch;
} }
command_list->D3DSetComputeRoot32BitConstants( command_list.D3DSetComputeRoot32BitConstants(
0, sizeof(root_constants) / sizeof(uint32_t), &root_constants, 0); 0, sizeof(root_constants) / sizeof(uint32_t), &root_constants, 0);
EdramLoadStoreMode mode = GetLoadStoreMode(render_target->key.is_depth, EdramLoadStoreMode mode = GetLoadStoreMode(render_target->key.is_depth,
render_target->key.format); render_target->key.format);
command_processor_->SetComputePipelineState( command_processor_.SetComputePipelineState(
edram_load_pipelines_[size_t(mode)]); edram_load_pipelines_[size_t(mode)]);
// 1 group per 80x16 samples. // 1 group per 80x16 samples.
command_list->D3DDispatch(render_target->key.width_ss_div_80, edram_rows, command_list.D3DDispatch(render_target->key.width_ss_div_80, edram_rows, 1);
1);
// Commit the UAV write and transition the copy buffer to copy source now. // Commit the UAV write and transition the copy buffer to copy source now.
command_processor_->PushUAVBarrier(copy_buffer); command_processor_.PushUAVBarrier(copy_buffer);
command_processor_->PushTransitionBarrier(copy_buffer, copy_buffer_state, command_processor_.PushTransitionBarrier(copy_buffer, copy_buffer_state,
D3D12_RESOURCE_STATE_COPY_SOURCE); D3D12_RESOURCE_STATE_COPY_SOURCE);
copy_buffer_state = D3D12_RESOURCE_STATE_COPY_SOURCE; copy_buffer_state = D3D12_RESOURCE_STATE_COPY_SOURCE;
// Copy to the render target planes. // Copy to the render target planes.
command_processor_->SubmitBarriers(); command_processor_.SubmitBarriers();
D3D12_TEXTURE_COPY_LOCATION location_source, location_dest; D3D12_TEXTURE_COPY_LOCATION location_source, location_dest;
location_source.pResource = copy_buffer; location_source.pResource = copy_buffer;
location_source.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; location_source.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
@ -2157,15 +2154,15 @@ void RenderTargetCache::LoadRenderTargetsFromEdram(
location_dest.pResource = render_target->resource; location_dest.pResource = render_target->resource;
location_dest.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; location_dest.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
location_dest.SubresourceIndex = 0; location_dest.SubresourceIndex = 0;
command_list->CopyTexture(location_dest, location_source); command_list.CopyTexture(location_dest, location_source);
if (render_target->key.is_depth) { if (render_target->key.is_depth) {
location_source.PlacedFootprint = render_target->footprints[1]; location_source.PlacedFootprint = render_target->footprints[1];
location_dest.SubresourceIndex = 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 } // namespace d3d12

View File

@ -250,12 +250,13 @@ class RenderTargetCache {
DXGI_FORMAT format; DXGI_FORMAT format;
}; };
RenderTargetCache(D3D12CommandProcessor* command_processor, RenderTargetCache(D3D12CommandProcessor& command_processor,
RegisterFile* register_file, TraceWriter* trace_writer, const RegisterFile& register_file,
bool bindless_resources_used, bool edram_rov_used); TraceWriter& trace_writer, bool bindless_resources_used,
bool edram_rov_used);
~RenderTargetCache(); ~RenderTargetCache();
bool Initialize(const TextureCache* texture_cache); bool Initialize(const TextureCache& texture_cache);
void Shutdown(); void Shutdown();
void ClearCache(); void ClearCache();
@ -483,9 +484,9 @@ class RenderTargetCache {
DXGI_FORMAT format); DXGI_FORMAT format);
#endif #endif
D3D12CommandProcessor* command_processor_; D3D12CommandProcessor& command_processor_;
RegisterFile* register_file_; const RegisterFile& register_file_;
TraceWriter* trace_writer_; TraceWriter& trace_writer_;
bool bindless_resources_used_; bool bindless_resources_used_;
bool edram_rov_used_; bool edram_rov_used_;

View File

@ -34,8 +34,8 @@ namespace xe {
namespace gpu { namespace gpu {
namespace d3d12 { namespace d3d12 {
SharedMemory::SharedMemory(D3D12CommandProcessor* command_processor, SharedMemory::SharedMemory(D3D12CommandProcessor& command_processor,
Memory* memory, TraceWriter* trace_writer) Memory& memory, TraceWriter& trace_writer)
: command_processor_(command_processor), : command_processor_(command_processor),
memory_(memory), memory_(memory),
trace_writer_(trace_writer) { trace_writer_(trace_writer) {
@ -46,8 +46,8 @@ SharedMemory::SharedMemory(D3D12CommandProcessor* command_processor,
SharedMemory::~SharedMemory() { Shutdown(); } SharedMemory::~SharedMemory() { Shutdown(); }
bool SharedMemory::Initialize() { bool SharedMemory::Initialize() {
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
D3D12_RESOURCE_DESC buffer_desc; D3D12_RESOURCE_DESC buffer_desc;
ui::d3d12::util::FillBufferResourceDesc( ui::d3d12::util::FillBufferResourceDesc(
@ -65,7 +65,7 @@ bool SharedMemory::Initialize() {
"Direct3D 12 tiled resources are not used for shared memory " "Direct3D 12 tiled resources are not used for shared memory "
"emulation - video memory usage may increase significantly " "emulation - video memory usage may increase significantly "
"because a full 512 MB buffer will be created!"); "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. // As of October 8th, 2018, PIX doesn't support tiled buffers.
// FIXME(Triang3l): Re-enable tiled resources with PIX once fixed. // FIXME(Triang3l): Re-enable tiled resources with PIX once fixed.
XELOGGPU( XELOGGPU(
@ -104,47 +104,47 @@ bool SharedMemory::Initialize() {
buffer_descriptor_heap_->GetCPUDescriptorHandleForHeapStart(); buffer_descriptor_heap_->GetCPUDescriptorHandleForHeapStart();
ui::d3d12::util::CreateBufferRawSRV( ui::d3d12::util::CreateBufferRawSRV(
device, device,
provider->OffsetViewDescriptor(buffer_descriptor_heap_start_, provider.OffsetViewDescriptor(buffer_descriptor_heap_start_,
uint32_t(BufferDescriptorIndex::kRawSRV)), uint32_t(BufferDescriptorIndex::kRawSRV)),
buffer_, kBufferSize); buffer_, kBufferSize);
ui::d3d12::util::CreateBufferTypedSRV( ui::d3d12::util::CreateBufferTypedSRV(
device, device,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
buffer_descriptor_heap_start_, buffer_descriptor_heap_start_,
uint32_t(BufferDescriptorIndex::kR32UintSRV)), uint32_t(BufferDescriptorIndex::kR32UintSRV)),
buffer_, DXGI_FORMAT_R32_UINT, kBufferSize >> 2); buffer_, DXGI_FORMAT_R32_UINT, kBufferSize >> 2);
ui::d3d12::util::CreateBufferTypedSRV( ui::d3d12::util::CreateBufferTypedSRV(
device, device,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
buffer_descriptor_heap_start_, buffer_descriptor_heap_start_,
uint32_t(BufferDescriptorIndex::kR32G32UintSRV)), uint32_t(BufferDescriptorIndex::kR32G32UintSRV)),
buffer_, DXGI_FORMAT_R32G32_UINT, kBufferSize >> 3); buffer_, DXGI_FORMAT_R32G32_UINT, kBufferSize >> 3);
ui::d3d12::util::CreateBufferTypedSRV( ui::d3d12::util::CreateBufferTypedSRV(
device, device,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
buffer_descriptor_heap_start_, buffer_descriptor_heap_start_,
uint32_t(BufferDescriptorIndex::kR32G32B32A32UintSRV)), uint32_t(BufferDescriptorIndex::kR32G32B32A32UintSRV)),
buffer_, DXGI_FORMAT_R32G32B32A32_UINT, kBufferSize >> 4); buffer_, DXGI_FORMAT_R32G32B32A32_UINT, kBufferSize >> 4);
ui::d3d12::util::CreateBufferRawUAV( ui::d3d12::util::CreateBufferRawUAV(
device, device,
provider->OffsetViewDescriptor(buffer_descriptor_heap_start_, provider.OffsetViewDescriptor(buffer_descriptor_heap_start_,
uint32_t(BufferDescriptorIndex::kRawUAV)), uint32_t(BufferDescriptorIndex::kRawUAV)),
buffer_, kBufferSize); buffer_, kBufferSize);
ui::d3d12::util::CreateBufferTypedUAV( ui::d3d12::util::CreateBufferTypedUAV(
device, device,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
buffer_descriptor_heap_start_, buffer_descriptor_heap_start_,
uint32_t(BufferDescriptorIndex::kR32UintUAV)), uint32_t(BufferDescriptorIndex::kR32UintUAV)),
buffer_, DXGI_FORMAT_R32_UINT, kBufferSize >> 2); buffer_, DXGI_FORMAT_R32_UINT, kBufferSize >> 2);
ui::d3d12::util::CreateBufferTypedUAV( ui::d3d12::util::CreateBufferTypedUAV(
device, device,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
buffer_descriptor_heap_start_, buffer_descriptor_heap_start_,
uint32_t(BufferDescriptorIndex::kR32G32UintUAV)), uint32_t(BufferDescriptorIndex::kR32G32UintUAV)),
buffer_, DXGI_FORMAT_R32G32_UINT, kBufferSize >> 3); buffer_, DXGI_FORMAT_R32G32_UINT, kBufferSize >> 3);
ui::d3d12::util::CreateBufferTypedUAV( ui::d3d12::util::CreateBufferTypedUAV(
device, device,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
buffer_descriptor_heap_start_, buffer_descriptor_heap_start_,
uint32_t(BufferDescriptorIndex::kR32G32B32A32UintUAV)), uint32_t(BufferDescriptorIndex::kR32G32B32A32UintUAV)),
buffer_, DXGI_FORMAT_R32G32B32A32_UINT, kBufferSize >> 4); 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_)); xe::align(uint32_t(4 * 1024 * 1024), uint32_t(1) << page_size_log2_));
memory_invalidation_callback_handle_ = memory_invalidation_callback_handle_ =
memory_->RegisterPhysicalMemoryInvalidationCallback( memory_.RegisterPhysicalMemoryInvalidationCallback(
MemoryInvalidationCallbackThunk, this); MemoryInvalidationCallbackThunk, this);
ResetTraceGPUWrittenBuffer(); ResetTraceGPUWrittenBuffer();
@ -186,7 +186,7 @@ void SharedMemory::Shutdown() {
watch_range_pools_.clear(); watch_range_pools_.clear();
if (memory_invalidation_callback_handle_ != nullptr) { if (memory_invalidation_callback_handle_ != nullptr) {
memory_->UnregisterPhysicalMemoryInvalidationCallback( memory_.UnregisterPhysicalMemoryInvalidationCallback(
memory_invalidation_callback_handle_); memory_invalidation_callback_handle_);
memory_invalidation_callback_handle_ = nullptr; memory_invalidation_callback_handle_ = nullptr;
} }
@ -238,7 +238,7 @@ void SharedMemory::ClearCache() {
} }
void SharedMemory::CompletedSubmissionUpdated() { void SharedMemory::CompletedSubmissionUpdated() {
upload_buffer_pool_->Reclaim(command_processor_->GetCompletedSubmission()); upload_buffer_pool_->Reclaim(command_processor_.GetCompletedSubmission());
} }
SharedMemory::GlobalWatchHandle SharedMemory::RegisterGlobalWatch( SharedMemory::GlobalWatchHandle SharedMemory::RegisterGlobalWatch(
@ -364,9 +364,9 @@ bool SharedMemory::EnsureTilesResident(uint32_t start, uint32_t length) {
if (heaps_[i] != nullptr) { if (heaps_[i] != nullptr) {
continue; continue;
} }
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
auto direct_queue = provider->GetDirectQueue(); auto direct_queue = provider.GetDirectQueue();
D3D12_HEAP_DESC heap_desc = {}; D3D12_HEAP_DESC heap_desc = {};
heap_desc.SizeInBytes = kHeapSize; heap_desc.SizeInBytes = kHeapSize;
heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT; 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; uint32_t last = start + length - 1;
auto command_list = command_processor_->GetDeferredCommandList(); auto& command_list = command_processor_.GetDeferredCommandList();
#if FINE_GRAINED_DRAW_SCOPES #if FINE_GRAINED_DRAW_SCOPES
SCOPE_profile_cpu_f("gpu"); SCOPE_profile_cpu_f("gpu");
@ -429,17 +429,17 @@ bool SharedMemory::RequestRange(uint32_t start, uint32_t length) {
return true; return true;
} }
CommitUAVWritesAndTransitionBuffer(D3D12_RESOURCE_STATE_COPY_DEST); CommitUAVWritesAndTransitionBuffer(D3D12_RESOURCE_STATE_COPY_DEST);
command_processor_->SubmitBarriers(); command_processor_.SubmitBarriers();
for (auto upload_range : upload_ranges_) { for (auto upload_range : upload_ranges_) {
uint32_t upload_range_start = upload_range.first; uint32_t upload_range_start = upload_range.first;
uint32_t upload_range_length = upload_range.second; uint32_t upload_range_length = upload_range.second;
trace_writer_->WriteMemoryRead(upload_range_start << page_size_log2_, trace_writer_.WriteMemoryRead(upload_range_start << page_size_log2_,
upload_range_length << page_size_log2_); upload_range_length << page_size_log2_);
while (upload_range_length != 0) { while (upload_range_length != 0) {
ID3D12Resource* upload_buffer; ID3D12Resource* upload_buffer;
uint32_t upload_buffer_offset, upload_buffer_size; uint32_t upload_buffer_offset, upload_buffer_size;
uint8_t* upload_buffer_mapping = upload_buffer_pool_->RequestPartial( uint8_t* upload_buffer_mapping = upload_buffer_pool_->RequestPartial(
command_processor_->GetCurrentSubmission(), command_processor_.GetCurrentSubmission(),
upload_range_length << page_size_log2_, &upload_buffer, upload_range_length << page_size_log2_, &upload_buffer,
&upload_buffer_offset, &upload_buffer_size, nullptr); &upload_buffer_offset, &upload_buffer_size, nullptr);
if (upload_buffer_mapping == 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); upload_buffer_pages << page_size_log2_, false);
std::memcpy( std::memcpy(
upload_buffer_mapping, upload_buffer_mapping,
memory_->TranslatePhysical(upload_range_start << page_size_log2_), memory_.TranslatePhysical(upload_range_start << page_size_log2_),
upload_buffer_size); upload_buffer_size);
command_list->D3DCopyBufferRegion( command_list.D3DCopyBufferRegion(
buffer_, upload_range_start << page_size_log2_, upload_buffer, buffer_, upload_range_start << page_size_log2_, upload_buffer,
upload_buffer_offset, upload_buffer_size); upload_buffer_offset, upload_buffer_size);
upload_range_start += upload_buffer_pages; upload_range_start += upload_buffer_pages;
@ -519,12 +519,12 @@ bool SharedMemory::AreTiledResourcesUsed() const {
if (!cvars::d3d12_tiled_shared_memory) { if (!cvars::d3d12_tiled_shared_memory) {
return false; 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. // As of October 8th, 2018, PIX doesn't support tiled buffers.
// FIXME(Triang3l): Re-enable tiled resources with PIX once fixed. // FIXME(Triang3l): Re-enable tiled resources with PIX once fixed.
return provider->GetTiledResourcesTier() != return provider.GetTiledResourcesTier() !=
D3D12_TILED_RESOURCES_TIER_NOT_SUPPORTED && D3D12_TILED_RESOURCES_TIER_NOT_SUPPORTED &&
provider->GetGraphicsAnalysis() == nullptr; provider.GetGraphicsAnalysis() == nullptr;
} }
void SharedMemory::MakeRangeValid(uint32_t start, uint32_t length, 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_) { if (memory_invalidation_callback_handle_) {
memory_->EnablePhysicalMemoryAccessCallbacks( memory_.EnablePhysicalMemoryAccessCallbacks(
valid_page_first << page_size_log2_, valid_page_first << page_size_log2_,
(valid_page_last - valid_page_first + 1) << page_size_log2_, true, (valid_page_last - valid_page_first + 1) << page_size_log2_, true,
false); false);
@ -718,34 +718,34 @@ void SharedMemory::CommitUAVWritesAndTransitionBuffer(
if (buffer_state_ == new_state) { if (buffer_state_ == new_state) {
if (new_state == D3D12_RESOURCE_STATE_UNORDERED_ACCESS && if (new_state == D3D12_RESOURCE_STATE_UNORDERED_ACCESS &&
buffer_uav_writes_commit_needed_) { buffer_uav_writes_commit_needed_) {
command_processor_->PushUAVBarrier(buffer_); command_processor_.PushUAVBarrier(buffer_);
buffer_uav_writes_commit_needed_ = false; buffer_uav_writes_commit_needed_ = false;
} }
return; return;
} }
command_processor_->PushTransitionBarrier(buffer_, buffer_state_, new_state); command_processor_.PushTransitionBarrier(buffer_, buffer_state_, new_state);
buffer_state_ = new_state; buffer_state_ = new_state;
// "UAV -> anything" transition commits the writes implicitly. // "UAV -> anything" transition commits the writes implicitly.
buffer_uav_writes_commit_needed_ = false; buffer_uav_writes_commit_needed_ = false;
} }
void SharedMemory::WriteRawSRVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle) { void SharedMemory::WriteRawSRVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle) {
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
device->CopyDescriptorsSimple( device->CopyDescriptorsSimple(
1, handle, 1, handle,
provider->OffsetViewDescriptor(buffer_descriptor_heap_start_, provider.OffsetViewDescriptor(buffer_descriptor_heap_start_,
uint32_t(BufferDescriptorIndex::kRawSRV)), uint32_t(BufferDescriptorIndex::kRawSRV)),
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
} }
void SharedMemory::WriteRawUAVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle) { void SharedMemory::WriteRawUAVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle) {
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
device->CopyDescriptorsSimple( device->CopyDescriptorsSimple(
1, handle, 1, handle,
provider->OffsetViewDescriptor(buffer_descriptor_heap_start_, provider.OffsetViewDescriptor(buffer_descriptor_heap_start_,
uint32_t(BufferDescriptorIndex::kRawUAV)), uint32_t(BufferDescriptorIndex::kRawUAV)),
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
} }
@ -766,12 +766,12 @@ void SharedMemory::WriteUintPow2SRVDescriptor(
assert_unhandled_case(element_size_bytes_pow2); assert_unhandled_case(element_size_bytes_pow2);
return; return;
} }
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
device->CopyDescriptorsSimple( device->CopyDescriptorsSimple(
1, handle, 1, handle,
provider->OffsetViewDescriptor(buffer_descriptor_heap_start_, provider.OffsetViewDescriptor(buffer_descriptor_heap_start_,
uint32_t(descriptor_index)), uint32_t(descriptor_index)),
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
} }
@ -792,12 +792,12 @@ void SharedMemory::WriteUintPow2UAVDescriptor(
assert_unhandled_case(element_size_bytes_pow2); assert_unhandled_case(element_size_bytes_pow2);
return; return;
} }
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
device->CopyDescriptorsSimple( device->CopyDescriptorsSimple(
1, handle, 1, handle,
provider->OffsetViewDescriptor(buffer_descriptor_heap_start_, provider.OffsetViewDescriptor(buffer_descriptor_heap_start_,
uint32_t(descriptor_index)), uint32_t(descriptor_index)),
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); 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_, gpu_written_buffer_desc, gpu_written_page_count << page_size_log2_,
D3D12_RESOURCE_FLAG_NONE); D3D12_RESOURCE_FLAG_NONE);
auto device = auto device =
command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice();
if (FAILED(device->CreateCommittedResource( if (FAILED(device->CreateCommittedResource(
&ui::d3d12::util::kHeapPropertiesReadback, D3D12_HEAP_FLAG_NONE, &ui::d3d12::util::kHeapPropertiesReadback, D3D12_HEAP_FLAG_NONE,
&gpu_written_buffer_desc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, &gpu_written_buffer_desc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr,
@ -903,9 +903,9 @@ bool SharedMemory::InitializeTraceSubmitDownloads() {
ResetTraceGPUWrittenBuffer(); ResetTraceGPUWrittenBuffer();
return false; return false;
} }
auto command_list = command_processor_->GetDeferredCommandList(); auto& command_list = command_processor_.GetDeferredCommandList();
UseAsCopySource(); UseAsCopySource();
command_processor_->SubmitBarriers(); command_processor_.SubmitBarriers();
uint32_t gpu_written_buffer_offset = 0; uint32_t gpu_written_buffer_offset = 0;
for (auto& gpu_written_submit_range : trace_gpu_written_ranges_) { for (auto& gpu_written_submit_range : trace_gpu_written_ranges_) {
// For cases like resolution scale, when the data may not be actually // 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; gpu_written_submit_range.second = 0;
continue; continue;
} }
command_list->D3DCopyBufferRegion( command_list.D3DCopyBufferRegion(
trace_gpu_written_buffer_, gpu_written_buffer_offset, buffer_, trace_gpu_written_buffer_, gpu_written_buffer_offset, buffer_,
gpu_written_submit_range.first, gpu_written_submit_range.second); gpu_written_submit_range.first, gpu_written_submit_range.second);
gpu_written_buffer_offset += 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))) { trace_gpu_written_buffer_->Map(0, nullptr, &download_mapping))) {
uint32_t gpu_written_buffer_offset = 0; uint32_t gpu_written_buffer_offset = 0;
for (auto gpu_written_submit_range : trace_gpu_written_ranges_) { 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, gpu_written_submit_range.first, gpu_written_submit_range.second,
reinterpret_cast<const uint8_t*>(download_mapping) + reinterpret_cast<const uint8_t*>(download_mapping) +
gpu_written_buffer_offset); gpu_written_buffer_offset);

View File

@ -31,8 +31,8 @@ class D3D12CommandProcessor;
// system page size granularity. // system page size granularity.
class SharedMemory { class SharedMemory {
public: public:
SharedMemory(D3D12CommandProcessor* command_processor, Memory* memory, SharedMemory(D3D12CommandProcessor& command_processor, Memory& memory,
TraceWriter* trace_writer); TraceWriter& trace_writer);
~SharedMemory(); ~SharedMemory();
bool Initialize(); bool Initialize();
@ -153,9 +153,9 @@ class SharedMemory {
// Mark the memory range as updated and protect it. // Mark the memory range as updated and protect it.
void MakeRangeValid(uint32_t start, uint32_t length, bool written_by_gpu); void MakeRangeValid(uint32_t start, uint32_t length, bool written_by_gpu);
D3D12CommandProcessor* command_processor_; D3D12CommandProcessor& command_processor_;
Memory* memory_; Memory& memory_;
TraceWriter* trace_writer_; TraceWriter& trace_writer_;
// The 512 MB tiled buffer. // The 512 MB tiled buffer.
static constexpr uint32_t kBufferSizeLog2 = 29; static constexpr uint32_t kBufferSizeLog2 = 29;

View File

@ -829,10 +829,10 @@ const TextureCache::LoadModeInfo TextureCache::load_mode_info_[] = {
4}, 4},
}; };
TextureCache::TextureCache(D3D12CommandProcessor* command_processor, TextureCache::TextureCache(D3D12CommandProcessor& command_processor,
RegisterFile* register_file, const RegisterFile& register_file,
bool bindless_resources_used, bool bindless_resources_used,
SharedMemory* shared_memory) SharedMemory& shared_memory)
: command_processor_(command_processor), : command_processor_(command_processor),
register_file_(register_file), register_file_(register_file),
bindless_resources_used_(bindless_resources_used), bindless_resources_used_(bindless_resources_used),
@ -841,15 +841,15 @@ TextureCache::TextureCache(D3D12CommandProcessor* command_processor,
TextureCache::~TextureCache() { Shutdown(); } TextureCache::~TextureCache() { Shutdown(); }
bool TextureCache::Initialize(bool edram_rov_used) { bool TextureCache::Initialize(bool edram_rov_used) {
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
// Try to create the tiled buffer 2x resolution scaling. // Try to create the tiled buffer 2x resolution scaling.
// Not currently supported with the RTV/DSV output path for various reasons. // Not currently supported with the RTV/DSV output path for various reasons.
if (cvars::d3d12_resolution_scale >= 2 && edram_rov_used && if (cvars::d3d12_resolution_scale >= 2 && edram_rov_used &&
provider->GetTiledResourcesTier() != provider.GetTiledResourcesTier() !=
D3D12_TILED_RESOURCES_TIER_NOT_SUPPORTED && D3D12_TILED_RESOURCES_TIER_NOT_SUPPORTED &&
provider->GetVirtualAddressBitsPerResource() >= provider.GetVirtualAddressBitsPerResource() >=
kScaledResolveBufferSizeLog2) { kScaledResolveBufferSizeLog2) {
D3D12_RESOURCE_DESC scaled_resolve_buffer_desc; D3D12_RESOURCE_DESC scaled_resolve_buffer_desc;
ui::d3d12::util::FillBufferResourceDesc( ui::d3d12::util::FillBufferResourceDesc(
@ -983,7 +983,7 @@ bool TextureCache::Initialize(bool edram_rov_used) {
null_srv_desc.Texture2DArray.ResourceMinLODClamp = 0.0f; null_srv_desc.Texture2DArray.ResourceMinLODClamp = 0.0f;
device->CreateShaderResourceView( device->CreateShaderResourceView(
nullptr, &null_srv_desc, nullptr, &null_srv_desc,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
null_srv_descriptor_heap_start_, null_srv_descriptor_heap_start_,
uint32_t(NullSRVDescriptorIndex::k2DArray))); uint32_t(NullSRVDescriptorIndex::k2DArray)));
null_srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D; 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; null_srv_desc.Texture3D.ResourceMinLODClamp = 0.0f;
device->CreateShaderResourceView( device->CreateShaderResourceView(
nullptr, &null_srv_desc, nullptr, &null_srv_desc,
provider->OffsetViewDescriptor(null_srv_descriptor_heap_start_, provider.OffsetViewDescriptor(null_srv_descriptor_heap_start_,
uint32_t(NullSRVDescriptorIndex::k3D))); uint32_t(NullSRVDescriptorIndex::k3D)));
null_srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE; null_srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
null_srv_desc.TextureCube.MostDetailedMip = 0; null_srv_desc.TextureCube.MostDetailedMip = 0;
null_srv_desc.TextureCube.MipLevels = 1; null_srv_desc.TextureCube.MipLevels = 1;
null_srv_desc.TextureCube.ResourceMinLODClamp = 0.0f; null_srv_desc.TextureCube.ResourceMinLODClamp = 0.0f;
device->CreateShaderResourceView( device->CreateShaderResourceView(
nullptr, &null_srv_desc, nullptr, &null_srv_desc,
provider->OffsetViewDescriptor(null_srv_descriptor_heap_start_, provider.OffsetViewDescriptor(null_srv_descriptor_heap_start_,
uint32_t(NullSRVDescriptorIndex::kCube))); uint32_t(NullSRVDescriptorIndex::kCube)));
if (IsResolutionScale2X()) { if (IsResolutionScale2X()) {
scaled_resolve_global_watch_handle_ = shared_memory_->RegisterGlobalWatch( scaled_resolve_global_watch_handle_ = shared_memory_.RegisterGlobalWatch(
ScaledResolveGlobalWatchCallbackThunk, this); ScaledResolveGlobalWatchCallbackThunk, this);
} }
@ -1017,7 +1017,7 @@ void TextureCache::Shutdown() {
ClearCache(); ClearCache();
if (scaled_resolve_global_watch_handle_ != nullptr) { 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; scaled_resolve_global_watch_handle_ = nullptr;
} }
@ -1046,13 +1046,13 @@ void TextureCache::ClearCache() {
// Destroy all the textures. // Destroy all the textures.
for (auto texture_pair : textures_) { for (auto texture_pair : textures_) {
Texture* texture = texture_pair.second; Texture* texture = texture_pair.second;
shared_memory_->UnwatchMemoryRange(texture->base_watch_handle); shared_memory_.UnwatchMemoryRange(texture->base_watch_handle);
shared_memory_->UnwatchMemoryRange(texture->mip_watch_handle); shared_memory_.UnwatchMemoryRange(texture->mip_watch_handle);
// Bindful descriptor cache will be cleared entirely now, so only release // Bindful descriptor cache will be cleared entirely now, so only release
// bindless descriptors. // bindless descriptors.
if (bindless_resources_used_) { if (bindless_resources_used_) {
for (auto descriptor_pair : texture->srv_descriptors) { for (auto descriptor_pair : texture->srv_descriptors) {
command_processor_->ReleaseViewBindlessDescriptorImmediately( command_processor_.ReleaseViewBindlessDescriptorImmediately(
descriptor_pair.second); descriptor_pair.second);
} }
} }
@ -1090,7 +1090,7 @@ void TextureCache::BeginFrame() {
texture_current_usage_time_ = xe::Clock::QueryHostUptimeMillis(); texture_current_usage_time_ = xe::Clock::QueryHostUptimeMillis();
// If memory usage is too high, destroy unused textures. // 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_soft_mb = cvars::d3d12_texture_cache_limit_soft;
uint32_t limit_hard_mb = cvars::d3d12_texture_cache_limit_hard; uint32_t limit_hard_mb = cvars::d3d12_texture_cache_limit_hard;
if (IsResolutionScale2X()) { if (IsResolutionScale2X()) {
@ -1134,11 +1134,11 @@ void TextureCache::BeginFrame() {
// Exclude the texture from the memory usage counter. // Exclude the texture from the memory usage counter.
textures_total_size_ -= texture->resource_size; textures_total_size_ -= texture->resource_size;
// Destroy the texture. // Destroy the texture.
shared_memory_->UnwatchMemoryRange(texture->base_watch_handle); shared_memory_.UnwatchMemoryRange(texture->base_watch_handle);
shared_memory_->UnwatchMemoryRange(texture->mip_watch_handle); shared_memory_.UnwatchMemoryRange(texture->mip_watch_handle);
if (bindless_resources_used_) { if (bindless_resources_used_) {
for (auto descriptor_pair : texture->srv_descriptors) { for (auto descriptor_pair : texture->srv_descriptors) {
command_processor_->ReleaseViewBindlessDescriptorImmediately( command_processor_.ReleaseViewBindlessDescriptorImmediately(
descriptor_pair.second); descriptor_pair.second);
} }
} else { } else {
@ -1177,7 +1177,7 @@ void TextureCache::EndFrame() {
} }
void TextureCache::RequestTextures(uint32_t used_texture_mask) { void TextureCache::RequestTextures(uint32_t used_texture_mask) {
auto& regs = *register_file_; const auto& regs = register_file_;
#if FINE_GRAINED_DRAW_SCOPES #if FINE_GRAINED_DRAW_SCOPES
SCOPE_profile_cpu_f("gpu"); SCOPE_profile_cpu_f("gpu");
@ -1315,7 +1315,7 @@ void TextureCache::RequestTextures(uint32_t used_texture_mask) {
if (binding.texture != nullptr) { if (binding.texture != nullptr) {
// Will be referenced by the command list, so mark as used. // Will be referenced by the command list, so mark as used.
MarkTextureUsed(binding.texture); MarkTextureUsed(binding.texture);
command_processor_->PushTransitionBarrier( command_processor_.PushTransitionBarrier(
binding.texture->resource, binding.texture->state, binding.texture->resource, binding.texture->state,
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE |
D3D12_RESOURCE_STATE_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) { if (binding.texture_signed != nullptr) {
MarkTextureUsed(binding.texture_signed); MarkTextureUsed(binding.texture_signed);
command_processor_->PushTransitionBarrier( command_processor_.PushTransitionBarrier(
binding.texture_signed->resource, binding.texture_signed->state, binding.texture_signed->resource, binding.texture_signed->state,
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE |
D3D12_RESOURCE_STATE_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; D3D12_CPU_DESCRIPTOR_HANDLE source_handle;
if (descriptor_index != UINT32_MAX) { if (descriptor_index != UINT32_MAX) {
assert_not_null(texture); assert_not_null(texture);
@ -1413,10 +1413,10 @@ void TextureCache::WriteActiveTextureBindfulSRV(
host_shader_binding.dimension == xenos::FetchOpDimension::k2D); host_shader_binding.dimension == xenos::FetchOpDimension::k2D);
null_descriptor_index = NullSRVDescriptorIndex::k2DArray; null_descriptor_index = NullSRVDescriptorIndex::k2DArray;
} }
source_handle = provider->OffsetViewDescriptor( source_handle = provider.OffsetViewDescriptor(
null_srv_descriptor_heap_start_, uint32_t(null_descriptor_index)); null_srv_descriptor_heap_start_, uint32_t(null_descriptor_index));
} }
auto device = provider->GetDevice(); auto device = provider.GetDevice();
{ {
#if FINE_GRAINED_DRAW_SCOPES #if FINE_GRAINED_DRAW_SCOPES
SCOPE_profile_cpu_i( SCOPE_profile_cpu_i(
@ -1465,7 +1465,7 @@ uint32_t TextureCache::GetActiveTextureBindlessSRVIndex(
TextureCache::SamplerParameters TextureCache::GetSamplerParameters( TextureCache::SamplerParameters TextureCache::GetSamplerParameters(
const D3D12Shader::SamplerBinding& binding) const { const D3D12Shader::SamplerBinding& binding) const {
auto& regs = *register_file_; const auto& regs = register_file_;
const auto& fetch = regs.Get<xenos::xe_gpu_texture_fetch_t>( const auto& fetch = regs.Get<xenos::xe_gpu_texture_fetch_t>(
XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 + binding.fetch_constant * 6); 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. // Maximum mip level is in the texture resource itself.
desc.MaxLOD = FLT_MAX; desc.MaxLOD = FLT_MAX;
auto device = auto device =
command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice();
device->CreateSampler(&desc, handle); device->CreateSampler(&desc, handle);
} }
@ -1604,7 +1604,7 @@ void TextureCache::MarkRangeAsResolved(uint32_t start_unscaled,
// Invalidate textures. Toggling individual textures between scaled and // Invalidate textures. Toggling individual textures between scaled and
// unscaled also relies on invalidation through shared memory. // 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, bool TextureCache::EnsureScaledResolveBufferResident(uint32_t start_unscaled,
@ -1627,9 +1627,9 @@ bool TextureCache::EnsureScaledResolveBufferResident(uint32_t start_unscaled,
if (scaled_resolve_heaps_[i] != nullptr) { if (scaled_resolve_heaps_[i] != nullptr) {
continue; continue;
} }
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
auto direct_queue = provider->GetDirectQueue(); auto direct_queue = provider.GetDirectQueue();
D3D12_HEAP_DESC heap_desc = {}; D3D12_HEAP_DESC heap_desc = {};
heap_desc.SizeInBytes = kScaledResolveHeapSize; heap_desc.SizeInBytes = kScaledResolveHeapSize;
heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT; heap_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT;
@ -1671,7 +1671,7 @@ bool TextureCache::EnsureScaledResolveBufferResident(uint32_t start_unscaled,
void TextureCache::UseScaledResolveBufferForReading() { void TextureCache::UseScaledResolveBufferForReading() {
assert_true(IsResolutionScale2X()); assert_true(IsResolutionScale2X());
command_processor_->PushTransitionBarrier( command_processor_.PushTransitionBarrier(
scaled_resolve_buffer_, scaled_resolve_buffer_state_, scaled_resolve_buffer_, scaled_resolve_buffer_state_,
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
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()); assert_true(IsResolutionScale2X());
if (scaled_resolve_buffer_state_ == D3D12_RESOURCE_STATE_UNORDERED_ACCESS) { if (scaled_resolve_buffer_state_ == D3D12_RESOURCE_STATE_UNORDERED_ACCESS) {
if (scaled_resolve_buffer_uav_writes_commit_needed_) { 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; scaled_resolve_buffer_uav_writes_commit_needed_ = false;
} }
return; return;
} }
command_processor_->PushTransitionBarrier( command_processor_.PushTransitionBarrier(
scaled_resolve_buffer_, scaled_resolve_buffer_state_, scaled_resolve_buffer_, scaled_resolve_buffer_state_,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS); D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
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) { uint32_t guest_length_bytes, uint32_t element_size_bytes_pow2) {
assert_true(IsResolutionScale2X()); assert_true(IsResolutionScale2X());
ui::d3d12::util::CreateBufferTypedUAV( ui::d3d12::util::CreateBufferTypedUAV(
command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(), command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice(),
handle, scaled_resolve_buffer_, handle, scaled_resolve_buffer_,
ui::d3d12::util::GetUintPow2DXGIFormat(element_size_bytes_pow2), ui::d3d12::util::GetUintPow2DXGIFormat(element_size_bytes_pow2),
guest_length_bytes << 2 >> element_size_bytes_pow2, guest_length_bytes << 2 >> element_size_bytes_pow2,
@ -1709,7 +1709,7 @@ void TextureCache::CreateScaledResolveBufferUintPow2UAV(
ID3D12Resource* TextureCache::RequestSwapTexture( ID3D12Resource* TextureCache::RequestSwapTexture(
D3D12_SHADER_RESOURCE_VIEW_DESC& srv_desc_out, D3D12_SHADER_RESOURCE_VIEW_DESC& srv_desc_out,
xenos::TextureFormat& format_out) { xenos::TextureFormat& format_out) {
auto& regs = *register_file_; const auto& regs = register_file_;
const auto& fetch = regs.Get<xenos::xe_gpu_texture_fetch_t>( const auto& fetch = regs.Get<xenos::xe_gpu_texture_fetch_t>(
XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0); XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0);
TextureKey key; TextureKey key;
@ -1727,7 +1727,7 @@ ID3D12Resource* TextureCache::RequestSwapTexture(
// The swap texture is likely to be used only for the presentation pixel // 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 | // shader, and not during emulation, where it'd be NON_PIXEL_SHADER_RESOURCE |
// PIXEL_SHADER_RESOURCE. // PIXEL_SHADER_RESOURCE.
command_processor_->PushTransitionBarrier( command_processor_.PushTransitionBarrier(
texture->resource, texture->state, texture->resource, texture->state,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); D3D12_RESOURCE_STATE_PIXEL_SHADER_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. // is not done that often.
desc.Flags = D3D12_RESOURCE_FLAG_NONE; desc.Flags = D3D12_RESOURCE_FLAG_NONE;
auto device = auto device =
command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice();
// Assuming untiling will be the next operation. // Assuming untiling will be the next operation.
D3D12_RESOURCE_STATES state = D3D12_RESOURCE_STATE_COPY_DEST; D3D12_RESOURCE_STATES state = D3D12_RESOURCE_STATE_COPY_DEST;
ID3D12Resource* resource; ID3D12Resource* resource;
@ -1972,7 +1972,7 @@ TextureCache::Texture* TextureCache::FindOrCreateTexture(TextureKey key) {
texture->resource_size = texture->resource_size =
device->GetResourceAllocationInfo(0, 1, &desc).SizeInBytes; device->GetResourceAllocationInfo(0, 1, &desc).SizeInBytes;
texture->state = state; 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->last_usage_time = texture_current_usage_time_;
texture->used_previous = texture_used_last_; texture->used_previous = texture_used_last_;
texture->used_next = nullptr; texture->used_next = nullptr;
@ -2070,9 +2070,9 @@ bool TextureCache::LoadTextureData(Texture* texture) {
return true; return true;
} }
auto command_list = command_processor_->GetDeferredCommandList(); auto& command_list = command_processor_.GetDeferredCommandList();
auto device = auto device =
command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice();
// Get the pipeline. // Get the pipeline.
LoadMode load_mode = GetLoadMode(texture->key); 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 // its pages is invalidated, in this case we'll need the texture from the
// shared memory to load the unscaled parts. // shared memory to load the unscaled parts.
if (!base_in_sync) { if (!base_in_sync) {
if (!shared_memory_->RequestRange(texture->key.base_page << 12, if (!shared_memory_.RequestRange(texture->key.base_page << 12,
texture->base_size)) { texture->base_size)) {
return false; return false;
} }
} }
if (!mips_in_sync) { if (!mips_in_sync) {
if (!shared_memory_->RequestRange(texture->key.mip_page << 12, if (!shared_memory_.RequestRange(texture->key.mip_page << 12,
texture->mip_size)) { texture->mip_size)) {
return false; return false;
} }
} }
@ -2205,7 +2205,7 @@ bool TextureCache::LoadTextureData(Texture* texture) {
} }
D3D12_RESOURCE_STATES copy_buffer_state = D3D12_RESOURCE_STATES copy_buffer_state =
D3D12_RESOURCE_STATE_UNORDERED_ACCESS; 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); uint32_t(host_slice_size), copy_buffer_state);
if (copy_buffer == nullptr) { if (copy_buffer == nullptr) {
return false; return false;
@ -2237,8 +2237,8 @@ bool TextureCache::LoadTextureData(Texture* texture) {
} }
} }
ui::d3d12::util::DescriptorCPUGPUHandlePair descriptors[3]; ui::d3d12::util::DescriptorCPUGPUHandlePair descriptors[3];
if (!command_processor_->RequestOneUseSingleViewDescriptors(descriptor_count, if (!command_processor_.RequestOneUseSingleViewDescriptors(descriptor_count,
descriptors)) { descriptors)) {
return false; return false;
} }
uint32_t descriptor_write_index = 0; uint32_t descriptor_write_index = 0;
@ -2285,30 +2285,30 @@ bool TextureCache::LoadTextureData(Texture* texture) {
load_mode_info.srv_bpe_log2_2x); load_mode_info.srv_bpe_log2_2x);
} }
} else { } else {
shared_memory_->UseForReading(); shared_memory_.UseForReading();
if (bindless_resources_used_) { if (bindless_resources_used_) {
descriptors_source[0] = descriptors_source[0] =
command_processor_->GetSharedMemoryUintPow2BindlessSRVHandlePair( command_processor_.GetSharedMemoryUintPow2BindlessSRVHandlePair(
load_mode_info.srv_bpe_log2); load_mode_info.srv_bpe_log2);
} else { } else {
assert_true(descriptor_write_index < descriptor_count); assert_true(descriptor_write_index < descriptor_count);
descriptors_source[0] = descriptors[descriptor_write_index++]; descriptors_source[0] = descriptors[descriptor_write_index++];
shared_memory_->WriteUintPow2SRVDescriptor(descriptors_source[0].first, shared_memory_.WriteUintPow2SRVDescriptor(descriptors_source[0].first,
load_mode_info.srv_bpe_log2); load_mode_info.srv_bpe_log2);
} }
} }
command_processor_->SetComputePipelineState(pipeline_state); command_processor_.SetComputePipelineState(pipeline_state);
command_list->D3DSetComputeRootSignature(load_root_signature_); command_list.D3DSetComputeRootSignature(load_root_signature_);
command_list->D3DSetComputeRootDescriptorTable(2, descriptor_dest.second); command_list.D3DSetComputeRootDescriptorTable(2, descriptor_dest.second);
// Update LRU caching because the texture will be used by the command list. // Update LRU caching because the texture will be used by the command list.
MarkTextureUsed(texture); MarkTextureUsed(texture);
// Submit commands. // Submit commands.
command_processor_->PushTransitionBarrier(texture->resource, texture->state, command_processor_.PushTransitionBarrier(texture->resource, texture->state,
D3D12_RESOURCE_STATE_COPY_DEST); D3D12_RESOURCE_STATE_COPY_DEST);
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; LoadConstants load_constants;
load_constants.is_3d_endian = load_constants.is_3d_endian =
uint32_t(is_3d) | (uint32_t(texture->key.endianness) << 1); 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; uint32_t descriptor_source_last_index = UINT32_MAX;
for (uint32_t slice = 0; slice < slice_count; ++slice) { 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, copy_buffer_state, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
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; 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)); xe::next_pow2(load_constants.size_blocks[1]), uint32_t(32));
} }
D3D12_GPU_VIRTUAL_ADDRESS cbuffer_gpu_address; D3D12_GPU_VIRTUAL_ADDRESS cbuffer_gpu_address;
uint8_t* cbuffer_mapping = cbuffer_pool->Request( uint8_t* cbuffer_mapping = cbuffer_pool.Request(
command_processor_->GetCurrentFrame(), command_processor_.GetCurrentFrame(),
xe::align(uint32_t(sizeof(load_constants)), uint32_t(256)), nullptr, xe::align(uint32_t(sizeof(load_constants)), uint32_t(256)), nullptr,
nullptr, &cbuffer_gpu_address); nullptr, &cbuffer_gpu_address);
if (cbuffer_mapping == nullptr) { if (cbuffer_mapping == nullptr) {
command_processor_->ReleaseScratchGPUBuffer(copy_buffer, command_processor_.ReleaseScratchGPUBuffer(copy_buffer,
copy_buffer_state); copy_buffer_state);
return false; return false;
} }
std::memcpy(cbuffer_mapping, &load_constants, sizeof(load_constants)); std::memcpy(cbuffer_mapping, &load_constants, sizeof(load_constants));
if (descriptor_source_last_index != descriptor_source_index) { if (descriptor_source_last_index != descriptor_source_index) {
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); 1, descriptors_source[descriptor_source_index].second);
} }
command_list->D3DSetComputeRootConstantBufferView(0, cbuffer_gpu_address); command_list.D3DSetComputeRootConstantBufferView(0, cbuffer_gpu_address);
command_processor_->SubmitBarriers(); command_processor_.SubmitBarriers();
// Each thread group processes 32x32x1 guest blocks. // Each thread group processes 32x32x1 guest blocks.
command_list->D3DDispatch((load_constants.size_blocks[0] + 31) >> 5, command_list.D3DDispatch((load_constants.size_blocks[0] + 31) >> 5,
(load_constants.size_blocks[1] + 31) >> 5, (load_constants.size_blocks[1] + 31) >> 5,
load_constants.size_blocks[2]); load_constants.size_blocks[2]);
} }
command_processor_->PushUAVBarrier(copy_buffer); command_processor_.PushUAVBarrier(copy_buffer);
command_processor_->PushTransitionBarrier(copy_buffer, copy_buffer_state, command_processor_.PushTransitionBarrier(copy_buffer, copy_buffer_state,
D3D12_RESOURCE_STATE_COPY_SOURCE); D3D12_RESOURCE_STATE_COPY_SOURCE);
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; UINT slice_first_subresource = slice * texture_mip_count;
for (uint32_t mip = mip_first; mip <= mip_last; ++mip) { for (uint32_t mip = mip_first; mip <= mip_last; ++mip) {
D3D12_TEXTURE_COPY_LOCATION location_source, location_dest; 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); xe::align(std::max(height >> mip, uint32_t(1)), host_block_height);
source_box.back = source_box.back =
source_box.front + std::max(depth >> mip, uint32_t(1)); source_box.front + std::max(depth >> mip, uint32_t(1));
command_list->CopyTextureRegion(location_dest, 0, 0, 0, location_source, command_list.CopyTextureRegion(location_dest, 0, 0, 0, location_source,
source_box); source_box);
} else { } else {
location_source.PlacedFootprint = host_layouts[mip - mip_first]; 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 // 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 // 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->base_in_sync = true;
texture->mips_in_sync = true; texture->mips_in_sync = true;
if (!base_in_sync) { 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, texture->key.base_page << 12, texture->base_size, WatchCallbackThunk,
this, texture, 0); this, texture, 0);
} }
if (!mips_in_sync) { 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, texture->key.mip_page << 12, texture->mip_size, WatchCallbackThunk,
this, texture, 1); this, texture, 1);
} }
@ -2552,11 +2552,11 @@ uint32_t TextureCache::FindOrCreateTextureDescriptor(Texture& texture,
D3D12_SHADER_COMPONENT_MAPPING_ALWAYS_SET_BIT_AVOIDING_ZEROMEM_MISTAKES; D3D12_SHADER_COMPONENT_MAPPING_ALWAYS_SET_BIT_AVOIDING_ZEROMEM_MISTAKES;
auto device = auto device =
command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice(); command_processor_.GetD3D12Context().GetD3D12Provider().GetDevice();
uint32_t descriptor_index; uint32_t descriptor_index;
if (bindless_resources_used_) { if (bindless_resources_used_) {
descriptor_index = descriptor_index =
command_processor_->RequestPersistentViewBindlessDescriptor(); command_processor_.RequestPersistentViewBindlessDescriptor();
if (descriptor_index == UINT32_MAX) { if (descriptor_index == UINT32_MAX) {
XELOGE( XELOGE(
"Failed to create a texture descriptor - no free bindless view " "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( D3D12_CPU_DESCRIPTOR_HANDLE TextureCache::GetTextureDescriptorCPUHandle(
uint32_t descriptor_index) const { uint32_t descriptor_index) const {
auto provider = command_processor_->GetD3D12Context()->GetD3D12Provider(); auto& provider = command_processor_.GetD3D12Context().GetD3D12Provider();
if (bindless_resources_used_) { if (bindless_resources_used_) {
return provider->OffsetViewDescriptor( return provider.OffsetViewDescriptor(
command_processor_->GetViewBindlessHeapCPUStart(), descriptor_index); command_processor_.GetViewBindlessHeapCPUStart(), descriptor_index);
} }
D3D12_CPU_DESCRIPTOR_HANDLE heap_start = D3D12_CPU_DESCRIPTOR_HANDLE heap_start =
srv_descriptor_cache_[descriptor_index / srv_descriptor_cache_[descriptor_index /
SRVDescriptorCachePage::kHeapSize] SRVDescriptorCachePage::kHeapSize]
.heap_start; .heap_start;
uint32_t heap_offset = descriptor_index % SRVDescriptorCachePage::kHeapSize; 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) { 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. // This is called very frequently, don't relink unless needed for caching.
if (texture->last_usage_frame != current_frame) { if (texture->last_usage_frame != current_frame) {
texture->last_usage_frame = current_frame; texture->last_usage_frame = current_frame;

View File

@ -167,9 +167,9 @@ class TextureCache {
} }
}; };
TextureCache(D3D12CommandProcessor* command_processor, TextureCache(D3D12CommandProcessor& command_processor,
RegisterFile* register_file, bool bindless_resources_used, const RegisterFile& register_file, bool bindless_resources_used,
SharedMemory* shared_memory); SharedMemory& shared_memory);
~TextureCache(); ~TextureCache();
bool Initialize(bool edram_rov_used); bool Initialize(bool edram_rov_used);
@ -543,10 +543,10 @@ class TextureCache {
static const char* const dimension_names_[4]; static const char* const dimension_names_[4];
D3D12CommandProcessor* command_processor_; D3D12CommandProcessor& command_processor_;
RegisterFile* register_file_; const RegisterFile& register_file_;
bool bindless_resources_used_; bool bindless_resources_used_;
SharedMemory* shared_memory_; SharedMemory& shared_memory_;
static const LoadModeInfo load_mode_info_[]; static const LoadModeInfo load_mode_info_[];
ID3D12RootSignature* load_root_signature_ = nullptr; ID3D12RootSignature* load_root_signature_ = nullptr;

View File

@ -32,10 +32,10 @@ D3D12Context::D3D12Context(D3D12Provider* provider, Window* target_window)
D3D12Context::~D3D12Context() { Shutdown(); } D3D12Context::~D3D12Context() { Shutdown(); }
bool D3D12Context::Initialize() { bool D3D12Context::Initialize() {
auto provider = GetD3D12Provider(); auto& provider = GetD3D12Provider();
auto dxgi_factory = provider->GetDXGIFactory(); auto dxgi_factory = provider.GetDXGIFactory();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
auto direct_queue = provider->GetDirectQueue(); auto direct_queue = provider.GetDirectQueue();
context_lost_ = false; context_lost_ = false;
@ -74,7 +74,7 @@ bool D3D12Context::Initialize() {
swap_chain_desc.Flags = 0; swap_chain_desc.Flags = 0;
IDXGISwapChain1* swap_chain_1; IDXGISwapChain1* swap_chain_1;
if (FAILED(dxgi_factory->CreateSwapChainForHwnd( if (FAILED(dxgi_factory->CreateSwapChainForHwnd(
provider->GetDirectQueue(), provider.GetDirectQueue(),
static_cast<HWND>(target_window_->native_handle()), static_cast<HWND>(target_window_->native_handle()),
&swap_chain_desc, nullptr, nullptr, &swap_chain_1))) { &swap_chain_desc, nullptr, nullptr, &swap_chain_1))) {
XELOGE("Failed to create a DXGI swap chain"); XELOGE("Failed to create a DXGI swap chain");
@ -131,7 +131,7 @@ bool D3D12Context::Initialize() {
swap_command_list_->Close(); swap_command_list_->Close();
// Initialize the immediate mode drawer if not offscreen. // Initialize the immediate mode drawer if not offscreen.
immediate_drawer_ = std::make_unique<D3D12ImmediateDrawer>(this); immediate_drawer_ = std::make_unique<D3D12ImmediateDrawer>(*this);
if (!immediate_drawer_->Initialize()) { if (!immediate_drawer_->Initialize()) {
Shutdown(); Shutdown();
return false; return false;
@ -155,7 +155,7 @@ bool D3D12Context::InitializeSwapChainBuffers() {
swap_chain_back_buffer_index_ = swap_chain_->GetCurrentBackBufferIndex(); swap_chain_back_buffer_index_ = swap_chain_->GetCurrentBackBufferIndex();
// Create RTV descriptors for the swap chain buffers. // Create RTV descriptors for the swap chain buffers.
auto device = GetD3D12Provider()->GetDevice(); auto device = GetD3D12Provider().GetDevice();
D3D12_RENDER_TARGET_VIEW_DESC rtv_desc; D3D12_RENDER_TARGET_VIEW_DESC rtv_desc;
rtv_desc.Format = kSwapChainFormat; rtv_desc.Format = kSwapChainFormat;
rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
@ -223,12 +223,6 @@ ImmediateDrawer* D3D12Context::immediate_drawer() {
return immediate_drawer_.get(); return immediate_drawer_.get();
} }
bool D3D12Context::is_current() { return false; }
bool D3D12Context::MakeCurrent() { return true; }
void D3D12Context::ClearCurrent() {}
void D3D12Context::BeginSwap() { void D3D12Context::BeginSwap() {
if (!target_window_ || context_lost_) { if (!target_window_ || context_lost_) {
return; return;
@ -320,7 +314,7 @@ void D3D12Context::EndSwap() {
return; return;
} }
auto direct_queue = GetD3D12Provider()->GetDirectQueue(); auto direct_queue = GetD3D12Provider().GetDirectQueue();
// Switch the back buffer to presentation state. // Switch the back buffer to presentation state.
D3D12_RESOURCE_BARRIER barrier; D3D12_RESOURCE_BARRIER barrier;
@ -358,8 +352,8 @@ std::unique_ptr<RawImage> D3D12Context::Capture() {
D3D12_CPU_DESCRIPTOR_HANDLE D3D12Context::GetSwapChainBufferRTV( D3D12_CPU_DESCRIPTOR_HANDLE D3D12Context::GetSwapChainBufferRTV(
uint32_t buffer_index) const { uint32_t buffer_index) const {
return GetD3D12Provider()->OffsetRTVDescriptor(swap_chain_rtv_heap_start_, return GetD3D12Provider().OffsetRTVDescriptor(swap_chain_rtv_heap_start_,
buffer_index); buffer_index);
} }
} // namespace d3d12 } // namespace d3d12

View File

@ -28,10 +28,6 @@ class D3D12Context : public GraphicsContext {
ImmediateDrawer* immediate_drawer() override; ImmediateDrawer* immediate_drawer() override;
bool is_current() override;
bool MakeCurrent() override;
void ClearCurrent() override;
bool WasLost() override { return context_lost_; } bool WasLost() override { return context_lost_; }
void BeginSwap() override; void BeginSwap() override;
@ -39,8 +35,8 @@ class D3D12Context : public GraphicsContext {
std::unique_ptr<RawImage> Capture() override; std::unique_ptr<RawImage> Capture() override;
D3D12Provider* GetD3D12Provider() const { D3D12Provider& GetD3D12Provider() const {
return static_cast<D3D12Provider*>(provider_); return static_cast<D3D12Provider&>(*provider_);
} }
// The format used by DWM. // The format used by DWM.

View File

@ -109,14 +109,14 @@ void D3D12ImmediateTexture::Transition(
state_ = new_state; state_ = new_state;
} }
D3D12ImmediateDrawer::D3D12ImmediateDrawer(D3D12Context* graphics_context) D3D12ImmediateDrawer::D3D12ImmediateDrawer(D3D12Context& graphics_context)
: ImmediateDrawer(graphics_context), context_(graphics_context) {} : ImmediateDrawer(&graphics_context), context_(graphics_context) {}
D3D12ImmediateDrawer::~D3D12ImmediateDrawer() { Shutdown(); } D3D12ImmediateDrawer::~D3D12ImmediateDrawer() { Shutdown(); }
bool D3D12ImmediateDrawer::Initialize() { bool D3D12ImmediateDrawer::Initialize() {
auto provider = context_->GetD3D12Provider(); auto& provider = context_.GetD3D12Provider();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
// Create the root signature. // Create the root signature.
D3D12_ROOT_PARAMETER root_parameters[size_t(RootParameter::kCount)]; 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_cpu_start_ = sampler_heap_->GetCPUDescriptorHandleForHeapStart();
sampler_heap_gpu_start_ = sampler_heap_->GetGPUDescriptorHandleForHeapStart(); sampler_heap_gpu_start_ = sampler_heap_->GetGPUDescriptorHandleForHeapStart();
uint32_t sampler_size = provider->GetSamplerDescriptorSize(); uint32_t sampler_size = provider.GetSamplerDescriptorSize();
// Nearest neighbor, clamp. // Nearest neighbor, clamp.
D3D12_SAMPLER_DESC sampler_desc; D3D12_SAMPLER_DESC sampler_desc;
sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
@ -326,7 +326,7 @@ std::unique_ptr<ImmediateTexture> D3D12ImmediateDrawer::CreateTexture(
const uint8_t* data) { const uint8_t* data) {
auto texture = auto texture =
std::make_unique<D3D12ImmediateTexture>(width, height, filter, repeat); std::make_unique<D3D12ImmediateTexture>(width, height, filter, repeat);
texture->Initialize(context_->GetD3D12Provider()->GetDevice()); texture->Initialize(context_.GetD3D12Provider().GetDevice());
if (data != nullptr) { if (data != nullptr) {
UpdateTexture(texture.get(), data); UpdateTexture(texture.get(), data);
} }
@ -343,7 +343,7 @@ void D3D12ImmediateDrawer::UpdateTexture(ImmediateTexture* texture,
} }
uint32_t width = d3d_texture->width, height = d3d_texture->height; 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. // Create and fill the upload buffer.
D3D12_RESOURCE_DESC texture_desc = texture_resource->GetDesc(); D3D12_RESOURCE_DESC texture_desc = texture_resource->GetDesc();
@ -400,7 +400,7 @@ void D3D12ImmediateDrawer::UpdateTexture(ImmediateTexture* texture,
&location_source, nullptr); &location_source, nullptr);
SubmittedTextureUpload submitted_upload; SubmittedTextureUpload submitted_upload;
submitted_upload.buffer = buffer; submitted_upload.buffer = buffer;
submitted_upload.fence_value = context_->GetSwapCurrentFenceValue(); submitted_upload.fence_value = context_.GetSwapCurrentFenceValue();
texture_uploads_submitted_.push_back(submitted_upload); texture_uploads_submitted_.push_back(submitted_upload);
} else { } else {
// Defer uploading to the next frame when there's a command list. // 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, void D3D12ImmediateDrawer::Begin(int render_target_width,
int render_target_height) { int render_target_height) {
auto device = context_->GetD3D12Provider()->GetDevice(); auto device = context_.GetD3D12Provider().GetDevice();
// Use the compositing command list. // Use the compositing command list.
current_command_list_ = context_->GetSwapCommandList(); current_command_list_ = context_.GetSwapCommandList();
uint64_t completed_fence_value = context_->GetSwapCompletedFenceValue(); uint64_t completed_fence_value = context_.GetSwapCompletedFenceValue();
uint64_t current_fence_value = context_->GetSwapCurrentFenceValue(); uint64_t current_fence_value = context_.GetSwapCurrentFenceValue();
// Remove temporary buffers for completed texture uploads. // Remove temporary buffers for completed texture uploads.
auto erase_uploads_end = texture_uploads_submitted_.begin(); auto erase_uploads_end = texture_uploads_submitted_.begin();
@ -494,7 +494,7 @@ void D3D12ImmediateDrawer::BeginDrawBatch(const ImmediateDrawBatch& batch) {
if (current_command_list_ == nullptr) { if (current_command_list_ == nullptr) {
return; return;
} }
uint64_t current_fence_value = context_->GetSwapCurrentFenceValue(); uint64_t current_fence_value = context_.GetSwapCurrentFenceValue();
batch_open_ = false; batch_open_ = false;
@ -549,8 +549,8 @@ void D3D12ImmediateDrawer::Draw(const ImmediateDraw& draw) {
return; return;
} }
auto provider = context_->GetD3D12Provider(); auto& provider = context_.GetD3D12Provider();
auto device = provider->GetDevice(); auto device = provider.GetDevice();
// Bind the texture. // Bind the texture.
auto texture = reinterpret_cast<D3D12ImmediateTexture*>(draw.texture_handle); auto texture = reinterpret_cast<D3D12ImmediateTexture*>(draw.texture_handle);
@ -565,7 +565,7 @@ void D3D12ImmediateDrawer::Draw(const ImmediateDraw& draw) {
bool bind_texture = current_texture_ != texture; bool bind_texture = current_texture_ != texture;
uint32_t texture_descriptor_index; uint32_t texture_descriptor_index;
uint64_t texture_heap_index = texture_descriptor_pool_->Request( 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); bind_texture ? 1 : 0, 1, texture_descriptor_index);
if (texture_heap_index == DescriptorHeapPool::kHeapIndexInvalid) { if (texture_heap_index == DescriptorHeapPool::kHeapIndexInvalid) {
return; return;
@ -589,12 +589,12 @@ void D3D12ImmediateDrawer::Draw(const ImmediateDraw& draw) {
texture_view_desc.Texture2D.ResourceMinLODClamp = 0.0f; texture_view_desc.Texture2D.ResourceMinLODClamp = 0.0f;
device->CreateShaderResourceView( device->CreateShaderResourceView(
texture_resource, &texture_view_desc, texture_resource, &texture_view_desc,
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
texture_descriptor_pool_->GetLastRequestHeapCPUStart(), texture_descriptor_pool_->GetLastRequestHeapCPUStart(),
texture_descriptor_index)); texture_descriptor_index));
current_command_list_->SetGraphicsRootDescriptorTable( current_command_list_->SetGraphicsRootDescriptorTable(
UINT(RootParameter::kTexture), UINT(RootParameter::kTexture),
provider->OffsetViewDescriptor( provider.OffsetViewDescriptor(
texture_descriptor_pool_->GetLastRequestHeapGPUStart(), texture_descriptor_pool_->GetLastRequestHeapGPUStart(),
texture_descriptor_index)); texture_descriptor_index));
current_texture_ = texture; current_texture_ = texture;
@ -616,8 +616,8 @@ void D3D12ImmediateDrawer::Draw(const ImmediateDraw& draw) {
if (current_sampler_index_ != sampler_index) { if (current_sampler_index_ != sampler_index) {
current_command_list_->SetGraphicsRootDescriptorTable( current_command_list_->SetGraphicsRootDescriptorTable(
UINT(RootParameter::kSampler), UINT(RootParameter::kSampler),
provider->OffsetSamplerDescriptor(sampler_heap_gpu_start_, provider.OffsetSamplerDescriptor(sampler_heap_gpu_start_,
uint32_t(sampler_index))); uint32_t(sampler_index)));
current_sampler_index_ = sampler_index; current_sampler_index_ = sampler_index;
} }

View File

@ -26,7 +26,7 @@ class D3D12Context;
class D3D12ImmediateDrawer : public ImmediateDrawer { class D3D12ImmediateDrawer : public ImmediateDrawer {
public: public:
D3D12ImmediateDrawer(D3D12Context* graphics_context); D3D12ImmediateDrawer(D3D12Context& graphics_context);
~D3D12ImmediateDrawer() override; ~D3D12ImmediateDrawer() override;
bool Initialize(); bool Initialize();
@ -46,7 +46,7 @@ class D3D12ImmediateDrawer : public ImmediateDrawer {
void End() override; void End() override;
private: private:
D3D12Context* context_ = nullptr; D3D12Context& context_;
ID3D12RootSignature* root_signature_ = nullptr; ID3D12RootSignature* root_signature_ = nullptr;
enum class RootParameter { enum class RootParameter {

View File

@ -23,10 +23,10 @@ const D3D12_HEAP_PROPERTIES kHeapPropertiesReadback = {
D3D12_HEAP_TYPE_READBACK}; D3D12_HEAP_TYPE_READBACK};
ID3D12RootSignature* CreateRootSignature( ID3D12RootSignature* CreateRootSignature(
D3D12Provider* provider, const D3D12_ROOT_SIGNATURE_DESC& desc) { D3D12Provider& provider, const D3D12_ROOT_SIGNATURE_DESC& desc) {
ID3DBlob* blob; ID3DBlob* blob;
ID3DBlob* error_blob = nullptr; ID3DBlob* error_blob = nullptr;
if (FAILED(provider->SerializeRootSignature( if (FAILED(provider.SerializeRootSignature(
&desc, D3D_ROOT_SIGNATURE_VERSION_1, &blob, &error_blob))) { &desc, D3D_ROOT_SIGNATURE_VERSION_1, &blob, &error_blob))) {
XELOGE("Failed to serialize a root signature"); XELOGE("Failed to serialize a root signature");
if (error_blob != nullptr) { if (error_blob != nullptr) {
@ -40,9 +40,9 @@ ID3D12RootSignature* CreateRootSignature(
error_blob->Release(); error_blob->Release();
} }
ID3D12RootSignature* root_signature = nullptr; ID3D12RootSignature* root_signature = nullptr;
provider->GetDevice()->CreateRootSignature(0, blob->GetBufferPointer(), provider.GetDevice()->CreateRootSignature(0, blob->GetBufferPointer(),
blob->GetBufferSize(), blob->GetBufferSize(),
IID_PPV_ARGS(&root_signature)); IID_PPV_ARGS(&root_signature));
blob->Release(); blob->Release();
return root_signature; return root_signature;
} }

View File

@ -36,7 +36,7 @@ inline bool ReleaseAndNull(T& object) {
return false; return false;
}; };
ID3D12RootSignature* CreateRootSignature(D3D12Provider* provider, ID3D12RootSignature* CreateRootSignature(D3D12Provider& provider,
const D3D12_ROOT_SIGNATURE_DESC& desc); const D3D12_ROOT_SIGNATURE_DESC& desc);
ID3D12PipelineState* CreateComputePipelineState( ID3D12PipelineState* CreateComputePipelineState(

View File

@ -20,5 +20,11 @@ GraphicsContext::GraphicsContext(GraphicsProvider* provider,
GraphicsContext::~GraphicsContext() = default; GraphicsContext::~GraphicsContext() = default;
bool GraphicsContext::is_current() { return true; }
bool GraphicsContext::MakeCurrent() { return true; }
void GraphicsContext::ClearCurrent() {}
} // namespace ui } // namespace ui
} // namespace xe } // namespace xe

View File

@ -41,15 +41,15 @@ class GraphicsContext {
virtual ImmediateDrawer* immediate_drawer() = 0; virtual ImmediateDrawer* immediate_drawer() = 0;
virtual bool is_current() = 0; virtual bool is_current();
virtual bool MakeCurrent() = 0; virtual bool MakeCurrent();
virtual void ClearCurrent() = 0; virtual void ClearCurrent();
// Returns true if the OS took away our context because we caused a TDR or // 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 // some other outstanding error. When this happens, this context, as well as
// any other shared contexts are junk. // any other shared contexts are junk.
// This context must be made current in order for this call to work properly. // 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 BeginSwap() = 0;
virtual void EndSwap() = 0; virtual void EndSwap() = 0;