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;
ERROR: 0:32: 'gl_' : reserved built-in name: gl_i\r
ERROR: 0:35: 'gl_in' : no declaration found for redeclaration \r
ERROR: 0:39: 'gl_FragCoord' : cannot redeclare a non block as a block \r
-ERROR: 5 compilation errors. No code generated.\r
+ERROR: 0:44: 'non-literal layout-id value' : not supported for this version or the enabled extensions \r
+ERROR: 0:44: 'layout-id value' : cannot be negative \r
+ERROR: 0:45: 'non-literal layout-id value' : not supported for this version or the enabled extensions \r
+ERROR: 0:46: 'layout-id value' : scalar integer expression required \r
+ERROR: 0:46: 'location' : location is too large \r
+ERROR: 0:51: 'layout-id value' : cannot be negative \r
+ERROR: 0:52: 'layout-id value' : cannot be negative \r
+ERROR: 12 compilation errors. No code generated.\r
\r
\r
ERROR: node is still EOpNull!\r
0:? 'varyingVar' (smooth in 4-component vector of float)\r
0:? '__anon__0' (in block{in 4-component vector of float gl_Color, })\r
0:? 'gl_name' (in block{in int gl_i})\r
+0:? 'start' (const int)\r
+0:? 6 (const int)\r
+0:? 'v1' (smooth in 4-component vector of float)\r
+0:? 'v2' (layout(location=8 ) smooth in 4-component vector of float)\r
+0:? 'v20' (smooth in 4-component vector of float)\r
+0:? 'v3' (layout(location=6 ) smooth in 4-component vector of float)\r
+0:? 'v4' (smooth in 4-component vector of float)\r
+0:? 'v5' (smooth in 4-component vector of float)\r
+0:? 'v6' (layout(location=34 ) smooth in 4-component vector of float)\r
\r
\r
Linked fragment stage:\r
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
};
//
// source have to figure out how to create revision.h just to get a build\r
// going. However, if it is not updated, it can be a version behind.\r
\r
-#define GLSLANG_REVISION "24664"\r
-#define GLSLANG_DATE "2014/01/06 14:27:56"\r
+#define GLSLANG_REVISION "24674"\r
+#define GLSLANG_DATE "2014/01/07 10:44:41"\r
//
// 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.
// 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;
}
// 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);
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&);
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,
"#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";
}
}
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
| INTCONSTANT {\r
TConstUnionArray unionArray(1);\r
unionArray[0].setIConst($1.i);\r
- $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.loc);\r
+ $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.loc, true);\r
}\r
| UINTCONSTANT { \r
parseContext.fullIntegerCheck($1.loc, "unsigned literal");\r
TConstUnionArray unionArray(1);\r
unionArray[0].setUConst($1.u);\r
- $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtUint, EvqConst), $1.loc);\r
+ $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtUint, EvqConst), $1.loc, true);\r
}\r
| FLOATCONSTANT {\r
TConstUnionArray unionArray(1);\r
unionArray[0].setDConst($1.d);\r
- $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.loc);\r
+ $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.loc, true);\r
}\r
| DOUBLECONSTANT {\r
parseContext.doubleCheck($1.loc, "double literal");\r
TConstUnionArray unionArray(1);\r
unionArray[0].setDConst($1.d);\r
- $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtDouble, EvqConst), $1.loc);\r
+ $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtDouble, EvqConst), $1.loc, true);\r
}\r
| BOOLCONSTANT {\r
TConstUnionArray unionArray(1);\r
unionArray[0].setBConst($1.b);\r
- $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $1.loc);\r
+ $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $1.loc, true);\r
}\r
| LEFT_PAREN expression RIGHT_PAREN {\r
$$ = $2;\r
$$.init($1.loc);\r
parseContext.setLayoutQualifier($1.loc, $$, *$1.string);\r
}\r
- | IDENTIFIER EQUAL INTCONSTANT {\r
+ | IDENTIFIER EQUAL constant_expression {\r
$$.init($1.loc);\r
- parseContext.setLayoutQualifier($1.loc, $$, *$1.string, $3.i);\r
- }\r
- | IDENTIFIER EQUAL UINTCONSTANT {\r
- $$.init($1.loc);\r
- parseContext.setLayoutQualifier($1.loc, $$, *$1.string, (int)$3.u);\r
+ parseContext.setLayoutQualifier($1.loc, $$, *$1.string, $3);\r
}\r
| SHARED { // because "shared" is both an identifier and a keyword\r
$$.init($1.loc);\r
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);