From fd252b21ff291f5dee8d74f1702d5755af30a776 Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Mon, 8 Nov 2021 15:59:45 -0500 Subject: [PATCH] Separate (partially) the tracking of depth images from depth compare ops. SPIR-V allows an image to be marked as a depth image, but with a non-depth format. Such images should be read or sampled as vectors instead of scalars, except when they are subject to compare operations. Don't mark an OpSampledImage as using a compare operation just because the image contains a depth marker. Instead, require that a compare operation is actually used on that image. Compiler::image_is_comparison() was really testing whether an image is a depth image, since it incorporates the depth marker. Rename that function to is_depth_image(), to clarify what it is really testing. In Compiler::is_depth_image(), do not treat an image as a depth image if it has been explicitly marked with a color format, unless the image is subject to compare operations. In CompilerMSL::to_function_name(), test for compare operations specifically, rather than assuming them from the depth-image marker. CompilerGLSL and CompilerMSL still contain a number of internal tests that use is_depth_image() both for testing for a depth image, and for testing whether compare operations are being used. I've left these as they are for now, but these should be cleaned up at some point. Add unit tests for fetch/sample depth images with color formats and no compare ops. --- .../depth-image-color-format-fetch.asm.frag | 33 ++++ .../depth-image-color-format-sampled.asm.frag | 33 ++++ .../depth-image-color-format-fetch.asm.frag | 47 +++++ .../depth-image-color-format-sampled.asm.frag | 46 +++++ .../depth-image-color-format-fetch.asm.frag | 170 +++++++++++++++++ .../depth-image-color-format-sampled.asm.frag | 173 ++++++++++++++++++ spirv_cross.cpp | 13 +- spirv_cross.hpp | 2 +- spirv_glsl.cpp | 18 +- spirv_hlsl.cpp | 6 +- spirv_msl.cpp | 11 +- 11 files changed, 526 insertions(+), 26 deletions(-) create mode 100644 reference/opt/shaders-msl/asm/frag/depth-image-color-format-fetch.asm.frag create mode 100644 reference/opt/shaders-msl/asm/frag/depth-image-color-format-sampled.asm.frag create mode 100644 reference/shaders-msl/asm/frag/depth-image-color-format-fetch.asm.frag create mode 100644 reference/shaders-msl/asm/frag/depth-image-color-format-sampled.asm.frag create mode 100644 shaders-msl/asm/frag/depth-image-color-format-fetch.asm.frag create mode 100644 shaders-msl/asm/frag/depth-image-color-format-sampled.asm.frag diff --git a/reference/opt/shaders-msl/asm/frag/depth-image-color-format-fetch.asm.frag b/reference/opt/shaders-msl/asm/frag/depth-image-color-format-fetch.asm.frag new file mode 100644 index 00000000..be9f1331 --- /dev/null +++ b/reference/opt/shaders-msl/asm/frag/depth-image-color-format-fetch.asm.frag @@ -0,0 +1,33 @@ +#include +#include + +using namespace metal; + +struct _7 +{ + float4 _m0[64]; +}; + +struct main0_out +{ + float4 m_3 [[color(0)]]; +}; + +struct main0_in +{ + float4 m_2 [[user(locn1)]]; +}; + +fragment main0_out main0(main0_in in [[stage_in]], device _7& _10 [[buffer(0)]], texture2d _8 [[texture(0)]]) +{ + main0_out out = {}; + for (int _154 = 0; _154 < 64; ) + { + _10._m0[_154] = _8.read(uint2(int2(_154 - 8 * (_154 / 8), _154 / 8)), 0); + _154++; + continue; + } + out.m_3 = in.m_2; + return out; +} + diff --git a/reference/opt/shaders-msl/asm/frag/depth-image-color-format-sampled.asm.frag b/reference/opt/shaders-msl/asm/frag/depth-image-color-format-sampled.asm.frag new file mode 100644 index 00000000..bbe0acd7 --- /dev/null +++ b/reference/opt/shaders-msl/asm/frag/depth-image-color-format-sampled.asm.frag @@ -0,0 +1,33 @@ +#include +#include + +using namespace metal; + +struct _7 +{ + float4 _m0[64]; +}; + +struct main0_out +{ + float4 m_3 [[color(0)]]; +}; + +struct main0_in +{ + float4 m_2 [[user(locn1)]]; +}; + +fragment main0_out main0(main0_in in [[stage_in]], device _7& _10 [[buffer(0)]], texture2d _8 [[texture(0)]], sampler _9 [[sampler(0)]]) +{ + main0_out out = {}; + for (int _158 = 0; _158 < 64; ) + { + _10._m0[_158] = _8.sample(_9, (float2(int2(_158 - 8 * (_158 / 8), _158 / 8)) * float2(0.125)), level(0.0)); + _158++; + continue; + } + out.m_3 = in.m_2; + return out; +} + diff --git a/reference/shaders-msl/asm/frag/depth-image-color-format-fetch.asm.frag b/reference/shaders-msl/asm/frag/depth-image-color-format-fetch.asm.frag new file mode 100644 index 00000000..01c670d9 --- /dev/null +++ b/reference/shaders-msl/asm/frag/depth-image-color-format-fetch.asm.frag @@ -0,0 +1,47 @@ +#pragma clang diagnostic ignored "-Wmissing-prototypes" + +#include +#include + +using namespace metal; + +struct _7 +{ + float4 _m0[64]; +}; + +struct main0_out +{ + float4 m_3 [[color(0)]]; +}; + +struct main0_in +{ + float4 m_2 [[user(locn1)]]; +}; + +static inline __attribute__((always_inline)) +void _108(int _109, thread texture2d v_8, device _7& v_10) +{ + int2 _113 = int2(_109 - 8 * (_109 / 8), _109 / 8); + v_10._m0[_109] = v_8.read(uint2(_113), 0); +} + +static inline __attribute__((always_inline)) +float4 _98(float4 _119, thread texture2d v_8, device _7& v_10) +{ + for (int _121 = 0; _121 < 64; _121++) + { + _108(_121, v_8, v_10); + } + return _119; +} + +fragment main0_out main0(main0_in in [[stage_in]], device _7& v_10 [[buffer(0)]], texture2d v_8 [[texture(0)]]) +{ + main0_out out = {}; + float4 _97 = _98(in.m_2, v_8, v_10); + out.m_3 = _97; + return out; +} + diff --git a/reference/shaders-msl/asm/frag/depth-image-color-format-sampled.asm.frag b/reference/shaders-msl/asm/frag/depth-image-color-format-sampled.asm.frag new file mode 100644 index 00000000..9e374c0a --- /dev/null +++ b/reference/shaders-msl/asm/frag/depth-image-color-format-sampled.asm.frag @@ -0,0 +1,46 @@ +#pragma clang diagnostic ignored "-Wmissing-prototypes" + +#include +#include + +using namespace metal; + +struct _7 +{ + float4 _m0[64]; +}; + +struct main0_out +{ + float4 m_3 [[color(0)]]; +}; + +struct main0_in +{ + float4 m_2 [[user(locn1)]]; +}; + +static inline __attribute__((always_inline)) +void _108(int _109, thread texture2d v_8, thread sampler v_9, device _7& v_10) +{ + v_10._m0[_109] = v_8.sample(v_9, (float2(int2(_109 - 8 * (_109 / 8), _109 / 8)) / float2(8.0)), level(0.0)); +} + +static inline __attribute__((always_inline)) +float4 _98(float4 _121, thread texture2d v_8, thread sampler v_9, device _7& v_10) +{ + for (int _123 = 0; _123 < 64; _123++) + { + _108(_123, v_8, v_9, v_10); + } + return _121; +} + +fragment main0_out main0(main0_in in [[stage_in]], device _7& v_10 [[buffer(0)]], texture2d v_8 [[texture(0)]], sampler v_9 [[sampler(0)]]) +{ + main0_out out = {}; + float4 _97 = _98(in.m_2, v_8, v_9, v_10); + out.m_3 = _97; + return out; +} + diff --git a/shaders-msl/asm/frag/depth-image-color-format-fetch.asm.frag b/shaders-msl/asm/frag/depth-image-color-format-fetch.asm.frag new file mode 100644 index 00000000..0be26d1c --- /dev/null +++ b/shaders-msl/asm/frag/depth-image-color-format-fetch.asm.frag @@ -0,0 +1,170 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos SPIR-V Tools Assembler; 0 +; Bound: 132 +; Schema: 0 + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %1 "main" %2 %3 %4 + OpExecutionMode %1 OriginUpperLeft + OpDecorate %3 Location 0 + OpDecorate %2 Location 1 + OpDecorate %4 BuiltIn FragCoord + OpDecorate %5 ArrayStride 4 + OpDecorate %6 ArrayStride 16 + OpMemberDecorate %7 0 Offset 0 + OpDecorate %7 BufferBlock + OpDecorate %8 DescriptorSet 0 + OpDecorate %8 Binding 0 + OpDecorate %9 DescriptorSet 0 + OpDecorate %9 Binding 1 + OpDecorate %10 DescriptorSet 0 + OpDecorate %10 Binding 2 + %11 = OpTypeVoid + %12 = OpTypeBool + %13 = OpTypeInt 32 1 + %14 = OpTypeInt 32 0 + %16 = OpTypeFloat 32 + %17 = OpTypeVector %13 2 + %18 = OpTypeVector %14 2 + %19 = OpTypeVector %16 2 + %20 = OpTypeVector %13 3 + %21 = OpTypeVector %14 3 + %22 = OpTypeVector %16 3 + %23 = OpTypeVector %13 4 + %24 = OpTypeVector %14 4 + %25 = OpTypeVector %16 4 + %26 = OpTypeVector %12 4 + %27 = OpTypeFunction %25 %25 + %28 = OpTypeFunction %12 + %29 = OpTypeFunction %11 + %30 = OpTypePointer Input %16 + %31 = OpTypePointer Input %13 + %32 = OpTypePointer Input %14 + %33 = OpTypePointer Input %19 + %34 = OpTypePointer Input %17 + %35 = OpTypePointer Input %18 + %38 = OpTypePointer Input %22 + %40 = OpTypePointer Input %25 + %41 = OpTypePointer Input %23 + %42 = OpTypePointer Input %24 + %43 = OpTypePointer Output %16 + %44 = OpTypePointer Output %13 + %45 = OpTypePointer Output %14 + %46 = OpTypePointer Output %19 + %47 = OpTypePointer Output %17 + %48 = OpTypePointer Output %18 + %49 = OpTypePointer Output %25 + %50 = OpTypePointer Output %23 + %51 = OpTypePointer Output %24 + %52 = OpTypePointer Function %16 + %53 = OpTypePointer Function %13 + %54 = OpTypePointer Function %25 + %55 = OpConstant %16 1 + %56 = OpConstant %16 0 + %57 = OpConstant %16 0.5 + %58 = OpConstant %16 -1 + %59 = OpConstant %16 7 + %60 = OpConstant %16 8 + %61 = OpConstant %13 0 + %62 = OpConstant %13 1 + %63 = OpConstant %13 2 + %64 = OpConstant %13 3 + %65 = OpConstant %13 4 + %66 = OpConstant %14 0 + %67 = OpConstant %14 1 + %68 = OpConstant %14 2 + %69 = OpConstant %14 3 + %70 = OpConstant %14 32 + %71 = OpConstant %14 4 + %72 = OpConstant %14 2147483647 + %73 = OpConstantComposite %25 %55 %55 %55 %55 + %74 = OpConstantComposite %25 %55 %56 %56 %55 + %75 = OpConstantComposite %25 %57 %57 %57 %57 + %76 = OpTypeArray %16 %67 + %77 = OpTypeArray %16 %68 + %78 = OpTypeArray %25 %69 + %79 = OpTypeArray %16 %71 + %80 = OpTypeArray %25 %70 + %81 = OpTypePointer Input %78 + %82 = OpTypePointer Input %80 + %83 = OpTypePointer Output %77 + %84 = OpTypePointer Output %78 + %85 = OpTypePointer Output %79 + %4 = OpVariable %40 Input + %3 = OpVariable %49 Output + %2 = OpVariable %40 Input + %86 = OpConstant %14 64 + %87 = OpConstant %13 64 + %88 = OpConstant %13 8 + %89 = OpConstantComposite %19 %60 %60 + %5 = OpTypeArray %16 %86 + %6 = OpTypeArray %25 %86 + %90 = OpTypePointer Uniform %16 + %91 = OpTypePointer Uniform %25 + %7 = OpTypeStruct %6 + %92 = OpTypePointer Uniform %7 + %10 = OpVariable %92 Uniform + %93 = OpTypeImage %16 2D 1 0 0 1 Rgba32f + %94 = OpTypePointer UniformConstant %93 + %8 = OpVariable %94 UniformConstant + %95 = OpTypeSampler + %96 = OpTypePointer UniformConstant %95 + %9 = OpVariable %96 UniformConstant + %97 = OpTypeSampledImage %93 + %98 = OpTypeFunction %11 %13 + %1 = OpFunction %11 None %29 + %99 = OpLabel + %100 = OpLoad %25 %2 + %101 = OpFunctionCall %25 %102 %100 + OpStore %3 %101 + OpReturn + OpFunctionEnd + %103 = OpFunction %12 None %28 + %104 = OpLabel + %105 = OpAccessChain %30 %4 %61 + %106 = OpAccessChain %30 %4 %62 + %107 = OpLoad %16 %105 + %108 = OpLoad %16 %106 + %109 = OpFOrdEqual %12 %107 %57 + %110 = OpFOrdEqual %12 %108 %57 + %111 = OpLogicalAnd %12 %109 %110 + OpReturnValue %111 + OpFunctionEnd + %112 = OpFunction %11 None %98 + %113 = OpFunctionParameter %13 + %114 = OpLabel + %115 = OpSRem %13 %113 %88 + %116 = OpSDiv %13 %113 %88 + %117 = OpCompositeConstruct %17 %115 %116 + %118 = OpConvertSToF %19 %117 + %119 = OpFDiv %19 %118 %89 + %120 = OpLoad %93 %8 + %121 = OpImageFetch %25 %120 %117 + %36 = OpAccessChain %91 %10 %61 %113 + OpStore %36 %121 + OpReturn + OpFunctionEnd + %102 = OpFunction %25 None %27 + %122 = OpFunctionParameter %25 + %123 = OpLabel + %124 = OpVariable %53 Function + OpStore %124 %61 + OpBranch %125 + %125 = OpLabel + %15 = OpLoad %13 %124 + %126 = OpSLessThan %12 %15 %87 + OpLoopMerge %127 %128 None + OpBranchConditional %126 %129 %127 + %129 = OpLabel + %130 = OpLoad %13 %124 + %131 = OpFunctionCall %11 %112 %130 + OpBranch %128 + %128 = OpLabel + %37 = OpLoad %13 %124 + %39 = OpIAdd %13 %37 %62 + OpStore %124 %39 + OpBranch %125 + %127 = OpLabel + OpReturnValue %122 + OpFunctionEnd diff --git a/shaders-msl/asm/frag/depth-image-color-format-sampled.asm.frag b/shaders-msl/asm/frag/depth-image-color-format-sampled.asm.frag new file mode 100644 index 00000000..97e88b55 --- /dev/null +++ b/shaders-msl/asm/frag/depth-image-color-format-sampled.asm.frag @@ -0,0 +1,173 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos SPIR-V Tools Assembler; 0 +; Bound: 134 +; Schema: 0 + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %1 "main" %2 %3 %4 + OpExecutionMode %1 OriginUpperLeft + OpDecorate %3 Location 0 + OpDecorate %2 Location 1 + OpDecorate %4 BuiltIn FragCoord + OpDecorate %5 ArrayStride 4 + OpDecorate %6 ArrayStride 16 + OpMemberDecorate %7 0 Offset 0 + OpDecorate %7 BufferBlock + OpDecorate %8 DescriptorSet 0 + OpDecorate %8 Binding 0 + OpDecorate %9 DescriptorSet 0 + OpDecorate %9 Binding 1 + OpDecorate %10 DescriptorSet 0 + OpDecorate %10 Binding 2 + %11 = OpTypeVoid + %12 = OpTypeBool + %13 = OpTypeInt 32 1 + %14 = OpTypeInt 32 0 + %16 = OpTypeFloat 32 + %17 = OpTypeVector %13 2 + %18 = OpTypeVector %14 2 + %19 = OpTypeVector %16 2 + %20 = OpTypeVector %13 3 + %21 = OpTypeVector %14 3 + %22 = OpTypeVector %16 3 + %23 = OpTypeVector %13 4 + %24 = OpTypeVector %14 4 + %25 = OpTypeVector %16 4 + %26 = OpTypeVector %12 4 + %27 = OpTypeFunction %25 %25 + %28 = OpTypeFunction %12 + %29 = OpTypeFunction %11 + %30 = OpTypePointer Input %16 + %31 = OpTypePointer Input %13 + %32 = OpTypePointer Input %14 + %33 = OpTypePointer Input %19 + %34 = OpTypePointer Input %17 + %35 = OpTypePointer Input %18 + %38 = OpTypePointer Input %22 + %40 = OpTypePointer Input %25 + %41 = OpTypePointer Input %23 + %42 = OpTypePointer Input %24 + %43 = OpTypePointer Output %16 + %44 = OpTypePointer Output %13 + %45 = OpTypePointer Output %14 + %46 = OpTypePointer Output %19 + %47 = OpTypePointer Output %17 + %48 = OpTypePointer Output %18 + %49 = OpTypePointer Output %25 + %50 = OpTypePointer Output %23 + %51 = OpTypePointer Output %24 + %52 = OpTypePointer Function %16 + %53 = OpTypePointer Function %13 + %54 = OpTypePointer Function %25 + %55 = OpConstant %16 1 + %56 = OpConstant %16 0 + %57 = OpConstant %16 0.5 + %58 = OpConstant %16 -1 + %59 = OpConstant %16 7 + %60 = OpConstant %16 8 + %61 = OpConstant %13 0 + %62 = OpConstant %13 1 + %63 = OpConstant %13 2 + %64 = OpConstant %13 3 + %65 = OpConstant %13 4 + %66 = OpConstant %14 0 + %67 = OpConstant %14 1 + %68 = OpConstant %14 2 + %69 = OpConstant %14 3 + %70 = OpConstant %14 32 + %71 = OpConstant %14 4 + %72 = OpConstant %14 2147483647 + %73 = OpConstantComposite %25 %55 %55 %55 %55 + %74 = OpConstantComposite %25 %55 %56 %56 %55 + %75 = OpConstantComposite %25 %57 %57 %57 %57 + %76 = OpTypeArray %16 %67 + %77 = OpTypeArray %16 %68 + %78 = OpTypeArray %25 %69 + %79 = OpTypeArray %16 %71 + %80 = OpTypeArray %25 %70 + %81 = OpTypePointer Input %78 + %82 = OpTypePointer Input %80 + %83 = OpTypePointer Output %77 + %84 = OpTypePointer Output %78 + %85 = OpTypePointer Output %79 + %4 = OpVariable %40 Input + %3 = OpVariable %49 Output + %2 = OpVariable %40 Input + %86 = OpConstant %14 64 + %87 = OpConstant %13 64 + %88 = OpConstant %13 8 + %89 = OpConstantComposite %19 %60 %60 + %5 = OpTypeArray %16 %86 + %6 = OpTypeArray %25 %86 + %90 = OpTypePointer Uniform %16 + %91 = OpTypePointer Uniform %25 + %7 = OpTypeStruct %6 + %92 = OpTypePointer Uniform %7 + %10 = OpVariable %92 Uniform + %93 = OpTypeImage %16 2D 1 0 0 1 Rgba32f + %94 = OpTypePointer UniformConstant %93 + %8 = OpVariable %94 UniformConstant + %95 = OpTypeSampler + %96 = OpTypePointer UniformConstant %95 + %9 = OpVariable %96 UniformConstant + %97 = OpTypeSampledImage %93 + %98 = OpTypeFunction %11 %13 + %1 = OpFunction %11 None %29 + %99 = OpLabel + %100 = OpLoad %25 %2 + %101 = OpFunctionCall %25 %102 %100 + OpStore %3 %101 + OpReturn + OpFunctionEnd + %103 = OpFunction %12 None %28 + %104 = OpLabel + %105 = OpAccessChain %30 %4 %61 + %106 = OpAccessChain %30 %4 %62 + %107 = OpLoad %16 %105 + %108 = OpLoad %16 %106 + %109 = OpFOrdEqual %12 %107 %57 + %110 = OpFOrdEqual %12 %108 %57 + %111 = OpLogicalAnd %12 %109 %110 + OpReturnValue %111 + OpFunctionEnd + %112 = OpFunction %11 None %98 + %113 = OpFunctionParameter %13 + %114 = OpLabel + %115 = OpSRem %13 %113 %88 + %116 = OpSDiv %13 %113 %88 + %117 = OpCompositeConstruct %17 %115 %116 + %118 = OpConvertSToF %19 %117 + %119 = OpFDiv %19 %118 %89 + %120 = OpLoad %93 %8 + %121 = OpLoad %95 %9 + %122 = OpSampledImage %97 %120 %121 + %123 = OpImageSampleExplicitLod %25 %122 %119 Lod %56 + %36 = OpAccessChain %91 %10 %61 %113 + OpStore %36 %123 + OpReturn + OpFunctionEnd + %102 = OpFunction %25 None %27 + %124 = OpFunctionParameter %25 + %125 = OpLabel + %126 = OpVariable %53 Function + OpStore %126 %61 + OpBranch %127 + %127 = OpLabel + %15 = OpLoad %13 %126 + %128 = OpSLessThan %12 %15 %87 + OpLoopMerge %129 %130 None + OpBranchConditional %128 %131 %129 + %131 = OpLabel + %132 = OpLoad %13 %126 + %133 = OpFunctionCall %11 %112 %132 + OpBranch %130 + %130 = OpLabel + %37 = OpLoad %13 %126 + %39 = OpIAdd %13 %37 %62 + OpStore %126 %39 + OpBranch %127 + %129 = OpLabel + OpReturnValue %124 + OpFunctionEnd + diff --git a/spirv_cross.cpp b/spirv_cross.cpp index 07fdb946..13e41357 100644 --- a/spirv_cross.cpp +++ b/spirv_cross.cpp @@ -4448,16 +4448,13 @@ bool Compiler::CombinedImageSamplerUsageHandler::handle(Op opcode, const uint32_ if (length < 4) return false; - uint32_t result_type = args[0]; - uint32_t result_id = args[1]; - auto &type = compiler.get(result_type); - // If the underlying resource has been used for comparison then duplicate loads of that resource must be too. // This image must be a depth image. + uint32_t result_id = args[1]; uint32_t image = args[2]; uint32_t sampler = args[3]; - if (type.image.depth || dref_combined_samplers.count(result_id) != 0) + if (dref_combined_samplers.count(result_id) != 0) { add_hierarchy_to_comparison_ids(image); @@ -4717,9 +4714,11 @@ bool Compiler::is_desktop_only_format(spv::ImageFormat format) return false; } -bool Compiler::image_is_comparison(const SPIRType &type, uint32_t id) const +// An image is determined to be a depth image if it is marked as a depth image and is not also +// explicitly marked with a color format, or if there are any sample/gather compare operations on it. +bool Compiler::is_depth_image(const SPIRType &type, uint32_t id) const { - return type.image.depth || (comparison_ids.count(id) != 0); + return (type.image.depth && type.image.format == ImageFormatUnknown) || comparison_ids.count(id); } bool Compiler::type_is_opaque_value(const SPIRType &type) const diff --git a/spirv_cross.hpp b/spirv_cross.hpp index d8967963..26744376 100644 --- a/spirv_cross.hpp +++ b/spirv_cross.hpp @@ -1107,7 +1107,7 @@ protected: Bitset combined_decoration_for_member(const SPIRType &type, uint32_t index) const; static bool is_desktop_only_format(spv::ImageFormat format); - bool image_is_comparison(const SPIRType &type, uint32_t id) const; + bool is_depth_image(const SPIRType &type, uint32_t id) const; void set_extended_decoration(uint32_t id, ExtendedDecorations decoration, uint32_t value = 0); uint32_t get_extended_decoration(uint32_t id, ExtendedDecorations decoration) const; diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index 9578502c..a663318b 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -6215,7 +6215,7 @@ string CompilerGLSL::legacy_tex_op(const std::string &op, const SPIRType &imgtyp // GLES has very limited support for shadow samplers. // Basically shadow2D and shadow2DProj work through EXT_shadow_samplers, // everything else can just throw - bool is_comparison = image_is_comparison(imgtype, tex); + bool is_comparison = is_depth_image(imgtype, tex); if (is_comparison && is_legacy_es()) { if (op == "texture" || op == "textureProj") @@ -6842,7 +6842,7 @@ std::string CompilerGLSL::to_texture_op(const Instruction &i, bool sparse, bool expr += ")"; // texture(samplerXShadow) returns float. shadowX() returns vec4. Swizzle here. - if (is_legacy() && image_is_comparison(imgtype, img)) + if (is_legacy() && is_depth_image(imgtype, img)) expr += ".r"; // Sampling from a texture which was deduced to be a depth image, might actually return 1 component here. @@ -6853,16 +6853,16 @@ std::string CompilerGLSL::to_texture_op(const Instruction &i, bool sparse, bool const auto *combined = maybe_get(img); VariableID image_id = combined ? combined->image : img; - if (combined && image_is_comparison(imgtype, combined->image)) + if (combined && is_depth_image(imgtype, combined->image)) image_is_depth = true; - else if (image_is_comparison(imgtype, img)) + else if (is_depth_image(imgtype, img)) image_is_depth = true; // We must also check the backing variable for the image. // We might have loaded an OpImage, and used that handle for two different purposes. // Once with comparison, once without. auto *image_variable = maybe_get_backing_variable(image_id); - if (image_variable && image_is_comparison(get(image_variable->basetype), image_variable->self)) + if (image_variable && is_depth_image(get(image_variable->basetype), image_variable->self)) image_is_depth = true; if (image_is_depth) @@ -6930,7 +6930,7 @@ string CompilerGLSL::to_function_name(const TextureFunctionNameArguments &args) // This happens for HLSL SampleCmpLevelZero on Texture2DArray and TextureCube. bool workaround_lod_array_shadow_as_grad = false; if (((imgtype.image.arrayed && imgtype.image.dim == Dim2D) || imgtype.image.dim == DimCube) && - image_is_comparison(imgtype, tex) && args.lod) + is_depth_image(imgtype, tex) && args.lod) { if (!expression_is_constant_null(args.lod)) { @@ -7074,7 +7074,7 @@ string CompilerGLSL::to_function_args(const TextureFunctionArguments &args, bool // This happens for HLSL SampleCmpLevelZero on Texture2DArray and TextureCube. bool workaround_lod_array_shadow_as_grad = ((imgtype.image.arrayed && imgtype.image.dim == Dim2D) || imgtype.image.dim == DimCube) && - image_is_comparison(imgtype, img) && args.lod != 0; + is_depth_image(imgtype, img) && args.lod != 0; if (args.dref) { @@ -13392,7 +13392,7 @@ string CompilerGLSL::image_type_glsl(const SPIRType &type, uint32_t id) // "Shadow" state in GLSL only exists for samplers and combined image samplers. if (((type.basetype == SPIRType::SampledImage) || (type.basetype == SPIRType::Sampler)) && - image_is_comparison(type, id)) + is_depth_image(type, id)) { res += "Shadow"; } @@ -15831,7 +15831,7 @@ void CompilerGLSL::emit_inout_fragment_outputs_copy_to_subpass_inputs() bool CompilerGLSL::variable_is_depth_or_compare(VariableID id) const { - return image_is_comparison(get(get(id).basetype), id); + return is_depth_image(get(get(id).basetype), id); } const char *CompilerGLSL::ShaderSubgroupSupportHelper::get_extension_name(Candidate c) diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp index 1f04c400..bdcb6dd3 100644 --- a/spirv_hlsl.cpp +++ b/spirv_hlsl.cpp @@ -2380,7 +2380,7 @@ void CompilerHLSL::emit_function_prototype(SPIRFunction &func, const Bitset &ret arg_type.image.dim != DimBuffer) { // Manufacture automatic sampler arg for SampledImage texture - arglist.push_back(join(image_is_comparison(arg_type, arg.id) ? "SamplerComparisonState " : "SamplerState ", + arglist.push_back(join(is_depth_image(arg_type, arg.id) ? "SamplerComparisonState " : "SamplerState ", to_sampler_expression(arg.id), type_to_array_glsl(arg_type))); } @@ -2910,7 +2910,7 @@ void CompilerHLSL::emit_texture_op(const Instruction &i, bool sparse) { texop += img_expr; - if (image_is_comparison(imgtype, img)) + if (is_depth_image(imgtype, img)) { if (gather) { @@ -3386,7 +3386,7 @@ void CompilerHLSL::emit_modern_uniform(const SPIRVariable &var) if (type.basetype == SPIRType::SampledImage && type.image.dim != DimBuffer) { // For combined image samplers, also emit a combined image sampler. - if (image_is_comparison(type, var.self)) + if (is_depth_image(type, var.self)) statement("SamplerComparisonState ", to_sampler_expression(var.self), type_to_array_glsl(type), to_resource_binding_sampler(var), ";"); else diff --git a/spirv_msl.cpp b/spirv_msl.cpp index 3f53ebd5..b08bb86f 100644 --- a/spirv_msl.cpp +++ b/spirv_msl.cpp @@ -9393,8 +9393,6 @@ static bool needs_chroma_reconstruction(const MSLConstexprSampler *constexpr_sam string CompilerMSL::to_function_name(const TextureFunctionNameArguments &args) { VariableID img = args.base.img; - auto &imgtype = *args.base.imgtype; - const MSLConstexprSampler *constexpr_sampler = nullptr; bool is_dynamic_img_sampler = false; if (auto *var = maybe_get_backing_variable(img)) @@ -9408,8 +9406,9 @@ string CompilerMSL::to_function_name(const TextureFunctionNameArguments &args) if (msl_options.swizzle_texture_samples && args.base.is_gather && !is_dynamic_img_sampler && (!constexpr_sampler || !constexpr_sampler->ycbcr_conversion_enable)) { - add_spv_func_and_recompile(imgtype.image.depth ? SPVFuncImplGatherCompareSwizzle : SPVFuncImplGatherSwizzle); - return imgtype.image.depth ? "spvGatherCompareSwizzle" : "spvGatherSwizzle"; + bool is_compare = comparison_ids.count(img); + add_spv_func_and_recompile(is_compare ? SPVFuncImplGatherCompareSwizzle : SPVFuncImplGatherSwizzle); + return is_compare ? "spvGatherCompareSwizzle" : "spvGatherSwizzle"; } auto *combined = maybe_get(img); @@ -10021,7 +10020,7 @@ string CompilerMSL::to_function_args(const TextureFunctionArguments &args, bool image_var = var->self; } - if (image_var == 0 || !image_is_comparison(expression_type(image_var), image_var)) + if (image_var == 0 || !is_depth_image(expression_type(image_var), image_var)) farg_str += ", " + to_component_argument(args.component); } } @@ -13631,7 +13630,7 @@ string CompilerMSL::image_type_glsl(const SPIRType &type, uint32_t id) // Bypass pointers because we need the real image struct auto &img_type = get(type.self).image; - if (image_is_comparison(type, id)) + if (is_depth_image(type, id)) { switch (img_type.dim) {