From 125287dc30cb745891f4cdbba761deac70b26def Mon Sep 17 00:00:00 2001 From: nmzik Date: Mon, 27 Jul 2026 10:29:37 +0200 Subject: [PATCH] graphics: broaden depth compatibility --- .../host_gpu/renderer/descriptors.cpp | 28 +++++++++---- src/graphics/host_gpu/renderer/descriptors.h | 3 +- tests/ShaderRecompilerComputeTests.cpp | 39 ++++++++++++++++++- 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/graphics/host_gpu/renderer/descriptors.cpp b/src/graphics/host_gpu/renderer/descriptors.cpp index 8bb4a0cdf..99c61d139 100644 --- a/src/graphics/host_gpu/renderer/descriptors.cpp +++ b/src/graphics/host_gpu/renderer/descriptors.cpp @@ -229,7 +229,7 @@ bool IsSupportedDepthTargetDescriptor(const ShaderTextureResource& descriptor, c pitch == image.info.pitch; } -bool IsSupportedDepthTextureEncoding(const ShaderTextureResource& descriptor) { +bool IsSupportedDepthTextureEncoding(const ShaderTextureResource& descriptor, const Image& image) { constexpr uint32_t field1_reserved_mask = 0x200fff00u; constexpr uint32_t field2_reserved_mask = 0xf0003000u; constexpr uint32_t field3_common = 0x01800000u; @@ -237,11 +237,24 @@ bool IsSupportedDepthTextureEncoding(const ShaderTextureResource& descriptor) { const uint32_t field3_expected = (descriptor.Type() << 28u) | field3_common | descriptor.DstSelXYZW(); const uint32_t field4_expected = descriptor.Depth() | (descriptor.BaseArray5() << 16u); - return (descriptor.fields[1] & field1_reserved_mask) == 0 && - (descriptor.fields[2] & field2_reserved_mask) == 0 && - descriptor.fields[3] == field3_expected && descriptor.fields[4] == field4_expected && - descriptor.fields[5] == field5_expected && descriptor.fields[6] == 0 && - descriptor.fields[7] == 0; + const bool common = (descriptor.fields[1] & field1_reserved_mask) == 0 && + (descriptor.fields[2] & field2_reserved_mask) == 0 && + descriptor.fields[3] == field3_expected && + descriptor.fields[4] == field4_expected && + descriptor.fields[5] == field5_expected; + if (!common || (descriptor.fields[6] == 0 && descriptor.fields[7] != 0)) { + return false; + } + if (descriptor.fields[6] == 0) { + return true; + } + constexpr uint32_t htile_control = 0x00280000u; + const auto metadata_addr = descriptor.MetaAddr() << 8u; + return (descriptor.fields[6] & 0x00ffffffu) == htile_control && metadata_addr != 0 && + descriptor.TileMode() == Prospero::GpuEnumValue(Prospero::TileMode::kDepth) && + image.info.tile_mode == Prospero::GpuEnumValue(Prospero::TileMode::kDepth) && + image.info.metadata.kind == ImageMetadataKind::Htile && + image.info.metadata.range.Valid() && image.info.metadata.range.address == metadata_addr; } static void ValidateDepthTargetBinding(const ShaderRecompiler::IR::ImageResource& resource, @@ -250,7 +263,8 @@ static void ValidateDepthTargetBinding(const ShaderRecompiler::IR::ImageResource const bool resource_ok = IsSupportedSampledDepthResource(resource); const bool descriptor_ok = image != nullptr && IsSupportedDepthTargetDescriptor(descriptor, *image); - const bool encoding_ok = IsSupportedDepthTextureEncoding(descriptor); + const bool encoding_ok = + image != nullptr && IsSupportedDepthTextureEncoding(descriptor, *image); const bool format_ok = image != nullptr && IsSupportedSampledDepthFormat(image->info.pixel_format, descriptor.Format(), view_format); diff --git a/src/graphics/host_gpu/renderer/descriptors.h b/src/graphics/host_gpu/renderer/descriptors.h index 77dc29028..722c34911 100644 --- a/src/graphics/host_gpu/renderer/descriptors.h +++ b/src/graphics/host_gpu/renderer/descriptors.h @@ -35,7 +35,8 @@ ResolveTargetTextureView(const ShaderRecompiler::IR::ImageResource& resource, [[nodiscard]] bool IsSupportedDepthTargetDescriptor(const ShaderTextureResource& descriptor, const Image& image); -[[nodiscard]] bool IsSupportedDepthTextureEncoding(const ShaderTextureResource& descriptor); +[[nodiscard]] bool IsSupportedDepthTextureEncoding(const ShaderTextureResource& descriptor, + const Image& image); [[nodiscard]] bool IsSupportedSampledVideoOutView(const ShaderRecompiler::IR::ImageResource& resource, const ShaderTextureResource& descriptor, const Image& image); diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index 02a9f6904..a00beedb7 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -15596,11 +15596,46 @@ void CheckSampledDepthDescriptor(RenderContext &renderer) { cube_image.info.resources.layers); Require("SampledDepthDescriptor", "normalized depth cube", IsSupportedDepthTargetDescriptor(cube_descriptor, cube_image) && - IsSupportedDepthTextureEncoding(cube_descriptor) && + IsSupportedDepthTextureEncoding(cube_descriptor, cube_image) && cube_view.type == vk::ImageViewType::e2DArray && cube_view.layer_count == 6, "normalized depth cube did not preserve its six-face view"); + constexpr uint64_t captured_htile_address = 0x106d48000ull; + const ShaderTextureResource compressed_descriptor{{ + 0x0104d500u, 0xc1600000u, 0x021bc3bfu, 0x91800924u, + 0x00000000u, 0x00700000u, 0x80280000u, 0x000106d4u, + }}; + image.info.metadata.range = {captured_htile_address, 0x1000}; + image.info.metadata.kind = ImageMetadataKind::Htile; + auto mismatched_metadata = compressed_descriptor; + mismatched_metadata.fields[7] ^= 1u; + auto mismatched_metadata_low = compressed_descriptor; + mismatched_metadata_low.fields[6] ^= 1u << 24u; + auto dcc_only_control = compressed_descriptor; + dcc_only_control.fields[6] |= 1u << 22u; + const bool accepts_compressed = + IsSupportedDepthTextureEncoding(compressed_descriptor, image); + image.info.metadata.kind = ImageMetadataKind::Dcc; + const bool rejects_dcc = !IsSupportedDepthTextureEncoding(compressed_descriptor, image); + image.info.metadata.kind = ImageMetadataKind::None; + const bool rejects_none = !IsSupportedDepthTextureEncoding(compressed_descriptor, image); + image.info.metadata.kind = ImageMetadataKind::Htile; + image.info.metadata.range.size = 0; + const bool rejects_empty = !IsSupportedDepthTextureEncoding(compressed_descriptor, image); + image.info.metadata.range.size = TRACKER_ADDRESS_SIZE - captured_htile_address + 1u; + const bool rejects_overflow = !IsSupportedDepthTextureEncoding(compressed_descriptor, image); + image.info.metadata.range.size = 0x1000; + Require("SampledDepthDescriptor", "compressed HTILE descriptor", + accepts_compressed && + !IsSupportedDepthTextureEncoding(mismatched_metadata, image) && + !IsSupportedDepthTextureEncoding(mismatched_metadata_low, image) && + !IsSupportedDepthTextureEncoding(dcc_only_control, image), + "compressed sampled depth did not require its exact tracked HTILE"); + Require("SampledDepthDescriptor", "tracked HTILE state", + rejects_dcc && rejects_none && rejects_empty && rejects_overflow, + "compressed sampled depth accepted invalid tracked metadata"); + auto partial_cube = cube_descriptor; partial_cube.fields[4] = 4; auto based_cube = cube_descriptor; @@ -15618,7 +15653,7 @@ void CheckSampledDepthDescriptor(RenderContext &renderer) { rejects_pitch && !IsSupportedDepthTargetDescriptor(partial_cube, cube_image) && !IsSupportedDepthTargetDescriptor(based_cube, cube_image) && - !IsSupportedDepthTextureEncoding(reserved_cube) && + !IsSupportedDepthTextureEncoding(reserved_cube, cube_image) && !IsSupportedDepthTargetDescriptor(non_square_cube, cube_image), "normalized depth descriptor accepted an incompatible image view"); std::printf("[host] %-32s ok\n", "SampledDepthDescriptor");