Fix resizing of gl_PrimitiveIndicesNV[] to max_primitives*geomSize
authorSahil Parmar <sparmar@nvidia.com>
Mon, 11 Feb 2019 23:12:13 +0000 (15:12 -0800)
committerSahil Parmar <sparmar@nvidia.com>
Mon, 11 Feb 2019 23:15:33 +0000 (15:15 -0800)
- This change also allows redeclaration of gl_PrimitiveIndicesNV and
  adds error checks against incorrect explicit array size.
- Also modifies gtests to check array bound limits and redeclare gl_PrimitiveIndicesNV[].

Test/baseResults/spv.meshShaderBuiltins.mesh.out
Test/baseResults/spv.meshShaderRedeclBuiltins.mesh.out
Test/spv.meshShaderBuiltins.mesh
Test/spv.meshShaderRedeclBuiltins.mesh
glslang/MachineIndependent/ParseHelper.cpp
glslang/MachineIndependent/ParseHelper.h

index 8090f7b..38d363b 100644 (file)
@@ -1,7 +1,7 @@
 spv.meshShaderBuiltins.mesh
 // Module Version 10000
 // Generated by (magic number): 80007
-// Id's are bound by 146
+// Id's are bound by 148
 
                               Capability ClipDistance
                               Capability CullDistance
@@ -14,7 +14,7 @@ spv.meshShaderBuiltins.mesh
                               Extension  "SPV_NV_viewport_array2"
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
-                              EntryPoint MeshNV 4  "main" 11 17 34 88 128 139 143
+                              EntryPoint MeshNV 4  "main" 11 17 34 88 129 142 146
                               ExecutionMode 4 LocalSize 32 1 1
                               ExecutionMode 4 OutputVertices 81
                               ExecutionMode 4 OutputPrimitivesNV 32
@@ -43,9 +43,9 @@ spv.meshShaderBuiltins.mesh
                               MemberName 84(gl_MeshPerPrimitiveNV) 4  "gl_LayerPerViewNV"
                               MemberName 84(gl_MeshPerPrimitiveNV) 5  "gl_ViewportMaskPerViewNV"
                               Name 88  "gl_MeshPrimitivesNV"
-                              Name 128  "gl_PrimitiveIndicesNV"
-                              Name 139  "gl_DrawID"
-                              Name 143  "gl_PrimitiveCountNV"
+                              Name 129  "gl_PrimitiveIndicesNV"
+                              Name 142  "gl_DrawID"
+                              Name 146  "gl_PrimitiveCountNV"
                               Decorate 11(gl_LocalInvocationID) BuiltIn LocalInvocationId
                               Decorate 17(gl_WorkGroupID) BuiltIn WorkgroupId
                               MemberDecorate 30(gl_MeshPerVertexNV) 0 BuiltIn Position
@@ -74,10 +74,10 @@ spv.meshShaderBuiltins.mesh
                               MemberDecorate 84(gl_MeshPerPrimitiveNV) 5 PerViewNV
                               MemberDecorate 84(gl_MeshPerPrimitiveNV) 5 BuiltIn ViewportMaskPerViewNV
                               Decorate 84(gl_MeshPerPrimitiveNV) Block
-                              Decorate 128(gl_PrimitiveIndicesNV) BuiltIn PrimitiveIndicesNV
-                              Decorate 139(gl_DrawID) BuiltIn DrawIndex
-                              Decorate 143(gl_PrimitiveCountNV) BuiltIn PrimitiveCountNV
-                              Decorate 145 BuiltIn WorkgroupSize
+                              Decorate 129(gl_PrimitiveIndicesNV) BuiltIn PrimitiveIndicesNV
+                              Decorate 142(gl_DrawID) BuiltIn DrawIndex
+                              Decorate 146(gl_PrimitiveCountNV) BuiltIn PrimitiveCountNV
+                              Decorate 147 BuiltIn WorkgroupSize
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeInt 32 0
@@ -130,17 +130,18 @@ spv.meshShaderBuiltins.mesh
               94:     36(int) Constant 7
               97:     36(int) Constant 8
              100:     36(int) Constant 9
