Implemented interpolation qualifier parsing.

TRAC #22857 Signed-off-by: Jamie Madill Signed-off-by: Shannon Woods Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2149 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent e229012c
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
......@@ -113,6 +113,16 @@ enum TQualifier
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
};
......@@ -144,9 +154,29 @@ inline const char* getQualifierString(TQualifier q)
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 EvqSmoothOut: return "smooth out"; break;
case EvqCentroidOut: return "centroid out"; break;
case EvqFlatOut: return "flat out"; break;
case EvqSmoothIn: return "smooth in"; break;
case EvqCentroidIn: return "centroid in"; break;
case EvqFlatIn: return "flat in"; break;
default: return "unknown qualifier";
}
}
inline const char* getInterpolationString(TQualifier q)
{
switch(q)
{
case EvqSmoothOut: return "smooth"; break;
case EvqCentroidOut: return "centroid"; break;
case EvqFlatOut: return "flat"; break;
case EvqSmoothIn: return "smooth"; break;
case EvqCentroidIn: return "centroid"; break;
case EvqFlatIn: return "flat"; break;
default: return "unknown interpolation";
}
}
#endif // _BASICTYPES_INCLUDED_
......@@ -1150,7 +1150,7 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
mReferencedAttributes[name] = node;
out << decorate(name);
}
else if (qualifier == EvqVaryingOut || qualifier == EvqInvariantVaryingOut || qualifier == EvqVaryingIn || qualifier == EvqInvariantVaryingIn)
else if (isVarying(qualifier))
{
mReferencedVaryings[name] = node;
out << decorate(name);
......@@ -1644,7 +1644,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
}
else UNREACHABLE();
}
else if (variable && (variable->getQualifier() == EvqVaryingOut || variable->getQualifier() == EvqInvariantVaryingOut))
else if (variable && isVaryingOut(variable->getQualifier()))
{
for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++)
{
......@@ -3221,4 +3221,39 @@ GLenum OutputHLSL::glVariablePrecision(const TType &type)
return GL_NONE;
}
bool OutputHLSL::isVaryingOut(TQualifier qualifier)
{
switch(qualifier)
{
case EvqVaryingOut:
case EvqInvariantVaryingOut:
case EvqSmoothOut:
case EvqFlatOut:
case EvqCentroidOut:
return true;
}
return false;
}
bool OutputHLSL::isVaryingIn(TQualifier qualifier)
{
switch(qualifier)
{
case EvqVaryingIn:
case EvqInvariantVaryingIn:
case EvqSmoothIn:
case EvqFlatIn:
case EvqCentroidIn:
return true;
}
return false;
}
bool OutputHLSL::isVarying(TQualifier qualifier)
{
return isVaryingIn(qualifier) || isVaryingOut(qualifier);
}
}
......@@ -168,8 +168,12 @@ class OutputHLSL : public TIntermTraverser
int samplerRegister(TIntermSymbol *sampler);
int uniformRegister(TIntermSymbol *uniform);
void declareUniform(const TType &type, const TString &name, int index);
static GLenum glVariableType(const TType &type);
static GLenum glVariablePrecision(const TType &type);
static bool isVaryingIn(TQualifier qualifier);
static bool isVaryingOut(TQualifier qualifier);
static bool isVarying(TQualifier qualifier);
ActiveUniforms mActiveUniforms;
};
......
//
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
......@@ -277,7 +277,7 @@ protected:
void computeDeepestStructNesting();
TBasicType type : 6;
TPrecision precision;
TPrecision precision : 4;
TQualifier qualifier : 7;
int size : 8; // size of vector or matrix, not size of array
unsigned int matrix : 1;
......
......@@ -167,7 +167,7 @@ extern void yyerror(TParseContext* context, const char* reason);
%type <interm.qualifier> parameter_qualifier parameter_type_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> struct_specifier
%type <interm.typeLine> struct_declarator
......@@ -1502,6 +1502,17 @@ fully_specified_type
}
;
interpolation_qualifier
: SMOOTH {
$$.qualifier = EvqSmooth;
$$.line = $1.line;
}
| FLAT {
$$.qualifier = EvqFlat;
$$.line = $1.line;
}
;
parameter_type_qualifier
: CONST_QUAL {
$$ = EvqConst;
......@@ -1511,13 +1522,13 @@ parameter_type_qualifier
type_qualifier
: ATTRIBUTE {
VERTEX_ONLY("attribute", $1.line);
ES2_ONLY("attribute", $1.line);
ES2_ONLY("attribute", $1.line);
if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "attribute"))
context->recover();
$$.setBasic(EbtVoid, EvqAttribute, $1.line);
}
| VARYING {
ES2_ONLY("varying", $1.line);
ES2_ONLY("varying", $1.line);
if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "varying"))
context->recover();
if (context->shaderType == SH_VERTEX_SHADER)
......@@ -1526,7 +1537,7 @@ type_qualifier
$$.setBasic(EbtVoid, EvqVaryingIn, $1.line);
}
| INVARIANT VARYING {
ES2_ONLY("varying", $1.line);
ES2_ONLY("varying", $1.line);
if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "invariant varying"))
context->recover();
if (context->shaderType == SH_VERTEX_SHADER)
......@@ -1534,43 +1545,84 @@ type_qualifier
else
$$.setBasic(EbtVoid, EvqInvariantVaryingIn, $1.line);
}
| storage_qualifier {
| storage_qualifier {
$$.setBasic(EbtVoid, $1.qualifier, $1.line);
}
| interpolation_qualifier storage_qualifier {
if ($2.qualifier == EvqSmoothIn) {
if ($1.qualifier == EvqSmooth)
$$.setBasic(EbtVoid, EvqSmoothIn, $2.line);
else if ($1.qualifier == EvqFlat)
$$.setBasic(EbtVoid, EvqFlatIn, $2.line);
else UNREACHABLE();
}
else if ($2.qualifier == EvqCentroidIn) {
if ($1.qualifier == EvqSmooth)
$$.setBasic(EbtVoid, EvqCentroidIn, $2.line);
else if ($1.qualifier == EvqFlat)
$$.setBasic(EbtVoid, EvqFlatIn, $2.line);
else UNREACHABLE();
}
else if ($2.qualifier == EvqSmoothOut) {
if ($1.qualifier == EvqSmooth)
$$.setBasic(EbtVoid, EvqSmoothOut, $2.line);
else if ($1.qualifier == EvqFlat)
$$.setBasic(EbtVoid, EvqFlatOut, $2.line);
else UNREACHABLE();
}
else if ($2.qualifier == EvqCentroidOut) {
if ($1.qualifier == EvqSmooth)
$$.setBasic(EbtVoid, EvqCentroidOut, $2.line);
else if ($1.qualifier == EvqFlat)
$$.setBasic(EbtVoid, EvqFlatOut, $2.line);
else UNREACHABLE();
}
else {
context->error($1.line, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getInterpolationString($1.qualifier));
context->recover();
$$.setBasic(EbtVoid, $2.qualifier, $2.line);
}
}
| interpolation_qualifier {
context->error($1.line, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getInterpolationString($1.qualifier));
context->recover();
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtVoid, qual, $1.line);
}
;
storage_qualifier
: CONST_QUAL {
$$.qualifier = EvqConst;
$$.line = $1.line;
$$.line = $1.line;
}
| IN_QUAL {
ES3_ONLY("in", $1.line);
$$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqVaryingIn : EvqAttribute;
$$.line = $1.line;
ES3_ONLY("in", $1.line);
$$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqSmoothIn : EvqAttribute;
$$.line = $1.line;
}
| OUT_QUAL {
ES3_ONLY("out", $1.line);
$$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragColor : EvqVaryingOut;
$$.line = $1.line;
ES3_ONLY("out", $1.line);
$$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragColor : EvqSmoothOut;
$$.line = $1.line;
}
| CENTROID IN_QUAL {
ES3_ONLY("in", $1.line);
// FIXME: Handle centroid qualifier
$$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqVaryingIn : EvqAttribute;
$$.line = $2.line;
}
| CENTROID OUT_QUAL {
ES3_ONLY("out", $1.line);
// FIXME: Handle centroid qualifier
$$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragColor : EvqVaryingOut;
$$.line = $2.line;
}
| UNIFORM {
ES3_ONLY("centroid in", $1.line);
$$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqCentroidIn : EvqAttribute;
$$.line = $1.line;
}
| CENTROID OUT_QUAL {
ES3_ONLY("centroid out", $1.line);
$$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragColor : EvqCentroidOut;
$$.line = $1.line;
}
| UNIFORM {
if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "uniform"))
context->recover();
$$.qualifier = EvqUniform;
$$.line = $1.line;
$$.line = $1.line;
}
;
......
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