diff --git a/Test/420.tesc b/Test/420.tesc index 04ac4433a80aa3be0d34af37db7e8e16d4f2ad3b..b9fd21c2fd5f7df81b4cc065a5ae268190dc5734 100644 --- a/Test/420.tesc +++ b/Test/420.tesc @@ -38,4 +38,6 @@ void foo() { ; } -} \ No newline at end of file +} + +layout(vertices = 0) out; // ERROR, can't be 0 diff --git a/Test/baseResults/150.tesc.out b/Test/baseResults/150.tesc.out index 484718c796cb613189c47829d4806805b5f10db7..a5289c93d015a1838239df69bd191d8051067fd9 100644 --- a/Test/baseResults/150.tesc.out +++ b/Test/baseResults/150.tesc.out @@ -586,7 +586,7 @@ ERROR: 1 compilation errors. No code generated. Shader version: 400 -vertices = 0 +vertices = -1 ERROR: node is still EOpNull! 0:8 Function Definition: main( (global void) 0:8 Function Parameters: @@ -603,7 +603,8 @@ ERROR: 0:12: 'vertices' : inconsistent output number of vertices for array size ERROR: 0:26: 'gl_PointSize' : no such field in structure ERROR: 0:26: 'assign' : cannot convert from 'temp float' to 'temp block{out 4-component vector of float Position gl_Position}' ERROR: 0:29: 'out' : type must be an array: outf -ERROR: 6 compilation errors. No code generated. +ERROR: 0:43: 'vertices' : must be greater than 0 +ERROR: 7 compilation errors. No code generated. Shader version: 420 diff --git a/Test/baseResults/410.geom.out b/Test/baseResults/410.geom.out index 51ab9934391b039a0e23d9d7a23706d68d7d23ed..b1f5a5758fc008b2f6d613e3bc9dcd1e89a791f1 100644 --- a/Test/baseResults/410.geom.out +++ b/Test/baseResults/410.geom.out @@ -13,7 +13,7 @@ ERROR: 7 compilation errors. No code generated. Shader version: 410 invocations = 0 -max_vertices = 0 +max_vertices = -1 input primitive = none output primitive = none ERROR: node is still EOpNull! @@ -66,7 +66,7 @@ ERROR: Linking geometry stage: At least one shader must specify a layout(max_ver Shader version: 410 invocations = 0 -max_vertices = 0 +max_vertices = -1 input primitive = none output primitive = none ERROR: node is still EOpNull! diff --git a/Test/baseResults/410.tesc.out b/Test/baseResults/410.tesc.out index 7c536c06db68fcc7cb0007bf88e78bf782b60a1b..3305c407fd83a9937e4c87e529e20cd00a06f23e 100644 --- a/Test/baseResults/410.tesc.out +++ b/Test/baseResults/410.tesc.out @@ -5,7 +5,7 @@ ERROR: 1 compilation errors. No code generated. Shader version: 400 -vertices = 0 +vertices = -1 ERROR: node is still EOpNull! 0:8 Function Definition: main( (global void) 0:8 Function Parameters: @@ -20,7 +20,7 @@ Linked tessellation control stage: ERROR: Linking tessellation control stage: At least one shader must specify an output layout(vertices=...) Shader version: 400 -vertices = 0 +vertices = -1 ERROR: node is still EOpNull! 0:8 Function Definition: main( (global void) 0:8 Function Parameters: diff --git a/Test/baseResults/420.geom.out b/Test/baseResults/420.geom.out index 99d6274edc46e10420484f90426e61480c1618a8..fdb2cc88e2fbbdb8cbf3ea28e247bbd7ce7092be 100644 --- a/Test/baseResults/420.geom.out +++ b/Test/baseResults/420.geom.out @@ -11,7 +11,7 @@ ERROR: 6 compilation errors. No code generated. Shader version: 420 invocations = 0 -max_vertices = 0 +max_vertices = -1 input primitive = triangles output primitive = none ERROR: node is still EOpNull! @@ -138,7 +138,7 @@ ERROR: Linking geometry stage: At least one shader must specify a layout(max_ver Shader version: 420 invocations = 0 -max_vertices = 0 +max_vertices = -1 input primitive = triangles output primitive = none ERROR: node is still EOpNull! diff --git a/Test/baseResults/420.tesc.out b/Test/baseResults/420.tesc.out index ed5fbea7367496e526915048973f7fe918a7a755..db65fd999a0d64a8f87b6b3ae4984ae712e3d616 100644 --- a/Test/baseResults/420.tesc.out +++ b/Test/baseResults/420.tesc.out @@ -6,7 +6,8 @@ ERROR: 0:12: 'vertices' : inconsistent output number of vertices for array size ERROR: 0:26: 'gl_PointSize' : no such field in structure ERROR: 0:26: 'assign' : cannot convert from 'temp float' to 'temp block{out 4-component vector of float Position gl_Position}' ERROR: 0:29: 'out' : type must be an array: outf -ERROR: 6 compilation errors. No code generated. +ERROR: 0:43: 'vertices' : must be greater than 0 +ERROR: 7 compilation errors. No code generated. Shader version: 420 diff --git a/Test/baseResults/420_size_gl_in.geom.out b/Test/baseResults/420_size_gl_in.geom.out index bb7e5150ac557d25a2572f2fe4e76481a7c40280..577c246d7ec7376f9973ce8b30ecfc3c39b4decb 100644 --- a/Test/baseResults/420_size_gl_in.geom.out +++ b/Test/baseResults/420_size_gl_in.geom.out @@ -6,7 +6,7 @@ ERROR: 1 compilation errors. No code generated. Shader version: 420 invocations = 0 -max_vertices = 0 +max_vertices = -1 input primitive = triangles output primitive = none ERROR: node is still EOpNull! @@ -45,7 +45,7 @@ ERROR: Linking geometry stage: At least one shader must specify a layout(max_ver Shader version: 420 invocations = 0 -max_vertices = 0 +max_vertices = -1 input primitive = triangles output primitive = none ERROR: node is still EOpNull! diff --git a/Test/baseResults/450.geom.out b/Test/baseResults/450.geom.out index d39c0998910238c81884866a8f9e969f9f6d5c17..0876a0c344b685d9366089a18d5413a9e99d2250 100644 --- a/Test/baseResults/450.geom.out +++ b/Test/baseResults/450.geom.out @@ -3,7 +3,7 @@ Warning, version 450 is not yet complete; most version-specific features are pre Shader version: 450 invocations = 0 -max_vertices = 0 +max_vertices = -1 input primitive = none output primitive = none 0:? Sequence @@ -41,7 +41,7 @@ ERROR: Linking geometry stage: At least one shader must specify a layout(max_ver Shader version: 450 invocations = 0 -max_vertices = 0 +max_vertices = -1 input primitive = none output primitive = none 0:? Sequence diff --git a/Test/baseResults/450.tesc.out b/Test/baseResults/450.tesc.out index 8f8c2a44896840540a913b21d299222854d93b11..8a8e9fbf240167b41d0329835e7da2486f0d5697 100644 --- a/Test/baseResults/450.tesc.out +++ b/Test/baseResults/450.tesc.out @@ -2,7 +2,7 @@ Warning, version 450 is not yet complete; most version-specific features are present, but some are missing. Shader version: 450 -vertices = 0 +vertices = -1 0:? Sequence 0:11 Function Definition: main( (global void) 0:11 Function Parameters: @@ -37,7 +37,7 @@ Linked tessellation control stage: ERROR: Linking tessellation control stage: At least one shader must specify an output layout(vertices=...) Shader version: 450 -vertices = 0 +vertices = -1 0:? Sequence 0:11 Function Definition: main( (global void) 0:11 Function Parameters: diff --git a/Test/baseResults/mains1.frag.out b/Test/baseResults/mains1.frag.out index 9a10431f3a8a6bed9700f289576acb352ad47d98..140dae8182166d4ffe7c8532c1054af725059b55 100644 --- a/Test/baseResults/mains1.frag.out +++ b/Test/baseResults/mains1.frag.out @@ -19,7 +19,7 @@ ERROR: 1 compilation errors. No code generated. Shader version: 150 invocations = 0 -max_vertices = 0 +max_vertices = -1 input primitive = none output primitive = points ERROR: node is still EOpNull! @@ -30,7 +30,7 @@ ERROR: node is still EOpNull! noMain2.geom Shader version: 150 invocations = 0 -max_vertices = 0 +max_vertices = -1 input primitive = none output primitive = line_strip 0:? Sequence @@ -53,7 +53,7 @@ ERROR: Linking fragment stage: Multiple function bodies in multiple compilation Shader version: 150 invocations = 0 -max_vertices = 0 +max_vertices = -1 input primitive = none output primitive = points ERROR: node is still EOpNull! diff --git a/Test/baseResults/max_vertices_0.geom.out b/Test/baseResults/max_vertices_0.geom.out new file mode 100644 index 0000000000000000000000000000000000000000..85f2e385818606f3a4c92f995a4df7fd56c6f1a1 --- /dev/null +++ b/Test/baseResults/max_vertices_0.geom.out @@ -0,0 +1,35 @@ +max_vertices_0.geom +Shader version: 330 +invocations = 0 +max_vertices = 0 +input primitive = points +output primitive = triangle_strip +0:? Sequence +0:8 Function Definition: main( (global void) +0:8 Function Parameters: +0:10 Sequence +0:10 EndPrimitive (global void) +0:11 EndPrimitive (global void) +0:? Linker Objects +0:? 'v_geom_FragColor' (in 1-element array of 4-component vector of float) +0:? 'v_frag_FragColor' (layout(stream=0 ) out 4-component vector of float) + + +Linked geometry stage: + + +Shader version: 330 +invocations = 0 +max_vertices = 0 +input primitive = points +output primitive = triangle_strip +0:? Sequence +0:8 Function Definition: main( (global void) +0:8 Function Parameters: +0:10 Sequence +0:10 EndPrimitive (global void) +0:11 EndPrimitive (global void) +0:? Linker Objects +0:? 'v_geom_FragColor' (in 1-element array of 4-component vector of float) +0:? 'v_frag_FragColor' (layout(stream=0 ) out 4-component vector of float) + diff --git a/Test/max_vertices_0.geom b/Test/max_vertices_0.geom new file mode 100644 index 0000000000000000000000000000000000000000..4a420be10f1f44d9ff4c4a8fbde703da42ccd3fe --- /dev/null +++ b/Test/max_vertices_0.geom @@ -0,0 +1,12 @@ +#version 330 + +layout(points) in; +layout(triangle_strip, max_vertices = 0) out; +in highp vec4 v_geom_FragColor[]; +out highp vec4 v_frag_FragColor; + +void main (void) +{ + EndPrimitive(); + EndPrimitive(); +} diff --git a/Test/runtests b/Test/runtests index ea881bcc4d787d8a3eebbdf6bad186112a6d39ea..c324911c07d0797cfca397c3f65ebfb1f9b39d54 100755 --- a/Test/runtests +++ b/Test/runtests @@ -84,6 +84,7 @@ runBulkTest 300link2.frag runBulkTest 300link3.frag runBulkTest empty.frag empty2.frag empty3.frag runBulkTest 150.tesc 150.tese 400.tesc 400.tese 410.tesc 420.tesc 420.tese +runBulkTest max_vertices_0.geom # # reflection tests diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index ec179439c2075d6907942ad91a5875523c228d65..ca6caf112f8a7f3db75d9fea853d34a7d2be97f0 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -327,6 +327,8 @@ enum TBlendEquationShift { class TQualifier { public: + static const int layoutNotSet = -1; + void clear() { precision = EpqNone; @@ -489,8 +491,8 @@ public: { layoutMatrix = ElmNone; layoutPacking = ElpNone; - layoutOffset = -1; - layoutAlign = -1; + layoutOffset = layoutNotSet; + layoutAlign = layoutNotSet; layoutLocation = layoutLocationEnd; layoutComponent = layoutComponentEnd; @@ -567,11 +569,11 @@ public: } bool hasOffset() const { - return layoutOffset != -1; + return layoutOffset != layoutNotSet; } bool hasAlign() const { - return layoutAlign != -1; + return layoutAlign != layoutNotSet; } bool hasAnyLocation() const { @@ -789,7 +791,7 @@ struct TShaderQualifiers { originUpperLeft = false; pixelCenterInteger = false; invocations = 0; // 0 means no declaration - vertices = 0; + vertices = TQualifier::layoutNotSet; spacing = EvsNone; order = EvoNone; pointMode = false; @@ -813,7 +815,7 @@ struct TShaderQualifiers { originUpperLeft = src.originUpperLeft; if (src.invocations != 0) invocations = src.invocations; - if (src.vertices != 0) + if (src.vertices != TQualifier::layoutNotSet) vertices = src.vertices; if (src.spacing != EvsNone) spacing = src.spacing; diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h index eee5008f1385d50d8b2bd5bdf4ccf59eb20bc03d..a35b8be62dacc300d5e42bf8dc620c5ef14024c4 100644 --- a/glslang/Include/revision.h +++ b/glslang/Include/revision.h @@ -2,5 +2,5 @@ // For the version, it uses the latest git tag followed by the number of commits. // For the date, it uses the current date (when then script is run). -#define GLSLANG_REVISION "SPIRV99.839" +#define GLSLANG_REVISION "SPIRV99.841" #define GLSLANG_DATE "11-Dec-2015" diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 72c6996b96c2f07d87221dbdba74b0d5ca8fb0b0..7dcaa52d930cee794317ce60fcfe713f97199390 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -662,7 +662,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().isImplicitlySizedArray()) { int newSize = getIoArrayImplicitSize(); - if (newSize) + if (newSize > 0) symbolNode->getWritableType().changeOuterArraySize(newSize); } } @@ -703,7 +703,7 @@ int TParseContext::getIoArrayImplicitSize() const if (language == EShLangGeometry) return TQualifier::mapGeometryToSize(intermediate.getInputPrimitive()); else if (language == EShLangTessControl) - return intermediate.getVertices(); + return intermediate.getVertices() != TQualifier::layoutNotSet ? intermediate.getVertices() : 0; else return 0; } @@ -3875,7 +3875,10 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi case EShLangTessControl: if (id == "vertices") { - publicType.shaderQualifiers.vertices = value; + if (value == 0) + error(loc, "must be greater than 0", "vertices", ""); + else + publicType.shaderQualifiers.vertices = value; return; } break; @@ -4275,7 +4278,7 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua error(loc, message, TQualifier::getGeometryString(shaderQualifiers.geometry), ""); if (shaderQualifiers.invocations > 0) error(loc, message, "invocations", ""); - if (shaderQualifiers.vertices > 0) { + if (shaderQualifiers.vertices != TQualifier::layoutNotSet) { if (language == EShLangGeometry) error(loc, message, "max_vertices", ""); else if (language == EShLangTessControl) @@ -5438,7 +5441,7 @@ void TParseContext::invariantCheck(const TSourceLoc& loc, const TQualifier& qual // void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, const TPublicType& publicType) { - if (publicType.shaderQualifiers.vertices) { + if (publicType.shaderQualifiers.vertices != TQualifier::layoutNotSet) { assert(language == EShLangTessControl || language == EShLangGeometry); const char* id = (language == EShLangTessControl) ? "vertices" : "max_vertices"; diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp index 19edae46f2692714ba98c9a4384dd1784892f464..e769982ca4476acc1f7b37115527946d83657a6a 100644 --- a/glslang/MachineIndependent/linkValidate.cpp +++ b/glslang/MachineIndependent/linkValidate.cpp @@ -100,7 +100,7 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit) else if (outputPrimitive != unit.outputPrimitive) error(infoSink, "Contradictory output layout primitives"); - if (vertices == 0) + if (vertices == TQualifier::layoutNotSet) vertices = unit.vertices; else if (vertices != unit.vertices) { if (language == EShLangGeometry) @@ -409,7 +409,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink) case EShLangVertex: break; case EShLangTessControl: - if (vertices == 0) + if (vertices == TQualifier::layoutNotSet) error(infoSink, "At least one shader must specify an output layout(vertices=...)"); break; case EShLangTessEvaluation: @@ -425,7 +425,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink) error(infoSink, "At least one shader must specify an input layout primitive"); if (outputPrimitive == ElgNone) error(infoSink, "At least one shader must specify an output layout primitive"); - if (vertices == 0) + if (vertices == TQualifier::layoutNotSet) error(infoSink, "At least one shader must specify a layout(max_vertices = value)"); break; case EShLangFragment: diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 17f8bc4f0465003bba456c6312127553c6c0e9af..501086c16c23c7bedf1e99740ca79fad21f42404 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -126,7 +126,7 @@ class TIntermediate { public: explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : language(l), treeRoot(0), profile(p), version(v), spv(0), numMains(0), numErrors(0), recursive(false), - invocations(0), vertices(0), inputPrimitive(ElgNone), outputPrimitive(ElgNone), pixelCenterInteger(false), originUpperLeft(false), + invocations(0), vertices(TQualifier::layoutNotSet), inputPrimitive(ElgNone), outputPrimitive(ElgNone), pixelCenterInteger(false), originUpperLeft(false), vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false), depthLayout(EldNone), depthReplacing(false), blendEquations(0), xfbMode(false) { localSize[0] = 1; @@ -212,7 +212,7 @@ public: int getInvocations() const { return invocations; } bool setVertices(int m) { - if (vertices > 0) + if (vertices != TQualifier::layoutNotSet) return vertices == m; vertices = m; return true;