-             126:             TypeArray 6(int) 31
-             127:             TypePointer Output 126
-128(gl_PrimitiveIndicesNV):    127(ptr) Variable Output
-             129:      6(int) Constant 257
-             130:             TypePointer Output 6(int)
-             138:             TypePointer Input 36(int)
-  139(gl_DrawID):    138(ptr) Variable Input
-             142:      6(int) Constant 16909060
-143(gl_PrimitiveCountNV):    130(ptr) Variable Output
-             144:      6(int) Constant 96
-             145:    9(ivec3) ConstantComposite 85 27 27
+             126:      6(int) Constant 96
+             127:             TypeArray 6(int) 126
+             128:             TypePointer Output 127
+129(gl_PrimitiveIndicesNV):    128(ptr) Variable Output
+             130:      6(int) Constant 257
+             131:             TypePointer Output 6(int)
+             133:     36(int) Constant 95
+             141:             TypePointer Input 36(int)
+  142(gl_DrawID):    141(ptr) Variable Input
+             145:      6(int) Constant 16909060
+146(gl_PrimitiveCountNV):    131(ptr) Variable Output
+             147:    9(ivec3) ConstantComposite 85 27 27
          4(main):           2 Function None 3
                5:             Label
           8(iid):      7(ptr) Variable Function
@@ -239,19 +240,21 @@ spv.meshShaderBuiltins.mesh
                               Store 125 124
                               MemoryBarrier 27 55
                               ControlBarrier 56 56 55
-             131:    130(ptr) AccessChain 128(gl_PrimitiveIndicesNV) 37
-                              Store 131 129
-             132:      6(int) Load 16(gid)
-             133:      6(int) Load 16(gid)
-             134:      6(int) ISub 133 27
-             135:    130(ptr) AccessChain 128(gl_PrimitiveIndicesNV) 134
-             136:      6(int) Load 135
-             137:    130(ptr) AccessChain 128(gl_PrimitiveIndicesNV) 132
-                              Store 137 136
-             140:     36(int) Load 139(gl_DrawID)
-             141:      6(int) Bitcast 140
-             142:         141 WritePackedPrimitiveIndices4x8NV
-                              Store 143(gl_PrimitiveCountNV) 144
+             132:    131(ptr) AccessChain 129(gl_PrimitiveIndicesNV) 37
+                              Store 132 130
+             134:    131(ptr) AccessChain 129(gl_PrimitiveIndicesNV) 133
+                              Store 134 56
+             135:      6(int) Load 16(gid)
+             136:      6(int) Load 16(gid)
+             137:      6(int) ISub 136 27
+             138:    131(ptr) AccessChain 129(gl_PrimitiveIndicesNV) 137
+             139:      6(int) Load 138
+             140:    131(ptr) AccessChain 129(gl_PrimitiveIndicesNV) 135
+                              Store 140 139
+             143:     36(int) Load 142(gl_DrawID)
+             144:      6(int) Bitcast 143
+             145:         144 WritePackedPrimitiveIndices4x8NV
+                              Store 146(gl_PrimitiveCountNV) 126
                               MemoryBarrier 27 55
                               ControlBarrier 56 56 55
                               Return
index f4491c0..4afbef9 100644 (file)
@@ -1,7 +1,7 @@
 spv.meshShaderRedeclBuiltins.mesh
 // Module Version 10000
 // Generated by (magic number): 80007
-// Id's are bound by 120
+// Id's are bound by 129
 
                               Capability ClipDistance
                               Capability CullDistance
@@ -12,7 +12,7 @@ spv.meshShaderRedeclBuiltins.mesh
                               Extension  "SPV_NV_viewport_array2"
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
-                              EntryPoint MeshNV 4  "main" 11 17 28 81
+                              EntryPoint MeshNV 4  "main" 11 17 28 81 122 127
                               ExecutionMode 4 LocalSize 32 1 1
                               ExecutionMode 4 OutputVertices 81
                               ExecutionMode 4 OutputPrimitivesNV 32
@@ -36,6 +36,8 @@ spv.meshShaderRedeclBuiltins.mesh
                               MemberName 77(gl_MeshPerPrimitiveNV) 2  "gl_ViewportIndex"
                               MemberName 77(gl_MeshPerPrimitiveNV) 3  "gl_ViewportMask"
                               Name 81  "gl_MeshPrimitivesNV"
