diff --git a/src/xenia/gpu/d3d12/d3d12_texture_cache.cc b/src/xenia/gpu/d3d12/d3d12_texture_cache.cc index 74682680c..68932ef08 100644 --- a/src/xenia/gpu/d3d12/d3d12_texture_cache.cc +++ b/src/xenia/gpu/d3d12/d3d12_texture_cache.cc @@ -1442,19 +1442,30 @@ D3D12TextureCache::D3D12Texture::~D3D12Texture() { } bool D3D12TextureCache::IsDecompressionNeeded(xenos::TextureFormat format, - uint32_t width, uint32_t height) { + uint32_t width, + uint32_t height) const { DXGI_FORMAT dxgi_format_uncompressed = host_formats_[uint32_t(format)].dxgi_format_uncompressed; if (dxgi_format_uncompressed == DXGI_FORMAT_UNKNOWN) { return false; } const FormatInfo* format_info = FormatInfo::Get(format); - return (width & (format_info->block_width - 1)) != 0 || - (height & (format_info->block_height - 1)) != 0; + if (!(width & (format_info->block_width - 1)) && + !(height & (format_info->block_height - 1))) { + return false; + } + // UnalignedBlockTexturesSupported is for block-compressed textures with the + // block size of 4x4, but not for 2x1 (4:2:2) subsampled formats. + if (format_info->block_width == 4 && format_info->block_height == 4 && + command_processor_.GetD3D12Provider() + .AreUnalignedBlockTexturesSupported()) { + return false; + } + return true; } TextureCache::LoadShaderIndex D3D12TextureCache::GetLoadShaderIndex( - TextureKey key) { + TextureKey key) const { const HostFormat& host_format = host_formats_[uint32_t(key.format)]; if (key.signed_separate) { return host_format.load_shader_signed; diff --git a/src/xenia/gpu/d3d12/d3d12_texture_cache.h b/src/xenia/gpu/d3d12/d3d12_texture_cache.h index cf51ca905..d2b6cdb1b 100644 --- a/src/xenia/gpu/d3d12/d3d12_texture_cache.h +++ b/src/xenia/gpu/d3d12/d3d12_texture_cache.h @@ -361,30 +361,30 @@ class D3D12TextureCache final : public TextureCache { // Whether decompression is needed on the host (Direct3D only allows creation // of block-compressed textures with 4x4-aligned dimensions on PC). - static bool IsDecompressionNeeded(xenos::TextureFormat format, uint32_t width, - uint32_t height); - static DXGI_FORMAT GetDXGIResourceFormat(xenos::TextureFormat format, - uint32_t width, uint32_t height) { + bool IsDecompressionNeeded(xenos::TextureFormat format, uint32_t width, + uint32_t height) const; + DXGI_FORMAT GetDXGIResourceFormat(xenos::TextureFormat format, uint32_t width, + uint32_t height) const { const HostFormat& host_format = host_formats_[uint32_t(format)]; return IsDecompressionNeeded(format, width, height) ? host_format.dxgi_format_uncompressed : host_format.dxgi_format_resource; } - static DXGI_FORMAT GetDXGIResourceFormat(TextureKey key) { + DXGI_FORMAT GetDXGIResourceFormat(TextureKey key) const { return GetDXGIResourceFormat(key.format, key.GetWidth(), key.GetHeight()); } - static DXGI_FORMAT GetDXGIUnormFormat(xenos::TextureFormat format, - uint32_t width, uint32_t height) { + DXGI_FORMAT GetDXGIUnormFormat(xenos::TextureFormat format, uint32_t width, + uint32_t height) const { const HostFormat& host_format = host_formats_[uint32_t(format)]; return IsDecompressionNeeded(format, width, height) ? host_format.dxgi_format_uncompressed : host_format.dxgi_format_unsigned; } - static DXGI_FORMAT GetDXGIUnormFormat(TextureKey key) { + DXGI_FORMAT GetDXGIUnormFormat(TextureKey key) const { return GetDXGIUnormFormat(key.format, key.GetWidth(), key.GetHeight()); } - static LoadShaderIndex GetLoadShaderIndex(TextureKey key); + LoadShaderIndex GetLoadShaderIndex(TextureKey key) const; static constexpr bool AreDimensionsCompatible( xenos::FetchOpDimension binding_dimension, diff --git a/src/xenia/ui/d3d12/d3d12_provider.cc b/src/xenia/ui/d3d12/d3d12_provider.cc index 3c3825091..287b64cb8 100644 --- a/src/xenia/ui/d3d12/d3d12_provider.cc +++ b/src/xenia/ui/d3d12/d3d12_provider.cc @@ -422,6 +422,7 @@ bool D3D12Provider::Initialize() { rasterizer_ordered_views_supported_ = false; resource_binding_tier_ = D3D12_RESOURCE_BINDING_TIER_1; tiled_resources_tier_ = D3D12_TILED_RESOURCES_TIER_NOT_SUPPORTED; + unaligned_block_textures_supported_ = false; D3D12_FEATURE_DATA_D3D12_OPTIONS options; if (SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options)))) { @@ -439,6 +440,12 @@ bool D3D12Provider::Initialize() { programmable_sample_positions_tier_ = options2.ProgrammableSamplePositionsTier; } + D3D12_FEATURE_DATA_D3D12_OPTIONS8 options8; + if (SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS8, + &options8, sizeof(options8)))) { + unaligned_block_textures_supported_ = + bool(options8.UnalignedBlockTexturesSupported); + } virtual_address_bits_per_resource_ = 0; D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT virtual_address_support; if (SUCCEEDED(device->CheckFeatureSupport( @@ -455,14 +462,16 @@ bool D3D12Provider::Initialize() { "* Programmable sample positions: tier {}\n" "* Rasterizer-ordered views: {}\n" "* Resource binding: tier {}\n" - "* Tiled resources: tier {}\n", + "* Tiled resources: tier {}\n" + "* Unaligned block-compressed textures: {}", virtual_address_bits_per_resource_, (heap_flag_create_not_zeroed_ & D3D12_HEAP_FLAG_CREATE_NOT_ZEROED) ? "yes" : "no", ps_specified_stencil_reference_supported_ ? "yes" : "no", uint32_t(programmable_sample_positions_tier_), rasterizer_ordered_views_supported_ ? "yes" : "no", - uint32_t(resource_binding_tier_), uint32_t(tiled_resources_tier_)); + uint32_t(resource_binding_tier_), uint32_t(tiled_resources_tier_), + unaligned_block_textures_supported_ ? "yes" : "no"); // Get the graphics analysis interface, will silently fail if PIX is not // attached. diff --git a/src/xenia/ui/d3d12/d3d12_provider.h b/src/xenia/ui/d3d12/d3d12_provider.h index 937acaae9..36164eaba 100644 --- a/src/xenia/ui/d3d12/d3d12_provider.h +++ b/src/xenia/ui/d3d12/d3d12_provider.h @@ -108,6 +108,9 @@ class D3D12Provider : public GraphicsProvider { D3D12_TILED_RESOURCES_TIER GetTiledResourcesTier() const { return tiled_resources_tier_; } + bool AreUnalignedBlockTexturesSupported() const { + return unaligned_block_textures_supported_; + } uint32_t GetVirtualAddressBitsPerResource() const { return virtual_address_bits_per_resource_; } @@ -184,11 +187,12 @@ class D3D12Provider : public GraphicsProvider { D3D12_HEAP_FLAGS heap_flag_create_not_zeroed_; D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER programmable_sample_positions_tier_; - bool ps_specified_stencil_reference_supported_; - bool rasterizer_ordered_views_supported_; D3D12_RESOURCE_BINDING_TIER resource_binding_tier_; D3D12_TILED_RESOURCES_TIER tiled_resources_tier_; uint32_t virtual_address_bits_per_resource_; + bool ps_specified_stencil_reference_supported_; + bool rasterizer_ordered_views_supported_; + bool unaligned_block_textures_supported_; }; } // namespace d3d12