зеркало из https://github.com/AvaloniaUI/angle.git
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: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Родитель
d9c6f50118
Коммит
89dd8f3701
|
@ -49,7 +49,7 @@ typedef unsigned int GLenum;
|
|||
|
||||
// Version number for shader translation API.
|
||||
// It is incremented every time the API changes.
|
||||
#define ANGLE_SH_VERSION 166
|
||||
#define ANGLE_SH_VERSION 167
|
||||
|
||||
enum ShShaderSpec
|
||||
{
|
||||
|
@ -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
|
||||
// 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;
|
||||
const ShCompileOptions SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3 = UINT64_C(1) << 30;
|
||||
|
||||
// Defines alternate strategies for implementing array index clamping.
|
||||
enum ShArrayIndexClampingStrategy
|
||||
|
|
|
@ -103,6 +103,22 @@ bool IsGLSL410OrOlder(ShShaderOutput 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)
|
||||
{
|
||||
// WebGL defines a max token legnth of 256, while ES2 leaves max token
|
||||
|
@ -394,8 +410,7 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
|
|||
(outputType == SH_GLSL_COMPATIBILITY_OUTPUT)))
|
||||
initializeGLPosition(root);
|
||||
|
||||
if (success && !(compileOptions & SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT) &&
|
||||
shaderType == GL_FRAGMENT_SHADER && IsGLSL420OrNewer(outputType))
|
||||
if (success && RemoveInvariant(shaderType, shaderVersion, outputType, compileOptions))
|
||||
sh::RemoveInvariantDeclaration(root);
|
||||
|
||||
// This pass might emit short circuits so keep it before the short circuit unfolding
|
||||
|
|
|
@ -44,6 +44,14 @@ bool IsGLSL130OrNewer(ShShaderOutput output);
|
|||
bool IsGLSL420OrNewer(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.
|
||||
//
|
||||
|
|
|
@ -14,6 +14,7 @@ TOutputESSL::TOutputESSL(TInfoSinkBase &objSink,
|
|||
ShHashFunction64 hashFunction,
|
||||
NameMap &nameMap,
|
||||
TSymbolTable &symbolTable,
|
||||
sh::GLenum shaderType,
|
||||
int shaderVersion,
|
||||
bool forceHighp,
|
||||
ShCompileOptions compileOptions)
|
||||
|
@ -22,6 +23,7 @@ TOutputESSL::TOutputESSL(TInfoSinkBase &objSink,
|
|||
hashFunction,
|
||||
nameMap,
|
||||
symbolTable,
|
||||
shaderType,
|
||||
shaderVersion,
|
||||
SH_ESSL_OUTPUT,
|
||||
compileOptions),
|
||||
|
|
|
@ -14,20 +14,21 @@ namespace sh
|
|||
|
||||
class TOutputESSL : public TOutputGLSLBase
|
||||
{
|
||||
public:
|
||||
TOutputESSL(TInfoSinkBase& objSink,
|
||||
public:
|
||||
TOutputESSL(TInfoSinkBase &objSink,
|
||||
ShArrayIndexClampingStrategy clampingStrategy,
|
||||
ShHashFunction64 hashFunction,
|
||||
NameMap& nameMap,
|
||||
TSymbolTable& symbolTable,
|
||||
NameMap &nameMap,
|
||||
TSymbolTable &symbolTable,
|
||||
sh::GLenum shaderType,
|
||||
int shaderVersion,
|
||||
bool forceHighp,
|
||||
ShCompileOptions compileOptions);
|
||||
|
||||
protected:
|
||||
bool writeVariablePrecision(TPrecision precision) override;
|
||||
protected:
|
||||
bool writeVariablePrecision(TPrecision precision) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
bool mForceHighp;
|
||||
};
|
||||
|
||||
|
|
|
@ -9,11 +9,12 @@
|
|||
namespace sh
|
||||
{
|
||||
|
||||
TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink,
|
||||
TOutputGLSL::TOutputGLSL(TInfoSinkBase &objSink,
|
||||
ShArrayIndexClampingStrategy clampingStrategy,
|
||||
ShHashFunction64 hashFunction,
|
||||
NameMap& nameMap,
|
||||
TSymbolTable& symbolTable,
|
||||
NameMap &nameMap,
|
||||
TSymbolTable &symbolTable,
|
||||
sh::GLenum shaderType,
|
||||
int shaderVersion,
|
||||
ShShaderOutput output,
|
||||
ShCompileOptions compileOptions)
|
||||
|
@ -22,6 +23,7 @@ TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink,
|
|||
hashFunction,
|
||||
nameMap,
|
||||
symbolTable,
|
||||
shaderType,
|
||||
shaderVersion,
|
||||
output,
|
||||
compileOptions)
|
||||
|
|
|
@ -15,11 +15,12 @@ namespace sh
|
|||
class TOutputGLSL : public TOutputGLSLBase
|
||||
{
|
||||
public:
|
||||
TOutputGLSL(TInfoSinkBase& objSink,
|
||||
TOutputGLSL(TInfoSinkBase &objSink,
|
||||
ShArrayIndexClampingStrategy clampingStrategy,
|
||||
ShHashFunction64 hashFunction,
|
||||
NameMap& nameMap,
|
||||
TSymbolTable& symbolTable,
|
||||
NameMap &nameMap,
|
||||
TSymbolTable &symbolTable,
|
||||
sh::GLenum shaderType,
|
||||
int shaderVersion,
|
||||
ShShaderOutput output,
|
||||
ShCompileOptions compileOptions);
|
||||
|
|
|
@ -85,6 +85,7 @@ TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink,
|
|||
ShHashFunction64 hashFunction,
|
||||
NameMap &nameMap,
|
||||
TSymbolTable &symbolTable,
|
||||
sh::GLenum shaderType,
|
||||
int shaderVersion,
|
||||
ShShaderOutput output,
|
||||
ShCompileOptions compileOptions)
|
||||
|
@ -95,6 +96,7 @@ TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink,
|
|||
mHashFunction(hashFunction),
|
||||
mNameMap(nameMap),
|
||||
mSymbolTable(symbolTable),
|
||||
mShaderType(shaderType),
|
||||
mShaderVersion(shaderVersion),
|
||||
mOutput(output),
|
||||
mCompileOptions(compileOptions)
|
||||
|
@ -103,11 +105,7 @@ 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)
|
||||
if (!sh::RemoveInvariant(mShaderType, mShaderVersion, mOutput, mCompileOptions))
|
||||
{
|
||||
TInfoSinkBase &out = objSink();
|
||||
out << "invariant ";
|
||||
|
@ -165,7 +163,7 @@ void TOutputGLSLBase::writeLayoutQualifier(const TType &type)
|
|||
const char *TOutputGLSLBase::mapQualifierToString(TQualifier qualifier)
|
||||
{
|
||||
if (sh::IsGLSL410OrOlder(mOutput) && mShaderVersion >= 300 &&
|
||||
!!(mCompileOptions & SH_REMOVE_CENTROID_FOR_ESSL3))
|
||||
(mCompileOptions & SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3) != 0)
|
||||
{
|
||||
switch (qualifier)
|
||||
{
|
||||
|
@ -960,8 +958,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
|
|||
ASSERT(sequence && sequence->size() == 1);
|
||||
const TIntermSymbol *symbol = sequence->front()->getAsSymbolNode();
|
||||
ASSERT(symbol);
|
||||
writeInvariantQualifier(symbol->getType());
|
||||
out << hashVariableName(symbol->getName());
|
||||
out << "invariant " << hashVariableName(symbol->getName());
|
||||
}
|
||||
visitChildren = false;
|
||||
break;
|
||||
|
|
|
@ -23,7 +23,8 @@ class TOutputGLSLBase : public TIntermTraverser
|
|||
ShArrayIndexClampingStrategy clampingStrategy,
|
||||
ShHashFunction64 hashFunction,
|
||||
NameMap &nameMap,
|
||||
TSymbolTable& symbolTable,
|
||||
TSymbolTable &symbolTable,
|
||||
sh::GLenum shaderType,
|
||||
int shaderVersion,
|
||||
ShShaderOutput output,
|
||||
ShCompileOptions compileOptions);
|
||||
|
@ -102,6 +103,8 @@ class TOutputGLSLBase : public TIntermTraverser
|
|||
|
||||
TSymbolTable &mSymbolTable;
|
||||
|
||||
sh::GLenum mShaderType;
|
||||
|
||||
const int mShaderVersion;
|
||||
|
||||
ShShaderOutput mOutput;
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace
|
|||
{
|
||||
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
|
@ -26,17 +26,10 @@ class RemoveInvariantDeclarationTraverser : public TIntermTraverser
|
|||
{
|
||||
if (node->getOp() == EOpInvariantDeclaration)
|
||||
{
|
||||
for (TIntermNode *&child : *node->getSequence())
|
||||
{
|
||||
TIntermTyped *typed = child->getAsTyped();
|
||||
if (typed && typed->getQualifier() == EvqVaryingIn)
|
||||
{
|
||||
TIntermSequence emptyReplacement;
|
||||
mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(
|
||||
getParentNode()->getAsBlock(), node, emptyReplacement));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
TIntermSequence emptyReplacement;
|
||||
mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(),
|
||||
node, emptyReplacement));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -81,7 +81,8 @@ void TranslatorESSL::translate(TIntermNode *root, ShCompileOptions compileOption
|
|||
|
||||
// Write translated shader.
|
||||
TOutputESSL outputESSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(),
|
||||
getSymbolTable(), shaderVer, precisionEmulation, compileOptions);
|
||||
getSymbolTable(), getShaderType(), shaderVer, precisionEmulation,
|
||||
compileOptions);
|
||||
root->traverse(&outputESSL);
|
||||
}
|
||||
|
||||
|
|
|
@ -188,13 +188,8 @@ void TranslatorGLSL::translate(TIntermNode *root, ShCompileOptions compileOption
|
|||
}
|
||||
|
||||
// Write translated shader.
|
||||
TOutputGLSL outputGLSL(sink,
|
||||
getArrayIndexClampingStrategy(),
|
||||
getHashFunction(),
|
||||
getNameMap(),
|
||||
getSymbolTable(),
|
||||
getShaderVersion(),
|
||||
getOutputType(),
|
||||
TOutputGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(),
|
||||
getSymbolTable(), getShaderType(), getShaderVersion(), getOutputType(),
|
||||
compileOptions);
|
||||
root->traverse(&outputGLSL);
|
||||
}
|
||||
|
|
|
@ -80,6 +80,11 @@ ShCompileOptions ShaderGL::prepareSourceAndReturnOptions(std::stringstream *sour
|
|||
options |= SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT;
|
||||
}
|
||||
|
||||
if (mWorkarounds.removeInvariantAndCentroidForESSL3)
|
||||
{
|
||||
options |= SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3;
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,8 @@ struct WorkaroundsGL
|
|||
addAndTrueToLoopCondition(false),
|
||||
emulateIsnanFloat(false),
|
||||
useUnusedBlocksWithStandardOrSharedLayout(false),
|
||||
dontRemoveInvariantForFragmentInput(false)
|
||||
dontRemoveInvariantForFragmentInput(false),
|
||||
removeInvariantAndCentroidForESSL3(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -116,6 +117,9 @@ struct WorkaroundsGL
|
|||
// This flag will keep invariant declaration for input in fragment shader for GLSL >=4.20
|
||||
// on AMD.
|
||||
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
|
|||
workarounds->unpackLastRowSeparatelyForPaddingInclusion = IsNvidia(vendor);
|
||||
workarounds->packLastRowSeparatelyForPaddingInclusion = IsNvidia(vendor);
|
||||
#endif
|
||||
|
||||
workarounds->removeInvariantAndCentroidForESSL3 = functions->isAtMostGL(gl::Version(4, 1));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче