Initialize all output variables.
BUG=angleproject:1441
TEST=bots
Change-Id: Ia4cf415d8346c3234bf0f548a178ee3ea8cd35c4
Reviewed-on: https://chromium-review.googlesource.com/362110
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Commit-Queue: Zhenyao Mo <zmo@chromium.org>
diff --git a/src/compiler/translator/InitializeVariables.cpp b/src/compiler/translator/InitializeVariables.cpp
index 86d3e6b..482260a 100644
--- a/src/compiler/translator/InitializeVariables.cpp
+++ b/src/compiler/translator/InitializeVariables.cpp
@@ -6,23 +6,40 @@
#include "compiler/translator/InitializeVariables.h"
+#include "angle_gl.h"
#include "common/debug.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/util.h"
namespace
{
-TIntermConstantUnion *constructFloatConstUnionNode(const TType &type)
+TIntermConstantUnion *constructConstUnionNode(const TType &type)
{
TType myType = type;
- unsigned char size = static_cast<unsigned char>(myType.getNominalSize());
- if (myType.isMatrix())
- size *= size;
- TConstantUnion *u = new TConstantUnion[size];
- for (int ii = 0; ii < size; ++ii)
- u[ii].setFConst(0.0f);
-
myType.clearArrayness();
myType.setQualifier(EvqConst);
+ size_t size = myType.getObjectSize();
+ TConstantUnion *u = new TConstantUnion[size];
+ for (size_t ii = 0; ii < size; ++ii)
+ {
+ switch (type.getBasicType())
+ {
+ case EbtFloat:
+ u[ii].setFConst(0.0f);
+ break;
+ case EbtInt:
+ u[ii].setIConst(0);
+ break;
+ case EbtUInt:
+ u[ii].setUConst(0u);
+ break;
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ }
+
TIntermConstantUnion *node = new TIntermConstantUnion(u, myType);
return node;
}
@@ -37,9 +54,33 @@
return node;
}
-} // namespace anonymous
+class VariableInitializer : public TIntermTraverser
+{
+ public:
+ VariableInitializer(const InitVariableList &vars)
+ : TIntermTraverser(true, false, false), mVariables(vars), mCodeInserted(false)
+ {
+ }
-bool InitializeVariables::visitAggregate(Visit visit, TIntermAggregate *node)
+ protected:
+ bool visitBinary(Visit, TIntermBinary *node) override { return false; }
+ bool visitUnary(Visit, TIntermUnary *node) override { return false; }
+ bool visitSelection(Visit, TIntermSelection *node) override { return false; }
+ bool visitLoop(Visit, TIntermLoop *node) override { return false; }
+ bool visitBranch(Visit, TIntermBranch *node) override { return false; }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+
+ private:
+ void insertInitCode(TIntermSequence *sequence);
+
+ const InitVariableList &mVariables;
+ bool mCodeInserted;
+};
+
+// VariableInitializer implementation.
+
+bool VariableInitializer::visitAggregate(Visit visit, TIntermAggregate *node)
{
bool visitChildren = !mCodeInserted;
switch (node->getOp())
@@ -77,28 +118,33 @@
return visitChildren;
}
-void InitializeVariables::insertInitCode(TIntermSequence *sequence)
+void VariableInitializer::insertInitCode(TIntermSequence *sequence)
{
for (size_t ii = 0; ii < mVariables.size(); ++ii)
{
- const InitVariableInfo &varInfo = mVariables[ii];
-
- if (varInfo.type.isArray())
+ const sh::ShaderVariable &var = mVariables[ii];
+ ASSERT(!var.isStruct());
+ TType type = sh::ConvertShaderVariableTypeToTType(var.type);
+ TString name = TString(var.name.c_str());
+ if (var.isArray())
{
- for (int index = varInfo.type.getArraySize() - 1; index >= 0; --index)
+ size_t pos = name.find_last_of('[');
+ if (pos != TString::npos)
+ name = name.substr(0, pos);
+ for (int index = static_cast<int>(var.arraySize) - 1; index >= 0; --index)
{
TIntermBinary *assign = new TIntermBinary(EOpAssign);
sequence->insert(sequence->begin(), assign);
TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect);
- TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type);
+ TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
indexDirect->setLeft(symbol);
TIntermConstantUnion *indexNode = constructIndexNode(index);
indexDirect->setRight(indexNode);
assign->setLeft(indexDirect);
- TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type);
+ TIntermConstantUnion *zeroConst = constructConstUnionNode(type);
assign->setRight(zeroConst);
}
}
@@ -106,12 +152,19 @@
{
TIntermBinary *assign = new TIntermBinary(EOpAssign);
sequence->insert(sequence->begin(), assign);
- TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type);
+ TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
assign->setLeft(symbol);
- TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type);
+ TIntermConstantUnion *zeroConst = constructConstUnionNode(type);
assign->setRight(zeroConst);
}
}
}
+} // namespace anonymous
+
+void InitializeVariables(TIntermNode *root, const InitVariableList &vars)
+{
+ VariableInitializer initializer(vars);
+ root->traverse(&initializer);
+}