From 494a02a2b0adf74f93dafd5f6be3080de01950bf Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Fri, 11 Dec 2015 15:44:12 -0700 Subject: [PATCH] Semantics: Geometry stage can support max_vertices = 0. To do this, more generally use a named -1 as a not set value. --- Test/420.tesc | 4 ++- Test/baseResults/150.tesc.out | 5 +-- Test/baseResults/410.geom.out | 4 +-- Test/baseResults/410.tesc.out | 4 +-- Test/baseResults/420.geom.out | 4 +-- Test/baseResults/420.tesc.out | 3 +- Test/baseResults/420_size_gl_in.geom.out | 4 +-- Test/baseResults/450.geom.out | 4 +-- Test/baseResults/450.tesc.out | 4 +-- Test/baseResults/mains1.frag.out | 6 ++-- Test/baseResults/max_vertices_0.geom.out | 35 +++++++++++++++++++ Test/max_vertices_0.geom | 12 +++++++ Test/runtests | 1 + glslang/Include/Types.h | 14 ++++---- glslang/Include/revision.h | 2 +- glslang/MachineIndependent/ParseHelper.cpp | 13 ++++--- glslang/MachineIndependent/linkValidate.cpp | 6 ++-- .../MachineIndependent/localintermediate.h | 4 +-- 18 files changed, 93 insertions(+), 36 deletions(-) create mode 100644 Test/baseResults/max_vertices_0.geom.out create mode 100644 Test/max_vertices_0.geom diff --git a/Test/420.tesc b/Test/420.tesc index 04ac4433a..b9fd21c2f 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 484718c79..a5289c93d 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 51ab99343..b1f5a5758 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 7c536c06d..3305c407f 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 99d6274ed..fdb2cc88e 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 ed5fbea73..db65fd999 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 bb7e5150a..577c246d7 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 d39c09989..0876a0c34 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 8f8c2a448..8a8e9fbf2 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 9a10431f3..140dae818 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 000000000..85f2e3858 --- /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 000000000..4a420be10 --- /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 ea881bcc4..c324911c0 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 ec179439c..ca6caf112 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 eee5008f1..a35b8be62 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 72c6996b9..7dcaa52d9 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 19edae46f..e769982ca 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 17f8bc4f0..501086c16 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;