broad depth guards

This commit is contained in:
nmzik
2026-07-18 03:52:30 +02:00
parent aa99796d8a
commit df385a7aad
4 changed files with 57 additions and 15 deletions
+19 -11
View File
@@ -299,13 +299,7 @@ static bool IsSupportedSampledColorResource(const ShaderRecompiler::IR::ImageRes
!resource.written && !resource.atomic && !resource.depth_compare; !resource.written && !resource.atomic && !resource.depth_compare;
} }
struct TargetTextureViewInfo { TargetTextureViewInfo
VkImageViewType type = VK_IMAGE_VIEW_TYPE_MAX_ENUM;
uint32_t base_layer = 0;
uint32_t layer_count = 0;
};
static TargetTextureViewInfo
ResolveTargetTextureView(const ShaderRecompiler::IR::ImageResource& resource, ResolveTargetTextureView(const ShaderRecompiler::IR::ImageResource& resource,
Prospero::ImageType type, uint32_t base_layer, uint32_t image_layers) { Prospero::ImageType type, uint32_t base_layer, uint32_t image_layers) {
switch (type) { switch (type) {
@@ -343,12 +337,15 @@ bool IsSupportedDepthTargetDescriptor(const ShaderTextureResource& descriptor,
const auto width = static_cast<uint32_t>(descriptor.Width5()) + 1u; const auto width = static_cast<uint32_t>(descriptor.Width5()) + 1u;
const auto height = static_cast<uint32_t>(descriptor.Height5()) + 1u; const auto height = static_cast<uint32_t>(descriptor.Height5()) + 1u;
const auto pitch = TileGetTexturePitch(descriptor.Format(), width, 1, descriptor.TileMode()); const auto pitch = TileGetTexturePitch(descriptor.Format(), width, 1, descriptor.TileMode());
const auto type = static_cast<Prospero::ImageType>(descriptor.Type());
const bool supported_type = type == Prospero::ImageType::kColor2D ||
type == Prospero::ImageType::kColor2DArray;
return image.type == VulkanImageType::DepthStencil && image.layers == 1 && return image.type == VulkanImageType::DepthStencil && image.layers == 1 &&
width == image.extent.width && height == image.extent.height && width == image.extent.width && height == image.extent.height &&
descriptor.Depth() == 0 && descriptor.BaseLevel() == 0 && descriptor.LastLevel() == 0 && descriptor.Depth() == 0 && descriptor.BaseLevel() == 0 && descriptor.LastLevel() == 0 &&
descriptor.MaxMip() == 0 && descriptor.MinLod() == 0 && descriptor.BaseArray5() == 0 && descriptor.MaxMip() == 0 && descriptor.MinLod() == 0 && descriptor.BaseArray5() == 0 &&
descriptor.TileMode() == Prospero::GpuEnumValue(Prospero::TileMode::kDepth) && descriptor.TileMode() == Prospero::GpuEnumValue(Prospero::TileMode::kDepth) &&
descriptor.Type() == Prospero::GpuEnumValue(Prospero::ImageType::kColor2D) && supported_type &&
descriptor.BCSwizzle() == 0 && !descriptor.MsaaDepth() && pitch >= width && descriptor.BCSwizzle() == 0 && !descriptor.MsaaDepth() && pitch >= width &&
pitch == image.guest_pitch; pitch == image.guest_pitch;
} }
@@ -356,11 +353,13 @@ bool IsSupportedDepthTargetDescriptor(const ShaderTextureResource& descriptor,
static bool IsSupportedDepthTextureEncoding(const ShaderTextureResource& descriptor) { static bool IsSupportedDepthTextureEncoding(const ShaderTextureResource& descriptor) {
constexpr uint32_t field1_reserved_mask = 0x200fff00u; constexpr uint32_t field1_reserved_mask = 0x200fff00u;
constexpr uint32_t field2_reserved_mask = 0xf0003000u; constexpr uint32_t field2_reserved_mask = 0xf0003000u;
constexpr uint32_t field3_base = 0x91800000u; constexpr uint32_t field3_common = 0x01800000u;
constexpr uint32_t field5_expected = 0x00700000u; constexpr uint32_t field5_expected = 0x00700000u;
const uint32_t field3_expected =
(descriptor.Type() << 28u) | field3_common | descriptor.DstSelXYZW();
return (descriptor.fields[1] & field1_reserved_mask) == 0 && return (descriptor.fields[1] & field1_reserved_mask) == 0 &&
(descriptor.fields[2] & field2_reserved_mask) == 0 && (descriptor.fields[2] & field2_reserved_mask) == 0 &&
descriptor.fields[3] == (field3_base | descriptor.DstSelXYZW()) && descriptor.fields[3] == field3_expected &&
descriptor.fields[4] == 0 && descriptor.fields[5] == field5_expected && descriptor.fields[4] == 0 && descriptor.fields[5] == field5_expected &&
descriptor.fields[6] == 0 && descriptor.fields[7] == 0; descriptor.fields[6] == 0 && descriptor.fields[7] == 0;
} }
@@ -591,10 +590,19 @@ NativeTexture(uint64_t submit_id, CommandBuffer* command_buffer,
if (uint_reinterpret || uint_storage_reinterpret) { if (uint_reinterpret || uint_storage_reinterpret) {
image = nullptr; image = nullptr;
} else { } else {
const auto depth_view = ResolveTargetTextureView(
resource, type, descriptor.BaseArray5(), image->layers);
ValidateDepthTargetBinding(resource, descriptor, image, view_format, size.size); ValidateDepthTargetBinding(resource, descriptor, image, view_format, size.size);
if (depth_view.type == VK_IMAGE_VIEW_TYPE_MAX_ENUM) {
EXIT("unsupported sampled depth target view: dimension=%u descriptor_type=%u "
"base_array=%u image_layers=%u\n",
static_cast<uint32_t>(resource.dimension), descriptor.Type(),
descriptor.BaseArray5(), image->layers);
}
image_view = g_render_ctx->GetTextureCache()->GetDepthTargetSampledView( image_view = g_render_ctx->GetTextureCache()->GetDepthTargetSampledView(
g_render_ctx->GetGraphicCtx(), static_cast<DepthStencilVulkanImage*>(image), g_render_ctx->GetGraphicCtx(), static_cast<DepthStencilVulkanImage*>(image),
view_format, swizzle, 0, 1, VK_IMAGE_VIEW_TYPE_2D, 0, 1); view_format, swizzle, 0, 1, depth_view.type, depth_view.base_layer,
depth_view.layer_count);
} }
} else { } else {
if (!(storage ? IsSupportedStorageImageResource(resource) if (!(storage ? IsSupportedStorageImageResource(resource)
@@ -5,11 +5,23 @@
#include "graphics/shader/shaderBindings.h" #include "graphics/shader/shaderBindings.h"
#include <cstdint> #include <cstdint>
#include <vulkan/vulkan_core.h>
namespace Libs::Graphics { namespace Libs::Graphics {
struct VulkanImage; struct VulkanImage;
struct TargetTextureViewInfo {
VkImageViewType type = VK_IMAGE_VIEW_TYPE_MAX_ENUM;
uint32_t base_layer = 0;
uint32_t layer_count = 0;
};
[[nodiscard]] TargetTextureViewInfo
ResolveTargetTextureView(const ShaderRecompiler::IR::ImageResource& resource,
Prospero::ImageType type, uint32_t base_layer,
uint32_t image_layers);
[[nodiscard]] bool IsSupportedDepthTargetDescriptor(const ShaderTextureResource& descriptor, [[nodiscard]] bool IsSupportedDepthTargetDescriptor(const ShaderTextureResource& descriptor,
const VulkanImage& image); const VulkanImage& image);
[[nodiscard]] bool [[nodiscard]] bool
+2 -1
View File
@@ -155,7 +155,8 @@ namespace Libs::Graphics {
[[nodiscard]] inline bool [[nodiscard]] inline bool
IsSupportedSampledDepthResource(const ShaderRecompiler::IR::ImageResource& resource) noexcept { IsSupportedSampledDepthResource(const ShaderRecompiler::IR::ImageResource& resource) noexcept {
return resource.kind == ShaderRecompiler::IR::ResourceKind::Image && return resource.kind == ShaderRecompiler::IR::ResourceKind::Image &&
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2D && (resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2D ||
resource.dimension == ShaderRecompiler::Decoder::ImageDimension::Dim2DArray) &&
resource.mip_mode == ShaderRecompiler::IR::ImageMipMode::None && resource.read && resource.mip_mode == ShaderRecompiler::IR::ImageMipMode::None && resource.read &&
!resource.written && !resource.atomic; !resource.written && !resource.atomic;
} }
+24 -3
View File
@@ -9367,9 +9367,20 @@ void CheckSampledDepthResource() {
"dynamic-storage mip depth resource was accepted"); "dynamic-storage mip depth resource was accepted");
resource = basic; resource = basic;
resource.dimension = ShaderRecompiler::Decoder::ImageDimension::Dim2DArray; resource.dimension = ShaderRecompiler::Decoder::ImageDimension::Dim2DArray;
Require("SampledDepthResource", "array rejected", Require("SampledDepthResource", "singleton array accepted",
!IsSupportedSampledDepthResource(resource), IsSupportedSampledDepthResource(resource),
"array depth resource was accepted"); "array depth resource was rejected");
const auto singleton_array_view = ResolveTargetTextureView(
resource, Prospero::ImageType::kColor2DArray, 0, 1);
Require("SampledDepthResource", "singleton array view",
singleton_array_view.type == VK_IMAGE_VIEW_TYPE_2D_ARRAY &&
singleton_array_view.base_layer == 0 &&
singleton_array_view.layer_count == 1,
"singleton depth array did not preserve the shader array view type");
Require("SampledDepthResource", "array type mismatch rejected",
ResolveTargetTextureView(resource, Prospero::ImageType::kColor2D, 0, 1)
.type == VK_IMAGE_VIEW_TYPE_MAX_ENUM,
"array shader resource accepted a non-array descriptor view");
resource = basic; resource = basic;
resource.kind = ShaderRecompiler::IR::ResourceKind::ImageUint; resource.kind = ShaderRecompiler::IR::ResourceKind::ImageUint;
Require("SampledDepthResource", "integer rejected", Require("SampledDepthResource", "integer rejected",
@@ -9449,6 +9460,16 @@ void CheckSampledDepthDescriptor() {
IsSupportedDepthTargetDescriptor(descriptor, image), IsSupportedDepthTargetDescriptor(descriptor, image),
"valid padded-pitch depth texture was rejected"); "valid padded-pitch depth texture was rejected");
descriptor.fields[3] =
(descriptor.fields[3] & ~(0xfu << 28u)) |
(Prospero::GpuEnumValue(Prospero::ImageType::kColor2DArray) << 28u);
Require("SampledDepthDescriptor", "singleton array descriptor",
IsSupportedDepthTargetDescriptor(descriptor, image),
"valid singleton-array depth texture was rejected");
descriptor.fields[3] =
(descriptor.fields[3] & ~(0xfu << 28u)) |
(Prospero::GpuEnumValue(Prospero::ImageType::kColor2D) << 28u);
image.guest_pitch = 1344; image.guest_pitch = 1344;
Require("SampledDepthDescriptor", "target pitch mismatch", Require("SampledDepthDescriptor", "target pitch mismatch",
!IsSupportedDepthTargetDescriptor(descriptor, image), !IsSupportedDepthTargetDescriptor(descriptor, image),