Handle initializing of struct typed output variable correctly.
BUG=angleproject:1441
TEST=webgl2 conformance
Change-Id: Idb27036347e1e814ba4603969cc2065e425ac4aa
Reviewed-on: https://chromium-review.googlesource.com/362641
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Commit-Queue: Zhenyao Mo <zmo@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/InitializeVariables.cpp b/src/compiler/translator/InitializeVariables.cpp
index 482260a..a10beb7 100644
--- a/src/compiler/translator/InitializeVariables.cpp
+++ b/src/compiler/translator/InitializeVariables.cpp
@@ -123,11 +123,10 @@
for (size_t ii = 0; ii < mVariables.size(); ++ii)
{
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())
{
+ TType type = sh::ConvertShaderVariableTypeToTType(var.type);
size_t pos = name.find_last_of('[');
if (pos != TString::npos)
name = name.substr(0, pos);
@@ -148,8 +147,38 @@
assign->setRight(zeroConst);
}
}
+ else if (var.isStruct())
+ {
+ TFieldList *fields = new TFieldList;
+ TSourceLoc loc;
+ for (auto field : var.fields)
+ {
+ fields->push_back(new TField(nullptr, new TString(field.name.c_str()), loc));
+ }
+ TStructure *structure = new TStructure(new TString(var.structName.c_str()), fields);
+ TType type;
+ type.setStruct(structure);
+ for (int ii = 0; ii < static_cast<int>(var.fields.size()); ++ii)
+ {
+ TIntermBinary *assign = new TIntermBinary(EOpAssign);
+ sequence->insert(sequence->begin(), assign);
+
+ TIntermBinary *indexDirectStruct = new TIntermBinary(EOpIndexDirectStruct);
+ TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
+ indexDirectStruct->setLeft(symbol);
+ TIntermConstantUnion *indexNode = constructIndexNode(ii);
+ indexDirectStruct->setRight(indexNode);
+ assign->setLeft(indexDirectStruct);
+
+ const sh::ShaderVariable &field = var.fields[ii];
+ TType fieldType = sh::ConvertShaderVariableTypeToTType(field.type);
+ TIntermConstantUnion *zeroConst = constructConstUnionNode(fieldType);
+ assign->setRight(zeroConst);
+ }
+ }
else
{
+ TType type = sh::ConvertShaderVariableTypeToTType(var.type);
TIntermBinary *assign = new TIntermBinary(EOpAssign);
sequence->insert(sequence->begin(), assign);
TIntermSymbol *symbol = new TIntermSymbol(0, name, type);