diff --git a/src/xenia/gpu/d3d12/d3d12_command_processor.cc b/src/xenia/gpu/d3d12/d3d12_command_processor.cc index 7f426fbac..f5de017bb 100644 --- a/src/xenia/gpu/d3d12/d3d12_command_processor.cc +++ b/src/xenia/gpu/d3d12/d3d12_command_processor.cc @@ -616,48 +616,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 { @@ -1705,46 +1663,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( diff --git a/src/xenia/gpu/d3d12/d3d12_command_processor.h b/src/xenia/gpu/d3d12/d3d12_command_processor.h index c14371b58..85ccb25fc 100644 --- a/src/xenia/gpu/d3d12/d3d12_command_processor.h +++ b/src/xenia/gpu/d3d12/d3d12_command_processor.h @@ -176,13 +176,6 @@ class D3D12CommandProcessor final : public CommandProcessor { kNullRawSRV = kNullRawSRVAndSharedMemoryRawUAVStart, kSharedMemoryRawUAV, - kSharedMemoryR32UintSRV, - kSharedMemoryR32G32UintSRV, - kSharedMemoryR32G32B32A32UintSRV, - kSharedMemoryR32UintUAV, - kSharedMemoryR32G32UintUAV, - kSharedMemoryR32G32B32A32UintUAV, - kEdramRawSRV, kEdramR32UintSRV, kEdramR32G32UintSRV, @@ -208,12 +201,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; diff --git a/src/xenia/gpu/d3d12/d3d12_render_target_cache.cc b/src/xenia/gpu/d3d12/d3d12_render_target_cache.cc index f12864249..ba4951525 100644 --- a/src/xenia/gpu/d3d12/d3d12_render_target_cache.cc +++ b/src/xenia/gpu/d3d12/d3d12_render_target_cache.cc @@ -247,6 +247,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; @@ -337,31 +338,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; @@ -557,20 +542,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; @@ -1022,18 +998,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; @@ -1387,95 +1355,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), - ©_shader_constants.dest_relative, 0); - } else { - command_list.D3DSetComputeRoot32BitConstants( - 0, sizeof(copy_shader_constants) / sizeof(uint32_t), - ©_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), + ©_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), + ©_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 " @@ -1519,76 +1444,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 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 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()); @@ -4576,38 +4482,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(), diff --git a/src/xenia/gpu/d3d12/d3d12_render_target_cache.h b/src/xenia/gpu/d3d12/d3d12_render_target_cache.h index 3a5dbaeb0..db2ce8a26 100644 --- a/src/xenia/gpu/d3d12/d3d12_render_target_cache.h +++ b/src/xenia/gpu/d3d12/d3d12_render_target_cache.h @@ -180,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; diff --git a/src/xenia/gpu/d3d12/d3d12_shared_memory.cc b/src/xenia/gpu/d3d12/d3d12_shared_memory.cc index 51d384609..c3fd75cb7 100644 --- a/src/xenia/gpu/d3d12/d3d12_shared_memory.cc +++ b/src/xenia/gpu/d3d12/d3d12_shared_memory.cc @@ -233,60 +233,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(); diff --git a/src/xenia/gpu/d3d12/d3d12_shared_memory.h b/src/xenia/gpu/d3d12/d3d12_shared_memory.h index 73cff2e7b..87cb116c0 100644 --- a/src/xenia/gpu/d3d12/d3d12_shared_memory.h +++ b/src/xenia/gpu/d3d12/d3d12_shared_memory.h @@ -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(); diff --git a/src/xenia/gpu/d3d12/d3d12_texture_cache.cc b/src/xenia/gpu/d3d12/d3d12_texture_cache.cc index 32f225024..afdeeddb8 100644 --- a/src/xenia/gpu/d3d12/d3d12_texture_cache.cc +++ b/src/xenia/gpu/d3d12/d3d12_texture_cache.cc @@ -183,26 +183,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)); @@ -1283,40 +1271,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( @@ -1678,61 +1642,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(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. @@ -1774,20 +1695,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; } diff --git a/src/xenia/gpu/d3d12/d3d12_texture_cache.h b/src/xenia/gpu/d3d12/d3d12_texture_cache.h index 8ef39abc4..dc2673cf2 100644 --- a/src/xenia/gpu/d3d12/d3d12_texture_cache.h +++ b/src/xenia/gpu/d3d12/d3d12_texture_cache.h @@ -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()); diff --git a/src/xenia/gpu/d3d12/deferred_command_list.cc b/src/xenia/gpu/d3d12/deferred_command_list.cc index 2783d91d7..e21d990a4 100644 --- a/src/xenia/gpu/d3d12/deferred_command_list.cc +++ b/src/xenia/gpu/d3d12/deferred_command_list.cc @@ -200,15 +200,13 @@ void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list, } break; case Command::kD3DSetComputeRootConstantBufferView: { auto& args = - *reinterpret_cast( - stream); + *reinterpret_cast(stream); command_list->SetComputeRootConstantBufferView( args.root_parameter_index, args.buffer_location); } break; case Command::kD3DSetGraphicsRootConstantBufferView: { auto& args = - *reinterpret_cast( - stream); + *reinterpret_cast(stream); command_list->SetGraphicsRootConstantBufferView( args.root_parameter_index, args.buffer_location); } break; @@ -224,6 +222,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(stream); + command_list->SetComputeRootShaderResourceView( + args.root_parameter_index, args.buffer_location); + } break; + case Command::kD3DSetGraphicsRootShaderResourceView: { + auto& args = + *reinterpret_cast(stream); + command_list->SetGraphicsRootShaderResourceView( + args.root_parameter_index, args.buffer_location); + } break; case Command::kD3DSetComputeRootSignature: { command_list->SetComputeRootSignature( *reinterpret_cast(stream)); @@ -232,6 +242,18 @@ void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list, command_list->SetGraphicsRootSignature( *reinterpret_cast(stream)); } break; + case Command::kD3DSetComputeRootUnorderedAccessView: { + auto& args = + *reinterpret_cast(stream); + command_list->SetComputeRootUnorderedAccessView( + args.root_parameter_index, args.buffer_location); + } break; + case Command::kD3DSetGraphicsRootUnorderedAccessView: { + auto& args = + *reinterpret_cast(stream); + command_list->SetGraphicsRootUnorderedAccessView( + args.root_parameter_index, args.buffer_location); + } break; case Command::kSetDescriptorHeaps: { auto& args = *reinterpret_cast(stream); diff --git a/src/xenia/gpu/d3d12/deferred_command_list.h b/src/xenia/gpu/d3d12/deferred_command_list.h index 3d5b1e4db..3bbae0e63 100644 --- a/src/xenia/gpu/d3d12/deferred_command_list.h +++ b/src/xenia/gpu/d3d12/deferred_command_list.h @@ -357,18 +357,18 @@ class DeferredCommandList { void D3DSetComputeRootConstantBufferView( UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS buffer_location) { - auto& args = *reinterpret_cast( + auto& args = *reinterpret_cast( 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( + auto& args = *reinterpret_cast( WriteCommand(Command::kD3DSetGraphicsRootConstantBufferView, - sizeof(SetRootConstantBufferViewArguments))); + sizeof(SetRootDescriptorArguments))); args.root_parameter_index = root_parameter_index; args.buffer_location = buffer_location; } @@ -391,6 +391,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( + 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( + 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(WriteCommand( Command::kD3DSetComputeRootSignature, sizeof(ID3D12RootSignature*))); @@ -403,6 +421,24 @@ class DeferredCommandList { arg = root_signature; } + void D3DSetComputeRootUnorderedAccessView( + UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS buffer_location) { + auto& args = *reinterpret_cast( + 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( + 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(WriteCommand( @@ -489,8 +525,12 @@ class DeferredCommandList { kD3DSetGraphicsRootConstantBufferView, kD3DSetComputeRootDescriptorTable, kD3DSetGraphicsRootDescriptorTable, + kD3DSetComputeRootShaderResourceView, + kD3DSetGraphicsRootShaderResourceView, kD3DSetComputeRootSignature, kD3DSetGraphicsRootSignature, + kD3DSetComputeRootUnorderedAccessView, + kD3DSetGraphicsRootUnorderedAccessView, kSetDescriptorHeaps, kD3DSetPipelineState, kSetPipelineStateHandle, @@ -616,7 +656,7 @@ class DeferredCommandList { UINT dest_offset_in_32bit_values; }; - struct SetRootConstantBufferViewArguments { + struct SetRootDescriptorArguments { UINT root_parameter_index; D3D12_GPU_VIRTUAL_ADDRESS buffer_location; }; diff --git a/src/xenia/gpu/draw_util.cc b/src/xenia/gpu/draw_util.cc index 4206ecd17..c9465ab71 100644 --- a/src/xenia/gpu/draw_util.cc +++ b/src/xenia/gpu/draw_util.cc @@ -935,15 +935,15 @@ void GetResolveEdramTileSpan(ResolveEdramInfo edram_info, constexpr ResolveCopyShaderInfo resolve_copy_shader_info[size_t(ResolveCopyShaderIndex::kCount)] = { - {"Resolve Copy Fast 32bpp 1x/2xMSAA", false, 4, 4, 6, 3}, - {"Resolve Copy Fast 32bpp 4xMSAA", false, 4, 4, 6, 3}, - {"Resolve Copy Fast 64bpp 1x/2xMSAA", false, 4, 4, 5, 3}, - {"Resolve Copy Fast 64bpp 4xMSAA", false, 3, 4, 5, 3}, - {"Resolve Copy Full 8bpp", true, 2, 3, 6, 3}, - {"Resolve Copy Full 16bpp", true, 2, 3, 5, 3}, - {"Resolve Copy Full 32bpp", true, 2, 4, 5, 3}, - {"Resolve Copy Full 64bpp", true, 2, 4, 5, 3}, - {"Resolve Copy Full 128bpp", true, 2, 4, 4, 3}, + {"Resolve Copy Fast 32bpp 1x/2xMSAA", 6, 3}, + {"Resolve Copy Fast 32bpp 4xMSAA", 6, 3}, + {"Resolve Copy Fast 64bpp 1x/2xMSAA", 5, 3}, + {"Resolve Copy Fast 64bpp 4xMSAA", 5, 3}, + {"Resolve Copy Full 8bpp", 6, 3}, + {"Resolve Copy Full 16bpp", 5, 3}, + {"Resolve Copy Full 32bpp", 5, 3}, + {"Resolve Copy Full 64bpp", 5, 3}, + {"Resolve Copy Full 128bpp", 4, 3}, }; XE_MSVC_OPTIMIZE_SMALL() bool GetResolveInfo(const RegisterFile& regs, const Memory& memory, diff --git a/src/xenia/gpu/draw_util.h b/src/xenia/gpu/draw_util.h index 46a50af77..104e8118b 100644 --- a/src/xenia/gpu/draw_util.h +++ b/src/xenia/gpu/draw_util.h @@ -593,20 +593,6 @@ enum class ResolveCopyShaderIndex { struct ResolveCopyShaderInfo { // Debug name of the pipeline state object with this shader. const char* debug_name; - // Whether the EDRAM source needs be bound as a raw buffer (ByteAddressBuffer - // in Direct3D) since it can load different numbers of 32-bit values at once - // on some hardware. If the host API doesn't support raw buffers, a typed - // buffer with source_bpe_log2-byte elements needs to be used instead. - bool source_is_raw; - // Log2 of bytes per element of the type of the EDRAM buffer bound to the - // shader (at least 2). - uint32_t source_bpe_log2; - // Log2 of bytes per element of the type of the destination buffer bound to - // the shader (at least 2 because of the 128 megatexel minimum requirement on - // Direct3D 10+ - D3D12_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP - that - // prevents binding the entire shared memory buffer with smaller element - // sizes). - uint32_t dest_bpe_log2; // Log2 of number of pixels in a single thread group along X and Y. 64 threads // per group preferred (GCN lane count). uint32_t group_size_x_log2, group_size_y_log2; diff --git a/src/xenia/gpu/shaders/bytecode/.clang-format b/src/xenia/gpu/shaders/bytecode/.clang-format deleted file mode 100644 index 9d159247d..000000000 --- a/src/xenia/gpu/shaders/bytecode/.clang-format +++ /dev/null @@ -1,2 +0,0 @@ -DisableFormat: true -SortIncludes: false diff --git a/src/xenia/gpu/shaders/edram.xesli b/src/xenia/gpu/shaders/edram.xesli index 28029e6da..a306c45fa 100644 --- a/src/xenia/gpu/shaders/edram.xesli +++ b/src/xenia/gpu/shaders/edram.xesli @@ -20,10 +20,10 @@ // can't exceed 11 bits, and the modulo operator doesn't need to be performed to // access the data in the render targets that are located in both ends of the // EDRAM at the same time. -uint XeEdramOffsetInts(uint2_xe pixel_index, uint base_tiles, bool wrap, - uint pitch_tiles, uint msaa_samples, bool is_depth, - uint format_ints_log2, uint pixel_sample_index, - uint2_xe resolution_scale) { +uint XeEdramOffsetBytes(uint2_xe pixel_index, uint base_tiles, bool wrap, + uint pitch_tiles, uint msaa_samples, bool is_depth, + uint format_ints_log2, uint pixel_sample_index, + uint2_xe resolution_scale) { uint2_xe rt_sample_index = pixel_index << uint2_xe(greater_than_equal_xe( @@ -54,7 +54,7 @@ uint XeEdramOffsetInts(uint2_xe pixel_index, uint base_tiles, bool wrap, // EDRAM addressing is periodic (modulo the EDRAM size). address %= tile_size_at_32bpp.x * tile_size_at_32bpp.y * 2048u; } - return address; + return address << 2; } #endif // XENIA_GPU_SHADERS_EDRAM_XESLI_ diff --git a/src/xenia/gpu/shaders/host_depth_store_1xmsaa.cs.xesl b/src/xenia/gpu/shaders/host_depth_store_1xmsaa.cs.xesl index 4e389f1df..17c568960 100644 --- a/src/xenia/gpu/shaders/host_depth_store_1xmsaa.cs.xesl +++ b/src/xenia/gpu/shaders/host_depth_store_1xmsaa.cs.xesl @@ -10,15 +10,15 @@ #include "edram.xesli" #include "host_depth_store.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_host_depth_store_dest, set=0, binding=0, - u0, space0) +byte_buffer_align16_wo_declare_xe(xe_host_depth_store_dest, set=0, binding=0, + u0, space0) #define LOCAL_SIZE_X_XE 8 #define LOCAL_SIZE_Y_XE 8 #define LOCAL_SIZE_Z_XE 1 entry_bindings_begin_compute_xe XE_HOST_DEPTH_STORE_PUSH_CONSTANTS_BINDING entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_host_depth_store_dest, buffer(1)) + byte_buffer_wo_binding_xe(xe_host_depth_store_dest, buffer(1)) entry_binding_next_xe texture_xe(texture_2d_xe, xe_host_depth_store_source, set=1, binding=0, t0, space0, texture(0)) @@ -40,14 +40,12 @@ entry_inputs_end_code_begin_compute_xe int2_xe pixel_index = int2_xe( XeHostDepthStoreRectUnscaledOrigin(rect_constant) * resolution_scale + (in_global_thread_id_xe.xy << uint2_xe(3u, 0u))); - uint edram_address_int4s = - XeEdramOffsetInts(uint2_xe(pixel_index), 0u, false, - XeHostDepthStoreRTPitchTiles(rt_constant), - kXenosMsaaSamples_1X, false, 0u, 0u, - resolution_scale) - >> 2u; - array_buffer_store_xe( - xe_host_depth_store_dest, edram_address_int4s, + uint edram_address = XeEdramOffsetBytes( + uint2_xe(pixel_index), 0u, false, + XeHostDepthStoreRTPitchTiles(rt_constant), kXenosMsaaSamples_1X, false, + 0u, 0u, resolution_scale); + byte_buffer_align16_store16_xe( + xe_host_depth_store_dest, edram_address, float_bits_to_uint_xe(float4_xe( texel_fetch_2d_xe(xe_host_depth_store_source, pixel_index, 0).r, texel_fetch_2d_xe(xe_host_depth_store_source, @@ -56,8 +54,8 @@ entry_inputs_end_code_begin_compute_xe pixel_index + int2_xe(2, 0), 0).r, texel_fetch_2d_xe(xe_host_depth_store_source, pixel_index + int2_xe(3, 0), 0).r))); - array_buffer_store_xe( - xe_host_depth_store_dest, edram_address_int4s + 1u, + byte_buffer_align16_store16_xe( + xe_host_depth_store_dest, edram_address + 16u, float_bits_to_uint_xe(float4_xe( texel_fetch_2d_xe(xe_host_depth_store_source, pixel_index + int2_xe(4, 0), 0).r, diff --git a/src/xenia/gpu/shaders/host_depth_store_2xmsaa.cs.xesl b/src/xenia/gpu/shaders/host_depth_store_2xmsaa.cs.xesl index 4a974d156..ed11fa507 100644 --- a/src/xenia/gpu/shaders/host_depth_store_2xmsaa.cs.xesl +++ b/src/xenia/gpu/shaders/host_depth_store_2xmsaa.cs.xesl @@ -10,15 +10,15 @@ #include "edram.xesli" #include "host_depth_store.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_host_depth_store_dest, set=0, binding=0, - u0, space0) +byte_buffer_align16_wo_declare_xe(xe_host_depth_store_dest, set=0, binding=0, + u0, space0) #define LOCAL_SIZE_X_XE 8 #define LOCAL_SIZE_Y_XE 8 #define LOCAL_SIZE_Z_XE 1 entry_bindings_begin_compute_xe XE_HOST_DEPTH_STORE_PUSH_CONSTANTS_BINDING entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_host_depth_store_dest, buffer(1)) + byte_buffer_wo_binding_xe(xe_host_depth_store_dest, buffer(1)) entry_binding_next_xe texture_xe(texture_2d_ms_xe, xe_host_depth_store_source, set=1, binding=0, t0, space0, texture(0)) @@ -41,20 +41,18 @@ entry_inputs_end_code_begin_compute_xe XeHostDepthStoreRectUnscaledOrigin(rect_constant) * resolution_scale + uint2_xe(in_global_thread_id_xe.x << 3u, in_global_thread_id_xe.y >> 1u)); uint dest_sample_index = in_global_thread_id_xe.y & 1u; - uint edram_address_int4s = - XeEdramOffsetInts(uint2_xe(pixel_index), 0u, false, - XeHostDepthStoreRTPitchTiles(rt_constant), - kXenosMsaaSamples_2X, false, 0u, dest_sample_index, - resolution_scale) - >> 2u; + uint edram_address = XeEdramOffsetBytes( + uint2_xe(pixel_index), 0u, false, + XeHostDepthStoreRTPitchTiles(rt_constant), kXenosMsaaSamples_2X, false, + 0u, dest_sample_index, resolution_scale); // Top and bottom to Direct3D 10.1+ and Vulkan top 1 and bottom 0 (for 2x) or // top-left 0 and bottom-right 3 (for 4x). int source_sample_index = XeHostDepthStoreRTMsaa2xSupported(rt_constant) ? (bool(dest_sample_index) ? 0 : 1) : (bool(dest_sample_index) ? 3 : 0); - array_buffer_store_xe( - xe_host_depth_store_dest, edram_address_int4s, + byte_buffer_align16_store16_xe( + xe_host_depth_store_dest, edram_address, float_bits_to_uint_xe(float4_xe( texel_fetch_2d_ms_xe(xe_host_depth_store_source, pixel_index, source_sample_index).r, @@ -67,8 +65,8 @@ entry_inputs_end_code_begin_compute_xe texel_fetch_2d_ms_xe(xe_host_depth_store_source, pixel_index + int2_xe(3, 0), source_sample_index).r))); - array_buffer_store_xe( - xe_host_depth_store_dest, edram_address_int4s + 1u, + byte_buffer_align16_store16_xe( + xe_host_depth_store_dest, edram_address + 16u, float_bits_to_uint_xe(float4_xe( texel_fetch_2d_ms_xe(xe_host_depth_store_source, pixel_index + int2_xe(4, 0), diff --git a/src/xenia/gpu/shaders/host_depth_store_4xmsaa.cs.xesl b/src/xenia/gpu/shaders/host_depth_store_4xmsaa.cs.xesl index f708fe459..f7433488a 100644 --- a/src/xenia/gpu/shaders/host_depth_store_4xmsaa.cs.xesl +++ b/src/xenia/gpu/shaders/host_depth_store_4xmsaa.cs.xesl @@ -10,15 +10,15 @@ #include "edram.xesli" #include "host_depth_store.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_host_depth_store_dest, set=0, binding=0, - u0, space0) +byte_buffer_align16_wo_declare_xe(xe_host_depth_store_dest, set=0, binding=0, + u0, space0) #define LOCAL_SIZE_X_XE 8 #define LOCAL_SIZE_Y_XE 8 #define LOCAL_SIZE_Z_XE 1 entry_bindings_begin_compute_xe XE_HOST_DEPTH_STORE_PUSH_CONSTANTS_BINDING entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_host_depth_store_dest, buffer(1)) + byte_buffer_wo_binding_xe(xe_host_depth_store_dest, buffer(1)) entry_binding_next_xe texture_xe(texture_2d_ms_xe, xe_host_depth_store_source, set=1, binding=0, t0, space0, texture(0)) @@ -40,18 +40,17 @@ entry_inputs_end_code_begin_compute_xe int2_xe pixel_index = int2_xe( XeHostDepthStoreRectUnscaledOrigin(rect_constant) * resolution_scale + uint2_xe(in_global_thread_id_xe.x << 2u, in_global_thread_id_xe.y >> 1u)); - // For simplicity, passing samples directly, not pixels, to XeEdramOffsetInts. - uint edram_address_int4s = - XeEdramOffsetInts( - (uint2_xe(pixel_index) << 1u) | (in_global_thread_id_xe.xy & 1u), - 0u, false, XeHostDepthStoreRTPitchTiles(rt_constant), - kXenosMsaaSamples_1X, false, 0u, 0u, resolution_scale) - >> 2u; + // For simplicity, passing samples directly, not pixels, to + // XeEdramOffsetBytes. + uint edram_address = XeEdramOffsetBytes( + (uint2_xe(pixel_index) << 1u) | (in_global_thread_id_xe.xy & 1u), 0u, + false, XeHostDepthStoreRTPitchTiles(rt_constant), kXenosMsaaSamples_1X, + false, 0u, 0u, resolution_scale); // Render target horizontal sample in bit 0, vertical sample in bit 1. int source_sample_left = int((in_global_thread_id_xe.y & 1u) << 1u); int source_sample_right = source_sample_left + 1; - array_buffer_store_xe( - xe_host_depth_store_dest, edram_address_int4s, + byte_buffer_align16_store16_xe( + xe_host_depth_store_dest, edram_address, float_bits_to_uint_xe(float4_xe( texel_fetch_2d_ms_xe(xe_host_depth_store_source, pixel_index, source_sample_left).r, @@ -63,8 +62,8 @@ entry_inputs_end_code_begin_compute_xe texel_fetch_2d_ms_xe(xe_host_depth_store_source, pixel_index + int2_xe(1, 0), source_sample_right).r))); - array_buffer_store_xe( - xe_host_depth_store_dest, edram_address_int4s + 1u, + byte_buffer_align16_store16_xe( + xe_host_depth_store_dest, edram_address + 16u, float_bits_to_uint_xe(float4_xe( texel_fetch_2d_ms_xe(xe_host_depth_store_source, pixel_index + int2_xe(2, 0), diff --git a/src/xenia/gpu/shaders/resolve.xesli b/src/xenia/gpu/shaders/resolve.xesli index b7ec4f034..4585be29b 100644 --- a/src/xenia/gpu/shaders/resolve.xesli +++ b/src/xenia/gpu/shaders/resolve.xesli @@ -44,18 +44,22 @@ push_const_end_xe #define XE_RESOLVE_PUSH_CONST_BINDING push_const_binding_xe(buffer(0)) #ifndef XE_RESOLVE_CLEAR - #ifdef XE_RESOLVE_COPY_EDRAM_IS_UINT_VECTOR_BUFFER - uint_vector_buffer_declare_xe(xe_resolve_edram, set=0, binding=0, t0, - space0) - #define XE_RESOLVE_COPY_EDRAM_BINDING \ - uint_vector_buffer_binding_xe(xe_resolve_edram, buffer(2)) - #else - array_buffer_declare_xe(XE_RESOLVE_SOURCE_TYPE, xe_resolve_edram, set=0, - binding=0, t0, space0) - #define XE_RESOLVE_COPY_EDRAM_BINDING \ - array_buffer_binding_xe(XE_RESOLVE_SOURCE_TYPE, xe_resolve_edram, \ - buffer(2)) + #if XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_ALIGNMENT == 4 + #define XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_DECLARE_MACRO \ + byte_buffer_align4_declare_xe + #elif XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_ALIGNMENT == 8 + #define XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_DECLARE_MACRO \ + byte_buffer_align8_declare_xe + #elif XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_ALIGNMENT == 16 + #define XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_DECLARE_MACRO \ + byte_buffer_align16_declare_xe #endif + #ifdef XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_DECLARE_MACRO + XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_DECLARE_MACRO(xe_resolve_edram, set=0, + binding=0, t0, space0) + #endif + #define XE_RESOLVE_COPY_EDRAM_BINDING \ + byte_buffer_binding_xe(xe_resolve_edram, buffer(2)) #endif struct XeResolveInfo { @@ -153,8 +157,8 @@ XeResolveInfo XeResolveGetInfo(param_push_consts_xe) { return resolve_info; } -uint XeResolveEdramPixelStrideInts(XeResolveInfo resolve_info) { - return 1u << (resolve_info.edram_format_ints_log2 + +uint XeResolveEdramPixelStrideBytes(XeResolveInfo resolve_info) { + return 4u << (resolve_info.edram_format_ints_log2 + uint(resolve_info.edram_msaa_samples >= kXenosMsaaSamples_4X)); } @@ -231,9 +235,9 @@ uint XeResolveEdramPixelStrideInts(XeResolveInfo resolve_info) { // Offset to the first sample to participate in averaging (or the sample to be // copied if not averaging). - uint XeResolveColorCopySourcePixelAddressIntsYHalfPixelOffsetFilling( + uint XeResolveColorCopySourcePixelAddressBytesYHalfPixelOffsetFilling( XeResolveInfo resolve_info, uint2_xe pixel_index) { - return XeEdramOffsetInts( + return XeEdramOffsetBytes( uint2_xe(pixel_index.x, max(pixel_index.y, resolve_info.half_pixel_offset_fill_source.y)) + @@ -457,116 +461,114 @@ uint XeResolveEdramPixelStrideInts(XeResolveInfo resolve_info) { } } - #ifdef XE_RESOLVE_COPY_EDRAM_IS_UINT_VECTOR_BUFFER + #if XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_ALIGNMENT == 4 void XeResolveLoad2RGBAUnswappedPixelSamplesFromRaw( - param_uint_vector_buffer_xe(xe_resolve_edram) - param_next_after_uint_vector_buffer_xe - uint sample_address_ints, uint pixel_stride_ints, uint format_ints_log2, - uint format, out_param_xe(float4_xe, pixel_0), + param_byte_buffer_xe(xe_resolve_edram) param_next_after_byte_buffer_xe + uint sample_address_bytes, uint pixel_stride_bytes, + uint format_ints_log2, uint format, out_param_xe(float4_xe, pixel_0), out_param_xe(float4_xe, pixel_1)) { dont_flatten_xe if (format_ints_log2 != 0u) { uint4_xe packed; - dont_flatten_xe if (pixel_stride_ints == 2u) { - packed = uint_vector_buffer_load4_xe( - xe_resolve_edram, sample_address_ints); + dont_flatten_xe if (pixel_stride_bytes == 8u) { + packed = byte_buffer_align4_load16u_xe( + xe_resolve_edram, sample_address_bytes); } else { - packed.xy = uint_vector_buffer_load2_xe( - xe_resolve_edram, sample_address_ints); - packed.zw = uint_vector_buffer_load2_xe( - xe_resolve_edram, sample_address_ints + pixel_stride_ints); + packed.xy = byte_buffer_align4_load8u_xe( + xe_resolve_edram, sample_address_bytes); + packed.zw = byte_buffer_align4_load8u_xe( + xe_resolve_edram, sample_address_bytes + pixel_stride_bytes); } XeResolveUnpack64bpp2Samples(packed, format, pixel_0, pixel_1); } else { uint2_xe packed; - dont_flatten_xe if (pixel_stride_ints == 1u) { - packed = uint_vector_buffer_load2_xe( - xe_resolve_edram, sample_address_ints); + dont_flatten_xe if (pixel_stride_bytes == 4u) { + packed = byte_buffer_align4_load8u_xe( + xe_resolve_edram, sample_address_bytes); } else { - packed.x = uint_vector_buffer_load1_xe( - xe_resolve_edram, sample_address_ints); - packed.y = uint_vector_buffer_load1_xe( - xe_resolve_edram, sample_address_ints + pixel_stride_ints); + packed.x = byte_buffer_align4_load4_xe( + xe_resolve_edram, sample_address_bytes); + packed.y = byte_buffer_align4_load4_xe( + xe_resolve_edram, sample_address_bytes + pixel_stride_bytes); } XeResolveUnpack32bpp2Samples(packed, format, pixel_0, pixel_1); } } void XeResolveLoad4RGBAUnswappedPixelSamplesFromRaw( - param_uint_vector_buffer_xe(xe_resolve_edram) - param_next_after_uint_vector_buffer_xe - uint sample_address_ints, uint pixel_stride_ints, uint format_ints_log2, - uint format, out_param_xe(float4_xe, pixel_0), + param_byte_buffer_xe(xe_resolve_edram) param_next_after_byte_buffer_xe + uint sample_address_bytes, uint pixel_stride_bytes, + uint format_ints_log2, uint format, out_param_xe(float4_xe, pixel_0), out_param_xe(float4_xe, pixel_1), out_param_xe(float4_xe, pixel_2), out_param_xe(float4_xe, pixel_3)) { dont_flatten_xe if (format_ints_log2 != 0u) { uint4_xe packed_01, packed_23; - dont_flatten_xe if (pixel_stride_ints == 2u) { - packed_01 = uint_vector_buffer_load4_xe( - xe_resolve_edram, sample_address_ints); - packed_23 = uint_vector_buffer_load4_xe( - xe_resolve_edram, sample_address_ints + 4u); + dont_flatten_xe if (pixel_stride_bytes == 8u) { + packed_01 = byte_buffer_align4_load16u_xe( + xe_resolve_edram, sample_address_bytes); + packed_23 = byte_buffer_align4_load16u_xe( + xe_resolve_edram, sample_address_bytes + 16u); } else { - packed_01.xy = uint_vector_buffer_load2_xe( - xe_resolve_edram, sample_address_ints); - packed_01.zw = uint_vector_buffer_load2_xe( - xe_resolve_edram, sample_address_ints + pixel_stride_ints); - packed_23.xy = uint_vector_buffer_load2_xe( - xe_resolve_edram, sample_address_ints + 2u * pixel_stride_ints); - packed_23.zw = uint_vector_buffer_load2_xe( - xe_resolve_edram, sample_address_ints + 3u * pixel_stride_ints); + packed_01.xy = byte_buffer_align4_load8u_xe( + xe_resolve_edram, sample_address_bytes); + packed_01.zw = byte_buffer_align4_load8u_xe( + xe_resolve_edram, sample_address_bytes + pixel_stride_bytes); + packed_23.xy = byte_buffer_align4_load8u_xe( + xe_resolve_edram, sample_address_bytes + 2u * pixel_stride_bytes); + packed_23.zw = byte_buffer_align4_load8u_xe( + xe_resolve_edram, sample_address_bytes + 3u * pixel_stride_bytes); } XeResolveUnpack64bpp4Samples(packed_01, packed_23, format, pixel_0, pixel_1, pixel_2, pixel_3); } else { uint4_xe packed; - dont_flatten_xe if (pixel_stride_ints == 1u) { - packed = uint_vector_buffer_load4_xe( - xe_resolve_edram, sample_address_ints); + dont_flatten_xe if (pixel_stride_bytes == 4u) { + packed = byte_buffer_align4_load16u_xe( + xe_resolve_edram, sample_address_bytes); } else { - packed.x = uint_vector_buffer_load1_xe( - xe_resolve_edram, sample_address_ints); - packed.y = uint_vector_buffer_load1_xe( - xe_resolve_edram, sample_address_ints + pixel_stride_ints); - packed.z = uint_vector_buffer_load1_xe( - xe_resolve_edram, sample_address_ints + 2u * pixel_stride_ints); - packed.w = uint_vector_buffer_load1_xe( - xe_resolve_edram, sample_address_ints + 3u * pixel_stride_ints); + packed.x = byte_buffer_align4_load4_xe( + xe_resolve_edram, sample_address_bytes); + packed.y = byte_buffer_align4_load4_xe( + xe_resolve_edram, sample_address_bytes + pixel_stride_bytes); + packed.z = byte_buffer_align4_load4_xe( + xe_resolve_edram, sample_address_bytes + 2u * pixel_stride_bytes); + packed.w = byte_buffer_align4_load4_xe( + xe_resolve_edram, sample_address_bytes + 3u * pixel_stride_bytes); } XeResolveUnpack32bpp4Samples(packed, format, pixel_0, pixel_1, pixel_2, pixel_3); } } - // For red/blue swapping for 64bpp, pre-add 1 to sample_address_ints. + // For red/blue swapping for 64bpp, pre-add 4 to sample_address_bytes. void XeResolveLoad8RedPixelSamplesFromRaw( - param_uint_vector_buffer_xe(xe_resolve_edram) - param_next_after_uint_vector_buffer_xe - uint sample_address_ints, uint pixel_stride_ints, uint format_ints_log2, - uint format, bool swap_32bpp, out_param_xe(float4_xe, pixels_0123), + param_byte_buffer_xe(xe_resolve_edram) param_next_after_byte_buffer_xe + uint sample_address_bytes, uint pixel_stride_bytes, + uint format_ints_log2, uint format, bool swap_32bpp, + out_param_xe(float4_xe, pixels_0123), out_param_xe(float4_xe, pixels_4567)) { uint4_xe packed_0123, packed_4567; - dont_flatten_xe if (pixel_stride_ints == 1u) { - packed_0123 = uint_vector_buffer_load4_xe( - xe_resolve_edram, sample_address_ints); - packed_4567 = uint_vector_buffer_load4_xe( - xe_resolve_edram, sample_address_ints + 4u); + dont_flatten_xe if (pixel_stride_bytes == 4u) { + packed_0123 = byte_buffer_align4_load16u_xe( + xe_resolve_edram, sample_address_bytes); + packed_4567 = byte_buffer_align4_load16u_xe( + xe_resolve_edram, sample_address_bytes + 16u); } else { - packed_0123.x = uint_vector_buffer_load1_xe( - xe_resolve_edram, sample_address_ints); - packed_0123.y = uint_vector_buffer_load1_xe( - xe_resolve_edram, sample_address_ints + pixel_stride_ints); - packed_0123.z = uint_vector_buffer_load1_xe( - xe_resolve_edram, sample_address_ints + 2u * pixel_stride_ints); - packed_0123.w = uint_vector_buffer_load1_xe( - xe_resolve_edram, sample_address_ints + 3u * pixel_stride_ints); - packed_4567.x = uint_vector_buffer_load1_xe( - xe_resolve_edram, sample_address_ints + 4u * pixel_stride_ints); - packed_4567.y = uint_vector_buffer_load1_xe( - xe_resolve_edram, sample_address_ints + 5u * pixel_stride_ints); - packed_4567.z = uint_vector_buffer_load1_xe( - xe_resolve_edram, sample_address_ints + 6u * pixel_stride_ints); - packed_4567.w = uint_vector_buffer_load1_xe( - xe_resolve_edram, sample_address_ints + 7u * pixel_stride_ints); + packed_0123.x = byte_buffer_align4_load4_xe( + xe_resolve_edram, sample_address_bytes); + packed_0123.y = byte_buffer_align4_load4_xe( + xe_resolve_edram, sample_address_bytes + pixel_stride_bytes); + packed_0123.z = byte_buffer_align4_load4_xe( + xe_resolve_edram, sample_address_bytes + 2u * pixel_stride_bytes); + packed_0123.w = byte_buffer_align4_load4_xe( + xe_resolve_edram, sample_address_bytes + 3u * pixel_stride_bytes); + packed_4567.x = byte_buffer_align4_load4_xe( + xe_resolve_edram, sample_address_bytes + 4u * pixel_stride_bytes); + packed_4567.y = byte_buffer_align4_load4_xe( + xe_resolve_edram, sample_address_bytes + 5u * pixel_stride_bytes); + packed_4567.z = byte_buffer_align4_load4_xe( + xe_resolve_edram, sample_address_bytes + 6u * pixel_stride_bytes); + packed_4567.w = byte_buffer_align4_load4_xe( + xe_resolve_edram, sample_address_bytes + 7u * pixel_stride_bytes); } dont_flatten_xe if (format_ints_log2 != 0u) { XeResolveUnpack64bpp8RedUnswappedSamples(packed_0123, packed_4567, @@ -579,48 +581,46 @@ uint XeResolveEdramPixelStrideInts(XeResolveInfo resolve_info) { } void XeResolveLoad2RGBAColors( - param_uint_vector_buffer_xe(xe_resolve_edram) - param_next_after_uint_vector_buffer_xe - XeResolveInfo resolve_info, uint address_ints, + param_byte_buffer_xe(xe_resolve_edram) param_next_after_byte_buffer_xe + XeResolveInfo resolve_info, uint address_bytes, out_param_xe(float4_xe, pixel_0), out_param_xe(float4_xe, pixel_1)) { - uint pixel_stride_ints = XeResolveEdramPixelStrideInts(resolve_info); + uint pixel_stride_bytes = XeResolveEdramPixelStrideBytes(resolve_info); XeResolveLoad2RGBAUnswappedPixelSamplesFromRaw( - pass_uint_vector_buffer_xe(xe_resolve_edram) - pass_next_after_uint_vector_buffer_xe - address_ints, pixel_stride_ints, resolve_info.edram_format_ints_log2, - resolve_info.edram_format, pixel_0, pixel_1); + pass_byte_buffer_xe(xe_resolve_edram) pass_next_after_byte_buffer_xe + address_bytes, pixel_stride_bytes, + resolve_info.edram_format_ints_log2, resolve_info.edram_format, + pixel_0, pixel_1); float exp_bias = resolve_info.dest_exp_bias_factor; dont_flatten_xe if (resolve_info.sample_select >= kXenosCopySampleSelect_01) { - uint tile_row_stride_ints = 80u * resolve_info.resolution_scale.x; + uint tile_row_stride_bytes = 4u * 80u * resolve_info.resolution_scale.x; // TODO(Triang3l): Gamma-correct resolve for 8_8_8_8_GAMMA. exp_bias *= 0.5f; float4_xe msaa_resolve_pixel_0, msaa_resolve_pixel_1; XeResolveLoad2RGBAUnswappedPixelSamplesFromRaw( - pass_uint_vector_buffer_xe(xe_resolve_edram) - pass_next_after_uint_vector_buffer_xe - address_ints + tile_row_stride_ints, pixel_stride_ints, + pass_byte_buffer_xe(xe_resolve_edram) pass_next_after_byte_buffer_xe + address_bytes + tile_row_stride_bytes, pixel_stride_bytes, resolve_info.edram_format_ints_log2, resolve_info.edram_format, msaa_resolve_pixel_0, msaa_resolve_pixel_1); pixel_0 += msaa_resolve_pixel_0; pixel_1 += msaa_resolve_pixel_1; dont_flatten_xe if (resolve_info.sample_select >= kXenosCopySampleSelect_0123) { - uint sample_stride_ints = 1u << resolve_info.edram_format_ints_log2; + uint sample_stride_bytes = 4u << resolve_info.edram_format_ints_log2; exp_bias *= 0.5f; XeResolveLoad2RGBAUnswappedPixelSamplesFromRaw( - pass_uint_vector_buffer_xe(xe_resolve_edram) - pass_next_after_uint_vector_buffer_xe - address_ints + sample_stride_ints, pixel_stride_ints, + pass_byte_buffer_xe(xe_resolve_edram) + pass_next_after_byte_buffer_xe + address_bytes + sample_stride_bytes, pixel_stride_bytes, resolve_info.edram_format_ints_log2, resolve_info.edram_format, msaa_resolve_pixel_0, msaa_resolve_pixel_1); pixel_0 += msaa_resolve_pixel_0; pixel_1 += msaa_resolve_pixel_1; XeResolveLoad2RGBAUnswappedPixelSamplesFromRaw( - pass_uint_vector_buffer_xe(xe_resolve_edram) - pass_next_after_uint_vector_buffer_xe - address_ints + tile_row_stride_ints + sample_stride_ints, - pixel_stride_ints, resolve_info.edram_format_ints_log2, + pass_byte_buffer_xe(xe_resolve_edram) + pass_next_after_byte_buffer_xe + address_bytes + tile_row_stride_bytes + sample_stride_bytes, + pixel_stride_bytes, resolve_info.edram_format_ints_log2, resolve_info.edram_format, msaa_resolve_pixel_0, msaa_resolve_pixel_1); pixel_0 += msaa_resolve_pixel_0; @@ -650,21 +650,20 @@ uint XeResolveEdramPixelStrideInts(XeResolveInfo resolve_info) { } void XeResolveLoad4RGBAColors( - param_uint_vector_buffer_xe(xe_resolve_edram) - param_next_after_uint_vector_buffer_xe - XeResolveInfo resolve_info, uint address_ints, + param_byte_buffer_xe(xe_resolve_edram) param_next_after_byte_buffer_xe + XeResolveInfo resolve_info, uint address_bytes, out_param_xe(float4_xe, pixel_0), out_param_xe(float4_xe, pixel_1), out_param_xe(float4_xe, pixel_2), out_param_xe(float4_xe, pixel_3)) { - uint pixel_stride_ints = XeResolveEdramPixelStrideInts(resolve_info); + uint pixel_stride_bytes = XeResolveEdramPixelStrideBytes(resolve_info); XeResolveLoad4RGBAUnswappedPixelSamplesFromRaw( - pass_uint_vector_buffer_xe(xe_resolve_edram) - pass_next_after_uint_vector_buffer_xe - address_ints, pixel_stride_ints, resolve_info.edram_format_ints_log2, - resolve_info.edram_format, pixel_0, pixel_1, pixel_2, pixel_3); + pass_byte_buffer_xe(xe_resolve_edram) pass_next_after_byte_buffer_xe + address_bytes, pixel_stride_bytes, + resolve_info.edram_format_ints_log2, resolve_info.edram_format, + pixel_0, pixel_1, pixel_2, pixel_3); float exp_bias = resolve_info.dest_exp_bias_factor; dont_flatten_xe if (resolve_info.sample_select >= kXenosCopySampleSelect_01) { - uint tile_row_stride_ints = 80u * resolve_info.resolution_scale.x; + uint tile_row_stride_bytes = 4u * 80u * resolve_info.resolution_scale.x; // TODO(Triang3l): Gamma-correct resolve for 8_8_8_8_GAMMA. exp_bias *= 0.5f; float4_xe msaa_resolve_pixel_0; @@ -672,9 +671,8 @@ uint XeResolveEdramPixelStrideInts(XeResolveInfo resolve_info) { float4_xe msaa_resolve_pixel_2; float4_xe msaa_resolve_pixel_3; XeResolveLoad4RGBAUnswappedPixelSamplesFromRaw( - pass_uint_vector_buffer_xe(xe_resolve_edram) - pass_next_after_uint_vector_buffer_xe - address_ints + tile_row_stride_ints, pixel_stride_ints, + pass_byte_buffer_xe(xe_resolve_edram) pass_next_after_byte_buffer_xe + address_bytes + tile_row_stride_bytes, pixel_stride_bytes, resolve_info.edram_format_ints_log2, resolve_info.edram_format, msaa_resolve_pixel_0, msaa_resolve_pixel_1, msaa_resolve_pixel_2, msaa_resolve_pixel_3); @@ -684,12 +682,12 @@ uint XeResolveEdramPixelStrideInts(XeResolveInfo resolve_info) { pixel_3 += msaa_resolve_pixel_3; dont_flatten_xe if (resolve_info.sample_select >= kXenosCopySampleSelect_0123) { - uint sample_stride_ints = 1u << resolve_info.edram_format_ints_log2; + uint sample_stride_bytes = 4u << resolve_info.edram_format_ints_log2; exp_bias *= 0.5f; XeResolveLoad4RGBAUnswappedPixelSamplesFromRaw( - pass_uint_vector_buffer_xe(xe_resolve_edram) - pass_next_after_uint_vector_buffer_xe - address_ints + sample_stride_ints, pixel_stride_ints, + pass_byte_buffer_xe(xe_resolve_edram) + pass_next_after_byte_buffer_xe + address_bytes + sample_stride_bytes, pixel_stride_bytes, resolve_info.edram_format_ints_log2, resolve_info.edram_format, msaa_resolve_pixel_0, msaa_resolve_pixel_1, msaa_resolve_pixel_2, msaa_resolve_pixel_3); @@ -698,10 +696,10 @@ uint XeResolveEdramPixelStrideInts(XeResolveInfo resolve_info) { pixel_2 += msaa_resolve_pixel_2; pixel_3 += msaa_resolve_pixel_3; XeResolveLoad4RGBAUnswappedPixelSamplesFromRaw( - pass_uint_vector_buffer_xe(xe_resolve_edram) - pass_next_after_uint_vector_buffer_xe - address_ints + tile_row_stride_ints + sample_stride_ints, - pixel_stride_ints, resolve_info.edram_format_ints_log2, + pass_byte_buffer_xe(xe_resolve_edram) + pass_next_after_byte_buffer_xe + address_bytes + tile_row_stride_bytes + sample_stride_bytes, + pixel_stride_bytes, resolve_info.edram_format_ints_log2, resolve_info.edram_format, msaa_resolve_pixel_0, msaa_resolve_pixel_1, msaa_resolve_pixel_2, msaa_resolve_pixel_3); pixel_0 += msaa_resolve_pixel_0; @@ -739,33 +737,30 @@ uint XeResolveEdramPixelStrideInts(XeResolveInfo resolve_info) { } void XeResolveLoad8RedColors( - param_uint_vector_buffer_xe(xe_resolve_edram) - param_next_after_uint_vector_buffer_xe - XeResolveInfo resolve_info, uint address_ints, + param_byte_buffer_xe(xe_resolve_edram) param_next_after_byte_buffer_xe + XeResolveInfo resolve_info, uint address_bytes, out_param_xe(float4_xe, pixels_0123), out_param_xe(float4_xe, pixels_4567)) { - uint pixel_stride_ints = XeResolveEdramPixelStrideInts(resolve_info); - if (resolve_info.dest_swap) { + uint pixel_stride_bytes = XeResolveEdramPixelStrideBytes(resolve_info); + if (resolve_info.dest_swap && resolve_info.edram_format_ints_log2 != 0u) { // Likely want to load the blue part from the right half for 64bpp. - address_ints += resolve_info.edram_format_ints_log2; + address_bytes += 4u; } XeResolveLoad8RedPixelSamplesFromRaw( - pass_uint_vector_buffer_xe(xe_resolve_edram) - pass_next_after_uint_vector_buffer_xe - address_ints, pixel_stride_ints, resolve_info.edram_format_ints_log2, - resolve_info.edram_format, resolve_info.dest_swap, pixels_0123, - pixels_4567); + pass_byte_buffer_xe(xe_resolve_edram) pass_next_after_byte_buffer_xe + address_bytes, pixel_stride_bytes, + resolve_info.edram_format_ints_log2, resolve_info.edram_format, + resolve_info.dest_swap, pixels_0123, pixels_4567); float exp_bias = resolve_info.dest_exp_bias_factor; dont_flatten_xe if (resolve_info.sample_select >= kXenosCopySampleSelect_01) { - uint tile_row_stride_ints = 80u * resolve_info.resolution_scale.x; + uint tile_row_stride_bytes = 4u * 80u * resolve_info.resolution_scale.x; // TODO(Triang3l): Gamma-correct resolve for 8_8_8_8_GAMMA. exp_bias *= 0.5f; float4_xe msaa_resolve_pixels_0123, msaa_resolve_pixels_4567; XeResolveLoad8RedPixelSamplesFromRaw( - pass_uint_vector_buffer_xe(xe_resolve_edram) - pass_next_after_uint_vector_buffer_xe - address_ints + tile_row_stride_ints, pixel_stride_ints, + pass_byte_buffer_xe(xe_resolve_edram) pass_next_after_byte_buffer_xe + address_bytes + tile_row_stride_bytes, pixel_stride_bytes, resolve_info.edram_format_ints_log2, resolve_info.edram_format, resolve_info.dest_swap, msaa_resolve_pixels_0123, msaa_resolve_pixels_4567); @@ -773,22 +768,22 @@ uint XeResolveEdramPixelStrideInts(XeResolveInfo resolve_info) { pixels_4567 += msaa_resolve_pixels_4567; dont_flatten_xe if (resolve_info.sample_select >= kXenosCopySampleSelect_0123) { - uint sample_stride_ints = 1u << resolve_info.edram_format_ints_log2; + uint sample_stride_bytes = 4u << resolve_info.edram_format_ints_log2; exp_bias *= 0.5f; XeResolveLoad8RedPixelSamplesFromRaw( - pass_uint_vector_buffer_xe(xe_resolve_edram) - pass_next_after_uint_vector_buffer_xe - address_ints + sample_stride_ints, pixel_stride_ints, + pass_byte_buffer_xe(xe_resolve_edram) + pass_next_after_byte_buffer_xe + address_bytes + sample_stride_bytes, pixel_stride_bytes, resolve_info.edram_format_ints_log2, resolve_info.edram_format, resolve_info.dest_swap, msaa_resolve_pixels_0123, msaa_resolve_pixels_4567); pixels_0123 += msaa_resolve_pixels_0123; pixels_4567 += msaa_resolve_pixels_4567; XeResolveLoad8RedPixelSamplesFromRaw( - pass_uint_vector_buffer_xe(xe_resolve_edram) - pass_next_after_uint_vector_buffer_xe - address_ints + tile_row_stride_ints + sample_stride_ints, - pixel_stride_ints, resolve_info.edram_format_ints_log2, + pass_byte_buffer_xe(xe_resolve_edram) + pass_next_after_byte_buffer_xe + address_bytes + tile_row_stride_bytes + sample_stride_bytes, + pixel_stride_bytes, resolve_info.edram_format_ints_log2, resolve_info.edram_format, resolve_info.dest_swap, msaa_resolve_pixels_0123, msaa_resolve_pixels_4567); pixels_0123 += msaa_resolve_pixels_0123; @@ -798,7 +793,7 @@ uint XeResolveEdramPixelStrideInts(XeResolveInfo resolve_info) { pixels_0123 *= exp_bias; pixels_4567 *= exp_bias; } - #endif // XE_RESOLVE_COPY_EDRAM_IS_UINT_VECTOR_BUFFER + #endif // XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_ALIGNMENT == 4 uint4_xe XeResolveSwapRedBlue_8_8_8_8(uint4_xe pixels) { return (pixels & ~0xFF00FFu) | ((pixels & 0xFFu) << 16u) | diff --git a/src/xenia/gpu/shaders/resolve_clear_32bpp.xesli b/src/xenia/gpu/shaders/resolve_clear_32bpp.xesli index c57b5075b..8117436c1 100644 --- a/src/xenia/gpu/shaders/resolve_clear_32bpp.xesli +++ b/src/xenia/gpu/shaders/resolve_clear_32bpp.xesli @@ -10,15 +10,15 @@ #define XE_RESOLVE_CLEAR #include "resolve.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_resolve_edram, set=0, binding=0, u0, - space0) +byte_buffer_align16_wo_declare_xe(xe_resolve_edram, set=0, binding=0, u0, + space0) #define LOCAL_SIZE_X_XE 8 #define LOCAL_SIZE_Y_XE 8 #define LOCAL_SIZE_Z_XE 1 entry_bindings_begin_compute_xe XE_RESOLVE_PUSH_CONST_BINDING entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_resolve_edram, buffer(1)) + byte_buffer_wo_binding_xe(xe_resolve_edram, buffer(1)) entry_bindings_end_inputs_begin_compute_xe entry_in_global_thread_id_xe entry_inputs_end_code_begin_compute_xe @@ -34,17 +34,15 @@ entry_inputs_end_code_begin_compute_xe resolve_info.width_div_8_scaled << extent_scale.x) { return; } - uint address_int4s = - XeEdramOffsetInts( - (in_global_thread_id_xe.xy << uint2_xe(3u, 0u)) + - (resolve_info.edram_offset_scaled << extent_scale), - resolve_info.edram_base_tiles, true, resolve_info.edram_pitch_tiles, - kXenosMsaaSamples_1X, resolve_info.edram_is_depth, 0u, 0u, - resolve_info.resolution_scale) - >> 2u; - array_buffer_store_xe(xe_resolve_edram, address_int4s, - resolve_info.clear_value.xxxx); - array_buffer_store_xe(xe_resolve_edram, address_int4s + 1u, - resolve_info.clear_value.xxxx); + uint address = XeEdramOffsetBytes( + (in_global_thread_id_xe.xy << uint2_xe(3u, 0u)) + + (resolve_info.edram_offset_scaled << extent_scale), + resolve_info.edram_base_tiles, true, resolve_info.edram_pitch_tiles, + kXenosMsaaSamples_1X, resolve_info.edram_is_depth, 0u, 0u, + resolve_info.resolution_scale); + byte_buffer_align16_store16_xe(xe_resolve_edram, address, + resolve_info.clear_value.xxxx); + byte_buffer_align16_store16_xe(xe_resolve_edram, address + 16u, + resolve_info.clear_value.xxxx); } entry_code_end_compute_xe diff --git a/src/xenia/gpu/shaders/resolve_clear_64bpp.xesli b/src/xenia/gpu/shaders/resolve_clear_64bpp.xesli index 46af18c41..cfb755fb6 100644 --- a/src/xenia/gpu/shaders/resolve_clear_64bpp.xesli +++ b/src/xenia/gpu/shaders/resolve_clear_64bpp.xesli @@ -10,15 +10,15 @@ #define XE_RESOLVE_CLEAR #include "resolve.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_resolve_edram, set=0, binding=0, u0, - space0) +byte_buffer_align16_wo_declare_xe(xe_resolve_edram, set=0, binding=0, u0, + space0) #define LOCAL_SIZE_X_XE 8 #define LOCAL_SIZE_Y_XE 8 #define LOCAL_SIZE_Z_XE 1 entry_bindings_begin_compute_xe XE_RESOLVE_PUSH_CONST_BINDING entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_resolve_edram, buffer(1)) + byte_buffer_wo_binding_xe(xe_resolve_edram, buffer(1)) entry_bindings_end_inputs_begin_compute_xe entry_in_global_thread_id_xe entry_inputs_end_code_begin_compute_xe @@ -34,17 +34,15 @@ entry_inputs_end_code_begin_compute_xe resolve_info.width_div_8_scaled << extent_scale.x) { return; } - uint address_int4s = - XeEdramOffsetInts( - (in_global_thread_id_xe.xy << uint2_xe(3u, 0u)) + - (resolve_info.edram_offset_scaled << extent_scale), - resolve_info.edram_base_tiles, true, resolve_info.edram_pitch_tiles, - kXenosMsaaSamples_1X, false, 1u, 0u, resolve_info.resolution_scale) - >> 2u; + uint address = XeEdramOffsetBytes( + (in_global_thread_id_xe.xy << uint2_xe(3u, 0u)) + + (resolve_info.edram_offset_scaled << extent_scale), + resolve_info.edram_base_tiles, true, resolve_info.edram_pitch_tiles, + kXenosMsaaSamples_1X, false, 1u, 0u, resolve_info.resolution_scale); uint i; unroll_xe for (i = 0u; i < 4u; ++i) { - array_buffer_store_xe(xe_resolve_edram, address_int4s + i, - resolve_info.clear_value.xyxy); + byte_buffer_align16_store16_xe(xe_resolve_edram, address + (i << 4), + resolve_info.clear_value.xyxy); } } entry_code_end_compute_xe diff --git a/src/xenia/gpu/shaders/resolve_fast_32bpp_1x2xmsaa.xesli b/src/xenia/gpu/shaders/resolve_fast_32bpp_1x2xmsaa.xesli index d0e85d73c..06a49a13e 100644 --- a/src/xenia/gpu/shaders/resolve_fast_32bpp_1x2xmsaa.xesli +++ b/src/xenia/gpu/shaders/resolve_fast_32bpp_1x2xmsaa.xesli @@ -8,18 +8,17 @@ */ #include "endian.xesli" -#define XE_RESOLVE_SOURCE_TYPE uint4_xe +#define XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_ALIGNMENT 16 #include "resolve.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_resolve_dest, set=1, binding=0, u0, - space0) +byte_buffer_align16_wo_declare_xe(xe_resolve_dest, set=1, binding=0, u0, space0) #define LOCAL_SIZE_X_XE 8 #define LOCAL_SIZE_Y_XE 8 #define LOCAL_SIZE_Z_XE 1 entry_bindings_begin_compute_xe XE_RESOLVE_PUSH_CONST_BINDING entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_resolve_dest, buffer(1)) + byte_buffer_wo_binding_xe(xe_resolve_dest, buffer(1)) entry_binding_next_xe XE_RESOLVE_COPY_EDRAM_BINDING entry_bindings_end_inputs_begin_compute_xe @@ -34,21 +33,19 @@ entry_inputs_end_code_begin_compute_xe return; } uint2_xe pixel_index = in_global_thread_id_xe.xy << uint2_xe(3u, 0u); - uint source_address_int4s = - XeEdramOffsetInts( - uint2_xe(pixel_index.x, - max(pixel_index.y, - resolve_info.half_pixel_offset_fill_source.y)) + - resolve_info.edram_offset_scaled, - resolve_info.edram_base_tiles, true, resolve_info.edram_pitch_tiles, - resolve_info.edram_msaa_samples, resolve_info.edram_is_depth, 0u, - XeResolveFirstSampleIndex(resolve_info.sample_select), - resolve_info.resolution_scale) - >> 2u; - uint4_xe pixels_0123 = - array_buffer_load_xe(xe_resolve_edram, source_address_int4s); - uint4_xe pixels_4567 = - array_buffer_load_xe(xe_resolve_edram, source_address_int4s + 1u); + uint source_address = XeEdramOffsetBytes( + uint2_xe(pixel_index.x, + max(pixel_index.y, + resolve_info.half_pixel_offset_fill_source.y)) + + resolve_info.edram_offset_scaled, + resolve_info.edram_base_tiles, true, resolve_info.edram_pitch_tiles, + resolve_info.edram_msaa_samples, resolve_info.edram_is_depth, 0u, + XeResolveFirstSampleIndex(resolve_info.sample_select), + resolve_info.resolution_scale); + uint4_xe pixels_0123 = byte_buffer_align16_load16_xe(xe_resolve_edram, + source_address); + uint4_xe pixels_4567 = byte_buffer_align16_load16_xe(xe_resolve_edram, + source_address + 16u); dont_flatten_xe if (pixel_index.x == 0u && resolve_info.half_pixel_offset_fill_source.x != 0u) { @@ -61,13 +58,12 @@ entry_inputs_end_code_begin_compute_xe pixels_0123.x = pixels_0123.y; } XeResolveSwap8PixelsRedBlue32bpp(resolve_info, pixels_0123, pixels_4567); - uint dest_address = - XeResolveDestPixelAddress(resolve_info, pixel_index, 2u) >> 4u; - array_buffer_store_xe( + uint dest_address = XeResolveDestPixelAddress(resolve_info, pixel_index, 2u); + byte_buffer_align16_store16_xe( xe_resolve_dest, dest_address, XeEndianSwap32(pixels_0123, resolve_info.dest_endian_128)); - dest_address += XeResolveLocalXAddressXor(4u, 2u) >> 4u; - array_buffer_store_xe( + dest_address += XeResolveLocalXAddressXor(4u, 2u); + byte_buffer_align16_store16_xe( xe_resolve_dest, dest_address, XeEndianSwap32(pixels_4567, resolve_info.dest_endian_128)); } diff --git a/src/xenia/gpu/shaders/resolve_fast_32bpp_4xmsaa.xesli b/src/xenia/gpu/shaders/resolve_fast_32bpp_4xmsaa.xesli index a6b1b68c6..8f1453bd5 100644 --- a/src/xenia/gpu/shaders/resolve_fast_32bpp_4xmsaa.xesli +++ b/src/xenia/gpu/shaders/resolve_fast_32bpp_4xmsaa.xesli @@ -8,18 +8,17 @@ */ #include "endian.xesli" -#define XE_RESOLVE_SOURCE_TYPE uint4_xe +#define XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_ALIGNMENT 16 #include "resolve.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_resolve_dest, set=1, binding=0, u0, - space0) +byte_buffer_align16_wo_declare_xe(xe_resolve_dest, set=1, binding=0, u0, space0) #define LOCAL_SIZE_X_XE 8 #define LOCAL_SIZE_Y_XE 8 #define LOCAL_SIZE_Z_XE 1 entry_bindings_begin_compute_xe XE_RESOLVE_PUSH_CONST_BINDING entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_resolve_dest, buffer(1)) + byte_buffer_wo_binding_xe(xe_resolve_dest, buffer(1)) entry_binding_next_xe XE_RESOLVE_COPY_EDRAM_BINDING entry_bindings_end_inputs_begin_compute_xe @@ -34,38 +33,36 @@ entry_inputs_end_code_begin_compute_xe return; } uint2_xe pixel_index = in_global_thread_id_xe.xy << uint2_xe(3u, 0u); - uint source_address_int4s = - XeEdramOffsetInts( - uint2_xe(pixel_index.x, - max(pixel_index.y, - resolve_info.half_pixel_offset_fill_source.y)) + - resolve_info.edram_offset_scaled, - resolve_info.edram_base_tiles, true, resolve_info.edram_pitch_tiles, - kXenosMsaaSamples_4X, resolve_info.edram_is_depth, 0u, - XeResolveFirstSampleIndex(resolve_info.sample_select), - resolve_info.resolution_scale) - >> 2u; + uint source_address = XeEdramOffsetBytes( + uint2_xe(pixel_index.x, + max(pixel_index.y, + resolve_info.half_pixel_offset_fill_source.y)) + + resolve_info.edram_offset_scaled, + resolve_info.edram_base_tiles, true, resolve_info.edram_pitch_tiles, + kXenosMsaaSamples_4X, resolve_info.edram_is_depth, 0u, + XeResolveFirstSampleIndex(resolve_info.sample_select), + resolve_info.resolution_scale); uint4_xe pixels_0123, pixels_4567; dont_flatten_xe if (resolve_info.sample_select != kXenosCopySampleSelect_2 && resolve_info.sample_select != kXenosCopySampleSelect_3) { - pixels_0123.xy = array_buffer_load_xe( - xe_resolve_edram, source_address_int4s).xz; - pixels_0123.zw = array_buffer_load_xe( - xe_resolve_edram, source_address_int4s + 1u).xz; - pixels_4567.xy = array_buffer_load_xe( - xe_resolve_edram, source_address_int4s + 2u).xz; - pixels_4567.zw = array_buffer_load_xe( - xe_resolve_edram, source_address_int4s + 3u).xz; + pixels_0123.xy = byte_buffer_align16_load16_xe(xe_resolve_edram, + source_address).xz; + pixels_0123.zw = byte_buffer_align16_load16_xe(xe_resolve_edram, + source_address + 0x10u).xz; + pixels_4567.xy = byte_buffer_align16_load16_xe(xe_resolve_edram, + source_address + 0x20u).xz; + pixels_4567.zw = byte_buffer_align16_load16_xe(xe_resolve_edram, + source_address + 0x30u).xz; } else { - pixels_0123.xy = array_buffer_load_xe( - xe_resolve_edram, source_address_int4s).yw; - pixels_0123.zw = array_buffer_load_xe( - xe_resolve_edram, source_address_int4s + 1u).yw; - pixels_4567.xy = array_buffer_load_xe( - xe_resolve_edram, source_address_int4s + 2u).yw; - pixels_4567.zw = array_buffer_load_xe( - xe_resolve_edram, source_address_int4s + 3u).yw; + pixels_0123.xy = byte_buffer_align16_load16_xe(xe_resolve_edram, + source_address).yw; + pixels_0123.zw = byte_buffer_align16_load16_xe(xe_resolve_edram, + source_address + 0x10u).yw; + pixels_4567.xy = byte_buffer_align16_load16_xe(xe_resolve_edram, + source_address + 0x20u).yw; + pixels_4567.zw = byte_buffer_align16_load16_xe(xe_resolve_edram, + source_address + 0x30u).yw; } dont_flatten_xe if (pixel_index.x == 0u && @@ -79,13 +76,12 @@ entry_inputs_end_code_begin_compute_xe pixels_0123.x = pixels_0123.y; } XeResolveSwap8PixelsRedBlue32bpp(resolve_info, pixels_0123, pixels_4567); - uint dest_address = - XeResolveDestPixelAddress(resolve_info, pixel_index, 2u) >> 4u; - array_buffer_store_xe( + uint dest_address = XeResolveDestPixelAddress(resolve_info, pixel_index, 2u); + byte_buffer_align16_store16_xe( xe_resolve_dest, dest_address, XeEndianSwap32(pixels_0123, resolve_info.dest_endian_128)); - dest_address += XeResolveLocalXAddressXor(4u, 2u) >> 4u; - array_buffer_store_xe( + dest_address += XeResolveLocalXAddressXor(4u, 2u); + byte_buffer_align16_store16_xe( xe_resolve_dest, dest_address, XeEndianSwap32(pixels_4567, resolve_info.dest_endian_128)); } diff --git a/src/xenia/gpu/shaders/resolve_fast_64bpp_1x2xmsaa.xesli b/src/xenia/gpu/shaders/resolve_fast_64bpp_1x2xmsaa.xesli index 62449803e..a00280b32 100644 --- a/src/xenia/gpu/shaders/resolve_fast_64bpp_1x2xmsaa.xesli +++ b/src/xenia/gpu/shaders/resolve_fast_64bpp_1x2xmsaa.xesli @@ -8,18 +8,17 @@ */ #include "endian.xesli" -#define XE_RESOLVE_SOURCE_TYPE uint4_xe +#define XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_ALIGNMENT 16 #include "resolve.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_resolve_dest, set=1, binding=0, u0, - space0) +byte_buffer_align16_wo_declare_xe(xe_resolve_dest, set=1, binding=0, u0, space0) #define LOCAL_SIZE_X_XE 8 #define LOCAL_SIZE_Y_XE 8 #define LOCAL_SIZE_Z_XE 1 entry_bindings_begin_compute_xe XE_RESOLVE_PUSH_CONST_BINDING entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_resolve_dest, buffer(1)) + byte_buffer_wo_binding_xe(xe_resolve_dest, buffer(1)) entry_binding_next_xe XE_RESOLVE_COPY_EDRAM_BINDING entry_bindings_end_inputs_begin_compute_xe @@ -34,21 +33,19 @@ entry_inputs_end_code_begin_compute_xe if (pixel_index.x >= resolve_info.width_div_8_scaled << 3u) { return; } - uint source_address_int4s = - XeEdramOffsetInts( - uint2_xe(pixel_index.x, - max(pixel_index.y, - resolve_info.half_pixel_offset_fill_source.y)) + - resolve_info.edram_offset_scaled, - resolve_info.edram_base_tiles, true, resolve_info.edram_pitch_tiles, - resolve_info.edram_msaa_samples, false, 1u, - XeResolveFirstSampleIndex(resolve_info.sample_select), - resolve_info.resolution_scale) - >> 2u; - uint4_xe pixels_01 = - array_buffer_load_xe(xe_resolve_edram, source_address_int4s); - uint4_xe pixels_23 = - array_buffer_load_xe(xe_resolve_edram, source_address_int4s + 1u); + uint source_address = XeEdramOffsetBytes( + uint2_xe(pixel_index.x, + max(pixel_index.y, + resolve_info.half_pixel_offset_fill_source.y)) + + resolve_info.edram_offset_scaled, + resolve_info.edram_base_tiles, true, resolve_info.edram_pitch_tiles, + resolve_info.edram_msaa_samples, false, 1u, + XeResolveFirstSampleIndex(resolve_info.sample_select), + resolve_info.resolution_scale); + uint4_xe pixels_01 = byte_buffer_align16_load16_xe(xe_resolve_edram, + source_address); + uint4_xe pixels_23 = byte_buffer_align16_load16_xe(xe_resolve_edram, + source_address + 16u); dont_flatten_xe if (pixel_index.x == 0u && resolve_info.half_pixel_offset_fill_source.x != 0u) { @@ -61,13 +58,12 @@ entry_inputs_end_code_begin_compute_xe pixels_01.xy = pixels_01.zw; } XeResolveSwap4PixelsRedBlue64bpp(resolve_info, pixels_01, pixels_23); - uint dest_address = - XeResolveDestPixelAddress(resolve_info, pixel_index, 3u) >> 4u; - array_buffer_store_xe( + uint dest_address = XeResolveDestPixelAddress(resolve_info, pixel_index, 3u); + byte_buffer_align16_store16_xe( xe_resolve_dest, dest_address, XeEndianSwap64(pixels_01, resolve_info.dest_endian_128)); - dest_address += XeResolveLocalXAddressXor(2u, 3u) >> 4u; - array_buffer_store_xe( + dest_address += XeResolveLocalXAddressXor(2u, 3u); + byte_buffer_align16_store16_xe( xe_resolve_dest, dest_address, XeEndianSwap64(pixels_23, resolve_info.dest_endian_128)); } diff --git a/src/xenia/gpu/shaders/resolve_fast_64bpp_4xmsaa.xesli b/src/xenia/gpu/shaders/resolve_fast_64bpp_4xmsaa.xesli index 020775f2f..4a7ef067e 100644 --- a/src/xenia/gpu/shaders/resolve_fast_64bpp_4xmsaa.xesli +++ b/src/xenia/gpu/shaders/resolve_fast_64bpp_4xmsaa.xesli @@ -8,18 +8,17 @@ */ #include "endian.xesli" -#define XE_RESOLVE_SOURCE_TYPE uint2_xe +#define XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_ALIGNMENT 8 #include "resolve.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_resolve_dest, set=1, binding=0, u0, - space0) +byte_buffer_align16_wo_declare_xe(xe_resolve_dest, set=1, binding=0, u0, space0) #define LOCAL_SIZE_X_XE 8 #define LOCAL_SIZE_Y_XE 8 #define LOCAL_SIZE_Z_XE 1 entry_bindings_begin_compute_xe XE_RESOLVE_PUSH_CONST_BINDING entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_resolve_dest, buffer(1)) + byte_buffer_wo_binding_xe(xe_resolve_dest, buffer(1)) entry_binding_next_xe XE_RESOLVE_COPY_EDRAM_BINDING entry_bindings_end_inputs_begin_compute_xe @@ -34,25 +33,23 @@ entry_inputs_end_code_begin_compute_xe if (pixel_index.x >= resolve_info.width_div_8_scaled << 3u) { return; } - uint source_address_int2s = - XeEdramOffsetInts( - uint2_xe(pixel_index.x, - max(pixel_index.y, - resolve_info.half_pixel_offset_fill_source.y)) + - resolve_info.edram_offset_scaled, - resolve_info.edram_base_tiles, true, resolve_info.edram_pitch_tiles, - kXenosMsaaSamples_4X, false, 1u, - XeResolveFirstSampleIndex(resolve_info.sample_select), - resolve_info.resolution_scale) - >> 1u; + uint source_address = XeEdramOffsetBytes( + uint2_xe(pixel_index.x, + max(pixel_index.y, + resolve_info.half_pixel_offset_fill_source.y)) + + resolve_info.edram_offset_scaled, + resolve_info.edram_base_tiles, true, resolve_info.edram_pitch_tiles, + kXenosMsaaSamples_4X, false, 1u, + XeResolveFirstSampleIndex(resolve_info.sample_select), + resolve_info.resolution_scale); uint4_xe pixels_01, pixels_23; - pixels_01.xy = array_buffer_load_xe(xe_resolve_edram, source_address_int2s); - pixels_01.zw = - array_buffer_load_xe(xe_resolve_edram, source_address_int2s + 2u); - pixels_23.xy = - array_buffer_load_xe(xe_resolve_edram, source_address_int2s + 4u); - pixels_23.zw = - array_buffer_load_xe(xe_resolve_edram, source_address_int2s + 6u); + pixels_01.xy = byte_buffer_align8_load8_xe(xe_resolve_edram, source_address); + pixels_01.zw = byte_buffer_align8_load8_xe(xe_resolve_edram, + source_address + 0x10u); + pixels_23.xy = byte_buffer_align8_load8_xe(xe_resolve_edram, + source_address + 0x20u); + pixels_23.zw = byte_buffer_align8_load8_xe(xe_resolve_edram, + source_address + 0x30u); dont_flatten_xe if (pixel_index.x == 0u && resolve_info.half_pixel_offset_fill_source.x != 0u) { @@ -65,13 +62,12 @@ entry_inputs_end_code_begin_compute_xe pixels_01.xy = pixels_01.zw; } XeResolveSwap4PixelsRedBlue64bpp(resolve_info, pixels_01, pixels_23); - uint dest_address = - XeResolveDestPixelAddress(resolve_info, pixel_index, 3u) >> 4u; - array_buffer_store_xe( + uint dest_address = XeResolveDestPixelAddress(resolve_info, pixel_index, 3u); + byte_buffer_align16_store16_xe( xe_resolve_dest, dest_address, XeEndianSwap64(pixels_01, resolve_info.dest_endian_128)); - dest_address += XeResolveLocalXAddressXor(2u, 3u) >> 4u; - array_buffer_store_xe( + dest_address += XeResolveLocalXAddressXor(2u, 3u); + byte_buffer_align16_store16_xe( xe_resolve_dest, dest_address, XeEndianSwap64(pixels_23, resolve_info.dest_endian_128)); } diff --git a/src/xenia/gpu/shaders/resolve_full_128bpp.xesli b/src/xenia/gpu/shaders/resolve_full_128bpp.xesli index 5935d2eee..398aa0801 100644 --- a/src/xenia/gpu/shaders/resolve_full_128bpp.xesli +++ b/src/xenia/gpu/shaders/resolve_full_128bpp.xesli @@ -8,18 +8,17 @@ */ #include "endian.xesli" -#define XE_RESOLVE_COPY_EDRAM_IS_UINT_VECTOR_BUFFER +#define XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_ALIGNMENT 4 #include "resolve.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_resolve_dest, set=1, binding=0, u0, - space0) +byte_buffer_align16_wo_declare_xe(xe_resolve_dest, set=1, binding=0, u0, space0) #define LOCAL_SIZE_X_XE 8 #define LOCAL_SIZE_Y_XE 8 #define LOCAL_SIZE_Z_XE 1 entry_bindings_begin_compute_xe XE_RESOLVE_PUSH_CONST_BINDING entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_resolve_dest, buffer(1)) + byte_buffer_wo_binding_xe(xe_resolve_dest, buffer(1)) entry_binding_next_xe XE_RESOLVE_COPY_EDRAM_BINDING entry_bindings_end_inputs_begin_compute_xe @@ -36,10 +35,9 @@ entry_inputs_end_code_begin_compute_xe } float4_xe pixel_0, pixel_1; XeResolveLoad2RGBAColors( - pass_uint_vector_buffer_xe(xe_resolve_edram) - pass_next_after_uint_vector_buffer_xe + pass_byte_buffer_xe(xe_resolve_edram) pass_next_after_byte_buffer_xe resolve_info, - XeResolveColorCopySourcePixelAddressIntsYHalfPixelOffsetFilling( + XeResolveColorCopySourcePixelAddressBytesYHalfPixelOffsetFilling( resolve_info, uint2_xe(max(pixel_index.x, resolve_info.half_pixel_offset_fill_source.x), @@ -56,14 +54,13 @@ entry_inputs_end_code_begin_compute_xe pixel_1 = pixel_0; } // Only 32_32_32_32_FLOAT color format is 128bpp. - uint dest_address = - XeResolveDestPixelAddress(resolve_info, pixel_index, 4u) >> 4u; - array_buffer_store_xe( + uint dest_address = XeResolveDestPixelAddress(resolve_info, pixel_index, 4u); + byte_buffer_align16_store16_xe( xe_resolve_dest, dest_address, XeEndianSwap128(float_bits_to_uint_xe(pixel_0), resolve_info.dest_endian_128)); - dest_address += XeResolveLocalXAddressXor(1u, 4u) >> 4u; - array_buffer_store_xe( + dest_address += XeResolveLocalXAddressXor(1u, 4u); + byte_buffer_align16_store16_xe( xe_resolve_dest, dest_address, XeEndianSwap128(float_bits_to_uint_xe(pixel_1), resolve_info.dest_endian_128)); diff --git a/src/xenia/gpu/shaders/resolve_full_16bpp.xesli b/src/xenia/gpu/shaders/resolve_full_16bpp.xesli index 344d2d4f8..b5bc1af4f 100644 --- a/src/xenia/gpu/shaders/resolve_full_16bpp.xesli +++ b/src/xenia/gpu/shaders/resolve_full_16bpp.xesli @@ -9,18 +9,17 @@ #include "endian.xesli" #include "pixel_formats.xesli" -#define XE_RESOLVE_COPY_EDRAM_IS_UINT_VECTOR_BUFFER +#define XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_ALIGNMENT 4 #include "resolve.xesli" -array_buffer_wo_declare_xe(uint2_xe, xe_resolve_dest, set=1, binding=0, u0, - space0) +byte_buffer_align8_wo_declare_xe(xe_resolve_dest, set=1, binding=0, u0, space0) #define LOCAL_SIZE_X_XE 8 #define LOCAL_SIZE_Y_XE 8 #define LOCAL_SIZE_Z_XE 1 entry_bindings_begin_compute_xe XE_RESOLVE_PUSH_CONST_BINDING entry_binding_next_xe - array_buffer_wo_binding_xe(uint2_xe, xe_resolve_dest, buffer(1)) + byte_buffer_wo_binding_xe(xe_resolve_dest, buffer(1)) entry_binding_next_xe XE_RESOLVE_COPY_EDRAM_BINDING entry_bindings_end_inputs_begin_compute_xe @@ -37,10 +36,9 @@ entry_inputs_end_code_begin_compute_xe } float4_xe pixel_0, pixel_1, pixel_2, pixel_3; XeResolveLoad4RGBAColors( - pass_uint_vector_buffer_xe(xe_resolve_edram) - pass_next_after_uint_vector_buffer_xe + pass_byte_buffer_xe(xe_resolve_edram) pass_next_after_byte_buffer_xe resolve_info, - XeResolveColorCopySourcePixelAddressIntsYHalfPixelOffsetFilling( + XeResolveColorCopySourcePixelAddressBytesYHalfPixelOffsetFilling( resolve_info, pixel_index), pixel_0, pixel_1, pixel_2, pixel_3); uint2_xe packed = XePack16bpp4PixelsInUInt2( @@ -56,9 +54,8 @@ entry_inputs_end_code_begin_compute_xe } packed.x = (packed.x >> 16u) | (packed.x & 0xFFFF0000u); } - array_buffer_store_xe( - xe_resolve_dest, - XeResolveDestPixelAddress(resolve_info, pixel_index, 1u) >> 3u, + byte_buffer_align8_store8_xe( + xe_resolve_dest, XeResolveDestPixelAddress(resolve_info, pixel_index, 1u), XeEndianSwap16(packed, resolve_info.dest_endian_128)); } entry_code_end_compute_xe diff --git a/src/xenia/gpu/shaders/resolve_full_32bpp.xesli b/src/xenia/gpu/shaders/resolve_full_32bpp.xesli index 92cdd75ec..ae3e18fc3 100644 --- a/src/xenia/gpu/shaders/resolve_full_32bpp.xesli +++ b/src/xenia/gpu/shaders/resolve_full_32bpp.xesli @@ -9,18 +9,17 @@ #include "endian.xesli" #include "pixel_formats.xesli" -#define XE_RESOLVE_COPY_EDRAM_IS_UINT_VECTOR_BUFFER +#define XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_ALIGNMENT 4 #include "resolve.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_resolve_dest, set=1, binding=0, u0, - space0) +byte_buffer_align16_wo_declare_xe(xe_resolve_dest, set=1, binding=0, u0, space0) #define LOCAL_SIZE_X_XE 8 #define LOCAL_SIZE_Y_XE 8 #define LOCAL_SIZE_Z_XE 1 entry_bindings_begin_compute_xe XE_RESOLVE_PUSH_CONST_BINDING entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_resolve_dest, buffer(1)) + byte_buffer_wo_binding_xe(xe_resolve_dest, buffer(1)) entry_binding_next_xe XE_RESOLVE_COPY_EDRAM_BINDING entry_bindings_end_inputs_begin_compute_xe @@ -39,10 +38,9 @@ entry_inputs_end_code_begin_compute_xe } float4_xe pixel_0, pixel_1, pixel_2, pixel_3; XeResolveLoad4RGBAColors( - pass_uint_vector_buffer_xe(xe_resolve_edram) - pass_next_after_uint_vector_buffer_xe + pass_byte_buffer_xe(xe_resolve_edram) pass_next_after_byte_buffer_xe resolve_info, - XeResolveColorCopySourcePixelAddressIntsYHalfPixelOffsetFilling( + XeResolveColorCopySourcePixelAddressBytesYHalfPixelOffsetFilling( resolve_info, pixel_index), pixel_0, pixel_1, pixel_2, pixel_3); uint4_xe packed = XePack32bpp4Pixels(pixel_0, pixel_1, pixel_2, pixel_3, @@ -58,9 +56,8 @@ entry_inputs_end_code_begin_compute_xe } packed.x = packed.y; } - array_buffer_store_xe( - xe_resolve_dest, - XeResolveDestPixelAddress(resolve_info, pixel_index, 2u) >> 4u, + byte_buffer_align16_store16_xe( + xe_resolve_dest, XeResolveDestPixelAddress(resolve_info, pixel_index, 2u), XeEndianSwap32(packed, resolve_info.dest_endian_128)); } entry_code_end_compute_xe diff --git a/src/xenia/gpu/shaders/resolve_full_64bpp.xesli b/src/xenia/gpu/shaders/resolve_full_64bpp.xesli index beb50c515..63a0fd4e3 100644 --- a/src/xenia/gpu/shaders/resolve_full_64bpp.xesli +++ b/src/xenia/gpu/shaders/resolve_full_64bpp.xesli @@ -9,18 +9,17 @@ #include "endian.xesli" #include "pixel_formats.xesli" -#define XE_RESOLVE_COPY_EDRAM_IS_UINT_VECTOR_BUFFER +#define XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_ALIGNMENT 4 #include "resolve.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_resolve_dest, set=1, binding=0, u0, - space0) +byte_buffer_align16_wo_declare_xe(xe_resolve_dest, set=1, binding=0, u0, space0) #define LOCAL_SIZE_X_XE 8 #define LOCAL_SIZE_Y_XE 8 #define LOCAL_SIZE_Z_XE 1 entry_bindings_begin_compute_xe XE_RESOLVE_PUSH_CONST_BINDING entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_resolve_dest, buffer(1)) + byte_buffer_wo_binding_xe(xe_resolve_dest, buffer(1)) entry_binding_next_xe XE_RESOLVE_COPY_EDRAM_BINDING entry_bindings_end_inputs_begin_compute_xe @@ -37,10 +36,9 @@ entry_inputs_end_code_begin_compute_xe } float4_xe pixel_0, pixel_1, pixel_2, pixel_3; XeResolveLoad4RGBAColors( - pass_uint_vector_buffer_xe(xe_resolve_edram) - pass_next_after_uint_vector_buffer_xe + pass_byte_buffer_xe(xe_resolve_edram) pass_next_after_byte_buffer_xe resolve_info, - XeResolveColorCopySourcePixelAddressIntsYHalfPixelOffsetFilling( + XeResolveColorCopySourcePixelAddressBytesYHalfPixelOffsetFilling( resolve_info, pixel_index), pixel_0, pixel_1, pixel_2, pixel_3); uint4_xe packed_01, packed_23; @@ -57,13 +55,12 @@ entry_inputs_end_code_begin_compute_xe } packed_01.xy = packed_01.zw; } - uint dest_address = - XeResolveDestPixelAddress(resolve_info, pixel_index, 3u) >> 4u; - array_buffer_store_xe( + uint dest_address = XeResolveDestPixelAddress(resolve_info, pixel_index, 3u); + byte_buffer_align16_store16_xe( xe_resolve_dest, dest_address, XeEndianSwap64(packed_01, resolve_info.dest_endian_128)); - dest_address += XeResolveLocalXAddressXor(2u, 3u) >> 4u; - array_buffer_store_xe( + dest_address += XeResolveLocalXAddressXor(2u, 3u); + byte_buffer_align16_store16_xe( xe_resolve_dest, dest_address, XeEndianSwap64(packed_23, resolve_info.dest_endian_128)); } diff --git a/src/xenia/gpu/shaders/resolve_full_8bpp.xesli b/src/xenia/gpu/shaders/resolve_full_8bpp.xesli index 0b9c7d677..29224d963 100644 --- a/src/xenia/gpu/shaders/resolve_full_8bpp.xesli +++ b/src/xenia/gpu/shaders/resolve_full_8bpp.xesli @@ -9,18 +9,17 @@ #include "endian.xesli" #include "pixel_formats.xesli" -#define XE_RESOLVE_COPY_EDRAM_IS_UINT_VECTOR_BUFFER +#define XE_RESOLVE_COPY_EDRAM_BYTE_BUFFER_ALIGNMENT 4 #include "resolve.xesli" -array_buffer_wo_declare_xe(uint2_xe, xe_resolve_dest, set=1, binding=0, u0, - space0) +byte_buffer_align8_wo_declare_xe(xe_resolve_dest, set=1, binding=0, u0, space0) #define LOCAL_SIZE_X_XE 8 #define LOCAL_SIZE_Y_XE 8 #define LOCAL_SIZE_Z_XE 1 entry_bindings_begin_compute_xe XE_RESOLVE_PUSH_CONST_BINDING entry_binding_next_xe - array_buffer_wo_binding_xe(uint2_xe, xe_resolve_dest, buffer(1)) + byte_buffer_wo_binding_xe(xe_resolve_dest, buffer(1)) entry_binding_next_xe XE_RESOLVE_COPY_EDRAM_BINDING entry_bindings_end_inputs_begin_compute_xe @@ -37,10 +36,9 @@ entry_inputs_end_code_begin_compute_xe uint2_xe pixel_index = in_global_thread_id_xe.xy << uint2_xe(3u, 0u); float4_xe pixels_0123, pixels_4567; XeResolveLoad8RedColors( - pass_uint_vector_buffer_xe(xe_resolve_edram) - pass_next_after_uint_vector_buffer_xe + pass_byte_buffer_xe(xe_resolve_edram) pass_next_after_byte_buffer_xe resolve_info, - XeResolveColorCopySourcePixelAddressIntsYHalfPixelOffsetFilling( + XeResolveColorCopySourcePixelAddressBytesYHalfPixelOffsetFilling( resolve_info, pixel_index), pixels_0123, pixels_4567); dont_flatten_xe @@ -56,9 +54,8 @@ entry_inputs_end_code_begin_compute_xe } // Convert to R8. // TODO(Triang3l): Investigate formats 8_A and 8_B. - array_buffer_store_xe( - xe_resolve_dest, - XeResolveDestPixelAddress(resolve_info, pixel_index, 0u) >> 3u, + byte_buffer_align8_store8_xe( + xe_resolve_dest, XeResolveDestPixelAddress(resolve_info, pixel_index, 0u), uint2_xe(XePackR8G8B8A8UNorm(pixels_0123), XePackR8G8B8A8UNorm(pixels_4567))); } diff --git a/src/xenia/gpu/shaders/texture_load.xesli b/src/xenia/gpu/shaders/texture_load.xesli index cc1b3664e..967f6169d 100644 --- a/src/xenia/gpu/shaders/texture_load.xesli +++ b/src/xenia/gpu/shaders/texture_load.xesli @@ -49,6 +49,21 @@ push_const_begin_xe(b0, space0) uint xe_texture_load_height_texels; push_const_end_xe +#define XE_TEXTURE_LOAD_ENTRY(source_byte_buffer_alignment) \ + byte_buffer_align16_wo_declare_xe(xe_texture_load_dest, set=0, binding=0, \ + u0, space0) \ + byte_buffer_align##source_byte_buffer_alignment##_declare_xe( \ + xe_texture_load_source, set=1, binding=0, t0, space0) \ + entry_bindings_begin_compute_xe \ + XE_TEXTURE_LOAD_PUSH_CONST_BINDING \ + entry_binding_next_xe \ + byte_buffer_wo_binding_xe(xe_texture_load_dest, buffer(1)) \ + entry_binding_next_xe \ + byte_buffer_binding_xe(xe_texture_load_source, buffer(2)) \ + entry_bindings_end_inputs_begin_compute_xe \ + entry_in_global_thread_id_xe \ + entry_inputs_end_code_begin_compute_xe + #define XE_TEXTURE_LOAD_PUSH_CONST_BINDING push_const_binding_xe(buffer(0)) struct XeTextureLoadInfo { diff --git a/src/xenia/gpu/shaders/texture_load_128bpb.xesli b/src/xenia/gpu/shaders/texture_load_128bpb.xesli index ccba3b6b8..ed451f228 100644 --- a/src/xenia/gpu/shaders/texture_load_128bpb.xesli +++ b/src/xenia/gpu/shaders/texture_load_128bpb.xesli @@ -9,19 +9,7 @@ #include "texture_load.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_texture_load_dest, set=0, binding=0, u0, - space0) -array_buffer_declare_xe(uint4_xe, xe_texture_load_source, set=1, binding=0, t0, - space0) -entry_bindings_begin_compute_xe - XE_TEXTURE_LOAD_PUSH_CONST_BINDING - entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_texture_load_dest, buffer(1)) - entry_binding_next_xe - array_buffer_binding_xe(uint4_xe, xe_texture_load_source, buffer(2)) -entry_bindings_end_inputs_begin_compute_xe - entry_in_global_thread_id_xe -entry_inputs_end_code_begin_compute_xe +XE_TEXTURE_LOAD_ENTRY(16) { // 1 thread = 2 blocks. XeTextureLoadInfo load_info = XeTextureLoadGetInfo(pass_push_consts_xe); @@ -30,24 +18,24 @@ entry_inputs_end_code_begin_compute_xe if (any(greater_than_equal_xe(block_index.xy, load_info.size_blocks.xy))) { return; } - uint block_offset_host = uint( - (XeTextureHostLinearOffset(int3_xe(block_index), load_info.host_pitch, - load_info.size_blocks.y, 16u) + - load_info.host_offset) >> 4u); + uint block_offset_host = + load_info.host_offset + + uint(XeTextureHostLinearOffset(int3_xe(block_index), load_info.host_pitch, + load_info.size_blocks.y, 16u)); uint block_offset_guest = - XeTextureLoadSourceAddress(load_info, block_index, 4u) >> 4u; - array_buffer_store_xe( + XeTextureLoadSourceAddress(load_info, block_index, 4u); + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, - XeEndianSwap32(array_buffer_load_xe(xe_texture_load_source, - block_offset_guest), + XeEndianSwap32(byte_buffer_align16_load16_xe(xe_texture_load_source, + block_offset_guest), load_info.endian_32)); - ++block_offset_host; + block_offset_host += 16u; block_offset_guest += - XeTextureLoadLocalXAddressXor(1u, 4u, load_info.is_tiled) >> 4u; - array_buffer_store_xe( + XeTextureLoadLocalXAddressXor(1u, 4u, load_info.is_tiled); + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, - XeEndianSwap32(array_buffer_load_xe(xe_texture_load_source, - block_offset_guest), + XeEndianSwap32(byte_buffer_align16_load16_xe(xe_texture_load_source, + block_offset_guest), load_info.endian_32)); } entry_code_end_compute_xe diff --git a/src/xenia/gpu/shaders/texture_load_16bpb.xesli b/src/xenia/gpu/shaders/texture_load_16bpb.xesli index 03cbb0d0b..37212163d 100644 --- a/src/xenia/gpu/shaders/texture_load_16bpb.xesli +++ b/src/xenia/gpu/shaders/texture_load_16bpb.xesli @@ -9,19 +9,7 @@ #include "texture_load.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_texture_load_dest, set=0, binding=0, u0, - space0) -array_buffer_declare_xe(uint4_xe, xe_texture_load_source, set=1, binding=0, t0, - space0) -entry_bindings_begin_compute_xe - XE_TEXTURE_LOAD_PUSH_CONST_BINDING - entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_texture_load_dest, buffer(1)) - entry_binding_next_xe - array_buffer_binding_xe(uint4_xe, xe_texture_load_source, buffer(2)) -entry_bindings_end_inputs_begin_compute_xe - entry_in_global_thread_id_xe -entry_inputs_end_code_begin_compute_xe +XE_TEXTURE_LOAD_ENTRY(16) { // 1 thread = 16 blocks passed through an externally provided // uint4 transformation function (XE_TEXTURE_LOAD_16BPB_TRANSFORM). @@ -31,24 +19,24 @@ entry_inputs_end_code_begin_compute_xe if (any(greater_than_equal_xe(block_index.xy, load_info.size_blocks.xy))) { return; } - uint block_offset_host = uint( - (XeTextureHostLinearOffset(int3_xe(block_index), load_info.host_pitch, - load_info.size_blocks.y, 2u) + - load_info.host_offset) >> 4u); + uint block_offset_host = + load_info.host_offset + + uint(XeTextureHostLinearOffset(int3_xe(block_index), load_info.host_pitch, + load_info.size_blocks.y, 2u)); uint block_offset_guest = - XeTextureLoadSourceAddress(load_info, block_index, 1u) >> 4u; + XeTextureLoadSourceAddress(load_info, block_index, 1u); uint4_xe guest_blocks = XeEndianSwap16( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, block_offset_guest), load_info.endian_32); - array_buffer_store_xe(xe_texture_load_dest, block_offset_host, - XE_TEXTURE_LOAD_16BPB_TRANSFORM(guest_blocks)); - ++block_offset_host; + byte_buffer_align16_store16_xe(xe_texture_load_dest, block_offset_host, + XE_TEXTURE_LOAD_16BPB_TRANSFORM(guest_blocks)); + block_offset_host += 16u; block_offset_guest += - XeTextureLoadLocalXAddressXor(8u, 1u, load_info.is_tiled) >> 4u; + XeTextureLoadLocalXAddressXor(8u, 1u, load_info.is_tiled); guest_blocks = XeEndianSwap16( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, block_offset_guest), load_info.endian_32); - array_buffer_store_xe(xe_texture_load_dest, block_offset_host, - XE_TEXTURE_LOAD_16BPB_TRANSFORM(guest_blocks)); + byte_buffer_align16_store16_xe(xe_texture_load_dest, block_offset_host, + XE_TEXTURE_LOAD_16BPB_TRANSFORM(guest_blocks)); } entry_code_end_compute_xe diff --git a/src/xenia/gpu/shaders/texture_load_32bpb.xesli b/src/xenia/gpu/shaders/texture_load_32bpb.xesli index f26680874..45fdc2932 100644 --- a/src/xenia/gpu/shaders/texture_load_32bpb.xesli +++ b/src/xenia/gpu/shaders/texture_load_32bpb.xesli @@ -9,19 +9,7 @@ #include "texture_load.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_texture_load_dest, set=0, binding=0, u0, - space0) -array_buffer_declare_xe(uint4_xe, xe_texture_load_source, set=1, binding=0, t0, - space0) -entry_bindings_begin_compute_xe - XE_TEXTURE_LOAD_PUSH_CONST_BINDING - entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_texture_load_dest, buffer(1)) - entry_binding_next_xe - array_buffer_binding_xe(uint4_xe, xe_texture_load_source, buffer(2)) -entry_bindings_end_inputs_begin_compute_xe - entry_in_global_thread_id_xe -entry_inputs_end_code_begin_compute_xe +XE_TEXTURE_LOAD_ENTRY(16) { // 1 thread = 8 blocks passed through an externally provided // uint4 transformation function (XE_TEXTURE_LOAD_32BPB_TRANSFORM). @@ -31,24 +19,24 @@ entry_inputs_end_code_begin_compute_xe if (any(greater_than_equal_xe(block_index.xy, load_info.size_blocks.xy))) { return; } - uint block_offset_host = uint( - (XeTextureHostLinearOffset(int3_xe(block_index), load_info.host_pitch, - load_info.size_blocks.y, 4u) + - load_info.host_offset) >> 4u); + uint block_offset_host = + load_info.host_offset + + uint(XeTextureHostLinearOffset(int3_xe(block_index), load_info.host_pitch, + load_info.size_blocks.y, 4u)); uint block_offset_guest = - XeTextureLoadSourceAddress(load_info, block_index, 2u) >> 4u; + XeTextureLoadSourceAddress(load_info, block_index, 2u); uint4_xe guest_blocks = XeEndianSwap32( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, block_offset_guest), load_info.endian_32); - array_buffer_store_xe(xe_texture_load_dest, block_offset_host, - XE_TEXTURE_LOAD_32BPB_TRANSFORM(guest_blocks)); - ++block_offset_host; + byte_buffer_align16_store16_xe(xe_texture_load_dest, block_offset_host, + XE_TEXTURE_LOAD_32BPB_TRANSFORM(guest_blocks)); + block_offset_host += 16u; block_offset_guest += - XeTextureLoadLocalXAddressXor(4u, 2u, load_info.is_tiled) >> 4u; + XeTextureLoadLocalXAddressXor(4u, 2u, load_info.is_tiled); guest_blocks = XeEndianSwap32( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, block_offset_guest), load_info.endian_32); - array_buffer_store_xe(xe_texture_load_dest, block_offset_host, - XE_TEXTURE_LOAD_32BPB_TRANSFORM(guest_blocks)); + byte_buffer_align16_store16_xe(xe_texture_load_dest, block_offset_host, + XE_TEXTURE_LOAD_32BPB_TRANSFORM(guest_blocks)); } entry_code_end_compute_xe diff --git a/src/xenia/gpu/shaders/texture_load_32bpb_64bpb.xesli b/src/xenia/gpu/shaders/texture_load_32bpb_64bpb.xesli index 60a5dba5b..04324939a 100644 --- a/src/xenia/gpu/shaders/texture_load_32bpb_64bpb.xesli +++ b/src/xenia/gpu/shaders/texture_load_32bpb_64bpb.xesli @@ -9,19 +9,7 @@ #include "texture_load.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_texture_load_dest, set=0, binding=0, u0, - space0) -array_buffer_declare_xe(uint4_xe, xe_texture_load_source, set=1, binding=0, t0, - space0) -entry_bindings_begin_compute_xe - XE_TEXTURE_LOAD_PUSH_CONST_BINDING - entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_texture_load_dest, buffer(1)) - entry_binding_next_xe - array_buffer_binding_xe(uint4_xe, xe_texture_load_source, buffer(2)) -entry_bindings_end_inputs_begin_compute_xe - entry_in_global_thread_id_xe -entry_inputs_end_code_begin_compute_xe +XE_TEXTURE_LOAD_ENTRY(16) { // 1 thread = 8 packed 32-bit texels with the externally provided uint4 -> 2x // uint4 function (XE_TEXTURE_LOAD_32BPB_TO_64BPB) for converting to 64bpb - @@ -32,26 +20,30 @@ entry_inputs_end_code_begin_compute_xe if (any(greater_than_equal_xe(block_index.xy, load_info.size_blocks.xy))) { return; } - uint block_offset_host = uint( - (XeTextureHostLinearOffset(int3_xe(block_index), load_info.host_pitch, - load_info.size_blocks.y, 8u) + - load_info.host_offset) >> 4u); + uint block_offset_host = + load_info.host_offset + + uint(XeTextureHostLinearOffset(int3_xe(block_index), load_info.host_pitch, + load_info.size_blocks.y, 8u)); uint block_offset_guest = - XeTextureLoadSourceAddress(load_info, block_index, 2u) >> 4u; + XeTextureLoadSourceAddress(load_info, block_index, 2u); uint4_xe guest_blocks = XeEndianSwap32( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, block_offset_guest), load_info.endian_32); uint4_xe block_0, block_1; XE_TEXTURE_LOAD_32BPB_TO_64BPB(guest_blocks, block_0, block_1); - array_buffer_store_xe(xe_texture_load_dest, block_offset_host, block_0); - array_buffer_store_xe(xe_texture_load_dest, block_offset_host + 1u, block_1); + byte_buffer_align16_store16_xe(xe_texture_load_dest, block_offset_host, + block_0); + byte_buffer_align16_store16_xe(xe_texture_load_dest, + block_offset_host + 0x10u, block_1); block_offset_guest += - XeTextureLoadLocalXAddressXor(4u, 2u, load_info.is_tiled) >> 4u; + XeTextureLoadLocalXAddressXor(4u, 2u, load_info.is_tiled); guest_blocks = XeEndianSwap32( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, block_offset_guest), load_info.endian_32); XE_TEXTURE_LOAD_32BPB_TO_64BPB(guest_blocks, block_0, block_1); - array_buffer_store_xe(xe_texture_load_dest, block_offset_host + 2u, block_0); - array_buffer_store_xe(xe_texture_load_dest, block_offset_host + 3u, block_1); + byte_buffer_align16_store16_xe(xe_texture_load_dest, + block_offset_host + 0x20u, block_0); + byte_buffer_align16_store16_xe(xe_texture_load_dest, + block_offset_host + 0x30u, block_1); } entry_code_end_compute_xe diff --git a/src/xenia/gpu/shaders/texture_load_64bpb.xesli b/src/xenia/gpu/shaders/texture_load_64bpb.xesli index ad8520ae8..df449ab2c 100644 --- a/src/xenia/gpu/shaders/texture_load_64bpb.xesli +++ b/src/xenia/gpu/shaders/texture_load_64bpb.xesli @@ -9,19 +9,7 @@ #include "texture_load.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_texture_load_dest, set=0, binding=0, u0, - space0) -array_buffer_declare_xe(uint4_xe, xe_texture_load_source, set=1, binding=0, t0, - space0) -entry_bindings_begin_compute_xe - XE_TEXTURE_LOAD_PUSH_CONST_BINDING - entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_texture_load_dest, buffer(1)) - entry_binding_next_xe - array_buffer_binding_xe(uint4_xe, xe_texture_load_source, buffer(2)) -entry_bindings_end_inputs_begin_compute_xe - entry_in_global_thread_id_xe -entry_inputs_end_code_begin_compute_xe +XE_TEXTURE_LOAD_ENTRY(16) { // 1 thread = 4 blocks passed through an externally provided // uint4 transformation function (XE_TEXTURE_LOAD_64BPB_TRANSFORM). @@ -31,24 +19,24 @@ entry_inputs_end_code_begin_compute_xe if (any(greater_than_equal_xe(block_index.xy, load_info.size_blocks.xy))) { return; } - uint block_offset_host = uint( - (XeTextureHostLinearOffset(int3_xe(block_index), load_info.host_pitch, - load_info.size_blocks.y, 8u) + - load_info.host_offset) >> 4u); + uint block_offset_host = + load_info.host_offset + + uint(XeTextureHostLinearOffset(int3_xe(block_index), load_info.host_pitch, + load_info.size_blocks.y, 8u)); uint block_offset_guest = - XeTextureLoadSourceAddress(load_info, block_index, 3u) >> 4u; + XeTextureLoadSourceAddress(load_info, block_index, 3u); uint4_xe guest_blocks = XeEndianSwap32( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, block_offset_guest), load_info.endian_32); - array_buffer_store_xe(xe_texture_load_dest, block_offset_host, - XE_TEXTURE_LOAD_64BPB_TRANSFORM(guest_blocks)); - ++block_offset_host; + byte_buffer_align16_store16_xe(xe_texture_load_dest, block_offset_host, + XE_TEXTURE_LOAD_64BPB_TRANSFORM(guest_blocks)); + block_offset_host += 16u; block_offset_guest += - XeTextureLoadLocalXAddressXor(2u, 3u, load_info.is_tiled) >> 4u; + XeTextureLoadLocalXAddressXor(2u, 3u, load_info.is_tiled); guest_blocks = XeEndianSwap32( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, block_offset_guest), load_info.endian_32); - array_buffer_store_xe(xe_texture_load_dest, block_offset_host, - XE_TEXTURE_LOAD_64BPB_TRANSFORM(guest_blocks)); + byte_buffer_align16_store16_xe(xe_texture_load_dest, block_offset_host, + XE_TEXTURE_LOAD_64BPB_TRANSFORM(guest_blocks)); } entry_code_end_compute_xe diff --git a/src/xenia/gpu/shaders/texture_load_8bpb.xesli b/src/xenia/gpu/shaders/texture_load_8bpb.xesli index 804a8e15e..92112d5a6 100644 --- a/src/xenia/gpu/shaders/texture_load_8bpb.xesli +++ b/src/xenia/gpu/shaders/texture_load_8bpb.xesli @@ -9,19 +9,7 @@ #include "texture_load.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_texture_load_dest, set=0, binding=0, u0, - space0) -array_buffer_declare_xe(uint2_xe, xe_texture_load_source, set=1, binding=0, t0, - space0) -entry_bindings_begin_compute_xe - XE_TEXTURE_LOAD_PUSH_CONST_BINDING - entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_texture_load_dest, buffer(1)) - entry_binding_next_xe - array_buffer_binding_xe(uint2_xe, xe_texture_load_source, buffer(2)) -entry_bindings_end_inputs_begin_compute_xe - entry_in_global_thread_id_xe -entry_inputs_end_code_begin_compute_xe +XE_TEXTURE_LOAD_ENTRY(8) { // 1 thread = 16 blocks. XeTextureLoadInfo load_info = XeTextureLoadGetInfo(pass_push_consts_xe); @@ -30,20 +18,20 @@ entry_inputs_end_code_begin_compute_xe if (any(greater_than_equal_xe(block_index.xy, load_info.size_blocks.xy))) { return; } - uint block_offset_host = uint( - (XeTextureHostLinearOffset(int3_xe(block_index), load_info.host_pitch, - load_info.size_blocks.y, 1u) + - load_info.host_offset) >> 4u); + uint block_offset_host = + load_info.host_offset + + uint(XeTextureHostLinearOffset(int3_xe(block_index), load_info.host_pitch, + load_info.size_blocks.y, 1u)); uint block_offset_guest = - XeTextureLoadSourceAddress(load_info, block_index, 0u) >> 3u; - array_buffer_store_xe( + XeTextureLoadSourceAddress(load_info, block_index, 0u); + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, uint4_xe( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), - array_buffer_load_xe( + byte_buffer_align8_load8_xe(xe_texture_load_source, + block_offset_guest), + byte_buffer_align8_load8_xe( xe_texture_load_source, block_offset_guest + - (XeTextureLoadLocalXAddressXor(8u, 0u, load_info.is_tiled) - >> 3u)))); + XeTextureLoadLocalXAddressXor(8u, 0u, load_info.is_tiled)))); } entry_code_end_compute_xe diff --git a/src/xenia/gpu/shaders/texture_load_ctx1.cs.xesl b/src/xenia/gpu/shaders/texture_load_ctx1.cs.xesl index 6c093039b..6eb683269 100644 --- a/src/xenia/gpu/shaders/texture_load_ctx1.cs.xesl +++ b/src/xenia/gpu/shaders/texture_load_ctx1.cs.xesl @@ -24,19 +24,7 @@ // II JJ KK LL // MM NN OO PP -array_buffer_wo_declare_xe(uint4_xe, xe_texture_load_dest, set=0, binding=0, u0, - space0) -array_buffer_declare_xe(uint4_xe, xe_texture_load_source, set=1, binding=0, t0, - space0) -entry_bindings_begin_compute_xe - XE_TEXTURE_LOAD_PUSH_CONST_BINDING - entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_texture_load_dest, buffer(1)) - entry_binding_next_xe - array_buffer_binding_xe(uint4_xe, xe_texture_load_source, buffer(2)) -entry_bindings_end_inputs_begin_compute_xe - entry_in_global_thread_id_xe -entry_inputs_end_code_begin_compute_xe +XE_TEXTURE_LOAD_ENTRY(16) { // 1 thread = 4 CTX1 blocks to 16x4 R8G8 texels. XeTextureLoadInfo load_info = XeTextureLoadGetInfo(pass_push_consts_xe); @@ -46,24 +34,24 @@ entry_inputs_end_code_begin_compute_xe return; } uint3_xe texel_index_host = block_index << uint3_xe(2u, 2u, 0u); - uint block_offset_host = uint( - (XeTextureHostLinearOffset(int3_xe(texel_index_host), - load_info.host_pitch, load_info.height_texels, - 2u) + - load_info.host_offset) >> 4u); - uint elements_pitch_host = load_info.host_pitch >> 4u; + uint block_offset_host = + load_info.host_offset + + uint(XeTextureHostLinearOffset(int3_xe(texel_index_host), + load_info.host_pitch, + load_info.height_texels, 2u)); uint block_offset_guest = - XeTextureLoadSourceAddress(load_info, block_index, 3u) >> 4u; + XeTextureLoadSourceAddress(load_info, block_index, 3u); uint i; unroll_xe for (i = 0u; i < 2u; ++i) { if (i != 0u) { - ++block_offset_host; - // Odd 2 blocks = even 2 blocks + 32 bytes when tiled. - block_offset_guest += load_info.is_tiled ? 2u : 1u; + block_offset_host += 16u; + block_offset_guest += XeTextureLoadLocalXAddressXor(2u, 3u, + load_info.is_tiled); } // Two blocks. uint4_xe blocks = XeEndianSwap32( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, + block_offset_guest), load_info.endian_32); // Unpack the endpoints as 0x00g000r0 0x00G000R0 0x00g100r1 0x00G100R1 so // they can be multiplied by their weights allowing overflow. @@ -71,22 +59,22 @@ entry_inputs_end_code_begin_compute_xe end_8in16.xz = ((blocks.xz >> 8u) & 0xFFu) | ((blocks.xz & 0xFFu) << 16u); end_8in16.yw = (blocks.xz >> 24u) | (blocks.xz & 0xFF0000u); uint2_xe weights_high = XeDXTHighColorWeights(blocks.yw); - array_buffer_store_xe( + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, XeCTX1TwoBlocksRowToR8G8(end_8in16, weights_high)); dont_flatten_xe if (texel_index_host.y + 1u < load_info.height_texels) { - array_buffer_store_xe( - xe_texture_load_dest, block_offset_host + elements_pitch_host, + byte_buffer_align16_store16_xe( + xe_texture_load_dest, block_offset_host + load_info.host_pitch, XeCTX1TwoBlocksRowToR8G8(end_8in16, weights_high >> 8u)); dont_flatten_xe if (texel_index_host.y + 2u < load_info.height_texels) { - array_buffer_store_xe( - xe_texture_load_dest, block_offset_host + 2u * elements_pitch_host, + byte_buffer_align16_store16_xe( + xe_texture_load_dest, block_offset_host + 2u * load_info.host_pitch, XeCTX1TwoBlocksRowToR8G8(end_8in16, weights_high >> 16u)); dont_flatten_xe if (texel_index_host.y + 3u < load_info.height_texels) { - array_buffer_store_xe( + byte_buffer_align16_store16_xe( xe_texture_load_dest, - block_offset_host + 3u * elements_pitch_host, + block_offset_host + 3u * load_info.host_pitch, XeCTX1TwoBlocksRowToR8G8(end_8in16, weights_high >> 24u)); } } diff --git a/src/xenia/gpu/shaders/texture_load_dxn_rg8.cs.xesl b/src/xenia/gpu/shaders/texture_load_dxn_rg8.cs.xesl index 80aa5a24d..432688633 100644 --- a/src/xenia/gpu/shaders/texture_load_dxn_rg8.cs.xesl +++ b/src/xenia/gpu/shaders/texture_load_dxn_rg8.cs.xesl @@ -10,19 +10,7 @@ #include "pixel_formats.xesli" #include "texture_load.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_texture_load_dest, set=0, binding=0, u0, - space0) -array_buffer_declare_xe(uint4_xe, xe_texture_load_source, set=1, binding=0, t0, - space0) -entry_bindings_begin_compute_xe - XE_TEXTURE_LOAD_PUSH_CONST_BINDING - entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_texture_load_dest, buffer(1)) - entry_binding_next_xe - array_buffer_binding_xe(uint4_xe, xe_texture_load_source, buffer(2)) -entry_bindings_end_inputs_begin_compute_xe - entry_in_global_thread_id_xe -entry_inputs_end_code_begin_compute_xe +XE_TEXTURE_LOAD_ENTRY(16) { // 1 thread = 2 DXN blocks to 8x4 R8G8 texels. XeTextureLoadInfo load_info = XeTextureLoadGetInfo(pass_push_consts_xe); @@ -32,21 +20,20 @@ entry_inputs_end_code_begin_compute_xe return; } uint3_xe texel_index_host = block_index << uint3_xe(2u, 2u, 0u); - uint block_offset_host = uint( - (XeTextureHostLinearOffset(int3_xe(texel_index_host), - load_info.host_pitch, load_info.height_texels, - 2u) + - load_info.host_offset) >> 4u); - uint elements_pitch_host = load_info.host_pitch >> 4u; + uint block_offset_host = + load_info.host_offset + + uint(XeTextureHostLinearOffset(int3_xe(texel_index_host), + load_info.host_pitch, + load_info.height_texels, 2u)); uint block_offset_guest = - XeTextureLoadSourceAddress(load_info, block_index, 4u) >> 4u; + XeTextureLoadSourceAddress(load_info, block_index, 4u); uint4_xe block_0 = XeEndianSwap32( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, block_offset_guest), load_info.endian_32); - // Odd block = even block + 32 guest bytes when tiled. - block_offset_guest += load_info.is_tiled ? 2u : 1u; + block_offset_guest += XeTextureLoadLocalXAddressXor(1u, 4u, + load_info.is_tiled); uint4_xe block_1 = XeEndianSwap32( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, block_offset_guest), load_info.endian_32); uint4_xe end_0 = (block_0.xxzz >> uint4_xe(0u, 8u, 0u, 8u)) & 0xFFu; uint4_xe end_1 = (block_1.xxzz >> uint4_xe(0u, 8u, 0u, 8u)) & 0xFFu; @@ -56,38 +43,38 @@ entry_inputs_end_code_begin_compute_xe XeDXT5HighAlphaWeights(end_0.zw, weights.y), XeDXT5HighAlphaWeights(end_1.xy, weights.z), XeDXT5HighAlphaWeights(end_1.zw, weights.w)); - array_buffer_store_xe( + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, uint4_xe(XeDXT5RowToA8In16(end_0.xy, weights.x) | (XeDXT5RowToA8In16(end_0.zw, weights.y) << 8u), XeDXT5RowToA8In16(end_1.xy, weights.z) | (XeDXT5RowToA8In16(end_1.zw, weights.w) << 8u))); dont_flatten_xe if (++texel_index_host.y < load_info.height_texels) { - block_offset_host += elements_pitch_host; + block_offset_host += load_info.host_pitch; weights >>= 12u; - array_buffer_store_xe( + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, uint4_xe(XeDXT5RowToA8In16(end_0.xy, weights.x) | (XeDXT5RowToA8In16(end_0.zw, weights.y) << 8u), XeDXT5RowToA8In16(end_1.xy, weights.z) | (XeDXT5RowToA8In16(end_1.zw, weights.w) << 8u))); dont_flatten_xe if (++texel_index_host.y < load_info.height_texels) { - block_offset_host += elements_pitch_host; + block_offset_host += load_info.host_pitch; weights = uint4_xe(block_0.yw, block_1.yw) >> 8u; weights = uint4_xe(XeDXT5HighAlphaWeights(end_0.xy, weights.x), XeDXT5HighAlphaWeights(end_0.zw, weights.y), XeDXT5HighAlphaWeights(end_1.xy, weights.z), XeDXT5HighAlphaWeights(end_1.zw, weights.w)); - array_buffer_store_xe( + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, uint4_xe(XeDXT5RowToA8In16(end_0.xy, weights.x) | (XeDXT5RowToA8In16(end_0.zw, weights.y) << 8u), XeDXT5RowToA8In16(end_1.xy, weights.z) | (XeDXT5RowToA8In16(end_1.zw, weights.w) << 8u))); dont_flatten_xe if (++texel_index_host.y < load_info.height_texels) { - block_offset_host += elements_pitch_host; + block_offset_host += load_info.host_pitch; weights >>= 12u; - array_buffer_store_xe( + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, uint4_xe(XeDXT5RowToA8In16(end_0.xy, weights.x) | (XeDXT5RowToA8In16(end_0.zw, weights.y) << 8u), diff --git a/src/xenia/gpu/shaders/texture_load_dxt1_rgba8.cs.xesl b/src/xenia/gpu/shaders/texture_load_dxt1_rgba8.cs.xesl index 5aab74f27..439f56a70 100644 --- a/src/xenia/gpu/shaders/texture_load_dxt1_rgba8.cs.xesl +++ b/src/xenia/gpu/shaders/texture_load_dxt1_rgba8.cs.xesl @@ -10,19 +10,7 @@ #include "pixel_formats.xesli" #include "texture_load.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_texture_load_dest, set=0, binding=0, u0, - space0) -array_buffer_declare_xe(uint4_xe, xe_texture_load_source, set=1, binding=0, t0, - space0) -entry_bindings_begin_compute_xe - XE_TEXTURE_LOAD_PUSH_CONST_BINDING - entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_texture_load_dest, buffer(1)) - entry_binding_next_xe - array_buffer_binding_xe(uint4_xe, xe_texture_load_source, buffer(2)) -entry_bindings_end_inputs_begin_compute_xe - entry_in_global_thread_id_xe -entry_inputs_end_code_begin_compute_xe +XE_TEXTURE_LOAD_ENTRY(16) { // 1 thread = 4 DXT1 blocks to 16x4 R8G8B8A8 texels. XeTextureLoadInfo load_info = XeTextureLoadGetInfo(pass_push_consts_xe); @@ -32,21 +20,20 @@ entry_inputs_end_code_begin_compute_xe return; } uint3_xe texel_index_host = block_index << uint3_xe(2u, 2u, 0u); - uint block_offset_host = uint( - (XeTextureHostLinearOffset(int3_xe(texel_index_host), - load_info.host_pitch, load_info.height_texels, - 4u) + - load_info.host_offset) >> 4u); - uint elements_pitch_host = load_info.host_pitch >> 4u; + uint block_offset_host = + load_info.host_offset + + uint(XeTextureHostLinearOffset(int3_xe(texel_index_host), + load_info.host_pitch, + load_info.height_texels, 4u)); uint block_offset_guest = - XeTextureLoadSourceAddress(load_info, block_index, 3u) >> 4u; + XeTextureLoadSourceAddress(load_info, block_index, 3u); uint4_xe blocks_01 = XeEndianSwap32( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, block_offset_guest), load_info.endian_32); - // Odd 2 blocks = even 2 blocks + 32 bytes when tiled. - block_offset_guest += load_info.is_tiled ? 2u : 1u; + block_offset_guest += XeTextureLoadLocalXAddressXor(2u, 3u, + load_info.is_tiled); uint4_xe blocks_23 = XeEndianSwap32( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, block_offset_guest), load_info.endian_32); uint4_xe end_8in10_01 = uint4_xe(XeDXTColorEndpointsToBGR8In10(blocks_01.x), @@ -66,26 +53,26 @@ entry_inputs_end_code_begin_compute_xe if (texel_index_host.y + i >= load_info.height_texels) { break; } - block_offset_host += elements_pitch_host; + block_offset_host += load_info.host_pitch; weights >>= 8u; } - array_buffer_store_xe( + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, is_trans.x ? XeDXT1TransRowToRGBA8(end_8in10_01.xy, weights.x) : (XeDXTOpaqueRowToRGB8(end_8in10_01.xy, weights.x) | 0xFF000000u)); - array_buffer_store_xe( - xe_texture_load_dest, block_offset_host + 1u, + byte_buffer_align16_store16_xe( + xe_texture_load_dest, block_offset_host + 0x10u, is_trans.y ? XeDXT1TransRowToRGBA8(end_8in10_01.zw, weights.y) : (XeDXTOpaqueRowToRGB8(end_8in10_01.zw, weights.y) | 0xFF000000u)); - array_buffer_store_xe( - xe_texture_load_dest, block_offset_host + 2u, + byte_buffer_align16_store16_xe( + xe_texture_load_dest, block_offset_host + 0x20u, is_trans.z ? XeDXT1TransRowToRGBA8(end_8in10_23.xy, weights.z) : (XeDXTOpaqueRowToRGB8(end_8in10_23.xy, weights.z) | 0xFF000000u)); - array_buffer_store_xe( - xe_texture_load_dest, block_offset_host + 3u, + byte_buffer_align16_store16_xe( + xe_texture_load_dest, block_offset_host + 0x30u, is_trans.w ? XeDXT1TransRowToRGBA8(end_8in10_23.zw, weights.w) : (XeDXTOpaqueRowToRGB8(end_8in10_23.zw, weights.w) | 0xFF000000u)); diff --git a/src/xenia/gpu/shaders/texture_load_dxt3_rgba8.cs.xesl b/src/xenia/gpu/shaders/texture_load_dxt3_rgba8.cs.xesl index 207030c32..077bd916a 100644 --- a/src/xenia/gpu/shaders/texture_load_dxt3_rgba8.cs.xesl +++ b/src/xenia/gpu/shaders/texture_load_dxt3_rgba8.cs.xesl @@ -10,19 +10,7 @@ #include "pixel_formats.xesli" #include "texture_load.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_texture_load_dest, set=0, binding=0, u0, - space0) -array_buffer_declare_xe(uint4_xe, xe_texture_load_source, set=1, binding=0, t0, - space0) -entry_bindings_begin_compute_xe - XE_TEXTURE_LOAD_PUSH_CONST_BINDING - entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_texture_load_dest, buffer(1)) - entry_binding_next_xe - array_buffer_binding_xe(uint4_xe, xe_texture_load_source, buffer(2)) -entry_bindings_end_inputs_begin_compute_xe - entry_in_global_thread_id_xe -entry_inputs_end_code_begin_compute_xe +XE_TEXTURE_LOAD_ENTRY(16) { // 1 thread = 2 DXT3 blocks to 8x4 R8G8B8A8 texels. XeTextureLoadInfo load_info = XeTextureLoadGetInfo(pass_push_consts_xe); @@ -32,49 +20,49 @@ entry_inputs_end_code_begin_compute_xe return; } uint3_xe texel_index_host = block_index << uint3_xe(2u, 2u, 0u); - uint block_offset_host = uint( - (XeTextureHostLinearOffset(int3_xe(texel_index_host), - load_info.host_pitch, load_info.height_texels, - 4u) + - load_info.host_offset) >> 4u); - uint elements_pitch_host = load_info.host_pitch >> 4u; + uint block_offset_host = + load_info.host_offset + + uint(XeTextureHostLinearOffset(int3_xe(texel_index_host), + load_info.host_pitch, + load_info.height_texels, 4u)); uint block_offset_guest = - XeTextureLoadSourceAddress(load_info, block_index, 4u) >> 4u; + XeTextureLoadSourceAddress(load_info, block_index, 4u); uint i; unroll_xe for (i = 0u; i < 2u; ++i) { if (i != 0u) { - ++block_offset_host; - // Odd block = even block + 32 guest bytes when tiled. - block_offset_guest += load_info.is_tiled ? 2u : 1u; + block_offset_host += 16u; + block_offset_guest += XeTextureLoadLocalXAddressXor(1u, 4u, + load_info.is_tiled); } uint4_xe block = XeEndianSwap32( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, + block_offset_guest), load_info.endian_32); uint2_xe bgr_end_8in10 = XeDXTColorEndpointsToBGR8In10(block.z); // Sort the color indices so they can be used as weights for the second // endpoint. uint bgr_weights = XeDXTHighColorWeights(block.w); - array_buffer_store_xe( + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, XeDXTOpaqueRowToRGB8(bgr_end_8in10, bgr_weights) + ((block.xxxx >> uint4_xe(0u, 4u, 8u, 12u)) & 0xFu) * 0x11000000u); dont_flatten_xe if (texel_index_host.y + 1u < load_info.height_texels) { - array_buffer_store_xe( - xe_texture_load_dest, block_offset_host + elements_pitch_host, + byte_buffer_align16_store16_xe( + xe_texture_load_dest, block_offset_host + load_info.host_pitch, XeDXTOpaqueRowToRGB8(bgr_end_8in10, bgr_weights >> 8u) + ((block.xxxx >> uint4_xe(16u, 20u, 24u, 28u)) & 0xFu) * 0x11000000u); dont_flatten_xe if (texel_index_host.y + 2u < load_info.height_texels) { - array_buffer_store_xe( - xe_texture_load_dest, block_offset_host + 2u * elements_pitch_host, + byte_buffer_align16_store16_xe( + xe_texture_load_dest, block_offset_host + 2u * load_info.host_pitch, XeDXTOpaqueRowToRGB8(bgr_end_8in10, bgr_weights >> 16u) + ((block.yyyy >> uint4_xe(0u, 4u, 8u, 12u)) & 0xFu) * 0x11000000u); dont_flatten_xe if (texel_index_host.y + 3u < load_info.height_texels) { - array_buffer_store_xe( + byte_buffer_align16_store16_xe( xe_texture_load_dest, - block_offset_host + 3u * elements_pitch_host, + block_offset_host + 3u * load_info.host_pitch, XeDXTOpaqueRowToRGB8(bgr_end_8in10, bgr_weights >> 24u) + ((block.yyyy >> uint4_xe(16u, 20u, 24u, 28u)) & 0xFu) * 0x11000000u); diff --git a/src/xenia/gpu/shaders/texture_load_dxt3a.cs.xesl b/src/xenia/gpu/shaders/texture_load_dxt3a.cs.xesl index bfdb37601..c2015253f 100644 --- a/src/xenia/gpu/shaders/texture_load_dxt3a.cs.xesl +++ b/src/xenia/gpu/shaders/texture_load_dxt3a.cs.xesl @@ -10,19 +10,7 @@ #include "pixel_formats.xesli" #include "texture_load.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_texture_load_dest, set=0, binding=0, u0, - space0) -array_buffer_declare_xe(uint4_xe, xe_texture_load_source, set=1, binding=0, t0, - space0) -entry_bindings_begin_compute_xe - XE_TEXTURE_LOAD_PUSH_CONST_BINDING - entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_texture_load_dest, buffer(1)) - entry_binding_next_xe - array_buffer_binding_xe(uint4_xe, xe_texture_load_source, buffer(2)) -entry_bindings_end_inputs_begin_compute_xe - entry_in_global_thread_id_xe -entry_inputs_end_code_begin_compute_xe +XE_TEXTURE_LOAD_ENTRY(16) { // 1 thread = 4 DXT3A blocks to 16x4 R8 texels (no need to convert to DXT3 // because the overhead is the same, 2x, but the size must be 4-aligned on @@ -34,38 +22,37 @@ entry_inputs_end_code_begin_compute_xe return; } uint3_xe texel_index_host = block_index << uint3_xe(2u, 2u, 0u); - uint block_offset_host = uint( - (XeTextureHostLinearOffset(int3_xe(texel_index_host), - load_info.host_pitch, load_info.height_texels, - 1u) + - load_info.host_offset) >> 4u); - uint elements_pitch_host = load_info.host_pitch >> 4u; + uint block_offset_host = + load_info.host_offset + + uint(XeTextureHostLinearOffset(int3_xe(texel_index_host), + load_info.host_pitch, + load_info.height_texels, 1u)); uint block_offset_guest = - XeTextureLoadSourceAddress(load_info, block_index, 3u) >> 4u; + XeTextureLoadSourceAddress(load_info, block_index, 3u); uint4_xe blocks_01 = XeEndianSwap32( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, block_offset_guest), load_info.endian_32); - // Odd 2 blocks = even 2 blocks + 32 bytes when tiled. - block_offset_guest += load_info.is_tiled ? 2u : 1u; + block_offset_guest += XeTextureLoadLocalXAddressXor(2u, 3u, + load_info.is_tiled); uint4_xe blocks_23 = XeEndianSwap32( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, block_offset_guest), load_info.endian_32); - array_buffer_store_xe( + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, XeDXT3FourBlocksRowToA8(uint4_xe(blocks_01.xz, blocks_23.xz))); dont_flatten_xe if (++texel_index_host.y < load_info.height_texels) { - block_offset_host += elements_pitch_host; - array_buffer_store_xe( + block_offset_host += load_info.host_pitch; + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, XeDXT3FourBlocksRowToA8(uint4_xe(blocks_01.xz, blocks_23.xz) >> 16u)); dont_flatten_xe if (++texel_index_host.y < load_info.height_texels) { - block_offset_host += elements_pitch_host; - array_buffer_store_xe( + block_offset_host += load_info.host_pitch; + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, XeDXT3FourBlocksRowToA8(uint4_xe(blocks_01.yw, blocks_23.yw))); dont_flatten_xe if (++texel_index_host.y < load_info.height_texels) { - block_offset_host += elements_pitch_host; - array_buffer_store_xe( + block_offset_host += load_info.host_pitch; + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, XeDXT3FourBlocksRowToA8( uint4_xe(blocks_01.yw, blocks_23.yw) >> 16u)); diff --git a/src/xenia/gpu/shaders/texture_load_dxt3aas1111.xesli b/src/xenia/gpu/shaders/texture_load_dxt3aas1111.xesli index 57d9e74e1..7ea57e610 100644 --- a/src/xenia/gpu/shaders/texture_load_dxt3aas1111.xesli +++ b/src/xenia/gpu/shaders/texture_load_dxt3aas1111.xesli @@ -9,19 +9,7 @@ #include "texture_load.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_texture_load_dest, set=0, binding=0, u0, - space0) -array_buffer_declare_xe(uint4_xe, xe_texture_load_source, set=1, binding=0, t0, - space0) -entry_bindings_begin_compute_xe - XE_TEXTURE_LOAD_PUSH_CONST_BINDING - entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_texture_load_dest, buffer(1)) - entry_binding_next_xe - array_buffer_binding_xe(uint4_xe, xe_texture_load_source, buffer(2)) -entry_bindings_end_inputs_begin_compute_xe - entry_in_global_thread_id_xe -entry_inputs_end_code_begin_compute_xe +XE_TEXTURE_LOAD_ENTRY(16) { // 1 thread = 4 DXT3A-as-1111 blocks to 16x4 16bpp texels passed through an // externally provided @@ -34,53 +22,52 @@ entry_inputs_end_code_begin_compute_xe return; } uint3_xe texel_index_host = block_index << uint3_xe(2u, 2u, 0u); - uint block_offset_host = uint( - (XeTextureHostLinearOffset(int3_xe(texel_index_host), - load_info.host_pitch, load_info.height_texels, - 2u) + - load_info.host_offset) >> 4u); - uint elements_pitch_host = load_info.host_pitch >> 4u; + uint block_offset_host = + load_info.host_offset + + uint(XeTextureHostLinearOffset(int3_xe(texel_index_host), + load_info.host_pitch, + load_info.height_texels, 2u)); uint block_offset_guest = - XeTextureLoadSourceAddress(load_info, block_index, 3u) >> 4u; + XeTextureLoadSourceAddress(load_info, block_index, 3u); uint4_xe blocks_01 = XeEndianSwap32( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, block_offset_guest), load_info.endian_32); - // Odd 2 blocks = even 2 blocks + 32 bytes when tiled. - block_offset_guest += load_info.is_tiled ? 2u : 1u; + block_offset_guest += XeTextureLoadLocalXAddressXor(2u, 3u, + load_info.is_tiled); uint4_xe blocks_23 = XeEndianSwap32( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, block_offset_guest), load_info.endian_32); - array_buffer_store_xe( + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, XE_TEXTURE_LOAD_DXT3A_AS_1_1_1_1_TO_16BPP(blocks_01.xz)); - array_buffer_store_xe( - xe_texture_load_dest, block_offset_host + 1u, + byte_buffer_align16_store16_xe( + xe_texture_load_dest, block_offset_host + 16u, XE_TEXTURE_LOAD_DXT3A_AS_1_1_1_1_TO_16BPP(blocks_23.xz)); dont_flatten_xe if (++texel_index_host.y < load_info.height_texels) { - block_offset_host += elements_pitch_host; + block_offset_host += load_info.host_pitch; uint4_xe high_halfblocks = uint4_xe(blocks_01.xz, blocks_23.xz) >> 16u; - array_buffer_store_xe( + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, XE_TEXTURE_LOAD_DXT3A_AS_1_1_1_1_TO_16BPP(high_halfblocks.xy)); - array_buffer_store_xe( - xe_texture_load_dest, block_offset_host + 1u, + byte_buffer_align16_store16_xe( + xe_texture_load_dest, block_offset_host + 16u, XE_TEXTURE_LOAD_DXT3A_AS_1_1_1_1_TO_16BPP(high_halfblocks.zw)); dont_flatten_xe if (++texel_index_host.y < load_info.height_texels) { - block_offset_host += elements_pitch_host; - array_buffer_store_xe( + block_offset_host += load_info.host_pitch; + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, XE_TEXTURE_LOAD_DXT3A_AS_1_1_1_1_TO_16BPP(blocks_01.yw)); - array_buffer_store_xe( - xe_texture_load_dest, block_offset_host + 1u, + byte_buffer_align16_store16_xe( + xe_texture_load_dest, block_offset_host + 16u, XE_TEXTURE_LOAD_DXT3A_AS_1_1_1_1_TO_16BPP(blocks_23.yw)); dont_flatten_xe if (++texel_index_host.y < load_info.height_texels) { - block_offset_host += elements_pitch_host; + block_offset_host += load_info.host_pitch; high_halfblocks = uint4_xe(blocks_01.yw, blocks_23.yw) >> 16u; - array_buffer_store_xe( + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, XE_TEXTURE_LOAD_DXT3A_AS_1_1_1_1_TO_16BPP(high_halfblocks.xy)); - array_buffer_store_xe( - xe_texture_load_dest, block_offset_host + 1u, + byte_buffer_align16_store16_xe( + xe_texture_load_dest, block_offset_host + 16u, XE_TEXTURE_LOAD_DXT3A_AS_1_1_1_1_TO_16BPP(high_halfblocks.zw)); } } diff --git a/src/xenia/gpu/shaders/texture_load_dxt5_rgba8.cs.xesl b/src/xenia/gpu/shaders/texture_load_dxt5_rgba8.cs.xesl index 51dfcc080..5b935c740 100644 --- a/src/xenia/gpu/shaders/texture_load_dxt5_rgba8.cs.xesl +++ b/src/xenia/gpu/shaders/texture_load_dxt5_rgba8.cs.xesl @@ -10,19 +10,7 @@ #include "pixel_formats.xesli" #include "texture_load.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_texture_load_dest, set=0, binding=0, u0, - space0) -array_buffer_declare_xe(uint4_xe, xe_texture_load_source, set=1, binding=0, t0, - space0) -entry_bindings_begin_compute_xe - XE_TEXTURE_LOAD_PUSH_CONST_BINDING - entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_texture_load_dest, buffer(1)) - entry_binding_next_xe - array_buffer_binding_xe(uint4_xe, xe_texture_load_source, buffer(2)) -entry_bindings_end_inputs_begin_compute_xe - entry_in_global_thread_id_xe -entry_inputs_end_code_begin_compute_xe +XE_TEXTURE_LOAD_ENTRY(16) { // 1 thread = 2 DXT5 blocks to 8x4 R8G8B8A8 texels. XeTextureLoadInfo load_info = XeTextureLoadGetInfo(pass_push_consts_xe); @@ -32,23 +20,23 @@ entry_inputs_end_code_begin_compute_xe return; } uint3_xe texel_index_host = block_index << uint3_xe(2u, 2u, 0u); - uint block_offset_host = uint( - (XeTextureHostLinearOffset(int3_xe(texel_index_host), - load_info.host_pitch, load_info.height_texels, - 4u) + - load_info.host_offset) >> 4u); - uint elements_pitch_host = load_info.host_pitch >> 4u; + uint block_offset_host = + load_info.host_offset + + uint(XeTextureHostLinearOffset(int3_xe(texel_index_host), + load_info.host_pitch, + load_info.height_texels, 4u)); uint block_offset_guest = - XeTextureLoadSourceAddress(load_info, block_index, 4u) >> 4u; + XeTextureLoadSourceAddress(load_info, block_index, 4u); uint i; unroll_xe for (i = 0u; i < 2u; ++i) { if (i != 0u) { - ++block_offset_host; - // Odd block = even block + 32 guest bytes when tiled. - block_offset_guest += load_info.is_tiled ? 2u : 1u; + block_offset_host += 16u; + block_offset_guest += XeTextureLoadLocalXAddressXor(1u, 4u, + load_info.is_tiled); } uint4_xe block = XeEndianSwap32( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, + block_offset_guest), load_info.endian_32); uint2_xe bgr_end_8in10 = XeDXTColorEndpointsToBGR8In10(block.z); // Sort the color indices so they can be used as weights for the second @@ -57,32 +45,32 @@ entry_inputs_end_code_begin_compute_xe uint2_xe alpha_end = (block.xx >> uint2_xe(0u, 8u)) & 0xFFu; uint alpha_weights = XeDXT5HighAlphaWeights( alpha_end, (block.x >> 16u) | ((block.y & 0xFFu) << 16u)); - array_buffer_store_xe( + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, XeDXTOpaqueRowToRGB8(bgr_end_8in10, bgr_weights) | ((uint_x4_xe(XeDXT5RowToA8(alpha_end, alpha_weights)) << uint4_xe(24u, 16u, 8u, 0u)) & 0xFF000000u)); dont_flatten_xe if (texel_index_host.y + 1u < load_info.height_texels) { - array_buffer_store_xe( - xe_texture_load_dest, block_offset_host + elements_pitch_host, + byte_buffer_align16_store16_xe( + xe_texture_load_dest, block_offset_host + load_info.host_pitch, XeDXTOpaqueRowToRGB8(bgr_end_8in10, bgr_weights >> 8u) | ((uint_x4_xe(XeDXT5RowToA8(alpha_end, alpha_weights >> 12u)) << uint4_xe(24u, 16u, 8u, 0u)) & 0xFF000000u)); dont_flatten_xe if (texel_index_host.y + 2u < load_info.height_texels) { alpha_weights = XeDXT5HighAlphaWeights(alpha_end, block.y >> 8u); - array_buffer_store_xe( - xe_texture_load_dest, block_offset_host + 2u * elements_pitch_host, + byte_buffer_align16_store16_xe( + xe_texture_load_dest, block_offset_host + 2u * load_info.host_pitch, XeDXTOpaqueRowToRGB8(bgr_end_8in10, bgr_weights >> 16u) | ((uint_x4_xe(XeDXT5RowToA8(alpha_end, alpha_weights)) << uint4_xe(24u, 16u, 8u, 0u)) & 0xFF000000u)); dont_flatten_xe if (texel_index_host.y + 3u < load_info.height_texels) { - array_buffer_store_xe( + byte_buffer_align16_store16_xe( xe_texture_load_dest, - block_offset_host + 3u * elements_pitch_host, + block_offset_host + 3u * load_info.host_pitch, XeDXTOpaqueRowToRGB8(bgr_end_8in10, bgr_weights >> 24u) | ((uint_x4_xe(XeDXT5RowToA8(alpha_end, alpha_weights >> 12u)) << uint4_xe(24u, 16u, 8u, 0u)) diff --git a/src/xenia/gpu/shaders/texture_load_dxt5a_r8.cs.xesl b/src/xenia/gpu/shaders/texture_load_dxt5a_r8.cs.xesl index d2fb00bf1..b601557bb 100644 --- a/src/xenia/gpu/shaders/texture_load_dxt5a_r8.cs.xesl +++ b/src/xenia/gpu/shaders/texture_load_dxt5a_r8.cs.xesl @@ -10,19 +10,7 @@ #include "pixel_formats.xesli" #include "texture_load.xesli" -array_buffer_wo_declare_xe(uint4_xe, xe_texture_load_dest, set=0, binding=0, u0, - space0) -array_buffer_declare_xe(uint4_xe, xe_texture_load_source, set=1, binding=0, t0, - space0) -entry_bindings_begin_compute_xe - XE_TEXTURE_LOAD_PUSH_CONST_BINDING - entry_binding_next_xe - array_buffer_wo_binding_xe(uint4_xe, xe_texture_load_dest, buffer(1)) - entry_binding_next_xe - array_buffer_binding_xe(uint4_xe, xe_texture_load_source, buffer(2)) -entry_bindings_end_inputs_begin_compute_xe - entry_in_global_thread_id_xe -entry_inputs_end_code_begin_compute_xe +XE_TEXTURE_LOAD_ENTRY(16) { // 1 thread = 4 DXT5A blocks to 16x4 R8 texels. XeTextureLoadInfo load_info = XeTextureLoadGetInfo(pass_push_consts_xe); @@ -32,21 +20,20 @@ entry_inputs_end_code_begin_compute_xe return; } uint3_xe texel_index_host = block_index << uint3_xe(2u, 2u, 0u); - uint block_offset_host = uint( - (XeTextureHostLinearOffset(int3_xe(texel_index_host), - load_info.host_pitch, load_info.height_texels, - 1u) + - load_info.host_offset) >> 4u); - uint elements_pitch_host = load_info.host_pitch >> 4u; + uint block_offset_host = + load_info.host_offset + + uint(XeTextureHostLinearOffset(int3_xe(texel_index_host), + load_info.host_pitch, + load_info.height_texels, 1u)); uint block_offset_guest = - XeTextureLoadSourceAddress(load_info, block_index, 3u) >> 4u; + XeTextureLoadSourceAddress(load_info, block_index, 3u); uint4_xe blocks_01 = XeEndianSwap32( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, block_offset_guest), load_info.endian_32); - // Odd 2 blocks = even 2 blocks + 32 bytes when tiled. - block_offset_guest += load_info.is_tiled ? 2u : 1u; + block_offset_guest += XeTextureLoadLocalXAddressXor(2u, 3u, + load_info.is_tiled); uint4_xe blocks_23 = XeEndianSwap32( - array_buffer_load_xe(xe_texture_load_source, block_offset_guest), + byte_buffer_align16_load16_xe(xe_texture_load_source, block_offset_guest), load_info.endian_32); uint4_xe end_01 = (blocks_01.xxzz >> uint4_xe(0u, 8u, 0u, 8u)) & 0xFFu; uint4_xe end_23 = (blocks_23.xxzz >> uint4_xe(0u, 8u, 0u, 8u)) & 0xFFu; @@ -57,38 +44,38 @@ entry_inputs_end_code_begin_compute_xe XeDXT5HighAlphaWeights(end_01.zw, weights.y), XeDXT5HighAlphaWeights(end_23.xy, weights.z), XeDXT5HighAlphaWeights(end_23.zw, weights.w)); - array_buffer_store_xe( + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, uint4_xe(XeDXT5RowToA8(end_01.xy, weights.x), XeDXT5RowToA8(end_01.zw, weights.y), XeDXT5RowToA8(end_23.xy, weights.z), XeDXT5RowToA8(end_23.zw, weights.w))); dont_flatten_xe if (++texel_index_host.y < load_info.height_texels) { - block_offset_host += elements_pitch_host; + block_offset_host += load_info.host_pitch; weights >>= 12u; - array_buffer_store_xe( + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, uint4_xe(XeDXT5RowToA8(end_01.xy, weights.x), XeDXT5RowToA8(end_01.zw, weights.y), XeDXT5RowToA8(end_23.xy, weights.z), XeDXT5RowToA8(end_23.zw, weights.w))); dont_flatten_xe if (++texel_index_host.y < load_info.height_texels) { - block_offset_host += elements_pitch_host; + block_offset_host += load_info.host_pitch; weights = uint4_xe(blocks_01.yw, blocks_23.yw) >> 8u; weights = uint4_xe(XeDXT5HighAlphaWeights(end_01.xy, weights.x), XeDXT5HighAlphaWeights(end_01.zw, weights.y), XeDXT5HighAlphaWeights(end_23.xy, weights.z), XeDXT5HighAlphaWeights(end_23.zw, weights.w)); - array_buffer_store_xe( + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, uint4_xe(XeDXT5RowToA8(end_01.xy, weights.x), XeDXT5RowToA8(end_01.zw, weights.y), XeDXT5RowToA8(end_23.xy, weights.z), XeDXT5RowToA8(end_23.zw, weights.w))); dont_flatten_xe if (++texel_index_host.y < load_info.height_texels) { - block_offset_host += elements_pitch_host; + block_offset_host += load_info.host_pitch; weights >>= 12u; - array_buffer_store_xe( + byte_buffer_align16_store16_xe( xe_texture_load_dest, block_offset_host, uint4_xe(XeDXT5RowToA8(end_01.xy, weights.x), XeDXT5RowToA8(end_01.zw, weights.y), diff --git a/src/xenia/gpu/texture_cache.cc b/src/xenia/gpu/texture_cache.cc index 0531e2cf3..747d4cdc3 100644 --- a/src/xenia/gpu/texture_cache.cc +++ b/src/xenia/gpu/texture_cache.cc @@ -71,76 +71,41 @@ namespace gpu { const TextureCache::LoadShaderInfo TextureCache::load_shader_info_[kLoadShaderCount] = { - // k8bpb - {3, 4, 1, 4}, - // k16bpb - {4, 4, 2, 4}, - // k32bpb - {4, 4, 4, 3}, - // k64bpb - {4, 4, 8, 2}, - // k128bpb - {4, 4, 16, 1}, - // kR5G5B5A1ToB5G5R5A1 - {4, 4, 2, 4}, - // kR5G6B5ToB5G6R5 - {4, 4, 2, 4}, - // kR5G5B6ToB5G6R5WithRBGASwizzle - {4, 4, 2, 4}, - // kRGBA4ToBGRA4 - {4, 4, 2, 4}, - // kRGBA4ToARGB4 - {4, 4, 2, 4}, - // kGBGR8ToGRGB8 - {4, 4, 4, 3}, - // kGBGR8ToRGB8 - {4, 4, 8, 3}, - // kBGRG8ToRGBG8 - {4, 4, 4, 3}, - // kBGRG8ToRGB8 - {4, 4, 8, 3}, - // kR10G11B11ToRGBA16 - {4, 4, 8, 3}, - // kR10G11B11ToRGBA16SNorm - {4, 4, 8, 3}, - // kR11G11B10ToRGBA16 - {4, 4, 8, 3}, - // kR11G11B10ToRGBA16SNorm - {4, 4, 8, 3}, - // kR16UNormToFloat - {4, 4, 2, 4}, - // kR16SNormToFloat - {4, 4, 2, 4}, - // kRG16UNormToFloat - {4, 4, 4, 3}, - // kRG16SNormToFloat - {4, 4, 4, 3}, - // kRGBA16UNormToFloat - {4, 4, 8, 2}, - // kRGBA16SNormToFloat - {4, 4, 8, 2}, - // kDXT1ToRGBA8 - {4, 4, 4, 2}, - // kDXT3ToRGBA8 - {4, 4, 4, 1}, - // kDXT5ToRGBA8 - {4, 4, 4, 1}, - // kDXNToRG8 - {4, 4, 2, 1}, - // kDXT3A - {4, 4, 1, 2}, - // kDXT3AAs1111ToBGRA4 - {4, 4, 2, 2}, - // kDXT3AAs1111ToARGB4 - {4, 4, 2, 2}, - // kDXT5AToR8 - {4, 4, 1, 2}, - // kCTX1 - {4, 4, 2, 2}, - // kDepthUnorm - {4, 4, 4, 3}, - // kDepthFloat - {4, 4, 4, 3}, + {1, 4}, // k8bpb + {2, 4}, // k16bpb + {4, 3}, // k32bpb + {8, 2}, // k64bpb + {16, 1}, // k128bpb + {2, 4}, // kR5G5B5A1ToB5G5R5A1 + {2, 4}, // kR5G6B5ToB5G6R5 + {2, 4}, // kR5G5B6ToB5G6R5WithRBGASwizzle + {2, 4}, // kRGBA4ToBGRA4 + {2, 4}, // kRGBA4ToARGB4 + {4, 3}, // kGBGR8ToGRGB8 + {8, 3}, // kGBGR8ToRGB8 + {4, 3}, // kBGRG8ToRGBG8 + {8, 3}, // kBGRG8ToRGB8 + {8, 3}, // kR10G11B11ToRGBA16 + {8, 3}, // kR10G11B11ToRGBA16SNorm + {8, 3}, // kR11G11B10ToRGBA16 + {8, 3}, // kR11G11B10ToRGBA16SNorm + {2, 4}, // kR16UNormToFloat + {2, 4}, // kR16SNormToFloat + {4, 3}, // kRG16UNormToFloat + {4, 3}, // kRG16SNormToFloat + {8, 2}, // kRGBA16UNormToFloat + {8, 2}, // kRGBA16SNormToFloat + {4, 2}, // kDXT1ToRGBA8 + {4, 1}, // kDXT3ToRGBA8 + {4, 1}, // kDXT5ToRGBA8 + {2, 1}, // kDXNToRG8 + {1, 2}, // kDXT3A + {2, 2}, // kDXT3AAs1111ToBGRA4 + {2, 2}, // kDXT3AAs1111ToARGB4 + {1, 2}, // kDXT5AToR8 + {2, 2}, // kCTX1 + {4, 3}, // kDepthUnorm + {4, 3}, // kDepthFloat }; TextureCache::TextureCache(const RegisterFile& register_file, diff --git a/src/xenia/gpu/texture_cache.h b/src/xenia/gpu/texture_cache.h index a87656bb7..61c475e64 100644 --- a/src/xenia/gpu/texture_cache.h +++ b/src/xenia/gpu/texture_cache.h @@ -496,11 +496,6 @@ class TextureCache { }; struct LoadShaderInfo { - // Log2 of the sizes, in bytes, of the elements in the source (guest) and - // the destination (host) buffer bindings accessed by the copying shader, - // since the shader may copy multiple blocks per one invocation. - uint32_t source_bpe_log2; - uint32_t dest_bpe_log2; // Number of bytes in a host resolution-scaled block (corresponding to a // guest block if not decompressing, or a host texel if decompressing) // written by the shader. diff --git a/src/xenia/gpu/vulkan/vulkan_texture_cache.cc b/src/xenia/gpu/vulkan/vulkan_texture_cache.cc index 05b7ef001..45fa30636 100644 --- a/src/xenia/gpu/vulkan/vulkan_texture_cache.cc +++ b/src/xenia/gpu/vulkan/vulkan_texture_cache.cc @@ -1335,11 +1335,6 @@ bool VulkanTextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture, write_descriptor_set_dest.pTexelBufferView = nullptr; } // TODO(Triang3l): Use a single 512 MB shared memory binding if possible. - // Aligning because if the data for a vector in a storage buffer is provided - // partially, the value read may still be (0, 0, 0, 0), and small (especially - // linear) textures won't be loaded correctly. - uint32_t source_length_alignment = UINT32_C(1) - << load_shader_info.source_bpe_log2; VkDescriptorSet descriptor_set_source_base = VK_NULL_HANDLE; VkDescriptorSet descriptor_set_source_mips = VK_NULL_HANDLE; VkDescriptorBufferInfo write_descriptor_set_source_base_buffer_info; @@ -1374,10 +1369,10 @@ bool VulkanTextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture, write_descriptor_set_source_base_buffer_info.buffer = scaled_buffer; write_descriptor_set_source_base_buffer_info.offset = buffer_relative_offset; - write_descriptor_set_source_base_buffer_info.range = - xe::align(guest_size * draw_resolution_scale_area, - source_length_alignment); - + // Align because shaders use up to 16-byte loads for multiple + // blocks at once. + write_descriptor_set_source_base_buffer_info.range = xe::align( + guest_size * draw_resolution_scale_area, uint32_t(16)); } else { XELOGE( "Scaled resolve texture load: Failed to get current scaled " @@ -1405,8 +1400,10 @@ bool VulkanTextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture, vulkan_shared_memory.buffer(); write_descriptor_set_source_base_buffer_info.offset = texture_key.base_page << 12; + // Align (primarily the last row of linear textures) because shaders use + // up to 16-byte loads for multiple blocks at once. write_descriptor_set_source_base_buffer_info.range = - xe::align(vulkan_texture.GetGuestBaseSize(), source_length_alignment); + xe::align(vulkan_texture.GetGuestBaseSize(), uint32_t(16)); } VkWriteDescriptorSet& write_descriptor_set_source_base = write_descriptor_sets[write_descriptor_set_count++]; @@ -1440,8 +1437,10 @@ bool VulkanTextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture, vulkan_shared_memory.buffer(); write_descriptor_set_source_mips_buffer_info.offset = texture_key.mip_page << 12; + // Align (primarily the last row of a linear packed mip tail) because + // shaders use up to 16-byte loads for multiple blocks at once. write_descriptor_set_source_mips_buffer_info.range = - xe::align(vulkan_texture.GetGuestMipsSize(), source_length_alignment); + xe::align(vulkan_texture.GetGuestMipsSize(), uint32_t(16)); VkWriteDescriptorSet& write_descriptor_set_source_mips = write_descriptor_sets[write_descriptor_set_count++]; write_descriptor_set_source_mips.sType = diff --git a/src/xenia/ui/shaders/xesl.xesli b/src/xenia/ui/shaders/xesl.xesli index 06b91cdb6..49a19dda0 100644 --- a/src/xenia/ui/shaders/xesl.xesli +++ b/src/xenia/ui/shaders/xesl.xesli @@ -281,70 +281,70 @@ float4_xe float_x4_xe(float x) { return float4_xe(x, x, x, x); } #endif // SHADING_LANGUAGE_*_XE #ifndef entry_outputs_begin_xe #define entry_outputs_begin_xe -#endif // !entry_outputs_begin_xe +#endif #ifndef entry_out_position_xe #define entry_out_position_xe -#endif // !entry_out_position_xe +#endif #ifndef entry_outputs_end_stage_inputs_begin_xe #define entry_outputs_end_stage_inputs_begin_xe -#endif // !entry_outputs_end_stage_inputs_begin_xe +#endif #ifndef entry_in_stage_vertex_xe #define entry_in_stage_vertex_xe(type, name, index, semantic) \ entry_in_stage_xe(type, name, index, semantic) -#endif // !entry_in_stage_vertex_xe +#endif #ifndef entry_stage_inputs_end_bindings_begin_vertex_xe #define entry_stage_inputs_end_bindings_begin_vertex_xe -#endif // !entry_stage_inputs_end_bindings_begin_vertex_xe +#endif #ifndef entry_stage_inputs_end_bindings_begin_pixel_xe #define entry_stage_inputs_end_bindings_begin_pixel_xe -#endif // !entry_stage_inputs_end_bindings_begin_pixel_xe +#endif #ifndef entry_bindings_begin_compute_xe #define entry_bindings_begin_compute_xe -#endif // !entry_bindings_begin_compute_xe +#endif #ifndef entry_binding_next_xe #define entry_binding_next_xe -#endif // !entry_binding_next_xe +#endif #ifndef entry_bindings_end_inputs_begin_xe #define entry_bindings_end_inputs_begin_xe -#endif // !entry_bindings_end_inputs_begin_xe +#endif #ifndef entry_bindings_empty_end_inputs_begin_xe #define entry_bindings_empty_end_inputs_begin_xe -#endif // !entry_bindings_empty_end_inputs_begin_xe +#endif #ifndef entry_bindings_end_inputs_begin_compute_xe #define entry_bindings_end_inputs_begin_compute_xe -#endif // !entry_bindings_end_inputs_begin_compute_xe +#endif #ifndef entry_input_next_xe #define entry_input_next_xe -#endif // !entry_input_next_xe +#endif #ifndef entry_in_stage_inputs_xe #define entry_in_stage_inputs_xe -#endif // !entry_in_stage_inputs_xe +#endif #ifndef entry_in_vertex_id_xe #define entry_in_vertex_id_xe -#endif // !entry_in_vertex_id_xe +#endif #ifndef entry_in_pixel_coord_xe #define entry_in_pixel_coord_xe -#endif // !entry_in_pixel_coord_xe +#endif #ifndef entry_in_group_id_xe #define entry_in_group_id_xe -#endif // !entry_in_group_id_xe +#endif #ifndef entry_in_local_thread_id_xe #define entry_in_local_thread_id_xe -#endif // !entry_in_local_thread_id_xe +#endif #ifndef entry_in_global_thread_id_xe #define entry_in_global_thread_id_xe -#endif // !entry_in_global_thread_id_xe +#endif #ifndef entry_in_local_thread_index_xe #define entry_in_local_thread_index_xe -#endif // !entry_in_local_thread_index_xe +#endif #ifndef entry_code_end_xe #define entry_code_end_xe \ entry_return_xe \ } -#endif // !entry_code_end_xe +#endif #ifndef entry_code_end_compute_xe #define entry_code_end_compute_xe } -#endif // !entry_code_end_compute_xe +#endif // NDC_DIRECTION_Y_XE, assuming a positive viewport height, is: // * 1.0 if +out_position_xe.y is towards +in_pixel_coord_xe.y, @@ -353,7 +353,7 @@ float4_xe float_x4_xe(float x) { return float4_xe(x, x, x, x); } #define NDC_DIRECTION_Y_XE 1.0f #else #define NDC_DIRECTION_Y_XE -1.0f -#endif // SHADING_LANGUAGE_GLSL_XE +#endif #if SHADING_LANGUAGE_GLSL_XE // GLSL requires just const for declaring a constant in the global scope. @@ -461,140 +461,214 @@ float4_xe float_x4_xe(float x) { return float4_xe(x, x, x, x); } #endif // SHADING_LANGUAGE_*_XE #ifndef const_buffer_binding_xe #define const_buffer_binding_xe(name, msl_buffer) -#endif // !const_buffer_binding_xe +#endif #ifndef push_const_binding_xe #define push_const_binding_xe(msl_buffer) -#endif // !push_const_binding_xe +#endif -// Declarations of typed storage buffers and dword buffers (_declare) must be -// outside the entry point, but their bindings (_binding) must also be specified -// in the entry point binding declarations. +// Byte buffers represent raw data accessible as `uint` vectors, addressed with +// a byte offset with some alignment requirement, and implemented as storage +// buffers on GLSL, byte address buffers on HLSL, and buffer pointers on MSL. // -// An array buffer is a buffer limited to 1/2/4-component vectors of 32-bit -// integers and floats, a typed buffer on Direct3D, but a storage buffer (as -// opposed to a texel buffer, which has a very small minimum requirement for the -// maximum size) on Vulkan. +// These underlying binding types were chosen primarily because of the high +// range limits they offer, as well as the ability for the compiler and the GPU +// to take more optimal access paths as it's known that no type conversion would +// be necessary. // -// A UInt vector buffer is a buffer containing 32-bit values, but loading or -// storing may be done for 2, 3 or 4 consecutive values that are still -// 32-bit-aligned, and depending on the language and hardware support, access -// of multiple elements may or may not be compiled into a single hardware -// instruction instead of separate accesses of individual elements. Each index -// value corresponds to a 32-bit element. Implementations for languages without -// native support must use functions, not macros, for adding the component -// offset to the index to avoid evaluating the address multiple times. +// In Vulkan, the minimum required `maxStorageBufferRange` is 128 MB, while only +// 65536 is required for `maxTexelBufferElements`. +// +// In Direct3D 11 and 12, the range limit for typed buffers is 2^27 elements +// (`REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP`), and according to "Summary of +// Changes in this Chapter from D3D10 to D3D11.3" in the chapter 21 "System +// Limits on Various Resources" in the Direct3D 11.3 Functional Specification, +// this limit also applies to structured buffers. However, the entire resource +// (up to 2 GB - `REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_C_TERM` - in most +// cases) must be accessible via a byte address buffer. +// +// Also, byte address buffers were chosen over structured buffers because 8-byte +// and 16-byte accesses are common, and the same buffer may need to be accessed +// with different granularities, however, in Direct3D 11, one buffer can't be +// accessed with different structure byte strides. +// +// Bounds checking is not guaranteed for byte buffers (may be bound via root +// descriptors on Direct3D 12, and on MSL they're bound as pointers). +// +// For 4-aligned byte buffers, loads larger than the alignment of the buffer are +// supported, with the `u` load expecting the address to be aligned to the +// buffer alignment, and the `a` load expecting it to be aligned to the size of +// the loaded data. +// +// Declarations of byte buffers (`_declare`) must be outside the entry point, +// but their bindings (`_binding`) must also be specified in the entry point +// function signature. This is necessary so byte buffers can be declared and +// used in header files and in functions declared in them, as they're +// implemented as buffer blocks in GLSL. +// +// The `_impl` definitions are for internal use in this file. + #if SHADING_LANGUAGE_GLSL_XE - // Binding declarations. - #define array_buffer_declare_xe(value_type, name, glsl_set, glsl_binding, \ - hlsl_t, hlsl_t_space) \ - layout(std430, glsl_set, glsl_binding) \ - readonly buffer name##_xe_block { \ - value_type data[]; \ + #define byte_buffer_declare_xe_impl(value_type, name, glsl_set, \ + glsl_binding, hlsl_t, hlsl_t_space) \ + layout(std430, glsl_set, glsl_binding) \ + readonly buffer name##_xe_block { \ + value_type data[]; \ } name; - #define array_buffer_wo_declare_xe(value_type, name, glsl_set, glsl_binding, \ - hlsl_u, hlsl_u_space) \ - layout(std430, glsl_set, glsl_binding) \ - writeonly buffer name##_xe_block { \ - value_type data[]; \ + #define byte_buffer_wo_declare_xe_impl(value_type, name, glsl_set, \ + glsl_binding, hlsl_t, hlsl_t_space) \ + layout(std430, glsl_set, glsl_binding) \ + writeonly buffer name##_xe_block { \ + value_type data[]; \ } name; - #define uint_vector_buffer_declare_xe(name, glsl_set, glsl_binding, hlsl_t, \ - hlsl_t_space) \ - layout(std430, glsl_set, glsl_binding) \ - readonly buffer name##_xe_block { \ - uint data[]; \ - } name; \ - uint2_xe name##_xe_load2(uint position) { \ - return uint2_xe(name.data[position], name.data[position + 1u]); \ - } \ - uint3_xe name##_xe_load3(uint position) { \ - return uint3_xe(name.data[position], name.data[position + 1u], \ - name.data[position + 2u]); \ - } \ - uint4_xe name##_xe_load4(uint position) { \ - return uint4_xe(name.data[position], name.data[position + 1u], \ - name.data[position + 2u], name.data[position + 3u]); \ - } - // Loading and storing. - #define array_buffer_load_xe(name, position) ((name).data[uint(position)]) - #define array_buffer_store_xe(name, position, value) \ - ((name).data[uint(position)] = (value)) - #define uint_vector_buffer_load1_xe(name, position) \ - ((name).data[uint(position)]) - #define uint_vector_buffer_load2_xe(name, position) \ - name##_xe_load2(uint(position)) - #define uint_vector_buffer_load3_xe(name, position) \ - name##_xe_load3(uint(position)) - #define uint_vector_buffer_load4_xe(name, position) \ - name##_xe_load4(uint(position)) + + #define byte_buffer_align4_load4_xe(name, byte_address) \ + ((name).data[uint(byte_address) >> 2]) + #define byte_buffer_align4_load8u_xe(name, byte_address) \ + uint2_xe((name).data[uint(byte_address) >> 2], \ + (name).data[(uint(byte_address) >> 2) + 1u]) + #define byte_buffer_align4_load16u_xe(name, byte_address) \ + uint4_xe((name).data[uint(byte_address) >> 2], \ + (name).data[(uint(byte_address) >> 2) + 1u], \ + (name).data[(uint(byte_address) >> 2) + 2u], \ + (name).data[(uint(byte_address) >> 2) + 3u]) + + #define byte_buffer_align8_load8_xe(name, byte_address) \ + ((name).data[uint(byte_address) >> 3]) + + #define byte_buffer_align16_load16_xe(name, byte_address) \ + ((name).data[uint(byte_address) >> 4]) + + #define byte_buffer_align4_store4_xe(name, byte_address, value) \ + ((name).data[uint(byte_address) >> 2] = (value)) + #define byte_buffer_align8_store8_xe(name, byte_address, value) \ + ((name).data[uint(byte_address) >> 3] = (value)) + #define byte_buffer_align16_store16_xe(name, byte_address, value) \ + ((name).data[uint(byte_address) >> 4] = (value)) + #elif SHADING_LANGUAGE_HLSL_XE - // Binding declarations. - #define array_buffer_declare_xe(value_type, name, glsl_set, glsl_binding, \ - hlsl_t, hlsl_t_space) \ - Buffer name : register(hlsl_t, hlsl_t_space); - #define array_buffer_wo_declare_xe(value_type, name, glsl_set, glsl_binding, \ - hlsl_u, hlsl_u_space) \ - RWBuffer name : register(hlsl_u, hlsl_u_space); - #define uint_vector_buffer_declare_xe(name, glsl_set, glsl_binding, hlsl_t, \ - hlsl_t_space) \ + #define byte_buffer_declare_xe_impl(value_type, name, glsl_set, \ + glsl_binding, hlsl_t, hlsl_t_space) \ ByteAddressBuffer name : register(hlsl_t, hlsl_t_space); - // Loading and storing. - #define array_buffer_load_xe(name, position) ((name)[uint(position)]) - #define array_buffer_store_xe(name, position, value) \ - ((name)[uint(position)] = (value)) - #define uint_vector_buffer_load1_xe(name, position) \ - ((name).Load(int(position) << 2)) - #define uint_vector_buffer_load2_xe(name, position) \ - ((name).Load2(int(position) << 2)) - #define uint_vector_buffer_load3_xe(name, position) \ - ((name).Load3(int(position) << 2)) - #define uint_vector_buffer_load4_xe(name, position) \ - ((name).Load4(int(position) << 2)) + #define byte_buffer_wo_declare_xe_impl(value_type, name, glsl_set, \ + glsl_binding, hlsl_t, hlsl_t_space) \ + RWByteAddressBuffer name : register(hlsl_t, hlsl_t_space); + + #define byte_buffer_align4_load4_xe(name, byte_address) \ + ((name).Load(uint(byte_address))) + #define byte_buffer_align4_load8u_xe(name, byte_address) \ + ((name).Load2(uint(byte_address))) + #define byte_buffer_align4_load16u_xe(name, byte_address) \ + ((name).Load4(uint(byte_address))) + + #define byte_buffer_align8_load8_xe(name, byte_address) \ + ((name).Load2(uint(byte_address))) + + #define byte_buffer_align16_load16_xe(name, byte_address) \ + ((name).Load4(uint(byte_address))) + + #define byte_buffer_align4_store4_xe(name, byte_address, value) \ + ((name).Store(uint(byte_address), value)) + #define byte_buffer_align8_store8_xe(name, byte_address, value) \ + ((name).Store2(uint(byte_address), value)) + #define byte_buffer_align16_store16_xe(name, byte_address, value) \ + ((name).Store4(uint(byte_address), value)) + #elif SHADING_LANGUAGE_MSL_XE - // Binding declarations. - #define array_buffer_binding_xe(value_type, name, msl_buffer) \ - const device value_type* name [[msl_buffer]] - #define array_buffer_wo_binding_xe(value_type, name, msl_buffer) \ - device value_type* name [[msl_buffer]] - #define uint_vector_buffer_binding_xe(name, msl_buffer) \ - const device uint* name [[msl_buffer]] - // Loading and storing. - #define array_buffer_load_xe(name, position) ((name)[size_t(position)]) - #define array_buffer_store_xe(name, position, value) \ - ((name)[size_t(position)] = (value)) - #define uint_vector_buffer_load1_xe(name, position) ((name)[size_t(position)]) - #define uint_vector_buffer_load2_xe(name, position) \ + #define byte_buffer_binding_xe(name, msl_buffer) \ + const device char* name [[msl_buffer]] + #define byte_buffer_wo_binding_xe(name, msl_buffer) \ + device char* name [[msl_buffer]] + + #define byte_buffer_align4_load4_xe(name, byte_address) \ + (*reinterpret_cast(&(name)[(byte_address)])) + #define byte_buffer_align4_load8u_xe(name, byte_address) \ uint2_xe(*reinterpret_cast( \ - &((name)[size_t(position)]))) - #define uint_vector_buffer_load3_xe(name, position) \ - uint3_xe(*reinterpret_cast( \ - &((name)[size_t(position)]))) - #define uint_vector_buffer_load4_xe(name, position) \ + &(name)[(byte_address)])) + #define byte_buffer_align4_load8a_xe(name, byte_address) \ + (*reinterpret_cast(&(name)[(byte_address)])) + #define byte_buffer_align4_load16u_xe(name, byte_address) \ uint4_xe(*reinterpret_cast( \ - &((name)[size_t(position)]))) + &(name)[(byte_address)])) + #define byte_buffer_align4_load16a_xe(name, byte_address) \ + (*reinterpret_cast(&(name)[(byte_address)])) + + #define byte_buffer_align8_load8_xe(name, byte_address) \ + (*reinterpret_cast(&(name)[(byte_address)])) + + #define byte_buffer_align16_load16_xe(name, byte_address) \ + (*reinterpret_cast(&(name)[(byte_address)])) + + #define byte_buffer_align4_store4_xe(name, byte_address, value) \ + (*reinterpret_cast(&(name)[(byte_address)]) = (value)) + #define byte_buffer_align8_store8_xe(name, byte_address, value) \ + (*reinterpret_cast(&(name)[(byte_address)]) = (value)) + #define byte_buffer_align16_store16_xe(name, byte_address, value) \ + (*reinterpret_cast(&(name)[(byte_address)]) = (value)) + #else - #error Storage buffers not defined for the target language. + #error Byte buffers not defined for the target language. #endif // SHADING_LANGUAGE_*_XE -#ifndef array_buffer_declare_xe - #define array_buffer_declare_xe(value_type, name, glsl_set, glsl_binding, \ + +#ifndef byte_buffer_declare_xe_impl + #define byte_buffer_declare_xe_impl(value_type, name, glsl_set, \ + glsl_binding, hlsl_t, hlsl_t_space) +#endif +#ifndef byte_buffer_binding_xe + #define byte_buffer_binding_xe(name, msl_buffer) +#endif +#ifndef byte_buffer_wo_declare_xe_impl + #define byte_buffer_wo_declare_xe_impl(value_type, name, glsl_set, \ + glsl_binding, hlsl_t, hlsl_t_space) +#endif +#ifndef byte_buffer_wo_binding_xe + #define byte_buffer_wo_binding_xe(name, msl_buffer) +#endif + +#ifndef byte_buffer_align4_declare_xe + #define byte_buffer_align4_declare_xe(name, glsl_set, glsl_binding, hlsl_t, \ + hlsl_t_space) \ + byte_buffer_declare_xe_impl(uint, name, glsl_set, glsl_binding, hlsl_t, \ + hlsl_t_space) +#endif +#ifndef byte_buffer_align4_wo_declare_xe + #define byte_buffer_align4_wo_declare_xe(name, glsl_set, glsl_binding, \ + hlsl_t, hlsl_t_space) \ + byte_buffer_wo_declare_xe_impl(uint, name, glsl_set, glsl_binding, \ + hlsl_t, hlsl_t_space) +#endif + +#ifndef byte_buffer_align8_declare_xe + #define byte_buffer_align8_declare_xe(name, glsl_set, glsl_binding, hlsl_t, \ + hlsl_t_space) \ + byte_buffer_declare_xe_impl(uint2_xe, name, glsl_set, glsl_binding, \ hlsl_t, hlsl_t_space) -#endif // !array_buffer_declare_xe -#ifndef array_buffer_wo_declare_xe - #define array_buffer_wo_declare_xe(value_type, name, glsl_set, glsl_binding, \ - hlsl_u, hlsl_u_space) -#endif // !array_buffer_wo_declare_xe -#ifndef array_buffer_binding_xe - #define array_buffer_binding_xe(value_type, name, msl_buffer) -#endif // !array_buffer_binding_xe -#ifndef array_buffer_wo_binding_xe - #define array_buffer_wo_binding_xe(value_type, name, msl_buffer) -#endif // !array_buffer_wo_binding_xe -#ifndef uint_vector_buffer_declare_xe - #define uint_vector_buffer_declare_xe(name, glsl_set, glsl_binding, hlsl_t, \ - hlsl_t_space) -#endif // !uint_vector_buffer_declare_xe -#ifndef uint_vector_buffer_binding_xe - #define uint_vector_buffer_binding_xe(name, msl_buffer) -#endif // !uint_vector_buffer_binding_xe +#endif +#ifndef byte_buffer_align8_wo_declare_xe + #define byte_buffer_align8_wo_declare_xe(name, glsl_set, glsl_binding, \ + hlsl_t, hlsl_t_space) \ + byte_buffer_wo_declare_xe_impl(uint2_xe, name, glsl_set, glsl_binding, \ + hlsl_t, hlsl_t_space) +#endif + +#ifndef byte_buffer_align16_declare_xe + #define byte_buffer_align16_declare_xe(name, glsl_set, glsl_binding, hlsl_t, \ + hlsl_t_space) \ + byte_buffer_declare_xe_impl(uint4_xe, name, glsl_set, glsl_binding, \ + hlsl_t, hlsl_t_space) +#endif +#ifndef byte_buffer_align16_wo_declare_xe + #define byte_buffer_align16_wo_declare_xe(name, glsl_set, glsl_binding, \ + hlsl_t, hlsl_t_space) \ + byte_buffer_wo_declare_xe_impl(uint4_xe, name, glsl_set, glsl_binding, \ + hlsl_t, hlsl_t_space) +#endif + +#ifndef byte_buffer_align4_load8a_xe + #define byte_buffer_align4_load8a_xe byte_buffer_align4_load8u_xe +#endif +#ifndef byte_buffer_align4_load16a_xe + #define byte_buffer_align4_load16a_xe byte_buffer_align4_load16u_xe +#endif // Buffer, texture, sampler and image bindings must be in the entry point // bindings declaration. @@ -741,7 +815,7 @@ float4_xe float_x4_xe(float x) { return float4_xe(x, x, x, x); } #if !COMBINED_TEXTURE_SAMPLER_XE #ifndef sampler_2d_xe #define sampler_2d_xe texture_2d_xe - #endif // !sampler_2d_xe + #endif #ifndef sampler_xe #define sampler_xe(sampler_type, name, glsl_set, glsl_binding, hlsl_t, \ hlsl_t_space, hlsl_s, hlsl_s_space, msl_texture, \ @@ -751,32 +825,32 @@ float4_xe float_x4_xe(float x) { return float4_xe(x, x, x, x); } entry_binding_next_xe \ sampler_state_xe(name##_xe_sampler, glsl_set, glsl_binding, hlsl_s, \ hlsl_s_space, msl_sampler) - #endif // !sampler_xe + #endif #ifndef sample_comb_lod_2d_xe #define sample_comb_lod_2d_xe(texture_sampler_name, position, lod) \ sample_sep_lod_2d_xe(texture_sampler_name, \ texture_sampler_name##_xe_sampler, position, lod) - #endif // !sample_comb_lod_2d_xe + #endif #ifndef gather_comb_2d_r_xe #define gather_comb_2d_r_xe(texture_sampler_name, position) \ gather_sep_2d_r_xe(texture_sampler_name, \ texture_sampler_name##_xe_sampler, position) - #endif // !gather_comb_2d_r_xe + #endif #ifndef gather_comb_2d_g_xe #define gather_comb_2d_g_xe(texture_sampler_name, position) \ gather_sep_2d_g_xe(texture_sampler_name, \ texture_sampler_name##_xe_sampler, position) - #endif // !gather_comb_2d_g_xe + #endif #ifndef gather_comb_2d_b_xe #define gather_comb_2d_b_xe(texture_sampler_name, position) \ gather_sep_2d_b_xe(texture_sampler_name, \ texture_sampler_name##_xe_sampler, position) - #endif // !gather_comb_2d_b_xe + #endif #ifndef gather_comb_2d_a_xe #define gather_comb_2d_a_xe(texture_sampler_name, position) \ gather_sep_2d_a_xe(texture_sampler_name, \ texture_sampler_name##_xe_sampler, position) - #endif // !gather_comb_2d_a_xe + #endif #endif // !COMBINED_TEXTURE_SAMPLER_XE // Passing bindings to functions, and also output and input / output parameters. @@ -795,55 +869,59 @@ float4_xe float_x4_xe(float x) { return float4_xe(x, x, x, x); } #define param_next_after_const_buffer_xe , #define param_push_consts_xe constant push_const_struct_xe& push_consts_xe #define param_next_after_push_consts_xe , - #define param_uint_vector_buffer_xe(name) const device uint* name - #define param_next_after_uint_vector_buffer_xe , + #define param_byte_buffer_xe(name) const device char* name + #define param_byte_buffer_wo_xe(name) device char* name + #define param_next_after_byte_buffer_xe , // Call arguments. #define pass_const_buffer_xe(name) (name) #define pass_next_after_const_buffer_xe , #define pass_push_consts_xe push_consts_xe #define pass_next_after_push_consts_xe , - #define pass_uint_vector_buffer_xe(name) (name) - #define pass_next_after_uint_vector_buffer_xe , + #define pass_byte_buffer_xe(name) (name) + #define pass_next_after_byte_buffer_xe , #endif // SHADING_LANGUAGE_*_XE // Prototype parameters. #ifndef param_const_buffer_xe #define param_const_buffer_xe(name) -#endif // !param_const_buffer_xe +#endif #ifndef param_next_after_const_buffer_xe #define param_next_after_const_buffer_xe -#endif // !param_next_after_const_buffer_xe +#endif #ifndef param_push_consts_xe #define param_push_consts_xe -#endif // !param_push_consts_xe +#endif #ifndef param_next_after_push_consts_xe #define param_next_after_push_consts_xe -#endif // !param_next_after_push_consts_xe -#ifndef param_uint_vector_buffer_xe - #define param_uint_vector_buffer_xe(name) -#endif // !param_uint_vector_buffer_xe -#ifndef param_next_after_uint_vector_buffer_xe - #define param_next_after_uint_vector_buffer_xe -#endif // !param_next_after_uint_vector_buffer_xe +#endif +#ifndef param_byte_buffer_xe + #define param_byte_buffer_xe(name) +#endif +#ifndef param_byte_buffer_wo_xe + #define param_byte_buffer_wo_xe(name) +#endif +#ifndef param_next_after_byte_buffer_xe + #define param_next_after_byte_buffer_xe +#endif // Call arguments. #ifndef pass_const_buffer_xe #define pass_const_buffer_xe(name) -#endif // !pass_const_buffer_xe +#endif #ifndef pass_next_after_const_buffer_xe #define pass_next_after_const_buffer_xe -#endif // !pass_next_after_const_buffer_xe +#endif #ifndef pass_push_consts_xe #define pass_push_consts_xe -#endif // !pass_push_consts_xe +#endif #ifndef pass_next_after_push_consts_xe #define pass_next_after_push_consts_xe -#endif // !pass_next_after_push_consts_xe -#ifndef pass_uint_vector_buffer_xe - #define pass_uint_vector_buffer_xe(name) -#endif // !pass_uint_vector_buffer_xe -#ifndef pass_next_after_uint_vector_buffer_xe - #define pass_next_after_uint_vector_buffer_xe -#endif // !pass_next_after_uint_vector_buffer_xe +#endif +#ifndef pass_byte_buffer_xe + #define pass_byte_buffer_xe(name) +#endif +#ifndef pass_next_after_byte_buffer_xe + #define pass_next_after_byte_buffer_xe +#endif // Attributes. @@ -860,16 +938,16 @@ float4_xe float_x4_xe(float x) { return float4_xe(x, x, x, x); } #endif // SHADING_LANGUAGE_*_XE #ifndef unroll_xe #define unroll_xe -#endif // !unroll_xe +#endif #ifndef dont_unroll #define dont_unroll -#endif // !dont_unroll +#endif #ifndef flatten_xe #define flatten_xe -#endif // !flatten_xe +#endif #ifndef dont_flatten_xe #define dont_flatten_xe -#endif // !dont_flatten_xe +#endif // Function aliases.