Add productions/data for about 14 qualifiers (versions 1.2 through 4.3). Fixed some case issues for rect/array keywords.

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@20742 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2013-03-01 21:53:13 +00:00
parent 4b67103b02
commit ca8899c9ae
8 changed files with 205 additions and 68 deletions

View File

@ -9,6 +9,9 @@ float precision;
in vec4 i;
out vec4 o;
uniform sampler2D s2D;
centroid varying vec2 centTexCoord;
uniform mat4x2 m;
struct s {
@ -58,4 +61,6 @@ void main()
b = a; // ERROR
b = b + f; // ERROR
f |= b; // ERROR
gl_FragColor = texture2D(s2D, centTexCoord);
}

18
Test/120.vert Normal file
View File

@ -0,0 +1,18 @@
#version 120
in vec4 i;
out vec4 o;
attribute vec2 attv2;
attribute vec4 attv4;
uniform sampler2D s2D;
invariant varying vec2 centTexCoord;
invariant gl_Position;
centroid centroid foo;
void main()
{
centTexCoord = attv2;
gl_Position = attv4;
}

View File

@ -6,6 +6,7 @@ versionsClean.frag
versionsClean.vert
versionsErrors.frag
versionsErrors.vert
120.vert
120.frag
130.frag
140.frag

View File

