Commit 55a2cbc6 by Alexis Hetu Committed by Alexis Hétu

Adding new glsl interpolation qualifiers

This adds proper handling of the new interpolation qualifiers "flat" and "smooth" for glsl in OpenGL ES 3.0. These aren't implemented yet, they are simply parsed properly with this cl. Change-Id: I32aa2ca0f9ddb4c2b1a1e9c5f285a41a1716f4cc Reviewed-on: https://swiftshader-review.googlesource.com/2861Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent 6467b7b4
......@@ -142,6 +142,16 @@ enum TQualifier : unsigned char
EvqFragColor,
EvqFragData,
// GLSL ES 3.0 vertex output and fragment input
EvqSmooth, // Incomplete qualifier, smooth is the default
EvqFlat, // Incomplete qualifier
EvqSmoothOut = EvqSmooth,
EvqFlatOut = EvqFlat,
EvqCentroidOut, // Implies smooth
EvqSmoothIn,
EvqFlatIn,
EvqCentroidIn, // Implies smooth
// end of list
EvqLast
};
......@@ -192,7 +202,13 @@ inline const char *getQualifierString(TQualifier qualifier)
case EvqFragCoord: return "FragCoord"; break;
case EvqFrontFacing: return "FrontFacing"; break;
case EvqFragColor: return "FragColor"; break;
case EvqFragData: return "FragData"; break;
case EvqFragData: return "FragData"; break;
case EvqSmooth: return "Smooth"; break;
case EvqFlat: return "Flat"; break;
case EvqCentroidOut: return "CentroidOut"; break;
case EvqSmoothIn: return "SmoothIn"; break;
case EvqFlatIn: return "FlatIn"; break;
case EvqCentroidIn: return "CentroidIn"; break;
default: UNREACHABLE(); return "unknown qualifier";
}
}
......
......@@ -315,6 +315,9 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod
case EvqConstReadOnly: message = "can't modify a const"; break;
case EvqAttribute: message = "can't modify an attribute"; break;
case EvqUniform: message = "can't modify a uniform"; break;
case EvqSmoothIn:
case EvqFlatIn:
case EvqCentroidIn:
case EvqVaryingIn: message = "can't modify a varying"; break;
case EvqInput: message = "can't modify an input"; break;
case EvqFragCoord: message = "can't modify gl_FragCoord"; break;
......@@ -609,12 +612,27 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const
bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType)
{
if ((pType.qualifier == EvqVaryingIn || pType.qualifier == EvqVaryingOut || pType.qualifier == EvqAttribute) &&
pType.type == EbtStruct) {
error(line, "cannot be used with a structure", getQualifierString(pType.qualifier));
return true;
}
switch(pType.qualifier)
{
case EvqVaryingOut:
case EvqSmooth:
case EvqFlat:
case EvqCentroidOut:
case EvqVaryingIn:
case EvqSmoothIn:
case EvqFlatIn:
case EvqCentroidIn:
case EvqAttribute:
if(pType.type == EbtStruct)
{
error(line, "cannot be used with a structure", getQualifierString(pType.qualifier));
return true;
}
break;
default:
break;
}
if (pType.qualifier != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform"))
return true;
......@@ -1381,6 +1399,52 @@ TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualif
return joinedQualifier;
}
TPublicType TParseContext::joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier,
const TSourceLoc &storageLoc, TQualifier storageQualifier)
{
TQualifier mergedQualifier = EvqSmoothIn;
if(storageQualifier == EvqVaryingIn) {
if(interpolationQualifier == EvqSmooth)
mergedQualifier = EvqSmoothIn;
else if(interpolationQualifier == EvqFlat)
mergedQualifier = EvqFlatIn;
else UNREACHABLE();
}
else if(storageQualifier == EvqCentroidIn) {
if(interpolationQualifier == EvqSmooth)
mergedQualifier = EvqCentroidIn;
else if(interpolationQualifier == EvqFlat)
mergedQualifier = EvqFlatIn;
else UNREACHABLE();
}
else if(storageQualifier == EvqVaryingOut) {
if(interpolationQualifier == EvqSmooth)
mergedQualifier = EvqSmoothOut;
else if(interpolationQualifier == EvqFlat)
mergedQualifier = EvqFlatOut;
else UNREACHABLE();
}
else if(storageQualifier == EvqCentroidOut) {
if(interpolationQualifier == EvqSmooth)
mergedQualifier = EvqCentroidOut;
else if(interpolationQualifier == EvqFlat)
mergedQualifier = EvqFlatOut;
else UNREACHABLE();
}
else {
error(interpolationLoc, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getQualifierString(interpolationQualifier));
recover();
mergedQualifier = storageQualifier;
}
TPublicType type;
type.setBasic(EbtVoid, mergedQualifier, storageLoc);
return type;
}
bool TParseContext::enterStructDeclaration(int line, const TString& identifier)
{
++structNestingLevel;
......
......@@ -127,6 +127,7 @@ struct TParseContext {
TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine);
TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine);
TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier);
TPublicType joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier, const TSourceLoc &storageLoc, TQualifier storageQualifier);
// Performs an error check for embedded struct declarations.
// Returns true if an error was raised due to the declaration of
......
......@@ -173,7 +173,7 @@ extern void yyerror(TParseContext* context, const char* reason);
%type <interm.layoutQualifier> layout_qualifier layout_qualifier_id_list layout_qualifier_id
%type <interm.precision> precision_qualifier
%type <interm.type> type_qualifier fully_specified_type type_specifier storage_qualifier
%type <interm.type> type_qualifier fully_specified_type type_specifier storage_qualifier interpolation_qualifier
%type <interm.type> type_specifier_no_prec type_specifier_nonarray
%type <interm.type> struct_specifier
%type <interm.typeLine> struct_declarator
......@@ -1514,6 +1514,15 @@ fully_specified_type
}
;
interpolation_qualifier
: SMOOTH {
$$.qualifier = EvqSmooth;
}
| FLAT {
$$.qualifier = EvqFlat;
}
;
parameter_type_qualifier
: CONST_QUAL {
$$ = EvqConstReadOnly;
......@@ -1549,6 +1558,16 @@ type_qualifier
| storage_qualifier {
$$.setBasic(EbtVoid, $1.qualifier, $1.line);
}
| interpolation_qualifier storage_qualifier {
$$ = context->joinInterpolationQualifiers($1.line, $1.qualifier, $2.line, $2.qualifier);
}
| interpolation_qualifier {
context->error($1.line, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getQualifierString($1.qualifier));
context->recover();
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtVoid, qual, $1.line);
}
| layout_qualifier {
$$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.layoutQualifier = $1;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment