Merge pull request #1697 from sparmarNV/fix-NV_mesh_shader

Fix resizing of gl_PrimitiveIndicesNV[] to max_primitives*geomSize
This commit is contained in:
John Kessenich 2019-02-14 17:49:29 +07:00 committed by GitHub
commit da1be9a322
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 150 additions and 88 deletions

View File

@ -1,7 +1,7 @@
spv.meshShaderBuiltins.mesh spv.meshShaderBuiltins.mesh
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80007 // Generated by (magic number): 80007
// Id's are bound by 146 // Id's are bound by 148
Capability ClipDistance Capability ClipDistance
Capability CullDistance Capability CullDistance
@ -14,7 +14,7 @@ spv.meshShaderBuiltins.mesh
Extension "SPV_NV_viewport_array2" Extension "SPV_NV_viewport_array2"
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 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 LocalSize 32 1 1
ExecutionMode 4 OutputVertices 81 ExecutionMode 4 OutputVertices 81
ExecutionMode 4 OutputPrimitivesNV 32 ExecutionMode 4 OutputPrimitivesNV 32
@ -43,9 +43,9 @@ spv.meshShaderBuiltins.mesh
MemberName 84(gl_MeshPerPrimitiveNV) 4 "gl_LayerPerViewNV" MemberName 84(gl_MeshPerPrimitiveNV) 4 "gl_LayerPerViewNV"
MemberName 84(gl_MeshPerPrimitiveNV) 5 "gl_ViewportMaskPerViewNV" MemberName 84(gl_MeshPerPrimitiveNV) 5 "gl_ViewportMaskPerViewNV"
Name 88 "gl_MeshPrimitivesNV" Name 88 "gl_MeshPrimitivesNV"
Name 128 "gl_PrimitiveIndicesNV" Name 129 "gl_PrimitiveIndicesNV"
Name 139 "gl_DrawID" Name 142 "gl_DrawID"
Name 143 "gl_PrimitiveCountNV" Name 146 "gl_PrimitiveCountNV"
Decorate 11(gl_LocalInvocationID) BuiltIn LocalInvocationId Decorate 11(gl_LocalInvocationID) BuiltIn LocalInvocationId
Decorate 17(gl_WorkGroupID) BuiltIn WorkgroupId Decorate 17(gl_WorkGroupID) BuiltIn WorkgroupId
MemberDecorate 30(gl_MeshPerVertexNV) 0 BuiltIn Position 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 PerViewNV
MemberDecorate 84(gl_MeshPerPrimitiveNV) 5 BuiltIn ViewportMaskPerViewNV MemberDecorate 84(gl_MeshPerPrimitiveNV) 5 BuiltIn ViewportMaskPerViewNV
Decorate 84(gl_MeshPerPrimitiveNV) Block Decorate 84(gl_MeshPerPrimitiveNV) Block
Decorate 128(gl_PrimitiveIndicesNV) BuiltIn PrimitiveIndicesNV Decorate 129(gl_PrimitiveIndicesNV) BuiltIn PrimitiveIndicesNV
Decorate 139(gl_DrawID) BuiltIn DrawIndex Decorate 142(gl_DrawID) BuiltIn DrawIndex
Decorate 143(gl_PrimitiveCountNV) BuiltIn PrimitiveCountNV Decorate 146(gl_PrimitiveCountNV) BuiltIn PrimitiveCountNV
Decorate 145 BuiltIn WorkgroupSize Decorate 147 BuiltIn WorkgroupSize
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeInt 32 0 6: TypeInt 32 0
@ -130,17 +130,18 @@ spv.meshShaderBuiltins.mesh
94: 36(int) Constant 7 94: 36(int) Constant 7
97: 36(int) Constant 8 97: 36(int) Constant 8
100: 36(int) Constant 9 100: 36(int) Constant 9
126: TypeArray 6(int) 31 126: 6(int) Constant 96
127: TypePointer Output 126 127: TypeArray 6(int) 126
128(gl_PrimitiveIndicesNV): 127(ptr) Variable Output 128: TypePointer Output 127
129: 6(int) Constant 257 129(gl_PrimitiveIndicesNV): 128(ptr) Variable Output
130: TypePointer Output 6(int) 130: 6(int) Constant 257
138: TypePointer Input 36(int) 131: TypePointer Output 6(int)
139(gl_DrawID): 138(ptr) Variable Input 133: 36(int) Constant 95
142: 6(int) Constant 16909060 141: TypePointer Input 36(int)
143(gl_PrimitiveCountNV): 130(ptr) Variable Output 142(gl_DrawID): 141(ptr) Variable Input
144: 6(int) Constant 96 145: 6(int) Constant 16909060
145: 9(ivec3) ConstantComposite 85 27 27 146(gl_PrimitiveCountNV): 131(ptr) Variable Output
147: 9(ivec3) ConstantComposite 85 27 27
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
8(iid): 7(ptr) Variable Function 8(iid): 7(ptr) Variable Function
@ -239,19 +240,21 @@ spv.meshShaderBuiltins.mesh
Store 125 124 Store 125 124
MemoryBarrier 27 55 MemoryBarrier 27 55
ControlBarrier 56 56 55 ControlBarrier 56 56 55
131: 130(ptr) AccessChain 128(gl_PrimitiveIndicesNV) 37 132: 131(ptr) AccessChain 129(gl_PrimitiveIndicesNV) 37
Store 131 129 Store 132 130
132: 6(int) Load 16(gid) 134: 131(ptr) AccessChain 129(gl_PrimitiveIndicesNV) 133
133: 6(int) Load 16(gid) Store 134 56
134: 6(int) ISub 133 27 135: 6(int) Load 16(gid)
135: 130(ptr) AccessChain 128(gl_PrimitiveIndicesNV) 134 136: 6(int) Load 16(gid)
136: 6(int) Load 135 137: 6(int) ISub 136 27
137: 130(ptr) AccessChain 128(gl_PrimitiveIndicesNV) 132 138: 131(ptr) AccessChain 129(gl_PrimitiveIndicesNV) 137
Store 137 136 139: 6(int) Load 138
140: 36(int) Load 139(gl_DrawID) 140: 131(ptr) AccessChain 129(gl_PrimitiveIndicesNV) 135
141: 6(int) Bitcast 140 Store 140 139
142: 141 WritePackedPrimitiveIndices4x8NV 143: 36(int) Load 142(gl_DrawID)
Store 143(gl_PrimitiveCountNV) 144 144: 6(int) Bitcast 143
145: 144 WritePackedPrimitiveIndices4x8NV
Store 146(gl_PrimitiveCountNV) 126
MemoryBarrier 27 55 MemoryBarrier 27 55
ControlBarrier 56 56 55 ControlBarrier 56 56 55
Return Return