@ -169,19 +169,52 @@ inline TArraySizes NewPoolTArraySizes()
}
//
// This is a workaround for a problem with the yacc stack, It can't have
// TPublicType is a workaround for a problem with the yacc stack, It can't have
// types that it thinks have non-trivial constructors. It should
// just be used while recognizing the grammar, not anything else. Pointers
// could be used, but also trying to avoid lots of memory management overhead.
//
// Not as bad as it looks, there is no actual assumption that the fields
// match up or are name the same or anything like that.
// match up or are named the same or anything like that.
//
class TQualifier {
public:
void clear()
{
storage = EvqTemporary;
precision = EpqNone;
buffer = false;
invariant = false;
centroid = false;
smooth = false;
flat = false;
nopersp = false;
patch = false;
sample = false;
shared = false;
coherent = false;
volatil = false;
restrict = false;
readonly = false;
writeonly = false;
}
TStorageQualifier storage : 7;
TPrecisionQualifier precision : 3;
bool buffer : 1;
bool invariant : 1;
bool centroid : 1;
bool smooth : 1;
bool flat : 1;
bool nopersp : 1;
bool patch : 1;
bool sample : 1;
bool shared : 1;
bool coherent : 1;
bool volatil : 1;
bool restrict : 1;
bool readonly : 1;
bool writeonly : 1;
};
class TPublicType {
@ -209,8 +242,9 @@ public:
void initQualifiers(bool global = false)
{
qualifier.storage = global ? EvqGlobal : EvqTemporary;
qualifier.precision = EpqNone;
qualifier.clear();
if (global)
qualifier.storage = EvqGlobal;
}
void init(int line = 0, bool global = false)
@ -249,8 +283,8 @@ public:
fieldName(0), mangled(0), typeName(0)
{
sampler.clear();
qualifier.clear();
qualifier.storage = q;
qualifier.precision = EpqNone;
}
TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0) :
type(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0),
@ -258,6 +292,7 @@ public:
fieldName(0), mangled(0), typeName(0)
{
sampler.clear();
qualifier.clear();
qualifier.storage = q;
qualifier.precision = p;
assert(p >= 0 && p <= EpqHigh);
@ -278,8 +313,7 @@ public:
structure(userDef), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0)
{
sampler.clear();
qualifier.storage = EvqTemporary;
qualifier.precision = EpqNone;
qualifier.clear();
typeName = NewPoolTString(n.c_str());
}
explicit TType() {}
@ -421,11 +455,39 @@ public:
TString TType::getCompleteString() const
{
const int maxSize = 100;
const int maxSize = 200;
char buf[maxSize];
char *p = &buf[0];
char *end = &buf[maxSize];
if (qualifier.buffer)
p += snprintf(p, end - p, "buffer ");
if (qualifier.invariant)
p += snprintf(p, end - p, "invariant ");
if (qualifier.centroid)
p += snprintf(p, end - p, "centroid ");
if (qualifier.smooth)
p += snprintf(p, end - p, "smooth ");
if (qualifier.flat)
p += snprintf(p, end - p, "flat ");
if (qualifier.nopersp)
p += snprintf(p, end - p, "noperspective ");
if (qualifier.patch)
p += snprintf(p, end - p, "patch ");
if (qualifier.sample)
p += snprintf(p, end - p, "sample ");
if (qualifier.shared)
p += snprintf(p, end - p, "shared ");
if (qualifier.coherent)
p += snprintf(p, end - p, "coherent ");
if (qualifier.volatil)
p += snprintf(p, end - p, "volatile ");
if (qualifier.restrict)
p += snprintf(p, end - p, "restrict ");
if (qualifier.readonly)
p += snprintf(p, end - p, "readonly ");
if (qualifier.writeonly)
p += snprintf(p, end - p, "writeonly ");
if (qualifier.storage != EvqTemporary && qualifier.storage != EvqGlobal)
p += snprintf(p, end - p, "%s ", getStorageQualifierString());
if (arraySizes) {

View File

@ -668,6 +668,62 @@ bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType
return false;
}
//
// Merge characteristics of the 'right' qualifier into the 'left'.
// If there is duplication, issue error messages.
//
// Return true if there was an error.
//
bool TParseContext::mergeQualifiersErrorCheck(int line, TPublicType& left, const TPublicType& right)
{
bool bad = false;
// Storage qualification
if (left.qualifier.storage == EvqTemporary)
left.qualifier.storage = right.qualifier.storage;
else if (left.qualifier.storage == EvqIn && right.qualifier.storage == EvqOut ||
left.qualifier.storage == EvqOut && right.qualifier.storage == EvqIn)
left.qualifier.storage = EvqInOut;
else if (left.qualifier.storage == EvqIn && right.qualifier.storage == EvqConst ||
left.qualifier.storage == EvqConst && right.qualifier.storage == EvqIn)
left.qualifier.storage = EvqConstReadOnly;
else if ( left.qualifier.storage != EvqTemporary &&
right.qualifier.storage != EvqTemporary) {
error(line, "too many storage qualifiers", getStorageQualifierString(right.qualifier.storage), "");
bad = true;
}
// Precision qualifiers
if (left.qualifier.precision == EpqNone)
left.qualifier.precision = right.qualifier.precision;
else if (right.qualifier.precision) {
error(line, "only one precision qualifier allowed", getPrecisionQualifierString(right.qualifier.precision), "");
bad = true;
}
// other qualifiers
#define MERGE_SINGLETON(field) bad |= left.qualifier.field && right.qualifier.field; left.qualifier.field |= right.qualifier.field;
MERGE_SINGLETON(buffer);
MERGE_SINGLETON(invariant);
MERGE_SINGLETON(centroid);
MERGE_SINGLETON(smooth);
MERGE_SINGLETON(flat);
MERGE_SINGLETON(nopersp);
MERGE_SINGLETON(patch);
MERGE_SINGLETON(sample);
MERGE_SINGLETON(shared);
MERGE_SINGLETON(coherent);
MERGE_SINGLETON(volatil);
MERGE_SINGLETON(restrict);
MERGE_SINGLETON(readonly);
MERGE_SINGLETON(writeonly);
if (bad)
error(line, "replicated qualifiers", "", "");
return bad;
}
void TParseContext::setDefaultPrecision(int line, TBasicType type, TPrecisionQualifier qualifier)
{
if (type == EbtSampler || type == EbtInt || type == EbtFloat) {

View File

@ -120,6 +120,7 @@ struct TParseContext {
bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason);
bool globalQualifierFixAndErrorCheck(int line, TQualifier&);
bool structQualifierErrorCheck(int line, const TPublicType& pType);
bool mergeQualifiersErrorCheck(int line, TPublicType& left, const TPublicType& right);
void setDefaultPrecision(int line, TBasicType, TPrecisionQualifier);
bool parameterSamplerErrorCheck(int line, TStorageQualifier qualifier, const TType& type);
bool containsSampler(const TType& type);

View File

@ -268,30 +268,30 @@ int yy_input(char* buf, int max_size);
"image3D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE3D); }
"iimage3D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE3D); }
"uimage3D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE3D); }
"image2Drect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE2DRECT); }
"iimage2Drect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE2DRECT); }
"uimage2Drect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE2DRECT); }
"image2DRect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE2DRECT); }
"iimage2DRect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE2DRECT); }
"uimage2DRect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE2DRECT); }
"imageCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGECUBE); }
"iimageCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGECUBE); }
"uimageCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGECUBE); }
"imageBuffer" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGEBUFFER); }
"iimageBuffer" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGEBUFFER); }
"uimageBuffer" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGEBUFFER); }
"image1Darray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE1DARRAY); }
"iimage1Darray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE1DARRAY); }
"uimage1Darray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE1DARRAY); }
"image2Darray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE2DARRAY); }
"iimage2Darray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE2DARRAY); }
"uimage2Darray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE2DARRAY); }
"imageCubearray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGECUBEARRAY); }
"iimageCubearray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGECUBEARRAY); }
"uimageCubearray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGECUBEARRAY); }
"image1DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE1DARRAY); }
"iimage1DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE1DARRAY); }
"uimage1DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE1DARRAY); }
"image2DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE2DARRAY); }
"iimage2DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE2DARRAY); }
"uimage2DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE2DARRAY); }
"imageCubeArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGECUBEARRAY); }
"iimageCubeArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGECUBEARRAY); }
"uimageCubeArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGECUBEARRAY); }
"image2DMS" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE2DMS); }
"iimage2DMS" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE2DMS); }
"uimage2DMS" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE2DMS); }
"image2DMSarray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE2DMSARRAY); }
"iimage2DMSarray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE2DMSARRAY); }
"uimage2DMSarray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE2DMSARRAY); }
"image2DMSArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE2DMSARRAY); }
"iimage2DMSArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE2DMSARRAY); }
"uimage2DMSArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE2DMSARRAY); }
"struct" { pyylval->lex.line = yylineno; return(STRUCT); }

