Split varyings into input and output varyings in compiler
This patch intends to split all vector<Varying> into two vectors
to store input and output varyings separately in the compiler.
This patch is a base of implementing the built-ins, inputs and
outputs of a geometry shader to ANGLE GLSL compiler. Unlike the
vertex shaders (their outputs are varyings) and fragment shaders
(their inputs are varyings), the inputs and outputs of geometry
shaders are all varyings, so we need two vector<Varying> to store
them correctly.
BUG=angleproject:1941
Change-Id: I9e8cc16045d5e29e9a80a09dc31b33a7ae39b345
Reviewed-on: https://chromium-review.googlesource.com/593347
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index cf0483d..d3c858b 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -473,9 +473,9 @@
if (success && shouldCollectVariables(compileOptions))
{
ASSERT(!variablesCollected);
- CollectVariables(root, &attributes, &outputVariables, &uniforms, &varyings,
- &interfaceBlocks, hashFunction, &symbolTable, shaderVersion,
- extensionBehavior);
+ CollectVariables(root, &attributes, &outputVariables, &uniforms, &inputVaryings,
+ &outputVaryings, &interfaceBlocks, hashFunction, &symbolTable,
+ shaderVersion, extensionBehavior);
variablesCollected = true;
if (compileOptions & SH_USE_UNUSED_STANDARD_SHARED_BLOCKS)
{
@@ -760,7 +760,8 @@
attributes.clear();
outputVariables.clear();
uniforms.clear();
- varyings.clear();
+ inputVaryings.clear();
+ outputVaryings.clear();
interfaceBlocks.clear();
variablesCollected = false;
mGLPositionInitialized = false;
@@ -999,7 +1000,7 @@
InitVariableList list;
if (shaderType == GL_VERTEX_SHADER)
{
- for (auto var : varyings)
+ for (auto var : outputVaryings)
{
list.push_back(var);
if (var.name == "gl_Position")
@@ -1063,9 +1064,16 @@
bool TCompiler::isVaryingDefined(const char *varyingName)
{
ASSERT(variablesCollected);
- for (size_t ii = 0; ii < varyings.size(); ++ii)
+ for (size_t ii = 0; ii < inputVaryings.size(); ++ii)
{
- if (varyings[ii].name == varyingName)
+ if (inputVaryings[ii].name == varyingName)
+ {
+ return true;
+ }
+ }
+ for (size_t ii = 0; ii < outputVaryings.size(); ++ii)
+ {
+ if (outputVaryings[ii].name == varyingName)
{
return true;
}
diff --git a/src/compiler/translator/Compiler.h b/src/compiler/translator/Compiler.h
index 36d4921..2b2796c 100644
--- a/src/compiler/translator/Compiler.h
+++ b/src/compiler/translator/Compiler.h
@@ -110,7 +110,8 @@
const std::vector<sh::Attribute> &getAttributes() const { return attributes; }
const std::vector<sh::OutputVariable> &getOutputVariables() const { return outputVariables; }
const std::vector<sh::Uniform> &getUniforms() const { return uniforms; }
- const std::vector<sh::Varying> &getVaryings() const { return varyings; }
+ const std::vector<sh::Varying> &getInputVaryings() const { return inputVaryings; }
+ const std::vector<sh::Varying> &getOutputVaryings() const { return outputVaryings; }
const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return interfaceBlocks; }
ShHashFunction64 getHashFunction() const { return hashFunction; }
@@ -184,7 +185,8 @@
std::vector<sh::Attribute> attributes;
std::vector<sh::OutputVariable> outputVariables;
std::vector<sh::Uniform> uniforms;
- std::vector<sh::Varying> varyings;
+ std::vector<sh::Varying> inputVaryings;
+ std::vector<sh::Varying> outputVaryings;
std::vector<sh::InterfaceBlock> interfaceBlocks;
private:
diff --git a/src/compiler/translator/ShaderLang.cpp b/src/compiler/translator/ShaderLang.cpp
index 2d6d0d4..04d7b81 100644
--- a/src/compiler/translator/ShaderLang.cpp
+++ b/src/compiler/translator/ShaderLang.cpp
@@ -45,7 +45,20 @@
template <>
const std::vector<Varying> *GetVariableList(const TCompiler *compiler)
{
- return &compiler->getVaryings();
+ switch (compiler->getShaderType())
+ {
+ case GL_VERTEX_SHADER:
+ return &compiler->getOutputVaryings();
+ case GL_FRAGMENT_SHADER:
+ return &compiler->getInputVaryings();
+ case GL_COMPUTE_SHADER:
+ ASSERT(compiler->getOutputVaryings().empty() && compiler->getInputVaryings().empty());
+ return &compiler->getOutputVaryings();
+ // Since geometry shaders have both input and output varyings, we shouldn't call GetVaryings
+ // on a geometry shader.
+ default:
+ return nullptr;
+ }
}
template <>
@@ -66,8 +79,7 @@
return &compiler->getInterfaceBlocks();
}
-template <typename VarT>
-const std::vector<VarT> *GetShaderVariables(const ShHandle handle)
+TCompiler *GetCompilerFromHandle(ShHandle handle)
{
if (!handle)
{
@@ -75,7 +87,13 @@
}
TShHandleBase *base = static_cast<TShHandleBase *>(handle);
- TCompiler *compiler = base->getAsCompiler();
+ return base->getAsCompiler();
+}
+
+template <typename VarT>
+const std::vector<VarT> *GetShaderVariables(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
if (!compiler)
{
return nullptr;
@@ -84,14 +102,6 @@
return GetVariableList<VarT>(compiler);
}
-TCompiler *GetCompilerFromHandle(ShHandle handle)
-{
- if (!handle)
- return nullptr;
- TShHandleBase *base = static_cast<TShHandleBase *>(handle);
- return base->getAsCompiler();
-}
-
#ifdef ANGLE_ENABLE_HLSL
TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle)
{
@@ -355,6 +365,26 @@
return GetShaderVariables<Uniform>(handle);
}
+const std::vector<sh::Varying> *GetInputVaryings(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (compiler == nullptr)
+ {
+ return nullptr;
+ }
+ return &compiler->getInputVaryings();
+}
+
+const std::vector<sh::Varying> *GetOutputVaryings(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (compiler == nullptr)
+ {
+ return nullptr;
+ }
+ return &compiler->getOutputVaryings();
+}
+
const std::vector<Varying> *GetVaryings(const ShHandle handle)
{
return GetShaderVariables<Varying>(handle);
diff --git a/src/compiler/translator/VariableInfo.cpp b/src/compiler/translator/VariableInfo.cpp
index 18178d7..06e9d0b 100644
--- a/src/compiler/translator/VariableInfo.cpp
+++ b/src/compiler/translator/VariableInfo.cpp
@@ -92,7 +92,8 @@
CollectVariablesTraverser(std::vector<Attribute> *attribs,
std::vector<OutputVariable> *outputVariables,
std::vector<Uniform> *uniforms,
- std::vector<Varying> *varyings,
+ std::vector<Varying> *inputVaryings,
+ std::vector<Varying> *outputVaryings,
std::vector<InterfaceBlock> *interfaceBlocks,
ShHashFunction64 hashFunction,
TSymbolTable *symbolTable,
@@ -116,14 +117,17 @@
void setBuiltInInfoFromSymbolTable(const char *name, ShaderVariable *info);
- void recordBuiltInVaryingUsed(const char *name, bool *addedFlag);
+ void recordBuiltInVaryingUsed(const char *name,
+ bool *addedFlag,
+ std::vector<Varying> *varyings);
void recordBuiltInFragmentOutputUsed(const char *name, bool *addedFlag);
void recordBuiltInAttributeUsed(const char *name, bool *addedFlag);
std::vector<Attribute> *mAttribs;
std::vector<OutputVariable> *mOutputVariables;
std::vector<Uniform> *mUniforms;
- std::vector<Varying> *mVaryings;
+ std::vector<Varying> *mInputVaryings;
+ std::vector<Varying> *mOutputVaryings;
std::vector<InterfaceBlock> *mInterfaceBlocks;
std::map<std::string, InterfaceBlockField *> mInterfaceBlockFields;
@@ -155,7 +159,8 @@
std::vector<sh::Attribute> *attribs,
std::vector<sh::OutputVariable> *outputVariables,
std::vector<sh::Uniform> *uniforms,
- std::vector<sh::Varying> *varyings,
+ std::vector<sh::Varying> *inputVaryings,
+ std::vector<sh::Varying> *outputVaryings,
std::vector<sh::InterfaceBlock> *interfaceBlocks,
ShHashFunction64 hashFunction,
TSymbolTable *symbolTable,
@@ -165,7 +170,8 @@
mAttribs(attribs),
mOutputVariables(outputVariables),
mUniforms(uniforms),
- mVaryings(varyings),
+ mInputVaryings(inputVaryings),
+ mOutputVaryings(outputVaryings),
mInterfaceBlocks(interfaceBlocks),
mDepthRangeAdded(false),
mPointCoordAdded(false),
@@ -203,15 +209,18 @@
info->precision = GLVariablePrecision(type);
}
-void CollectVariablesTraverser::recordBuiltInVaryingUsed(const char *name, bool *addedFlag)
+void CollectVariablesTraverser::recordBuiltInVaryingUsed(const char *name,
+ bool *addedFlag,
+ std::vector<Varying> *varyings)
{
+ ASSERT(varyings);
if (!(*addedFlag))
{
Varying info;
setBuiltInInfoFromSymbolTable(name, &info);
info.staticUse = true;
info.isInvariant = mSymbolTable->isVaryingInvariant(name);
- mVaryings->push_back(info);
+ varyings->push_back(info);
(*addedFlag) = true;
}
}
@@ -259,9 +268,13 @@
ShaderVariable *var = nullptr;
const TString &symbolName = symbol->getName().getString();
- if (IsVarying(symbol->getQualifier()))
+ if (IsVaryingIn(symbol->getQualifier()))
{
- var = FindVariable(symbolName, mVaryings);
+ var = FindVariable(symbolName, mInputVaryings);
+ }
+ else if (IsVaryingOut(symbol->getQualifier()))
+ {
+ var = FindVariable(symbolName, mOutputVaryings);
}
else if (symbol->getType().getBasicType() == EbtInterfaceBlock)
{
@@ -351,13 +364,13 @@
}
break;
case EvqFragCoord:
- recordBuiltInVaryingUsed("gl_FragCoord", &mFragCoordAdded);
+ recordBuiltInVaryingUsed("gl_FragCoord", &mFragCoordAdded, mInputVaryings);
return;
case EvqFrontFacing:
- recordBuiltInVaryingUsed("gl_FrontFacing", &mFrontFacingAdded);
+ recordBuiltInVaryingUsed("gl_FrontFacing", &mFrontFacingAdded, mInputVaryings);
return;
case EvqPointCoord:
- recordBuiltInVaryingUsed("gl_PointCoord", &mPointCoordAdded);
+ recordBuiltInVaryingUsed("gl_PointCoord", &mPointCoordAdded, mInputVaryings);
return;
case EvqInstanceID:
// Whenever the SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW option is set,
@@ -384,13 +397,13 @@
recordBuiltInAttributeUsed("gl_VertexID", &mVertexIDAdded);
return;
case EvqPosition:
- recordBuiltInVaryingUsed("gl_Position", &mPositionAdded);
+ recordBuiltInVaryingUsed("gl_Position", &mPositionAdded, mOutputVaryings);
return;
case EvqPointSize:
- recordBuiltInVaryingUsed("gl_PointSize", &mPointSizeAdded);
+ recordBuiltInVaryingUsed("gl_PointSize", &mPointSizeAdded, mOutputVaryings);
return;
case EvqLastFragData:
- recordBuiltInVaryingUsed("gl_LastFragData", &mLastFragDataAdded);
+ recordBuiltInVaryingUsed("gl_LastFragData", &mLastFragDataAdded, mInputVaryings);
return;
case EvqFragColor:
recordBuiltInFragmentOutputUsed("gl_FragColor", &mFragColorAdded);
@@ -615,7 +628,15 @@
mUniforms->push_back(recordUniform(variable));
break;
default:
- mVaryings->push_back(recordVarying(variable));
+ if (IsVaryingIn(qualifier))
+ {
+ mInputVaryings->push_back(recordVarying(variable));
+ }
+ else
+ {
+ ASSERT(IsVaryingOut(qualifier));
+ mOutputVaryings->push_back(recordVarying(variable));
+ }
break;
}
}
@@ -660,16 +681,17 @@
std::vector<Attribute> *attributes,
std::vector<OutputVariable> *outputVariables,
std::vector<Uniform> *uniforms,
- std::vector<Varying> *varyings,
+ std::vector<Varying> *inputVaryings,
+ std::vector<Varying> *outputVaryings,
std::vector<InterfaceBlock> *interfaceBlocks,
ShHashFunction64 hashFunction,
TSymbolTable *symbolTable,
int shaderVersion,
const TExtensionBehavior &extensionBehavior)
{
- CollectVariablesTraverser collect(attributes, outputVariables, uniforms, varyings,
- interfaceBlocks, hashFunction, symbolTable, shaderVersion,
- extensionBehavior);
+ CollectVariablesTraverser collect(attributes, outputVariables, uniforms, inputVaryings,
+ outputVaryings, interfaceBlocks, hashFunction, symbolTable,
+ shaderVersion, extensionBehavior);
root->traverse(&collect);
}
diff --git a/src/compiler/translator/VariableInfo.h b/src/compiler/translator/VariableInfo.h
index 96d0b3b..b14de8e 100644
--- a/src/compiler/translator/VariableInfo.h
+++ b/src/compiler/translator/VariableInfo.h
@@ -21,7 +21,8 @@
std::vector<Attribute> *attributes,
std::vector<OutputVariable> *outputVariables,
std::vector<Uniform> *uniforms,
- std::vector<Varying> *varyings,
+ std::vector<Varying> *inputVaryings,
+ std::vector<Varying> *outputVaryings,
std::vector<InterfaceBlock> *interfaceBlocks,
ShHashFunction64 hashFunction,
TSymbolTable *symbolTable,