Semantics: Geometry stage can support max_vertices = 0.

To do this, more generally use a named -1 as a not set value.
This commit is contained in:
John Kessenich 2015-12-11 15:44:12 -07:00
parent 3c24a06c8c
commit 494a02a2b0
18 changed files with 93 additions and 36 deletions

View File

@ -38,4 +38,6 @@ void foo()
{ {
; ;
} }
} }
layout(vertices = 0) out; // ERROR, can't be 0

View File

@ -586,7 +586,7 @@ ERROR: 1 compilation errors. No code generated.
Shader version: 400 Shader version: 400
vertices = 0 vertices = -1
ERROR: node is still EOpNull! ERROR: node is still EOpNull!
0:8 Function Definition: main( (global void) 0:8 Function Definition: main( (global void)
0:8 Function Parameters: 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: '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: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: 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 Shader version: 420

View File

@ -13,7 +13,7 @@ ERROR: 7 compilation errors. No code generated.
Shader version: 410 Shader version: 410
invocations = 0 invocations = 0
max_vertices = 0 max_vertices = -1
input primitive = none input primitive = none
output primitive = none output primitive = none
ERROR: node is still EOpNull! 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 Shader version: 410
invocations = 0 invocations = 0
max_vertices = 0 max_vertices = -1
input primitive = none input primitive = none
output primitive = none output primitive = none
ERROR: node is still EOpNull! ERROR: node is still EOpNull!

View File

@ -5,7 +5,7 @@ ERROR: 1 compilation errors. No code generated.
Shader version: 400 Shader version: 400
vertices = 0 vertices = -1
ERROR: node is still EOpNull! ERROR: node is still EOpNull!
0:8 Function Definition: main( (global void) 0:8 Function Definition: main( (global void)
0:8 Function Parameters: 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=...) ERROR: Linking tessellation control stage: At least one shader must specify an output layout(vertices=...)
Shader version: 400 Shader version: 400
vertices = 0 vertices = -1
ERROR: node is still EOpNull! ERROR: node is still EOpNull!
0:8 Function Definition: main( (global void) 0:8 Function Definition: main( (global void)
0:8 Function Parameters: 0:8 Function Parameters:

View File

@ -11,7 +11,7 @@ ERROR: 6 compilation errors. No code generated.
Shader version: 420 Shader version: 420
invocations = 0 invocations = 0
max_vertices = 0 max_vertices = -1
input primitive = triangles input primitive = triangles
output primitive = none output primitive = none
ERROR: node is still EOpNull! 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 Shader version: 420
invocations = 0 invocations = 0
max_vertices = 0 max_vertices = -1
input primitive = triangles input primitive = triangles
output primitive = none output primitive = none
ERROR: node is still EOpNull! ERROR: node is still EOpNull!

View File

@ -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: '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: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: 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 Shader version: 420

View File

@ -6,7 +6,7 @@ ERROR: 1 compilation errors. No code generated.
Shader version: 420 Shader version: 420
invocations = 0 invocations = 0
max_vertices = 0 max_vertices = -1
input primitive = triangles input primitive = triangles
output primitive = none output primitive = none
ERROR: node is still EOpNull! 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 Shader version: 420
invocations = 0 invocations = 0
max_vertices = 0 max_vertices = -1
input primitive = triangles input primitive = triangles
output primitive = none output primitive = none
ERROR: node is still EOpNull! ERROR: node is still EOpNull!

View File

@ -3,7 +3,7 @@ Warning, version 450 is not yet complete; most version-specific features are pre
Shader version: 450 Shader version: 450
invocations = 0 invocations = 0
max_vertices = 0 max_vertices = -1
input primitive = none input primitive = none
output primitive = none output primitive = none
0:? Sequence 0:? Sequence
@ -41,7 +41,7 @@ ERROR: Linking geometry stage: At least one shader must specify a layout(max_ver
Shader version: 450 Shader version: 450
invocations = 0 invocations = 0
max_vertices = 0 max_vertices = -1
input primitive = none input primitive = none
output primitive = none output primitive = none
0:? Sequence 0:? Sequence

View File

@ -2,7 +2,7 @@
Warning, version 450 is not yet complete; most version-specific features are present, but some are missing. Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
Shader version: 450 Shader version: 450
vertices = 0 vertices = -1
0:? Sequence 0:? Sequence
0:11 Function Definition: main( (global void) 0:11 Function Definition: main( (global void)
0:11 Function Parameters: 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=...) ERROR: Linking tessellation control stage: At least one shader must specify an output layout(vertices=...)
Shader version: 450 Shader version: 450
vertices = 0 vertices = -1
0:? Sequence 0:? Sequence
0:11 Function Definition: main( (global void) 0:11 Function Definition: main( (global void)
0:11 Function Parameters: 0:11 Function Parameters:

View File

@ -19,7 +19,7 @@ ERROR: 1 compilation errors. No code generated.
Shader version: 150 Shader version: 150
invocations = 0 invocations = 0
max_vertices = 0 max_vertices = -1
input primitive = none input primitive = none
output primitive = points output primitive = points
ERROR: node is still EOpNull! ERROR: node is still EOpNull!
@ -30,7 +30,7 @@ ERROR: node is still EOpNull!
noMain2.geom noMain2.geom
Shader version: 150 Shader version: 150
invocations = 0 invocations = 0
max_vertices = 0 max_vertices = -1
input primitive = none input primitive = none
output primitive = line_strip output primitive = line_strip
0:? Sequence 0:? Sequence
@ -53,7 +53,7 @@ ERROR: Linking fragment stage: Multiple function bodies in multiple compilation
Shader version: 150 Shader version: 150
invocations = 0 invocations = 0
max_vertices = 0 max_vertices = -1
input primitive = none input primitive = none
output primitive = points output primitive = points
ERROR: node is still EOpNull! ERROR: node is still EOpNull!

View File

@ -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)

12
Test/max_vertices_0.geom Normal file
View File

@ -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();
}

View File

@ -84,6 +84,7 @@ runBulkTest 300link2.frag
runBulkTest 300link3.frag runBulkTest 300link3.frag
runBulkTest empty.frag empty2.frag empty3.frag runBulkTest empty.frag empty2.frag empty3.frag
runBulkTest 150.tesc 150.tese 400.tesc 400.tese 410.tesc 420.tesc 420.tese runBulkTest 150.tesc 150.tese 400.tesc 400.tese 410.tesc 420.tesc 420.tese
runBulkTest max_vertices_0.geom
# #
# reflection tests # reflection tests

View File

@ -327,6 +327,8 @@ enum TBlendEquationShift {
class TQualifier { class TQualifier {
public: public:
static const int layoutNotSet = -1;
void clear() void clear()
{ {
precision = EpqNone; precision = EpqNone;
@ -489,8 +491,8 @@ public:
{ {
layoutMatrix = ElmNone; layoutMatrix = ElmNone;
layoutPacking = ElpNone; layoutPacking = ElpNone;
layoutOffset = -1; layoutOffset = layoutNotSet;
layoutAlign = -1; layoutAlign = layoutNotSet;
layoutLocation = layoutLocationEnd; layoutLocation = layoutLocationEnd;
layoutComponent = layoutComponentEnd; layoutComponent = layoutComponentEnd;
@ -567,11 +569,11 @@ public:
} }
bool hasOffset() const bool hasOffset() const
{ {
return layoutOffset != -1; return layoutOffset != layoutNotSet;
} }
bool hasAlign() const bool hasAlign() const
{ {
return layoutAlign != -1; return layoutAlign != layoutNotSet;
} }
bool hasAnyLocation() const bool hasAnyLocation() const
{ {
@ -789,7 +791,7 @@ struct TShaderQualifiers {
originUpperLeft = false; originUpperLeft = false;
pixelCenterInteger = false; pixelCenterInteger = false;
invocations = 0; // 0 means no declaration invocations = 0; // 0 means no declaration
vertices = 0; vertices = TQualifier::layoutNotSet;
spacing = EvsNone; spacing = EvsNone;
order = EvoNone; order = EvoNone;
pointMode = false; pointMode = false;
@ -813,7 +815,7 @@ struct TShaderQualifiers {
originUpperLeft = src.originUpperLeft; originUpperLeft = src.originUpperLeft;
if (src.invocations != 0) if (src.invocations != 0)
invocations = src.invocations; invocations = src.invocations;
if (src.vertices != 0) if (src.vertices != TQualifier::layoutNotSet)
vertices = src.vertices; vertices = src.vertices;
if (src.spacing != EvsNone) if (src.spacing != EvsNone)
spacing = src.spacing; spacing = src.spacing;

View File

@ -2,5 +2,5 @@
// For the version, it uses the latest git tag followed by the number of commits. // 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). // 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" #define GLSLANG_DATE "11-Dec-2015"

View File

@ -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) // fix array size, if it can be fixed and needs to be fixed (will allow variable indexing)
if (symbolNode->getType().isImplicitlySizedArray()) { if (symbolNode->getType().isImplicitlySizedArray()) {
int newSize = getIoArrayImplicitSize(); int newSize = getIoArrayImplicitSize();
if (newSize) if (newSize > 0)
symbolNode->getWritableType().changeOuterArraySize(newSize); symbolNode->getWritableType().changeOuterArraySize(newSize);
} }
} }
@ -703,7 +703,7 @@ int TParseContext::getIoArrayImplicitSize() const
if (language == EShLangGeometry) if (language == EShLangGeometry)
return TQualifier::mapGeometryToSize(intermediate.getInputPrimitive()); return TQualifier::mapGeometryToSize(intermediate.getInputPrimitive());
else if (language == EShLangTessControl) else if (language == EShLangTessControl)
return intermediate.getVertices(); return intermediate.getVertices() != TQualifier::layoutNotSet ? intermediate.getVertices() : 0;
else else
return 0; return 0;
} }
@ -3875,7 +3875,10 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
case EShLangTessControl: case EShLangTessControl:
if (id == "vertices") { if (id == "vertices") {
publicType.shaderQualifiers.vertices = value; if (value == 0)
error(loc, "must be greater than 0", "vertices", "");
else
publicType.shaderQualifiers.vertices = value;
return; return;
} }
break; break;
@ -4275,7 +4278,7 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua
error(loc, message, TQualifier::getGeometryString(shaderQualifiers.geometry), ""); error(loc, message, TQualifier::getGeometryString(shaderQualifiers.geometry), "");
if (shaderQualifiers.invocations > 0) if (shaderQualifiers.invocations > 0)
error(loc, message, "invocations", ""); error(loc, message, "invocations", "");
if (shaderQualifiers.vertices > 0) { if (shaderQualifiers.vertices != TQualifier::layoutNotSet) {
if (language == EShLangGeometry) if (language == EShLangGeometry)
error(loc, message, "max_vertices", ""); error(loc, message, "max_vertices", "");
else if (language == EShLangTessControl) 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) void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, const TPublicType& publicType)
{ {
if (publicType.shaderQualifiers.vertices) { if (publicType.shaderQualifiers.vertices != TQualifier::layoutNotSet) {
assert(language == EShLangTessControl || language == EShLangGeometry); assert(language == EShLangTessControl || language == EShLangGeometry);
const char* id = (language == EShLangTessControl) ? "vertices" : "max_vertices"; const char* id = (language == EShLangTessControl) ? "vertices" : "max_vertices";

View File

@ -100,7 +100,7 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
else if (outputPrimitive != unit.outputPrimitive) else if (outputPrimitive != unit.outputPrimitive)
error(infoSink, "Contradictory output layout primitives"); error(infoSink, "Contradictory output layout primitives");
if (vertices == 0) if (vertices == TQualifier::layoutNotSet)
vertices = unit.vertices; vertices = unit.vertices;
else if (vertices != unit.vertices) { else if (vertices != unit.vertices) {
if (language == EShLangGeometry) if (language == EShLangGeometry)
@ -409,7 +409,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink)
case EShLangVertex: case EShLangVertex:
break; break;
case EShLangTessControl: case EShLangTessControl:
if (vertices == 0) if (vertices == TQualifier::layoutNotSet)
error(infoSink, "At least one shader must specify an output layout(vertices=...)"); error(infoSink, "At least one shader must specify an output layout(vertices=...)");
break; break;
case EShLangTessEvaluation: case EShLangTessEvaluation:
@ -425,7 +425,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink)
error(infoSink, "At least one shader must specify an input layout primitive"); error(infoSink, "At least one shader must specify an input layout primitive");
if (outputPrimitive == ElgNone) if (outputPrimitive == ElgNone)
error(infoSink, "At least one shader must specify an output layout primitive"); 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)"); error(infoSink, "At least one shader must specify a layout(max_vertices = value)");
break; break;
case EShLangFragment: case EShLangFragment:

View File

@ -126,7 +126,7 @@ class TIntermediate {
public: public:
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : language(l), treeRoot(0), profile(p), version(v), spv(0), 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), 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) vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false), depthLayout(EldNone), depthReplacing(false), blendEquations(0), xfbMode(false)
{ {
localSize[0] = 1; localSize[0] = 1;
@ -212,7 +212,7 @@ public:
int getInvocations() const { return invocations; } int getInvocations() const { return invocations; }
bool setVertices(int m) bool setVertices(int m)
{ {
if (vertices > 0) if (vertices != TQualifier::layoutNotSet)
return vertices == m; return vertices == m;
vertices = m; vertices = m;
return true; return true;