diff options
Diffstat (limited to 'gfx/angle/src/compiler/translator/InitializeVariables.cpp')
-rwxr-xr-x | gfx/angle/src/compiler/translator/InitializeVariables.cpp | 183 |
1 files changed, 126 insertions, 57 deletions
diff --git a/gfx/angle/src/compiler/translator/InitializeVariables.cpp b/gfx/angle/src/compiler/translator/InitializeVariables.cpp index dafea1bd6..21f00936e 100755 --- a/gfx/angle/src/compiler/translator/InitializeVariables.cpp +++ b/gfx/angle/src/compiler/translator/InitializeVariables.cpp @@ -9,122 +9,191 @@ #include "angle_gl.h" #include "common/debug.h" #include "compiler/translator/IntermNode.h" -#include "compiler/translator/SymbolTable.h" #include "compiler/translator/util.h" -namespace sh +namespace { -namespace +TIntermConstantUnion *constructConstUnionNode(const TType &type) +{ + TType myType = type; + 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; +} + +TIntermConstantUnion *constructIndexNode(int index) { + TConstantUnion *u = new TConstantUnion[1]; + u[0].setIConst(index); + + TType type(EbtInt, EbpUndefined, EvqConst, 1); + TIntermConstantUnion *node = new TIntermConstantUnion(u, type); + return node; +} class VariableInitializer : public TIntermTraverser { public: - VariableInitializer(const InitVariableList &vars, const TSymbolTable &symbolTable) - : TIntermTraverser(true, false, false), - mVariables(vars), - mSymbolTable(symbolTable), - mCodeInserted(false) + VariableInitializer(const InitVariableList &vars) + : TIntermTraverser(true, false, false), mVariables(vars), mCodeInserted(false) { - ASSERT(mSymbolTable.atGlobalLevel()); } protected: bool visitBinary(Visit, TIntermBinary *node) override { return false; } bool visitUnary(Visit, TIntermUnary *node) override { return false; } - bool visitIfElse(Visit, TIntermIfElse *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, TIntermAggregate *node) override { return false; } - bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override; + bool visitAggregate(Visit visit, TIntermAggregate *node) override; private: void insertInitCode(TIntermSequence *sequence); const InitVariableList &mVariables; - const TSymbolTable &mSymbolTable; bool mCodeInserted; }; // VariableInitializer implementation. -bool VariableInitializer::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) +bool VariableInitializer::visitAggregate(Visit visit, TIntermAggregate *node) { - // Function definition. - ASSERT(visit == PreVisit); - if (node->getFunctionSymbolInfo()->isMain()) + bool visitChildren = !mCodeInserted; + switch (node->getOp()) { - TIntermBlock *body = node->getBody(); - insertInitCode(body->getSequence()); - mCodeInserted = true; + case EOpSequence: + break; + case EOpFunction: + { + // Function definition. + ASSERT(visit == PreVisit); + if (node->getName() == "main(") + { + TIntermSequence *sequence = node->getSequence(); + ASSERT((sequence->size() == 1) || (sequence->size() == 2)); + TIntermAggregate *body = NULL; + if (sequence->size() == 1) + { + body = new TIntermAggregate(EOpSequence); + sequence->push_back(body); + } + else + { + body = (*sequence)[1]->getAsAggregate(); + } + ASSERT(body); + insertInitCode(body->getSequence()); + mCodeInserted = true; + } + break; + } + default: + visitChildren = false; + break; } - return false; + return visitChildren; } void VariableInitializer::insertInitCode(TIntermSequence *sequence) { - for (const auto &var : mVariables) + for (size_t ii = 0; ii < mVariables.size(); ++ii) { + const sh::ShaderVariable &var = mVariables[ii]; TString name = TString(var.name.c_str()); - if (var.isArray()) { - // Assign the array elements one by one to keep the AST compatible with ESSL 1.00 which - // doesn't have array assignment. + TType type = sh::ConvertShaderVariableTypeToTType(var.type); size_t pos = name.find_last_of('['); if (pos != TString::npos) - { name = name.substr(0, pos); - } - TType elementType = sh::GetShaderVariableBasicType(var); - TType arrayType = elementType; - arrayType.setArraySize(var.elementCount()); - - for (unsigned int i = 0; i < var.arraySize; ++i) + for (int index = static_cast<int>(var.arraySize) - 1; index >= 0; --index) { - TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, arrayType); - TIntermBinary *element = new TIntermBinary(EOpIndexDirect, arraySymbol, - TIntermTyped::CreateIndexNode(i)); + TIntermBinary *assign = new TIntermBinary(EOpAssign); + sequence->insert(sequence->begin(), assign); + + TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect); + TIntermSymbol *symbol = new TIntermSymbol(0, name, type); + indexDirect->setLeft(symbol); + TIntermConstantUnion *indexNode = constructIndexNode(index); + indexDirect->setRight(indexNode); - TIntermTyped *zero = TIntermTyped::CreateZero(elementType); - TIntermBinary *assignment = new TIntermBinary(EOpAssign, element, zero); + assign->setLeft(indexDirect); - sequence->insert(sequence->begin(), assignment); + TIntermConstantUnion *zeroConst = constructConstUnionNode(type); + assign->setRight(zeroConst); } } else if (var.isStruct()) { - TVariable *structInfo = reinterpret_cast<TVariable *>(mSymbolTable.findGlobal(name)); - ASSERT(structInfo); - - TIntermSymbol *symbol = new TIntermSymbol(0, name, structInfo->getType()); - TIntermTyped *zero = TIntermTyped::CreateZero(structInfo->getType()); - - TIntermBinary *assign = new TIntermBinary(EOpAssign, symbol, zero); - sequence->insert(sequence->begin(), assign); + 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 fieldIndex = 0; fieldIndex < static_cast<int>(var.fields.size()); ++fieldIndex) + { + 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(fieldIndex); + indexDirectStruct->setRight(indexNode); + assign->setLeft(indexDirectStruct); + + const sh::ShaderVariable &field = var.fields[fieldIndex]; + TType fieldType = sh::ConvertShaderVariableTypeToTType(field.type); + TIntermConstantUnion *zeroConst = constructConstUnionNode(fieldType); + assign->setRight(zeroConst); + } } else { - TType type = sh::GetShaderVariableBasicType(var); - TIntermSymbol *symbol = new TIntermSymbol(0, name, type); - TIntermTyped *zero = TIntermTyped::CreateZero(type); - - TIntermBinary *assign = new TIntermBinary(EOpAssign, symbol, zero); + TType type = sh::ConvertShaderVariableTypeToTType(var.type); + TIntermBinary *assign = new TIntermBinary(EOpAssign); sequence->insert(sequence->begin(), assign); + TIntermSymbol *symbol = new TIntermSymbol(0, name, type); + assign->setLeft(symbol); + TIntermConstantUnion *zeroConst = constructConstUnionNode(type); + assign->setRight(zeroConst); } + } } } // namespace anonymous -void InitializeVariables(TIntermNode *root, - const InitVariableList &vars, - const TSymbolTable &symbolTable) +void InitializeVariables(TIntermNode *root, const InitVariableList &vars) { - VariableInitializer initializer(vars, symbolTable); + VariableInitializer initializer(vars); root->traverse(&initializer); } - -} // namespace sh |