blob: 0819cabc4ce753fdacb7d6a08240fd8f41596de3 [file] [log] [blame]
Qin Jiajia7835b522016-10-08 11:20:17 +08001//
2// Copyright 2016 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// UseInterfaceBlockFields.cpp: insert statements to reference all members in InterfaceBlock list at
8// the beginning of main. This is to work around a Mac driver that treats unused standard/shared
9// uniform blocks as inactive.
10
11#include "compiler/translator/UseInterfaceBlockFields.h"
12
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030013#include "compiler/translator/FindMain.h"
Qin Jiajia7835b522016-10-08 11:20:17 +080014#include "compiler/translator/IntermNode.h"
Zhenyao Mod7490962016-11-09 15:49:51 -080015#include "compiler/translator/SymbolTable.h"
Qin Jiajia7835b522016-10-08 11:20:17 +080016#include "compiler/translator/util.h"
17
18namespace sh
19{
20
21namespace
22{
23
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030024void AddFieldUseStatements(const ShaderVariable &var,
25 TIntermSequence *sequence,
26 const TSymbolTable &symbolTable)
Qin Jiajia7835b522016-10-08 11:20:17 +080027{
28 TString name = TString(var.name.c_str());
Qin Jiajia7835b522016-10-08 11:20:17 +080029 if (var.isArray())
30 {
31 size_t pos = name.find_last_of('[');
32 if (pos != TString::npos)
33 {
34 name = name.substr(0, pos);
35 }
Zhenyao Mod7490962016-11-09 15:49:51 -080036 }
37 const TType *type;
38 TType basicType;
39 if (var.isStruct())
40 {
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030041 TVariable *structInfo = reinterpret_cast<TVariable *>(symbolTable.findGlobal(name));
Zhenyao Mod7490962016-11-09 15:49:51 -080042 ASSERT(structInfo);
43 const TType &structType = structInfo->getType();
44 type = &structType;
45 }
46 else
47 {
48 basicType = sh::GetShaderVariableBasicType(var);
49 type = &basicType;
50 }
51 ASSERT(type);
Qin Jiajia7835b522016-10-08 11:20:17 +080052
Zhenyao Mod7490962016-11-09 15:49:51 -080053 TIntermSymbol *symbol = new TIntermSymbol(0, name, *type);
54 if (var.isArray())
55 {
Qin Jiajia7835b522016-10-08 11:20:17 +080056 for (unsigned int i = 0; i < var.arraySize; ++i)
57 {
58 TIntermBinary *element =
Zhenyao Mod7490962016-11-09 15:49:51 -080059 new TIntermBinary(EOpIndexDirect, symbol, TIntermTyped::CreateIndexNode(i));
Qin Jiajia7835b522016-10-08 11:20:17 +080060 sequence->insert(sequence->begin(), element);
61 }
62 }
63 else
64 {
Qin Jiajia7835b522016-10-08 11:20:17 +080065 sequence->insert(sequence->begin(), symbol);
66 }
67}
68
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030069void InsertUseCode(TIntermSequence *sequence,
70 const InterfaceBlockList &blocks,
71 const TSymbolTable &symbolTable)
Qin Jiajia7835b522016-10-08 11:20:17 +080072{
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030073 for (const auto &block : blocks)
Qin Jiajia7835b522016-10-08 11:20:17 +080074 {
75 if (block.instanceName.empty())
76 {
77 for (const auto &var : block.fields)
78 {
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030079 AddFieldUseStatements(var, sequence, symbolTable);
Qin Jiajia7835b522016-10-08 11:20:17 +080080 }
81 }
82 else if (block.arraySize > 0)
83 {
Zhenyao Mod7490962016-11-09 15:49:51 -080084 TString name = TString(block.instanceName.c_str());
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030085 TVariable *ubInfo = reinterpret_cast<TVariable *>(symbolTable.findGlobal(name));
Zhenyao Mod7490962016-11-09 15:49:51 -080086 ASSERT(ubInfo);
87 TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, ubInfo->getType());
Qin Jiajia7835b522016-10-08 11:20:17 +080088 for (unsigned int i = 0; i < block.arraySize; ++i)
89 {
90 TIntermBinary *instanceSymbol = new TIntermBinary(EOpIndexDirect, arraySymbol,
91 TIntermTyped::CreateIndexNode(i));
92 for (unsigned int j = 0; j < block.fields.size(); ++j)
93 {
94 TIntermBinary *element =
95 new TIntermBinary(EOpIndexDirectInterfaceBlock, instanceSymbol,
96 TIntermTyped::CreateIndexNode(j));
97 sequence->insert(sequence->begin(), element);
98 }
99 }
100 }
101 else
102 {
Zhenyao Mod7490962016-11-09 15:49:51 -0800103 TString name = TString(block.instanceName.c_str());
Olli Etuaho9cbc07c2017-05-10 18:22:01 +0300104 TVariable *ubInfo = reinterpret_cast<TVariable *>(symbolTable.findGlobal(name));
Zhenyao Mod7490962016-11-09 15:49:51 -0800105 ASSERT(ubInfo);
106 TIntermSymbol *blockSymbol = new TIntermSymbol(0, name, ubInfo->getType());
Qin Jiajia7835b522016-10-08 11:20:17 +0800107 for (unsigned int i = 0; i < block.fields.size(); ++i)
108 {
109 TIntermBinary *element = new TIntermBinary(
110 EOpIndexDirectInterfaceBlock, blockSymbol, TIntermTyped::CreateIndexNode(i));
111
112 sequence->insert(sequence->begin(), element);
113 }
114 }
115 }
116}
117
118} // namespace anonymous
119
Olli Etuaho9cbc07c2017-05-10 18:22:01 +0300120void UseInterfaceBlockFields(TIntermBlock *root,
Zhenyao Mod7490962016-11-09 15:49:51 -0800121 const InterfaceBlockList &blocks,
122 const TSymbolTable &symbolTable)
Qin Jiajia7835b522016-10-08 11:20:17 +0800123{
Olli Etuaho9cbc07c2017-05-10 18:22:01 +0300124 TIntermFunctionDefinition *main = FindMain(root);
125 TIntermBlock *mainBody = main->getBody();
126 ASSERT(mainBody);
127 InsertUseCode(mainBody->getSequence(), blocks, symbolTable);
Qin Jiajia7835b522016-10-08 11:20:17 +0800128}
129
130} // namespace sh