Require fixed workgroup size declaration
authorJeremy Hayes <jeremy@lunarg.com>
Tue, 23 Feb 2021 01:21:25 +0000 (18:21 -0700)
committerJeremy Hayes <jeremy@lunarg.com>
Wed, 24 Feb 2021 21:49:31 +0000 (14:49 -0700)
Fix 2479.

Test/baseResults/negativeWorkGroupSize.comp.out [new file with mode: 0644]
Test/negativeWorkGroupSize.comp [new file with mode: 0644]
glslang/MachineIndependent/ParseHelper.cpp
glslang/MachineIndependent/localintermediate.h
gtests/AST.FromFile.cpp

diff --git a/Test/baseResults/negativeWorkGroupSize.comp.out b/Test/baseResults/negativeWorkGroupSize.comp.out
new file mode 100644 (file)
index 0000000..7ae3798
--- /dev/null
@@ -0,0 +1,69 @@
+negativeWorkGroupSize.comp
+ERROR: 0:4: 'initializer' : can't read from gl_WorkGroupSize before a fixed workgroup size has been declared 
+ERROR: 1 compilation errors.  No code generated.
+
+
+Shader version: 460
+local_size = (64, 1, 1)
+ERROR: node is still EOpNull!
+0:3  Function Definition: fn( ( global void)
+0:3    Function Parameters: 
+0:4    Sequence
+0:4      Sequence
+0:4        move second child to first child ( temp 3-component vector of uint)
+0:4          'wgs' ( temp 3-component vector of uint)
+0:4          Constant:
+0:4            1 (const uint)
+0:4            1 (const uint)
+0:4            1 (const uint)
+0:9  Function Definition: main( ( global void)
+0:9    Function Parameters: 
+0:10    Sequence
+0:10      Function Call: fn( ( global void)
+0:11      Sequence
+0:11        move second child to first child ( temp 3-component vector of uint)
+0:11          'wgs' ( temp 3-component vector of uint)
+0:11          Constant:
+0:11            64 (const uint)
+0:11            1 (const uint)
+0:11            1 (const uint)
+0:?   Linker Objects
+0:?     'gl_WorkGroupSize' ( const 3-component vector of uint WorkGroupSize)
+0:?       64 (const uint)
+0:?       1 (const uint)
+0:?       1 (const uint)
+
+
+Linked compute stage:
+
+
+Shader version: 460
+local_size = (64, 1, 1)
+ERROR: node is still EOpNull!
+0:3  Function Definition: fn( ( global void)
+0:3    Function Parameters: 
+0:4    Sequence
+0:4      Sequence
+0:4        move second child to first child ( temp 3-component vector of uint)
+0:4          'wgs' ( temp 3-component vector of uint)
+0:4          Constant:
+0:4            1 (const uint)
+0:4            1 (const uint)
+0:4            1 (const uint)
+0:9  Function Definition: main( ( global void)
+0:9    Function Parameters: 
+0:10    Sequence
+0:10      Function Call: fn( ( global void)
+0:11      Sequence
+0:11        move second child to first child ( temp 3-component vector of uint)
+0:11          'wgs' ( temp 3-component vector of uint)
+0:11          Constant:
+0:11            64 (const uint)
+0:11            1 (const uint)
+0:11            1 (const uint)
+0:?   Linker Objects
+0:?     'gl_WorkGroupSize' ( const 3-component vector of uint WorkGroupSize)
+0:?       64 (const uint)
+0:?       1 (const uint)
+0:?       1 (const uint)
+
diff --git a/Test/negativeWorkGroupSize.comp b/Test/negativeWorkGroupSize.comp
new file mode 100644 (file)
index 0000000..1f007d0
--- /dev/null
@@ -0,0 +1,12 @@
+#version 460
+
+void fn(){
+    uvec3 wgs = gl_WorkGroupSize; // error: fixed workgroup size has not been declared
+}
+
+layout(local_size_x = 64) in; // declare workgroup size
+
+void main(){
+    fn();
+    uvec3 wgs = gl_WorkGroupSize; // valid
+}
index 88c278a..ea530ce 100644 (file)
@@ -2756,6 +2756,11 @@ void TParseContext::rValueErrorCheck(const TSourceLoc& loc, const char* op, TInt
     if (!(symNode && symNode->getQualifier().isWriteOnly())) // base class checks
         if (symNode && symNode->getQualifier().isExplicitInterpolation())
             error(loc, "can't read from explicitly-interpolated object: ", op, symNode->getName().c_str());
+
+    // local_size_{xyz} must be assigned or specialized before gl_WorkGroupSize can be assigned. 
+    if(node->getQualifier().builtIn == EbvWorkGroupSize &&
+       !(intermediate.isLocalSizeSet() || intermediate.isLocalSizeSpecialized()))
+        error(loc, "can't read from gl_WorkGroupSize before a fixed workgroup size has been declared", op, "");
 }
 
 //
index 1db3d1c..9fe684a 100644 (file)
@@ -550,6 +550,11 @@ public:
         return true;
     }
     unsigned int getLocalSize(int dim) const { return localSize[dim]; }
+    bool isLocalSizeSet() const
+    {
+        // Return true if any component has been set (i.e. any component is not default).
+        return localSizeNotDefault[0] || localSizeNotDefault[1] || localSizeNotDefault[2];
+    }
     bool setLocalSizeSpecId(int dim, int id)
     {
         if (localSizeSpecId[dim] != TQualifier::layoutNotSet)
@@ -558,6 +563,13 @@ public:
         return true;
     }
     int getLocalSizeSpecId(int dim) const { return localSizeSpecId[dim]; }
+    bool isLocalSizeSpecialized() const
+    {
+        // Return true if any component has been specialized.
+        return localSizeSpecId[0] != TQualifier::layoutNotSet ||
+               localSizeSpecId[1] != TQualifier::layoutNotSet ||
+               localSizeSpecId[2] != TQualifier::layoutNotSet;
+    }
 #ifdef GLSLANG_WEB
     void output(TInfoSink&, bool tree) { }
 
index dc7fea3..8885b29 100644 (file)
@@ -280,6 +280,7 @@ INSTANTIATE_TEST_SUITE_P(
         "glsl.es320.subgroupVote.comp",
         "terminate.frag",
         "terminate.vert",
+        "negativeWorkGroupSize.comp",
     })),
     FileNameAsCustomTestSuffix
 );