Repository: shader-slang/slang (2025-07-01T22:04:02Z)

Issue:
vk::binding supplied, slangc warns about lack of such binding only when targetting metallib

This may well be user error, but I'm seeing what I believe are spurios compile time warnings when targetting metallib
I do not see these warnings when I target spirv

I also see such warnings emitted twice (?)


```
SimpleVertexShaderInstanced.vs.slang(6): warning 39029: shader parameter 'SLANG_parameterGroup_ConstantBuffer' has a 'register' specified for D3D, but no '[[vk::binding(...)]]` specified for Vulkan, nor is `-fvk-b-shift` used.

[[vk::binding(0, 0)]] cbuffer ConstantBuffer : register(b0)

                                               ^~~~~~~~

SimpleVertexShaderInstanced.vs.slang(6): warning 39029: shader parameter 'SLANG_parameterGroup_ConstantBuffer' has a 'register' specified for D3D, but no '[[vk::binding(...)]]` specified for Vulkan, nor is `-fvk-b-shift` used.

[[vk::binding(0, 0)]] cbuffer ConstantBuffer : register(b0)

                                               ^~~~~~~~
```

The invocation for slangc is as follows:
```
shaderslang/bin/slangc -matrix-layout-row-major SimpleVertexShaderInstanced.vs.slang -target metallib -o via_shaderslang/metal/SimpleVertexShaderInstanced.vs.metallib
```

I'm using the current release, 2025.11 though I have seen this in other recent releases also

Note that the resulting shader appears to run just fine


Discussion:
Further to the above, when I build this same shader to target `spirv` I see no such compile time warning, though I **do** see a runtime warning from the Debug validation layer

```
VULKAN_ERR     |Vulkan Layer: VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT : vkCreateShaderModule(): pCreateInfo->pCode (spirv-val produced an error):
Invalid explicit layout decorations on type for operand '13[%13]'
  %14 = OpVariable %_ptr_Function__arr_v4float_int_21 Function