View File

@ -1,7 +1,7 @@
spv.meshShaderRedeclBuiltins.mesh spv.meshShaderRedeclBuiltins.mesh
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80007 // Generated by (magic number): 80007
// Id's are bound by 120 // Id's are bound by 129
Capability ClipDistance Capability ClipDistance
Capability CullDistance Capability CullDistance
@ -12,7 +12,7 @@ spv.meshShaderRedeclBuiltins.mesh
Extension "SPV_NV_viewport_array2" Extension "SPV_NV_viewport_array2"
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 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 LocalSize 32 1 1
ExecutionMode 4 OutputVertices 81 ExecutionMode 4 OutputVertices 81
ExecutionMode 4 OutputPrimitivesNV 32 ExecutionMode 4 OutputPrimitivesNV 32
@ -36,6 +36,8 @@ spv.meshShaderRedeclBuiltins.mesh
MemberName 77(gl_MeshPerPrimitiveNV) 2 "gl_ViewportIndex" MemberName 77(gl_MeshPerPrimitiveNV) 2 "gl_ViewportIndex"
MemberName 77(gl_MeshPerPrimitiveNV) 3 "gl_ViewportMask" MemberName 77(gl_MeshPerPrimitiveNV) 3 "gl_ViewportMask"
Name 81 "gl_MeshPrimitivesNV" Name 81 "gl_MeshPrimitivesNV"
Name 122 "gl_PrimitiveIndicesNV"
Name 127 "gl_PrimitiveCountNV"
Decorate 11(gl_LocalInvocationID) BuiltIn LocalInvocationId Decorate 11(gl_LocalInvocationID) BuiltIn LocalInvocationId
Decorate 17(gl_WorkGroupID) BuiltIn WorkgroupId Decorate 17(gl_WorkGroupID) BuiltIn WorkgroupId
MemberDecorate 24(gl_MeshPerVertexNV) 0 BuiltIn Position 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 PerPrimitiveNV
MemberDecorate 77(gl_MeshPerPrimitiveNV) 3 BuiltIn ViewportMaskNV MemberDecorate 77(gl_MeshPerPrimitiveNV) 3 BuiltIn ViewportMaskNV
Decorate 77(gl_MeshPerPrimitiveNV) Block 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 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeInt 32 0 6: TypeInt 32 0
@ -98,7 +102,14 @@ spv.meshShaderRedeclBuiltins.mesh
87: 30(int) Constant 7 87: 30(int) Constant 7
90: 30(int) Constant 8 90: 30(int) Constant 8
93: 30(int) Constant 9 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 4(main): 2 Function None 3
5: Label 5: Label
8(iid): 7(ptr) Variable Function 8(iid): 7(ptr) Variable Function
@ -197,5 +208,10 @@ spv.meshShaderRedeclBuiltins.mesh
Store 118 117 Store 118 117
MemoryBarrier 49 50 MemoryBarrier 49 50
ControlBarrier 51 51 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 Return
FunctionEnd FunctionEnd

