summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp')
-rw-r--r--src/3rdparty/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp238
1 files changed, 0 insertions, 238 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp b/src/3rdparty/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
deleted file mode 100644
index 746c16e2e6..0000000000
--- a/src/3rdparty/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-//
-// Copyright (c) 2002-2014 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.
-//
-// Scalarize vector and matrix constructor args, so that vectors built from components don't have
-// matrix arguments, and matrices built from components don't have vector arguments. This avoids
-// driver bugs around vector and matrix constructors.
-//
-
-#include "common/debug.h"
-#include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h"
-
-#include <algorithm>
-
-#include "angle_gl.h"
-#include "common/angleutils.h"
-#include "compiler/translator/IntermNode_util.h"
-#include "compiler/translator/IntermTraverse.h"
-
-namespace sh
-{
-
-namespace
-{
-
-bool ContainsMatrixNode(const TIntermSequence &sequence)
-{
- for (size_t ii = 0; ii < sequence.size(); ++ii)
- {
- TIntermTyped *node = sequence[ii]->getAsTyped();
- if (node && node->isMatrix())
- return true;
- }
- return false;
-}
-
-bool ContainsVectorNode(const TIntermSequence &sequence)
-{
- for (size_t ii = 0; ii < sequence.size(); ++ii)
- {
- TIntermTyped *node = sequence[ii]->getAsTyped();
- if (node && node->isVector())
- return true;
- }
- return false;
-}
-
-TIntermBinary *ConstructVectorIndexBinaryNode(TIntermSymbol *symbolNode, int index)
-{
- return new TIntermBinary(EOpIndexDirect, symbolNode, CreateIndexNode(index));
-}
-
-TIntermBinary *ConstructMatrixIndexBinaryNode(TIntermSymbol *symbolNode, int colIndex, int rowIndex)
-{
- TIntermBinary *colVectorNode = ConstructVectorIndexBinaryNode(symbolNode, colIndex);
-
- return new TIntermBinary(EOpIndexDirect, colVectorNode, CreateIndexNode(rowIndex));
-}
-
-class ScalarizeArgsTraverser : public TIntermTraverser
-{
- public:
- ScalarizeArgsTraverser(sh::GLenum shaderType,
- bool fragmentPrecisionHigh,
- TSymbolTable *symbolTable)
- : TIntermTraverser(true, false, false, symbolTable),
- mShaderType(shaderType),
- mFragmentPrecisionHigh(fragmentPrecisionHigh)
- {
- }
-
- protected:
- bool visitAggregate(Visit visit, TIntermAggregate *node) override;
- bool visitBlock(Visit visit, TIntermBlock *node) override;
-
- private:
- void scalarizeArgs(TIntermAggregate *aggregate, bool scalarizeVector, bool scalarizeMatrix);
-
- // If we have the following code:
- // mat4 m(0);
- // vec4 v(1, m);
- // We will rewrite to:
- // mat4 m(0);
- // mat4 s0 = m;
- // vec4 v(1, s0[0][0], s0[0][1], s0[0][2]);
- // This function is to create nodes for "mat4 s0 = m;" and insert it to the code sequence. This
- // way the possible side effects of the constructor argument will only be evaluated once.
- void createTempVariable(TIntermTyped *original);
-
- std::vector<TIntermSequence> mBlockStack;
-
- sh::GLenum mShaderType;
- bool mFragmentPrecisionHigh;
-};
-
-bool ScalarizeArgsTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
-{
- if (visit == PreVisit && node->getOp() == EOpConstruct)
- {
- if (node->getType().isVector() && ContainsMatrixNode(*(node->getSequence())))
- scalarizeArgs(node, false, true);
- else if (node->getType().isMatrix() && ContainsVectorNode(*(node->getSequence())))
- scalarizeArgs(node, true, false);
- }
- return true;
-}
-
-bool ScalarizeArgsTraverser::visitBlock(Visit visit, TIntermBlock *node)
-{
- mBlockStack.push_back(TIntermSequence());
- {
- for (TIntermNode *child : *node->getSequence())
- {
- ASSERT(child != nullptr);
- child->traverse(this);
- mBlockStack.back().push_back(child);
- }
- }
- if (mBlockStack.back().size() > node->getSequence()->size())
- {
- node->getSequence()->clear();
- *(node->getSequence()) = mBlockStack.back();
- }
- mBlockStack.pop_back();
- return false;
-}
-
-void ScalarizeArgsTraverser::scalarizeArgs(TIntermAggregate *aggregate,
- bool scalarizeVector,
- bool scalarizeMatrix)
-{
- ASSERT(aggregate);
- ASSERT(!aggregate->isArray());
- int size = static_cast<int>(aggregate->getType().getObjectSize());
- TIntermSequence *sequence = aggregate->getSequence();
- TIntermSequence original(*sequence);
- sequence->clear();
- for (size_t ii = 0; ii < original.size(); ++ii)
- {
- ASSERT(size > 0);
- TIntermTyped *node = original[ii]->getAsTyped();
- ASSERT(node);
- createTempVariable(node);
- if (node->isScalar())
- {
- sequence->push_back(createTempSymbol(node->getType()));
- size--;
- }
- else if (node->isVector())
- {
- if (scalarizeVector)
- {
- int repeat = std::min(size, node->getNominalSize());
- size -= repeat;
- for (int index = 0; index < repeat; ++index)
- {
- TIntermSymbol *symbolNode = createTempSymbol(node->getType());
- TIntermBinary *newNode = ConstructVectorIndexBinaryNode(symbolNode, index);
- sequence->push_back(newNode);
- }
- }
- else
- {
- TIntermSymbol *symbolNode = createTempSymbol(node->getType());
- sequence->push_back(symbolNode);
- size -= node->getNominalSize();
- }
- }
- else
- {
- ASSERT(node->isMatrix());
- if (scalarizeMatrix)
- {
- int colIndex = 0, rowIndex = 0;
- int repeat = std::min(size, node->getCols() * node->getRows());
- size -= repeat;
- while (repeat > 0)
- {
- TIntermSymbol *symbolNode = createTempSymbol(node->getType());
- TIntermBinary *newNode =
- ConstructMatrixIndexBinaryNode(symbolNode, colIndex, rowIndex);
- sequence->push_back(newNode);
- rowIndex++;
- if (rowIndex >= node->getRows())
- {
- rowIndex = 0;
- colIndex++;
- }
- repeat--;
- }
- }
- else
- {
- TIntermSymbol *symbolNode = createTempSymbol(node->getType());
- sequence->push_back(symbolNode);
- size -= node->getCols() * node->getRows();
- }
- }
- }
-}
-
-void ScalarizeArgsTraverser::createTempVariable(TIntermTyped *original)
-{
- ASSERT(original);
- nextTemporaryId();
- TIntermDeclaration *decl = createTempInitDeclaration(original);
-
- TType type = original->getType();
- if (mShaderType == GL_FRAGMENT_SHADER && type.getBasicType() == EbtFloat &&
- type.getPrecision() == EbpUndefined)
- {
- // We use the highest available precision for the temporary variable
- // to avoid computing the actual precision using the rules defined
- // in GLSL ES 1.0 Section 4.5.2.
- TIntermBinary *init = decl->getSequence()->at(0)->getAsBinaryNode();
- init->getTypePointer()->setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium);
- init->getLeft()->getTypePointer()->setPrecision(mFragmentPrecisionHigh ? EbpHigh
- : EbpMedium);
- }
-
- ASSERT(mBlockStack.size() > 0);
- TIntermSequence &sequence = mBlockStack.back();
- sequence.push_back(decl);
-}
-
-} // namespace anonymous
-
-void ScalarizeVecAndMatConstructorArgs(TIntermBlock *root,
- sh::GLenum shaderType,
- bool fragmentPrecisionHigh,
- TSymbolTable *symbolTable)
-{
- ScalarizeArgsTraverser scalarizer(shaderType, fragmentPrecisionHigh, symbolTable);
- root->traverse(&scalarizer);
-}
-
-} // namespace sh