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
This commit is contained in:
@@ -39,3 +39,15 @@ in gl_PerVertex { // ERROR
|
|||||||
in gl_PerVertex { // ERROR
|
in gl_PerVertex { // ERROR
|
||||||
vec4 gl_FragCoord;
|
vec4 gl_FragCoord;
|
||||||
}; // ERROR
|
}; // 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;
|
||||||
|
|||||||
@@ -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:32: 'gl_' : reserved built-in name: gl_i
|
||||||
ERROR: 0:35: 'gl_in' : no declaration found for redeclaration
|
ERROR: 0:35: 'gl_in' : no declaration found for redeclaration
|
||||||
ERROR: 0:39: 'gl_FragCoord' : cannot redeclare a non block as a block
|
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!
|
ERROR: node is still EOpNull!
|
||||||
@@ -45,6 +52,15 @@ ERROR: node is still EOpNull!
|
|||||||
0:? 'varyingVar' (smooth in 4-component vector of float)
|
0:? 'varyingVar' (smooth in 4-component vector of float)
|
||||||
0:? '__anon__0' (in block{in 4-component vector of float gl_Color, })
|
0:? '__anon__0' (in block{in 4-component vector of float gl_Color, })
|
||||||
0:? 'gl_name' (in block{in int gl_i})
|
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:
|
Linked fragment stage:
|
||||||
|
|||||||
@@ -494,15 +494,18 @@ protected:
|
|||||||
|
|
||||||
class TIntermConstantUnion : public TIntermTyped {
|
class TIntermConstantUnion : public TIntermTyped {
|
||||||
public:
|
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; }
|
const TConstUnionArray& getConstArray() const { return unionArray; }
|
||||||
virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
|
virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
|
||||||
virtual const TIntermConstantUnion* getAsConstantUnion() const { return this; }
|
virtual const TIntermConstantUnion* getAsConstantUnion() const { return this; }
|
||||||
virtual void traverse(TIntermTraverser*);
|
virtual void traverse(TIntermTraverser*);
|
||||||
virtual TIntermTyped* fold(TOperator, const TIntermTyped*) const;
|
virtual TIntermTyped* fold(TOperator, const TIntermTyped*) const;
|
||||||
virtual TIntermTyped* fold(TOperator, const TType&) const;
|
virtual TIntermTyped* fold(TOperator, const TType&) const;
|
||||||
|
void setLiteral() { literal = true; }
|
||||||
|
bool isLiteral() const { return literal; }
|
||||||
protected:
|
protected:
|
||||||
const TConstUnionArray unionArray;
|
const TConstUnionArray unionArray;
|
||||||
|
bool literal; // true if node represents a literal in the source code
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -9,5 +9,5 @@
|
|||||||
// source have to figure out how to create revision.h just to get a build
|
// 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.
|
// going. However, if it is not updated, it can be a version behind.
|
||||||
|
|
||||||
#define GLSLANG_REVISION "24664"
|
#define GLSLANG_REVISION "24674"
|
||||||
#define GLSLANG_DATE "2014/01/06 14:27:56"
|
#define GLSLANG_DATE "2014/01/07 10:44:41"
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ namespace glslang {
|
|||||||
//
|
//
|
||||||
// Returns a new node representing the result.
|
// 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
|
// For most cases, the return type matches the argument type, so set that
|
||||||
// up and just code to exceptions below.
|
// up and just code to exceptions below.
|
||||||
|
|||||||
@@ -782,10 +782,12 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
|
|||||||
// Returns the constant union node created.
|
// 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);
|
TIntermConstantUnion* node = new TIntermConstantUnion(unionArray, t);
|
||||||
node->setLoc(loc);
|
node->setLoc(loc);
|
||||||
|
if (literal)
|
||||||
|
node->setLiteral();
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
// Put the id's layout qualifier value into the public type. This is before we know any
|
||||||
// type information for error checking.
|
// 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) {
|
if (value < 0) {
|
||||||
error(loc, "cannot be negative", "layout qualifier value", "");
|
error(loc, "cannot be negative", feature, "");
|
||||||
return;
|
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);
|
std::transform(id.begin(), id.end(), id.begin(), ::tolower);
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ public:
|
|||||||
void constantIndexExpressionCheck(TIntermNode*);
|
void constantIndexExpressionCheck(TIntermNode*);
|
||||||
|
|
||||||
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&);
|
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 mergeObjectLayoutQualifiers(TSourceLoc, TQualifier& dest, const TQualifier& src, bool inheritOnly);
|
||||||
void layoutTypeCheck(TSourceLoc, const TSymbol&);
|
void layoutTypeCheck(TSourceLoc, const TSymbol&);
|
||||||
void layoutQualifierCheck(TSourceLoc, const TQualifier&);
|
void layoutQualifierCheck(TSourceLoc, const TQualifier&);
|
||||||
|
|||||||
@@ -162,6 +162,7 @@ void TParseContext::initializeExtensionBehavior()
|
|||||||
extensionBehavior[GL_ARB_gpu_shader5] = EBhDisablePartial;
|
extensionBehavior[GL_ARB_gpu_shader5] = EBhDisablePartial;
|
||||||
extensionBehavior[GL_ARB_separate_shader_objects] = EBhDisable;
|
extensionBehavior[GL_ARB_separate_shader_objects] = EBhDisable;
|
||||||
extensionBehavior[GL_ARB_tessellation_shader] = 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,
|
// 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_texture_gather 1\n"
|
||||||
"#define GL_ARB_gpu_shader5 1\n"
|
"#define GL_ARB_gpu_shader5 1\n"
|
||||||
"#define GL_ARB_separate_shader_objects 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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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_gpu_shader5 = "GL_ARB_gpu_shader5";
|
||||||
const char* const GL_ARB_separate_shader_objects = "GL_ARB_separate_shader_objects";
|
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_tessellation_shader = "GL_ARB_tessellation_shader";
|
||||||
|
const char* const GL_ARB_enhanced_layouts = "GL_ARB_enhanced_layouts";
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
|
|||||||
@@ -228,29 +228,29 @@ primary_expression
|
|||||||
| INTCONSTANT {
|
| INTCONSTANT {
|
||||||
TConstUnionArray unionArray(1);
|
TConstUnionArray unionArray(1);
|
||||||
unionArray[0].setIConst($1.i);
|
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 {
|
| UINTCONSTANT {
|
||||||
parseContext.fullIntegerCheck($1.loc, "unsigned literal");
|
parseContext.fullIntegerCheck($1.loc, "unsigned literal");
|
||||||
TConstUnionArray unionArray(1);
|
TConstUnionArray unionArray(1);
|
||||||
unionArray[0].setUConst($1.u);
|
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 {
|
| FLOATCONSTANT {
|
||||||
TConstUnionArray unionArray(1);
|
TConstUnionArray unionArray(1);
|
||||||
unionArray[0].setDConst($1.d);
|
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 {
|
| DOUBLECONSTANT {
|
||||||
parseContext.doubleCheck($1.loc, "double literal");
|
parseContext.doubleCheck($1.loc, "double literal");
|
||||||
TConstUnionArray unionArray(1);
|
TConstUnionArray unionArray(1);
|
||||||
unionArray[0].setDConst($1.d);
|
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 {
|
| BOOLCONSTANT {
|
||||||
TConstUnionArray unionArray(1);
|
TConstUnionArray unionArray(1);
|
||||||
unionArray[0].setBConst($1.b);
|
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 {
|
| LEFT_PAREN expression RIGHT_PAREN {
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
@@ -1110,13 +1110,9 @@ layout_qualifier_id
|
|||||||
$$.init($1.loc);
|
$$.init($1.loc);
|
||||||
parseContext.setLayoutQualifier($1.loc, $$, *$1.string);
|
parseContext.setLayoutQualifier($1.loc, $$, *$1.string);
|
||||||
}
|
}
|
||||||
| IDENTIFIER EQUAL INTCONSTANT {
|
| IDENTIFIER EQUAL constant_expression {
|
||||||
$$.init($1.loc);
|
$$.init($1.loc);
|
||||||
parseContext.setLayoutQualifier($1.loc, $$, *$1.string, $3.i);
|
parseContext.setLayoutQualifier($1.loc, $$, *$1.string, $3);
|
||||||
}
|
|
||||||
| IDENTIFIER EQUAL UINTCONSTANT {
|
|
||||||
$$.init($1.loc);
|
|
||||||
parseContext.setLayoutQualifier($1.loc, $$, *$1.string, (int)$3.u);
|
|
||||||
}
|
}
|
||||||
| SHARED { // because "shared" is both an identifier and a keyword
|
| SHARED { // because "shared" is both an identifier and a keyword
|
||||||
$$.init($1.loc);
|
$$.init($1.loc);
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ public:
|
|||||||
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc);
|
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc);
|
||||||
TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc);
|
TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc);
|
||||||
TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, 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*) ;
|
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ;
|
||||||
bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false);
|
bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false);
|
||||||
TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, TSourceLoc);
|
TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, TSourceLoc);
|
||||||
|
|||||||
Reference in New Issue
Block a user