Skip to content

Commit 64dfdbd

Browse files
Add warning for ignored binding attributes on uniforms (#6373)
Fixes #4251 When binding attributes (like [[vk::binding]]) are specified on uniforms that get packed into the default constant buffer, these binding attributes are effectively ignored since the uniform will always be placed at descriptor set 0, binding 0. This can be confusing for users who expect their explicit bindings to take effect. This change adds a new warning (71) that informs users when their binding attributes on uniforms will be ignored, and suggests declaring the uniform inside a constant buffer to preserve the explicit binding. The warning helps users understand: 1. Why their binding attribute isn't having the expected effect 2. That the uniform is being packed into the default constant buffer 3. How to fix it by using a constant buffer declaration Added test case in tests/bugs/binding-attribute-ignored.slang to verify the warning behavior. Co-authored-by: Ellie Hermaszewska <ellieh@nvidia.com>
1 parent 7f395a7 commit 64dfdbd

File tree

3 files changed

+45
-27
lines changed

3 files changed

+45
-27
lines changed

source/slang/slang-diagnostic-defs.h

+8
Original file line numberDiff line numberDiff line change
@@ -2055,6 +2055,14 @@ DIAGNOSTIC(
20552055
"shader parameter '$0' has a 'register' specified for D3D, but no '[[vk::binding(...)]]` "
20562056
"specified for Vulkan, nor is `-fvk-$1-shift` used.")
20572057

2058+
DIAGNOSTIC(
2059+
39071,
2060+
Warning,
2061+
bindingAttributeIgnoredOnUniform,
2062+
"binding attribute on uniform '$0' will be ignored since it will be packed into the default "
2063+
"constant buffer at descriptor set 0 binding 0. To use explicit bindings, declare the uniform "
2064+
"inside a constant buffer.")
2065+
20582066
//
20592067

20602068
// 4xxxx - IL code generation.

source/slang/slang-parameter-binding.cpp

+15-27
Original file line numberDiff line numberDiff line change
@@ -3511,34 +3511,22 @@ static void collectParameters(ParameterBindingContext* inContext, ComponentType*
35113511
/// Emit a diagnostic about a uniform/ordinary parameter at global scope.
35123512
void diagnoseGlobalUniform(SharedParameterBindingContext* sharedContext, VarDeclBase* varDecl)
35133513
{
3514-
// This subroutine gets invoked if a shader parameter containing
3515-
// "ordinary" data (sometimes just called "uniform" data) is present
3516-
// at the global scope.
3517-
//
3518-
// Slang can support such parameters by aggregating them into
3519-
// an implicit constant buffer, but it is also common for programmers
3520-
// to accidentally declare a global-scope shader parameter when they
3521-
// meant to declare a global variable instead:
3522-
//
3523-
// int gCounter = 0; // this is a shader parameter, not a global
3524-
//
3525-
// In order to avoid mistakes, we'd like to warn the user when
3526-
// they write code like the above, and hint to them that they
3527-
// should make their intention more explicit with a keyword:
3528-
//
3529-
// static int gCounter = 0; // this is now a (static) global
3530-
//
3531-
// uniform int gCounter; // this is now explicitly a shader parameter
3532-
//
3533-
// We skip the diagnostic whenever the variable was explicitly `uniform`,
3534-
// under the assumption that the programmer who added that modifier
3535-
// knew what they were opting into.
3536-
//
3537-
if (varDecl->hasModifier<HLSLUniformModifier>())
3538-
return;
3514+
// Don't emit the implicit global shader parameter warning if the variable is explicitly marked
3515+
// as uniform
3516+
if (!varDecl->hasModifier<HLSLUniformModifier>())
3517+
{
3518+
getSink(sharedContext)
3519+
->diagnose(varDecl, Diagnostics::globalUniformNotExpected, varDecl->getName());
3520+
}
35393521

3540-
getSink(sharedContext)
3541-
->diagnose(varDecl, Diagnostics::globalUniformNotExpected, varDecl->getName());
3522+
// Always check and warn about binding attributes being ignored, regardless of uniform modifier
3523+
if (varDecl->findModifier<GLSLBindingAttribute>())
3524+
{
3525+
sharedContext->m_sink->diagnose(
3526+
varDecl,
3527+
Diagnostics::bindingAttributeIgnoredOnUniform,
3528+
varDecl->getName());
3529+
}
35423530
}
35433531

35443532

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// binding-attribute-ignored.slang
2+
// Test that binding attributes on uniforms that get packed into the default uniform buffer trigger a warning
3+
4+
//TEST:SIMPLE(filecheck=CHECK):-target spirv
5+
6+
//CHECK: ([[# @LINE+2]]): warning 39071
7+
[[vk::binding(1, 2)]]
8+
uniform float4 g_position;
9+
10+
//CHECK: ([[# @LINE+2]]): warning 39071
11+
[[vk::binding(3, 1)]]
12+
uniform float4x4 g_transform;
13+
14+
// This won't trigger a warning because it's a texture (not packed into default uniform buffer)
15+
[[vk::binding(0, 0)]]
16+
Texture2D g_texture;
17+
18+
[shader("vertex")]
19+
float4 main(float4 pos : POSITION) : SV_POSITION
20+
{
21+
return g_position;
22+
}

0 commit comments

Comments
 (0)