소스 검색

Updated spirv-cross.

Бранимир Караџић 6 년 전
부모
커밋
a3b0f3ff42
42개의 변경된 파일1500개의 추가작업 그리고 51개의 파일을 삭제
  1. 7 1
      3rdparty/spirv-cross/CMakeLists.txt
  2. 17 0
      3rdparty/spirv-cross/reference/opt/shaders-msl/asm/vert/invariant.msl21.asm.vert
  3. 17 0
      3rdparty/spirv-cross/reference/opt/shaders-msl/frag/private-variable-prototype-declaration.frag
  4. 22 0
      3rdparty/spirv-cross/reference/opt/shaders-msl/frag/stencil-export.msl21.frag
  5. 26 0
      3rdparty/spirv-cross/reference/opt/shaders-msl/vert/invariant.msl21.vert
  6. 13 0
      3rdparty/spirv-cross/reference/opt/shaders/desktop-only/frag/stencil-export.desktop.frag
  7. 25 0
      3rdparty/spirv-cross/reference/shaders-msl/asm/vert/invariant.msl21.asm.vert
  8. 39 0
      3rdparty/spirv-cross/reference/shaders-msl/frag/private-variable-prototype-declaration.frag
  9. 29 0
      3rdparty/spirv-cross/reference/shaders-msl/frag/stencil-export.msl21.frag
  10. 26 0
      3rdparty/spirv-cross/reference/shaders-msl/vert/invariant.msl21.vert
  11. 32 0
      3rdparty/spirv-cross/reference/shaders-reflection/asm/op-source-glsl-ssbo-1.asm.comp.json
  12. 52 0
      3rdparty/spirv-cross/reference/shaders-reflection/asm/op-source-glsl-ssbo-2.asm.comp.json
  13. 32 0
      3rdparty/spirv-cross/reference/shaders-reflection/asm/op-source-hlsl-uav-1.asm.comp.json
  14. 39 0
      3rdparty/spirv-cross/reference/shaders-reflection/asm/op-source-hlsl-uav-2.asm.comp.json
  15. 32 0
      3rdparty/spirv-cross/reference/shaders-reflection/asm/op-source-none-ssbo-1.asm.comp.json
  16. 52 0
      3rdparty/spirv-cross/reference/shaders-reflection/asm/op-source-none-ssbo-2.asm.comp.json
  17. 32 0
      3rdparty/spirv-cross/reference/shaders-reflection/asm/op-source-none-uav-1.asm.comp.json
  18. 39 0
      3rdparty/spirv-cross/reference/shaders-reflection/asm/op-source-none-uav-2.asm.comp.json
  19. 13 0
      3rdparty/spirv-cross/reference/shaders/desktop-only/frag/stencil-export.desktop.frag
  20. 34 0
      3rdparty/spirv-cross/shaders-msl/asm/vert/invariant.msl21.asm.vert
  21. 20 0
      3rdparty/spirv-cross/shaders-msl/frag/private-variable-prototype-declaration.frag
  22. 17 0
      3rdparty/spirv-cross/shaders-msl/frag/stencil-export.msl21.frag
  23. 11 0
      3rdparty/spirv-cross/shaders-msl/vert/invariant.msl21.vert
  24. 53 0
      3rdparty/spirv-cross/shaders-reflection/asm/op-source-glsl-ssbo-1.asm.comp
  25. 65 0
      3rdparty/spirv-cross/shaders-reflection/asm/op-source-glsl-ssbo-2.asm.comp
  26. 48 0
      3rdparty/spirv-cross/shaders-reflection/asm/op-source-hlsl-uav-1.asm.comp
  27. 54 0
      3rdparty/spirv-cross/shaders-reflection/asm/op-source-hlsl-uav-2.asm.comp
  28. 52 0
      3rdparty/spirv-cross/shaders-reflection/asm/op-source-none-ssbo-1.asm.comp
  29. 64 0
      3rdparty/spirv-cross/shaders-reflection/asm/op-source-none-ssbo-2.asm.comp
  30. 47 0
      3rdparty/spirv-cross/shaders-reflection/asm/op-source-none-uav-1.asm.comp
  31. 53 0
      3rdparty/spirv-cross/shaders-reflection/asm/op-source-none-uav-2.asm.comp
  32. 11 0
      3rdparty/spirv-cross/shaders/desktop-only/frag/stencil-export.desktop.frag
  33. 60 9
      3rdparty/spirv-cross/spirv_cross.cpp
  34. 3 0
      3rdparty/spirv-cross/spirv_cross.hpp
  35. 43 11
      3rdparty/spirv-cross/spirv_cross_c.cpp
  36. 2 1
      3rdparty/spirv-cross/spirv_cross_c.h
  37. 21 0
      3rdparty/spirv-cross/spirv_glsl.cpp
  38. 121 27
      3rdparty/spirv-cross/spirv_msl.cpp
  39. 38 2
      3rdparty/spirv-cross/spirv_msl.hpp
  40. 6 0
      3rdparty/spirv-cross/test_shaders.py
  41. 133 0
      3rdparty/spirv-cross/tests-other/msl_constexpr_test.cpp
  42. BIN
      3rdparty/spirv-cross/tests-other/msl_constexpr_test.spv

+ 7 - 1
3rdparty/spirv-cross/CMakeLists.txt

@@ -287,7 +287,7 @@ if (SPIRV_CROSS_STATIC)
 endif()
 endif()
 
 
 set(spirv-cross-abi-major 0)
 set(spirv-cross-abi-major 0)
-set(spirv-cross-abi-minor 12)
+set(spirv-cross-abi-minor 13)
 set(spirv-cross-abi-patch 0)
 set(spirv-cross-abi-patch 0)
 
 
 if (SPIRV_CROSS_SHARED)
 if (SPIRV_CROSS_SHARED)
@@ -453,6 +453,10 @@ if (SPIRV_CROSS_CLI)
 				target_link_libraries(spirv-cross-small-vector-test spirv-cross-core)
 				target_link_libraries(spirv-cross-small-vector-test spirv-cross-core)
 				set_target_properties(spirv-cross-small-vector-test PROPERTIES LINK_FLAGS "${spirv-cross-link-flags}")
 				set_target_properties(spirv-cross-small-vector-test PROPERTIES LINK_FLAGS "${spirv-cross-link-flags}")
 
 
+				add_executable(spirv-cross-msl-constexpr-test tests-other/msl_constexpr_test.cpp)
+				target_link_libraries(spirv-cross-msl-constexpr-test spirv-cross-c)
+				set_target_properties(spirv-cross-msl-constexpr-test PROPERTIES LINK_FLAGS "${spirv-cross-link-flags}")
+
 				if (CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang"))
 				if (CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang"))
 					target_compile_options(spirv-cross-c-api-test PRIVATE -std=c89 -Wall -Wextra)
 					target_compile_options(spirv-cross-c-api-test PRIVATE -std=c89 -Wall -Wextra)
 				endif()
 				endif()
@@ -463,6 +467,8 @@ if (SPIRV_CROSS_CLI)
 						${spirv-cross-abi-patch})
 						${spirv-cross-abi-patch})
 				add_test(NAME spirv-cross-small-vector-test
 				add_test(NAME spirv-cross-small-vector-test
 						COMMAND $<TARGET_FILE:spirv-cross-small-vector-test>)
 						COMMAND $<TARGET_FILE:spirv-cross-small-vector-test>)
