blob: 0c9a959788b710b24227c0078d22918bb47a23a3 [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"
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030011#include "compiler/translator/FindMain.h"
Zhenyao Mo72111912016-07-20 17:45:56 -070012#include "compiler/translator/IntermNode.h"
Zhenyao Mod7490962016-11-09 15:49:51 -080013#include "compiler/translator/SymbolTable.h"
Zhenyao Mo72111912016-07-20 17:45:56 -070014#include "compiler/translator/util.h"
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080015
Jamie Madill45bcc782016-11-07 13:58:48 -050016namespace sh
17{
18
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080019namespace
20{
21
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030022void InsertInitCode(TIntermSequence *sequence,
23 const InitVariableList &variables,
24 const TSymbolTable &symbolTable)
Zhenyao Mo72111912016-07-20 17:45:56 -070025{
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030026 for (const auto &var : variables)
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080027 {
Zhenyao Mo72111912016-07-20 17:45:56 -070028 TString name = TString(var.name.c_str());
Corentin Wallez509e4562016-08-25 14:55:44 -040029
Zhenyao Mo72111912016-07-20 17:45:56 -070030 if (var.isArray())
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080031 {
Zhenyao Mod7490962016-11-09 15:49:51 -080032 // Assign the array elements one by one to keep the AST compatible with ESSL 1.00 which
33 // doesn't have array assignment.
Zhenyao Mo72111912016-07-20 17:45:56 -070034 size_t pos = name.find_last_of('[');
35 if (pos != TString::npos)
Corentin Wallez509e4562016-08-25 14:55:44 -040036 {
Zhenyao Mo72111912016-07-20 17:45:56 -070037 name = name.substr(0, pos);
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080038 }
Zhenyao Mod7490962016-11-09 15:49:51 -080039 TType elementType = sh::GetShaderVariableBasicType(var);
40 TType arrayType = elementType;
41 arrayType.setArraySize(var.elementCount());
Zhenyao Mof9312682016-07-22 12:51:31 -070042
Kai Ninomiyad1bed172017-04-12 17:35:54 -070043 // Workaround for http://crbug.com/709317
44 // This loop is reversed to initialize elements in increasing
45 // order [0 1 2 ...]. Otherwise, they're initialized in
46 // decreasing order [... 2 1 0], due to
47 // `sequence->insert(sequence->begin(), ...)` below.
48 for (unsigned int i = var.arraySize; i > 0; --i)
Corentin Wallez509e4562016-08-25 14:55:44 -040049 {
Kai Ninomiyad1bed172017-04-12 17:35:54 -070050 unsigned int index = i - 1;
Zhenyao Mod7490962016-11-09 15:49:51 -080051 TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, arrayType);
Olli Etuaho3272a6d2016-08-29 17:54:50 +030052 TIntermBinary *element = new TIntermBinary(EOpIndexDirect, arraySymbol,
Kai Ninomiyad1bed172017-04-12 17:35:54 -070053 TIntermTyped::CreateIndexNode(index));
Zhenyao Mof9312682016-07-22 12:51:31 -070054
Corentin Wallez509e4562016-08-25 14:55:44 -040055 TIntermTyped *zero = TIntermTyped::CreateZero(elementType);
56 TIntermBinary *assignment = new TIntermBinary(EOpAssign, element, zero);
57
58 sequence->insert(sequence->begin(), assignment);
Zhenyao Mof9312682016-07-22 12:51:31 -070059 }
60 }
Zhenyao Mod7490962016-11-09 15:49:51 -080061 else if (var.isStruct())
62 {
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030063 TVariable *structInfo = reinterpret_cast<TVariable *>(symbolTable.findGlobal(name));
Zhenyao Mod7490962016-11-09 15:49:51 -080064 ASSERT(structInfo);
65
66 TIntermSymbol *symbol = new TIntermSymbol(0, name, structInfo->getType());
67 TIntermTyped *zero = TIntermTyped::CreateZero(structInfo->getType());
68
69 TIntermBinary *assign = new TIntermBinary(EOpAssign, symbol, zero);
70 sequence->insert(sequence->begin(), assign);
71 }
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080072 else
73 {
Zhenyao Mod7490962016-11-09 15:49:51 -080074 TType type = sh::GetShaderVariableBasicType(var);
Zhenyao Mo72111912016-07-20 17:45:56 -070075 TIntermSymbol *symbol = new TIntermSymbol(0, name, type);
Corentin Wallez509e4562016-08-25 14:55:44 -040076 TIntermTyped *zero = TIntermTyped::CreateZero(type);
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080077
Corentin Wallez509e4562016-08-25 14:55:44 -040078 TIntermBinary *assign = new TIntermBinary(EOpAssign, symbol, zero);
79 sequence->insert(sequence->begin(), assign);
80 }
Zhenyao Mo4a667fe2014-02-11 12:35:01 -080081 }
82}
83
Zhenyao Mo72111912016-07-20 17:45:56 -070084} // namespace anonymous
85
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030086void InitializeVariables(TIntermBlock *root,
Zhenyao Mod7490962016-11-09 15:49:51 -080087 const InitVariableList &vars,
88 const TSymbolTable &symbolTable)
Zhenyao Mo72111912016-07-20 17:45:56 -070089{
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030090 TIntermFunctionDefinition *main = FindMain(root);
91 ASSERT(main != nullptr);
92 TIntermBlock *body = main->getBody();
93 InsertInitCode(body->getSequence(), vars, symbolTable);
Zhenyao Mo72111912016-07-20 17:45:56 -070094}
Jamie Madill45bcc782016-11-07 13:58:48 -050095
96} // namespace sh