Commit b7bf7426 by Zhenyao Mo Committed by Commit Bot

Don't ouput "invarant" and "centroid" in GLSL 4.1 or older.

BUG=chromium:639760,chromium:641129 TEST=webgl2_conformance Change-Id: I5fe87246eaea78888529d7b45b79399e6065daa9 Reviewed-on: https://chromium-review.googlesource.com/408569Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org> Commit-Queue: Zhenyao Mo <zmo@chromium.org>
parent 70697252
......@@ -219,6 +219,16 @@ const ShCompileOptions SH_USE_UNUSED_STANDARD_SHARED_BLOCKS = UINT64_C(1) << 28;
// But don't remove on AMD Linux to avoid triggering the bug on AMD.
const ShCompileOptions SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT = UINT64_C(1) << 29;
// Due to spec difference between GLSL 4.1 or lower and ESSL3, some platforms (for example, Mac OSX
// core profile) require a variable's "invariant"/"centroid" qualifiers to match between vertex and
// fragment shader. A simple solution to allow such shaders to link is to omit the two qualifiers.
// Note that the two flags only take effect on ESSL3 input shaders translated to GLSL 4.1 or lower.
// TODO(zmo): This is not a good long-term solution. Simply dropping these qualifiers may break some
// developers' content. A more complex workaround of dynamically generating, compiling, and
// re-linking shaders that use these qualifiers should be implemented.
const ShCompileOptions SH_REMOVE_INVARIANT_FOR_ESSL3 = UINT64_C(1) << 30;
const ShCompileOptions SH_REMOVE_CENTROID_FOR_ESSL3 = UINT64_C(1) << 31;
// Defines alternate strategies for implementing array index clamping.
enum ShArrayIndexClampingStrategy
{
......
......@@ -96,6 +96,13 @@ bool IsGLSL420OrNewer(ShShaderOutput output)
output == SH_GLSL_440_CORE_OUTPUT || output == SH_GLSL_450_CORE_OUTPUT);
}
bool IsGLSL410OrOlder(ShShaderOutput output)
{
return (output == SH_GLSL_130_OUTPUT || output == SH_GLSL_140_OUTPUT ||
output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT ||
output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT);
}
size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
{
// WebGL defines a max token legnth of 256, while ES2 leaves max token
......
......@@ -42,6 +42,7 @@ bool IsWebGLBasedSpec(ShShaderSpec spec);
//
bool IsGLSL130OrNewer(ShShaderOutput output);
bool IsGLSL420OrNewer(ShShaderOutput output);
bool IsGLSL410OrOlder(ShShaderOutput output);
//
// The base class used to back handles returned to the driver.
......
......@@ -101,6 +101,19 @@ TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink,
{
}
void TOutputGLSLBase::writeInvariantQualifier(const TType &type)
{
bool removeInvariant = ((type.getQualifier() == EvqVaryingIn && sh::IsGLSL420OrNewer(mOutput) &&
!(mCompileOptions & SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT)) ||
(sh::IsGLSL410OrOlder(mOutput) && mShaderVersion >= 300 &&
!!(mCompileOptions & SH_REMOVE_INVARIANT_FOR_ESSL3)));
if (!removeInvariant)
{
TInfoSinkBase &out = objSink();
out << "invariant ";
}
}
void TOutputGLSLBase::writeTriplet(
Visit visit, const char *preStr, const char *inStr, const char *postStr)
{
......@@ -149,15 +162,49 @@ void TOutputGLSLBase::writeLayoutQualifier(const TType &type)
out << ") ";
}
const char *TOutputGLSLBase::mapQualifierToString(TQualifier qualifier)
{
if (sh::IsGLSL410OrOlder(mOutput) && mShaderVersion >= 300 &&
!!(mCompileOptions & SH_REMOVE_CENTROID_FOR_ESSL3))
{
switch (qualifier)
{
// The return string is consistent with sh::getQualifierString() from
// BaseTypes.h minus the "centroid" keyword.
case EvqCentroid:
return "";
case EvqCentroidIn:
return "smooth in";
case EvqCentroidOut:
return "smooth out";
default:
break;
}
}
if (sh::IsGLSL130OrNewer(mOutput))
{
switch (qualifier)
{
case EvqAttribute:
return "in";
case EvqVaryingIn:
return "in";
case EvqVaryingOut:
return "out";
default:
break;
}
}
return sh::getQualifierString(qualifier);
}
void TOutputGLSLBase::writeVariableType(const TType &type)
{
TQualifier qualifier = type.getQualifier();
TInfoSinkBase &out = objSink();
bool removeInvariant = (qualifier == EvqVaryingIn && sh::IsGLSL420OrNewer(mOutput) &&
!(mCompileOptions & SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT));
if (type.isInvariant() && !removeInvariant)
if (type.isInvariant())
{
out << "invariant ";
writeInvariantQualifier(type);
}
if (type.getBasicType() == EbtInterfaceBlock)
{
......@@ -166,27 +213,10 @@ void TOutputGLSLBase::writeVariableType(const TType &type)
}
if (qualifier != EvqTemporary && qualifier != EvqGlobal)
{
if (sh::IsGLSL130OrNewer(mOutput))
{
switch (qualifier)
{
case EvqAttribute:
out << "in ";
break;
case EvqVaryingIn:
out << "in ";
break;
case EvqVaryingOut:
out << "out ";
break;
default:
out << type.getQualifierString() << " ";
break;
}
}
else
const char *qualifierString = mapQualifierToString(qualifier);
if (qualifierString && qualifierString[0] != '\0')
{
out << type.getQualifierString() << " ";
out << qualifierString << " ";
}
}
......@@ -930,7 +960,8 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
ASSERT(sequence && sequence->size() == 1);
const TIntermSymbol *symbol = sequence->front()->getAsSymbolNode();
ASSERT(symbol);
out << "invariant " << hashVariableName(symbol->getName());
writeInvariantQualifier(symbol->getType());
out << hashVariableName(symbol->getName());
}
visitChildren = false;
break;
......
......@@ -37,6 +37,7 @@ class TOutputGLSLBase : public TIntermTraverser
TInfoSinkBase &objSink() { return mObjSink; }
void writeTriplet(Visit visit, const char *preStr, const char *inStr, const char *postStr);
void writeLayoutQualifier(const TType &type);
void writeInvariantQualifier(const TType &type);
void writeVariableType(const TType &type);
virtual bool writeVariablePrecision(TPrecision precision) = 0;
void writeFunctionParameters(const TIntermSequence &args);
......@@ -81,6 +82,8 @@ class TOutputGLSLBase : public TIntermTraverser
void writeBuiltInFunctionTriplet(Visit visit, const char *preStr, bool useEmulatedFunction);
const char *mapQualifierToString(TQualifier qialifier);
TInfoSinkBase &mObjSink;
bool mDeclaringVariables;
......
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