+                              Name 122  "gl_PrimitiveIndicesNV"
+                              Name 127  "gl_PrimitiveCountNV"
                               Decorate 11(gl_LocalInvocationID) BuiltIn LocalInvocationId
                               Decorate 17(gl_WorkGroupID) BuiltIn WorkgroupId
                               MemberDecorate 24(gl_MeshPerVertexNV) 0 BuiltIn Position
@@ -52,7 +54,9 @@ spv.meshShaderRedeclBuiltins.mesh
                               MemberDecorate 77(gl_MeshPerPrimitiveNV) 3 PerPrimitiveNV
                               MemberDecorate 77(gl_MeshPerPrimitiveNV) 3 BuiltIn ViewportMaskNV
                               Decorate 77(gl_MeshPerPrimitiveNV) Block
-                              Decorate 119 BuiltIn WorkgroupSize
+                              Decorate 122(gl_PrimitiveIndicesNV) BuiltIn PrimitiveIndicesNV
+                              Decorate 127(gl_PrimitiveCountNV) BuiltIn PrimitiveCountNV
+                              Decorate 128 BuiltIn WorkgroupSize
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeInt 32 0
@@ -98,7 +102,14 @@ spv.meshShaderRedeclBuiltins.mesh
               87:     30(int) Constant 7
               90:     30(int) Constant 8
               93:     30(int) Constant 9
-             119:    9(ivec3) ConstantComposite 78 49 49
+             119:      6(int) Constant 96
+             120:             TypeArray 6(int) 119
+             121:             TypePointer Output 120
+122(gl_PrimitiveIndicesNV):    121(ptr) Variable Output
+             123:             TypePointer Output 6(int)
+             125:     30(int) Constant 95
+127(gl_PrimitiveCountNV):    123(ptr) Variable Output
+             128:    9(ivec3) ConstantComposite 78 49 49
          4(main):           2 Function None 3
                5:             Label
           8(iid):      7(ptr) Variable Function
@@ -197,5 +208,10 @@ spv.meshShaderRedeclBuiltins.mesh
                               Store 118 117
                               MemoryBarrier 49 50
                               ControlBarrier 51 51 50
+             124:    123(ptr) AccessChain 122(gl_PrimitiveIndicesNV) 31
+                              Store 124 49
+             126:    123(ptr) AccessChain 122(gl_PrimitiveIndicesNV) 125
+                              Store 126 51
+                              Store 127(gl_PrimitiveCountNV) 119
                               Return
                               FunctionEnd
index 8adff3d..0240a17 100644 (file)
@@ -50,8 +50,9 @@ void main()
 
     BARRIER();
 
-    // should truncate 257 -> 1
-    gl_PrimitiveIndicesNV[0] = 257;
+    // check bound limits
+    gl_PrimitiveIndicesNV[0] = 257; // should truncate 257 -> 1
+    gl_PrimitiveIndicesNV[(MAX_PRIM * 3) - 1] = 2;
     gl_PrimitiveIndicesNV[gid] = gl_PrimitiveIndicesNV[gid-1];
 
     // writes 4 indices at offset gl_DrawID
index 38107b2..d89439b 100644 (file)
@@ -22,14 +22,16 @@ out gl_MeshPerVertexNV {
     float gl_PointSize;
     float gl_ClipDistance[4];
     float gl_CullDistance[4];
-} gl_MeshVerticesNV[];
+} gl_MeshVerticesNV[MAX_VER];       // explicitly sized to MAX_VER
 
 perprimitiveNV out gl_MeshPerPrimitiveNV {
     int gl_PrimitiveID;
     int gl_Layer;
     int gl_ViewportIndex;
     int gl_ViewportMask[];
-} gl_MeshPrimitivesNV[];
+} gl_MeshPrimitivesNV[];            // implicitly sized to MAX_PRIM
+
+out uint gl_PrimitiveIndicesNV[];   // explicitly sized to MAX_PRIM * 3
 
 void main()
 {
@@ -63,4 +65,9 @@ void main()
     gl_MeshPrimitivesNV[iid+1].gl_ViewportMask[0] = gl_MeshPrimitivesNV[iid].gl_ViewportMask[0];
 
     BARRIER();
+
+    // check bound limits
+    gl_PrimitiveIndicesNV[0] = 1;
+    gl_PrimitiveIndicesNV[(MAX_PRIM * 3) - 1] = 2;
+    gl_PrimitiveCountNV = MAX_PRIM * 3;
 }
