Edit

kc3-lang/angle/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.cpp

Branch :

  • Show log

    Commit

  • Author : Shahbaz Youssefi
    Date : 2021-07-30 23:00:57
    Hash : a65b4056
    Message : Reland "Translator: Clean up type cloning" This is a reland of f016c4352f5203c10511df078b1ed5359afc1b35 Original change's description: > Translator: Clean up type cloning > > TType has a constructor that aids cloning + helpers to convert between > types. A number of places where a type is constructed from the > information gathered from another type is changed to clone the type and > then use one of these helpers. > > This clean up is part of an ongoing work to improve precision handling. > This change removes many references to TType::getPrecision(). > > Bug: angleproject:4889 > Change-Id: Ib85659ab5363b56ad298f8648fca856edc1ebf8b > Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3063944 > Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> > Reviewed-by: Jamie Madill <jmadill@chromium.org> > Reviewed-by: Tim Van Patten <timvp@google.com> Bug: angleproject:4889 Change-Id: I35772f178eb4f6cf2b64bfeb37a4a144acdb4daf Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3067802 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>

  • src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.cpp
  • //
    // 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
    
    ANGLE_NO_DISCARD 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 (int 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);
        }
    }
    
    ANGLE_NO_DISCARD 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