View File

@ -50,8 +50,9 @@ void main()
BARRIER(); BARRIER();
// should truncate 257 -> 1 // check bound limits
gl_PrimitiveIndicesNV[0] = 257; gl_PrimitiveIndicesNV[0] = 257; // should truncate 257 -> 1
gl_PrimitiveIndicesNV[(MAX_PRIM * 3) - 1] = 2;
gl_PrimitiveIndicesNV[gid] = gl_PrimitiveIndicesNV[gid-1]; gl_PrimitiveIndicesNV[gid] = gl_PrimitiveIndicesNV[gid-1];
// writes 4 indices at offset gl_DrawID // writes 4 indices at offset gl_DrawID

View File

@ -22,14 +22,16 @@ out gl_MeshPerVertexNV {
float gl_PointSize; float gl_PointSize;
float gl_ClipDistance[4]; float gl_ClipDistance[4];
float gl_CullDistance[4]; float gl_CullDistance[4];
} gl_MeshVerticesNV[]; } gl_MeshVerticesNV[MAX_VER]; // explicitly sized to MAX_VER
perprimitiveNV out gl_MeshPerPrimitiveNV { perprimitiveNV out gl_MeshPerPrimitiveNV {
int gl_PrimitiveID; int gl_PrimitiveID;
int gl_Layer; int gl_Layer;
int gl_ViewportIndex; int gl_ViewportIndex;
int gl_ViewportMask[]; int gl_ViewportMask[];
} gl_MeshPrimitivesNV[]; } gl_MeshPrimitivesNV[]; // implicitly sized to MAX_PRIM
out uint gl_PrimitiveIndicesNV[MAX_PRIM*3]; // explicitly sized to MAX_PRIM * 3
void main() void main()
{ {
@ -63,4 +65,9 @@ void main()
gl_MeshPrimitivesNV[iid+1].gl_ViewportMask[0] = gl_MeshPrimitivesNV[iid].gl_ViewportMask[0]; gl_MeshPrimitivesNV[iid+1].gl_ViewportMask[0] = gl_MeshPrimitivesNV[iid].gl_ViewportMask[0];
BARRIER(); BARRIER();
// check bound limits
gl_PrimitiveIndicesNV[0] = 1;
gl_PrimitiveIndicesNV[(MAX_PRIM * 3) - 1] = 2;
gl_PrimitiveCountNV = MAX_PRIM * 3;
} }

View File

