blob: 40bd42afad86b2d83db7850e2b48967eae32843f [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 Etuaho283c2192017-10-23 17:11:50 +030025void AddNodeUseStatements(TIntermTyped *node, TIntermSequence *sequence)
26{
27 if (node->isArray())
28 {
29 for (unsigned int i = 0u; i < node->getOutermostArraySize(); ++i)
30 {
31 TIntermBinary *element =
32 new TIntermBinary(EOpIndexDirect, node->deepCopy(), CreateIndexNode(i));
33 AddNodeUseStatements(element, sequence);
34 }
35 }
36 else
37 {
38 sequence->insert(sequence->begin(), node);
39 }
40}
41
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030042void AddFieldUseStatements(const ShaderVariable &var,
43 TIntermSequence *sequence,
44 const TSymbolTable &symbolTable)
Qin Jiajia7835b522016-10-08 11:20:17 +080045{
46 TString name = TString(var.name.c_str());
Olli Etuaho283c2192017-10-23 17:11:50 +030047 ASSERT(name.find_last_of('[') == TString::npos);
Olli Etuahodaaff1c2017-07-05 18:03:26 +030048 TIntermSymbol *symbol = ReferenceGlobalVariable(name, symbolTable);
Olli Etuaho283c2192017-10-23 17:11:50 +030049 AddNodeUseStatements(symbol, sequence);
Qin Jiajia7835b522016-10-08 11:20:17 +080050}
51
Olli Etuaho4cafb862017-07-05 14:05:06 +030052void InsertUseCode(const InterfaceBlock &block, TIntermTyped *blockNode, TIntermSequence *sequence)
53{
54 for (unsigned int i = 0; i < block.fields.size(); ++i)
55 {
56 TIntermBinary *element = new TIntermBinary(EOpIndexDirectInterfaceBlock,
57 blockNode->deepCopy(), CreateIndexNode(i));
58 sequence->insert(sequence->begin(), element);
59 }
60}
61
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030062void InsertUseCode(TIntermSequence *sequence,
63 const InterfaceBlockList &blocks,
64 const TSymbolTable &symbolTable)
Qin Jiajia7835b522016-10-08 11:20:17 +080065{
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030066 for (const auto &block : blocks)
Qin Jiajia7835b522016-10-08 11:20:17 +080067 {
68 if (block.instanceName.empty())
69 {
70 for (const auto &var : block.fields)
71 {
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030072 AddFieldUseStatements(var, sequence, symbolTable);
Qin Jiajia7835b522016-10-08 11:20:17 +080073 }
74 }
Olli Etuaho4cafb862017-07-05 14:05:06 +030075 else if (block.arraySize > 0u)
Qin Jiajia7835b522016-10-08 11:20:17 +080076 {
Olli Etuaho4cafb862017-07-05 14:05:06 +030077 TString name(block.instanceName.c_str());
Olli Etuahodaaff1c2017-07-05 18:03:26 +030078 TIntermSymbol *arraySymbol = ReferenceGlobalVariable(name, symbolTable);
Olli Etuaho4cafb862017-07-05 14:05:06 +030079 for (unsigned int i = 0u; i < block.arraySize; ++i)
Qin Jiajia7835b522016-10-08 11:20:17 +080080 {
Olli Etuaho4cafb862017-07-05 14:05:06 +030081 TIntermBinary *elementSymbol =
82 new TIntermBinary(EOpIndexDirect, arraySymbol->deepCopy(), CreateIndexNode(i));
83 InsertUseCode(block, elementSymbol, sequence);
Qin Jiajia7835b522016-10-08 11:20:17 +080084 }
85 }
86 else
87 {
Olli Etuaho4cafb862017-07-05 14:05:06 +030088 TString name(block.instanceName.c_str());
Olli Etuahodaaff1c2017-07-05 18:03:26 +030089 TIntermSymbol *blockSymbol = ReferenceGlobalVariable(name, symbolTable);
Olli Etuaho4cafb862017-07-05 14:05:06 +030090 InsertUseCode(block, blockSymbol, sequence);
Qin Jiajia7835b522016-10-08 11:20:17 +080091 }
92 }
93}
94
95} // namespace anonymous
96
Olli Etuaho9cbc07c2017-05-10 18:22:01 +030097void UseInterfaceBlockFields(TIntermBlock *root,
Zhenyao Mod7490962016-11-09 15:49:51 -080098 const InterfaceBlockList &blocks,
99 const TSymbolTable &symbolTable)
Qin Jiajia7835b522016-10-08 11:20:17 +0800100{
Martin Radevb50ccd32017-07-06 17:09:58 +0300101 TIntermBlock *mainBody = FindMainBody(root);
Olli Etuaho9cbc07c2017-05-10 18:22:01 +0300102 InsertUseCode(mainBody->getSequence(), blocks, symbolTable);
Qin Jiajia7835b522016-10-08 11:20:17 +0800103}
104
105} // namespace sh