blob: aa98611554a303496c36e26e41a62b5e87d7a048 [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"
Olli Etuaho3ec75682017-07-05 17:02:55 +030015#include "compiler/translator/IntermNode_util.h"
Zhenyao Mod7490962016-11-09 15:49:51 -080016#include "compiler/translator/SymbolTable.h"
Qin Jiajia7835b522016-10-08 11:20:17 +080017#include "compiler/translator/util.h"
18
19namespace sh
20{
21
22namespace
23{
24
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030025void AddFieldUseStatements(const ShaderVariable &var,
26 TIntermSequence *sequence,
27 const TSymbolTable &symbolTable)
Qin Jiajia7835b522016-10-08 11:20:17 +080028{
29 TString name = TString(var.name.c_str());
Qin Jiajia7835b522016-10-08 11:20:17 +080030 if (var.isArray())
31 {
32 size_t pos = name.find_last_of('[');
33 if (pos != TString::npos)
34 {
35 name = name.substr(0, pos);
36 }
Zhenyao Mod7490962016-11-09 15:49:51 -080037 }
38 const TType *type;
39 TType basicType;
40 if (var.isStruct())
41 {
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030042 TVariable *structInfo = reinterpret_cast<TVariable *>(symbolTable.findGlobal(name));
Zhenyao Mod7490962016-11-09 15:49:51 -080043 ASSERT(structInfo);
44 const TType &structType = structInfo->getType();
45 type = &structType;
46 }
47 else
48 {
49 basicType = sh::GetShaderVariableBasicType(var);
50 type = &basicType;
51 }
52 ASSERT(type);
Qin Jiajia7835b522016-10-08 11:20:17 +080053
Zhenyao Mod7490962016-11-09 15:49:51 -080054 TIntermSymbol *symbol = new TIntermSymbol(0, name, *type);
55 if (var.isArray())
56 {
Qin Jiajia7835b522016-10-08 11:20:17 +080057 for (unsigned int i = 0; i < var.arraySize; ++i)
58 {
Olli Etuaho3ec75682017-07-05 17:02:55 +030059 TIntermBinary *element = new TIntermBinary(EOpIndexDirect, symbol, 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 {
Olli Etuaho3ec75682017-07-05 17:02:55 +030090 TIntermBinary *instanceSymbol =
91 new TIntermBinary(EOpIndexDirect, arraySymbol, CreateIndexNode(i));
Qin Jiajia7835b522016-10-08 11:20:17 +080092 for (unsigned int j = 0; j < block.fields.size(); ++j)
93 {
Olli Etuaho3ec75682017-07-05 17:02:55 +030094 TIntermBinary *element = new TIntermBinary(EOpIndexDirectInterfaceBlock,
95 instanceSymbol, CreateIndexNode(j));
Qin Jiajia7835b522016-10-08 11:20:17 +080096 sequence->insert(sequence->begin(), element);
97 }
98 }
99 }
100 else
101 {
Zhenyao Mod7490962016-11-09 15:49:51 -0800102 TString name = TString(block.instanceName.c_str());
Olli Etuaho9cbc07c2017-05-10 18:22:01 +0300103 TVariable *ubInfo = reinterpret_cast<TVariable *>(symbolTable.findGlobal(name));
Zhenyao Mod7490962016-11-09 15:49:51 -0800104 ASSERT(ubInfo);
105 TIntermSymbol *blockSymbol = new TIntermSymbol(0, name, ubInfo->getType());
Qin Jiajia7835b522016-10-08 11:20:17 +0800106 for (unsigned int i = 0; i < block.fields.size(); ++i)
107 {
Olli Etuaho3ec75682017-07-05 17:02:55 +0300108 TIntermBinary *element = new TIntermBinary(EOpIndexDirectInterfaceBlock,
109 blockSymbol, CreateIndexNode(i));
Qin Jiajia7835b522016-10-08 11:20:17 +0800110
111 sequence->insert(sequence->begin(), element);
112 }
113 }
114 }
115}
116
117} // namespace anonymous
118
Olli Etuaho9cbc07c2017-05-10 18:22:01 +0300119void UseInterfaceBlockFields(TIntermBlock *root,
Zhenyao Mod7490962016-11-09 15:49:51 -0800120 const InterfaceBlockList &blocks,
121 const TSymbolTable &symbolTable)
Qin Jiajia7835b522016-10-08 11:20:17 +0800122{
Olli Etuaho9cbc07c2017-05-10 18:22:01 +0300123 TIntermFunctionDefinition *main = FindMain(root);
124 TIntermBlock *mainBody = main->getBody();
125 ASSERT(mainBody);
126 InsertUseCode(mainBody->getSequence(), blocks, symbolTable);
Qin Jiajia7835b522016-10-08 11:20:17 +0800127}
128
129} // namespace sh