Fix #2005. Allow multiple compilation units to declare identical push_constant blocks...
authorMalcolm Bechard <mbechard@users.noreply.github.com>
Mon, 16 Mar 2020 14:51:15 +0000 (10:51 -0400)
committerGitHub <noreply@github.com>
Mon, 16 Mar 2020 14:51:15 +0000 (08:51 -0600)
* 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

14 files changed:
Test/baseResults/link.vk.differentPC.0.0.frag.out [new file with mode: 0755]
Test/baseResults/link.vk.differentPC.1.0.frag.out [new file with mode: 0755]
Test/baseResults/link.vk.matchingPC.0.0.frag.out [new file with mode: 0755]
Test/link.vk.differentPC.0.0.frag [new file with mode: 0755]
Test/link.vk.differentPC.0.1.frag [new file with mode: 0755]
Test/link.vk.differentPC.0.2.frag [new file with mode: 0755]
Test/link.vk.differentPC.1.0.frag [new file with mode: 0755]
Test/link.vk.differentPC.1.1.frag [new file with mode: 0755]
Test/link.vk.differentPC.1.2.frag [new file with mode: 0755]
Test/link.vk.matchingPC.0.0.frag [new file with mode: 0755]
Test/link.vk.matchingPC.0.1.frag [new file with mode: 0755]
Test/link.vk.matchingPC.0.2.frag [new file with mode: 0755]
glslang/MachineIndependent/linkValidate.cpp
gtests/Link.FromFile.Vk.cpp

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 (executable)
index 0000000..d7cfd22
--- /dev/null
@@ -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 (executable)
index 0000000..632f18b
--- /dev/null
@@ -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 (executable)
index 0000000..1d6875a
--- /dev/null
@@ -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 (executable)
index 0000000..f5ad4ce
--- /dev/null
@@ -0,0 +1,18 @@
+#version 450\r
+\r
+layout(location=0) out vec4 color;\r
+\r
+layout (push_constant) uniform PushConstantBlock\r
+{\r
+       vec4 color;\r
+       vec4 color2;\r
+       float scale;\r
+} uPC;\r
+\r
+vec4 getColor2();\r
+float getScale();\r
+\r
+void main()\r
+{\r
+    color = uPC.color + getColor2() * getScale();\r
+}\r
diff --git a/Test/link.vk.differentPC.0.1.frag b/Test/link.vk.differentPC.0.1.frag
new file mode 100755 (executable)
index 0000000..972fc65
--- /dev/null
@@ -0,0 +1,14 @@
+#version 450\r
+\r
+layout (push_constant) uniform PushConstantBlock\r
+{\r
+       vec4 color;\r
+       vec4 color2;\r
+       float scale;\r
+} uPC;\r
+\r
+vec4\r
+getColor2()\r
+{\r
+       return uPC.color2;\r
+}\r
diff --git a/Test/link.vk.differentPC.0.2.frag b/Test/link.vk.differentPC.0.2.frag
new file mode 100755 (executable)
index 0000000..287e425
--- /dev/null
@@ -0,0 +1,15 @@
+#version 450\r
+\r
+layout (push_constant) uniform PushConstantBlock\r
+{\r
+       vec4 color;\r
+       vec4 color2;\r
+       float scale2;\r
+} uPC;\r
+\r
+float\r
+getScale()\r
+{\r
+       return uPC.scale2;\r
+}\r
+\r
diff --git a/Test/link.vk.differentPC.1.0.frag b/Test/link.vk.differentPC.1.0.frag
new file mode 100755 (executable)
index 0000000..e395bb8
--- /dev/null
@@ -0,0 +1,16 @@
+#version 450\r
+\r
+layout (push_constant) uniform PushConstantBlock\r
+{\r
+       vec4 color;\r
+       vec4 color2;\r
+       float scale;\r
+       float scale2;\r
+} uPC;\r
+\r
+float\r
+getScale()\r
+{\r
+       return uPC.scale;\r
+}\r
+\r
diff --git a/Test/link.vk.differentPC.1.1.frag b/Test/link.vk.differentPC.1.1.frag
new file mode 100755 (executable)
index 0000000..972fc65
--- /dev/null
@@ -0,0 +1,14 @@
+#version 450\r
+\r
+layout (push_constant) uniform PushConstantBlock\r
+{\r
+       vec4 color;\r
+       vec4 color2;\r
+       float scale;\r
+} uPC;\r
+\r
+vec4\r
+getColor2()\r
+{\r
+       return uPC.color2;\r
+}\r
diff --git a/Test/link.vk.differentPC.1.2.frag b/Test/link.vk.differentPC.1.2.frag
new file mode 100755 (executable)
index 0000000..f5ad4ce
--- /dev/null
@@ -0,0 +1,18 @@
+#version 450\r
+\r
+layout(location=0) out vec4 color;\r
+\r
+layout (push_constant) uniform PushConstantBlock\r
+{\r
+       vec4 color;\r
+       vec4 color2;\r
+       float scale;\r
+} uPC;\r
+\r
+vec4 getColor2();\r
+float getScale();\r
+\r
+void main()\r
+{\r
+    color = uPC.color + getColor2() * getScale();\r
+}\r
diff --git a/Test/link.vk.matchingPC.0.0.frag b/Test/link.vk.matchingPC.0.0.frag
new file mode 100755 (executable)
index 0000000..f5ad4ce
--- /dev/null
@@ -0,0 +1,18 @@
+#version 450\r
+\r
+layout(location=0) out vec4 color;\r
+\r
+layout (push_constant) uniform PushConstantBlock\r
+{\r
+       vec4 color;\r
+       vec4 color2;\r
+       float scale;\r
+} uPC;\r
+\r
+vec4 getColor2();\r
+float getScale();\r
+\r
+void main()\r
+{\r
+    color = uPC.color + getColor2() * getScale();\r
+}\r
diff --git a/Test/link.vk.matchingPC.0.1.frag b/Test/link.vk.matchingPC.0.1.frag
new file mode 100755 (executable)
index 0000000..972fc65
--- /dev/null
@@ -0,0 +1,14 @@
+#version 450\r
+\r
+layout (push_constant) uniform PushConstantBlock\r
+{\r
+       vec4 color;\r
+       vec4 color2;\r
+       float scale;\r
+} uPC;\r
+\r
+vec4\r
+getColor2()\r
+{\r
+       return uPC.color2;\r
+}\r
diff --git a/Test/link.vk.matchingPC.0.2.frag b/Test/link.vk.matchingPC.0.2.frag
new file mode 100755 (executable)
index 0000000..734358c
--- /dev/null
@@ -0,0 +1,14 @@
+#version 450\r
+\r
+layout (push_constant) uniform PushConstantBlock\r
+{\r
+       vec4 color;\r
+       vec4 color2;\r
+       float scale;\r
+} uPC;\r
+\r
+float\r
+getScale()\r
+{\r
+       return uPC.scale;\r
+}\r
index fe51ec9..7fa084b 100644 (file)
@@ -138,7 +138,11 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
     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 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
                 // 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]);
index fe96bd9..a032f11 100644 (file)
@@ -50,6 +50,7 @@ TEST_P(LinkTestVulkan, FromFile)
     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 @@ INSTANTIATE_TEST_CASE_P(
     ::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