@ -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) // fix array size, if it can be fixed and needs to be fixed (will allow variable indexing)
if (symbolNode->getType().isUnsizedArray()) { if (symbolNode->getType().isUnsizedArray()) {
int newSize = getIoArrayImplicitSize(symbolNode->getType().getQualifier().isPerPrimitive()); int newSize = getIoArrayImplicitSize(symbolNode->getType().getQualifier());
if (newSize > 0) if (newSize > 0)
symbolNode->getWritableType().changeOuterArraySize(newSize); symbolNode->getWritableType().changeOuterArraySize(newSize);
} }
@ -586,59 +586,80 @@ void TParseContext::handleIoResizeArrayAccess(const TSourceLoc& /*loc*/, TInterm
// Types without an array size will be given one. // Types without an array size will be given one.
// Types already having a size that is wrong will get an error. // 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, bool tailOnly)
{ {
int requiredSize = getIoArrayImplicitSize(isPerPrimitive); int requiredSize = 0;
if (requiredSize == 0) TString featureString;
return; size_t listSize = ioArraySymbolResizeList.size();
size_t i = 0;
const char* feature; // If tailOnly = true, only check the last array symbol in the list.
if (language == EShLangGeometry) if (tailOnly) {
feature = TQualifier::getGeometryString(intermediate.getInputPrimitive()); i = listSize - 1;
else if (language == EShLangTessControl }
for (bool firstIteration = true; i < listSize; ++i) {
TType &type = ioArraySymbolResizeList[i]->getWritableType();
// As I/O array sizes don't change, fetch requiredSize only once,
// except for mesh shaders which could have different I/O array sizes based on type qualifiers.
if (firstIteration
#ifdef NV_EXTENSIONS #ifdef NV_EXTENSIONS
|| language == EShLangFragment || (language == EShLangMeshNV)
#endif #endif
) )
{
feature = "vertices"; requiredSize = getIoArrayImplicitSize(type.getQualifier(), &featureString);
#ifdef NV_EXTENSIONS if (requiredSize == 0)
else if (language == EShLangMeshNV) { break;
feature = isPerPrimitive ? "max_primitives" : "max_vertices"; firstIteration = false;
}
#endif
else
feature = "unknown";
if (tailOnly) {
checkIoArrayConsistency(loc, requiredSize, feature, ioArraySymbolResizeList.back()->getWritableType(), ioArraySymbolResizeList.back()->getName());
return;
} }
for (size_t i = 0; i < ioArraySymbolResizeList.size(); ++i) checkIoArrayConsistency(loc, requiredSize, featureString.c_str(), type,
checkIoArrayConsistency(loc, requiredSize, feature, ioArraySymbolResizeList[i]->getWritableType(), ioArraySymbolResizeList[i]->getName()); ioArraySymbolResizeList[i]->getName());
}
} }
int TParseContext::getIoArrayImplicitSize(bool isPerPrimitive) const int TParseContext::getIoArrayImplicitSize(const TQualifier &qualifier, TString *featureString) const
{ {
if (language == EShLangGeometry) int expectedSize = 0;
return TQualifier::mapGeometryToSize(intermediate.getInputPrimitive()); TString str = "unknown";
else if (language == EShLangTessControl) unsigned int maxVertices = intermediate.getVertices() != TQualifier::layoutNotSet ? intermediate.getVertices() : 0;
return intermediate.getVertices() != TQualifier::layoutNotSet ? intermediate.getVertices() : 0;
if (language == EShLangGeometry) {
expectedSize = TQualifier::mapGeometryToSize(intermediate.getInputPrimitive());
str = TQualifier::getGeometryString(intermediate.getInputPrimitive());
}
else if (language == EShLangTessControl) {
expectedSize = maxVertices;
str = "vertices";
}
#ifdef NV_EXTENSIONS #ifdef NV_EXTENSIONS
else if (language == EShLangFragment) else if (language == EShLangFragment) {
return 3; //Number of vertices for Fragment shader is always three. // Number of vertices for Fragment shader is always three.
expectedSize = 3;
str = "vertices";
}
else if (language == EShLangMeshNV) { else if (language == EShLangMeshNV) {
if (isPerPrimitive) { unsigned int maxPrimitives =
return intermediate.getPrimitives() != TQualifier::layoutNotSet ? intermediate.getPrimitives() : 0; intermediate.getPrimitives() != TQualifier::layoutNotSet ? intermediate.getPrimitives() : 0;
} else { if (qualifier.builtIn == EbvPrimitiveIndicesNV) {
return intermediate.getVertices() != TQualifier::layoutNotSet ? intermediate.getVertices() : 0; expectedSize = maxPrimitives * TQualifier::mapGeometryToSize(intermediate.getOutputPrimitive());
str = "max_primitives*";
str += TQualifier::getGeometryString(intermediate.getOutputPrimitive());
}
else if (qualifier.isPerPrimitive()) {
expectedSize = maxPrimitives;
str = "max_primitives";
}
else {
expectedSize = maxVertices;
str = "max_vertices";
} }
} }
#endif #endif
if (featureString)
else *featureString = str;
return 0; return expectedSize;
} }
void TParseContext::checkIoArrayConsistency(const TSourceLoc& loc, int requiredSize, const char* feature, TType& type, const TString& name) void TParseContext::checkIoArrayConsistency(const TSourceLoc& loc, int requiredSize, const char* feature, TType& type, const TString& name)
@ -1386,7 +1407,7 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction
#endif #endif
) )
{ {
length = getIoArrayImplicitSize(type.getQualifier().isPerPrimitive()); length = getIoArrayImplicitSize(type.getQualifier());
} }
} }
if (length == 0) { if (length == 0) {
@ -3730,7 +3751,7 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie
if (! symbolTable.atBuiltInLevel()) { if (! symbolTable.atBuiltInLevel()) {
if (isIoResizeArray(type)) { if (isIoResizeArray(type)) {
ioArraySymbolResizeList.push_back(symbol); ioArraySymbolResizeList.push_back(symbol);
checkIoArraysConsistency(loc, true, type.getQualifier().isPerPrimitive()); checkIoArraysConsistency(loc, true);
} else } else
fixIoArraySize(loc, symbol->getWritableType()); fixIoArraySize(loc, symbol->getWritableType());
} }
@ -3783,7 +3804,7 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie
existingType.updateArraySizes(type); existingType.updateArraySizes(type);
if (isIoResizeArray(type)) if (isIoResizeArray(type))
checkIoArraysConsistency(loc, false, type.getQualifier().isPerPrimitive()); checkIoArraysConsistency(loc);
} }
// Policy and error check for needing a runtime sized array. // Policy and error check for needing a runtime sized array.
@ -3939,6 +3960,7 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
#ifdef NV_EXTENSIONS #ifdef NV_EXTENSIONS
identifier == "gl_SampleMask" || identifier == "gl_SampleMask" ||
identifier == "gl_Layer" || identifier == "gl_Layer" ||
identifier == "gl_PrimitiveIndicesNV" ||
#endif #endif
identifier == "gl_TexCoord") { identifier == "gl_TexCoord") {
@ -4018,7 +4040,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()); 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()) if (qualifier.hasLayout())
error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str()); error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str());
if (qualifier.storage != EvqVaryingOut) if (qualifier.storage != EvqVaryingOut)
@ -4270,7 +4296,7 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT
// Tracking for implicit sizing of array // Tracking for implicit sizing of array
if (isIoResizeArray(block->getType())) { if (isIoResizeArray(block->getType())) {
ioArraySymbolResizeList.push_back(block); ioArraySymbolResizeList.push_back(block);
checkIoArraysConsistency(loc, true, block->getType().getQualifier().isPerPrimitive()); checkIoArraysConsistency(loc, true);
} else if (block->getType().isArray()) } else if (block->getType().isArray())
fixIoArraySize(loc, block->getWritableType()); fixIoArraySize(loc, block->getWritableType());
@ -7102,7 +7128,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
// fix up // fix up
if (isIoResizeArray(blockType)) { if (isIoResizeArray(blockType)) {
ioArraySymbolResizeList.push_back(&variable); ioArraySymbolResizeList.push_back(&variable);
checkIoArraysConsistency(loc, true, blockType.getQualifier().isPerPrimitive()); checkIoArraysConsistency(loc, true);
} else } else
fixIoArraySize(loc, variable.getWritableType()); fixIoArraySize(loc, variable.getWritableType());
@ -7685,6 +7711,14 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
else else
error(loc, "can only apply to 'in'", "derivative_group_linearNV", ""); error(loc, "can only apply to 'in'", "derivative_group_linearNV", "");
} }
// Check mesh out array sizes, once all the necessary out qualifiers are defined.
if ((language == EShLangMeshNV) &&
(intermediate.getVertices() != TQualifier::layoutNotSet) &&
(intermediate.getPrimitives() != TQualifier::layoutNotSet) &&
(intermediate.getOutputPrimitive() != ElgNone))
{
checkIoArraysConsistency(loc);
}
#endif #endif
const TQualifier& qualifier = publicType.qualifier; const TQualifier& qualifier = publicType.qualifier;
@ -7835,3 +7869,4 @@ TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expre
} }
} // end namespace glslang } // end namespace glslang

View File

@ -299,8 +299,8 @@ public:
void fixIoArraySize(const TSourceLoc&, TType&); void fixIoArraySize(const TSourceLoc&, TType&);
void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier); void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier);
void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base); void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base);
void checkIoArraysConsistency(const TSourceLoc&, bool tailOnly = false, bool isPerPrimitive = false); void checkIoArraysConsistency(const TSourceLoc&, bool tailOnly = false);
int getIoArrayImplicitSize(bool isPerPrimitive = false) const; int getIoArrayImplicitSize(const TQualifier&, TString* featureString = nullptr) const;
void checkIoArrayConsistency(const TSourceLoc&, int requiredSize, const char* feature, TType&, const TString&); 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); TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);