index 6e38658..27ee78f 100755 (executable)
@@ -572,7 +572,7 @@ void TParseContext::handleIoResizeArrayAccess(const TSourceLoc& /*loc*/, TInterm
 
     // fix array size, if it can be fixed and needs to be fixed (will allow variable indexing)
     if (symbolNode->getType().isUnsizedArray()) {
-        int newSize = getIoArrayImplicitSize(symbolNode->getType().getQualifier().isPerPrimitive());
+        int newSize = getIoArrayImplicitSize(symbolNode->getType().getQualifier());
         if (newSize > 0)
             symbolNode->getWritableType().changeOuterArraySize(newSize);
     }
@@ -586,9 +586,9 @@ void TParseContext::handleIoResizeArrayAccess(const TSourceLoc& /*loc*/, TInterm
 // Types without an array size will be given one.
 // Types already having a size that is wrong will get an error.
 //
-void TParseContext::checkIoArraysConsistency(const TSourceLoc& loc, bool tailOnly, bool isPerPrimitive)
+void TParseContext::checkIoArraysConsistency(const TSourceLoc &loc, const TQualifier &qualifier, bool tailOnly)
 {
-    int requiredSize = getIoArrayImplicitSize(isPerPrimitive);
+    int requiredSize = getIoArrayImplicitSize(qualifier);
     if (requiredSize == 0)
         return;
 
@@ -603,9 +603,15 @@ void TParseContext::checkIoArraysConsistency(const TSourceLoc& loc, bool tailOnl
 
         feature = "vertices";
 #ifdef NV_EXTENSIONS
-     else if (language == EShLangMeshNV) {
-        feature = isPerPrimitive ? "max_primitives" : "max_vertices";
-     }
+    else if (language == EShLangMeshNV) {
+        if (qualifier.builtIn == EbvPrimitiveIndicesNV) {
+            TLayoutGeometry outPrimitive = intermediate.getOutputPrimitive();
+            TString featureString = "max_primitives*";
+            featureString += TQualifier::getGeometryString(outPrimitive);
+            feature = featureString.c_str();
+        } else
+            feature = qualifier.isPerPrimitive() ? "max_primitives" : "max_vertices";
+    }
 #endif
     else
         feature = "unknown";
@@ -619,21 +625,24 @@ void TParseContext::checkIoArraysConsistency(const TSourceLoc& loc, bool tailOnl
         checkIoArrayConsistency(loc, requiredSize, feature, ioArraySymbolResizeList[i]->getWritableType(), ioArraySymbolResizeList[i]->getName());
 }
 
-int TParseContext::getIoArrayImplicitSize(bool isPerPrimitive) const
+int TParseContext::getIoArrayImplicitSize(const TQualifier& qualifier) const
 {
+    unsigned int maxVertices = intermediate.getVertices() != TQualifier::layoutNotSet ? intermediate.getVertices() : 0;
     if (language == EShLangGeometry)
         return TQualifier::mapGeometryToSize(intermediate.getInputPrimitive());
     else if (language == EShLangTessControl)
-        return intermediate.getVertices() != TQualifier::layoutNotSet ? intermediate.getVertices() : 0;
+        return maxVertices;
 #ifdef NV_EXTENSIONS
     else if (language == EShLangFragment)
         return 3; //Number of vertices for Fragment shader is always three.
     else if (language == EShLangMeshNV) {
-        if (isPerPrimitive) {
-            return intermediate.getPrimitives() != TQualifier::layoutNotSet ? intermediate.getPrimitives() : 0;
-        } else {
-            return intermediate.getVertices() != TQualifier::layoutNotSet ? intermediate.getVertices() : 0;
-        }
+        unsigned int maxPrimitives = intermediate.getPrimitives() != TQualifier::layoutNotSet ? intermediate.getPrimitives() : 0;
+        if (qualifier.builtIn == EbvPrimitiveIndicesNV)
+            return maxPrimitives * TQualifier::mapGeometryToSize(intermediate.getOutputPrimitive());
+        else if (qualifier.isPerPrimitive())
+            return maxPrimitives;
+        else
+            return maxVertices;
     }
 #endif
 
@@ -1386,7 +1395,7 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction
 #endif
                         )
                     {
-                        length = getIoArrayImplicitSize(type.getQualifier().isPerPrimitive());
+                        length = getIoArrayImplicitSize(type.getQualifier());
                     }
                 }
                 if (length == 0) {
@@ -3730,7 +3739,7 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie
             if (! symbolTable.atBuiltInLevel()) {
                 if (isIoResizeArray(type)) {
                     ioArraySymbolResizeList.push_back(symbol);
-                    checkIoArraysConsistency(loc, true, type.getQualifier().isPerPrimitive());
+                    checkIoArraysConsistency(loc, symbol->getType().getQualifier(), true);
                 } else
                     fixIoArraySize(loc, symbol->getWritableType());
             }
@@ -3783,7 +3792,7 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie
     existingType.updateArraySizes(type);
 
     if (isIoResizeArray(type))
-        checkIoArraysConsistency(loc, false, type.getQualifier().isPerPrimitive());
+        checkIoArraysConsistency(loc, symbol->getType().getQualifier(), true);
 }
 
 // Policy and error check for needing a runtime sized array.
@@ -3939,6 +3948,7 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
 #ifdef NV_EXTENSIONS
          identifier == "gl_SampleMask"                                                              ||
          identifier == "gl_Layer"                                                                   ||
+         identifier == "gl_PrimitiveIndicesNV"                                                      ||
 #endif
          identifier == "gl_TexCoord") {
 
@@ -4018,7 +4028,11 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
                     error(loc, "all redeclarations must use the same depth layout on", "redeclaration", symbol->getName().c_str());
             }
         }
-        else if (identifier == "gl_FragStencilRefARB") {
+        else if (
+#ifdef NV_EXTENSIONS
+            identifier == "gl_PrimitiveIndicesNV" ||
+#endif
+            identifier == "gl_FragStencilRefARB") {
             if (qualifier.hasLayout())
                 error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str());
             if (qualifier.storage != EvqVaryingOut)
@@ -4270,7 +4284,7 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT
     // Tracking for implicit sizing of array
     if (isIoResizeArray(block->getType())) {
         ioArraySymbolResizeList.push_back(block);
-        checkIoArraysConsistency(loc, true, block->getType().getQualifier().isPerPrimitive());
+        checkIoArraysConsistency(loc, block->getType().getQualifier(), true);
     } else if (block->getType().isArray())
         fixIoArraySize(loc, block->getWritableType());
 
@@ -7102,7 +7116,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
     // fix up
     if (isIoResizeArray(blockType)) {
         ioArraySymbolResizeList.push_back(&variable);
-        checkIoArraysConsistency(loc, true, blockType.getQualifier().isPerPrimitive());
+        checkIoArraysConsistency(loc, blockType.getQualifier(), true);
     } else
         fixIoArraySize(loc, variable.getWritableType());
 
@@ -7489,7 +7503,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
             error(loc, "cannot change previously set layout value", id, "");
 
         if (language == EShLangTessControl)
-            checkIoArraysConsistency(loc);
+            checkIoArraysConsistency(loc, publicType.qualifier);
     }
 #ifdef NV_EXTENSIONS
     if (publicType.shaderQualifiers.primitives != TQualifier::layoutNotSet) {
@@ -7526,7 +7540,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
 #endif
                 if (intermediate.setInputPrimitive(publicType.shaderQualifiers.geometry)) {
                     if (language == EShLangGeometry)
-                        checkIoArraysConsistency(loc);
+                        checkIoArraysConsistency(loc, publicType.qualifier);
                 } else
                     error(loc, "cannot change previously set input primitive", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
                 break;
@@ -7835,3 +7849,4 @@ TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expre
 }
 
 } // end namespace glslang
+
index 5b7d430..44a9d76 100755 (executable)
@@ -299,8 +299,8 @@ public:
     void fixIoArraySize(const TSourceLoc&, TType&);
     void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier);
     void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base);
-    void checkIoArraysConsistency(const TSourceLoc&, bool tailOnly = false, bool isPerPrimitive = false);
-    int getIoArrayImplicitSize(bool isPerPrimitive = false) const;
+    void checkIoArraysConsistency(const TSourceLoc&, const TQualifier&, bool tailOnly = false);
+    int getIoArrayImplicitSize(const TQualifier&) const;
     void checkIoArrayConsistency(const TSourceLoc&, int requiredSize, const char* feature, TType&, const TString&);
 
     TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);