diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/ThirdParty/ANGLE/src/compiler/translator/UseInterfaceBlockFields.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/ThirdParty/ANGLE/src/compiler/translator/UseInterfaceBlockFields.cpp')
-rw-r--r-- | Source/ThirdParty/ANGLE/src/compiler/translator/UseInterfaceBlockFields.cpp | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/Source/ThirdParty/ANGLE/src/compiler/translator/UseInterfaceBlockFields.cpp b/Source/ThirdParty/ANGLE/src/compiler/translator/UseInterfaceBlockFields.cpp new file mode 100644 index 000000000..2a1a812e2 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/translator/UseInterfaceBlockFields.cpp @@ -0,0 +1,153 @@ +// +// 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/IntermNode.h" +#include "compiler/translator/util.h" + +namespace sh +{ + +namespace +{ + +class UseUniformBlockMembers : public TIntermTraverser +{ + public: + UseUniformBlockMembers(const InterfaceBlockList &blocks) + : TIntermTraverser(true, false, false), mBlocks(blocks), mCodeInserted(false) + { + } + + protected: + bool visitAggregate(Visit visit, TIntermAggregate *node) override { return !mCodeInserted; } + bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override; + + private: + void insertUseCode(TIntermSequence *sequence); + void AddFieldUseStatements(const ShaderVariable &var, TIntermSequence *sequence); + + const InterfaceBlockList &mBlocks; + bool mCodeInserted; +}; + +bool UseUniformBlockMembers::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) +{ + ASSERT(visit == PreVisit); + if (node->getFunctionSymbolInfo()->isMain()) + { + TIntermBlock *body = node->getBody(); + ASSERT(body); + insertUseCode(body->getSequence()); + mCodeInserted = true; + return false; + } + return !mCodeInserted; +} + +void UseUniformBlockMembers::AddFieldUseStatements(const ShaderVariable &var, + TIntermSequence *sequence) +{ + TString name = TString(var.name.c_str()); + TType type = GetShaderVariableType(var); + + if (var.isArray()) + { + size_t pos = name.find_last_of('['); + if (pos != TString::npos) + { + name = name.substr(0, pos); + } + TType elementType = type; + elementType.clearArrayness(); + + TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, type); + for (unsigned int i = 0; i < var.arraySize; ++i) + { + TIntermBinary *element = + new TIntermBinary(EOpIndexDirect, arraySymbol, TIntermTyped::CreateIndexNode(i)); + + sequence->insert(sequence->begin(), element); + } + } + else if (var.isStruct()) + { + TIntermSymbol *structSymbol = new TIntermSymbol(0, name, type); + for (unsigned int i = 0; i < var.fields.size(); ++i) + { + TIntermBinary *element = new TIntermBinary(EOpIndexDirectStruct, structSymbol, + TIntermTyped::CreateIndexNode(i)); + + sequence->insert(sequence->begin(), element); + } + } + else + { + TIntermSymbol *symbol = new TIntermSymbol(0, name, type); + + sequence->insert(sequence->begin(), symbol); + } +} + +void UseUniformBlockMembers::insertUseCode(TIntermSequence *sequence) +{ + for (const auto &block : mBlocks) + { + if (block.instanceName.empty()) + { + for (const auto &var : block.fields) + { + AddFieldUseStatements(var, sequence); + } + } + else if (block.arraySize > 0) + { + TType type = GetInterfaceBlockType(block); + TString name = TString(block.instanceName.c_str()); + TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, type); + for (unsigned int i = 0; i < block.arraySize; ++i) + { + TIntermBinary *instanceSymbol = new TIntermBinary(EOpIndexDirect, arraySymbol, + TIntermTyped::CreateIndexNode(i)); + for (unsigned int j = 0; j < block.fields.size(); ++j) + { + TIntermBinary *element = + new TIntermBinary(EOpIndexDirectInterfaceBlock, instanceSymbol, + TIntermTyped::CreateIndexNode(j)); + sequence->insert(sequence->begin(), element); + } + } + } + else + { + TType type = GetInterfaceBlockType(block); + TString name = TString(block.instanceName.c_str()); + TIntermSymbol *blockSymbol = new TIntermSymbol(0, name, type); + for (unsigned int i = 0; i < block.fields.size(); ++i) + { + TIntermBinary *element = new TIntermBinary( + EOpIndexDirectInterfaceBlock, blockSymbol, TIntermTyped::CreateIndexNode(i)); + + sequence->insert(sequence->begin(), element); + } + } + } +} + +} // namespace anonymous + +void UseInterfaceBlockFields(TIntermNode *root, const InterfaceBlockList &blocks) +{ + UseUniformBlockMembers useUniformBlock(blocks); + root->traverse(&useUniformBlock); +} + +} // namespace sh |