Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 1 | // |
| 2 | // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. |
| 3 | // Use of this source code is governed by a BSD-style license that can be |
| 4 | // found in the LICENSE file. |
| 5 | // |
| 6 | |
| 7 | #include "compiler/translator/InitializeVariables.h" |
Olli Etuaho | d57e0db | 2015-04-24 15:05:08 +0300 | [diff] [blame] | 8 | |
Zhenyao Mo | 7211191 | 2016-07-20 17:45:56 -0700 | [diff] [blame^] | 9 | #include "angle_gl.h" |
Olli Etuaho | d57e0db | 2015-04-24 15:05:08 +0300 | [diff] [blame] | 10 | #include "common/debug.h" |
Zhenyao Mo | 7211191 | 2016-07-20 17:45:56 -0700 | [diff] [blame^] | 11 | #include "compiler/translator/IntermNode.h" |
| 12 | #include "compiler/translator/util.h" |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 13 | |
| 14 | namespace |
| 15 | { |
| 16 | |
Zhenyao Mo | 7211191 | 2016-07-20 17:45:56 -0700 | [diff] [blame^] | 17 | TIntermConstantUnion *constructConstUnionNode(const TType &type) |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 18 | { |
| 19 | TType myType = type; |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 20 | myType.clearArrayness(); |
| 21 | myType.setQualifier(EvqConst); |
Zhenyao Mo | 7211191 | 2016-07-20 17:45:56 -0700 | [diff] [blame^] | 22 | size_t size = myType.getObjectSize(); |
| 23 | TConstantUnion *u = new TConstantUnion[size]; |
| 24 | for (size_t ii = 0; ii < size; ++ii) |
| 25 | { |
| 26 | switch (type.getBasicType()) |
| 27 | { |
| 28 | case EbtFloat: |
| 29 | u[ii].setFConst(0.0f); |
| 30 | break; |
| 31 | case EbtInt: |
| 32 | u[ii].setIConst(0); |
| 33 | break; |
| 34 | case EbtUInt: |
| 35 | u[ii].setUConst(0u); |
| 36 | break; |
| 37 | default: |
| 38 | UNREACHABLE(); |
| 39 | return nullptr; |
| 40 | } |
| 41 | } |
| 42 | |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 43 | TIntermConstantUnion *node = new TIntermConstantUnion(u, myType); |
| 44 | return node; |
| 45 | } |
| 46 | |
Zhenyao Mo | e40d1e9 | 2014-07-16 17:40:36 -0700 | [diff] [blame] | 47 | TIntermConstantUnion *constructIndexNode(int index) |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 48 | { |
Jamie Madill | 6ba6ead | 2015-05-04 14:21:21 -0400 | [diff] [blame] | 49 | TConstantUnion *u = new TConstantUnion[1]; |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 50 | u[0].setIConst(index); |
| 51 | |
| 52 | TType type(EbtInt, EbpUndefined, EvqConst, 1); |
| 53 | TIntermConstantUnion *node = new TIntermConstantUnion(u, type); |
| 54 | return node; |
| 55 | } |
| 56 | |
Zhenyao Mo | 7211191 | 2016-07-20 17:45:56 -0700 | [diff] [blame^] | 57 | class VariableInitializer : public TIntermTraverser |
| 58 | { |
| 59 | public: |
| 60 | VariableInitializer(const InitVariableList &vars) |
| 61 | : TIntermTraverser(true, false, false), mVariables(vars), mCodeInserted(false) |
| 62 | { |
| 63 | } |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 64 | |
Zhenyao Mo | 7211191 | 2016-07-20 17:45:56 -0700 | [diff] [blame^] | 65 | protected: |
| 66 | bool visitBinary(Visit, TIntermBinary *node) override { return false; } |
| 67 | bool visitUnary(Visit, TIntermUnary *node) override { return false; } |
| 68 | bool visitSelection(Visit, TIntermSelection *node) override { return false; } |
| 69 | bool visitLoop(Visit, TIntermLoop *node) override { return false; } |
| 70 | bool visitBranch(Visit, TIntermBranch *node) override { return false; } |
| 71 | |
| 72 | bool visitAggregate(Visit visit, TIntermAggregate *node) override; |
| 73 | |
| 74 | private: |
| 75 | void insertInitCode(TIntermSequence *sequence); |
| 76 | |
| 77 | const InitVariableList &mVariables; |
| 78 | bool mCodeInserted; |
| 79 | }; |
| 80 | |
| 81 | // VariableInitializer implementation. |
| 82 | |
| 83 | bool VariableInitializer::visitAggregate(Visit visit, TIntermAggregate *node) |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 84 | { |
| 85 | bool visitChildren = !mCodeInserted; |
| 86 | switch (node->getOp()) |
| 87 | { |
| 88 | case EOpSequence: |
| 89 | break; |
| 90 | case EOpFunction: |
| 91 | { |
| 92 | // Function definition. |
| 93 | ASSERT(visit == PreVisit); |
| 94 | if (node->getName() == "main(") |
| 95 | { |
Zhenyao Mo | e40d1e9 | 2014-07-16 17:40:36 -0700 | [diff] [blame] | 96 | TIntermSequence *sequence = node->getSequence(); |
| 97 | ASSERT((sequence->size() == 1) || (sequence->size() == 2)); |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 98 | TIntermAggregate *body = NULL; |
Zhenyao Mo | e40d1e9 | 2014-07-16 17:40:36 -0700 | [diff] [blame] | 99 | if (sequence->size() == 1) |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 100 | { |
| 101 | body = new TIntermAggregate(EOpSequence); |
Zhenyao Mo | e40d1e9 | 2014-07-16 17:40:36 -0700 | [diff] [blame] | 102 | sequence->push_back(body); |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 103 | } |
| 104 | else |
| 105 | { |
Zhenyao Mo | e40d1e9 | 2014-07-16 17:40:36 -0700 | [diff] [blame] | 106 | body = (*sequence)[1]->getAsAggregate(); |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 107 | } |
| 108 | ASSERT(body); |
| 109 | insertInitCode(body->getSequence()); |
| 110 | mCodeInserted = true; |
| 111 | } |
| 112 | break; |
| 113 | } |
| 114 | default: |
| 115 | visitChildren = false; |
| 116 | break; |
| 117 | } |
| 118 | return visitChildren; |
| 119 | } |
| 120 | |
Zhenyao Mo | 7211191 | 2016-07-20 17:45:56 -0700 | [diff] [blame^] | 121 | void VariableInitializer::insertInitCode(TIntermSequence *sequence) |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 122 | { |
| 123 | for (size_t ii = 0; ii < mVariables.size(); ++ii) |
| 124 | { |
Zhenyao Mo | 7211191 | 2016-07-20 17:45:56 -0700 | [diff] [blame^] | 125 | const sh::ShaderVariable &var = mVariables[ii]; |
| 126 | ASSERT(!var.isStruct()); |
| 127 | TType type = sh::ConvertShaderVariableTypeToTType(var.type); |
| 128 | TString name = TString(var.name.c_str()); |
| 129 | if (var.isArray()) |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 130 | { |
Zhenyao Mo | 7211191 | 2016-07-20 17:45:56 -0700 | [diff] [blame^] | 131 | size_t pos = name.find_last_of('['); |
| 132 | if (pos != TString::npos) |
| 133 | name = name.substr(0, pos); |
| 134 | for (int index = static_cast<int>(var.arraySize) - 1; index >= 0; --index) |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 135 | { |
| 136 | TIntermBinary *assign = new TIntermBinary(EOpAssign); |
Zhenyao Mo | e40d1e9 | 2014-07-16 17:40:36 -0700 | [diff] [blame] | 137 | sequence->insert(sequence->begin(), assign); |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 138 | |
| 139 | TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect); |
Zhenyao Mo | 7211191 | 2016-07-20 17:45:56 -0700 | [diff] [blame^] | 140 | TIntermSymbol *symbol = new TIntermSymbol(0, name, type); |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 141 | indexDirect->setLeft(symbol); |
| 142 | TIntermConstantUnion *indexNode = constructIndexNode(index); |
| 143 | indexDirect->setRight(indexNode); |
| 144 | |
| 145 | assign->setLeft(indexDirect); |
| 146 | |
Zhenyao Mo | 7211191 | 2016-07-20 17:45:56 -0700 | [diff] [blame^] | 147 | TIntermConstantUnion *zeroConst = constructConstUnionNode(type); |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 148 | assign->setRight(zeroConst); |
| 149 | } |
| 150 | } |
| 151 | else |
| 152 | { |
| 153 | TIntermBinary *assign = new TIntermBinary(EOpAssign); |
Zhenyao Mo | e40d1e9 | 2014-07-16 17:40:36 -0700 | [diff] [blame] | 154 | sequence->insert(sequence->begin(), assign); |
Zhenyao Mo | 7211191 | 2016-07-20 17:45:56 -0700 | [diff] [blame^] | 155 | TIntermSymbol *symbol = new TIntermSymbol(0, name, type); |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 156 | assign->setLeft(symbol); |
Zhenyao Mo | 7211191 | 2016-07-20 17:45:56 -0700 | [diff] [blame^] | 157 | TIntermConstantUnion *zeroConst = constructConstUnionNode(type); |
Zhenyao Mo | 4a667fe | 2014-02-11 12:35:01 -0800 | [diff] [blame] | 158 | assign->setRight(zeroConst); |
| 159 | } |
| 160 | |
| 161 | } |
| 162 | } |
| 163 | |
Zhenyao Mo | 7211191 | 2016-07-20 17:45:56 -0700 | [diff] [blame^] | 164 | } // namespace anonymous |
| 165 | |
| 166 | void InitializeVariables(TIntermNode *root, const InitVariableList &vars) |
| 167 | { |
| 168 | VariableInitializer initializer(vars); |
| 169 | root->traverse(&initializer); |
| 170 | } |