Merge remote-tracking branch 'xenia-master/master' into canary_experimental

This commit is contained in:
Herman S.
2026-03-06 14:10:00 +09:00
65 changed files with 1497 additions and 2231 deletions

View File

@@ -509,48 +509,6 @@ D3D12CommandProcessor::GetSystemBindlessViewHandlePair(
view_bindless_heap_gpu_start_, uint32_t(view)));
}
ui::d3d12::util::DescriptorCpuGpuHandlePair
D3D12CommandProcessor::GetSharedMemoryUintPow2BindlessSRVHandlePair(
uint32_t element_size_bytes_pow2) const {
SystemBindlessView view;
switch (element_size_bytes_pow2) {
case 2:
view = SystemBindlessView::kSharedMemoryR32UintSRV;
break;
case 3:
view = SystemBindlessView::kSharedMemoryR32G32UintSRV;
break;
case 4:
view = SystemBindlessView::kSharedMemoryR32G32B32A32UintSRV;
break;
default:
assert_unhandled_case(element_size_bytes_pow2);
view = SystemBindlessView::kSharedMemoryR32UintSRV;
}
return GetSystemBindlessViewHandlePair(view);
}
ui::d3d12::util::DescriptorCpuGpuHandlePair
D3D12CommandProcessor::GetSharedMemoryUintPow2BindlessUAVHandlePair(
uint32_t element_size_bytes_pow2) const {
SystemBindlessView view;
switch (element_size_bytes_pow2) {
case 2:
view = SystemBindlessView::kSharedMemoryR32UintUAV;
break;
case 3:
view = SystemBindlessView::kSharedMemoryR32G32UintUAV;
break;
case 4:
view = SystemBindlessView::kSharedMemoryR32G32B32A32UintUAV;
break;
default:
assert_unhandled_case(element_size_bytes_pow2);
view = SystemBindlessView::kSharedMemoryR32UintUAV;
}
return GetSystemBindlessViewHandlePair(view);
}
ui::d3d12::util::DescriptorCpuGpuHandlePair
D3D12CommandProcessor::GetEdramUintPow2BindlessSRVHandlePair(
uint32_t element_size_bytes_pow2) const {
@@ -1503,46 +1461,10 @@ bool D3D12CommandProcessor::SetupContext() {
shared_memory_->WriteRawSRVDescriptor(provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kSharedMemoryRawSRV)));
// kSharedMemoryR32UintSRV.
shared_memory_->WriteUintPow2SRVDescriptor(
provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kSharedMemoryR32UintSRV)),
2);
// kSharedMemoryR32G32UintSRV.
shared_memory_->WriteUintPow2SRVDescriptor(
provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kSharedMemoryR32G32UintSRV)),
3);
// kSharedMemoryR32G32B32A32UintSRV.
shared_memory_->WriteUintPow2SRVDescriptor(
provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kSharedMemoryR32G32B32A32UintSRV)),
4);
// kSharedMemoryRawUAV.
shared_memory_->WriteRawUAVDescriptor(provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kSharedMemoryRawUAV)));
// kSharedMemoryR32UintUAV.
shared_memory_->WriteUintPow2UAVDescriptor(
provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kSharedMemoryR32UintUAV)),
2);
// kSharedMemoryR32G32UintUAV.
shared_memory_->WriteUintPow2UAVDescriptor(
provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kSharedMemoryR32G32UintUAV)),
3);
// kSharedMemoryR32G32B32A32UintUAV.
shared_memory_->WriteUintPow2UAVDescriptor(
provider.OffsetViewDescriptor(
view_bindless_heap_cpu_start_,
uint32_t(SystemBindlessView::kSharedMemoryR32G32B32A32UintUAV)),
4);
// kEdramRawSRV.
render_target_cache_->WriteEdramRawSRVDescriptor(
provider.OffsetViewDescriptor(
@@ -2646,7 +2568,6 @@ bool D3D12CommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type,
if (host_render_targets_used) {
bound_depth_and_color_render_target_bits =
render_target_cache_->GetLastUpdateBoundRenderTargets(
render_target_cache_->gamma_render_target_as_srgb(),
bound_depth_and_color_render_target_formats);
} else {
bound_depth_and_color_render_target_bits = 0;
@@ -2979,8 +2900,7 @@ bool D3D12CommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type,
// Invalidate textures in memexported memory and watch for changes.
for (const draw_util::MemExportRange& memexport_range : memexport_ranges_) {
shared_memory_->RangeWrittenByGpu(
memexport_range.base_address_dwords << 2, memexport_range.size_bytes,
false);
memexport_range.base_address_dwords << 2, memexport_range.size_bytes);
}
if (GetGPUSetting(GPUSetting::ReadbackMemexport)) {
// Read the exported data on the CPU.
@@ -3785,7 +3705,8 @@ XE_NOINLINE void D3D12CommandProcessor::UpdateSystemConstantValues_Impl(
flags |= uint32_t(alpha_test_function)
<< DxbcShaderTranslator::kSysFlag_AlphaPassIfLess_Shift;
// Gamma writing.
if (!render_target_cache_->gamma_render_target_as_srgb()) {
if (!(edram_rov_used ||
render_target_cache_->gamma_render_target_as_unorm16())) {
for (uint32_t i = 0; i < 4; ++i) {
if (color_infos[i].color_format ==
xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA) {
@@ -3952,9 +3873,7 @@ XE_NOINLINE void D3D12CommandProcessor::UpdateSystemConstantValues_Impl(
}
// Texture signedness / gamma.
bool gamma_render_target_as_srgb =
render_target_cache_->gamma_render_target_as_srgb();
uint32_t textures_resolved = 0;
uint32_t textures_resolution_scaled = 0;
uint32_t textures_remaining = used_texture_mask;
uint32_t texture_index;
while (xe::bit_scan_forward(textures_remaining, &texture_index)) {
@@ -3974,14 +3893,14 @@ XE_NOINLINE void D3D12CommandProcessor::UpdateSystemConstantValues_Impl(
texture_signs_uint =
(texture_signs_uint & ~texture_signs_mask) | texture_signs_shifted;
// cache misses here, we're accessing the texture bindings out of order
textures_resolved |=
uint32_t(texture_cache_->IsActiveTextureResolved(texture_index))
textures_resolution_scaled |=
uint32_t(texture_cache_->IsActiveTextureResolutionScaled(texture_index))
<< texture_index;
}
update_dirty_uint32_cmp(system_constants_.textures_resolved,
textures_resolved);
system_constants_.textures_resolved = textures_resolved;
update_dirty_uint32_cmp(system_constants_.textures_resolution_scaled,
textures_resolution_scaled);
system_constants_.textures_resolution_scaled = textures_resolution_scaled;
// Log2 of sample count, for alpha to mask and with ROV, for EDRAM address
// calculation with MSAA.

View File

@@ -160,13 +160,6 @@ class D3D12CommandProcessor final : public CommandProcessor {
kNullRawSRV = kNullRawSRVAndSharedMemoryRawUAVStart,
kSharedMemoryRawUAV,
kSharedMemoryR32UintSRV,
kSharedMemoryR32G32UintSRV,
kSharedMemoryR32G32B32A32UintSRV,
kSharedMemoryR32UintUAV,
kSharedMemoryR32G32UintUAV,
kSharedMemoryR32G32B32A32UintUAV,
kEdramRawSRV,
kEdramR32UintSRV,
kEdramR32G32UintSRV,
@@ -192,12 +185,6 @@ class D3D12CommandProcessor final : public CommandProcessor {
ui::d3d12::util::DescriptorCpuGpuHandlePair GetSystemBindlessViewHandlePair(
SystemBindlessView view) const;
ui::d3d12::util::DescriptorCpuGpuHandlePair
GetSharedMemoryUintPow2BindlessSRVHandlePair(
uint32_t element_size_bytes_pow2) const;
ui::d3d12::util::DescriptorCpuGpuHandlePair
GetSharedMemoryUintPow2BindlessUAVHandlePair(
uint32_t element_size_bytes_pow2) const;
ui::d3d12::util::DescriptorCpuGpuHandlePair
GetEdramUintPow2BindlessSRVHandlePair(uint32_t element_size_bytes_pow2) const;
ui::d3d12::util::DescriptorCpuGpuHandlePair
GetEdramUintPow2BindlessUAVHandlePair(uint32_t element_size_bytes_pow2) const;

View File

@@ -274,6 +274,7 @@ bool D3D12RenderTargetCache::Initialize() {
return false;
}
edram_buffer_->SetName(L"EDRAM Buffer");
edram_buffer_gpu_address_ = edram_buffer_->GetGPUVirtualAddress();
edram_buffer_modification_status_ =
EdramBufferModificationStatus::kUnmodified;
@@ -364,31 +365,15 @@ bool D3D12RenderTargetCache::Initialize() {
resolve_copy_root_parameters[0].ShaderVisibility =
D3D12_SHADER_VISIBILITY_ALL;
// Parameter 1 is the destination (shared memory).
D3D12_DESCRIPTOR_RANGE resolve_copy_dest_range;
resolve_copy_dest_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
resolve_copy_dest_range.NumDescriptors = 1;
resolve_copy_dest_range.BaseShaderRegister = 0;
resolve_copy_dest_range.RegisterSpace = 0;
resolve_copy_dest_range.OffsetInDescriptorsFromTableStart = 0;
resolve_copy_root_parameters[1].ParameterType =
D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
resolve_copy_root_parameters[1].DescriptorTable.NumDescriptorRanges = 1;
resolve_copy_root_parameters[1].DescriptorTable.pDescriptorRanges =
&resolve_copy_dest_range;
resolve_copy_root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
resolve_copy_root_parameters[1].Descriptor.ShaderRegister = 0;
resolve_copy_root_parameters[1].Descriptor.RegisterSpace = 0;
resolve_copy_root_parameters[1].ShaderVisibility =
D3D12_SHADER_VISIBILITY_ALL;
// Parameter 2 is the source (EDRAM).
D3D12_DESCRIPTOR_RANGE resolve_copy_source_range;
resolve_copy_source_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
resolve_copy_source_range.NumDescriptors = 1;
resolve_copy_source_range.BaseShaderRegister = 0;
resolve_copy_source_range.RegisterSpace = 0;
resolve_copy_source_range.OffsetInDescriptorsFromTableStart = 0;
resolve_copy_root_parameters[2].ParameterType =
D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
resolve_copy_root_parameters[2].DescriptorTable.NumDescriptorRanges = 1;
resolve_copy_root_parameters[2].DescriptorTable.pDescriptorRanges =
&resolve_copy_source_range;
resolve_copy_root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV;
resolve_copy_root_parameters[2].Descriptor.ShaderRegister = 0;
resolve_copy_root_parameters[2].Descriptor.RegisterSpace = 0;
resolve_copy_root_parameters[2].ShaderVisibility =
D3D12_SHADER_VISIBILITY_ALL;
D3D12_ROOT_SIGNATURE_DESC resolve_copy_root_signature_desc;
@@ -456,7 +441,7 @@ bool D3D12RenderTargetCache::Initialize() {
if (path_ == Path::kHostRenderTargets) {
// Host render targets.
gamma_render_target_as_srgb_ = cvars::gamma_render_target_as_srgb;
gamma_render_target_as_unorm16_ = cvars::gamma_render_target_as_unorm16;
depth_float24_round_ = cvars::depth_float24_round;
depth_float24_convert_in_pixel_shader_ =
@@ -499,6 +484,17 @@ bool D3D12RenderTargetCache::Initialize() {
break;
}
}
if (msaa_2x_supported_ && gamma_render_target_as_unorm16_) {
multisample_quality_levels.Format = DXGI_FORMAT_R16G16B16A16_UNORM;
multisample_quality_levels.NumQualityLevels = 0;
if (FAILED(device->CheckFeatureSupport(
D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS,
&multisample_quality_levels,
sizeof(multisample_quality_levels))) ||
!multisample_quality_levels.NumQualityLevels) {
msaa_2x_supported_ = false;
}
}
} else {
msaa_2x_supported_ = false;
}
@@ -573,20 +569,11 @@ bool D3D12RenderTargetCache::Initialize() {
&host_depth_store_root_source_range;
host_depth_store_root_source.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
// Destination.
D3D12_DESCRIPTOR_RANGE host_depth_store_root_dest_range;
host_depth_store_root_dest_range.RangeType =
D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
host_depth_store_root_dest_range.NumDescriptors = 1;
host_depth_store_root_dest_range.BaseShaderRegister = 0;
host_depth_store_root_dest_range.RegisterSpace = 0;
host_depth_store_root_dest_range.OffsetInDescriptorsFromTableStart = 0;
D3D12_ROOT_PARAMETER& host_depth_store_root_dest =
host_depth_store_root_parameters[kHostDepthStoreRootParameterDest];
host_depth_store_root_dest.ParameterType =
D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
host_depth_store_root_dest.DescriptorTable.NumDescriptorRanges = 1;
host_depth_store_root_dest.DescriptorTable.pDescriptorRanges =
&host_depth_store_root_dest_range;
host_depth_store_root_dest.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
host_depth_store_root_dest.Descriptor.ShaderRegister = 0;
host_depth_store_root_dest.Descriptor.RegisterSpace = 0;
host_depth_store_root_dest.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
// Root signature.
D3D12_ROOT_SIGNATURE_DESC host_depth_store_root_desc;
@@ -834,12 +821,6 @@ bool D3D12RenderTargetCache::Initialize() {
dump_root_stencil_range.BaseShaderRegister = 1;
dump_root_stencil_range.RegisterSpace = 0;
dump_root_stencil_range.OffsetInDescriptorsFromTableStart = 0;
D3D12_DESCRIPTOR_RANGE dump_root_edram_range;
dump_root_edram_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
dump_root_edram_range.NumDescriptors = 1;
dump_root_edram_range.BaseShaderRegister = 0;
dump_root_edram_range.RegisterSpace = 0;
dump_root_edram_range.OffsetInDescriptorsFromTableStart = 0;
D3D12_ROOT_PARAMETER
dump_root_color_parameters[kDumpRootParameterColorCount];
D3D12_ROOT_PARAMETER
@@ -892,11 +873,9 @@ bool D3D12RenderTargetCache::Initialize() {
D3D12_ROOT_PARAMETER& dump_root_edram =
i ? dump_root_depth_parameters[kDumpRootParameterDepthEdram]
: dump_root_color_parameters[kDumpRootParameterColorEdram];
dump_root_edram.ParameterType =
D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
dump_root_edram.DescriptorTable.NumDescriptorRanges = 1;
dump_root_edram.DescriptorTable.pDescriptorRanges =
&dump_root_edram_range;
dump_root_edram.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
dump_root_edram.Descriptor.ShaderRegister = 0;
dump_root_edram.Descriptor.RegisterSpace = 0;
dump_root_edram.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
}
D3D12_ROOT_SIGNATURE_DESC dump_root_desc;
@@ -1014,8 +993,8 @@ bool D3D12RenderTargetCache::Initialize() {
} else if (path_ == Path::kPixelShaderInterlock) {
// Pixel shader interlock (rasterizer-ordered view).
// Blending is done in linear space directly in shaders.
gamma_render_target_as_srgb_ = false;
// Piecewise linear gamma is 8-bit with programmable blending.
gamma_render_target_as_unorm16_ = false;
// Always true float24 depth rounded to the nearest even.
depth_float24_round_ = true;
@@ -1038,18 +1017,10 @@ bool D3D12RenderTargetCache::Initialize() {
resolve_rov_clear_root_parameters[0].ShaderVisibility =
D3D12_SHADER_VISIBILITY_ALL;
// Parameter 1 is the destination (EDRAM).
D3D12_DESCRIPTOR_RANGE resolve_rov_clear_dest_range;
resolve_rov_clear_dest_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
resolve_rov_clear_dest_range.NumDescriptors = 1;
resolve_rov_clear_dest_range.BaseShaderRegister = 0;
resolve_rov_clear_dest_range.RegisterSpace = 0;
resolve_rov_clear_dest_range.OffsetInDescriptorsFromTableStart = 0;
resolve_rov_clear_root_parameters[1].ParameterType =
D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
resolve_rov_clear_root_parameters[1].DescriptorTable.NumDescriptorRanges =
1;
resolve_rov_clear_root_parameters[1].DescriptorTable.pDescriptorRanges =
&resolve_rov_clear_dest_range;
D3D12_ROOT_PARAMETER_TYPE_UAV;
resolve_rov_clear_root_parameters[1].Descriptor.ShaderRegister = 0;
resolve_rov_clear_root_parameters[1].Descriptor.RegisterSpace = 0;
resolve_rov_clear_root_parameters[1].ShaderVisibility =
D3D12_SHADER_VISIBILITY_ALL;
D3D12_ROOT_SIGNATURE_DESC resolve_rov_clear_root_signature_desc;
@@ -1397,95 +1368,52 @@ bool D3D12RenderTargetCache::Resolve(const Memory& memory,
resolve_info.copy_dest_extent_length);
}
if (copy_dest_committed) {
// Write the descriptors and transition the resources.
// Full shared memory without resolution scaling, range of the scaled
// resolve buffer with scaling because only at least 128 * 2^20 R32
// elements must be addressable
// (D3D12_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP).
ui::d3d12::util::DescriptorCpuGpuHandlePair descriptor_dest;
ui::d3d12::util::DescriptorCpuGpuHandlePair descriptor_source;
ui::d3d12::util::DescriptorCpuGpuHandlePair descriptors[2];
if (command_processor_.RequestOneUseSingleViewDescriptors(
bindless_resources_used_ ? uint32_t(draw_resolution_scaled) : 2,
descriptors)) {
if (bindless_resources_used_) {
if (draw_resolution_scaled) {
descriptor_dest = descriptors[0];
} else {
descriptor_dest =
command_processor_
.GetSharedMemoryUintPow2BindlessUAVHandlePair(
copy_shader_info.dest_bpe_log2);
}
if (copy_shader_info.source_is_raw) {
descriptor_source =
command_processor_.GetSystemBindlessViewHandlePair(
D3D12CommandProcessor::SystemBindlessView::kEdramRawSRV);
} else {
descriptor_source =
command_processor_.GetEdramUintPow2BindlessSRVHandlePair(
copy_shader_info.source_bpe_log2);
}
} else {
descriptor_dest = descriptors[0];
if (!draw_resolution_scaled) {
shared_memory.WriteUintPow2UAVDescriptor(
descriptor_dest.first, copy_shader_info.dest_bpe_log2);
}
descriptor_source = descriptors[1];
if (copy_shader_info.source_is_raw) {
WriteEdramRawSRVDescriptor(descriptor_source.first);
} else {
WriteEdramUintPow2SRVDescriptor(descriptor_source.first,
copy_shader_info.source_bpe_log2);
}
}
if (draw_resolution_scaled) {
texture_cache.CreateCurrentScaledResolveRangeUintPow2UAV(
descriptor_dest.first, copy_shader_info.dest_bpe_log2);
texture_cache.TransitionCurrentScaledResolveRange(
D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
} else {
shared_memory.UseForWriting();
}
TransitionEdramBuffer(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
command_list.D3DSetComputeRootSignature(resolve_copy_root_signature_);
// Submit the resolve.
command_list.D3DSetComputeRootSignature(resolve_copy_root_signature_);
command_list.D3DSetComputeRootDescriptorTable(
2, descriptor_source.second);
command_list.D3DSetComputeRootDescriptorTable(1,
descriptor_dest.second);
if (draw_resolution_scaled) {
command_list.D3DSetComputeRoot32BitConstants(
0,
sizeof(copy_shader_constants.dest_relative) / sizeof(uint32_t),
&copy_shader_constants.dest_relative, 0);
} else {
command_list.D3DSetComputeRoot32BitConstants(
0, sizeof(copy_shader_constants) / sizeof(uint32_t),
&copy_shader_constants, 0);
}
command_processor_.SetExternalPipeline(
resolve_copy_pipelines_[size_t(copy_shader)]);
command_processor_.SubmitBarriers();
command_list.D3DDispatch(copy_group_count_x, copy_group_count_y, 1);
// Source.
TransitionEdramBuffer(D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
command_list.D3DSetComputeRootShaderResourceView(
2, edram_buffer_gpu_address_);
// Order the resolve with other work using the destination as a UAV.
if (draw_resolution_scaled) {
texture_cache.MarkCurrentScaledResolveRangeUAVWritesCommitNeeded();
} else {
shared_memory.MarkUAVWritesCommitNeeded();
}
// Destination and constants.
if (draw_resolution_scaled) {
texture_cache.TransitionCurrentScaledResolveRange(
D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
command_list.D3DSetComputeRootUnorderedAccessView(
1, texture_cache.GetCurrentScaledResolveRangeGPUAddress());
// Invalidate textures and mark the range as scaled if needed.
texture_cache.MarkRangeAsResolved(
resolve_info.copy_dest_extent_start,
resolve_info.copy_dest_extent_length);
written_address_out = resolve_info.copy_dest_extent_start;
written_length_out = resolve_info.copy_dest_extent_length;
copied = true;
command_list.D3DSetComputeRoot32BitConstants(
0, sizeof(copy_shader_constants.dest_relative) / sizeof(uint32_t),
&copy_shader_constants.dest_relative, 0);
} else {
shared_memory.UseForWriting();
command_list.D3DSetComputeRootUnorderedAccessView(
1, shared_memory.GetGPUAddress());
command_list.D3DSetComputeRoot32BitConstants(
0, sizeof(copy_shader_constants) / sizeof(uint32_t),
&copy_shader_constants, 0);
}
// Dispatch the resolve.
command_processor_.SetExternalPipeline(
resolve_copy_pipelines_[size_t(copy_shader)]);
command_processor_.SubmitBarriers();
command_list.D3DDispatch(copy_group_count_x, copy_group_count_y, 1);
// Order the resolve with other work using the destination as a UAV.
if (draw_resolution_scaled) {
texture_cache.MarkCurrentScaledResolveRangeUAVWritesCommitNeeded();
} else {
shared_memory.MarkUAVWritesCommitNeeded();
}
// Invalidate textures and mark the range as scaled if needed.
texture_cache.MarkRangeAsResolved(resolve_info.copy_dest_extent_start,
resolve_info.copy_dest_extent_length);
written_address_out = resolve_info.copy_dest_extent_start;
written_length_out = resolve_info.copy_dest_extent_length;
copied = true;
} else {
XELOGE(
"D3D12RenderTargetCache: Failed to obtain the resolve destination "
@@ -1522,76 +1450,57 @@ bool D3D12RenderTargetCache::Resolve(const Memory& memory,
cleared = true;
} break;
case Path::kPixelShaderInterlock: {
ui::d3d12::util::DescriptorCpuGpuHandlePair descriptor_edram;
bool descriptor_edram_obtained;
if (bindless_resources_used_) {
descriptor_edram = command_processor_.GetSystemBindlessViewHandlePair(
D3D12CommandProcessor::SystemBindlessView ::
kEdramR32G32B32A32UintUAV);
descriptor_edram_obtained = true;
} else {
descriptor_edram_obtained =
command_processor_.RequestOneUseSingleViewDescriptors(
1, &descriptor_edram);
if (descriptor_edram_obtained) {
WriteEdramUintPow2UAVDescriptor(descriptor_edram.first, 4);
}
TransitionEdramBuffer(D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
// Should be safe to only commit once (if was UAV / ROV previously - if
// there was nothing to copy, only to clear, for some reason, for
// instance), overlap of the depth and the color ranges is highly
// unlikely.
CommitEdramBufferUAVWrites();
command_list.D3DSetComputeRootSignature(
resolve_rov_clear_root_signature_);
command_list.D3DSetComputeRootUnorderedAccessView(
1, edram_buffer_gpu_address_);
std::pair<uint32_t, uint32_t> clear_group_count =
resolve_info.GetClearShaderGroupCount(draw_resolution_scale_x(),
draw_resolution_scale_y());
assert_true(clear_group_count.first && clear_group_count.second);
if (clear_depth) {
draw_util::ResolveClearShaderConstants depth_clear_constants;
resolve_info.GetDepthClearShaderConstants(depth_clear_constants);
command_list.D3DSetComputeRoot32BitConstants(
0, sizeof(depth_clear_constants) / sizeof(uint32_t),
&depth_clear_constants, 0);
command_processor_.SetExternalPipeline(
resolve_rov_clear_32bpp_pipeline_);
command_processor_.SubmitBarriers();
command_list.D3DDispatch(clear_group_count.first,
clear_group_count.second, 1);
}
if (descriptor_edram_obtained) {
TransitionEdramBuffer(D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
// Should be safe to only commit once (if was UAV / ROV previously -
// if there was nothing to copy, only to clear, for some reason, for
// instance), overlap of the depth and the color ranges is highly
// unlikely.
CommitEdramBufferUAVWrites();
command_list.D3DSetComputeRootSignature(
resolve_rov_clear_root_signature_);
command_list.D3DSetComputeRootDescriptorTable(
1, descriptor_edram.second);
std::pair<uint32_t, uint32_t> clear_group_count =
resolve_info.GetClearShaderGroupCount(draw_resolution_scale_x(),
draw_resolution_scale_y());
assert_true(clear_group_count.first && clear_group_count.second);
if (clear_color) {
draw_util::ResolveClearShaderConstants color_clear_constants;
resolve_info.GetColorClearShaderConstants(color_clear_constants);
if (clear_depth) {
draw_util::ResolveClearShaderConstants depth_clear_constants;
resolve_info.GetDepthClearShaderConstants(depth_clear_constants);
// Non-RT-specific constants have already been set.
command_list.D3DSetComputeRoot32BitConstants(
0, sizeof(depth_clear_constants) / sizeof(uint32_t),
&depth_clear_constants, 0);
command_processor_.SetExternalPipeline(
resolve_rov_clear_32bpp_pipeline_);
command_processor_.SubmitBarriers();
command_list.D3DDispatch(clear_group_count.first,
clear_group_count.second, 1);
0, sizeof(color_clear_constants.rt_specific) / sizeof(uint32_t),
&color_clear_constants.rt_specific,
offsetof(draw_util::ResolveClearShaderConstants, rt_specific) /
sizeof(uint32_t));
} else {
command_list.D3DSetComputeRoot32BitConstants(
0, sizeof(color_clear_constants) / sizeof(uint32_t),
&color_clear_constants, 0);
}
if (clear_color) {
draw_util::ResolveClearShaderConstants color_clear_constants;
resolve_info.GetColorClearShaderConstants(color_clear_constants);
if (clear_depth) {
// Non-RT-specific constants have already been set.
command_list.D3DSetComputeRoot32BitConstants(
0,
sizeof(color_clear_constants.rt_specific) / sizeof(uint32_t),
&color_clear_constants.rt_specific,
offsetof(draw_util::ResolveClearShaderConstants,
rt_specific) /
sizeof(uint32_t));
} else {
command_list.D3DSetComputeRoot32BitConstants(
0, sizeof(color_clear_constants) / sizeof(uint32_t),
&color_clear_constants, 0);
}
command_processor_.SetExternalPipeline(
resolve_info.color_edram_info.format_is_64bpp
? resolve_rov_clear_64bpp_pipeline_
: resolve_rov_clear_32bpp_pipeline_);
command_processor_.SubmitBarriers();
command_list.D3DDispatch(clear_group_count.first,
clear_group_count.second, 1);
}
MarkEdramBufferModified();
cleared = true;
command_processor_.SetExternalPipeline(
resolve_info.color_edram_info.format_is_64bpp
? resolve_rov_clear_64bpp_pipeline_
: resolve_rov_clear_32bpp_pipeline_);
command_processor_.SubmitBarriers();
command_list.D3DDispatch(clear_group_count.first,
clear_group_count.second, 1);
}
MarkEdramBufferModified();
cleared = true;
} break;
default:
assert_unhandled_case(GetPath());
@@ -1775,12 +1684,10 @@ DXGI_FORMAT D3D12RenderTargetCache::GetColorResourceDXGIFormat(
// compression.
switch (format) {
case xenos::ColorRenderTargetFormat::k_8_8_8_8:
case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA:
if (gamma_render_target_as_srgb_) {
// Can toggle between UNORM and UNORM_SRGB for the same data.
return DXGI_FORMAT_R8G8B8A8_TYPELESS;
}
return DXGI_FORMAT_R8G8B8A8_UNORM;
case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA:
return gamma_render_target_as_unorm16_ ? DXGI_FORMAT_R16G16B16A16_UNORM
: DXGI_FORMAT_R8G8B8A8_UNORM;
case xenos::ColorRenderTargetFormat::k_2_10_10_10:
case xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10:
return DXGI_FORMAT_R10G10B10A2_UNORM;
@@ -1813,11 +1720,6 @@ DXGI_FORMAT D3D12RenderTargetCache::GetColorResourceDXGIFormat(
DXGI_FORMAT D3D12RenderTargetCache::GetColorDrawDXGIFormat(
xenos::ColorRenderTargetFormat format) const {
switch (format) {
case xenos::ColorRenderTargetFormat::k_8_8_8_8:
return DXGI_FORMAT_R8G8B8A8_UNORM;
case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA:
return gamma_render_target_as_srgb_ ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
: DXGI_FORMAT_R8G8B8A8_UNORM;
case xenos::ColorRenderTargetFormat::k_16_16:
return DXGI_FORMAT_R16G16_SNORM;
case xenos::ColorRenderTargetFormat::k_16_16_16_16:
@@ -1911,6 +1813,10 @@ DXGI_FORMAT D3D12RenderTargetCache::GetDepthSRVStencilDXGIFormat(
}
}
bool D3D12RenderTargetCache::IsGammaFormatHostStorageSeparate() const {
return gamma_render_target_as_unorm16_;
}
RenderTargetCache::RenderTarget* D3D12RenderTargetCache::CreateRenderTarget(
RenderTargetKey key) {
ID3D12Device* device = command_processor_.GetD3D12Provider().GetDevice();
@@ -1991,7 +1897,6 @@ RenderTargetCache::RenderTarget* D3D12RenderTargetCache::CreateRenderTarget(
}
D3D12_CPU_DESCRIPTOR_HANDLE descriptor_draw_handle =
descriptor_draw.GetHandle();
ui::d3d12::D3D12CpuDescriptorPool::Descriptor descriptor_draw_srgb;
ui::d3d12::D3D12CpuDescriptorPool::Descriptor descriptor_load_separate;
ui::d3d12::D3D12CpuDescriptorPool::Descriptor descriptor_srv_stencil;
D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc;
@@ -2050,23 +1955,6 @@ RenderTargetCache::RenderTarget* D3D12RenderTargetCache::CreateRenderTarget(
}
device->CreateRenderTargetView(resource.Get(), &rtv_desc,
descriptor_draw_handle);
// sRGB drawing RTV.
switch (key.GetColorFormat()) {
case xenos::ColorRenderTargetFormat::k_8_8_8_8:
case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA:
if (gamma_render_target_as_srgb_) {
descriptor_draw_srgb = descriptor_pool.AllocateDescriptor();
if (!descriptor_draw_srgb.IsValid()) {
return nullptr;
}
rtv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
device->CreateRenderTargetView(resource.Get(), &rtv_desc,
descriptor_draw_srgb.GetHandle());
}
break;
default:
break;
}
// Ownership transfer RTV.
DXGI_FORMAT load_format =
GetColorOwnershipTransferDXGIFormat(key.GetColorFormat());
@@ -2087,9 +1975,8 @@ RenderTargetCache::RenderTarget* D3D12RenderTargetCache::CreateRenderTarget(
return new D3D12RenderTarget(
key, resource.Get(), std::move(descriptor_draw),
std::move(descriptor_draw_srgb), std::move(descriptor_load_separate),
std::move(descriptor_srv), std::move(descriptor_srv_stencil),
resource_state);
std::move(descriptor_load_separate), std::move(descriptor_srv),
std::move(descriptor_srv_stencil), resource_state);
}
bool D3D12RenderTargetCache::IsHostDepthEncodingDifferent(
@@ -3430,15 +3317,25 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
if (dest_is_64bpp) {
// Handle construction of 64bpp color, either from two 32-bit samples in r0
// and r1, or from one 64bpp sample in r1. Using r2.x as temporary when
// and r1, or from one 64bpp sample in r1. Using r2.xy as temporary when
// needed.
// If color_packed_in_r0x_and_r1x, use the generic path for combining two
// 32-bit samples - as raw in r0.x and r1.x - into the destination.
bool color_packed_in_r0x_and_r1x = false;
if (source_is_color) {
switch (source_color_format) {
case xenos::ColorRenderTargetFormat::k_8_8_8_8:
case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA: {
// 8_8_8_8_GAMMA is represented by linear stored in
// R16G16B16A16_UNORM.
for (uint32_t i = 0; i < 2; ++i) {
for (uint32_t j = 0; j < 3; ++j) {
DxbcShaderTranslator::PreSaturatedLinearToPWLGamma(a, i, j, i, j,
2, 0, 2, 1);
}
}
}
[[fallthrough]];
case xenos::ColorRenderTargetFormat::k_8_8_8_8: {
color_packed_in_r0x_and_r1x = true;
for (uint32_t i = 0; i < 2; ++i) {
a.OpMAd(dxbc::Dest::R(i), dxbc::Src::R(i), dxbc::Src::LF(255.0f),
@@ -3589,7 +3486,14 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
switch (source_color_format) {
case xenos::ColorRenderTargetFormat::k_8_8_8_8:
case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA: {
// 8_8_8_8_GAMMA is represented by linear stored in
// R16G16B16A16_UNORM.
if (dest_is_stencil_bit) {
if (source_color_format ==
xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA) {
DxbcShaderTranslator::PreSaturatedLinearToPWLGamma(a, 1, 0, 1, 0,
2, 0, 2, 1);
}
a.OpMAd(dxbc::Dest::R(1, 0b0001), dxbc::Src::R(1, dxbc::Src::kXXXX),
dxbc::Src::LF(255.0f), dxbc::Src::LF(0.5f));
a.OpFToU(dxbc::Dest::R(1, 0b0001),
@@ -3599,18 +3503,38 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
xenos::ColorRenderTargetFormat::k_8_8_8_8 ||
dest_color_format ==
xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA)) {
// Same format - passthrough.
// Same format - only perform color space conversion.
if (dest_color_format != source_color_format) {
if (dest_color_format ==
xenos::ColorRenderTargetFormat::k_8_8_8_8) {
for (uint32_t i = 0; i < 3; ++i) {
DxbcShaderTranslator::PreSaturatedLinearToPWLGamma(
a, 1, i, 1, i, 2, 0, 2, 1);
}
} else {
for (uint32_t i = 0; i < 3; ++i) {
DxbcShaderTranslator::PWLGammaToLinear(a, 1, i, 1, i, true, 2,
0, 2, 1);
}
}
}
a.OpMov(dxbc::Dest::O(0), dxbc::Src::R(1));
} else if (mode.output == TransferOutput::kDepth) {
// When need only depth, not stencil, skip the red component.
a.OpMAd(dxbc::Dest::R(
1, osgn_parameter_index_sv_stencil_ref != UINT32_MAX
? 0b1111
: 0b1110),
dxbc::Src::R(1), dxbc::Src::LF(255.0f),
dxbc::Src::LF(0.5f));
// When need only depth, not stencil, skipping the red component.
if (source_color_format ==
xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA) {
for (uint32_t i = shader_uses_stencil_reference_output ? 0 : 1;
i < 3; ++i) {
DxbcShaderTranslator::PreSaturatedLinearToPWLGamma(
a, 1, i, 1, i, 2, 0, 2, 1);
}
}
a.OpMAd(
dxbc::Dest::R(
1, shader_uses_stencil_reference_output ? 0b1111 : 0b1110),
dxbc::Src::R(1), dxbc::Src::LF(255.0f), dxbc::Src::LF(0.5f));
a.OpFToU(dxbc::Dest::R(1, 0b1110), dxbc::Src::R(1));
if (osgn_parameter_index_sv_stencil_ref != UINT32_MAX) {
if (shader_uses_stencil_reference_output) {
// Write the red component to the stencil reference.
a.OpFToU(dxbc::Dest::OStencilRef(),
dxbc::Src::R(1, dxbc::Src::kXXXX));
@@ -3626,6 +3550,13 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
dxbc::Src::R(1, dxbc::Src::kYYYY));
} else {
color_packed_in_r1x = true;
if (source_color_format ==
xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA) {
for (uint32_t i = 0; i < 3; ++i) {
DxbcShaderTranslator::PreSaturatedLinearToPWLGamma(
a, 1, i, 1, i, 2, 0, 2, 1);
}
}
a.OpMAd(dxbc::Dest::R(1), dxbc::Src::R(1), dxbc::Src::LF(255.0f),
dxbc::Src::LF(0.5f));
a.OpFToU(dxbc::Dest::R(1), dxbc::Src::R(1));
@@ -3769,8 +3700,7 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
// this is the end of the shader.
if (color_packed_in_r1x) {
switch (dest_color_format) {
case xenos::ColorRenderTargetFormat::k_8_8_8_8:
case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA: {
case xenos::ColorRenderTargetFormat::k_8_8_8_8: {
a.OpUBFE(dxbc::Dest::R(1), dxbc::Src::LU(8),
dxbc::Src::LU(0, 8, 16, 24),
dxbc::Src::R(1, dxbc::Src::kXXXX));
@@ -3778,6 +3708,26 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
a.OpMul(dxbc::Dest::O(0), dxbc::Src::R(1),
dxbc::Src::LF(1.0f / 255.0f));
} break;
case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA: {
// 8_8_8_8_GAMMA is represented by linear stored in
// R16G16B16A16_UNORM.
a.OpUBFE(dxbc::Dest::R(1), dxbc::Src::LU(8),
dxbc::Src::LU(0, 8, 16, 24),
dxbc::Src::R(1, dxbc::Src::kXXXX));
a.OpUToF(dxbc::Dest::R(1), dxbc::Src::R(1));
a.OpMul(dxbc::Dest::R(1, 0b0111), dxbc::Src::R(1),
dxbc::Src::LF(1.0f / 255.0f));
a.OpMul(dxbc::Dest::O(0, 0b1000), dxbc::Src::R(1),
dxbc::Src::LF(1.0f / 255.0f));
for (uint32_t i = 0; i < 3; ++i) {
DxbcShaderTranslator::PWLGammaToLinear(a, 1, i, 1, i, true, 0,
0, 0, 1);
}
// TODO(Triang3l): The `mov` can be eliminated by passing the
// destination to `PWLGammaToLinear` as `dxbc::Dest` rather than
// just the register index.
a.OpMov(dxbc::Dest::O(0, 0b0111), dxbc::Src::R(1));
} break;
case xenos::ColorRenderTargetFormat::k_2_10_10_10:
case xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: {
a.OpUBFE(dxbc::Dest::R(1), dxbc::Src::LU(10, 10, 10, 2),
@@ -4499,38 +4449,19 @@ void D3D12RenderTargetCache::PerformTransfersAndResolveClears(
continue;
}
if (!host_depth_store_set_up) {
// Bindings.
// 0 - source.
// 1 - EDRAM if bindful.
// Source descriptor.
ui::d3d12::util::DescriptorCpuGpuHandlePair
host_depth_store_descriptors[2];
host_depth_store_descriptor_source;
if (!command_processor_.RequestOneUseSingleViewDescriptors(
1 + uint32_t(!bindless_resources_used_),
host_depth_store_descriptors)) {
1, &host_depth_store_descriptor_source)) {
continue;
}
command_list.D3DSetComputeRootSignature(
host_depth_store_root_signature_);
// Destination (EDRAM uint4 buffer).
if (bindless_resources_used_) {
command_list.D3DSetComputeRootDescriptorTable(
kHostDepthStoreRootParameterDest,
command_processor_.GetEdramUintPow2BindlessUAVHandlePair(4)
.second);
} else {
const ui::d3d12::util::DescriptorCpuGpuHandlePair&
host_depth_store_descriptor_dest =
host_depth_store_descriptors[1];
WriteEdramUintPow2UAVDescriptor(
host_depth_store_descriptor_dest.first, 4);
command_list.D3DSetComputeRootDescriptorTable(
kHostDepthStoreRootParameterDest,
host_depth_store_descriptor_dest.second);
}
// Destination (EDRAM buffer).
command_list.D3DSetComputeRootUnorderedAccessView(
kHostDepthStoreRootParameterDest, edram_buffer_gpu_address_);
// Depth source texture.
const ui::d3d12::util::DescriptorCpuGpuHandlePair&
host_depth_store_descriptor_source =
host_depth_store_descriptors[0];
device->CopyDescriptorsSimple(
1, host_depth_store_descriptor_source.first,
dest_d3d12_rt.descriptor_srv().GetHandle(),
@@ -5358,13 +5289,24 @@ void D3D12RenderTargetCache::PerformTransfersAndResolveClears(
float color_clear_value[4] = {};
bool clear_via_drawing = false;
switch (dest_rt_key.GetColorFormat()) {
case xenos::ColorRenderTargetFormat::k_8_8_8_8:
case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA: {
case xenos::ColorRenderTargetFormat::k_8_8_8_8: {
for (uint32_t j = 0; j < 4; ++j) {
color_clear_value[j] =
((clear_value >> (j * 8)) & 0xFF) * (1.0f / 0xFF);
}
} break;
case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA: {
// 8_8_8_8_GAMMA is represented by linear stored in
// R16G16B16A16_UNORM.
for (uint32_t j = 0; j < 4; ++j) {
color_clear_value[j] =
((clear_value >> (j * 8)) & 0xFF) * (1.0f / 0xFF);
}
for (uint32_t j = 0; j < 3; ++j) {
color_clear_value[j] =
xenos::PWLGammaToLinear(color_clear_value[j]);
}
} break;
case xenos::ColorRenderTargetFormat::k_2_10_10_10:
case xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10: {
for (uint32_t j = 0; j < 3; ++j) {
@@ -5509,17 +5451,6 @@ void D3D12RenderTargetCache::SetCommandListRenderTargets(
}
}
}
uint32_t render_targets_are_srgb;
if (gamma_render_target_as_srgb_) {
render_targets_are_srgb = last_update_accumulated_color_targets_are_gamma();
if (are_current_command_list_render_targets_srgb_ !=
render_targets_are_srgb) {
are_current_command_list_render_targets_srgb_ = render_targets_are_srgb;
are_current_command_list_render_targets_valid_ = false;
}
} else {
render_targets_are_srgb = 0;
}
if (!are_current_command_list_render_targets_valid_) {
std::memcpy(current_command_list_render_targets_,
depth_and_color_render_targets,
@@ -5546,10 +5477,7 @@ void D3D12RenderTargetCache::SetCommandListRenderTargets(
: null_rtv_descriptor_ss_.GetHandle();
}
auto& d3d12_rt = *static_cast<const D3D12RenderTarget*>(render_target);
rtv_handles[rtv_count++] =
(render_targets_are_srgb & (uint32_t(1) << i))
? d3d12_rt.descriptor_draw_srgb().GetHandle()
: d3d12_rt.descriptor_draw().GetHandle();
rtv_handles[rtv_count++] = d3d12_rt.descriptor_draw().GetHandle();
}
command_processor_.GetDeferredCommandList().D3DOMSetRenderTargets(
rtv_count, rtv_handles, false,
@@ -5702,7 +5630,7 @@ ID3D12PipelineState* D3D12RenderTargetCache::GetOrCreateDumpPipeline(
// Bindings.
// - Texture2D/Texture2DMS<float4/uint4> xe_edram_dump_source : t0
// - Optionally, Texture2D/Texture2DMS<uint2> xe_edram_dump_stencil : t1
// - RWBuffer<uint/uint2> xe_edram : u0
// - RWByteAddressBuffer xe_edram : u0
// - Constant buffers
uint32_t rdef_binding_count = 1 + key.is_depth + 1 + kDumpCbufferCount;
// Names.
@@ -5775,13 +5703,10 @@ ID3D12PipelineState* D3D12RenderTargetCache::GetOrCreateDumpPipeline(
dxbc::RdefInputBind& rdef_binding_edram =
rdef_bindings[rdef_binding_index++];
rdef_binding_edram.name_ptr = rdef_xe_edram_name_ptr;
rdef_binding_edram.type = dxbc::RdefInputType::kUAVRWTyped;
rdef_binding_edram.return_type = dxbc::ResourceReturnType::kUInt;
rdef_binding_edram.type = dxbc::RdefInputType::kUAVRWByteAddress;
rdef_binding_edram.return_type = dxbc::ResourceReturnType::kMixed;
rdef_binding_edram.dimension = dxbc::RdefDimension::kUAVBuffer;
rdef_binding_edram.sample_count = UINT32_MAX;
rdef_binding_edram.bind_count = 1;
rdef_binding_edram.flags =
format_is_64bpp ? dxbc::kRdefInputFlags2Component : 0;
// xe_edram_dump_offsets
dxbc::RdefInputBind& rdef_binding_offsets =
rdef_bindings[rdef_binding_index++];
@@ -5906,10 +5831,7 @@ ID3D12PipelineState* D3D12RenderTargetCache::GetOrCreateDumpPipeline(
dxbc::Src::T(dxbc::Src::Dcl, 1, 1, 1));
}
// EDRAM buffer.
a.OpDclUnorderedAccessViewTyped(
dxbc::ResourceDimension::kBuffer, 0,
dxbc::ResourceReturnTypeX4Token(dxbc::ResourceReturnType::kUInt),
dxbc::Src::U(dxbc::Src::Dcl, 0, 0, 0));
a.OpDclUnorderedAccessViewRaw(0, dxbc::Src::U(dxbc::Src::Dcl, 0, 0, 0));
a.OpDclInput(dxbc::Dest::VThreadID(0b0011));
// r0 - addressing before the load, then addressing and conversion scratch
// r1 - addressing scratch before the load, then data
@@ -6042,6 +5964,9 @@ ID3D12PipelineState* D3D12RenderTargetCache::GetOrCreateDumpPipeline(
a.OpIAdd(dxbc::Dest::R(0, 0b0100), dxbc::Src::R(0, dxbc::Src::kZZZZ),
dxbc::Src::R(1, dxbc::Src::kXXXX));
}
// Convert the destination address from samples to bytes.
a.OpIShL(dxbc::Dest::R(0, 0b0100), dxbc::Src::R(0, dxbc::Src::kZZZZ),
dxbc::Src::LU(format_is_64bpp ? 3 : 2));
// Extract the source texture base tile index to r1.x.
// r0.x = X sample position within the tile
@@ -6236,7 +6161,6 @@ ID3D12PipelineState* D3D12RenderTargetCache::GetOrCreateDumpPipeline(
} else {
switch (key.GetColorFormat()) {
case xenos::ColorRenderTargetFormat::k_8_8_8_8:
case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA:
if (!source_is_uint) {
a.OpMAd(dxbc::Dest::R(1), dxbc::Src::R(1), dxbc::Src::LF(255.0f),
dxbc::Src::LF(0.5f));
@@ -6248,6 +6172,22 @@ ID3D12PipelineState* D3D12RenderTargetCache::GetOrCreateDumpPipeline(
dxbc::Src::R(1, dxbc::Src::kXXXX));
}
break;
case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA:
// 8_8_8_8_GAMMA is represented by linear stored in R16G16B16A16_UNORM.
assert_false(source_is_uint);
for (uint32_t i = 0; i < 3; ++i) {
DxbcShaderTranslator::PreSaturatedLinearToPWLGamma(a, 1, i, 1, i, 0,
0, 0, 1);
}
a.OpMAd(dxbc::Dest::R(1), dxbc::Src::R(1), dxbc::Src::LF(255.0f),
dxbc::Src::LF(0.5f));
a.OpFToU(dxbc::Dest::R(1), dxbc::Src::R(1));
for (uint32_t i = 1; i < 4; ++i) {
a.OpBFI(dxbc::Dest::R(1, 0b0001), dxbc::Src::LU(8),
dxbc::Src::LU(i * 8), dxbc::Src::R(1).Select(i),
dxbc::Src::R(1, dxbc::Src::kXXXX));
}
break;
case xenos::ColorRenderTargetFormat::k_2_10_10_10:
case xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10:
if (!source_is_uint) {
@@ -6310,9 +6250,8 @@ ID3D12PipelineState* D3D12RenderTargetCache::GetOrCreateDumpPipeline(
}
// Write the sample to the destination address stored in r0.z.
a.OpStoreUAVTyped(
dxbc::Dest::U(0, 0), dxbc::Src::R(0, dxbc::Src::kZZZZ), 1,
dxbc::Src::R(1, format_is_64bpp ? 0b0100 : dxbc::Src::kXXXX));
a.OpStoreRaw(dxbc::Dest::U(0, 0, format_is_64bpp ? 0b0011 : 0b0001),
dxbc::Src::R(0, dxbc::Src::kZZZZ), dxbc::Src::R(1));
a.OpRet();
@@ -6455,29 +6394,8 @@ void D3D12RenderTargetCache::DumpRenderTargets(uint32_t dump_base,
pipeline_key.is_depth = rt_key.is_depth;
dump_invocations_.emplace_back(rectangle, pipeline_key);
}
// 32bpp and 64bpp.
size_t edram_uav_indices[2] = {SIZE_MAX, SIZE_MAX};
const ui::d3d12::D3D12Provider& provider =
command_processor_.GetD3D12Provider();
if (!bindless_resources_used_) {
if (any_sources_32bpp_64bpp[0]) {
edram_uav_indices[0] = current_temporary_descriptors_cpu_.size();
current_temporary_descriptors_cpu_.push_back(
provider.OffsetViewDescriptor(
edram_buffer_descriptor_heap_start_,
uint32_t(EdramBufferDescriptorIndex::kR32UintUAV)));
}
if (any_sources_32bpp_64bpp[1]) {
edram_uav_indices[1] = current_temporary_descriptors_cpu_.size();
current_temporary_descriptors_cpu_.push_back(
provider.OffsetViewDescriptor(
edram_buffer_descriptor_heap_start_,
uint32_t(EdramBufferDescriptorIndex::kR32G32UintUAV)));
}
}
// Copy source descriptors to a shader-visible heap.
ID3D12Device* device = provider.GetDevice();
uint32_t descriptor_count =
uint32_t(current_temporary_descriptors_cpu_.size());
current_temporary_descriptors_gpu_.resize(descriptor_count);
@@ -6485,6 +6403,7 @@ void D3D12RenderTargetCache::DumpRenderTargets(uint32_t dump_base,
descriptor_count, current_temporary_descriptors_gpu_.data())) {
return;
}
ID3D12Device* device = command_processor_.GetD3D12Provider().GetDevice();
for (uint32_t i = 0; i < descriptor_count; ++i) {
device->CopyDescriptorsSimple(1,
current_temporary_descriptors_gpu_[i].first,
@@ -6499,6 +6418,8 @@ void D3D12RenderTargetCache::DumpRenderTargets(uint32_t dump_base,
DeferredCommandList& command_list =
command_processor_.GetDeferredCommandList();
ID3D12RootSignature* last_root_signature = nullptr;
// `root_parameters_set` doesn't include the EDRAM buffer, which is never
// changed.
uint32_t root_parameters_set = 0;
uint32_t last_descriptor_index_source = UINT32_MAX;
uint32_t last_descriptor_index_stencil = UINT32_MAX;
@@ -6523,35 +6444,10 @@ void D3D12RenderTargetCache::DumpRenderTargets(uint32_t dump_base,
last_root_signature = root_signature;
command_list.D3DSetComputeRootSignature(root_signature);
root_parameters_set = 0;
}
DumpRootParameter root_parameter_edram = pipeline_key.is_depth
? kDumpRootParameterDepthEdram
: kDumpRootParameterColorEdram;
uint32_t root_parameter_edram_bit = uint32_t(1) << root_parameter_edram;
bool format_is_64bpp = rt_key.Is64bpp();
if (last_edram_uav_is_64bpp != format_is_64bpp) {
last_edram_uav_is_64bpp = format_is_64bpp;
root_parameters_set &= ~root_parameter_edram_bit;
}
if (!(root_parameters_set & root_parameter_edram_bit)) {
D3D12_GPU_DESCRIPTOR_HANDLE descriptor_handle_edram;
if (bindless_resources_used_) {
descriptor_handle_edram = command_processor_
.GetEdramUintPow2BindlessUAVHandlePair(
2 + uint32_t(last_edram_uav_is_64bpp))
.second;
} else {
assert_true(edram_uav_indices[size_t(last_edram_uav_is_64bpp)] !=
SIZE_MAX);
descriptor_handle_edram =
current_temporary_descriptors_gpu_[edram_uav_indices[size_t(
last_edram_uav_is_64bpp)]]
.second;
}
command_list.D3DSetComputeRootDescriptorTable(root_parameter_edram,
descriptor_handle_edram);
root_parameters_set |= root_parameter_edram_bit;
command_list.D3DSetComputeRootUnorderedAccessView(
pipeline_key.is_depth ? kDumpRootParameterDepthEdram
: kDumpRootParameterColorEdram,
edram_buffer_gpu_address_);
}
DumpRootParameter root_parameter_pitches =
@@ -6612,6 +6508,7 @@ void D3D12RenderTargetCache::DumpRenderTargets(uint32_t dump_base,
uint32_t(1) << kDumpRootParameterOffsets;
DumpOffsets offsets;
offsets.source_base_tiles = rt_key.base_tiles;
bool format_is_64bpp = rt_key.Is64bpp();
ResolveCopyDumpRectangle::Dispatch
dispatches[ResolveCopyDumpRectangle::kMaxDispatches];
uint32_t dispatch_count =

View File

@@ -95,8 +95,8 @@ class D3D12RenderTargetCache final : public RenderTargetCache {
// For host render targets.
bool gamma_render_target_as_srgb() const {
return gamma_render_target_as_srgb_;
bool gamma_render_target_as_unorm16() const {
return gamma_render_target_as_unorm16_;
}
// Using R16G16[B16A16]_SNORM, which are -1...1, not the needed -32...32.
@@ -129,6 +129,8 @@ class D3D12RenderTargetCache final : public RenderTargetCache {
xenos::DepthRenderTargetFormat format);
protected:
bool IsGammaFormatHostStorageSeparate() const override;
uint32_t GetMaxRenderTargetWidth() const override {
return D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION;
}
@@ -178,6 +180,7 @@ class D3D12RenderTargetCache final : public RenderTargetCache {
// copied to a different buffer - the same range may have ROV-owned color and
// host float32 depth at the same time).
ID3D12Resource* edram_buffer_ = nullptr;
D3D12_GPU_VIRTUAL_ADDRESS edram_buffer_gpu_address_ = 0;
D3D12_RESOURCE_STATES edram_buffer_state_;
EdramBufferModificationStatus edram_buffer_modification_status_ =
EdramBufferModificationStatus::kUnmodified;
@@ -225,16 +228,13 @@ class D3D12RenderTargetCache final : public RenderTargetCache {
class D3D12RenderTarget final : public RenderTarget {
public:
// descriptor_draw_srgb is only used for k_8_8_8_8 render targets when host
// sRGB (gamma_render_target_as_srgb) is used. descriptor_load is present
// when the DXGI formats are different for drawing and bit-exact loading
// (for NaN pattern preservation across EDRAM tile ownership transfers in
// floating-point formats, and to distinguish between two -1 representations
// in snorm formats).
// descriptor_load is present when the DXGI formats are different for
// drawing and bit-exact loading (for NaN pattern preservation across EDRAM
// tile ownership transfers in floating-point formats, and to distinguish
// between two -1 representations in snorm formats).
D3D12RenderTarget(
RenderTargetKey key, ID3D12Resource* resource,
ui::d3d12::D3D12CpuDescriptorPool::Descriptor&& descriptor_draw,
ui::d3d12::D3D12CpuDescriptorPool::Descriptor&& descriptor_draw_srgb,
ui::d3d12::D3D12CpuDescriptorPool::Descriptor&&
descriptor_load_separate,
ui::d3d12::D3D12CpuDescriptorPool::Descriptor&& descriptor_srv,
@@ -243,7 +243,6 @@ class D3D12RenderTargetCache final : public RenderTargetCache {
: RenderTarget(key),
resource_(resource),
descriptor_draw_(std::move(descriptor_draw)),
descriptor_draw_srgb_(std::move(descriptor_draw_srgb)),
descriptor_load_separate_(std::move(descriptor_load_separate)),
descriptor_srv_(std::move(descriptor_srv)),
descriptor_srv_stencil_(std::move(descriptor_srv_stencil)),
@@ -254,10 +253,6 @@ class D3D12RenderTargetCache final : public RenderTargetCache {
const {
return descriptor_draw_;
}
const ui::d3d12::D3D12CpuDescriptorPool::Descriptor& descriptor_draw_srgb()
const {
return descriptor_draw_srgb_;
}
const ui::d3d12::D3D12CpuDescriptorPool::Descriptor& descriptor_srv()
const {
return descriptor_srv_;
@@ -297,7 +292,6 @@ class D3D12RenderTargetCache final : public RenderTargetCache {
private:
Microsoft::WRL::ComPtr<ID3D12Resource> resource_;
ui::d3d12::D3D12CpuDescriptorPool::Descriptor descriptor_draw_;
ui::d3d12::D3D12CpuDescriptorPool::Descriptor descriptor_draw_srgb_;
ui::d3d12::D3D12CpuDescriptorPool::Descriptor descriptor_load_separate_;
// Texture SRV non-shader-visible descriptors, to prepare shader-visible
// descriptors faster, by copying rather than by creating every time.
@@ -617,7 +611,7 @@ class D3D12RenderTargetCache final : public RenderTargetCache {
// May be different for different sources.
kDumpRootParameterColorPitches = kDumpRootParameterSource + 1,
// Only changed between 32bpp and 64bpp.
// Not changed.
kDumpRootParameterColorEdram,
kDumpRootParameterColorCount,
@@ -718,7 +712,7 @@ class D3D12RenderTargetCache final : public RenderTargetCache {
bool use_stencil_reference_output_ = false;
bool gamma_render_target_as_srgb_ = false;
bool gamma_render_target_as_unorm16_ = false;
bool depth_float24_round_ = false;
bool depth_float24_convert_in_pixel_shader_ = false;
@@ -753,7 +747,6 @@ class D3D12RenderTargetCache final : public RenderTargetCache {
const RenderTarget* const*
current_command_list_render_targets_[1 + xenos::kMaxColorRenderTargets];
uint32_t are_current_command_list_render_targets_srgb_ = 0;
bool are_current_command_list_render_targets_valid_ = false;
// Temporary storage for descriptors used in PerformTransfersAndResolveClears

View File

@@ -107,47 +107,11 @@ bool D3D12SharedMemory::Initialize() {
provider.OffsetViewDescriptor(buffer_descriptor_heap_start_,
uint32_t(BufferDescriptorIndex::kRawSRV)),
buffer_, kBufferSize);
ui::d3d12::util::CreateBufferTypedSRV(
device,
provider.OffsetViewDescriptor(
buffer_descriptor_heap_start_,
uint32_t(BufferDescriptorIndex::kR32UintSRV)),
buffer_, DXGI_FORMAT_R32_UINT, kBufferSize >> 2);
ui::d3d12::util::CreateBufferTypedSRV(
device,
provider.OffsetViewDescriptor(
buffer_descriptor_heap_start_,
uint32_t(BufferDescriptorIndex::kR32G32UintSRV)),
buffer_, DXGI_FORMAT_R32G32_UINT, kBufferSize >> 3);
ui::d3d12::util::CreateBufferTypedSRV(
device,
provider.OffsetViewDescriptor(
buffer_descriptor_heap_start_,
uint32_t(BufferDescriptorIndex::kR32G32B32A32UintSRV)),
buffer_, DXGI_FORMAT_R32G32B32A32_UINT, kBufferSize >> 4);
ui::d3d12::util::CreateBufferRawUAV(
device,
provider.OffsetViewDescriptor(buffer_descriptor_heap_start_,
uint32_t(BufferDescriptorIndex::kRawUAV)),
buffer_, kBufferSize);
ui::d3d12::util::CreateBufferTypedUAV(
device,
provider.OffsetViewDescriptor(
buffer_descriptor_heap_start_,
uint32_t(BufferDescriptorIndex::kR32UintUAV)),
buffer_, DXGI_FORMAT_R32_UINT, kBufferSize >> 2);
ui::d3d12::util::CreateBufferTypedUAV(
device,
provider.OffsetViewDescriptor(
buffer_descriptor_heap_start_,
uint32_t(BufferDescriptorIndex::kR32G32UintUAV)),
buffer_, DXGI_FORMAT_R32G32_UINT, kBufferSize >> 3);
ui::d3d12::util::CreateBufferTypedUAV(
device,
provider.OffsetViewDescriptor(
buffer_descriptor_heap_start_,
uint32_t(BufferDescriptorIndex::kR32G32B32A32UintUAV)),
buffer_, DXGI_FORMAT_R32G32B32A32_UINT, kBufferSize >> 4);
upload_buffer_pool_ = std::make_unique<ui::d3d12::D3D12UploadBufferPool>(
provider, xe::align(ui::d3d12::D3D12UploadBufferPool::kDefaultPageSize,
@@ -233,60 +197,6 @@ void D3D12SharedMemory::WriteRawUAVDescriptor(
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
}
void D3D12SharedMemory::WriteUintPow2SRVDescriptor(
D3D12_CPU_DESCRIPTOR_HANDLE handle, uint32_t element_size_bytes_pow2) {
BufferDescriptorIndex descriptor_index;
switch (element_size_bytes_pow2) {
case 2:
descriptor_index = BufferDescriptorIndex::kR32UintSRV;
break;
case 3:
descriptor_index = BufferDescriptorIndex::kR32G32UintSRV;
break;
case 4:
descriptor_index = BufferDescriptorIndex::kR32G32B32A32UintSRV;
break;
default:
assert_unhandled_case(element_size_bytes_pow2);
return;
}
const ui::d3d12::D3D12Provider& provider =
command_processor_.GetD3D12Provider();
ID3D12Device* device = provider.GetDevice();
device->CopyDescriptorsSimple(
1, handle,
provider.OffsetViewDescriptor(buffer_descriptor_heap_start_,
uint32_t(descriptor_index)),
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
}
void D3D12SharedMemory::WriteUintPow2UAVDescriptor(
D3D12_CPU_DESCRIPTOR_HANDLE handle, uint32_t element_size_bytes_pow2) {
BufferDescriptorIndex descriptor_index;
switch (element_size_bytes_pow2) {
case 2:
descriptor_index = BufferDescriptorIndex::kR32UintUAV;
break;
case 3:
descriptor_index = BufferDescriptorIndex::kR32G32UintUAV;
break;
case 4:
descriptor_index = BufferDescriptorIndex::kR32G32B32A32UintUAV;
break;
default:
assert_unhandled_case(element_size_bytes_pow2);
return;
}
const ui::d3d12::D3D12Provider& provider =
command_processor_.GetD3D12Provider();
ID3D12Device* device = provider.GetDevice();
device->CopyDescriptorsSimple(
1, handle,
provider.OffsetViewDescriptor(buffer_descriptor_heap_start_,
uint32_t(descriptor_index)),
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
}
bool D3D12SharedMemory::InitializeTraceSubmitDownloads() {
ResetTraceDownload();
PrepareForTraceDownload();
@@ -453,7 +363,7 @@ bool D3D12SharedMemory::UploadRanges(
return false;
}
MakeRangeValid(upload_range_start << page_size_log2(),
uint32_t(upload_buffer_size), false, false);
uint32_t(upload_buffer_size), false);
if (upload_buffer_size < (1ULL << 32) && upload_buffer_size > 8192) {
memory::vastcpy(

View File

@@ -76,12 +76,6 @@ class D3D12SharedMemory : public SharedMemory {
void WriteRawSRVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle);
void WriteRawUAVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle);
// Due to the D3D12_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP limitation, the
// smallest supported formats are 32-bit.
void WriteUintPow2SRVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle,
uint32_t element_size_bytes_pow2);
void WriteUintPow2UAVDescriptor(D3D12_CPU_DESCRIPTOR_HANDLE handle,
uint32_t element_size_bytes_pow2);
// Returns true if any downloads were submitted to the command processor.
bool InitializeTraceSubmitDownloads();
@@ -110,13 +104,7 @@ class D3D12SharedMemory : public SharedMemory {
// rather than creation).
enum class BufferDescriptorIndex : uint32_t {
kRawSRV,
kR32UintSRV,
kR32G32UintSRV,
kR32G32B32A32UintSRV,
kRawUAV,
kR32UintUAV,
kR32G32UintUAV,
kR32G32B32A32UintUAV,
kCount,
};

View File

@@ -151,26 +151,14 @@ bool D3D12TextureCache::Initialize() {
root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
// Parameter 1 is the source (may be changed multiple times for the same
// destination).
D3D12_DESCRIPTOR_RANGE root_dest_range;
root_dest_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
root_dest_range.NumDescriptors = 1;
root_dest_range.BaseShaderRegister = 0;
root_dest_range.RegisterSpace = 0;
root_dest_range.OffsetInDescriptorsFromTableStart = 0;
root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
root_parameters[1].DescriptorTable.NumDescriptorRanges = 1;
root_parameters[1].DescriptorTable.pDescriptorRanges = &root_dest_range;
root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV;
root_parameters[1].Descriptor.ShaderRegister = 0;
root_parameters[1].Descriptor.RegisterSpace = 0;
root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
// Parameter 2 is the destination.
D3D12_DESCRIPTOR_RANGE root_source_range;
root_source_range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
root_source_range.NumDescriptors = 1;
root_source_range.BaseShaderRegister = 0;
root_source_range.RegisterSpace = 0;
root_source_range.OffsetInDescriptorsFromTableStart = 0;
root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
root_parameters[2].DescriptorTable.NumDescriptorRanges = 1;
root_parameters[2].DescriptorTable.pDescriptorRanges = &root_source_range;
root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
root_parameters[2].Descriptor.ShaderRegister = 0;
root_parameters[2].Descriptor.RegisterSpace = 0;
root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
root_signature_desc.NumParameters = UINT(xe::countof(root_parameters));
@@ -1183,40 +1171,16 @@ void D3D12TextureCache::TransitionCurrentScaledResolveRange(
buffer.resource(), buffer.SetResourceState(new_state), new_state);
}
void D3D12TextureCache::CreateCurrentScaledResolveRangeUintPow2SRV(
D3D12_CPU_DESCRIPTOR_HANDLE handle, uint32_t element_size_bytes_pow2) {
D3D12_GPU_VIRTUAL_ADDRESS
D3D12TextureCache::GetCurrentScaledResolveRangeGPUAddress() const {
assert_true(IsDrawResolutionScaled());
size_t buffer_index = GetCurrentScaledResolveBufferIndex();
const size_t buffer_index = GetCurrentScaledResolveBufferIndex();
const ScaledResolveVirtualBuffer* buffer =
scaled_resolve_2gb_buffers_[buffer_index].get();
assert_not_null(buffer);
ui::d3d12::util::CreateBufferTypedSRV(
command_processor_.GetD3D12Provider().GetDevice(), handle,
buffer->resource(),
ui::d3d12::util::GetUintPow2DXGIFormat(element_size_bytes_pow2),
uint32_t(scaled_resolve_current_range_length_scaled_ >>
element_size_bytes_pow2),
(scaled_resolve_current_range_start_scaled_ -
(uint64_t(buffer_index) << 30)) >>
element_size_bytes_pow2);
}
void D3D12TextureCache::CreateCurrentScaledResolveRangeUintPow2UAV(
D3D12_CPU_DESCRIPTOR_HANDLE handle, uint32_t element_size_bytes_pow2) {
assert_true(IsDrawResolutionScaled());
size_t buffer_index = GetCurrentScaledResolveBufferIndex();
const ScaledResolveVirtualBuffer* buffer =
scaled_resolve_2gb_buffers_[buffer_index].get();
assert_not_null(buffer);
ui::d3d12::util::CreateBufferTypedUAV(
command_processor_.GetD3D12Provider().GetDevice(), handle,
buffer->resource(),
ui::d3d12::util::GetUintPow2DXGIFormat(element_size_bytes_pow2),
uint32_t(scaled_resolve_current_range_length_scaled_ >>
element_size_bytes_pow2),
(scaled_resolve_current_range_start_scaled_ -
(uint64_t(buffer_index) << 30)) >>
element_size_bytes_pow2);
return buffer->resource()->GetGPUVirtualAddress() +
(scaled_resolve_current_range_start_scaled_ -
(uint64_t(buffer_index) << 30));
}
ID3D12Resource* D3D12TextureCache::RequestSwapTexture(
@@ -1566,61 +1530,18 @@ bool D3D12TextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture,
return false;
}
// Begin loading.
// May use different buffers for scaled base and mips, and also addressability
// of more than 128 * 2^20 (2^D3D12_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP)
// texels is not mandatory - need two separate UAV descriptors for base and
// mips.
// Destination.
uint32_t descriptor_count = 1;
if (texture_resolution_scaled) {
// Source - base and mips, one or both.
descriptor_count += (level_first == 0 && level_last != 0) ? 2 : 1;
} else {
// Source - shared memory.
if (!bindless_resources_used_) {
++descriptor_count;
}
}
ui::d3d12::util::DescriptorCpuGpuHandlePair descriptors_allocated[3];
if (!command_processor_.RequestOneUseSingleViewDescriptors(
descriptor_count, descriptors_allocated)) {
command_processor_.ReleaseScratchGPUBuffer(copy_buffer, copy_buffer_state);
return false;
}
uint32_t descriptor_write_index = 0;
command_processor_.SetExternalPipeline(pipeline);
command_list.D3DSetComputeRootSignature(load_root_signature_.Get());
// Set up the destination descriptor.
assert_true(descriptor_write_index < descriptor_count);
ui::d3d12::util::DescriptorCpuGpuHandlePair descriptor_dest =
descriptors_allocated[descriptor_write_index++];
ui::d3d12::util::CreateBufferTypedUAV(
device, descriptor_dest.first, copy_buffer,
ui::d3d12::util::GetUintPow2DXGIFormat(load_shader_info.dest_bpe_log2),
uint32_t(copy_buffer_size) >> load_shader_info.dest_bpe_log2);
command_list.D3DSetComputeRootDescriptorTable(2, descriptor_dest.second);
// Set up the unscaled source descriptor (scaled needs two descriptors that
// depend on the buffer being current, so they will be set later - for mips,
// after loading the base is done).
command_list.D3DSetComputeRootUnorderedAccessView(
2, copy_buffer->GetGPUVirtualAddress());
// Set up the unscaled source binding (scaled may have the base and the mips
// in different buffer resources).
if (!texture_resolution_scaled) {
D3D12SharedMemory& d3d12_shared_memory =
static_cast<D3D12SharedMemory&>(shared_memory());
d3d12_shared_memory.UseForReading();
ui::d3d12::util::DescriptorCpuGpuHandlePair descriptor_unscaled_source;
if (bindless_resources_used_) {
descriptor_unscaled_source =
command_processor_.GetSharedMemoryUintPow2BindlessSRVHandlePair(
load_shader_info.source_bpe_log2);
} else {
assert_true(descriptor_write_index < descriptor_count);
descriptor_unscaled_source =
descriptors_allocated[descriptor_write_index++];
d3d12_shared_memory.WriteUintPow2SRVDescriptor(
descriptor_unscaled_source.first, load_shader_info.source_bpe_log2);
}
command_list.D3DSetComputeRootDescriptorTable(
1, descriptor_unscaled_source.second);
command_list.D3DSetComputeRootShaderResourceView(
1, d3d12_shared_memory.GetGPUAddress());
}
// Submit the copy buffer population commands.
@@ -1656,20 +1577,15 @@ bool D3D12TextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture,
uint32_t guest_size_unscaled = is_base ? d3d12_texture.GetGuestBaseSize()
: d3d12_texture.GetGuestMipsSize();
if (!MakeScaledResolveRangeCurrent(guest_address, guest_size_unscaled,
load_shader_info.source_bpe_log2)) {
4)) {
command_processor_.ReleaseScratchGPUBuffer(copy_buffer,
copy_buffer_state);
return false;
}
TransitionCurrentScaledResolveRange(
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
assert_true(descriptor_write_index < descriptor_count);
ui::d3d12::util::DescriptorCpuGpuHandlePair descriptor_scaled_source =
descriptors_allocated[descriptor_write_index++];
CreateCurrentScaledResolveRangeUintPow2SRV(
descriptor_scaled_source.first, load_shader_info.source_bpe_log2);
command_list.D3DSetComputeRootDescriptorTable(
1, descriptor_scaled_source.second);
command_list.D3DSetComputeRootShaderResourceView(
1, GetCurrentScaledResolveRangeGPUAddress());
if (!is_base) {
scaled_mips_source_set_up = true;
}

View File

@@ -137,13 +137,9 @@ class D3D12TextureCache final : public TextureCache {
bool MakeScaledResolveRangeCurrent(uint32_t start_unscaled,
uint32_t length_unscaled,
uint32_t length_scaled_alignment_log2 = 0);
// These functions create a view of the range specified in the last successful
// MakeScaledResolveRangeCurrent call because that function must be called
// before this.
void CreateCurrentScaledResolveRangeUintPow2SRV(
D3D12_CPU_DESCRIPTOR_HANDLE handle, uint32_t element_size_bytes_pow2);
void CreateCurrentScaledResolveRangeUintPow2UAV(
D3D12_CPU_DESCRIPTOR_HANDLE handle, uint32_t element_size_bytes_pow2);
// Returns the GPU address of the range specified in the last successful
// MakeScaledResolveRangeCurrent call.
D3D12_GPU_VIRTUAL_ADDRESS GetCurrentScaledResolveRangeGPUAddress() const;
void TransitionCurrentScaledResolveRange(D3D12_RESOURCE_STATES new_state);
void MarkCurrentScaledResolveRangeUAVWritesCommitNeeded() {
assert_true(IsDrawResolutionScaled());

View File

@@ -183,15 +183,13 @@ void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list,
} break;
case Command::kD3DSetComputeRootConstantBufferView: {
auto& args =
*reinterpret_cast<const SetRootConstantBufferViewArguments*>(
stream);
*reinterpret_cast<const SetRootDescriptorArguments*>(stream);
command_list->SetComputeRootConstantBufferView(
args.root_parameter_index, args.buffer_location);
} break;
case Command::kD3DSetGraphicsRootConstantBufferView: {
auto& args =
*reinterpret_cast<const SetRootConstantBufferViewArguments*>(
stream);
*reinterpret_cast<const SetRootDescriptorArguments*>(stream);
command_list->SetGraphicsRootConstantBufferView(
args.root_parameter_index, args.buffer_location);
} break;
@@ -207,6 +205,18 @@ void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list,
command_list->SetGraphicsRootDescriptorTable(args.root_parameter_index,
args.base_descriptor);
} break;
case Command::kD3DSetComputeRootShaderResourceView: {
auto& args =
*reinterpret_cast<const SetRootDescriptorArguments*>(stream);
command_list->SetComputeRootShaderResourceView(
args.root_parameter_index, args.buffer_location);
} break;
case Command::kD3DSetGraphicsRootShaderResourceView: {
auto& args =
*reinterpret_cast<const SetRootDescriptorArguments*>(stream);
command_list->SetGraphicsRootShaderResourceView(
args.root_parameter_index, args.buffer_location);
} break;
case Command::kD3DSetComputeRootSignature: {
command_list->SetComputeRootSignature(
*reinterpret_cast<ID3D12RootSignature* const*>(stream));
@@ -215,6 +225,18 @@ void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list,
command_list->SetGraphicsRootSignature(
*reinterpret_cast<ID3D12RootSignature* const*>(stream));
} break;
case Command::kD3DSetComputeRootUnorderedAccessView: {
auto& args =
*reinterpret_cast<const SetRootDescriptorArguments*>(stream);
command_list->SetComputeRootUnorderedAccessView(
args.root_parameter_index, args.buffer_location);
} break;
case Command::kD3DSetGraphicsRootUnorderedAccessView: {
auto& args =
*reinterpret_cast<const SetRootDescriptorArguments*>(stream);
command_list->SetGraphicsRootUnorderedAccessView(
args.root_parameter_index, args.buffer_location);
} break;
case Command::kSetDescriptorHeaps: {
auto& args =
*reinterpret_cast<const SetDescriptorHeapsArguments*>(stream);

View File

@@ -327,18 +327,18 @@ class DeferredCommandList {
void D3DSetComputeRootConstantBufferView(
UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS buffer_location) {
auto& args = *reinterpret_cast<SetRootConstantBufferViewArguments*>(
auto& args = *reinterpret_cast<SetRootDescriptorArguments*>(
WriteCommand(Command::kD3DSetComputeRootConstantBufferView,
sizeof(SetRootConstantBufferViewArguments)));
sizeof(SetRootDescriptorArguments)));
args.root_parameter_index = root_parameter_index;
args.buffer_location = buffer_location;
}
void D3DSetGraphicsRootConstantBufferView(
UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS buffer_location) {
auto& args = *reinterpret_cast<SetRootConstantBufferViewArguments*>(
auto& args = *reinterpret_cast<SetRootDescriptorArguments*>(
WriteCommand(Command::kD3DSetGraphicsRootConstantBufferView,
sizeof(SetRootConstantBufferViewArguments)));
sizeof(SetRootDescriptorArguments)));
args.root_parameter_index = root_parameter_index;
args.buffer_location = buffer_location;
}
@@ -361,6 +361,24 @@ class DeferredCommandList {
args.base_descriptor.ptr = base_descriptor.ptr;
}
void D3DSetComputeRootShaderResourceView(
UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS buffer_location) {
auto& args = *reinterpret_cast<SetRootDescriptorArguments*>(
WriteCommand(Command::kD3DSetComputeRootShaderResourceView,
sizeof(SetRootDescriptorArguments)));
args.root_parameter_index = root_parameter_index;
args.buffer_location = buffer_location;
}
void D3DSetGraphicsRootShaderResourceView(
UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS buffer_location) {
auto& args = *reinterpret_cast<SetRootDescriptorArguments*>(
WriteCommand(Command::kD3DSetGraphicsRootShaderResourceView,
sizeof(SetRootDescriptorArguments)));
args.root_parameter_index = root_parameter_index;
args.buffer_location = buffer_location;
}
void D3DSetComputeRootSignature(ID3D12RootSignature* root_signature) {
auto& arg = *reinterpret_cast<ID3D12RootSignature**>(WriteCommand(
Command::kD3DSetComputeRootSignature, sizeof(ID3D12RootSignature*)));
@@ -373,6 +391,24 @@ class DeferredCommandList {
arg = root_signature;
}
void D3DSetComputeRootUnorderedAccessView(
UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS buffer_location) {
auto& args = *reinterpret_cast<SetRootDescriptorArguments*>(
WriteCommand(Command::kD3DSetComputeRootUnorderedAccessView,
sizeof(SetRootDescriptorArguments)));
args.root_parameter_index = root_parameter_index;
args.buffer_location = buffer_location;
}
void D3DSetGraphicsRootUnorderedAccessView(
UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS buffer_location) {
auto& args = *reinterpret_cast<SetRootDescriptorArguments*>(
WriteCommand(Command::kD3DSetGraphicsRootUnorderedAccessView,
sizeof(SetRootDescriptorArguments)));
args.root_parameter_index = root_parameter_index;
args.buffer_location = buffer_location;
}
void SetDescriptorHeaps(ID3D12DescriptorHeap* cbv_srv_uav_descriptor_heap,
ID3D12DescriptorHeap* sampler_descriptor_heap) {
auto& args = *reinterpret_cast<SetDescriptorHeapsArguments*>(WriteCommand(
@@ -432,8 +468,12 @@ class DeferredCommandList {
kD3DSetGraphicsRootConstantBufferView,
kD3DSetComputeRootDescriptorTable,
kD3DSetGraphicsRootDescriptorTable,
kD3DSetComputeRootShaderResourceView,
kD3DSetGraphicsRootShaderResourceView,
kD3DSetComputeRootSignature,
kD3DSetGraphicsRootSignature,
kD3DSetComputeRootUnorderedAccessView,
kD3DSetGraphicsRootUnorderedAccessView,
kSetDescriptorHeaps,
kD3DSetPipelineState,
kSetPipelineStateHandle,
@@ -541,7 +581,7 @@ class DeferredCommandList {
UINT dest_offset_in_32bit_values;
};
struct SetRootConstantBufferViewArguments {
struct SetRootDescriptorArguments {
UINT root_parameter_index;
D3D12_GPU_VIRTUAL_ADDRESS buffer_location;
};

View File

@@ -94,7 +94,8 @@ PipelineCache::PipelineCache(D3D12CommandProcessor& command_processor,
shader_translator_ = std::make_unique<DxbcShaderTranslator>(
provider.GetAdapterVendorID(), bindless_resources_used_, edram_rov_used,
render_target_cache_.gamma_render_target_as_srgb(),
!(edram_rov_used ||
render_target_cache_.gamma_render_target_as_unorm16()),
render_target_cache_.msaa_2x_supported(),
render_target_cache_.draw_resolution_scale_x(),
render_target_cache_.draw_resolution_scale_y(),
@@ -387,7 +388,9 @@ void PipelineCache::InitializeShaderStorage(
StringBuffer ucode_disasm_buffer;
DxbcShaderTranslator translator(
provider.GetAdapterVendorID(), bindless_resources_used_,
edram_rov_used, render_target_cache_.gamma_render_target_as_srgb(),
edram_rov_used,
!(edram_rov_used ||
render_target_cache_.gamma_render_target_as_unorm16()),
render_target_cache_.msaa_2x_supported(),
render_target_cache_.draw_resolution_scale_x(),
render_target_cache_.draw_resolution_scale_y(),