+				add_test(NAME spirv-cross-msl-constexpr-test
+						COMMAND $<TARGET_FILE:spirv-cross-msl-constexpr-test> ${CMAKE_CURRENT_SOURCE_DIR}/tests-other/msl_constexpr_test.spv)
 				add_test(NAME spirv-cross-test
 				add_test(NAME spirv-cross-test
 						COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --parallel
 						COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --parallel
 						${spirv-cross-externals}
 						${spirv-cross-externals}

+ 17 - 0
3rdparty/spirv-cross/reference/opt/shaders-msl/asm/vert/invariant.msl21.asm.vert

@@ -0,0 +1,17 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct main0_out
+{
+    float4 gl_Position [[position, invariant]];
+};
+
+vertex main0_out main0()
+{
+    main0_out out = {};
+    out.gl_Position = float4(1.0);
+    return out;
+}
+

+ 17 - 0
3rdparty/spirv-cross/reference/opt/shaders-msl/frag/private-variable-prototype-declaration.frag

@@ -0,0 +1,17 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct main0_out
+{
+    float3 FragColor [[color(0)]];
+};
+
+fragment main0_out main0()
+{
+    main0_out out = {};
+    out.FragColor = float3(1.0);
+    return out;
+}
+

+ 22 - 0
3rdparty/spirv-cross/reference/opt/shaders-msl/frag/stencil-export.msl21.frag

@@ -0,0 +1,22 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct main0_out
+{
+    float4 MRT0 [[color(0)]];
+    float4 MRT1 [[color(1)]];
+    uint gl_FragStencilRefARB [[stencil]];
+};
+
+fragment main0_out main0()
+{
+    main0_out out = {};
+    out.MRT0 = float4(1.0);
+    out.MRT1 = float4(1.0, 0.0, 1.0, 1.0);
+    out.gl_FragStencilRefARB = uint(100);
+    out.gl_FragStencilRefARB = uint(int(out.gl_FragStencilRefARB) + 10);
+    return out;
+}
+

+ 26 - 0
3rdparty/spirv-cross/reference/opt/shaders-msl/vert/invariant.msl21.vert

@@ -0,0 +1,26 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct main0_out
+{
+    float4 gl_Position [[position, invariant]];
+};
+
+struct main0_in
+{
+    float4 vInput0 [[attribute(0)]];
+    float4 vInput1 [[attribute(1)]];
+    float4 vInput2 [[attribute(2)]];
+};
+
+vertex main0_out main0(main0_in in [[stage_in]])
+{
+    main0_out out = {};
+    float4 _20 = in.vInput1 * in.vInput2;
+    float4 _21 = in.vInput0 + _20;
+    out.gl_Position = _21;
+    return out;
+}
+

+ 13 - 0
3rdparty/spirv-cross/reference/opt/shaders/desktop-only/frag/stencil-export.desktop.frag

@@ -0,0 +1,13 @@
+#version 450
+#extension GL_ARB_shader_stencil_export : require
+
+layout(location = 0) out vec4 MRT0;
+layout(location = 1) out vec4 MRT1;
+
+void main()
+{
+    MRT0 = vec4(1.0);
+    MRT1 = vec4(1.0, 0.0, 1.0, 1.0);
+    gl_FragStencilRefARB = 100;
+}
+

+ 25 - 0
3rdparty/spirv-cross/reference/shaders-msl/asm/vert/invariant.msl21.asm.vert

@@ -0,0 +1,25 @@
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct main0_out
+{
+    float4 gl_Position [[position, invariant]];
+};
+
+float4 _main()
+{
+    return float4(1.0);
+}
+
+vertex main0_out main0()
+{
+    main0_out out = {};
+    float4 _14 = _main();
+    out.gl_Position = _14;
+    return out;
+}
+

+ 39 - 0
3rdparty/spirv-cross/reference/shaders-msl/frag/private-variable-prototype-declaration.frag

@@ -0,0 +1,39 @@
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct AStruct
+{
+    float4 foobar;
+};
+
+struct main0_out
+{
+    float3 FragColor [[color(0)]];
+};
+
+void someFunction(thread AStruct& s)
+{
+    s.foobar = float4(1.0);
+}
+
+void otherFunction(thread float3& global_variable)
+{
+    global_variable = float3(1.0);
+}
+
+fragment main0_out main0()
+{
+    main0_out out = {};
+    AStruct param;
+    someFunction(param);
+    AStruct inputs = param;
+    float3 global_variable;
+    otherFunction(global_variable);
+    out.FragColor = global_variable;
+    return out;
+}
+

+ 29 - 0
3rdparty/spirv-cross/reference/shaders-msl/frag/stencil-export.msl21.frag

@@ -0,0 +1,29 @@
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct main0_out
+{
+    float4 MRT0 [[color(0)]];
+    float4 MRT1 [[color(1)]];
+    uint gl_FragStencilRefARB [[stencil]];
+};
+
+void update_stencil(thread uint& gl_FragStencilRefARB)
+{
+    gl_FragStencilRefARB = uint(int(gl_FragStencilRefARB) + 10);
+}
+
+fragment main0_out main0()
+{
+    main0_out out = {};
+    out.MRT0 = float4(1.0);
+    out.MRT1 = float4(1.0, 0.0, 1.0, 1.0);
+    out.gl_FragStencilRefARB = uint(100);
+    update_stencil(out.gl_FragStencilRefARB);
+    return out;
+}
+

+ 26 - 0
3rdparty/spirv-cross/reference/shaders-msl/vert/invariant.msl21.vert

@@ -0,0 +1,26 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct main0_out
+{
+    float4 gl_Position [[position, invariant]];
+};
+
+struct main0_in
+{
+    float4 vInput0 [[attribute(0)]];
+    float4 vInput1 [[attribute(1)]];
+    float4 vInput2 [[attribute(2)]];
+};
+
+vertex main0_out main0(main0_in in [[stage_in]])
+{
+    main0_out out = {};
+    float4 _20 = in.vInput1 * in.vInput2;
+    float4 _21 = in.vInput0 + _20;
+    out.gl_Position = _21;
+    return out;
+}
+

+ 32 - 0
3rdparty/spirv-cross/reference/shaders-reflection/asm/op-source-glsl-ssbo-1.asm.comp.json

@@ -0,0 +1,32 @@
+{
+    "entryPoints" : [
+        {
+            "name" : "main",
+            "mode" : "comp"
+        }
+    ],
+    "types" : {
+        "_5" : {
+            "name" : "SSBO0",
+            "members" : [
+                {
+                    "name" : "a",
+                    "type" : "vec4",
+                    "array" : [
+                        0
+                    ],
+                    "offset" : 0
+                }
+            ]
+        }
+    },
+    "ssbos" : [
+        {
+            "type" : "_5",
+            "name" : "SSBO0",
+            "block_size" : 0,
+            "set" : 0,
+            "binding" : 0
+        }
+    ]
+}

+ 52 - 0
3rdparty/spirv-cross/reference/shaders-reflection/asm/op-source-glsl-ssbo-2.asm.comp.json

@@ -0,0 +1,52 @@
+{
+    "entryPoints" : [
+        {
+            "name" : "main",
+            "mode" : "comp"
+        }
+    ],
+    "types" : {
+        "_4" : {
+            "name" : "SSBO0",
+            "members" : [
+                {
+                    "name" : "a",
+                    "type" : "vec4",
+                    "array" : [
+                        0
+                    ],
+                    "offset" : 0
+                }
+            ]
+        },
+        "_6" : {
+            "name" : "SSBO1",
+            "members" : [
+                {
+                    "name" : "b",
+                    "type" : "vec4",
+                    "array" : [
+                        0
+                    ],
+                    "offset" : 0
+                }
+            ]
+        }
+    },
+    "ssbos" : [
+        {
+            "type" : "_4",
+            "name" : "SSBO0",
+            "block_size" : 0,
+            "set" : 0,
+            "binding" : 0
+        },
+        {
+            "type" : "_6",
+            "name" : "SSBO1",
+            "block_size" : 0,
+            "set" : 0,
+            "binding" : 1
+        }
+    ]
+}

+ 32 - 0
3rdparty/spirv-cross/reference/shaders-reflection/asm/op-source-hlsl-uav-1.asm.comp.json

@@ -0,0 +1,32 @@
+{
+    "entryPoints" : [
+        {
+            "name" : "main",
+            "mode" : "comp"
+        }
+    ],
+    "types" : {
+        "_4" : {
+            "name" : "UAV0",
+            "members" : [
+                {
+                    "name" : "_data",
+                    "type" : "vec4",
+                    "array" : [
+                        0
+                    ],
+                    "offset" : 0
+                }
+            ]
+        }
+    },
+    "ssbos" : [
+        {
+            "type" : "_4",
+            "name" : "UAV0",
+            "block_size" : 0,
+            "set" : 0,
+            "binding" : 0
+        }
+    ]
+}

+ 39 - 0
3rdparty/spirv-cross/reference/shaders-reflection/asm/op-source-hlsl-uav-2.asm.comp.json

@@ -0,0 +1,39 @@
+{
+    "entryPoints" : [
+        {
+            "name" : "main",
+            "mode" : "comp"
+        }
+    ],
+    "types" : {
+        "_4" : {
+            "name" : "UAV0",
+            "members" : [
+                {
+                    "name" : "_data",
+                    "type" : "vec4",
+                    "array" : [
+                        0
+                    ],
+                    "offset" : 0
+                }
+            ]
+        }
+    },
+    "ssbos" : [
+        {
+            "type" : "_4",
+            "name" : "UAV0",
+            "block_size" : 0,
+            "set" : 0,
+            "binding" : 0
+        },
+        {
+            "type" : "_4",
+            "name" : "UAV1",
+            "block_size" : 0,
+            "set" : 0,
+            "binding" : 1
+        }
+    ]
+}

+ 32 - 0
3rdparty/spirv-cross/reference/shaders-reflection/asm/op-source-none-ssbo-1.asm.comp.json

@@ -0,0 +1,32 @@
+{
+    "entryPoints" : [
+        {
+            "name" : "main",
+            "mode" : "comp"
+        }
+    ],
+    "types" : {
+        "_5" : {
+            "name" : "SSBO0",
+            "members" : [
+                {
+                    "name" : "a",
+                    "type" : "vec4",
+                    "array" : [
+                        0
+                    ],
+                    "offset" : 0
+                }
+            ]
+        }
+    },
+    "ssbos" : [
+        {
+            "type" : "_5",
+            "name" : "SSBO0",
+            "block_size" : 0,
+            "set" : 0,
+            "binding" : 0
+        }
+    ]
+}

+ 52 - 0
3rdparty/spirv-cross/reference/shaders-reflection/asm/op-source-none-ssbo-2.asm.comp.json

@@ -0,0 +1,52 @@
+{
+    "entryPoints" : [
+        {
+            "name" : "main",
+            "mode" : "comp"
+        }
+    ],
+    "types" : {
+        "_4" : {
+            "name" : "SSBO0",
+            "members" : [
+                {
+                    "name" : "a",
+                    "type" : "vec4",
+                    "array" : [
+                        0
+                    ],
+                    "offset" : 0
+                }
+            ]
+        },
+        "_6" : {
+            "name" : "SSBO1",
+            "members" : [
+                {
+                    "name" : "b",
+                    "type" : "vec4",
+                    "array" : [
+                        0
+                    ],
+                    "offset" : 0
+                }
+            ]
+        }
+    },
+    "ssbos" : [
+        {
+            "type" : "_4",
+            "name" : "SSBO0",
+            "block_size" : 0,
+            "set" : 0,
+            "binding" : 0
+        },
+        {
+            "type" : "_6",
+            "name" : "SSBO1",
+            "block_size" : 0,
+            "set" : 0,
+            "binding" : 1
+        }
+    ]
+}

+ 32 - 0
3rdparty/spirv-cross/reference/shaders-reflection/asm/op-source-none-uav-1.asm.comp.json

@@ -0,0 +1,32 @@
+{
+    "entryPoints" : [
+        {
+            "name" : "main",
+            "mode" : "comp"
+        }
+    ],
+    "types" : {
+        "_4" : {
+            "name" : "UAV0",
+            "members" : [
+                {
+                    "name" : "_data",
+                    "type" : "vec4",
+                    "array" : [
+                        0
+                    ],
+                    "offset" : 0
+                }
+            ]
+        }
+    },
+    "ssbos" : [
+        {
+            "type" : "_4",
+            "name" : "UAV0",
+            "block_size" : 0,
+            "set" : 0,
+            "binding" : 0
+        }
+    ]
+}

+ 39 - 0
3rdparty/spirv-cross/reference/shaders-reflection/asm/op-source-none-uav-2.asm.comp.json

@@ -0,0 +1,39 @@
+{
+    "entryPoints" : [
+        {
+            "name" : "main",
+            "mode" : "comp"
+        }
+    ],
+    "types" : {
+        "_4" : {
+            "name" : "UAV0",
+            "members" : [
+                {
+                    "name" : "_data",
+                    "type" : "vec4",
+                    "array" : [
+                        0
+                    ],
+                    "offset" : 0
+                }
+            ]
+        }
+    },
+    "ssbos" : [
+        {
+            "type" : "_4",
+            "name" : "UAV0",
+            "block_size" : 0,
+            "set" : 0,
+            "binding" : 0
+        },
+        {
+            "type" : "_4",
+            "name" : "UAV1",
+            "block_size" : 0,
+            "set" : 0,
+            "binding" : 1
+        }
+    ]
+}

+ 13 - 0
3rdparty/spirv-cross/reference/shaders/desktop-only/frag/stencil-export.desktop.frag

@@ -0,0 +1,13 @@
+#version 450
+#extension GL_ARB_shader_stencil_export : require
+
+layout(location = 0) out vec4 MRT0;
+layout(location = 1) out vec4 MRT1;
+
+void main()
+{
+    MRT0 = vec4(1.0);
+    MRT1 = vec4(1.0, 0.0, 1.0, 1.0);
+    gl_FragStencilRefARB = 100;
+}
+

+ 34 - 0
3rdparty/spirv-cross/shaders-msl/asm/vert/invariant.msl21.asm.vert

@@ -0,0 +1,34 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 3
+; Bound: 18
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Vertex %main "main" %_entryPointOutput
+               OpSource HLSL 500
+               OpName %main "main"
+               OpName %_main_ "@main("
+               OpName %_entryPointOutput "@entryPointOutput"
+               OpDecorate %_entryPointOutput Invariant
+               OpDecorate %_entryPointOutput BuiltIn Position
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+          %8 = OpTypeFunction %v4float
+    %float_1 = OpConstant %float 1
+         %12 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%_entryPointOutput = OpVariable %_ptr_Output_v4float Output
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+         %17 = OpFunctionCall %v4float %_main_
+               OpStore %_entryPointOutput %17
+               OpReturn
+               OpFunctionEnd
+     %_main_ = OpFunction %v4float None %8
+         %10 = OpLabel
+               OpReturnValue %12
+               OpFunctionEnd

+ 20 - 0
3rdparty/spirv-cross/shaders-msl/frag/private-variable-prototype-declaration.frag

@@ -0,0 +1,20 @@
+#version 450
+
+struct AStruct { vec4 foobar; };
+
+void someFunction(out AStruct s) { s.foobar = vec4(1.0); }
+
+highp vec3 global_variable;
+
+void otherFunction() {
+    global_variable = vec3(1.0);
+}
+
+layout(location = 0) out vec3 FragColor;
+
+void main() {
+	AStruct inputs;
+	someFunction(inputs);
+    otherFunction();
+	FragColor = global_variable;
+}

+ 17 - 0
3rdparty/spirv-cross/shaders-msl/frag/stencil-export.msl21.frag

@@ -0,0 +1,17 @@
+#version 450
+#extension GL_ARB_shader_stencil_export : require
+
+layout(location = 0) out vec4 MRT0;
+layout(location = 1) out vec4 MRT1;
+void update_stencil()
+{
+	gl_FragStencilRefARB += 10;
+}
+
+void main()
+{
+	MRT0 = vec4(1.0);
+	MRT1 = vec4(1.0, 0.0, 1.0, 1.0);
+	gl_FragStencilRefARB = 100;
+	update_stencil();
+}

+ 11 - 0
3rdparty/spirv-cross/shaders-msl/vert/invariant.msl21.vert

@@ -0,0 +1,11 @@
+#version 310 es
+
+invariant gl_Position;
+layout(location = 0) in vec4 vInput0;
+layout(location = 1) in vec4 vInput1;
+layout(location = 2) in vec4 vInput2;
+
+void main()
+{
+	gl_Position = vInput0 + vInput1 * vInput2;
+}

+ 53 - 0
3rdparty/spirv-cross/shaders-reflection/asm/op-source-glsl-ssbo-1.asm.comp

@@ -0,0 +1,53 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 35
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID %_
+               OpExecutionMode %main LocalSize 1 1 1
+               OpSource GLSL 450
+               OpName %main "main"
+               OpName %SSBO0 "SSBO0"
+               OpMemberName %SSBO0 0 "a"
+               OpName %_ ""
+               OpName %gl_GlobalInvocationID "gl_GlobalInvocationID"
+               OpDecorate %_runtimearr_v4float ArrayStride 16
+               OpMemberDecorate %SSBO0 0 Offset 0
+               OpDecorate %SSBO0 BufferBlock
+               OpDecorate %_ DescriptorSet 0
+               OpDecorate %_ Binding 0
+               OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
+               OpDecorate %_runtimearr_v4float_0 ArrayStride 16
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_runtimearr_v4float = OpTypeRuntimeArray %v4float
+      %SSBO0 = OpTypeStruct %_runtimearr_v4float
+%_ptr_Uniform_SSBO0 = OpTypePointer Uniform %SSBO0
+          %_ = OpVariable %_ptr_Uniform_SSBO0 Uniform
+        %int = OpTypeInt 32 1
+      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+%_ptr_Input_v3uint = OpTypePointer Input %v3uint
+%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
+     %uint_0 = OpConstant %uint 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+    %float_1 = OpConstant %float 1
+         %23 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+%_runtimearr_v4float_0 = OpTypeRuntimeArray %v4float
+    %float_2 = OpConstant %float 2
+         %33 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+         %20 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0
+         %21 = OpLoad %uint %20
+         %25 = OpAccessChain %_ptr_Uniform_v4float %_ %int_0 %21
+               OpStore %25 %23
+               OpReturn
+               OpFunctionEnd

+ 65 - 0
3rdparty/spirv-cross/shaders-reflection/asm/op-source-glsl-ssbo-2.asm.comp

@@ -0,0 +1,65 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 35
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
+               OpExecutionMode %main LocalSize 1 1 1
+               OpSource GLSL 450
+               OpName %main "main"
+               OpName %SSBO0 "SSBO0"
+               OpMemberName %SSBO0 0 "a"
+               OpName %_ ""
+               OpName %gl_GlobalInvocationID "gl_GlobalInvocationID"
+               OpName %SSBO1 "SSBO1"
+               OpMemberName %SSBO1 0 "b"
+               OpName %__0 ""
+               OpDecorate %_runtimearr_v4float ArrayStride 16
+               OpMemberDecorate %SSBO0 0 Offset 0
+               OpDecorate %SSBO0 BufferBlock
+               OpDecorate %_ DescriptorSet 0
+               OpDecorate %_ Binding 0
+               OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
+               OpDecorate %_runtimearr_v4float_0 ArrayStride 16
+               OpMemberDecorate %SSBO1 0 Offset 0
+               OpDecorate %SSBO1 BufferBlock
+               OpDecorate %__0 DescriptorSet 0
+               OpDecorate %__0 Binding 1
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_runtimearr_v4float = OpTypeRuntimeArray %v4float
+      %SSBO0 = OpTypeStruct %_runtimearr_v4float
+%_ptr_Uniform_SSBO0 = OpTypePointer Uniform %SSBO0
+          %_ = OpVariable %_ptr_Uniform_SSBO0 Uniform
+        %int = OpTypeInt 32 1
+      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+%_ptr_Input_v3uint = OpTypePointer Input %v3uint
+%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
+     %uint_0 = OpConstant %uint 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+    %float_1 = OpConstant %float 1
+         %23 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+%_runtimearr_v4float_0 = OpTypeRuntimeArray %v4float
+      %SSBO1 = OpTypeStruct %_runtimearr_v4float_0
+%_ptr_Uniform_SSBO1 = OpTypePointer Uniform %SSBO1
+        %__0 = OpVariable %_ptr_Uniform_SSBO1 Uniform
+    %float_2 = OpConstant %float 2
+         %33 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+         %20 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0
+         %21 = OpLoad %uint %20
+         %25 = OpAccessChain %_ptr_Uniform_v4float %_ %int_0 %21
+               OpStore %25 %23
+         %34 = OpAccessChain %_ptr_Uniform_v4float %__0 %int_0 %21
+               OpStore %34 %33
+               OpReturn
+               OpFunctionEnd

+ 48 - 0
3rdparty/spirv-cross/shaders-reflection/asm/op-source-hlsl-uav-1.asm.comp

@@ -0,0 +1,48 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 48
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %main "main" %threadId
+               OpExecutionMode %main LocalSize 1 1 1
+               OpSource HLSL 500
+               OpName %main "main"
+               OpName %UAV0 "UAV0"
+               OpMemberName %UAV0 0 "@data"
+               OpName %UAV0_0 "UAV0"
+               OpName %threadId "threadId"
+               OpDecorate %_runtimearr_v4float ArrayStride 16
+               OpMemberDecorate %UAV0 0 Offset 0
+               OpDecorate %UAV0 BufferBlock
+               OpDecorate %UAV0_0 DescriptorSet 0
+               OpDecorate %UAV0_0 Binding 0
+               OpDecorate %threadId BuiltIn GlobalInvocationId
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %v3int = OpTypeVector %int 3
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_runtimearr_v4float = OpTypeRuntimeArray %v4float
+       %UAV0 = OpTypeStruct %_runtimearr_v4float
+%_ptr_Uniform_UAV0 = OpTypePointer Uniform %UAV0
+     %UAV0_0 = OpVariable %_ptr_Uniform_UAV0 Uniform
+      %int_0 = OpConstant %int 0
+    %float_1 = OpConstant %float 1
+         %26 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+    %float_2 = OpConstant %float 2
+         %33 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
+%_ptr_Input_v3int = OpTypePointer Input %v3int
+   %threadId = OpVariable %_ptr_Input_v3int Input
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+         %38 = OpLoad %v3int %threadId
+         %43 = OpCompositeExtract %int %38 0
+         %44 = OpAccessChain %_ptr_Uniform_v4float %UAV0_0 %int_0 %43
+               OpStore %44 %26
+               OpReturn
+               OpFunctionEnd

+ 54 - 0
3rdparty/spirv-cross/shaders-reflection/asm/op-source-hlsl-uav-2.asm.comp

@@ -0,0 +1,54 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 48
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %main "main" %threadId
+               OpExecutionMode %main LocalSize 1 1 1
+               OpSource HLSL 500
+               OpName %main "main"
+               OpName %UAV0 "UAV0"
+               OpMemberName %UAV0 0 "@data"
+               OpName %UAV0_0 "UAV0"
+               OpName %UAV1 "UAV1"
+               OpName %threadId "threadId"
+               OpDecorate %_runtimearr_v4float ArrayStride 16
+               OpMemberDecorate %UAV0 0 Offset 0
+               OpDecorate %UAV0 BufferBlock
+               OpDecorate %UAV0_0 DescriptorSet 0
+               OpDecorate %UAV0_0 Binding 0
+               OpDecorate %UAV1 DescriptorSet 0
+               OpDecorate %UAV1 Binding 1
+               OpDecorate %threadId BuiltIn GlobalInvocationId
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %v3int = OpTypeVector %int 3
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_runtimearr_v4float = OpTypeRuntimeArray %v4float
+       %UAV0 = OpTypeStruct %_runtimearr_v4float
+%_ptr_Uniform_UAV0 = OpTypePointer Uniform %UAV0
+     %UAV0_0 = OpVariable %_ptr_Uniform_UAV0 Uniform
+      %int_0 = OpConstant %int 0
+    %float_1 = OpConstant %float 1
+         %26 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+       %UAV1 = OpVariable %_ptr_Uniform_UAV0 Uniform
+    %float_2 = OpConstant %float 2
+         %33 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
+%_ptr_Input_v3int = OpTypePointer Input %v3int
+   %threadId = OpVariable %_ptr_Input_v3int Input
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+         %38 = OpLoad %v3int %threadId
+         %43 = OpCompositeExtract %int %38 0
+         %44 = OpAccessChain %_ptr_Uniform_v4float %UAV0_0 %int_0 %43
+               OpStore %44 %26
+         %47 = OpAccessChain %_ptr_Uniform_v4float %UAV1 %int_0 %43
+               OpStore %47 %33
+               OpReturn
+               OpFunctionEnd

+ 52 - 0
3rdparty/spirv-cross/shaders-reflection/asm/op-source-none-ssbo-1.asm.comp

@@ -0,0 +1,52 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 35
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID %_
+               OpExecutionMode %main LocalSize 1 1 1
+               OpName %main "main"
+               OpName %SSBO0 "SSBO0"
+               OpMemberName %SSBO0 0 "a"
+               OpName %_ ""
+               OpName %gl_GlobalInvocationID "gl_GlobalInvocationID"
+               OpDecorate %_runtimearr_v4float ArrayStride 16
+               OpMemberDecorate %SSBO0 0 Offset 0
+               OpDecorate %SSBO0 BufferBlock
+               OpDecorate %_ DescriptorSet 0
+               OpDecorate %_ Binding 0
+               OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
+               OpDecorate %_runtimearr_v4float_0 ArrayStride 16
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_runtimearr_v4float = OpTypeRuntimeArray %v4float
+      %SSBO0 = OpTypeStruct %_runtimearr_v4float
+%_ptr_Uniform_SSBO0 = OpTypePointer Uniform %SSBO0
+          %_ = OpVariable %_ptr_Uniform_SSBO0 Uniform
+        %int = OpTypeInt 32 1
+      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+%_ptr_Input_v3uint = OpTypePointer Input %v3uint
+%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
+     %uint_0 = OpConstant %uint 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+    %float_1 = OpConstant %float 1
+         %23 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+%_runtimearr_v4float_0 = OpTypeRuntimeArray %v4float
+    %float_2 = OpConstant %float 2
+         %33 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+         %20 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0
+         %21 = OpLoad %uint %20
+         %25 = OpAccessChain %_ptr_Uniform_v4float %_ %int_0 %21
+               OpStore %25 %23
+               OpReturn
+               OpFunctionEnd

+ 64 - 0
3rdparty/spirv-cross/shaders-reflection/asm/op-source-none-ssbo-2.asm.comp

@@ -0,0 +1,64 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 35
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
+               OpExecutionMode %main LocalSize 1 1 1
+               OpName %main "main"
+               OpName %SSBO0 "SSBO0"
+               OpMemberName %SSBO0 0 "a"
+               OpName %_ ""
+               OpName %gl_GlobalInvocationID "gl_GlobalInvocationID"
+               OpName %SSBO1 "SSBO1"
+               OpMemberName %SSBO1 0 "b"
+               OpName %__0 ""
+               OpDecorate %_runtimearr_v4float ArrayStride 16
+               OpMemberDecorate %SSBO0 0 Offset 0
+               OpDecorate %SSBO0 BufferBlock
+               OpDecorate %_ DescriptorSet 0
+               OpDecorate %_ Binding 0
+               OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
+               OpDecorate %_runtimearr_v4float_0 ArrayStride 16
+               OpMemberDecorate %SSBO1 0 Offset 0
+               OpDecorate %SSBO1 BufferBlock
+               OpDecorate %__0 DescriptorSet 0
+               OpDecorate %__0 Binding 1
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_runtimearr_v4float = OpTypeRuntimeArray %v4float
+      %SSBO0 = OpTypeStruct %_runtimearr_v4float
+%_ptr_Uniform_SSBO0 = OpTypePointer Uniform %SSBO0
+          %_ = OpVariable %_ptr_Uniform_SSBO0 Uniform
+        %int = OpTypeInt 32 1
+      %int_0 = OpConstant %int 0
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+%_ptr_Input_v3uint = OpTypePointer Input %v3uint
+%gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
+     %uint_0 = OpConstant %uint 0
+%_ptr_Input_uint = OpTypePointer Input %uint
+    %float_1 = OpConstant %float 1
+         %23 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+%_runtimearr_v4float_0 = OpTypeRuntimeArray %v4float
+      %SSBO1 = OpTypeStruct %_runtimearr_v4float_0
+%_ptr_Uniform_SSBO1 = OpTypePointer Uniform %SSBO1
+        %__0 = OpVariable %_ptr_Uniform_SSBO1 Uniform
+    %float_2 = OpConstant %float 2
+         %33 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+         %20 = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0
+         %21 = OpLoad %uint %20
+         %25 = OpAccessChain %_ptr_Uniform_v4float %_ %int_0 %21
+               OpStore %25 %23
+         %34 = OpAccessChain %_ptr_Uniform_v4float %__0 %int_0 %21
+               OpStore %34 %33
+               OpReturn
+               OpFunctionEnd

+ 47 - 0
3rdparty/spirv-cross/shaders-reflection/asm/op-source-none-uav-1.asm.comp

@@ -0,0 +1,47 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 48
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %main "main" %threadId
+               OpExecutionMode %main LocalSize 1 1 1
+               OpName %main "main"
+               OpName %UAV0 "UAV0"
+               OpMemberName %UAV0 0 "@data"
+               OpName %UAV0_0 "UAV0"
+               OpName %threadId "threadId"
+               OpDecorate %_runtimearr_v4float ArrayStride 16
+               OpMemberDecorate %UAV0 0 Offset 0
+               OpDecorate %UAV0 BufferBlock
+               OpDecorate %UAV0_0 DescriptorSet 0
+               OpDecorate %UAV0_0 Binding 0
+               OpDecorate %threadId BuiltIn GlobalInvocationId
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %v3int = OpTypeVector %int 3
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_runtimearr_v4float = OpTypeRuntimeArray %v4float
+       %UAV0 = OpTypeStruct %_runtimearr_v4float
+%_ptr_Uniform_UAV0 = OpTypePointer Uniform %UAV0
+     %UAV0_0 = OpVariable %_ptr_Uniform_UAV0 Uniform
+      %int_0 = OpConstant %int 0
+    %float_1 = OpConstant %float 1
+         %26 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+    %float_2 = OpConstant %float 2
+         %33 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
+%_ptr_Input_v3int = OpTypePointer Input %v3int
+   %threadId = OpVariable %_ptr_Input_v3int Input
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+         %38 = OpLoad %v3int %threadId
+         %43 = OpCompositeExtract %int %38 0
+         %44 = OpAccessChain %_ptr_Uniform_v4float %UAV0_0 %int_0 %43
+               OpStore %44 %26
+               OpReturn
+               OpFunctionEnd

+ 53 - 0
3rdparty/spirv-cross/shaders-reflection/asm/op-source-none-uav-2.asm.comp

@@ -0,0 +1,53 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 48
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %main "main" %threadId
+               OpExecutionMode %main LocalSize 1 1 1
+               OpName %main "main"
+               OpName %UAV0 "UAV0"
+               OpMemberName %UAV0 0 "@data"
+               OpName %UAV0_0 "UAV0"
+               OpName %UAV1 "UAV1"
+               OpName %threadId "threadId"
+               OpDecorate %_runtimearr_v4float ArrayStride 16
+               OpMemberDecorate %UAV0 0 Offset 0
+               OpDecorate %UAV0 BufferBlock
+               OpDecorate %UAV0_0 DescriptorSet 0
+               OpDecorate %UAV0_0 Binding 0
+               OpDecorate %UAV1 DescriptorSet 0
+               OpDecorate %UAV1 Binding 1
+               OpDecorate %threadId BuiltIn GlobalInvocationId
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %v3int = OpTypeVector %int 3
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%_runtimearr_v4float = OpTypeRuntimeArray %v4float
+       %UAV0 = OpTypeStruct %_runtimearr_v4float
+%_ptr_Uniform_UAV0 = OpTypePointer Uniform %UAV0
+     %UAV0_0 = OpVariable %_ptr_Uniform_UAV0 Uniform
+      %int_0 = OpConstant %int 0
+    %float_1 = OpConstant %float 1
+         %26 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+       %UAV1 = OpVariable %_ptr_Uniform_UAV0 Uniform
+    %float_2 = OpConstant %float 2
+         %33 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2
+%_ptr_Input_v3int = OpTypePointer Input %v3int
+   %threadId = OpVariable %_ptr_Input_v3int Input
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+         %38 = OpLoad %v3int %threadId
+         %43 = OpCompositeExtract %int %38 0
+         %44 = OpAccessChain %_ptr_Uniform_v4float %UAV0_0 %int_0 %43
+               OpStore %44 %26
+         %47 = OpAccessChain %_ptr_Uniform_v4float %UAV1 %int_0 %43
+               OpStore %47 %33
+               OpReturn
+               OpFunctionEnd

+ 11 - 0
3rdparty/spirv-cross/shaders/desktop-only/frag/stencil-export.desktop.frag

@@ -0,0 +1,11 @@
+#version 450
+#extension GL_ARB_shader_stencil_export : require
+
+layout(location = 0) out vec4 MRT0;
+layout(location = 1) out vec4 MRT1;
+void main()
+{
+	MRT0 = vec4(1.0);
+	MRT1 = vec4(1.0, 0.0, 1.0, 1.0);
+	gl_FragStencilRefARB = 100;
+}

+ 60 - 9
3rdparty/spirv-cross/spirv_cross.cpp

@@ -755,6 +755,8 @@ ShaderResources Compiler::get_shader_resources(const unordered_set<uint32_t> *ac
 {
 {
 	ShaderResources res;
 	ShaderResources res;
 
 
+	bool ssbo_instance_name = reflection_ssbo_instance_name_is_significant();
+
 	ir.for_each_typed_id<SPIRVariable>([&](uint32_t, const SPIRVariable &var) {
 	ir.for_each_typed_id<SPIRVariable>([&](uint32_t, const SPIRVariable &var) {
 		auto &type = this->get<SPIRType>(var.basetype);
 		auto &type = this->get<SPIRType>(var.basetype);
 
 
@@ -772,7 +774,7 @@ ShaderResources Compiler::get_shader_resources(const unordered_set<uint32_t> *ac
 			if (has_decoration(type.self, DecorationBlock))
 			if (has_decoration(type.self, DecorationBlock))
 			{
 			{
 				res.stage_inputs.push_back(
 				res.stage_inputs.push_back(
-				    { var.self, var.basetype, type.self, get_remapped_declared_block_name(var.self) });
+				    { var.self, var.basetype, type.self, get_remapped_declared_block_name(var.self, false) });
 			}
 			}
 			else
 			else
 				res.stage_inputs.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
 				res.stage_inputs.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
@@ -788,7 +790,7 @@ ShaderResources Compiler::get_shader_resources(const unordered_set<uint32_t> *ac
 			if (has_decoration(type.self, DecorationBlock))
 			if (has_decoration(type.self, DecorationBlock))
 			{
 			{
 				res.stage_outputs.push_back(
 				res.stage_outputs.push_back(
-				    { var.self, var.basetype, type.self, get_remapped_declared_block_name(var.self) });
+				    { var.self, var.basetype, type.self, get_remapped_declared_block_name(var.self, false) });
 			}
 			}
 			else
 			else
 				res.stage_outputs.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
 				res.stage_outputs.push_back({ var.self, var.basetype, type.self, get_name(var.self) });
@@ -797,19 +799,19 @@ ShaderResources Compiler::get_shader_resources(const unordered_set<uint32_t> *ac
 		else if (type.storage == StorageClassUniform && has_decoration(type.self, DecorationBlock))
 		else if (type.storage == StorageClassUniform && has_decoration(type.self, DecorationBlock))
 		{
 		{
 			res.uniform_buffers.push_back(
 			res.uniform_buffers.push_back(
-			    { var.self, var.basetype, type.self, get_remapped_declared_block_name(var.self) });
+			    { var.self, var.basetype, type.self, get_remapped_declared_block_name(var.self, false) });
 		}
 		}
 		// Old way to declare SSBOs.
 		// Old way to declare SSBOs.
 		else if (type.storage == StorageClassUniform && has_decoration(type.self, DecorationBufferBlock))
 		else if (type.storage == StorageClassUniform && has_decoration(type.self, DecorationBufferBlock))
 		{
 		{
 			res.storage_buffers.push_back(
 			res.storage_buffers.push_back(
-			    { var.self, var.basetype, type.self, get_remapped_declared_block_name(var.self) });
+			    { var.self, var.basetype, type.self, get_remapped_declared_block_name(var.self, ssbo_instance_name) });
 		}
 		}
 		// Modern way to declare SSBOs.
 		// Modern way to declare SSBOs.
 		else if (type.storage == StorageClassStorageBuffer)
 		else if (type.storage == StorageClassStorageBuffer)
 		{
 		{
 			res.storage_buffers.push_back(
 			res.storage_buffers.push_back(
-			    { var.self, var.basetype, type.self, get_remapped_declared_block_name(var.self) });
+			    { var.self, var.basetype, type.self, get_remapped_declared_block_name(var.self, ssbo_instance_name) });
 		}
 		}
 		// Push constant blocks
 		// Push constant blocks
 		else if (type.storage == StorageClassPushConstant)
 		else if (type.storage == StorageClassPushConstant)
@@ -4139,19 +4141,68 @@ const SmallVector<std::string> &Compiler::get_declared_extensions() const
 }
 }
 
 
 std::string Compiler::get_remapped_declared_block_name(uint32_t id) const
 std::string Compiler::get_remapped_declared_block_name(uint32_t id) const
+{
+	return get_remapped_declared_block_name(id, false);
+}
+
+std::string Compiler::get_remapped_declared_block_name(uint32_t id, bool fallback_prefer_instance_name) const
 {
 {
 	auto itr = declared_block_names.find(id);
 	auto itr = declared_block_names.find(id);
 	if (itr != end(declared_block_names))
 	if (itr != end(declared_block_names))
+	{
 		return itr->second;
 		return itr->second;
+	}
 	else
 	else
 	{
 	{
 		auto &var = get<SPIRVariable>(id);
 		auto &var = get<SPIRVariable>(id);
-		auto &type = get<SPIRType>(var.basetype);
 
 
-		auto *type_meta = ir.find_meta(type.self);
-		auto *block_name = type_meta ? &type_meta->decoration.alias : nullptr;
-		return (!block_name || block_name->empty()) ? get_block_fallback_name(id) : *block_name;
+		if (fallback_prefer_instance_name)
+		{
+			return to_name(var.self);
+		}
+		else
+		{
+			auto &type = get<SPIRType>(var.basetype);
+			auto *type_meta = ir.find_meta(type.self);
+			auto *block_name = type_meta ? &type_meta->decoration.alias : nullptr;
+			return (!block_name || block_name->empty()) ? get_block_fallback_name(id) : *block_name;
+		}
+	}
+}
+
+bool Compiler::reflection_ssbo_instance_name_is_significant() const
+{
+	if (ir.source.known)
+	{
+		// UAVs from HLSL source tend to be declared in a way where the type is reused
+		// but the instance name is significant, and that's the name we should report.
+		// For GLSL, SSBOs each have their own block type as that's how GLSL is written.
+		return ir.source.hlsl;
 	}
 	}
+
+	unordered_set<uint32_t> ssbo_type_ids;
+	bool aliased_ssbo_types = false;
+
+	// If we don't have any OpSource information, we need to perform some shaky heuristics.
+	ir.for_each_typed_id<SPIRVariable>([&](uint32_t, const SPIRVariable &var) {
+		auto &type = this->get<SPIRType>(var.basetype);
+		if (!type.pointer || var.storage == StorageClassFunction)
+			return;
+
+		bool ssbo = var.storage == StorageClassStorageBuffer ||
+		            (var.storage == StorageClassUniform && has_decoration(type.self, DecorationBufferBlock));
+
+		if (ssbo)
+		{
+			if (ssbo_type_ids.count(type.self))
+				aliased_ssbo_types = true;
+			else
+				ssbo_type_ids.insert(type.self);
+		}
+	});
+
+	// If the block name is aliased, assume we have HLSL-style UAV declarations.
+	return aliased_ssbo_types;
 }
 }
 
 
 bool Compiler::instruction_to_result_type(uint32_t &result_type, uint32_t &result_id, spv::Op op, const uint32_t *args,
 bool Compiler::instruction_to_result_type(uint32_t &result_type, uint32_t &result_id, spv::Op op, const uint32_t *args,

+ 3 - 0
3rdparty/spirv-cross/spirv_cross.hpp

@@ -976,6 +976,9 @@ protected:
 	bool type_is_block_like(const SPIRType &type) const;
 	bool type_is_block_like(const SPIRType &type) const;
 	bool type_is_opaque_value(const SPIRType &type) const;
 	bool type_is_opaque_value(const SPIRType &type) const;
 
 
+	bool reflection_ssbo_instance_name_is_significant() const;
+	std::string get_remapped_declared_block_name(uint32_t id, bool fallback_prefer_instance_name) const;
+
 private:
 private:
 	// Used only to implement the old deprecated get_entry_point() interface.
 	// Used only to implement the old deprecated get_entry_point() interface.
 	const SPIREntryPoint &get_first_entry_point(const std::string &name) const;
 	const SPIREntryPoint &get_first_entry_point(const std::string &name) const;

+ 43 - 11
3rdparty/spirv-cross/spirv_cross_c.cpp

@@ -941,18 +941,9 @@ spvc_bool spvc_compiler_msl_is_resource_used(spvc_compiler compiler, SpvExecutio
 #endif
 #endif
 }
 }
 
 
-spvc_result spvc_compiler_msl_remap_constexpr_sampler(spvc_compiler compiler, spvc_variable_id id,
-                                                      const spvc_msl_constexpr_sampler *sampler)
-{
 #if SPIRV_CROSS_C_API_MSL
 #if SPIRV_CROSS_C_API_MSL
-	if (compiler->backend != SPVC_BACKEND_MSL)
-	{
-		compiler->context->report_error("MSL function used on a non-MSL backend.");
-		return SPVC_ERROR_INVALID_ARGUMENT;
-	}
-
-	auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
-	MSLConstexprSampler samp;
+static void spvc_convert_msl_sampler(MSLConstexprSampler &samp, const spvc_msl_constexpr_sampler *sampler)
+{
 	samp.s_address = static_cast<MSLSamplerAddress>(sampler->s_address);
 	samp.s_address = static_cast<MSLSamplerAddress>(sampler->s_address);
 	samp.t_address = static_cast<MSLSamplerAddress>(sampler->t_address);
 	samp.t_address = static_cast<MSLSamplerAddress>(sampler->t_address);
 	samp.r_address = static_cast<MSLSamplerAddress>(sampler->r_address);
 	samp.r_address = static_cast<MSLSamplerAddress>(sampler->r_address);
@@ -968,6 +959,22 @@ spvc_result spvc_compiler_msl_remap_constexpr_sampler(spvc_compiler compiler, sp
 	samp.compare_func = static_cast<MSLSamplerCompareFunc>(sampler->compare_func);
 	samp.compare_func = static_cast<MSLSamplerCompareFunc>(sampler->compare_func);
 	samp.coord = static_cast<MSLSamplerCoord>(sampler->coord);
 	samp.coord = static_cast<MSLSamplerCoord>(sampler->coord);
 	samp.border_color = static_cast<MSLSamplerBorderColor>(sampler->border_color);
 	samp.border_color = static_cast<MSLSamplerBorderColor>(sampler->border_color);
+}
+#endif
+
+spvc_result spvc_compiler_msl_remap_constexpr_sampler(spvc_compiler compiler, spvc_variable_id id,
+                                                      const spvc_msl_constexpr_sampler *sampler)
+{
+#if SPIRV_CROSS_C_API_MSL
+	if (compiler->backend != SPVC_BACKEND_MSL)
+	{
+		compiler->context->report_error("MSL function used on a non-MSL backend.");
+		return SPVC_ERROR_INVALID_ARGUMENT;
+	}
+
+	auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
+	MSLConstexprSampler samp;
+	spvc_convert_msl_sampler(samp, sampler);
 	msl.remap_constexpr_sampler(id, samp);
 	msl.remap_constexpr_sampler(id, samp);
 	return SPVC_SUCCESS;
 	return SPVC_SUCCESS;
 #else
 #else
@@ -978,6 +985,31 @@ spvc_result spvc_compiler_msl_remap_constexpr_sampler(spvc_compiler compiler, sp
 #endif
 #endif
 }
 }
 
 
+spvc_result spvc_compiler_msl_remap_constexpr_sampler_by_binding(spvc_compiler compiler,
+                                                                 unsigned desc_set, unsigned binding,
+                                                                 const spvc_msl_constexpr_sampler *sampler)
+{
+#if SPIRV_CROSS_C_API_MSL
+	if (compiler->backend != SPVC_BACKEND_MSL)
+	{
+		compiler->context->report_error("MSL function used on a non-MSL backend.");
+		return SPVC_ERROR_INVALID_ARGUMENT;
+	}
+
+	auto &msl = *static_cast<CompilerMSL *>(compiler->compiler.get());
+	MSLConstexprSampler samp;
+	spvc_convert_msl_sampler(samp, sampler);
+	msl.remap_constexpr_sampler_by_binding(desc_set, binding, samp);
+	return SPVC_SUCCESS;
+#else
+	(void)desc_set;
+	(void)binding;
+	(void)sampler;
+	compiler->context->report_error("MSL function used on a non-MSL backend.");
+	return SPVC_ERROR_INVALID_ARGUMENT;
+#endif
+}
+
 spvc_result spvc_compiler_msl_set_fragment_output_components(spvc_compiler compiler, unsigned location,
 spvc_result spvc_compiler_msl_set_fragment_output_components(spvc_compiler compiler, unsigned location,
                                                              unsigned components)
                                                              unsigned components)
 {
 {

+ 2 - 1
3rdparty/spirv-cross/spirv_cross_c.h

@@ -33,7 +33,7 @@ extern "C" {
 /* Bumped if ABI or API breaks backwards compatibility. */
 /* Bumped if ABI or API breaks backwards compatibility. */
 #define SPVC_C_API_VERSION_MAJOR 0
 #define SPVC_C_API_VERSION_MAJOR 0
 /* Bumped if APIs or enumerations are added in a backwards compatible way. */
 /* Bumped if APIs or enumerations are added in a backwards compatible way. */
-#define SPVC_C_API_VERSION_MINOR 12
+#define SPVC_C_API_VERSION_MINOR 13
 /* Bumped if internal implementation details change. */
 /* Bumped if internal implementation details change. */
 #define SPVC_C_API_VERSION_PATCH 0
 #define SPVC_C_API_VERSION_PATCH 0
 
 
@@ -548,6 +548,7 @@ SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_is_resource_used(spvc_compiler compi
                                                              unsigned set,
                                                              unsigned set,
                                                              unsigned binding);
                                                              unsigned binding);
 SPVC_PUBLIC_API spvc_result spvc_compiler_msl_remap_constexpr_sampler(spvc_compiler compiler, spvc_variable_id id, const spvc_msl_constexpr_sampler *sampler);
 SPVC_PUBLIC_API spvc_result spvc_compiler_msl_remap_constexpr_sampler(spvc_compiler compiler, spvc_variable_id id, const spvc_msl_constexpr_sampler *sampler);
+SPVC_PUBLIC_API spvc_result spvc_compiler_msl_remap_constexpr_sampler_by_binding(spvc_compiler compiler, unsigned desc_set, unsigned binding, const spvc_msl_constexpr_sampler *sampler);
 SPVC_PUBLIC_API spvc_result spvc_compiler_msl_set_fragment_output_components(spvc_compiler compiler, unsigned location, unsigned components);
 SPVC_PUBLIC_API spvc_result spvc_compiler_msl_set_fragment_output_components(spvc_compiler compiler, unsigned location, unsigned components);
 
 
 /*
 /*

+ 21 - 0
3rdparty/spirv-cross/spirv_glsl.cpp

@@ -6156,6 +6156,17 @@ string CompilerGLSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage)
 	case BuiltInIncomingRayFlagsNV:
 	case BuiltInIncomingRayFlagsNV:
 		return "gl_IncomingRayFlagsNV";
 		return "gl_IncomingRayFlagsNV";
 
 
+	case BuiltInFragStencilRefEXT:
+	{
+		if (!options.es)
+		{
+			require_extension_internal("GL_ARB_shader_stencil_export");
+			return "gl_FragStencilRefARB";
+		}
+		else
+			SPIRV_CROSS_THROW("Stencil export not supported in GLES.");
+	}
+
 	default:
 	default:
 		return join("gl_BuiltIn_", convert_to_string(builtin));
 		return join("gl_BuiltIn_", convert_to_string(builtin));
 	}
 	}
@@ -10649,6 +10660,14 @@ void CompilerGLSL::emit_function(SPIRFunction &func, const Bitset &return_flags)
 	end_scope();
 	end_scope();
 	processing_entry_point = false;
 	processing_entry_point = false;
 	statement("");
 	statement("");
+
+	// Make sure deferred declaration state for local variables is cleared when we are done with function.
+	// We risk declaring Private/Workgroup variables in places we are not supposed to otherwise.
+	for (auto &v : func.local_variables)
+	{
+		auto &var = get<SPIRVariable>(v);
+		var.deferred_declaration = false;
+	}
 }
 }
 
 
 void CompilerGLSL::emit_fixup()
 void CompilerGLSL::emit_fixup()
@@ -11825,6 +11844,7 @@ void CompilerGLSL::bitcast_from_builtin_load(uint32_t source_id, std::string &ex
 	case BuiltInBaseVertex:
 	case BuiltInBaseVertex:
 	case BuiltInBaseInstance:
 	case BuiltInBaseInstance:
 	case BuiltInDrawIndex:
 	case BuiltInDrawIndex:
+	case BuiltInFragStencilRefEXT:
 		expected_type = SPIRType::Int;
 		expected_type = SPIRType::Int;
 		break;
 		break;
 
 
@@ -11860,6 +11880,7 @@ void CompilerGLSL::bitcast_to_builtin_store(uint32_t target_id, std::string &exp
 	case BuiltInLayer:
 	case BuiltInLayer:
 	case BuiltInPrimitiveId:
 	case BuiltInPrimitiveId:
 	case BuiltInViewportIndex:
 	case BuiltInViewportIndex:
+	case BuiltInFragStencilRefEXT:
 		expected_type = SPIRType::Int;
 		expected_type = SPIRType::Int;
 		break;
 		break;
 
 

+ 121 - 27
3rdparty/spirv-cross/spirv_msl.cpp

@@ -57,7 +57,8 @@ void CompilerMSL::add_msl_vertex_attribute(const MSLVertexAttr &va)
 
 
 void CompilerMSL::add_msl_resource_binding(const MSLResourceBinding &binding)
 void CompilerMSL::add_msl_resource_binding(const MSLResourceBinding &binding)
 {
 {
-	resource_bindings.push_back({ binding, false });
+	StageSetBinding tuple = { binding.stage, binding.desc_set, binding.binding };
+	resource_bindings[tuple] = { binding, false };
 }
 }
 
 
 void CompilerMSL::add_discrete_descriptor_set(uint32_t desc_set)
 void CompilerMSL::add_discrete_descriptor_set(uint32_t desc_set)
@@ -73,12 +74,9 @@ bool CompilerMSL::is_msl_vertex_attribute_used(uint32_t location)
 
 
 bool CompilerMSL::is_msl_resource_binding_used(ExecutionModel model, uint32_t desc_set, uint32_t binding)
 bool CompilerMSL::is_msl_resource_binding_used(ExecutionModel model, uint32_t desc_set, uint32_t binding)
 {
 {
-	auto itr = find_if(begin(resource_bindings), end(resource_bindings),
-	                   [&](const std::pair<MSLResourceBinding, bool> &resource) -> bool {
-		                   return model == resource.first.stage && desc_set == resource.first.desc_set &&
-		                          binding == resource.first.binding;
-	                   });
-	return itr != end(resource_bindings) && itr->second;
+	StageSetBinding tuple = { model, desc_set, binding };
+	auto itr = resource_bindings.find(tuple);
+	return itr != end(resource_bindings) && itr->second.second;
 }
 }
 
 
 void CompilerMSL::set_fragment_output_components(uint32_t location, uint32_t components)
 void CompilerMSL::set_fragment_output_components(uint32_t location, uint32_t components)
@@ -528,7 +526,7 @@ void CompilerMSL::emit_entry_point_declarations()
 	// FIXME: Get test coverage here ...
 	// FIXME: Get test coverage here ...
 
 
 	// Emit constexpr samplers here.
 	// Emit constexpr samplers here.
-	for (auto &samp : constexpr_samplers)
+	for (auto &samp : constexpr_samplers_by_id)
 	{
 	{
 		auto &var = get<SPIRVariable>(samp.first);
 		auto &var = get<SPIRVariable>(samp.first);
 		auto &type = get<SPIRType>(var.basetype);
 		auto &type = get<SPIRType>(var.basetype);
@@ -1958,7 +1956,7 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch)
 		bool is_interface_block_builtin =
 		bool is_interface_block_builtin =
 		    (bi_type == BuiltInPosition || bi_type == BuiltInPointSize || bi_type == BuiltInClipDistance ||
 		    (bi_type == BuiltInPosition || bi_type == BuiltInPointSize || bi_type == BuiltInClipDistance ||
 		     bi_type == BuiltInCullDistance || bi_type == BuiltInLayer || bi_type == BuiltInViewportIndex ||
 		     bi_type == BuiltInCullDistance || bi_type == BuiltInLayer || bi_type == BuiltInViewportIndex ||
-		     bi_type == BuiltInFragDepth || bi_type == BuiltInSampleMask) ||
+		     bi_type == BuiltInFragDepth || bi_type == BuiltInFragStencilRefEXT || bi_type == BuiltInSampleMask) ||
 		    (get_execution_model() == ExecutionModelTessellationEvaluation &&
 		    (get_execution_model() == ExecutionModelTessellationEvaluation &&
 		     (bi_type == BuiltInTessLevelOuter || bi_type == BuiltInTessLevelInner));
 		     (bi_type == BuiltInTessLevelOuter || bi_type == BuiltInTessLevelInner));
 
 
@@ -2092,7 +2090,7 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch)
 	set_name(ib_type_id, to_name(ir.default_entry_point) + "_" + ib_var_ref);
 	set_name(ib_type_id, to_name(ir.default_entry_point) + "_" + ib_var_ref);
 	set_name(ib_var_id, ib_var_ref);
 	set_name(ib_var_id, ib_var_ref);
 
 
-	for (auto p_var : vars)
+	for (auto *p_var : vars)
 	{
 	{
 		bool strip_array =
 		bool strip_array =
 		    (get_execution_model() == ExecutionModelTessellationControl ||
 		    (get_execution_model() == ExecutionModelTessellationControl ||
@@ -2190,7 +2188,8 @@ uint32_t CompilerMSL::ensure_correct_builtin_type(uint32_t type_id, BuiltIn buil
 	auto &type = get<SPIRType>(type_id);
 	auto &type = get<SPIRType>(type_id);
 
 
 	if ((builtin == BuiltInSampleMask && is_array(type)) ||
 	if ((builtin == BuiltInSampleMask && is_array(type)) ||
-	    ((builtin == BuiltInLayer || builtin == BuiltInViewportIndex) && type.basetype != SPIRType::UInt))
+	    ((builtin == BuiltInLayer || builtin == BuiltInViewportIndex || builtin == BuiltInFragStencilRefEXT) &&
+	     type.basetype != SPIRType::UInt))
 	{
 	{
 		uint32_t next_id = ir.increase_bound_by(type.pointer ? 2 : 1);
 		uint32_t next_id = ir.increase_bound_by(type.pointer ? 2 : 1);
 		uint32_t base_type_id = next_id++;
 		uint32_t base_type_id = next_id++;
@@ -5634,6 +5633,11 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
 		{
 		{
 			switch (builtin)
 			switch (builtin)
 			{
 			{
+			case BuiltInFragStencilRefEXT:
+				if (!msl_options.supports_msl_version(2, 1))
+					SPIRV_CROSS_THROW("Stencil export only supported in MSL 2.1 and up.");
+				return string(" [[") + builtin_qualifier(builtin) + "]]";
+
 			case BuiltInSampleMask:
 			case BuiltInSampleMask:
 			case BuiltInFragDepth:
 			case BuiltInFragDepth:
 				return string(" [[") + builtin_qualifier(builtin) + "]]";
 				return string(" [[") + builtin_qualifier(builtin) + "]]";
@@ -6034,6 +6038,28 @@ string CompilerMSL::entry_point_args_argument_buffer(bool append_comma)
 	return ep_args;
 	return ep_args;
 }
 }
 
 
+const MSLConstexprSampler *CompilerMSL::find_constexpr_sampler(uint32_t id) const
+{
+	// Try by ID.
+	{
+		auto itr = constexpr_samplers_by_id.find(id);
+		if (itr != end(constexpr_samplers_by_id))
+			return &itr->second;
+	}
+
+	// Try by binding.
+	{
+		uint32_t desc_set = get_decoration(id, DecorationDescriptorSet);
+		uint32_t binding = get_decoration(id, DecorationBinding);
+
+		auto itr = constexpr_samplers_by_binding.find({ desc_set, binding });
+		if (itr != end(constexpr_samplers_by_binding))
+			return &itr->second;
+	}
+
+	return nullptr;
+}
+
 void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args)
 void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args)
 {
 {
 	// Output resources, sorted by resource index & type
 	// Output resources, sorted by resource index & type
@@ -6064,19 +6090,30 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args)
 					return;
 					return;
 			}
 			}
 
 
+			const MSLConstexprSampler *constexpr_sampler = nullptr;
+			if (type.basetype == SPIRType::SampledImage || type.basetype == SPIRType::Sampler)
+			{
+				constexpr_sampler = find_constexpr_sampler(var_id);
+				if (constexpr_sampler)
+				{
+					// Mark this ID as a constexpr sampler for later in case it came from set/bindings.
+					constexpr_samplers_by_id[var_id] = *constexpr_sampler;
+				}
+			}
+
 			if (type.basetype == SPIRType::SampledImage)
 			if (type.basetype == SPIRType::SampledImage)
 			{
 			{
 				add_resource_name(var_id);
 				add_resource_name(var_id);
 				resources.push_back(
 				resources.push_back(
 				    { &var, to_name(var_id), SPIRType::Image, get_metal_resource_index(var, SPIRType::Image) });
 				    { &var, to_name(var_id), SPIRType::Image, get_metal_resource_index(var, SPIRType::Image) });
 
 
-				if (type.image.dim != DimBuffer && constexpr_samplers.count(var_id) == 0)
+				if (type.image.dim != DimBuffer && !constexpr_sampler)
 				{
 				{
 					resources.push_back({ &var, to_sampler_expression(var_id), SPIRType::Sampler,
 					resources.push_back({ &var, to_sampler_expression(var_id), SPIRType::Sampler,
 					                      get_metal_resource_index(var, SPIRType::Sampler) });
 					                      get_metal_resource_index(var, SPIRType::Sampler) });
 				}
 				}
 			}
 			}
-			else if (constexpr_samplers.count(var_id) == 0)
+			else if (!constexpr_sampler)
 			{
 			{
 				// constexpr samplers are not declared as resources.
 				// constexpr samplers are not declared as resources.
 				add_resource_name(var_id);
 				add_resource_name(var_id);
@@ -6384,24 +6421,21 @@ uint32_t CompilerMSL::get_metal_resource_index(SPIRVariable &var, SPIRType::Base
 	uint32_t var_desc_set = (var.storage == StorageClassPushConstant) ? kPushConstDescSet : var_dec.set;
 	uint32_t var_desc_set = (var.storage == StorageClassPushConstant) ? kPushConstDescSet : var_dec.set;
 	uint32_t var_binding = (var.storage == StorageClassPushConstant) ? kPushConstBinding : var_dec.binding;
 	uint32_t var_binding = (var.storage == StorageClassPushConstant) ? kPushConstBinding : var_dec.binding;
 
 
-	// If a matching binding has been specified, find and use it
-	auto itr = find_if(begin(resource_bindings), end(resource_bindings),
-	                   [&](const pair<MSLResourceBinding, bool> &resource) -> bool {
-		                   return var_desc_set == resource.first.desc_set && var_binding == resource.first.binding &&
-		                          execution.model == resource.first.stage;
-	                   });
+	// If a matching binding has been specified, find and use it.
+	auto itr = resource_bindings.find({ execution.model, var_desc_set, var_binding });
 
 
 	if (itr != end(resource_bindings))
 	if (itr != end(resource_bindings))
 	{
 	{
-		itr->second = true;
+		auto &remap = itr->second;
+		remap.second = true;
 		switch (basetype)
 		switch (basetype)
 		{
 		{
 		case SPIRType::Image:
 		case SPIRType::Image:
-			return itr->first.msl_texture;
+			return remap.first.msl_texture;
 		case SPIRType::Sampler:
 		case SPIRType::Sampler:
-			return itr->first.msl_sampler;
+			return remap.first.msl_sampler;
 		default:
 		default:
-			return itr->first.msl_buffer;
+			return remap.first.msl_buffer;
 		}
 		}
 	}
 	}
 
 
@@ -7498,6 +7532,7 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage)
 	case BuiltInCullDistance:
 	case BuiltInCullDistance:
 	case BuiltInLayer:
 	case BuiltInLayer:
 	case BuiltInFragDepth:
 	case BuiltInFragDepth:
+	case BuiltInFragStencilRefEXT:
 	case BuiltInSampleMask:
 	case BuiltInSampleMask:
 		if (get_execution_model() == ExecutionModelTessellationControl)
 		if (get_execution_model() == ExecutionModelTessellationControl)
 			break;
 			break;
@@ -7570,7 +7605,14 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin)
 	case BuiltInPointSize:
 	case BuiltInPointSize:
 		return "point_size";
 		return "point_size";
 	case BuiltInPosition:
 	case BuiltInPosition:
-		return "position";
+		if (position_invariant)
+		{
+			if (!msl_options.supports_msl_version(2, 1))
+				SPIRV_CROSS_THROW("Invariant position is only supported on MSL 2.1 and up.");
+			return "position, invariant";
+		}
+		else
+			return "position";
 	case BuiltInLayer:
 	case BuiltInLayer:
 		return "render_target_array_index";
 		return "render_target_array_index";
 	case BuiltInViewportIndex:
 	case BuiltInViewportIndex:
@@ -7629,6 +7671,9 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin)
 		else
 		else
 			return "depth(any)";
 			return "depth(any)";
 
 
+	case BuiltInFragStencilRefEXT:
+		return "stencil";
+
 	// Compute function in
 	// Compute function in
 	case BuiltInGlobalInvocationId:
 	case BuiltInGlobalInvocationId:
 		return "thread_position_in_grid";
 		return "thread_position_in_grid";
@@ -7752,6 +7797,9 @@ string CompilerMSL::builtin_type_decl(BuiltIn builtin)
 	case BuiltInFragDepth:
 	case BuiltInFragDepth:
 		return "float";
 		return "float";
 
 
+	case BuiltInFragStencilRefEXT:
+		return "uint";
+
 	// Compute function in
 	// Compute function in
 	case BuiltInGlobalInvocationId:
 	case BuiltInGlobalInvocationId:
 	case BuiltInLocalInvocationId:
 	case BuiltInLocalInvocationId:
@@ -8281,7 +8329,12 @@ void CompilerMSL::remap_constexpr_sampler(uint32_t id, const MSLConstexprSampler
 		SPIRV_CROSS_THROW("Can only remap SampledImage and Sampler type.");
 		SPIRV_CROSS_THROW("Can only remap SampledImage and Sampler type.");
 	if (!type.array.empty())
 	if (!type.array.empty())
 		SPIRV_CROSS_THROW("Can not remap array of samplers.");
 		SPIRV_CROSS_THROW("Can not remap array of samplers.");
-	constexpr_samplers[id] = sampler;
+	constexpr_samplers_by_id[id] = sampler;
+}
+
+void CompilerMSL::remap_constexpr_sampler_by_binding(uint32_t desc_set, uint32_t binding, const MSLConstexprSampler &sampler)
+{
+	constexpr_samplers_by_binding[{ desc_set, binding }] = sampler;
 }
 }
 
 
 void CompilerMSL::bitcast_from_builtin_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type)
 void CompilerMSL::bitcast_from_builtin_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type)
@@ -8306,6 +8359,7 @@ void CompilerMSL::bitcast_from_builtin_load(uint32_t source_id, std::string &exp
 	case BuiltInNumWorkgroups:
 	case BuiltInNumWorkgroups:
 	case BuiltInLayer:
 	case BuiltInLayer:
 	case BuiltInViewportIndex:
 	case BuiltInViewportIndex:
+	case BuiltInFragStencilRefEXT:
 		expected_type = SPIRType::UInt;
 		expected_type = SPIRType::UInt;
 		break;
 		break;
 
 
@@ -8346,6 +8400,7 @@ void CompilerMSL::bitcast_to_builtin_store(uint32_t target_id, std::string &expr
 	{
 	{
 	case BuiltInLayer:
 	case BuiltInLayer:
 	case BuiltInViewportIndex:
 	case BuiltInViewportIndex:
+	case BuiltInFragStencilRefEXT:
 		expected_type = SPIRType::UInt;
 		expected_type = SPIRType::UInt;
 		break;
 		break;
 
 
@@ -8439,6 +8494,17 @@ void CompilerMSL::analyze_argument_buffers()
 			if (desc_set >= kMaxArgumentBuffers)
 			if (desc_set >= kMaxArgumentBuffers)
 				SPIRV_CROSS_THROW("Descriptor set index is out of range.");
 				SPIRV_CROSS_THROW("Descriptor set index is out of range.");
 
 
+			const MSLConstexprSampler *constexpr_sampler = nullptr;
+			if (type.basetype == SPIRType::SampledImage || type.basetype == SPIRType::Sampler)
+			{
+				constexpr_sampler = find_constexpr_sampler(var_id);
+				if (constexpr_sampler)
+				{
+					// Mark this ID as a constexpr sampler for later in case it came from set/bindings.
+					constexpr_samplers_by_id[var_id] = *constexpr_sampler;
+				}
+			}
+
 			if (type.basetype == SPIRType::SampledImage)
 			if (type.basetype == SPIRType::SampledImage)
 			{
 			{
 				add_resource_name(var_id);
 				add_resource_name(var_id);
@@ -8453,13 +8519,13 @@ void CompilerMSL::analyze_argument_buffers()
 
 
 				resources_in_set[desc_set].push_back({ &var, to_name(var_id), SPIRType::Image, image_resource_index });
 				resources_in_set[desc_set].push_back({ &var, to_name(var_id), SPIRType::Image, image_resource_index });
 
 
-				if (type.image.dim != DimBuffer && constexpr_samplers.count(var_id) == 0)
+				if (type.image.dim != DimBuffer && !constexpr_sampler)
 				{
 				{
 					resources_in_set[desc_set].push_back(
 					resources_in_set[desc_set].push_back(
 					    { &var, to_sampler_expression(var_id), SPIRType::Sampler, sampler_resource_index });
 					    { &var, to_sampler_expression(var_id), SPIRType::Sampler, sampler_resource_index });
 				}
 				}
 			}
 			}
-			else if (constexpr_samplers.count(var_id) == 0)
+			else if (!constexpr_sampler)
 			{
 			{
 				// constexpr samplers are not declared as resources.
 				// constexpr samplers are not declared as resources.
 				add_resource_name(var_id);
 				add_resource_name(var_id);
@@ -8625,3 +8691,31 @@ void CompilerMSL::analyze_argument_buffers()
 		}
 		}
 	}
 	}
 }
 }
+
+bool CompilerMSL::SetBindingPair::operator==(const SetBindingPair &other) const
+{
+	return desc_set == other.desc_set && binding == other.binding;
+}
+
+bool CompilerMSL::StageSetBinding::operator==(const StageSetBinding &other) const
+{
+	return model == other.model && desc_set == other.desc_set && binding == other.binding;
+}
+
+size_t CompilerMSL::InternalHasher::operator()(const SetBindingPair &value) const
+{
+	// Quality of hash doesn't really matter here.
+	auto hash_set = std::hash<uint32_t>()(value.desc_set);
+	auto hash_binding = std::hash<uint32_t>()(value.binding);
+	return (hash_set * 0x10001b31) ^ hash_binding;
+}
+
+size_t CompilerMSL::InternalHasher::operator()(const StageSetBinding &value) const
+{
+	// Quality of hash doesn't really matter here.
+	auto hash_model = std::hash<uint32_t>()(value.model);
+	auto hash_set = std::hash<uint32_t>()(value.desc_set);
+	auto tmp_hash = (hash_model * 0x10001b31) ^ hash_set;
+	return (tmp_hash * 0x10001b31) ^ value.binding;
+}
+

+ 38 - 2
3rdparty/spirv-cross/spirv_msl.hpp

@@ -22,6 +22,7 @@
 #include <set>
 #include <set>
 #include <unordered_map>
 #include <unordered_map>
 #include <unordered_set>
 #include <unordered_set>
+#include <stddef.h>
 
 
 namespace SPIRV_CROSS_NAMESPACE
 namespace SPIRV_CROSS_NAMESPACE
 {
 {
@@ -306,6 +307,11 @@ public:
 
 
 	// Query after compilation is done. This allows you to check if a location or set/binding combination was used by the shader.
 	// Query after compilation is done. This allows you to check if a location or set/binding combination was used by the shader.
 	bool is_msl_vertex_attribute_used(uint32_t location);
 	bool is_msl_vertex_attribute_used(uint32_t location);
+
+	// NOTE: Only resources which are remapped using add_msl_resource_binding will be reported here.
+	// Constexpr samplers are always assumed to be emitted.
+	// No specific MSLResourceBinding remapping is required for constexpr samplers as long as they are remapped
+	// by remap_constexpr_sampler(_by_binding).
 	bool is_msl_resource_binding_used(spv::ExecutionModel model, uint32_t set, uint32_t binding);
 	bool is_msl_resource_binding_used(spv::ExecutionModel model, uint32_t set, uint32_t binding);
 
 
 	// Compiles the SPIR-V code into Metal Shading Language.
 	// Compiles the SPIR-V code into Metal Shading Language.
@@ -317,8 +323,13 @@ public:
 	// The sampler will not consume a binding, but be declared in the entry point as a constexpr sampler.
 	// The sampler will not consume a binding, but be declared in the entry point as a constexpr sampler.
 	// This can be used on both combined image/samplers (sampler2D) or standalone samplers.
 	// This can be used on both combined image/samplers (sampler2D) or standalone samplers.
 	// The remapped sampler must not be an array of samplers.
 	// The remapped sampler must not be an array of samplers.
+	// Prefer remap_constexpr_sampler_by_binding unless you're also doing reflection anyways.
 	void remap_constexpr_sampler(uint32_t id, const MSLConstexprSampler &sampler);
 	void remap_constexpr_sampler(uint32_t id, const MSLConstexprSampler &sampler);
 
 
+	// Same as remap_constexpr_sampler, except you provide set/binding, rather than variable ID.
+	// Remaps based on ID take priority over set/binding remaps.
+	void remap_constexpr_sampler_by_binding(uint32_t desc_set, uint32_t binding, const MSLConstexprSampler &sampler);
+
 	// If using CompilerMSL::Options::pad_fragment_output_components, override the number of components we expect
 	// If using CompilerMSL::Options::pad_fragment_output_components, override the number of components we expect
 	// to use for a particular location. The default is 4 if number of components is not overridden.
 	// to use for a particular location. The default is 4 if number of components is not overridden.
 	void set_fragment_output_components(uint32_t location, uint32_t components);
 	void set_fragment_output_components(uint32_t location, uint32_t components);
@@ -525,7 +536,28 @@ protected:
 	std::set<std::string> typedef_lines;
 	std::set<std::string> typedef_lines;
 	SmallVector<uint32_t> vars_needing_early_declaration;
 	SmallVector<uint32_t> vars_needing_early_declaration;
 
 
-	SmallVector<std::pair<MSLResourceBinding, bool>> resource_bindings;
+	struct SetBindingPair
+	{
+		uint32_t desc_set;
+		uint32_t binding;
+		bool operator==(const SetBindingPair &other) const;
+	};
+
+	struct StageSetBinding
+	{
+		spv::ExecutionModel model;
+		uint32_t desc_set;
+		uint32_t binding;
+		bool operator==(const StageSetBinding &other) const;
+	};
+
+	struct InternalHasher
+	{
+		size_t operator()(const SetBindingPair &value) const;
+		size_t operator()(const StageSetBinding &value) const;
+	};
+
+	std::unordered_map<StageSetBinding, std::pair<MSLResourceBinding, bool>, InternalHasher> resource_bindings;
 	uint32_t next_metal_resource_index_buffer = 0;
 	uint32_t next_metal_resource_index_buffer = 0;
 	uint32_t next_metal_resource_index_texture = 0;
 	uint32_t next_metal_resource_index_texture = 0;
 	uint32_t next_metal_resource_index_sampler = 0;
 	uint32_t next_metal_resource_index_sampler = 0;
@@ -559,7 +591,11 @@ protected:
 	std::string tess_factor_buffer_var_name = "spvTessLevel";
 	std::string tess_factor_buffer_var_name = "spvTessLevel";
 	spv::Op previous_instruction_opcode = spv::OpNop;
 	spv::Op previous_instruction_opcode = spv::OpNop;
 
 
-	std::unordered_map<uint32_t, MSLConstexprSampler> constexpr_samplers;
+	// Must be ordered since declaration is in a specific order.
+	std::map<uint32_t, MSLConstexprSampler> constexpr_samplers_by_id;
+	std::unordered_map<SetBindingPair, MSLConstexprSampler, InternalHasher> constexpr_samplers_by_binding;
+	const MSLConstexprSampler *find_constexpr_sampler(uint32_t id) const;
+
 	std::unordered_set<uint32_t> buffers_requiring_array_length;
 	std::unordered_set<uint32_t> buffers_requiring_array_length;
 	SmallVector<uint32_t> buffer_arrays;
 	SmallVector<uint32_t> buffer_arrays;
 
 

+ 6 - 0
3rdparty/spirv-cross/test_shaders.py

@@ -97,6 +97,8 @@ def path_to_msl_standard(shader):
             return '-std=ios-metal2.0'
             return '-std=ios-metal2.0'
         elif '.msl21.' in shader:
         elif '.msl21.' in shader:
             return '-std=ios-metal2.1'
             return '-std=ios-metal2.1'
+        elif '.msl22.' in shader:
+            return '-std=ios-metal2.2'
         elif '.msl11.' in shader:
         elif '.msl11.' in shader:
             return '-std=ios-metal1.1'
             return '-std=ios-metal1.1'
         elif '.msl10.' in shader:
         elif '.msl10.' in shader:
@@ -108,6 +110,8 @@ def path_to_msl_standard(shader):
             return '-std=macos-metal2.0'
             return '-std=macos-metal2.0'
         elif '.msl21.' in shader:
         elif '.msl21.' in shader:
             return '-std=macos-metal2.1'
             return '-std=macos-metal2.1'
+        elif '.msl22.' in shader:
+            return '-std=macos-metal2.2'
         elif '.msl11.' in shader:
         elif '.msl11.' in shader:
             return '-std=macos-metal1.1'
             return '-std=macos-metal1.1'
         else:
         else:
@@ -118,6 +122,8 @@ def path_to_msl_standard_cli(shader):
         return '20000'
         return '20000'
     elif '.msl21.' in shader:
     elif '.msl21.' in shader:
         return '20100'
         return '20100'
+    elif '.msl22.' in shader:
+        return '20200'
     elif '.msl11.' in shader:
     elif '.msl11.' in shader:
         return '10100'
         return '10100'
     else:
     else:

+ 133 - 0
3rdparty/spirv-cross/tests-other/msl_constexpr_test.cpp

@@ -0,0 +1,133 @@
+// Testbench for MSL constexpr samplers.
+// It does not validate output, but it's useful for ad-hoc testing.
+
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include <spirv_cross_c.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <vector>
+
+#define SPVC_CHECKED_CALL(x) do { \
+	if ((x) != SPVC_SUCCESS) { \
+		fprintf(stderr, "Failed at line %d.\n", __LINE__); \
+		exit(1); \
+	} \
+} while(0)
+#define SPVC_CHECKED_CALL_NEGATIVE(x) do { \
+	g_fail_on_error = SPVC_FALSE; \
+	if ((x) == SPVC_SUCCESS) { \
+		fprintf(stderr, "Failed at line %d.\n", __LINE__); \
+		exit(1); \
+	} \
+	g_fail_on_error = SPVC_TRUE; \
+} while(0)
+
+static std::vector<SpvId> read_file(const char *path)
+{
+	long len;
+	FILE *file = fopen(path, "rb");
+
+	if (!file)
+		return {};
+
+	fseek(file, 0, SEEK_END);
+	len = ftell(file);
+	rewind(file);
+
+	std::vector<SpvId> buffer(len / sizeof(SpvId));
+	if (fread(buffer.data(), 1, len, file) != (size_t)len)
+	{
+		fclose(file);
+		return {};
+	}
+
+	fclose(file);
+	return buffer;
+}
+
+int main(int argc, char **argv)
+{
+	if (argc != 2)
+		return EXIT_FAILURE;
+
+	auto buffer = read_file(argv[1]);
+	if (buffer.empty())
+		return EXIT_FAILURE;
+
+	spvc_context ctx;
+	spvc_parsed_ir parsed_ir;
+	spvc_compiler compiler;
+
+	SPVC_CHECKED_CALL(spvc_context_create(&ctx));
+	SPVC_CHECKED_CALL(spvc_context_parse_spirv(ctx, buffer.data(), buffer.size(), &parsed_ir));
+	SPVC_CHECKED_CALL(spvc_context_create_compiler(ctx, SPVC_BACKEND_MSL, parsed_ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &compiler));
+
+	spvc_msl_resource_binding binding;
+	spvc_msl_resource_binding_init(&binding);
+	binding.desc_set = 1;
+	binding.binding = 2;
+	binding.stage = SpvExecutionModelFragment;
+	binding.msl_texture = 0;
+	binding.msl_sampler = 0;
+	SPVC_CHECKED_CALL(spvc_compiler_msl_add_resource_binding(compiler, &binding));
+
+	binding.binding = 3;
+	binding.msl_texture = 1;
+	binding.msl_sampler = 1000; // Will be remapped anyways, sanity check.
+	SPVC_CHECKED_CALL(spvc_compiler_msl_add_resource_binding(compiler, &binding));
+
+	binding.desc_set = 2;
+	binding.binding = 2;
+	binding.msl_texture = 2;
+	SPVC_CHECKED_CALL(spvc_compiler_msl_add_resource_binding(compiler, &binding));
+
+	binding.binding = 3;
+	binding.msl_texture = 3;
+	SPVC_CHECKED_CALL(spvc_compiler_msl_add_resource_binding(compiler, &binding));
+
+	spvc_msl_constexpr_sampler samp;
+	spvc_msl_constexpr_sampler_init(&samp);
+	samp.s_address = SPVC_MSL_SAMPLER_ADDRESS_REPEAT;
+	samp.t_address = SPVC_MSL_SAMPLER_ADDRESS_REPEAT;
+	samp.r_address = SPVC_MSL_SAMPLER_ADDRESS_REPEAT;
+	SPVC_CHECKED_CALL(spvc_compiler_msl_remap_constexpr_sampler_by_binding(compiler, 1, 3, &samp));
+
+	samp.s_address = SPVC_MSL_SAMPLER_ADDRESS_CLAMP_TO_EDGE;
+	samp.t_address = SPVC_MSL_SAMPLER_ADDRESS_CLAMP_TO_EDGE;
+	samp.r_address = SPVC_MSL_SAMPLER_ADDRESS_CLAMP_TO_EDGE;
+	SPVC_CHECKED_CALL(spvc_compiler_msl_remap_constexpr_sampler_by_binding(compiler, 2, 4, &samp));
+
+	samp.compare_enable = SPVC_TRUE;
+	samp.compare_func = SPVC_MSL_SAMPLER_COMPARE_FUNC_LESS;
+	samp.s_address = SPVC_MSL_SAMPLER_ADDRESS_CLAMP_TO_EDGE;
+	samp.t_address = SPVC_MSL_SAMPLER_ADDRESS_CLAMP_TO_EDGE;
+	samp.r_address = SPVC_MSL_SAMPLER_ADDRESS_CLAMP_TO_EDGE;
+	SPVC_CHECKED_CALL(spvc_compiler_msl_remap_constexpr_sampler_by_binding(compiler, 2, 5, &samp));
+
+	const char *str;
+	SPVC_CHECKED_CALL(spvc_compiler_compile(compiler, &str));
+
+	// Should not be marked as used.
+	if (spvc_compiler_msl_is_resource_used(compiler, SpvExecutionModelFragment, 2, 4))
+		return EXIT_FAILURE;
+
+	// Should not be marked as used.
+	if (spvc_compiler_msl_is_resource_used(compiler, SpvExecutionModelFragment, 2, 5))
+		return EXIT_FAILURE;
+
+	// Should be marked, as a sanity check.
+	if (!spvc_compiler_msl_is_resource_used(compiler, SpvExecutionModelFragment, 1, 2))
+		return EXIT_FAILURE;
+	if (!spvc_compiler_msl_is_resource_used(compiler, SpvExecutionModelFragment, 1, 3))
+		return EXIT_FAILURE;
+	if (!spvc_compiler_msl_is_resource_used(compiler, SpvExecutionModelFragment, 2, 2))
+		return EXIT_FAILURE;
+	if (!spvc_compiler_msl_is_resource_used(compiler, SpvExecutionModelFragment, 2, 3))
+		return EXIT_FAILURE;
+
+	fprintf(stderr, "Output:\n%s\n", str);
+}
+

BIN
3rdparty/spirv-cross/tests-other/msl_constexpr_test.spv