Hash :
daaff1cc
Author :
Date :
2017-07-05T18:03:26
Set correct symbol ids when referring to GLSL built-ins The symbol ids are fetched from the symbol table. A new utility function is added to make this more convenient. BUG=angleproject:1490 TEST=angle_unittests, angle_end2end_tests Change-Id: I780430e3386f6599503d8290c568ca9bc9cad147 Reviewed-on: https://chromium-review.googlesource.com/559535 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: Jamie Madill <jmadill@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// UseInterfaceBlockFields.cpp: insert statements to reference all members in InterfaceBlock list at
// the beginning of main. This is to work around a Mac driver that treats unused standard/shared
// uniform blocks as inactive.
#include "compiler/translator/UseInterfaceBlockFields.h"
#include "compiler/translator/FindMain.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/util.h"
namespace sh
{
namespace
{
void AddFieldUseStatements(const ShaderVariable &var,
TIntermSequence *sequence,
const TSymbolTable &symbolTable)
{
TString name = TString(var.name.c_str());
if (var.isArray())
{
size_t pos = name.find_last_of('[');
if (pos != TString::npos)
{
name = name.substr(0, pos);
}
}
TIntermSymbol *symbol = ReferenceGlobalVariable(name, symbolTable);
if (var.isArray())
{
for (unsigned int i = 0u; i < var.arraySize; ++i)
{
TIntermBinary *element =
new TIntermBinary(EOpIndexDirect, symbol->deepCopy(), CreateIndexNode(i));
sequence->insert(sequence->begin(), element);
}
}
else
{
sequence->insert(sequence->begin(), symbol);
}
}
void InsertUseCode(const InterfaceBlock &block, TIntermTyped *blockNode, TIntermSequence *sequence)
{
for (unsigned int i = 0; i < block.fields.size(); ++i)
{
TIntermBinary *element = new TIntermBinary(EOpIndexDirectInterfaceBlock,
blockNode->deepCopy(), CreateIndexNode(i));
sequence->insert(sequence->begin(), element);
}
}
void InsertUseCode(TIntermSequence *sequence,
const InterfaceBlockList &blocks,
const TSymbolTable &symbolTable)
{
for (const auto &block : blocks)
{
if (block.instanceName.empty())
{
for (const auto &var : block.fields)
{
AddFieldUseStatements(var, sequence, symbolTable);
}
}
else if (block.arraySize > 0u)
{
TString name(block.instanceName.c_str());
TIntermSymbol *arraySymbol = ReferenceGlobalVariable(name, symbolTable);
for (unsigned int i = 0u; i < block.arraySize; ++i)
{
TIntermBinary *elementSymbol =
new TIntermBinary(EOpIndexDirect, arraySymbol->deepCopy(), CreateIndexNode(i));
InsertUseCode(block, elementSymbol, sequence);
}
}
else
{
TString name(block.instanceName.c_str());
TIntermSymbol *blockSymbol = ReferenceGlobalVariable(name, symbolTable);
InsertUseCode(block, blockSymbol, sequence);
}
}
}
} // namespace anonymous
void UseInterfaceBlockFields(TIntermBlock *root,
const InterfaceBlockList &blocks,
const TSymbolTable &symbolTable)
{
TIntermBlock *mainBody = FindMainBody(root);
InsertUseCode(mainBody->getSequence(), blocks, symbolTable);
}
} // namespace sh