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 ...@@ -142,6 +142,16 @@ enum TQualifier : unsigned char
EvqFragColor, EvqFragColor,
EvqFragData, 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 // end of list
EvqLast EvqLast
}; };
...@@ -192,7 +202,13 @@ inline const char *getQualifierString(TQualifier qualifier) ...@@ -192,7 +202,13 @@ inline const char *getQualifierString(TQualifier qualifier)
case EvqFragCoord: return "FragCoord"; break; case EvqFragCoord: return "FragCoord"; break;
case EvqFrontFacing: return "FrontFacing"; break; case EvqFrontFacing: return "FrontFacing"; break;
case EvqFragColor: return "FragColor"; 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"; default: UNREACHABLE(); return "unknown qualifier";
} }
} }
......
...@@ -315,6 +315,9 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod ...@@ -315,6 +315,9 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod
case EvqConstReadOnly: message = "can't modify a const"; break; case EvqConstReadOnly: message = "can't modify a const"; break;
case EvqAttribute: message = "can't modify an attribute"; break; case EvqAttribute: message = "can't modify an attribute"; break;
case EvqUniform: message = "can't modify a uniform"; 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 EvqVaryingIn: message = "can't modify a varying"; break;
case EvqInput: message = "can't modify an input"; break; case EvqInput: message = "can't modify an input"; break;
case EvqFragCoord: message = "can't modify gl_FragCoord"; break; case EvqFragCoord: message = "can't modify gl_FragCoord"; break;
...@@ -609,12 +612,27 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const ...@@ -609,12 +612,27 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const
bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType) bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType)
{ {
if ((pType.qualifier == EvqVaryingIn || pType.qualifier == EvqVaryingOut || pType.qualifier == EvqAttribute) && switch(pType.qualifier)
pType.type == EbtStruct) { {
error(line, "cannot be used with a structure", getQualifierString(pType.qualifier)); case EvqVaryingOut:
case EvqSmooth:
return true; 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")) if (pType.qualifier != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform"))
return true; return true;
...@@ -1381,6 +1399,52 @@ TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualif ...@@ -1381,6 +1399,52 @@ TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualif
return joinedQualifier; 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) bool TParseContext::enterStructDeclaration(int line, const TString& identifier)
{ {
++structNestingLevel; ++structNestingLevel;
......
...@@ -127,6 +127,7 @@ struct TParseContext { ...@@ -127,6 +127,7 @@ struct TParseContext {
TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine); 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 parseLayoutQualifier(const TString &qualifierType, const TSourceLoc& qualifierTypeLine, const TString &intValueString, int intValue, const TSourceLoc& intValueLine);
TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier); 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. // Performs an error check for embedded struct declarations.
// Returns true if an error was raised due to the declaration of // Returns true if an error was raised due to the declaration of
......
...@@ -173,7 +173,7 @@ extern void yyerror(TParseContext* context, const char* reason); ...@@ -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.layoutQualifier> layout_qualifier layout_qualifier_id_list layout_qualifier_id
%type <interm.precision> precision_qualifier %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> type_specifier_no_prec type_specifier_nonarray
%type <interm.type> struct_specifier %type <interm.type> struct_specifier
%type <interm.typeLine> struct_declarator %type <interm.typeLine> struct_declarator
...@@ -1514,6 +1514,15 @@ fully_specified_type ...@@ -1514,6 +1514,15 @@ fully_specified_type
} }
; ;
interpolation_qualifier
: SMOOTH {
$$.qualifier = EvqSmooth;
}
| FLAT {
$$.qualifier = EvqFlat;
}
;
parameter_type_qualifier parameter_type_qualifier
: CONST_QUAL { : CONST_QUAL {
$$ = EvqConstReadOnly; $$ = EvqConstReadOnly;
...@@ -1549,6 +1558,16 @@ type_qualifier ...@@ -1549,6 +1558,16 @@ type_qualifier
| storage_qualifier { | storage_qualifier {
$$.setBasic(EbtVoid, $1.qualifier, $1.line); $$.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 { | layout_qualifier {
$$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.layoutQualifier = $1; $$.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