Commit 89dd8f37 by Qiankun Miao Committed by Commit Bot

Remove invariant declaration in vertex shader for translation from ESSL 3.00 to GLSL <= 4.1

This is a follow-up patch of https://chromium-review.googlesource.com/408569. This CL removes invariant declaration in ESSL 3.00 vertex shader, such like: " out vec4 foo; invariant foo; " This CL also adds the workarounds in libANGLE. BUG=chromium:639760 TEST=webgl2_conformance Change-Id: I568ab51a9a2f5da10d1aff0b63aae8805097e081 Reviewed-on: https://chromium-review.googlesource.com/409157 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent d9c6f501
...@@ -49,7 +49,7 @@ typedef unsigned int GLenum; ...@@ -49,7 +49,7 @@ typedef unsigned int GLenum;
// Version number for shader translation API. // Version number for shader translation API.
// It is incremented every time the API changes. // It is incremented every time the API changes.
#define ANGLE_SH_VERSION 166 #define ANGLE_SH_VERSION 167
enum ShShaderSpec enum ShShaderSpec
{ {
...@@ -226,8 +226,7 @@ const ShCompileOptions SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT = UINT64_C(1) ...@@ -226,8 +226,7 @@ const ShCompileOptions SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT = UINT64_C(1)
// TODO(zmo): This is not a good long-term solution. Simply dropping these qualifiers may break some // 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 // developers' content. A more complex workaround of dynamically generating, compiling, and
// re-linking shaders that use these qualifiers should be implemented. // 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_INVARIANT_AND_CENTROID_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. // Defines alternate strategies for implementing array index clamping.
enum ShArrayIndexClampingStrategy enum ShArrayIndexClampingStrategy
......
...@@ -103,6 +103,22 @@ bool IsGLSL410OrOlder(ShShaderOutput output) ...@@ -103,6 +103,22 @@ bool IsGLSL410OrOlder(ShShaderOutput output)
output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT); output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT);
} }
bool RemoveInvariant(sh::GLenum shaderType,
int shaderVersion,
ShShaderOutput outputType,
ShCompileOptions compileOptions)
{
if ((compileOptions & SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT) == 0 &&
shaderType == GL_FRAGMENT_SHADER && IsGLSL420OrNewer(outputType))
return true;
if ((compileOptions & SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3) != 0 &&
shaderVersion >= 300 && shaderType == GL_VERTEX_SHADER && IsGLSL410OrOlder(outputType))
return true;
return false;
}
size_t GetGlobalMaxTokenSize(ShShaderSpec spec) size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
{ {
// WebGL defines a max token legnth of 256, while ES2 leaves max token // WebGL defines a max token legnth of 256, while ES2 leaves max token
...@@ -394,8 +410,7 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[], ...@@ -394,8 +410,7 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
(outputType == SH_GLSL_COMPATIBILITY_OUTPUT))) (outputType == SH_GLSL_COMPATIBILITY_OUTPUT)))
initializeGLPosition(root); initializeGLPosition(root);
if (success && !(compileOptions & SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT) && if (success && RemoveInvariant(shaderType, shaderVersion, outputType, compileOptions))
shaderType == GL_FRAGMENT_SHADER && IsGLSL420OrNewer(outputType))
sh::RemoveInvariantDeclaration(root); sh::RemoveInvariantDeclaration(root);
// This pass might emit short circuits so keep it before the short circuit unfolding // This pass might emit short circuits so keep it before the short circuit unfolding
......
...@@ -45,6 +45,14 @@ bool IsGLSL420OrNewer(ShShaderOutput output); ...@@ -45,6 +45,14 @@ bool IsGLSL420OrNewer(ShShaderOutput output);
bool IsGLSL410OrOlder(ShShaderOutput output); bool IsGLSL410OrOlder(ShShaderOutput output);
// //
// Helper function to check if the invariant qualifier can be removed.
//
bool RemoveInvariant(sh::GLenum shaderType,
int shaderVersion,
ShShaderOutput outputType,
ShCompileOptions compileOptions);
//
// The base class used to back handles returned to the driver. // The base class used to back handles returned to the driver.
// //
class TShHandleBase { class TShHandleBase {
......
...@@ -14,6 +14,7 @@ TOutputESSL::TOutputESSL(TInfoSinkBase &objSink, ...@@ -14,6 +14,7 @@ TOutputESSL::TOutputESSL(TInfoSinkBase &objSink,
ShHashFunction64 hashFunction, ShHashFunction64 hashFunction,
NameMap &nameMap, NameMap &nameMap,
TSymbolTable &symbolTable, TSymbolTable &symbolTable,
sh::GLenum shaderType,
int shaderVersion, int shaderVersion,
bool forceHighp, bool forceHighp,
ShCompileOptions compileOptions) ShCompileOptions compileOptions)
...@@ -22,6 +23,7 @@ TOutputESSL::TOutputESSL(TInfoSinkBase &objSink, ...@@ -22,6 +23,7 @@ TOutputESSL::TOutputESSL(TInfoSinkBase &objSink,
hashFunction, hashFunction,
nameMap, nameMap,
symbolTable, symbolTable,
shaderType,
shaderVersion, shaderVersion,
SH_ESSL_OUTPUT, SH_ESSL_OUTPUT,
compileOptions), compileOptions),
......
...@@ -14,20 +14,21 @@ namespace sh ...@@ -14,20 +14,21 @@ namespace sh
class TOutputESSL : public TOutputGLSLBase class TOutputESSL : public TOutputGLSLBase
{ {
public: public:
TOutputESSL(TInfoSinkBase& objSink, TOutputESSL(TInfoSinkBase &objSink,
ShArrayIndexClampingStrategy clampingStrategy, ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction, ShHashFunction64 hashFunction,
NameMap& nameMap, NameMap &nameMap,
TSymbolTable& symbolTable, TSymbolTable &symbolTable,
sh::GLenum shaderType,
int shaderVersion, int shaderVersion,
bool forceHighp, bool forceHighp,
ShCompileOptions compileOptions); ShCompileOptions compileOptions);
protected: protected:
bool writeVariablePrecision(TPrecision precision) override; bool writeVariablePrecision(TPrecision precision) override;
private: private:
bool mForceHighp; bool mForceHighp;
}; };
......
...@@ -9,11 +9,12 @@ ...@@ -9,11 +9,12 @@
namespace sh namespace sh
{ {
TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink, TOutputGLSL::TOutputGLSL(TInfoSinkBase &objSink,
ShArrayIndexClampingStrategy clampingStrategy, ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction, ShHashFunction64 hashFunction,
NameMap& nameMap, NameMap &nameMap,
TSymbolTable& symbolTable, TSymbolTable &symbolTable,
sh::GLenum shaderType,
int shaderVersion, int shaderVersion,
ShShaderOutput output, ShShaderOutput output,
ShCompileOptions compileOptions) ShCompileOptions compileOptions)
...@@ -22,6 +23,7 @@ TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink, ...@@ -22,6 +23,7 @@ TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink,
hashFunction, hashFunction,
nameMap, nameMap,
symbolTable, symbolTable,
shaderType,
shaderVersion, shaderVersion,
output, output,
compileOptions) compileOptions)
......
...@@ -15,11 +15,12 @@ namespace sh ...@@ -15,11 +15,12 @@ namespace sh
class TOutputGLSL : public TOutputGLSLBase class TOutputGLSL : public TOutputGLSLBase
{ {
public: public:
TOutputGLSL(TInfoSinkBase& objSink, TOutputGLSL(TInfoSinkBase &objSink,
ShArrayIndexClampingStrategy clampingStrategy, ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction, ShHashFunction64 hashFunction,
NameMap& nameMap, NameMap &nameMap,
TSymbolTable& symbolTable, TSymbolTable &symbolTable,
sh::GLenum shaderType,
int shaderVersion, int shaderVersion,
ShShaderOutput output, ShShaderOutput output,
ShCompileOptions compileOptions); ShCompileOptions compileOptions);
......
...@@ -85,6 +85,7 @@ TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink, ...@@ -85,6 +85,7 @@ TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink,
ShHashFunction64 hashFunction, ShHashFunction64 hashFunction,
NameMap &nameMap, NameMap &nameMap,
TSymbolTable &symbolTable, TSymbolTable &symbolTable,
sh::GLenum shaderType,
int shaderVersion, int shaderVersion,
ShShaderOutput output, ShShaderOutput output,
ShCompileOptions compileOptions) ShCompileOptions compileOptions)
...@@ -95,6 +96,7 @@ TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink, ...@@ -95,6 +96,7 @@ TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink,
mHashFunction(hashFunction), mHashFunction(hashFunction),
mNameMap(nameMap), mNameMap(nameMap),
mSymbolTable(symbolTable), mSymbolTable(symbolTable),
mShaderType(shaderType),
mShaderVersion(shaderVersion), mShaderVersion(shaderVersion),
mOutput(output), mOutput(output),
mCompileOptions(compileOptions) mCompileOptions(compileOptions)
...@@ -103,11 +105,7 @@ TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink, ...@@ -103,11 +105,7 @@ TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink,
void TOutputGLSLBase::writeInvariantQualifier(const TType &type) void TOutputGLSLBase::writeInvariantQualifier(const TType &type)
{ {
bool removeInvariant = ((type.getQualifier() == EvqVaryingIn && sh::IsGLSL420OrNewer(mOutput) && if (!sh::RemoveInvariant(mShaderType, mShaderVersion, mOutput, mCompileOptions))
!(mCompileOptions & SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT)) ||
(sh::IsGLSL410OrOlder(mOutput) && mShaderVersion >= 300 &&
!!(mCompileOptions & SH_REMOVE_INVARIANT_FOR_ESSL3)));
if (!removeInvariant)
{ {
TInfoSinkBase &out = objSink(); TInfoSinkBase &out = objSink();
out << "invariant "; out << "invariant ";
...@@ -165,7 +163,7 @@ void TOutputGLSLBase::writeLayoutQualifier(const TType &type) ...@@ -165,7 +163,7 @@ void TOutputGLSLBase::writeLayoutQualifier(const TType &type)
const char *TOutputGLSLBase::mapQualifierToString(TQualifier qualifier) const char *TOutputGLSLBase::mapQualifierToString(TQualifier qualifier)
{ {
if (sh::IsGLSL410OrOlder(mOutput) && mShaderVersion >= 300 && if (sh::IsGLSL410OrOlder(mOutput) && mShaderVersion >= 300 &&
!!(mCompileOptions & SH_REMOVE_CENTROID_FOR_ESSL3)) (mCompileOptions & SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3) != 0)
{ {
switch (qualifier) switch (qualifier)
{ {
...@@ -960,8 +958,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -960,8 +958,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
ASSERT(sequence && sequence->size() == 1); ASSERT(sequence && sequence->size() == 1);
const TIntermSymbol *symbol = sequence->front()->getAsSymbolNode(); const TIntermSymbol *symbol = sequence->front()->getAsSymbolNode();
ASSERT(symbol); ASSERT(symbol);
writeInvariantQualifier(symbol->getType()); out << "invariant " << hashVariableName(symbol->getName());
out << hashVariableName(symbol->getName());
} }
visitChildren = false; visitChildren = false;
break; break;
......
...@@ -23,7 +23,8 @@ class TOutputGLSLBase : public TIntermTraverser ...@@ -23,7 +23,8 @@ class TOutputGLSLBase : public TIntermTraverser
ShArrayIndexClampingStrategy clampingStrategy, ShArrayIndexClampingStrategy clampingStrategy,
ShHashFunction64 hashFunction, ShHashFunction64 hashFunction,
NameMap &nameMap, NameMap &nameMap,
TSymbolTable& symbolTable, TSymbolTable &symbolTable,
sh::GLenum shaderType,
int shaderVersion, int shaderVersion,
ShShaderOutput output, ShShaderOutput output,
ShCompileOptions compileOptions); ShCompileOptions compileOptions);
...@@ -102,6 +103,8 @@ class TOutputGLSLBase : public TIntermTraverser ...@@ -102,6 +103,8 @@ class TOutputGLSLBase : public TIntermTraverser
TSymbolTable &mSymbolTable; TSymbolTable &mSymbolTable;
sh::GLenum mShaderType;
const int mShaderVersion; const int mShaderVersion;
ShShaderOutput mOutput; ShShaderOutput mOutput;
......
...@@ -15,7 +15,7 @@ namespace ...@@ -15,7 +15,7 @@ namespace
{ {
// An AST traverser that removes invariant declaration for input in fragment shader // An AST traverser that removes invariant declaration for input in fragment shader
// when GLSL >= 4.20. // when GLSL >= 4.20 and for output in vertex shader when GLSL < 4.2.
class RemoveInvariantDeclarationTraverser : public TIntermTraverser class RemoveInvariantDeclarationTraverser : public TIntermTraverser
{ {
public: public:
...@@ -26,17 +26,10 @@ class RemoveInvariantDeclarationTraverser : public TIntermTraverser ...@@ -26,17 +26,10 @@ class RemoveInvariantDeclarationTraverser : public TIntermTraverser
{ {
if (node->getOp() == EOpInvariantDeclaration) if (node->getOp() == EOpInvariantDeclaration)
{ {
for (TIntermNode *&child : *node->getSequence()) TIntermSequence emptyReplacement;
{ mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(),
TIntermTyped *typed = child->getAsTyped(); node, emptyReplacement));
if (typed && typed->getQualifier() == EvqVaryingIn) return false;
{
TIntermSequence emptyReplacement;
mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(
getParentNode()->getAsBlock(), node, emptyReplacement));
return false;
}
}
} }
return true; return true;
} }
......
...@@ -81,7 +81,8 @@ void TranslatorESSL::translate(TIntermNode *root, ShCompileOptions compileOption ...@@ -81,7 +81,8 @@ void TranslatorESSL::translate(TIntermNode *root, ShCompileOptions compileOption
// Write translated shader. // Write translated shader.
TOutputESSL outputESSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), TOutputESSL outputESSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(),
getSymbolTable(), shaderVer, precisionEmulation, compileOptions); getSymbolTable(), getShaderType(), shaderVer, precisionEmulation,
compileOptions);
root->traverse(&outputESSL); root->traverse(&outputESSL);
} }
......
...@@ -188,13 +188,8 @@ void TranslatorGLSL::translate(TIntermNode *root, ShCompileOptions compileOption ...@@ -188,13 +188,8 @@ void TranslatorGLSL::translate(TIntermNode *root, ShCompileOptions compileOption
} }
// Write translated shader. // Write translated shader.
TOutputGLSL outputGLSL(sink, TOutputGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(),
getArrayIndexClampingStrategy(), getSymbolTable(), getShaderType(), getShaderVersion(), getOutputType(),
getHashFunction(),
getNameMap(),
getSymbolTable(),
getShaderVersion(),
getOutputType(),
compileOptions); compileOptions);
root->traverse(&outputGLSL); root->traverse(&outputGLSL);
} }
......
...@@ -80,6 +80,11 @@ ShCompileOptions ShaderGL::prepareSourceAndReturnOptions(std::stringstream *sour ...@@ -80,6 +80,11 @@ ShCompileOptions ShaderGL::prepareSourceAndReturnOptions(std::stringstream *sour
options |= SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT; options |= SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT;
} }
if (mWorkarounds.removeInvariantAndCentroidForESSL3)
{
options |= SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3;
}
return options; return options;
} }
......
...@@ -26,7 +26,8 @@ struct WorkaroundsGL ...@@ -26,7 +26,8 @@ struct WorkaroundsGL
addAndTrueToLoopCondition(false), addAndTrueToLoopCondition(false),
emulateIsnanFloat(false), emulateIsnanFloat(false),
useUnusedBlocksWithStandardOrSharedLayout(false), useUnusedBlocksWithStandardOrSharedLayout(false),
dontRemoveInvariantForFragmentInput(false) dontRemoveInvariantForFragmentInput(false),
removeInvariantAndCentroidForESSL3(false)
{ {
} }
...@@ -116,6 +117,9 @@ struct WorkaroundsGL ...@@ -116,6 +117,9 @@ struct WorkaroundsGL
// This flag will keep invariant declaration for input in fragment shader for GLSL >=4.20 // This flag will keep invariant declaration for input in fragment shader for GLSL >=4.20
// on AMD. // on AMD.
bool dontRemoveInvariantForFragmentInput; bool dontRemoveInvariantForFragmentInput;
// This flag is used to fix spec difference between GLSL 4.1 or lower and ESSL3.
bool removeInvariantAndCentroidForESSL3;
}; };
} }
......
...@@ -944,6 +944,8 @@ void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workaround ...@@ -944,6 +944,8 @@ void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workaround
workarounds->unpackLastRowSeparatelyForPaddingInclusion = IsNvidia(vendor); workarounds->unpackLastRowSeparatelyForPaddingInclusion = IsNvidia(vendor);
workarounds->packLastRowSeparatelyForPaddingInclusion = IsNvidia(vendor); workarounds->packLastRowSeparatelyForPaddingInclusion = IsNvidia(vendor);
#endif #endif
workarounds->removeInvariantAndCentroidForESSL3 = functions->isAtMostGL(gl::Version(4, 1));
} }
} }
......
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