From b76d6d64968b55bdefa0fa5360b88c44b09d3514 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Tue, 7 Jan 2014 18:14:48 +0000 Subject: [PATCH] GL_ARB_enhanced_layouts, part 1: Track whether constants are literals, to enable version-specific checking of layout(... = literal) vs. layout(... = expression). git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24675 e7fa87d3-cd2b-0410-9028-fcbf551c1848 --- Test/330.frag | 12 ++++++++++++ Test/baseResults/330.frag.out | 18 +++++++++++++++++- glslang/Include/intermediate.h | 5 ++++- glslang/Include/revision.h | 4 ++-- glslang/MachineIndependent/Constant.cpp | 2 +- glslang/MachineIndependent/Intermediate.cpp | 4 +++- glslang/MachineIndependent/ParseHelper.cpp | 18 +++++++++++++++--- glslang/MachineIndependent/ParseHelper.h | 2 +- glslang/MachineIndependent/Versions.cpp | 4 +++- glslang/MachineIndependent/Versions.h | 1 + glslang/MachineIndependent/glslang.y | 18 +++++++----------- glslang/MachineIndependent/localintermediate.h | 2 +- 12 files changed, 67 insertions(+), 23 deletions(-) diff --git a/Test/330.frag b/Test/330.frag index 22143f8..b90ae54 100644 --- a/Test/330.frag +++ b/Test/330.frag @@ -39,3 +39,15 @@ in gl_PerVertex { // ERROR in gl_PerVertex { // ERROR vec4 gl_FragCoord; }; // ERROR + +const int start = 6; +layout(location = -2) in vec4 v1; // ERROR +layout(location = start + 2) in vec4 v2; // ERROR +layout(location = 4.7e10) in vec4 v20; // ERROR + +#extension GL_ARB_enhanced_layouts : enable + +layout(location = start) in vec4 v3; +layout(location = -2) in vec4 v4; // ERROR +layout(location = -start) in vec4 v5; // ERROR +layout(location = start*start - 2) in vec4 v6; diff --git a/Test/baseResults/330.frag.out b/Test/baseResults/330.frag.out index cb28b8e..0ada059 100644 --- a/Test/baseResults/330.frag.out +++ b/Test/baseResults/330.frag.out @@ -5,7 +5,14 @@ ERROR: 0:31: 'gl_' : reserved built-in name: gl_name ERROR: 0:32: 'gl_' : reserved built-in name: gl_i ERROR: 0:35: 'gl_in' : no declaration found for redeclaration ERROR: 0:39: 'gl_FragCoord' : cannot redeclare a non block as a block -ERROR: 5 compilation errors. No code generated. +ERROR: 0:44: 'non-literal layout-id value' : not supported for this version or the enabled extensions +ERROR: 0:44: 'layout-id value' : cannot be negative +ERROR: 0:45: 'non-literal layout-id value' : not supported for this version or the enabled extensions +ERROR: 0:46: 'layout-id value' : scalar integer expression required +ERROR: 0:46: 'location' : location is too large +ERROR: 0:51: 'layout-id value' : cannot be negative +ERROR: 0:52: 'layout-id value' : cannot be negative +ERROR: 12 compilation errors. No code generated. ERROR: node is still EOpNull! @@ -45,6 +52,15 @@ ERROR: node is still EOpNull! 0:? 'varyingVar' (smooth in 4-component vector of float) 0:? '__anon__0' (in block{in 4-component vector of float gl_Color, }) 0:? 'gl_name' (in block{in int gl_i}) +0:? 'start' (const int) +0:? 6 (const int) +0:? 'v1' (smooth in 4-component vector of float) +0:? 'v2' (layout(location=8 ) smooth in 4-component vector of float) +0:? 'v20' (smooth in 4-component vector of float) +0:? 'v3' (layout(location=6 ) smooth in 4-component vector of float) +0:? 'v4' (smooth in 4-component vector of float) +0:? 'v5' (smooth in 4-component vector of float) +0:? 'v6' (layout(location=34 ) smooth in 4-component vector of float) Linked fragment stage: diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h index 6b0570a..b73083a 100644 --- a/glslang/Include/intermediate.h +++ b/glslang/Include/intermediate.h @@ -494,15 +494,18 @@ protected: class TIntermConstantUnion : public TIntermTyped { public: - TIntermConstantUnion(const TConstUnionArray& ua, const TType& t) : TIntermTyped(t), unionArray(ua) { } + TIntermConstantUnion(const TConstUnionArray& ua, const TType& t) : TIntermTyped(t), unionArray(ua), literal(false) { } const TConstUnionArray& getConstArray() const { return unionArray; } virtual TIntermConstantUnion* getAsConstantUnion() { return this; } virtual const TIntermConstantUnion* getAsConstantUnion() const { return this; } virtual void traverse(TIntermTraverser*); virtual TIntermTyped* fold(TOperator, const TIntermTyped*) const; virtual TIntermTyped* fold(TOperator, const TType&) const; + void setLiteral() { literal = true; } + bool isLiteral() const { return literal; } protected: const TConstUnionArray unionArray; + bool literal; // true if node represents a literal in the source code }; // diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h index a24f55d..90a7e27 100644 --- a/glslang/Include/revision.h +++ b/glslang/Include/revision.h @@ -9,5 +9,5 @@ // source have to figure out how to create revision.h just to get a build // going. However, if it is not updated, it can be a version behind. -#define GLSLANG_REVISION "24664" -#define GLSLANG_DATE "2014/01/06 14:27:56" +#define GLSLANG_REVISION "24674" +#define GLSLANG_DATE "2014/01/07 10:44:41" diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp index 7e045b6..801cf1d 100644 --- a/glslang/MachineIndependent/Constant.cpp +++ b/glslang/MachineIndependent/Constant.cpp @@ -85,7 +85,7 @@ namespace glslang { // // Returns a new node representing the result. // -TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* constantNode) const +TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* constantNode) const { // For most cases, the return type matches the argument type, so set that // up and just code to exceptions below. diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp index eaa070e..952d103 100644 --- a/glslang/MachineIndependent/Intermediate.cpp +++ b/glslang/MachineIndependent/Intermediate.cpp @@ -782,10 +782,12 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true // Returns the constant union node created. // -TIntermConstantUnion* TIntermediate::addConstantUnion(const TConstUnionArray& unionArray, const TType& t, TSourceLoc loc) +TIntermConstantUnion* TIntermediate::addConstantUnion(const TConstUnionArray& unionArray, const TType& t, TSourceLoc loc, bool literal) { TIntermConstantUnion* node = new TIntermConstantUnion(unionArray, t); node->setLoc(loc); + if (literal) + node->setLiteral(); return node; } diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 00b8b88..12cfb59 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -2808,12 +2808,24 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, // Put the id's layout qualifier value into the public type. This is before we know any // type information for error checking. -void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id, int value) +void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id, const TIntermTyped* node) { + const char* feature = "layout-id value"; + const char* nonLiteralFeature = "non-literal layout-id value"; + + integerCheck(node, feature); + const TIntermConstantUnion* constUnion = node->getAsConstantUnion(); + assert(constUnion); + int value = node->getAsConstantUnion()->getConstArray()[0].getIConst(); + + if (! constUnion->isLiteral()) { + requireProfile(loc, ECoreProfile | ECompatibilityProfile, nonLiteralFeature); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, GL_ARB_enhanced_layouts, nonLiteralFeature); + } + if (value < 0) { - error(loc, "cannot be negative", "layout qualifier value", ""); + error(loc, "cannot be negative", feature, ""); return; - // TODO: 4.4: test the above, once expressions are allowed; until then, can't even express a negative location } std::transform(id.begin(), id.end(), id.begin(), ::tolower); diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index b8c7906..a2dcc60 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -148,7 +148,7 @@ public: void constantIndexExpressionCheck(TIntermNode*); void setLayoutQualifier(TSourceLoc, TPublicType&, TString&); - void setLayoutQualifier(TSourceLoc, TPublicType&, TString&, int); + void setLayoutQualifier(TSourceLoc, TPublicType&, TString&, const TIntermTyped*); void mergeObjectLayoutQualifiers(TSourceLoc, TQualifier& dest, const TQualifier& src, bool inheritOnly); void layoutTypeCheck(TSourceLoc, const TSymbol&); void layoutQualifierCheck(TSourceLoc, const TQualifier&); diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index 6fc97f7..5fe2de3 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -162,6 +162,7 @@ void TParseContext::initializeExtensionBehavior() extensionBehavior[GL_ARB_gpu_shader5] = EBhDisablePartial; extensionBehavior[GL_ARB_separate_shader_objects] = EBhDisable; extensionBehavior[GL_ARB_tessellation_shader] = EBhDisable; + extensionBehavior[GL_ARB_enhanced_layouts] = EBhDisable; } // Get code that is not part of a shared symbol table, is specific to this shader, @@ -184,7 +185,8 @@ const char* TParseContext::getPreamble() "#define GL_ARB_texture_gather 1\n" "#define GL_ARB_gpu_shader5 1\n" "#define GL_ARB_separate_shader_objects 1\n" - "#define GL_ARB_tessellation_shader 1\n"; + "#define GL_ARB_tessellation_shader 1\n" + "#define GL_ARB_enhanced_layouts 1\n"; } } diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h index d0997b8..e7ccd2e 100644 --- a/glslang/MachineIndependent/Versions.h +++ b/glslang/MachineIndependent/Versions.h @@ -86,6 +86,7 @@ const char* const GL_ARB_texture_gather = "GL_ARB_texture_gather"; const char* const GL_ARB_gpu_shader5 = "GL_ARB_gpu_shader5"; const char* const GL_ARB_separate_shader_objects = "GL_ARB_separate_shader_objects"; const char* const GL_ARB_tessellation_shader = "GL_ARB_tessellation_shader"; +const char* const GL_ARB_enhanced_layouts = "GL_ARB_enhanced_layouts"; } // end namespace glslang diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y index a1dda87..11d6038 100644 --- a/glslang/MachineIndependent/glslang.y +++ b/glslang/MachineIndependent/glslang.y @@ -228,29 +228,29 @@ primary_expression | INTCONSTANT { TConstUnionArray unionArray(1); unionArray[0].setIConst($1.i); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.loc); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.loc, true); } | UINTCONSTANT { parseContext.fullIntegerCheck($1.loc, "unsigned literal"); TConstUnionArray unionArray(1); unionArray[0].setUConst($1.u); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtUint, EvqConst), $1.loc); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtUint, EvqConst), $1.loc, true); } | FLOATCONSTANT { TConstUnionArray unionArray(1); unionArray[0].setDConst($1.d); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.loc); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.loc, true); } | DOUBLECONSTANT { parseContext.doubleCheck($1.loc, "double literal"); TConstUnionArray unionArray(1); unionArray[0].setDConst($1.d); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtDouble, EvqConst), $1.loc); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtDouble, EvqConst), $1.loc, true); } | BOOLCONSTANT { TConstUnionArray unionArray(1); unionArray[0].setBConst($1.b); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $1.loc); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $1.loc, true); } | LEFT_PAREN expression RIGHT_PAREN { $$ = $2; @@ -1110,13 +1110,9 @@ layout_qualifier_id $$.init($1.loc); parseContext.setLayoutQualifier($1.loc, $$, *$1.string); } - | IDENTIFIER EQUAL INTCONSTANT { + | IDENTIFIER EQUAL constant_expression { $$.init($1.loc); - parseContext.setLayoutQualifier($1.loc, $$, *$1.string, $3.i); - } - | IDENTIFIER EQUAL UINTCONSTANT { - $$.init($1.loc); - parseContext.setLayoutQualifier($1.loc, $$, *$1.string, (int)$3.u); + parseContext.setLayoutQualifier($1.loc, $$, *$1.string, $3); } | SHARED { // because "shared" is both an identifier and a keyword $$.init($1.loc); diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 2ce1f1f..eb85daf 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -96,7 +96,7 @@ public: TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc); TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc); TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, TSourceLoc); - TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, TSourceLoc); + TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, TSourceLoc, bool literal = false); TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ; bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false); TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, TSourceLoc); -- 2.7.4