Commit 19571818 by Jamie Madill

Add more robust support for interpolation and storage qualifiers with varyings for GLSL ES 3.00.

This fixes some conformance failures in the dEQP varying link tests, particularly with ints and the flat keyword. TRAC #23745 Signed-off-by: Nicolas Capens Signed-off-by: Shannon Woods
parent f2e0f9bb
......@@ -301,8 +301,11 @@ enum TQualifier
EvqInvariantVaryingIn, // readonly, fragment shaders only
EvqInvariantVaryingOut, // vertex shaders only read/write
EvqUniform, // Readonly, vertex and fragment
EvqVertexInput, // Vertex shader input
EvqFragmentOutput, // Fragment shader output
EvqVertexIn, // Vertex shader input
EvqFragmentOut, // Fragment shader output
EvqVertexOut, // Vertex shader output
EvqFragmentIn, // Fragment shader input
// parameters
EvqIn,
......@@ -393,8 +396,10 @@ inline const char* getQualifierString(TQualifier q)
case EvqInvariantVaryingIn: return "invariant varying"; break;
case EvqInvariantVaryingOut:return "invariant varying"; break;
case EvqUniform: return "uniform"; break;
case EvqVertexInput: return "in"; break;
case EvqFragmentOutput: return "out"; break;
case EvqVertexIn: return "in"; break;
case EvqFragmentOut: return "out"; break;
case EvqVertexOut: return "out"; break;
case EvqFragmentIn: return "in"; break;
case EvqIn: return "in"; break;
case EvqOut: return "out"; break;
case EvqInOut: return "inout"; break;
......
......@@ -1549,7 +1549,7 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
out << decorateUniform(name, nodeType);
}
else if (qualifier == EvqAttribute || qualifier == EvqVertexInput)
else if (qualifier == EvqAttribute || qualifier == EvqVertexIn)
{
mReferencedAttributes[name] = node;
out << decorate(name);
......@@ -1559,7 +1559,7 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
mReferencedVaryings[name] = node;
out << decorate(name);
}
else if (qualifier == EvqFragmentOutput)
else if (qualifier == EvqFragmentOut)
{
mReferencedOutputVariables[name] = node;
out << "out_" << name;
......@@ -2924,11 +2924,13 @@ TString OutputHLSL::interpolationString(TQualifier qualifier)
switch(qualifier)
{
case EvqVaryingIn: return "";
case EvqFragmentIn: return "";
case EvqInvariantVaryingIn: return "";
case EvqSmoothIn: return "linear";
case EvqFlatIn: return "nointerpolation";
case EvqCentroidIn: return "centroid";
case EvqVaryingOut: return "";
case EvqVertexOut: return "";
case EvqInvariantVaryingOut: return "";
case EvqSmoothOut: return "linear";
case EvqFlatOut: return "nointerpolation";
......@@ -3772,6 +3774,7 @@ bool OutputHLSL::isVaryingOut(TQualifier qualifier)
case EvqSmoothOut:
case EvqFlatOut:
case EvqCentroidOut:
case EvqVertexOut:
return true;
}
......@@ -3787,6 +3790,7 @@ bool OutputHLSL::isVaryingIn(TQualifier qualifier)
case EvqSmoothIn:
case EvqFlatIn:
case EvqCentroidIn:
case EvqFragmentIn:
return true;
}
......
......@@ -318,7 +318,8 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& line, const char* op, TIn
case EvqConst: 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 EvqVertexInput: message = "can't modify an input"; break;
case EvqFragmentIn: message = "can't modify an input"; break;
case EvqVertexIn: message = "can't modify an input"; break;
case EvqUniform: message = "can't modify a uniform"; break;
case EvqVaryingIn: message = "can't modify a varying"; break;
case EvqFragCoord: message = "can't modify gl_FragCoord"; break;
......@@ -630,8 +631,8 @@ bool TParseContext::structQualifierErrorCheck(const TSourceLoc& line, const TPub
case EvqVaryingIn:
case EvqVaryingOut:
case EvqAttribute:
case EvqVertexInput:
case EvqFragmentOutput:
case EvqVertexIn:
case EvqFragmentOut:
if (pType.type == EbtStruct)
{
error(line, "cannot be used with a structure", getQualifierString(pType.qualifier));
......@@ -732,7 +733,7 @@ bool TParseContext::arraySizeErrorCheck(const TSourceLoc& line, TIntermTyped* ex
//
bool TParseContext::arrayQualifierErrorCheck(const TSourceLoc& line, TPublicType type)
{
if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqVertexInput) || (type.qualifier == EvqConst)) {
if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqVertexIn) || (type.qualifier == EvqConst)) {
error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str());
return true;
}
......@@ -938,7 +939,7 @@ bool TParseContext::singleDeclarationErrorCheck(TPublicType &publicType, const T
return true;
}
if (publicType.qualifier != EvqVertexInput && publicType.qualifier != EvqFragmentOutput && layoutLocationErrorCheck(identifierLocation, publicType.layoutQualifier))
if (publicType.qualifier != EvqVertexIn && publicType.qualifier != EvqFragmentOut && layoutLocationErrorCheck(identifierLocation, publicType.layoutQualifier))
{
return true;
}
......@@ -1164,10 +1165,28 @@ TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, TLayoutQu
{
switch (qualifier)
{
case EvqVertexInput:
case EvqFragmentOutput:
case EvqVaryingIn:
case EvqVaryingOut:
case EvqSmoothIn:
case EvqSmoothOut:
case EvqVertexOut:
case EvqFragmentIn:
case EvqCentroidOut:
case EvqCentroidIn:
if (typeSpecifier.type == EbtBool)
{
error(typeSpecifier.line, "cannot be bool", getQualifierString(qualifier));
recover();
}
if (typeSpecifier.type == EbtInt || typeSpecifier.type == EbtUInt)
{
error(typeSpecifier.line, "must use 'flat' interpolation here", getQualifierString(qualifier));
recover();
}
break;
case EvqVertexIn:
case EvqFragmentOut:
case EvqFlatIn:
case EvqFlatOut:
if (typeSpecifier.type == EbtBool)
{
error(typeSpecifier.line, "cannot be bool", getQualifierString(qualifier));
......@@ -2123,12 +2142,12 @@ TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, co
{
if (baseExpression->isInterfaceBlock())
{
error(location, "", "[", "array indexes for interface blocks arrays must be constant integeral expressions");
error(location, "", "[", "array indexes for interface blocks arrays must be constant integral expressions");
recover();
}
else if (baseExpression->getQualifier() == EvqFragmentOutput)
else if (baseExpression->getQualifier() == EvqFragmentOut)
{
error(location, "", "[", "array indexes for output variables must be constant integeral expressions");
error(location, "", "[", "array indexes for fragment outputs must be constant integral expressions");
recover();
}
......@@ -2462,7 +2481,7 @@ TPublicType TParseContext::joinInterpolationQualifiers(const TSourceLoc &interpo
{
TQualifier mergedQualifier = EvqSmoothIn;
if (storageQualifier == EvqSmoothIn) {
if (storageQualifier == EvqFragmentIn) {
if (interpolationQualifier == EvqSmooth)
mergedQualifier = EvqSmoothIn;
else if (interpolationQualifier == EvqFlat)
......@@ -2476,7 +2495,7 @@ TPublicType TParseContext::joinInterpolationQualifiers(const TSourceLoc &interpo
mergedQualifier = EvqFlatIn;
else UNREACHABLE();
}
else if (storageQualifier == EvqSmoothOut) {
else if (storageQualifier == EvqVertexOut) {
if (interpolationQualifier == EvqSmooth)
mergedQualifier = EvqSmoothOut;
else if (interpolationQualifier == EvqFlat)
......
......@@ -27,7 +27,7 @@ void ValidateOutputs::visitSymbol(TIntermSymbol *symbol)
mVisitedSymbols.insert(name);
if (qualifier == EvqFragmentOutput)
if (qualifier == EvqFragmentOut)
{
const TType &type = symbol->getType();
const int location = type.getLayoutQualifier().location;
......
......@@ -246,9 +246,9 @@ bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
case EOpDeclaration: {
const TIntermSequence& sequence = node->getSequence();
TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
if (qualifier == EvqAttribute || qualifier == EvqVertexInput || qualifier == EvqUniform)
if (qualifier == EvqAttribute || qualifier == EvqVertexIn || qualifier == EvqUniform)
{
TVariableInfoList& infoList = (qualifier == EvqAttribute || qualifier == EvqVertexInput) ?
TVariableInfoList& infoList = (qualifier == EvqAttribute || qualifier == EvqVertexIn) ?
mAttribs : mUniforms;
for (TIntermSequence::const_iterator i = sequence.begin();
i != sequence.end(); ++i)
......
......@@ -1190,11 +1190,11 @@ storage_qualifier
}
| IN_QUAL {
ES3_ONLY("in", @1, "storage qualifier");
$$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqSmoothIn : EvqVertexInput;
$$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn;
}
| OUT_QUAL {
ES3_ONLY("out", @1, "storage qualifier");
$$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentOutput : EvqSmoothOut;
$$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut;
}
| CENTROID IN_QUAL {
ES3_ONLY("centroid in", @1, "storage qualifier");
......@@ -1203,7 +1203,7 @@ storage_qualifier
context->error(@1, "invalid storage qualifier", "it is an error to use 'centroid in' in the vertex shader");
context->recover();
}
$$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexInput;
$$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn;
}
| CENTROID OUT_QUAL {
ES3_ONLY("centroid out", @1, "storage qualifier");
......@@ -1212,7 +1212,7 @@ storage_qualifier
context->error(@1, "invalid storage qualifier", "it is an error to use 'centroid out' in the fragment shader");
context->recover();
}
$$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentOutput : EvqCentroidOut;
$$.qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut;
}
| UNIFORM {
if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "uniform"))
......
......@@ -3852,7 +3852,7 @@ yyreduce:
{
ES3_ONLY("in", (yylsp[(1) - (1)]), "storage qualifier");
(yyval.interm.type).qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqSmoothIn : EvqVertexInput;
(yyval.interm.type).qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn;
}
break;
......@@ -3860,7 +3860,7 @@ yyreduce:
{
ES3_ONLY("out", (yylsp[(1) - (1)]), "storage qualifier");
(yyval.interm.type).qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentOutput : EvqSmoothOut;
(yyval.interm.type).qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut;
}
break;
......@@ -3873,7 +3873,7 @@ yyreduce:
context->error((yylsp[(1) - (2)]), "invalid storage qualifier", "it is an error to use 'centroid in' in the vertex shader");
context->recover();
}
(yyval.interm.type).qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexInput;
(yyval.interm.type).qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn;
}
break;
......@@ -3886,7 +3886,7 @@ yyreduce:
context->error((yylsp[(1) - (2)]), "invalid storage qualifier", "it is an error to use 'centroid out' in the fragment shader");
context->recover();
}
(yyval.interm.type).qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentOutput : EvqCentroidOut;
(yyval.interm.type).qualifier = (context->shaderType == SH_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut;
}
break;
......
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