Fix #2005. Allow multiple compilation units to declare identical push_constant blocks (#2123)
* Fixes #2005
Allow multiple units in a stage to have push_constants as long
as the blocks match.
Requires #2006 to be fixed to be functional.
* tweaks to #2005 fix after some testing
* add unit tests for push constants across multiple compilation units
For #2005
* update reference output for tests that fail validation
* fix uninitialized result.validationResult
diff --git a/Test/baseResults/link.vk.differentPC.0.0.frag.out b/Test/baseResults/link.vk.differentPC.0.0.frag.out
new file mode 100755
index 0000000..d7cfd22
--- /dev/null
+++ b/Test/baseResults/link.vk.differentPC.0.0.frag.out
@@ -0,0 +1,95 @@
+link.vk.differentPC.0.0.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:15 Function Definition: main( ( global void)
+0:15 Function Parameters:
+0:17 Sequence
+0:17 move second child to first child ( temp highp 4-component vector of float)
+0:17 'color' (layout( location=0) out highp 4-component vector of float)
+0:17 add ( temp highp 4-component vector of float)
+0:17 color: direct index for structure (layout( column_major std430 offset=0) uniform highp 4-component vector of float)
+0:17 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+0:17 Constant:
+0:17 0 (const int)
+0:17 vector-scale ( temp highp 4-component vector of float)
+0:17 Function Call: getColor2( ( global highp 4-component vector of float)
+0:17 Function Call: getScale( ( global highp float)
+0:? Linker Objects
+0:? 'color' (layout( location=0) out highp 4-component vector of float)
+0:? 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+
+link.vk.differentPC.0.1.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:11 Function Definition: getColor2( ( global highp 4-component vector of float)
+0:11 Function Parameters:
+0:13 Sequence
+0:13 Branch: Return with expression
+0:13 color2: direct index for structure (layout( column_major std430 offset=16) uniform highp 4-component vector of float)
+0:13 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+0:13 Constant:
+0:13 1 (const int)
+0:? Linker Objects
+0:? 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+
+link.vk.differentPC.0.2.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:11 Function Definition: getScale( ( global highp float)
+0:11 Function Parameters:
+0:13 Sequence
+0:13 Branch: Return with expression
+0:13 scale2: direct index for structure (layout( column_major std430 offset=32) uniform highp float)
+0:13 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale2})
+0:13 Constant:
+0:13 2 (const int)
+0:? Linker Objects
+0:? 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale2})
+
+
+Linked fragment stage:
+
+ERROR: Linking fragment stage: Types must match:
+ uPC: "layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale}" versus "layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale2}"
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:15 Function Definition: main( ( global void)
+0:15 Function Parameters:
+0:17 Sequence
+0:17 move second child to first child ( temp highp 4-component vector of float)
+0:17 'color' (layout( location=0) out highp 4-component vector of float)
+0:17 add ( temp highp 4-component vector of float)
+0:17 color: direct index for structure (layout( column_major std430 offset=0) uniform highp 4-component vector of float)
+0:17 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+0:17 Constant:
+0:17 0 (const int)
+0:17 vector-scale ( temp highp 4-component vector of float)
+0:17 Function Call: getColor2( ( global highp 4-component vector of float)
+0:17 Function Call: getScale( ( global highp float)
+0:11 Function Definition: getColor2( ( global highp 4-component vector of float)
+0:11 Function Parameters:
+0:13 Sequence
+0:13 Branch: Return with expression
+0:13 color2: direct index for structure (layout( column_major std430 offset=16) uniform highp 4-component vector of float)
+0:13 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+0:13 Constant:
+0:13 1 (const int)
+0:11 Function Definition: getScale( ( global highp float)
+0:11 Function Parameters:
+0:13 Sequence
+0:13 Branch: Return with expression
+0:13 scale2: direct index for structure (layout( column_major std430 offset=32) uniform highp float)
+0:13 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale2})
+0:13 Constant:
+0:13 2 (const int)
+0:? Linker Objects
+0:? 'color' (layout( location=0) out highp 4-component vector of float)
+0:? 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+
+Validation failed
+SPIR-V is not generated for failed compile or link
diff --git a/Test/baseResults/link.vk.differentPC.1.0.frag.out b/Test/baseResults/link.vk.differentPC.1.0.frag.out
new file mode 100755
index 0000000..632f18b
--- /dev/null
+++ b/Test/baseResults/link.vk.differentPC.1.0.frag.out
@@ -0,0 +1,97 @@
+link.vk.differentPC.1.0.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:12 Function Definition: getScale( ( global highp float)
+0:12 Function Parameters:
+0:14 Sequence
+0:14 Branch: Return with expression
+0:14 scale: direct index for structure (layout( column_major std430 offset=32) uniform highp float)
+0:14 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale, layout( column_major std430 offset=36) uniform highp float scale2})
+0:14 Constant:
+0:14 2 (const int)
+0:? Linker Objects
+0:? 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale, layout( column_major std430 offset=36) uniform highp float scale2})
+
+link.vk.differentPC.1.1.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:11 Function Definition: getColor2( ( global highp 4-component vector of float)
+0:11 Function Parameters:
+0:13 Sequence
+0:13 Branch: Return with expression
+0:13 color2: direct index for structure (layout( column_major std430 offset=16) uniform highp 4-component vector of float)
+0:13 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+0:13 Constant:
+0:13 1 (const int)
+0:? Linker Objects
+0:? 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+
+link.vk.differentPC.1.2.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:15 Function Definition: main( ( global void)
+0:15 Function Parameters:
+0:17 Sequence
+0:17 move second child to first child ( temp highp 4-component vector of float)
+0:17 'color' (layout( location=0) out highp 4-component vector of float)
+0:17 add ( temp highp 4-component vector of float)
+0:17 color: direct index for structure (layout( column_major std430 offset=0) uniform highp 4-component vector of float)
+0:17 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+0:17 Constant:
+0:17 0 (const int)
+0:17 vector-scale ( temp highp 4-component vector of float)
+0:17 Function Call: getColor2( ( global highp 4-component vector of float)
+0:17 Function Call: getScale( ( global highp float)
+0:? Linker Objects
+0:? 'color' (layout( location=0) out highp 4-component vector of float)
+0:? 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+
+
+Linked fragment stage:
+
+ERROR: Linking fragment stage: Types must match:
+ uPC: "layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale, layout( column_major std430 offset=36) uniform highp float scale2}" versus "layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale}"
+ERROR: Linking fragment stage: Types must match:
+ uPC: "layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale, layout( column_major std430 offset=36) uniform highp float scale2}" versus "layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale}"
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:12 Function Definition: getScale( ( global highp float)
+0:12 Function Parameters:
+0:14 Sequence
+0:14 Branch: Return with expression
+0:14 scale: direct index for structure (layout( column_major std430 offset=32) uniform highp float)
+0:14 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale, layout( column_major std430 offset=36) uniform highp float scale2})
+0:14 Constant:
+0:14 2 (const int)
+0:11 Function Definition: getColor2( ( global highp 4-component vector of float)
+0:11 Function Parameters:
+0:13 Sequence
+0:13 Branch: Return with expression
+0:13 color2: direct index for structure (layout( column_major std430 offset=16) uniform highp 4-component vector of float)
+0:13 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+0:13 Constant:
+0:13 1 (const int)
+0:15 Function Definition: main( ( global void)
+0:15 Function Parameters:
+0:17 Sequence
+0:17 move second child to first child ( temp highp 4-component vector of float)
+0:17 'color' (layout( location=0) out highp 4-component vector of float)
+0:17 add ( temp highp 4-component vector of float)
+0:17 color: direct index for structure (layout( column_major std430 offset=0) uniform highp 4-component vector of float)
+0:17 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+0:17 Constant:
+0:17 0 (const int)
+0:17 vector-scale ( temp highp 4-component vector of float)
+0:17 Function Call: getColor2( ( global highp 4-component vector of float)
+0:17 Function Call: getScale( ( global highp float)
+0:? Linker Objects
+0:? 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale, layout( column_major std430 offset=36) uniform highp float scale2})
+0:? 'color' (layout( location=0) out highp 4-component vector of float)
+
+Validation failed
+SPIR-V is not generated for failed compile or link
diff --git a/Test/baseResults/link.vk.matchingPC.0.0.frag.out b/Test/baseResults/link.vk.matchingPC.0.0.frag.out
new file mode 100755
index 0000000..1d6875a
--- /dev/null
+++ b/Test/baseResults/link.vk.matchingPC.0.0.frag.out
@@ -0,0 +1,155 @@
+link.vk.matchingPC.0.0.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:15 Function Definition: main( ( global void)
+0:15 Function Parameters:
+0:17 Sequence
+0:17 move second child to first child ( temp highp 4-component vector of float)
+0:17 'color' (layout( location=0) out highp 4-component vector of float)
+0:17 add ( temp highp 4-component vector of float)
+0:17 color: direct index for structure (layout( column_major std430 offset=0) uniform highp 4-component vector of float)
+0:17 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+0:17 Constant:
+0:17 0 (const int)
+0:17 vector-scale ( temp highp 4-component vector of float)
+0:17 Function Call: getColor2( ( global highp 4-component vector of float)
+0:17 Function Call: getScale( ( global highp float)
+0:? Linker Objects
+0:? 'color' (layout( location=0) out highp 4-component vector of float)
+0:? 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+
+link.vk.matchingPC.0.1.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:11 Function Definition: getColor2( ( global highp 4-component vector of float)
+0:11 Function Parameters:
+0:13 Sequence
+0:13 Branch: Return with expression
+0:13 color2: direct index for structure (layout( column_major std430 offset=16) uniform highp 4-component vector of float)
+0:13 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+0:13 Constant:
+0:13 1 (const int)
+0:? Linker Objects
+0:? 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+
+link.vk.matchingPC.0.2.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:11 Function Definition: getScale( ( global highp float)
+0:11 Function Parameters:
+0:13 Sequence
+0:13 Branch: Return with expression
+0:13 scale: direct index for structure (layout( column_major std430 offset=32) uniform highp float)
+0:13 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+0:13 Constant:
+0:13 2 (const int)
+0:? Linker Objects
+0:? 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:15 Function Definition: main( ( global void)
+0:15 Function Parameters:
+0:17 Sequence
+0:17 move second child to first child ( temp highp 4-component vector of float)
+0:17 'color' (layout( location=0) out highp 4-component vector of float)
+0:17 add ( temp highp 4-component vector of float)
+0:17 color: direct index for structure (layout( column_major std430 offset=0) uniform highp 4-component vector of float)
+0:17 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+0:17 Constant:
+0:17 0 (const int)
+0:17 vector-scale ( temp highp 4-component vector of float)
+0:17 Function Call: getColor2( ( global highp 4-component vector of float)
+0:17 Function Call: getScale( ( global highp float)
+0:11 Function Definition: getColor2( ( global highp 4-component vector of float)
+0:11 Function Parameters:
+0:13 Sequence
+0:13 Branch: Return with expression
+0:13 color2: direct index for structure (layout( column_major std430 offset=16) uniform highp 4-component vector of float)
+0:13 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+0:13 Constant:
+0:13 1 (const int)
+0:11 Function Definition: getScale( ( global highp float)
+0:11 Function Parameters:
+0:13 Sequence
+0:13 Branch: Return with expression
+0:13 scale: direct index for structure (layout( column_major std430 offset=32) uniform highp float)
+0:13 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+0:13 Constant:
+0:13 2 (const int)
+0:? Linker Objects
+0:? 'color' (layout( location=0) out highp 4-component vector of float)
+0:? 'uPC' (layout( column_major std430 push_constant) uniform block{layout( column_major std430 offset=0) uniform highp 4-component vector of float color, layout( column_major std430 offset=16) uniform highp 4-component vector of float color2, layout( column_major std430 offset=32) uniform highp float scale})
+
+// Module Version 10000
+// Generated by (magic number): 80008
+// Id's are bound by 39
+
+ Capability Shader
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Fragment 4 "main" 15
+ ExecutionMode 4 OriginUpperLeft
+ Source GLSL 450
+ Name 4 "main"
+ Name 9 "getColor2("
+ Name 12 "getScale("
+ Name 15 "color"
+ Name 16 "PushConstantBlock"
+ MemberName 16(PushConstantBlock) 0 "color"
+ MemberName 16(PushConstantBlock) 1 "color2"
+ MemberName 16(PushConstantBlock) 2 "scale"
+ Name 18 "uPC"
+ Decorate 15(color) Location 0
+ MemberDecorate 16(PushConstantBlock) 0 Offset 0
+ MemberDecorate 16(PushConstantBlock) 1 Offset 16
+ MemberDecorate 16(PushConstantBlock) 2 Offset 32
+ Decorate 16(PushConstantBlock) Block
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeFloat 32
+ 7: TypeVector 6(float) 4
+ 8: TypeFunction 7(fvec4)
+ 11: TypeFunction 6(float)
+ 14: TypePointer Output 7(fvec4)
+ 15(color): 14(ptr) Variable Output
+16(PushConstantBlock): TypeStruct 7(fvec4) 7(fvec4) 6(float)
+ 17: TypePointer PushConstant 16(PushConstantBlock)
+ 18(uPC): 17(ptr) Variable PushConstant
+ 19: TypeInt 32 1
+ 20: 19(int) Constant 0
+ 21: TypePointer PushConstant 7(fvec4)
+ 28: 19(int) Constant 1
+ 33: 19(int) Constant 2
+ 34: TypePointer PushConstant 6(float)
+ 4(main): 2 Function None 3
+ 5: Label
+ 22: 21(ptr) AccessChain 18(uPC) 20
+ 23: 7(fvec4) Load 22
+ 24: 7(fvec4) FunctionCall 9(getColor2()
+ 25: 6(float) FunctionCall 12(getScale()
+ 26: 7(fvec4) VectorTimesScalar 24 25
+ 27: 7(fvec4) FAdd 23 26
+ Store 15(color) 27
+ Return
+ FunctionEnd
+ 9(getColor2(): 7(fvec4) Function None 8
+ 10: Label
+ 29: 21(ptr) AccessChain 18(uPC) 28
+ 30: 7(fvec4) Load 29
+ ReturnValue 30
+ FunctionEnd
+ 12(getScale(): 6(float) Function None 11
+ 13: Label
+ 35: 34(ptr) AccessChain 18(uPC) 33
+ 36: 6(float) Load 35
+ ReturnValue 36
+ FunctionEnd
diff --git a/Test/link.vk.differentPC.0.0.frag b/Test/link.vk.differentPC.0.0.frag
new file mode 100755
index 0000000..f5ad4ce
--- /dev/null
+++ b/Test/link.vk.differentPC.0.0.frag
@@ -0,0 +1,18 @@
+#version 450
+
+layout(location=0) out vec4 color;
+
+layout (push_constant) uniform PushConstantBlock
+{
+ vec4 color;
+ vec4 color2;
+ float scale;
+} uPC;
+
+vec4 getColor2();
+float getScale();
+
+void main()
+{
+ color = uPC.color + getColor2() * getScale();
+}
diff --git a/Test/link.vk.differentPC.0.1.frag b/Test/link.vk.differentPC.0.1.frag
new file mode 100755
index 0000000..972fc65
--- /dev/null
+++ b/Test/link.vk.differentPC.0.1.frag
@@ -0,0 +1,14 @@
+#version 450
+
+layout (push_constant) uniform PushConstantBlock
+{
+ vec4 color;
+ vec4 color2;
+ float scale;
+} uPC;
+
+vec4
+getColor2()
+{
+ return uPC.color2;
+}
diff --git a/Test/link.vk.differentPC.0.2.frag b/Test/link.vk.differentPC.0.2.frag
new file mode 100755
index 0000000..287e425
--- /dev/null
+++ b/Test/link.vk.differentPC.0.2.frag
@@ -0,0 +1,15 @@
+#version 450
+
+layout (push_constant) uniform PushConstantBlock
+{
+ vec4 color;
+ vec4 color2;
+ float scale2;
+} uPC;
+
+float
+getScale()
+{
+ return uPC.scale2;
+}
+
diff --git a/Test/link.vk.differentPC.1.0.frag b/Test/link.vk.differentPC.1.0.frag
new file mode 100755
index 0000000..e395bb8
--- /dev/null
+++ b/Test/link.vk.differentPC.1.0.frag
@@ -0,0 +1,16 @@
+#version 450
+
+layout (push_constant) uniform PushConstantBlock
+{
+ vec4 color;
+ vec4 color2;
+ float scale;
+ float scale2;
+} uPC;
+
+float
+getScale()
+{
+ return uPC.scale;
+}
+
diff --git a/Test/link.vk.differentPC.1.1.frag b/Test/link.vk.differentPC.1.1.frag
new file mode 100755
index 0000000..972fc65
--- /dev/null
+++ b/Test/link.vk.differentPC.1.1.frag
@@ -0,0 +1,14 @@
+#version 450
+
+layout (push_constant) uniform PushConstantBlock
+{
+ vec4 color;
+ vec4 color2;
+ float scale;
+} uPC;
+
+vec4
+getColor2()
+{
+ return uPC.color2;
+}
diff --git a/Test/link.vk.differentPC.1.2.frag b/Test/link.vk.differentPC.1.2.frag
new file mode 100755
index 0000000..f5ad4ce
--- /dev/null
+++ b/Test/link.vk.differentPC.1.2.frag
@@ -0,0 +1,18 @@
+#version 450
+
+layout(location=0) out vec4 color;
+
+layout (push_constant) uniform PushConstantBlock
+{
+ vec4 color;
+ vec4 color2;
+ float scale;
+} uPC;
+
+vec4 getColor2();
+float getScale();
+
+void main()
+{
+ color = uPC.color + getColor2() * getScale();
+}
diff --git a/Test/link.vk.matchingPC.0.0.frag b/Test/link.vk.matchingPC.0.0.frag
new file mode 100755
index 0000000..f5ad4ce
--- /dev/null
+++ b/Test/link.vk.matchingPC.0.0.frag
@@ -0,0 +1,18 @@
+#version 450
+
+layout(location=0) out vec4 color;
+
+layout (push_constant) uniform PushConstantBlock
+{
+ vec4 color;
+ vec4 color2;
+ float scale;
+} uPC;
+
+vec4 getColor2();
+float getScale();
+
+void main()
+{
+ color = uPC.color + getColor2() * getScale();
+}
diff --git a/Test/link.vk.matchingPC.0.1.frag b/Test/link.vk.matchingPC.0.1.frag
new file mode 100755
index 0000000..972fc65
--- /dev/null
+++ b/Test/link.vk.matchingPC.0.1.frag
@@ -0,0 +1,14 @@
+#version 450
+
+layout (push_constant) uniform PushConstantBlock
+{
+ vec4 color;
+ vec4 color2;
+ float scale;
+} uPC;
+
+vec4
+getColor2()
+{
+ return uPC.color2;
+}
diff --git a/Test/link.vk.matchingPC.0.2.frag b/Test/link.vk.matchingPC.0.2.frag
new file mode 100755
index 0000000..734358c
--- /dev/null
+++ b/Test/link.vk.matchingPC.0.2.frag
@@ -0,0 +1,14 @@
+#version 450
+
+layout (push_constant) uniform PushConstantBlock
+{
+ vec4 color;
+ vec4 color2;
+ float scale;
+} uPC;
+
+float
+getScale()
+{
+ return uPC.scale;
+}
diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp
index fe51ec9..7fa084b 100644
--- a/glslang/MachineIndependent/linkValidate.cpp
+++ b/glslang/MachineIndependent/linkValidate.cpp
@@ -138,7 +138,11 @@
MERGE_MAX(spvVersion.openGl);
numErrors += unit.getNumErrors();
- numPushConstants += unit.numPushConstants;
+ // Only one push_constant is allowed, mergeLinkerObjects() will ensure the push_constant
+ // is the same for all units.
+ if (numPushConstants > 1 || unit.numPushConstants > 1)
+ error(infoSink, "Only one push_constant block is allowed per stage");
+ numPushConstants = std::min(numPushConstants + unit.numPushConstants, 1);
if (unit.invocations != TQualifier::layoutNotSet) {
if (invocations == TQualifier::layoutNotSet)
@@ -462,6 +466,9 @@
// Check for consistent types/qualification/initializers etc.
mergeErrorCheck(infoSink, *symbol, *unitSymbol, false);
}
+ // If different symbols, verify they arn't push_constant since there can only be one per stage
+ else if (symbol->getQualifier().isPushConstant() && unitSymbol->getQualifier().isPushConstant())
+ error(infoSink, "Only one push_constant block is allowed per stage");
}
if (merge)
linkerObjects.push_back(unitLinkerObjects[unitLinkObj]);
diff --git a/gtests/Link.FromFile.Vk.cpp b/gtests/Link.FromFile.Vk.cpp
index fe96bd9..a032f11 100644
--- a/gtests/Link.FromFile.Vk.cpp
+++ b/gtests/Link.FromFile.Vk.cpp
@@ -50,6 +50,7 @@
const size_t fileCount = fileNames.size();
const EShMessages controls = DeriveOptions(Source::GLSL, Semantics::Vulkan, Target::AST);
GlslangResult result;
+ result.validationResult = false;
// Compile each input shader file.
bool success = true;
@@ -108,6 +109,12 @@
::testing::ValuesIn(std::vector<std::vector<std::string>>({
{"link1.vk.frag", "link2.vk.frag"},
{"spv.unit1.frag", "spv.unit2.frag", "spv.unit3.frag"},
+ {"link.vk.matchingPC.0.0.frag", "link.vk.matchingPC.0.1.frag",
+ "link.vk.matchingPC.0.2.frag"},
+ {"link.vk.differentPC.0.0.frag", "link.vk.differentPC.0.1.frag",
+ "link.vk.differentPC.0.2.frag"},
+ {"link.vk.differentPC.1.0.frag", "link.vk.differentPC.1.1.frag",
+ "link.vk.differentPC.1.2.frag"},
}))
);
// clang-format on