Commit d842a6b2 by Qiankun Miao Committed by Commit Bot

Remove invariant qualifier for input in fragment shader

ESSL and GLSL are not consistent on invariant matching in vertex shader and fragment shader. See the following rules: ESSL 1.00 - input and output must match ESSL 3.00 - only output, inputs cannot be declared as invariant. GLSL 1.10.59 - does not exist GLSL 1.20.8 - input and output must match GLSL 1.30.10 - input and output must match GLSL 1.40.8 - input and output must match GLSL 1.50.11 - input and output must match GLSL 3.30.6 - input and output must match GLSL 4.00.9 - input and output must match GLSL 4.10.6 - input and output must match GLSL 4.20.11 - input can omit invariant GLSL 4.30.8 - input can omit invariant GLSL 4.40.9 - input can omit invariant GLSL 4.50.5 - input can omit invariant Since GLSL 4.20, invariant qualifier description were changed to: " Only variables output from a shader (including those that are then input to a subsequent shader) can be candidates for invariance. This includes user-defined output variables and the built-in output variables. As only outputs need be declared with invariant, an output from one shader stage will still match an input of a subsequent stage without the input being declared as invariant. " It's not very clear if input in fragment can be declared as invariant. Mesa driver disallows use of input declared as invariant in fragment shader, while other drivers may allow it. In ESSL 3.00, inputs cannot be declared as invariant. ANGLE should follow this rule for GLSL >= 4.20. BUG=chromium:639760 Change-Id: I7f7a07401381ac970488b69752f6d50d4f19d31f Reviewed-on: https://chromium-review.googlesource.com/400005Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
parent 4c5ff005
......@@ -92,6 +92,8 @@
'compiler/translator/RecordConstantPrecision.h',
'compiler/translator/RegenerateStructNames.cpp',
'compiler/translator/RegenerateStructNames.h',
'compiler/translator/RemoveInvariantDeclaration.cpp',
'compiler/translator/RemoveInvariantDeclaration.h',
'compiler/translator/RemovePow.cpp',
'compiler/translator/RemovePow.h',
'compiler/translator/RewriteDoWhile.cpp',
......
......@@ -23,6 +23,7 @@
#include "compiler/translator/ParseContext.h"
#include "compiler/translator/PruneEmptyDeclarations.h"
#include "compiler/translator/RegenerateStructNames.h"
#include "compiler/translator/RemoveInvariantDeclaration.h"
#include "compiler/translator/RemovePow.h"
#include "compiler/translator/RewriteDoWhile.h"
#include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h"
......@@ -91,6 +92,14 @@ bool IsGLSL130OrNewer(ShShaderOutput output)
output == SH_GLSL_450_CORE_OUTPUT);
}
bool IsGLSL420OrNewer(ShShaderOutput output)
{
return (output == SH_GLSL_420_CORE_OUTPUT ||
output == SH_GLSL_430_CORE_OUTPUT ||
output == SH_GLSL_440_CORE_OUTPUT ||
output == SH_GLSL_450_CORE_OUTPUT);
}
size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
{
// WebGL defines a max token legnth of 256, while ES2 leaves max token
......@@ -382,6 +391,9 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
(outputType == SH_GLSL_COMPATIBILITY_OUTPUT)))
initializeGLPosition(root);
if (success && shaderType == GL_FRAGMENT_SHADER && IsGLSL420OrNewer(outputType))
sh::RemoveInvariantDeclaration(root);
// This pass might emit short circuits so keep it before the short circuit unfolding
if (success && (compileOptions & SH_REWRITE_DO_WHILE_LOOPS))
RewriteDoWhile(root, getTemporaryIndex());
......
......@@ -38,6 +38,7 @@ bool IsWebGLBasedSpec(ShShaderSpec spec);
// Helper function to check if the shader type is GLSL.
//
bool IsGLSL130OrNewer(ShShaderOutput output);
bool IsGLSL420OrNewer(ShShaderOutput output);
//
// The base class used to back handles returned to the driver.
......
......@@ -146,8 +146,9 @@ void TOutputGLSLBase::writeLayoutQualifier(const TType &type)
void TOutputGLSLBase::writeVariableType(const TType &type)
{
TQualifier qualifier = type.getQualifier();
TInfoSinkBase &out = objSink();
if (type.isInvariant())
if (type.isInvariant() && qualifier != EvqFragmentIn && !IsGLSL420OrNewer(mOutput))
{
out << "invariant ";
}
......@@ -156,7 +157,6 @@ void TOutputGLSLBase::writeVariableType(const TType &type)
TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
declareInterfaceBlockLayout(interfaceBlock);
}
TQualifier qualifier = type.getQualifier();
if (qualifier != EvqTemporary && qualifier != EvqGlobal)
{
if (IsGLSL130OrNewer(mOutput))
......
//
// Copyright (c) 2016 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.
//
#include "compiler/translator/RemoveInvariantDeclaration.h"
#include "compiler/translator/IntermNode.h"
namespace sh
{
namespace
{
// An AST traverser that removes invariant declaration for input in fragment shader
// when GLSL > 4.20.
class RemoveInvariantDeclarationTraverser : public TIntermTraverser
{
public:
RemoveInvariantDeclarationTraverser() : TIntermTraverser(true, false, false) {}
private:
bool visitAggregate(Visit visit, TIntermAggregate *node) override
{
if (node->getOp() == EOpInvariantDeclaration)
{
TIntermSequence emptyReplacement;
mMultiReplacements.push_back(
NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(), node, emptyReplacement));
return false;
}
return true;
}
};
} // anonymous namespace
void RemoveInvariantDeclaration(TIntermNode *root)
{
RemoveInvariantDeclarationTraverser traverser;
root->traverse(&traverser);
traverser.updateTree();
}
} // namespace sh
//
// Copyright (c) 2016 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.
//
#ifndef COMPILER_TRANSLATOR_REMOVEINVARIANTDECLARATION_H_
#define COMPILER_TRANSLATOR_REMOVEINVARIANTDECLARATION_H_
class TIntermNode;
namespace sh
{
void RemoveInvariantDeclaration(TIntermNode *root);
} // namespace sh
#endif // COMPILER_TRANSLATOR_REMOVEINVARIANTDECLARATION_H_
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