The Vulkan spec states: All variables must have valid explicit layout decorations as described in Shader Interfaces (https://vulkan.lunarg.com/doc/view/1.4.313.0/mac/antora/spec/latest/appendices/spirvenv.html#VUID-StandaloneSpirv-None-10684)
```

`vkCreateShaderModule()` returns VK_SUCCESS and again, the shader appears to run just fine..  


The full shader source is attached (renamed to .txt because github)

[SimpleVertexShaderInstanced.vs.slang.txt](https://github.com/user-attachments/files/20965689/SimpleVertexShaderInstanced.vs.slang.txt)

The runtime warning from the validation layer appears to be a duplicate of [this issue](https://github.com/shader-slang/slang/issues/7508), whose fix is in 2025.11.1.
The metallib-related warnings appear to be a separate, legitimate issue.


Cheers @aidanfnv 
2025.11.1 does indeed resolve secondary (unrelated) issue



Patch:
diff --git a/source/slang-glslang/slang-glslang.cpp b/source/slang-glslang/slang-glslang.cpp
index e830fb15a8..56be8b0427 100644
--- a/source/slang-glslang/slang-glslang.cpp
+++ b/source/slang-glslang/slang-glslang.cpp
@@ -189,7 +189,7 @@ extern "C"
 #ifdef _MSC_VER
     _declspec(dllexport)
 #else
-__attribute__((__visibility__("default")))
+    __attribute__((__visibility__("default")))
 #endif
         bool glslang_disassembleSPIRVWithResult(
             const uint32_t* contents,
@@ -237,7 +237,7 @@ extern "C"
 #ifdef _MSC_VER
     _declspec(dllexport)
 #else
-__attribute__((__visibility__("default")))
+    __attribute__((__visibility__("default")))
 #endif
         bool glslang_disassembleSPIRV(const uint32_t* contents, int contentsSize)
 {
diff --git a/source/slang/slang-parameter-binding.cpp b/source/slang/slang-parameter-binding.cpp
index 86d76fc6d4..4ba9e4e03e 100644
--- a/source/slang/slang-parameter-binding.cpp
+++ b/source/slang/slang-parameter-binding.cpp
@@ -1069,7 +1069,7 @@ static void addExplicitParameterBindings_HLSL(
     }
 }
 
-static void _maybeDiagnoseMissingVulkanLayoutModifier(
+static bool _maybeDiagnoseMissingVulkanLayoutModifier(
     ParameterBindingContext* context,
     DeclRef<VarDeclBase> const& varDecl)
 {
@@ -1077,7 +1077,7 @@ static void _maybeDiagnoseMissingVulkanLayoutModifier(
     if (varDecl.getDecl()->hasModifier<PushConstantAttribute>() ||
         varDecl.getDecl()->hasModifier<ShaderRecordAttribute>())
     {
-        return;
+        return false;
     }
 
     // If the user didn't specify a `binding` (and optional `set`) for Vulkan,
@@ -1085,6 +1085,11 @@ static void _maybeDiagnoseMissingVulkanLayoutModifier(
     // oversight on their part.
     if (auto registerModifier = varDecl.getDecl()->findModifier<HLSLRegisterSemantic>())
     {
+        // Don't warn if the declaration already has a vk::binding attribute
+        if (varDecl.getDecl()->findModifier<GLSLBindingAttribute>())
+        {
+            return false;
+        }
         auto varType = getType(context->getASTBuilder(), varDecl.as<VarDeclBase>());
         if (auto textureType = as<TextureType>(varType))
         {
@@ -1095,7 +1100,7 @@ static void _maybeDiagnoseMissingVulkanLayoutModifier(
                     registerModifier,
                     Diagnostics::registerModifierButNoVulkanLayout,
                     varDecl.getName());
-                return;
+                return true;
             }
         }
 
@@ -1111,7 +1116,9 @@ static void _maybeDiagnoseMissingVulkanLayoutModifier(
             Diagnostics::registerModifierButNoVkBindingNorShift,
             varDecl.getName(),
             registerClassName);
+        return true;
     }
+    return false;
 }
 
 static void addExplicitParameterBindings_GLSL(
@@ -1273,8 +1280,16 @@ static void addExplicitParameterBindings_GLSL(
     // If we are not told how to infer bindings with a compile option, we warn
     if (hlslToVulkanLayoutOptions == nullptr || !hlslToVulkanLayoutOptions->canInferBindings())
     {
-        warnedMissingVulkanLayoutModifier = true;
-        _maybeDiagnoseMissingVulkanLayoutModifier(context, varDecl.as<VarDeclBase>());
+        warnedMissingVulkanLayoutModifier =
+            _maybeDiagnoseMissingVulkanLayoutModifier(context, varDecl.as<VarDeclBase>());
+        // For behavioral compatibility, if we didn't warn due to a push constant or shader record,
+        // we still need to set the flag to true to maintain the same binding logic
+        if (!warnedMissingVulkanLayoutModifier &&
+            (varDecl.getDecl()->hasModifier<PushConstantAttribute>() ||
+             varDecl.getDecl()->hasModifier<ShaderRecordAttribute>()))
+        {
+            warnedMissingVulkanLayoutModifier = true;
+        }
     }
 
     // We need an HLSL register semantic to to infer from
@@ -1301,8 +1316,8 @@ static void addExplicitParameterBindings_GLSL(
         {
             if (!warnedMissingVulkanLayoutModifier)
             {
-                _maybeDiagnoseMissingVulkanLayoutModifier(context, varDecl.as<VarDeclBase>());
-                warnedMissingVulkanLayoutModifier = true;
+                warnedMissingVulkanLayoutModifier =
+                    _maybeDiagnoseMissingVulkanLayoutModifier(context, varDecl.as<VarDeclBase>());
             }
             return;
         }
@@ -1323,8 +1338,8 @@ static void addExplicitParameterBindings_GLSL(
     {
         if (!warnedMissingVulkanLayoutModifier)
         {
-            _maybeDiagnoseMissingVulkanLayoutModifier(context, varDecl.as<VarDeclBase>());
-            warnedMissingVulkanLayoutModifier = true;
+            warnedMissingVulkanLayoutModifier =
+                _maybeDiagnoseMissingVulkanLayoutModifier(context, varDecl.as<VarDeclBase>());
         }
     }
 


Test patch:
diff --git a/tests/diagnostics/vk-binding-with-register-no-warning.slang b/tests/diagnostics/vk-binding-with-register-no-warning.slang
new file mode 100644
index 0000000000..3bbbcc1bd7
--- /dev/null
+++ b/tests/diagnostics/vk-binding-with-register-no-warning.slang
@@ -0,0 +1,35 @@
+// vk-binding-with-register-no-warning.slang
+
+//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK):-target metallib -matrix-layout-row-major -entry main
+
+// Test that no spurious warnings are generated when vk::binding is present alongside register
+// This addresses issue #7553 where the compiler incorrectly warned about missing vk::binding
+
+// Should NOT generate warning - has both vk::binding and register
+// CHECK-NOT: ([[# @LINE+1]]): warning 39029
+[[vk::binding(0, 0)]] cbuffer ConstantBuffer : register(b0)
+{
+    float4 testValue;
+};
+
+// Should NOT generate warning - has both vk::binding and register  
+// CHECK-NOT: ([[# @LINE+1]]): warning 39029
+[[vk::binding(1, 0)]] Texture2D tex : register(t1);
+
+// Should NOT generate warning - has both vk::binding and register
+// CHECK-NOT: ([[# @LINE+1]]): warning 39029
+[[vk::binding(2, 0)]] SamplerState sampler : register(s2);
+
+// Should generate warning - has register but no vk::binding
+// CHECK: ([[# @LINE+1]]): warning 39029
+Texture2D texNoBinding : register(t3);
+
+// Should generate warning - has register but no vk::binding
+// CHECK: ([[# @LINE+1]]): warning 39029
+ConstantBuffer<float4> cbNoBinding : register(b4);
+
+[shader("compute")]
+[numthreads(1, 1, 1)]
+void main()
+{
+}
\ No newline at end of file