diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.cpp | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.cpp')
-rw-r--r-- | gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.cpp | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.cpp new file mode 100644 index 0000000000..ddbb22685d --- /dev/null +++ b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.cpp @@ -0,0 +1,175 @@ +// +// Copyright 2020 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. +// +// ReplaceArrayOfMatrixVarying: Find any references to array of matrices varying +// and replace it with array of vectors. +// + +#include "compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.h" + +#include <vector> + +#include "common/bitset_utils.h" +#include "common/debug.h" +#include "common/utilities.h" +#include "compiler/translator/Compiler.h" +#include "compiler/translator/SymbolTable.h" +#include "compiler/translator/tree_util/BuiltIn.h" +#include "compiler/translator/tree_util/FindMain.h" +#include "compiler/translator/tree_util/IntermNode_util.h" +#include "compiler/translator/tree_util/IntermTraverse.h" +#include "compiler/translator/tree_util/ReplaceVariable.h" +#include "compiler/translator/tree_util/RunAtTheEndOfShader.h" +#include "compiler/translator/util.h" + +namespace sh +{ + +// We create two variables to replace the given varying: +// - The new varying which is an array of vectors to be used at input/ouput only. +// - The new global variable which is a same type as given variable, to temporarily be used +// as replacements for assignments, arithmetic ops and so on. During input/ouput phrase, this temp +// variable will be copied from/to the array of vectors variable above. +// NOTE(hqle): Consider eliminating the need for using temp variable. + +namespace +{ +class CollectVaryingTraverser : public TIntermTraverser +{ + public: + CollectVaryingTraverser(std::vector<const TVariable *> *varyingsOut) + : TIntermTraverser(true, false, false), mVaryingsOut(varyingsOut) + {} + + bool visitDeclaration(Visit visit, TIntermDeclaration *node) override + { + const TIntermSequence &sequence = *(node->getSequence()); + + if (sequence.size() != 1) + { + return false; + } + + TIntermTyped *variableType = sequence.front()->getAsTyped(); + if (!variableType || !IsVarying(variableType->getQualifier()) || + !variableType->isMatrix() || !variableType->isArray()) + { + return false; + } + + TIntermSymbol *variableSymbol = variableType->getAsSymbolNode(); + if (!variableSymbol) + { + return false; + } + + mVaryingsOut->push_back(&variableSymbol->variable()); + + return false; + } + + private: + std::vector<const TVariable *> *mVaryingsOut; +}; +} // namespace + +[[nodiscard]] bool ReplaceArrayOfMatrixVarying(TCompiler *compiler, + TIntermBlock *root, + TSymbolTable *symbolTable, + const TVariable *varying) +{ + const TType &type = varying->getType(); + + // Create global variable to temporarily acts as the given variable in places such as + // arithmetic, assignments an so on. + TType *tmpReplacementType = new TType(type); + tmpReplacementType->setQualifier(EvqGlobal); + + TVariable *tempReplaceVar = new TVariable( + symbolTable, ImmutableString(std::string("ANGLE_AOM_Temp_") + varying->name().data()), + tmpReplacementType, SymbolType::AngleInternal); + + if (!ReplaceVariable(compiler, root, varying, tempReplaceVar)) + { + return false; + } + + // Create array of vectors type + TType *varyingReplaceType = new TType(type); + varyingReplaceType->toMatrixColumnType(); + varyingReplaceType->toArrayElementType(); + varyingReplaceType->makeArray(type.getCols() * type.getOutermostArraySize()); + + TVariable *varyingReplaceVar = + new TVariable(symbolTable, varying->name(), varyingReplaceType, SymbolType::UserDefined); + + TIntermSymbol *varyingReplaceDeclarator = new TIntermSymbol(varyingReplaceVar); + TIntermDeclaration *varyingReplaceDecl = new TIntermDeclaration; + varyingReplaceDecl->appendDeclarator(varyingReplaceDeclarator); + root->insertStatement(0, varyingReplaceDecl); + + // Copy from/to the temp variable + TIntermBlock *reassignBlock = new TIntermBlock; + TIntermSymbol *tempReplaceSymbol = new TIntermSymbol(tempReplaceVar); + TIntermSymbol *varyingReplaceSymbol = new TIntermSymbol(varyingReplaceVar); + bool isInput = IsVaryingIn(type.getQualifier()); + + for (unsigned int i = 0; i < type.getOutermostArraySize(); ++i) + { + TIntermBinary *tempMatrixIndexed = + new TIntermBinary(EOpIndexDirect, tempReplaceSymbol->deepCopy(), CreateIndexNode(i)); + for (uint8_t col = 0; col < type.getCols(); ++col) + { + + TIntermBinary *tempMatrixColIndexed = new TIntermBinary( + EOpIndexDirect, tempMatrixIndexed->deepCopy(), CreateIndexNode(col)); + TIntermBinary *vectorIndexed = + new TIntermBinary(EOpIndexDirect, varyingReplaceSymbol->deepCopy(), + CreateIndexNode(i * type.getCols() + col)); + TIntermBinary *assignment; + if (isInput) + { + assignment = new TIntermBinary(EOpAssign, tempMatrixColIndexed, vectorIndexed); + } + else + { + assignment = new TIntermBinary(EOpAssign, vectorIndexed, tempMatrixColIndexed); + } + reassignBlock->appendStatement(assignment); + } + } + + if (isInput) + { + TIntermFunctionDefinition *main = FindMain(root); + main->getBody()->insertStatement(0, reassignBlock); + return compiler->validateAST(root); + } + else + { + return RunAtTheEndOfShader(compiler, root, reassignBlock, symbolTable); + } +} + +[[nodiscard]] bool ReplaceArrayOfMatrixVaryings(TCompiler *compiler, + TIntermBlock *root, + TSymbolTable *symbolTable) +{ + std::vector<const TVariable *> arrayOfMatrixVars; + CollectVaryingTraverser varCollector(&arrayOfMatrixVars); + root->traverse(&varCollector); + + for (const TVariable *var : arrayOfMatrixVars) + { + if (!ReplaceArrayOfMatrixVarying(compiler, root, symbolTable, var)) + { + return false; + } + } + + return true; +} + +} // namespace sh |