blob: 576b64cac77e84ee3c41fec342e797f1187bc32f [file] [log] [blame]
Zhenyao Mo4a667fe2014-02-11 12:35:01 -08001//
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 Etuahod57e0db2015-04-24 15:05:08 +03008
Zhenyao Mo72111912016-07-20 17:45:56 -07009#include "angle_gl.h"
Olli Etuahod57e0db2015-04-24 15:05:08 +030010#include "common/debug.h"
Zhenyao Mo72111912016-07-20 17:45:56 -070011#include "compiler/translator/IntermNode.h"
12#include "compiler/translator/util.h"
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080013
Jamie Madill45bcc782016-11-07 13:58:48 -050014namespace sh
15{
16
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080017namespace
18{
19
Zhenyao Mo72111912016-07-20 17:45:56 -070020class VariableInitializer : public TIntermTraverser
21{
22 public:
23 VariableInitializer(const InitVariableList &vars)
24 : TIntermTraverser(true, false, false), mVariables(vars), mCodeInserted(false)
25 {
26 }
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080027
Zhenyao Mo72111912016-07-20 17:45:56 -070028 protected:
29 bool visitBinary(Visit, TIntermBinary *node) override { return false; }
30 bool visitUnary(Visit, TIntermUnary *node) override { return false; }
Olli Etuaho57961272016-09-14 13:57:46 +030031 bool visitIfElse(Visit, TIntermIfElse *node) override { return false; }
Zhenyao Mo72111912016-07-20 17:45:56 -070032 bool visitLoop(Visit, TIntermLoop *node) override { return false; }
33 bool visitBranch(Visit, TIntermBranch *node) override { return false; }
Olli Etuaho336b1472016-10-05 16:37:55 +010034 bool visitAggregate(Visit, TIntermAggregate *node) override { return false; }
Zhenyao Mo72111912016-07-20 17:45:56 -070035
Olli Etuaho336b1472016-10-05 16:37:55 +010036 bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
Zhenyao Mo72111912016-07-20 17:45:56 -070037
38 private:
39 void insertInitCode(TIntermSequence *sequence);
40
41 const InitVariableList &mVariables;
42 bool mCodeInserted;
43};
44
45// VariableInitializer implementation.
46
Olli Etuaho336b1472016-10-05 16:37:55 +010047bool VariableInitializer::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080048{
Olli Etuaho336b1472016-10-05 16:37:55 +010049 // Function definition.
50 ASSERT(visit == PreVisit);
51 if (node->getFunctionSymbolInfo()->isMain())
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080052 {
Olli Etuaho336b1472016-10-05 16:37:55 +010053 TIntermBlock *body = node->getBody();
54 insertInitCode(body->getSequence());
55 mCodeInserted = true;
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080056 }
Olli Etuaho336b1472016-10-05 16:37:55 +010057 return false;
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080058}
59
Zhenyao Mo72111912016-07-20 17:45:56 -070060void VariableInitializer::insertInitCode(TIntermSequence *sequence)
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080061{
Corentin Wallez509e4562016-08-25 14:55:44 -040062 for (const auto &var : mVariables)
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080063 {
Zhenyao Mo72111912016-07-20 17:45:56 -070064 TString name = TString(var.name.c_str());
Corentin Wallez509e4562016-08-25 14:55:44 -040065 TType type = sh::GetShaderVariableType(var);
66
67 // Assign the array elements one by one to keep the AST compatible with ESSL 1.00 which
68 // doesn't have array assignment.
Zhenyao Mo72111912016-07-20 17:45:56 -070069 if (var.isArray())
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080070 {
Zhenyao Mo72111912016-07-20 17:45:56 -070071 size_t pos = name.find_last_of('[');
72 if (pos != TString::npos)
Corentin Wallez509e4562016-08-25 14:55:44 -040073 {
Zhenyao Mo72111912016-07-20 17:45:56 -070074 name = name.substr(0, pos);
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080075 }
Corentin Wallez509e4562016-08-25 14:55:44 -040076 TType elementType = type;
77 elementType.clearArrayness();
Zhenyao Mof9312682016-07-22 12:51:31 -070078
Corentin Wallez509e4562016-08-25 14:55:44 -040079 for (unsigned int i = 0; i < var.arraySize; ++i)
80 {
Olli Etuaho3272a6d2016-08-29 17:54:50 +030081 TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, type);
82 TIntermBinary *element = new TIntermBinary(EOpIndexDirect, arraySymbol,
83 TIntermTyped::CreateIndexNode(i));
Zhenyao Mof9312682016-07-22 12:51:31 -070084
Corentin Wallez509e4562016-08-25 14:55:44 -040085 TIntermTyped *zero = TIntermTyped::CreateZero(elementType);
86 TIntermBinary *assignment = new TIntermBinary(EOpAssign, element, zero);
87
88 sequence->insert(sequence->begin(), assignment);
Zhenyao Mof9312682016-07-22 12:51:31 -070089 }
90 }
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080091 else
92 {
Zhenyao Mo72111912016-07-20 17:45:56 -070093 TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
Corentin Wallez509e4562016-08-25 14:55:44 -040094 TIntermTyped *zero = TIntermTyped::CreateZero(type);
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080095
Corentin Wallez509e4562016-08-25 14:55:44 -040096 TIntermBinary *assign = new TIntermBinary(EOpAssign, symbol, zero);
97 sequence->insert(sequence->begin(), assign);
98 }
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080099 }
100}
101
Zhenyao Mo72111912016-07-20 17:45:56 -0700102} // namespace anonymous
103
104void InitializeVariables(TIntermNode *root, const InitVariableList &vars)
105{
106 VariableInitializer initializer(vars);
107 root->traverse(&initializer);
108}
Jamie Madill45bcc782016-11-07 13:58:48 -0500109
110} // namespace sh