View File

@ -1601,20 +1601,42 @@ fully_specified_type
invariant_qualifier
: INVARIANT {
parseContext.profileRequires($$.line, ENoProfile, 120, 0, "invariant");
$$.init($1.line);
$$.qualifier.invariant = true;
}
;
interpolation_qualifier
: SMOOTH {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "smooth"))
parseContext.recover();
parseContext.profileRequires($$.line, ENoProfile, 130, 0, "smooth");
parseContext.profileRequires($$.line, EEsProfile, 300, 0, "smooth");
$$.init($1.line);
$$.qualifier.smooth = true;
}
| FLAT {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "flat"))
parseContext.recover();
parseContext.profileRequires($$.line, ENoProfile, 130, 0, "flat");
parseContext.profileRequires($$.line, EEsProfile, 300, 0, "flat");
$$.init($1.line);
$$.qualifier.flat = true;
}
| NOPERSPECTIVE {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "noperspective"))
parseContext.recover();
parseContext.requireProfile($$.line, static_cast<EProfileMask>(~EEsProfileMask), "noperspective");
parseContext.profileRequires($$.line, ENoProfile, 130, 0, "noperspective");
$$.init($1.line);
$$.qualifier.nopersp = true;
}
;
layout_qualifier
: LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN {
$$.init($1.line);
}
;
@ -1635,6 +1657,7 @@ layout_qualifier_id
precise_qualifier
: PRECISE {
$$.init($1.line);
}
;
@ -1644,24 +1667,11 @@ type_qualifier
}
| type_qualifier single_type_qualifier {
$$ = $1;
// TODO: merge qualifiers in $1 and $2 and check for duplication
if ($$.type == EbtVoid) {
if ($$.type == EbtVoid)
$$.type = $2.type;
}
if ($$.qualifier.storage == EvqTemporary) {
$$.qualifier.storage = $2.qualifier.storage;
} else if ($$.qualifier.storage == EvqIn && $2.qualifier.storage == EvqOut ||
$$.qualifier.storage == EvqOut && $2.qualifier.storage == EvqIn) {
$$.qualifier.storage = EvqInOut;
} else if ($$.qualifier.storage == EvqIn && $2.qualifier.storage == EvqConst ||
$$.qualifier.storage == EvqConst && $2.qualifier.storage == EvqIn) {
$$.qualifier.storage = EvqConstReadOnly;
}
if ($$.qualifier.precision == EpqNone)
$$.qualifier.precision = $2.qualifier.precision;
if (parseContext.mergeQualifiersErrorCheck($$.line, $$, $2))
parseContext.recover();
}
;
@ -1741,24 +1751,24 @@ storage_qualifier
$$.qualifier.storage = EvqOut;
}
| CENTROID {
parseContext.profileRequires($$.line, ENoProfile, 120, 0, "centroid");
parseContext.profileRequires($$.line, EEsProfile, 300, 0, "centroid");
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "centroid"))
parseContext.recover();
$$.init($1.line);
$$.qualifier.storage = EvqVaryingIn;
$$.qualifier.centroid = true;
}
| PATCH {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "patch"))
parseContext.recover();
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
$$.qualifier.patch = true;
}
| SAMPLE {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "sample"))
parseContext.recover();
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
$$.qualifier.sample = true;
}
| UNIFORM {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "uniform"))
@ -1770,48 +1780,32 @@ storage_qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "buffer"))
parseContext.recover();
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
$$.qualifier.storage = EvqUniform;
$$.qualifier.buffer = true;
}
| SHARED {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "shared"))
parseContext.recover();
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
$$.qualifier.shared = true;
}
| COHERENT {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "coherent"))
parseContext.recover();
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
$$.qualifier.coherent = true;
}
| VOLATILE {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "volatile"))
parseContext.recover();
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
$$.qualifier.volatil = true;
}
| RESTRICT {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "restrict"))
parseContext.recover();
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
$$.qualifier.restrict = true;
}
| READONLY {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "readonly"))
parseContext.recover();
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
$$.qualifier.readonly = true;
}
| WRITEONLY {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "writeonly"))
parseContext.recover();
$$.init($1.line);
$$.qualifier.storage = EvqUniform;
$$.qualifier.writeonly = true;
}
| SUBROUTINE {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "subroutine"))