Commit 19515019 by Olli Etuaho Committed by Commit Bot

Refactor CollectVariables

New helper functions are added for collecting built-in variables, and the traverser is encapsulated inside VariableInfo.cpp. The helper functions get data for built-in variables from the symbol table, so a duplicate copy of the data doesn't need to be maintained in CollectVariables any more. BUG=angleproject:2068 TEST=angle_unittests Change-Id: I42595d0da0e5d4fb634a3d92f38db1dd6dd9efab Reviewed-on: https://chromium-review.googlesource.com/549323Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 0dc97810
...@@ -433,14 +433,24 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[], ...@@ -433,14 +433,24 @@ TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
if (success && shouldCollectVariables(compileOptions)) if (success && shouldCollectVariables(compileOptions))
{ {
collectVariables(root); ASSERT(!variablesCollected);
CollectVariables(root, &attributes, &outputVariables, &uniforms, &varyings,
&interfaceBlocks, hashFunction, symbolTable, shaderVersion,
extensionBehavior);
variablesCollected = true;
if (compileOptions & SH_USE_UNUSED_STANDARD_SHARED_BLOCKS) if (compileOptions & SH_USE_UNUSED_STANDARD_SHARED_BLOCKS)
{ {
useAllMembersInUnusedStandardAndSharedBlocks(root); useAllMembersInUnusedStandardAndSharedBlocks(root);
} }
if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS)
{ {
success = enforcePackingRestrictions(); std::vector<sh::ShaderVariable> expandedUniforms;
sh::ExpandUniforms(uniforms, &expandedUniforms);
VariablePacker packer;
// Returns true if, after applying the packing rules in the GLSL ES 1.00.17 spec
// Appendix A, section 7, the shader does not use too many uniforms.
success =
packer.CheckVariablesWithinPackingLimits(maxUniformVectors, expandedUniforms);
if (!success) if (!success)
{ {
mDiagnostics.globalError("too many uniforms"); mDiagnostics.globalError("too many uniforms");
...@@ -689,7 +699,6 @@ void TCompiler::clearResults() ...@@ -689,7 +699,6 @@ void TCompiler::clearResults()
attributes.clear(); attributes.clear();
outputVariables.clear(); outputVariables.clear();
uniforms.clear(); uniforms.clear();
expandedUniforms.clear();
varyings.clear(); varyings.clear();
interfaceBlocks.clear(); interfaceBlocks.clear();
variablesCollected = false; variablesCollected = false;
...@@ -887,21 +896,6 @@ bool TCompiler::limitExpressionComplexity(TIntermBlock *root) ...@@ -887,21 +896,6 @@ bool TCompiler::limitExpressionComplexity(TIntermBlock *root)
return true; return true;
} }
void TCompiler::collectVariables(TIntermNode *root)
{
if (!variablesCollected)
{
sh::CollectVariables collect(&attributes, &outputVariables, &uniforms, &varyings,
&interfaceBlocks, hashFunction, symbolTable,
extensionBehavior);
root->traverse(&collect);
// This is for enforcePackingRestriction().
sh::ExpandUniforms(uniforms, &expandedUniforms);
variablesCollected = true;
}
}
bool TCompiler::shouldCollectVariables(ShCompileOptions compileOptions) bool TCompiler::shouldCollectVariables(ShCompileOptions compileOptions)
{ {
return (compileOptions & SH_VARIABLES) != 0; return (compileOptions & SH_VARIABLES) != 0;
...@@ -912,12 +906,6 @@ bool TCompiler::wereVariablesCollected() const ...@@ -912,12 +906,6 @@ bool TCompiler::wereVariablesCollected() const
return variablesCollected; return variablesCollected;
} }
bool TCompiler::enforcePackingRestrictions()
{
VariablePacker packer;
return packer.CheckVariablesWithinPackingLimits(maxUniformVectors, expandedUniforms);
}
void TCompiler::initializeGLPosition(TIntermBlock *root) void TCompiler::initializeGLPosition(TIntermBlock *root)
{ {
InitVariableList list; InitVariableList list;
......
...@@ -138,9 +138,6 @@ class TCompiler : public TShHandleBase ...@@ -138,9 +138,6 @@ class TCompiler : public TShHandleBase
ShCompileOptions compileOptions){}; ShCompileOptions compileOptions){};
// Translate to object code. // Translate to object code.
virtual void translate(TIntermBlock *root, ShCompileOptions compileOptions) = 0; virtual void translate(TIntermBlock *root, ShCompileOptions compileOptions) = 0;
// Returns true if, after applying the packing rules in the GLSL 1.017 spec
// Appendix A, section 7, the shader does not use too many uniforms.
bool enforcePackingRestrictions();
// Insert statements to reference all members in unused uniform blocks with standard and shared // Insert statements to reference all members in unused uniform blocks with standard and shared
// layout. This is to work around a Mac driver that treats unused standard/shared // layout. This is to work around a Mac driver that treats unused standard/shared
// uniform blocks as inactive. // uniform blocks as inactive.
...@@ -176,7 +173,6 @@ class TCompiler : public TShHandleBase ...@@ -176,7 +173,6 @@ class TCompiler : public TShHandleBase
std::vector<sh::Attribute> attributes; std::vector<sh::Attribute> attributes;
std::vector<sh::OutputVariable> outputVariables; std::vector<sh::OutputVariable> outputVariables;
std::vector<sh::Uniform> uniforms; std::vector<sh::Uniform> uniforms;
std::vector<sh::ShaderVariable> expandedUniforms;
std::vector<sh::Varying> varyings; std::vector<sh::Varying> varyings;
std::vector<sh::InterfaceBlock> interfaceBlocks; std::vector<sh::InterfaceBlock> interfaceBlocks;
...@@ -189,9 +185,6 @@ class TCompiler : public TShHandleBase ...@@ -189,9 +185,6 @@ class TCompiler : public TShHandleBase
void initSamplerDefaultPrecision(TBasicType samplerType); void initSamplerDefaultPrecision(TBasicType samplerType);
// Collect info for all attribs, uniforms, varyings.
void collectVariables(TIntermNode *root);
bool variablesCollected; bool variablesCollected;
// Removes unused function declarations and prototypes from the AST // Removes unused function declarations and prototypes from the AST
......
...@@ -4,11 +4,13 @@ ...@@ -4,11 +4,13 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
#include "compiler/translator/VariableInfo.h"
#include "angle_gl.h" #include "angle_gl.h"
#include "common/utilities.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/SymbolTable.h" #include "compiler/translator/SymbolTable.h"
#include "compiler/translator/VariableInfo.h"
#include "compiler/translator/util.h" #include "compiler/translator/util.h"
#include "common/utilities.h"
namespace sh namespace sh
{ {
...@@ -62,16 +64,85 @@ VarT *FindVariable(const TString &name, std::vector<VarT> *infoList) ...@@ -62,16 +64,85 @@ VarT *FindVariable(const TString &name, std::vector<VarT> *infoList)
return nullptr; return nullptr;
} }
}
CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs, // Traverses the intermediate tree to collect all attributes, uniforms, varyings, fragment outputs,
std::vector<sh::OutputVariable> *outputVariables, // and interface blocks.
std::vector<sh::Uniform> *uniforms, class CollectVariablesTraverser : public TIntermTraverser
std::vector<sh::Varying> *varyings, {
std::vector<sh::InterfaceBlock> *interfaceBlocks, public:
ShHashFunction64 hashFunction, CollectVariablesTraverser(std::vector<Attribute> *attribs,
const TSymbolTable &symbolTable, std::vector<OutputVariable> *outputVariables,
const TExtensionBehavior &extensionBehavior) std::vector<Uniform> *uniforms,
std::vector<Varying> *varyings,
std::vector<InterfaceBlock> *interfaceBlocks,
ShHashFunction64 hashFunction,
const TSymbolTable &symbolTable,
int shaderVersion,
const TExtensionBehavior &extensionBehavior);
void visitSymbol(TIntermSymbol *symbol) override;
bool visitDeclaration(Visit, TIntermDeclaration *node) override;
bool visitBinary(Visit visit, TIntermBinary *binaryNode) override;
private:
void setCommonVariableProperties(const TType &type,
const TString &name,
ShaderVariable *variableOut) const;
Attribute recordAttribute(const TIntermSymbol &variable) const;
OutputVariable recordOutputVariable(const TIntermSymbol &variable) const;
Varying recordVarying(const TIntermSymbol &variable) const;
InterfaceBlock recordInterfaceBlock(const TIntermSymbol &variable) const;
Uniform recordUniform(const TIntermSymbol &variable) const;
void setBuiltInInfoFromSymbolTable(const char *name, ShaderVariable *info);
void recordBuiltInVaryingUsed(const char *name, bool *addedFlag);
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<InterfaceBlock> *mInterfaceBlocks;
std::map<std::string, InterfaceBlockField *> mInterfaceBlockFields;
bool mDepthRangeAdded;
bool mPointCoordAdded;
bool mFrontFacingAdded;
bool mFragCoordAdded;
bool mInstanceIDAdded;
bool mVertexIDAdded;
bool mPositionAdded;
bool mPointSizeAdded;
bool mLastFragDataAdded;
bool mFragColorAdded;
bool mFragDataAdded;
bool mFragDepthEXTAdded;
bool mFragDepthAdded;
bool mSecondaryFragColorEXTAdded;
bool mSecondaryFragDataEXTAdded;
ShHashFunction64 mHashFunction;
const TSymbolTable &mSymbolTable;
int mShaderVersion;
const TExtensionBehavior &mExtensionBehavior;
};
CollectVariablesTraverser::CollectVariablesTraverser(
std::vector<sh::Attribute> *attribs,
std::vector<sh::OutputVariable> *outputVariables,
std::vector<sh::Uniform> *uniforms,
std::vector<sh::Varying> *varyings,
std::vector<sh::InterfaceBlock> *interfaceBlocks,
ShHashFunction64 hashFunction,
const TSymbolTable &symbolTable,
int shaderVersion,
const TExtensionBehavior &extensionBehavior)
: TIntermTraverser(true, false, false), : TIntermTraverser(true, false, false),
mAttribs(attribs), mAttribs(attribs),
mOutputVariables(outputVariables), mOutputVariables(outputVariables),
...@@ -95,16 +166,70 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs, ...@@ -95,16 +166,70 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
mSecondaryFragDataEXTAdded(false), mSecondaryFragDataEXTAdded(false),
mHashFunction(hashFunction), mHashFunction(hashFunction),
mSymbolTable(symbolTable), mSymbolTable(symbolTable),
mShaderVersion(shaderVersion),
mExtensionBehavior(extensionBehavior) mExtensionBehavior(extensionBehavior)
{ {
} }
void CollectVariablesTraverser::setBuiltInInfoFromSymbolTable(const char *name,
ShaderVariable *info)
{
TVariable *symbolTableVar =
reinterpret_cast<TVariable *>(mSymbolTable.findBuiltIn(name, mShaderVersion));
ASSERT(symbolTableVar);
const TType &type = symbolTableVar->getType();
info->name = name;
info->mappedName = name;
info->type = GLVariableType(type);
info->arraySize = type.isArray() ? type.getArraySize() : 0;
info->precision = GLVariablePrecision(type);
}
void CollectVariablesTraverser::recordBuiltInVaryingUsed(const char *name, bool *addedFlag)
{
if (!(*addedFlag))
{
Varying info;
setBuiltInInfoFromSymbolTable(name, &info);
info.staticUse = true;
info.isInvariant = mSymbolTable.isVaryingInvariant(name);
mVaryings->push_back(info);
(*addedFlag) = true;
}
}
void CollectVariablesTraverser::recordBuiltInFragmentOutputUsed(const char *name, bool *addedFlag)
{
if (!(*addedFlag))
{
OutputVariable info;
setBuiltInInfoFromSymbolTable(name, &info);
info.staticUse = true;
mOutputVariables->push_back(info);
(*addedFlag) = true;
}
}
void CollectVariablesTraverser::recordBuiltInAttributeUsed(const char *name, bool *addedFlag)
{
if (!(*addedFlag))
{
Attribute info;
setBuiltInInfoFromSymbolTable(name, &info);
info.staticUse = true;
info.location = -1;
mAttribs->push_back(info);
(*addedFlag) = true;
}
}
// We want to check whether a uniform/varying is statically used // We want to check whether a uniform/varying is statically used
// because we only count the used ones in packing computing. // because we only count the used ones in packing computing.
// Also, gl_FragCoord, gl_PointCoord, and gl_FrontFacing count // Also, gl_FragCoord, gl_PointCoord, and gl_FrontFacing count
// toward varying counting if they are statically used in a fragment // toward varying counting if they are statically used in a fragment
// shader. // shader.
void CollectVariables::visitSymbol(TIntermSymbol *symbol) void CollectVariablesTraverser::visitSymbol(TIntermSymbol *symbol)
{ {
ASSERT(symbol != nullptr); ASSERT(symbol != nullptr);
ShaderVariable *var = nullptr; ShaderVariable *var = nullptr;
...@@ -202,241 +327,59 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol) ...@@ -202,241 +327,59 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
} }
break; break;
case EvqFragCoord: case EvqFragCoord:
if (!mFragCoordAdded) recordBuiltInVaryingUsed("gl_FragCoord", &mFragCoordAdded);
{
Varying info;
const char kName[] = "gl_FragCoord";
info.name = kName;
info.mappedName = kName;
info.type = GL_FLOAT_VEC4;
info.arraySize = 0;
info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
info.staticUse = true;
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
mVaryings->push_back(info);
mFragCoordAdded = true;
}
return; return;
case EvqFrontFacing: case EvqFrontFacing:
if (!mFrontFacingAdded) recordBuiltInVaryingUsed("gl_FrontFacing", &mFrontFacingAdded);
{
Varying info;
const char kName[] = "gl_FrontFacing";
info.name = kName;
info.mappedName = kName;
info.type = GL_BOOL;
info.arraySize = 0;
info.precision = GL_NONE;
info.staticUse = true;
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
mVaryings->push_back(info);
mFrontFacingAdded = true;
}
return; return;
case EvqPointCoord: case EvqPointCoord:
if (!mPointCoordAdded) recordBuiltInVaryingUsed("gl_PointCoord", &mPointCoordAdded);
{
Varying info;
const char kName[] = "gl_PointCoord";
info.name = kName;
info.mappedName = kName;
info.type = GL_FLOAT_VEC2;
info.arraySize = 0;
info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
info.staticUse = true;
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
mVaryings->push_back(info);
mPointCoordAdded = true;
}
return; return;
case EvqInstanceID: case EvqInstanceID:
if (!mInstanceIDAdded) recordBuiltInAttributeUsed("gl_InstanceID", &mInstanceIDAdded);
{
Attribute info;
const char kName[] = "gl_InstanceID";
info.name = kName;
info.mappedName = kName;
info.type = GL_INT;
info.arraySize = 0;
info.precision = GL_HIGH_INT; // Defined by spec.
info.staticUse = true;
info.location = -1;
mAttribs->push_back(info);
mInstanceIDAdded = true;
}
return; return;
case EvqVertexID: case EvqVertexID:
if (!mVertexIDAdded) recordBuiltInAttributeUsed("gl_VertexID", &mVertexIDAdded);
{
Attribute info;
const char kName[] = "gl_VertexID";
info.name = kName;
info.mappedName = kName;
info.type = GL_INT;
info.arraySize = 0;
info.precision = GL_HIGH_INT; // Defined by spec.
info.staticUse = true;
info.location = -1;
mAttribs->push_back(info);
mVertexIDAdded = true;
}
return; return;
case EvqPosition: case EvqPosition:
if (!mPositionAdded) recordBuiltInVaryingUsed("gl_Position", &mPositionAdded);
{
Varying info;
const char kName[] = "gl_Position";
info.name = kName;
info.mappedName = kName;
info.type = GL_FLOAT_VEC4;
info.arraySize = 0;
info.precision = GL_HIGH_FLOAT; // Defined by spec.
info.staticUse = true;
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
mVaryings->push_back(info);
mPositionAdded = true;
}
return; return;
case EvqPointSize: case EvqPointSize:
if (!mPointSizeAdded) recordBuiltInVaryingUsed("gl_PointSize", &mPointSizeAdded);
{
Varying info;
const char kName[] = "gl_PointSize";
info.name = kName;
info.mappedName = kName;
info.type = GL_FLOAT;
info.arraySize = 0;
info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
info.staticUse = true;
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
mVaryings->push_back(info);
mPointSizeAdded = true;
}
return; return;
case EvqLastFragData: case EvqLastFragData:
if (!mLastFragDataAdded) recordBuiltInVaryingUsed("gl_LastFragData", &mLastFragDataAdded);
{
Varying info;
const char kName[] = "gl_LastFragData";
info.name = kName;
info.mappedName = kName;
info.type = GL_FLOAT_VEC4;
info.arraySize = static_cast<const TVariable *>(
mSymbolTable.findBuiltIn("gl_MaxDrawBuffers", 100))
->getConstPointer()
->getIConst();
info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
info.staticUse = true;
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
mVaryings->push_back(info);
mLastFragDataAdded = true;
}
return; return;
case EvqFragColor: case EvqFragColor:
if (!mFragColorAdded) recordBuiltInFragmentOutputUsed("gl_FragColor", &mFragColorAdded);
{
OutputVariable info;
const char kName[] = "gl_FragColor";
info.name = kName;
info.mappedName = kName;
info.type = GL_FLOAT_VEC4;
info.arraySize = 0;
info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
info.staticUse = true;
mOutputVariables->push_back(info);
mFragColorAdded = true;
}
return; return;
case EvqFragData: case EvqFragData:
if (!mFragDataAdded) if (!mFragDataAdded)
{ {
OutputVariable info; OutputVariable info;
const char kName[] = "gl_FragData"; setBuiltInInfoFromSymbolTable("gl_FragData", &info);
info.name = kName; if (!::IsExtensionEnabled(mExtensionBehavior, "GL_EXT_draw_buffers"))
info.mappedName = kName;
info.type = GL_FLOAT_VEC4;
if (::IsExtensionEnabled(mExtensionBehavior, "GL_EXT_draw_buffers"))
{
info.arraySize = static_cast<const TVariable *>(
mSymbolTable.findBuiltIn("gl_MaxDrawBuffers", 100))
->getConstPointer()
->getIConst();
}
else
{ {
info.arraySize = 1; info.arraySize = 1;
} }
info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
info.staticUse = true; info.staticUse = true;
mOutputVariables->push_back(info); mOutputVariables->push_back(info);
mFragDataAdded = true; mFragDataAdded = true;
} }
return; return;
case EvqFragDepthEXT: case EvqFragDepthEXT:
if (!mFragDepthEXTAdded) recordBuiltInFragmentOutputUsed("gl_FragDepthEXT", &mFragDepthEXTAdded);
{
OutputVariable info;
const char kName[] = "gl_FragDepthEXT";
info.name = kName;
info.mappedName = kName;
info.type = GL_FLOAT;
info.arraySize = 0;
info.precision =
GLVariablePrecision(static_cast<const TVariable *>(
mSymbolTable.findBuiltIn("gl_FragDepthEXT", 100))
->getType());
info.staticUse = true;
mOutputVariables->push_back(info);
mFragDepthEXTAdded = true;
}
return; return;
case EvqFragDepth: case EvqFragDepth:
if (!mFragDepthAdded) recordBuiltInFragmentOutputUsed("gl_FragDepth", &mFragDepthAdded);
{
OutputVariable info;
const char kName[] = "gl_FragDepth";
info.name = kName;
info.mappedName = kName;
info.type = GL_FLOAT;
info.arraySize = 0;
info.precision = GL_HIGH_FLOAT;
info.staticUse = true;
mOutputVariables->push_back(info);
mFragDepthAdded = true;
}
return; return;
case EvqSecondaryFragColorEXT: case EvqSecondaryFragColorEXT:
if (!mSecondaryFragColorEXTAdded) recordBuiltInFragmentOutputUsed("gl_SecondaryFragColorEXT",
{ &mSecondaryFragColorEXTAdded);
OutputVariable info;
const char kName[] = "gl_SecondaryFragColorEXT";
info.name = kName;
info.mappedName = kName;
info.type = GL_FLOAT_VEC4;
info.arraySize = 0;
info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
info.staticUse = true;
mOutputVariables->push_back(info);
mSecondaryFragColorEXTAdded = true;
}
return; return;
case EvqSecondaryFragDataEXT: case EvqSecondaryFragDataEXT:
if (!mSecondaryFragDataEXTAdded) recordBuiltInFragmentOutputUsed("gl_SecondaryFragDataEXT",
{ &mSecondaryFragDataEXTAdded);
OutputVariable info;
const char kName[] = "gl_SecondaryFragDataEXT";
info.name = kName;
info.mappedName = kName;
info.type = GL_FLOAT_VEC4;
const TVariable *maxDualSourceDrawBuffersVar = static_cast<const TVariable *>(
mSymbolTable.findBuiltIn("gl_MaxDualSourceDrawBuffersEXT", 100));
info.arraySize = maxDualSourceDrawBuffersVar->getConstPointer()->getIConst();
info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
info.staticUse = true;
mOutputVariables->push_back(info);
mSecondaryFragDataEXTAdded = true;
}
return; return;
default: default:
break; break;
...@@ -448,9 +391,9 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol) ...@@ -448,9 +391,9 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
} }
} }
void CollectVariables::setCommonVariableProperties(const TType &type, void CollectVariablesTraverser::setCommonVariableProperties(const TType &type,
const TString &name, const TString &name,
ShaderVariable *variableOut) const ShaderVariable *variableOut) const
{ {
ASSERT(variableOut); ASSERT(variableOut);
...@@ -483,7 +426,7 @@ void CollectVariables::setCommonVariableProperties(const TType &type, ...@@ -483,7 +426,7 @@ void CollectVariables::setCommonVariableProperties(const TType &type,
variableOut->arraySize = type.getArraySize(); variableOut->arraySize = type.getArraySize();
} }
Attribute CollectVariables::recordAttribute(const TIntermSymbol &variable) const Attribute CollectVariablesTraverser::recordAttribute(const TIntermSymbol &variable) const
{ {
const TType &type = variable.getType(); const TType &type = variable.getType();
ASSERT(!type.getStruct()); ASSERT(!type.getStruct());
...@@ -495,7 +438,7 @@ Attribute CollectVariables::recordAttribute(const TIntermSymbol &variable) const ...@@ -495,7 +438,7 @@ Attribute CollectVariables::recordAttribute(const TIntermSymbol &variable) const
return attribute; return attribute;
} }
OutputVariable CollectVariables::recordOutputVariable(const TIntermSymbol &variable) const OutputVariable CollectVariablesTraverser::recordOutputVariable(const TIntermSymbol &variable) const
{ {
const TType &type = variable.getType(); const TType &type = variable.getType();
ASSERT(!type.getStruct()); ASSERT(!type.getStruct());
...@@ -507,7 +450,7 @@ OutputVariable CollectVariables::recordOutputVariable(const TIntermSymbol &varia ...@@ -507,7 +450,7 @@ OutputVariable CollectVariables::recordOutputVariable(const TIntermSymbol &varia
return outputVariable; return outputVariable;
} }
Varying CollectVariables::recordVarying(const TIntermSymbol &variable) const Varying CollectVariablesTraverser::recordVarying(const TIntermSymbol &variable) const
{ {
const TType &type = variable.getType(); const TType &type = variable.getType();
...@@ -536,7 +479,7 @@ Varying CollectVariables::recordVarying(const TIntermSymbol &variable) const ...@@ -536,7 +479,7 @@ Varying CollectVariables::recordVarying(const TIntermSymbol &variable) const
return varying; return varying;
} }
InterfaceBlock CollectVariables::recordInterfaceBlock(const TIntermSymbol &variable) const InterfaceBlock CollectVariablesTraverser::recordInterfaceBlock(const TIntermSymbol &variable) const
{ {
const TInterfaceBlock *blockType = variable.getType().getInterfaceBlock(); const TInterfaceBlock *blockType = variable.getType().getInterfaceBlock();
ASSERT(blockType); ASSERT(blockType);
...@@ -566,7 +509,7 @@ InterfaceBlock CollectVariables::recordInterfaceBlock(const TIntermSymbol &varia ...@@ -566,7 +509,7 @@ InterfaceBlock CollectVariables::recordInterfaceBlock(const TIntermSymbol &varia
return interfaceBlock; return interfaceBlock;
} }
Uniform CollectVariables::recordUniform(const TIntermSymbol &variable) const Uniform CollectVariablesTraverser::recordUniform(const TIntermSymbol &variable) const
{ {
Uniform uniform; Uniform uniform;
setCommonVariableProperties(variable.getType(), variable.getSymbol(), &uniform); setCommonVariableProperties(variable.getType(), variable.getSymbol(), &uniform);
...@@ -576,7 +519,7 @@ Uniform CollectVariables::recordUniform(const TIntermSymbol &variable) const ...@@ -576,7 +519,7 @@ Uniform CollectVariables::recordUniform(const TIntermSymbol &variable) const
return uniform; return uniform;
} }
bool CollectVariables::visitDeclaration(Visit, TIntermDeclaration *node) bool CollectVariablesTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
{ {
const TIntermSequence &sequence = *(node->getSequence()); const TIntermSequence &sequence = *(node->getSequence());
ASSERT(!sequence.empty()); ASSERT(!sequence.empty());
...@@ -630,7 +573,7 @@ bool CollectVariables::visitDeclaration(Visit, TIntermDeclaration *node) ...@@ -630,7 +573,7 @@ bool CollectVariables::visitDeclaration(Visit, TIntermDeclaration *node)
return false; return false;
} }
bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode) bool CollectVariablesTraverser::visitBinary(Visit, TIntermBinary *binaryNode)
{ {
if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock) if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock)
{ {
...@@ -655,6 +598,25 @@ bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode) ...@@ -655,6 +598,25 @@ bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode)
return true; return true;
} }
} // anonymous namespace
void CollectVariables(TIntermBlock *root,
std::vector<Attribute> *attributes,
std::vector<OutputVariable> *outputVariables,
std::vector<Uniform> *uniforms,
std::vector<Varying> *varyings,
std::vector<InterfaceBlock> *interfaceBlocks,
ShHashFunction64 hashFunction,
const TSymbolTable &symbolTable,
int shaderVersion,
const TExtensionBehavior &extensionBehavior)
{
CollectVariablesTraverser collect(attributes, outputVariables, uniforms, varyings,
interfaceBlocks, hashFunction, symbolTable, shaderVersion,
extensionBehavior);
root->traverse(&collect);
}
void ExpandVariable(const ShaderVariable &variable, void ExpandVariable(const ShaderVariable &variable,
const std::string &name, const std::string &name,
const std::string &mappedName, const std::string &mappedName,
...@@ -703,10 +665,10 @@ void ExpandVariable(const ShaderVariable &variable, ...@@ -703,10 +665,10 @@ void ExpandVariable(const ShaderVariable &variable,
void ExpandUniforms(const std::vector<Uniform> &compact, std::vector<ShaderVariable> *expanded) void ExpandUniforms(const std::vector<Uniform> &compact, std::vector<ShaderVariable> *expanded)
{ {
for (size_t variableIndex = 0; variableIndex < compact.size(); variableIndex++) for (const Uniform &variable : compact)
{ {
const ShaderVariable &variable = compact[variableIndex];
ExpandVariable(variable, variable.name, variable.mappedName, variable.staticUse, expanded); ExpandVariable(variable, variable.name, variable.mappedName, variable.staticUse, expanded);
} }
} }
}
} // namespace sh
...@@ -10,71 +10,23 @@ ...@@ -10,71 +10,23 @@
#include <GLSLANG/ShaderLang.h> #include <GLSLANG/ShaderLang.h>
#include "compiler/translator/ExtensionBehavior.h" #include "compiler/translator/ExtensionBehavior.h"
#include "compiler/translator/IntermNode.h"
class TSymbolTable;
namespace sh namespace sh
{ {
// Traverses intermediate tree to collect all attributes, uniforms, varyings. class TIntermBlock;
class CollectVariables : public TIntermTraverser class TSymbolTable;
{
public:
CollectVariables(std::vector<Attribute> *attribs,
std::vector<OutputVariable> *outputVariables,
std::vector<Uniform> *uniforms,
std::vector<Varying> *varyings,
std::vector<InterfaceBlock> *interfaceBlocks,
ShHashFunction64 hashFunction,
const TSymbolTable &symbolTable,
const TExtensionBehavior &extensionBehavior);
void visitSymbol(TIntermSymbol *symbol) override;
bool visitDeclaration(Visit, TIntermDeclaration *node) override;
bool visitBinary(Visit visit, TIntermBinary *binaryNode) override;
private:
void setCommonVariableProperties(const TType &type,
const TString &name,
ShaderVariable *variableOut) const;
Attribute recordAttribute(const TIntermSymbol &variable) const;
OutputVariable recordOutputVariable(const TIntermSymbol &variable) const;
Varying recordVarying(const TIntermSymbol &variable) const;
InterfaceBlock recordInterfaceBlock(const TIntermSymbol &variable) const;
Uniform recordUniform(const TIntermSymbol &variable) const;
std::vector<Attribute> *mAttribs;
std::vector<OutputVariable> *mOutputVariables;
std::vector<Uniform> *mUniforms;
std::vector<Varying> *mVaryings;
std::vector<InterfaceBlock> *mInterfaceBlocks;
std::map<std::string, InterfaceBlockField *> mInterfaceBlockFields;
bool mDepthRangeAdded;
bool mPointCoordAdded;
bool mFrontFacingAdded;
bool mFragCoordAdded;
bool mInstanceIDAdded;
bool mVertexIDAdded;
bool mPositionAdded;
bool mPointSizeAdded;
bool mLastFragDataAdded;
bool mFragColorAdded;
bool mFragDataAdded;
bool mFragDepthEXTAdded;
bool mFragDepthAdded;
bool mSecondaryFragColorEXTAdded;
bool mSecondaryFragDataEXTAdded;
ShHashFunction64 mHashFunction;
const TSymbolTable &mSymbolTable; void CollectVariables(TIntermBlock *root,
const TExtensionBehavior &mExtensionBehavior; std::vector<Attribute> *attributes,
}; std::vector<OutputVariable> *outputVariables,
std::vector<Uniform> *uniforms,
std::vector<Varying> *varyings,
std::vector<InterfaceBlock> *interfaceBlocks,
ShHashFunction64 hashFunction,
const TSymbolTable &symbolTable,
int shaderVersion,
const TExtensionBehavior &extensionBehavior);
void ExpandVariable(const ShaderVariable &variable, void ExpandVariable(const ShaderVariable &variable,
const std::string &name, const std::string &name,
......
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