Edit

kc3-lang/angle/src/compiler/translator/TranslatorMetalDirect/NameEmbeddedUniformStructsMetal.cpp

Branch :

  • Show log

    Commit

  • Author : Kyle Piddington
    Date : 2021-04-26 16:56:15
    Hash : d7aa0130
    Message : Upstream Apple's direct-to-Metal backend: compile translator. This change is meant to merge the translator changes from Apple's direct-to-Metal backend. Taken from Kyle Piddington's CL: https://chromium-review.googlesource.com/c/angle/angle/+/2857366/ The goal of this CL is to merge the translator code in a state that compiles, but not to switch the Metal backend over to use this translator backend yet. Bug: angleproject:5505 Change-Id: I68a6354604498cd5fd1eb96c13fc56f3b38f2bd0 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2897536 Reviewed-by: Jonah Ryan-Davis <jonahr@google.com> Commit-Queue: Jonah Ryan-Davis <jonahr@google.com>

  • src/compiler/translator/TranslatorMetalDirect/NameEmbeddedUniformStructsMetal.cpp
  • //
    // Copyright 2018 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.
    //
    // NameEmbeddedUniformStructsMetal: Gives nameless uniform struct internal names.
    //
    
    #include "compiler/translator/TranslatorMetalDirect/NameEmbeddedUniformStructsMetal.h"
    
    #include "compiler/translator/SymbolTable.h"
    #include "compiler/translator/tree_util/IntermTraverse.h"
    
    namespace sh
    {
    namespace
    {
    // This traverser translates embedded uniform structs into a specifier and declaration.
    // This makes the declarations easier to move into uniform blocks.
    class Traverser : public TIntermTraverser
    {
    
      public:
        std::unordered_map<int, TIntermSymbol *> replacements;
        explicit Traverser(TSymbolTable *symbolTable)
            : TIntermTraverser(true, false, false, symbolTable)
        {}
    
        bool visitDeclaration(Visit visit, TIntermDeclaration *decl) override
        {
            ASSERT(visit == PreVisit);
    
            if (!mInGlobalScope)
            {
                return false;
            }
    
            const TIntermSequence &sequence = *(decl->getSequence());
            ASSERT(sequence.size() == 1);
            TIntermTyped *declarator = sequence.front()->getAsTyped();
            const TType &type        = declarator->getType();
    
            if (type.isStructSpecifier() && type.getQualifier() == EvqUniform)
            {
                const TStructure *structure = type.getStruct();
    
                if (structure->symbolType() == SymbolType::Empty)
                {
                    doReplacement(decl, declarator, structure);
                }
            }
    
            return false;
        }
        void visitSymbol(TIntermSymbol *decl) override
        {
            auto symbol = replacements.find(decl->uniqueId().get());
            if (symbol != replacements.end())
            {
                queueReplacement(symbol->second->deepCopy(), OriginalNode::IS_DROPPED);
            }
        }
    
      private:
        void doReplacement(TIntermDeclaration *decl,
                           TIntermTyped *declarator,
                           const TStructure *oldStructure)
        {
            // struct <structName> { ... };
            TStructure *structure = new TStructure(mSymbolTable, kEmptyImmutableString,
                                                   &oldStructure->fields(), SymbolType::AngleInternal);
            TType *namedType      = new TType(structure, true);
            namedType->setQualifier(EvqGlobal);
    
            TVariable *structVariable =
                new TVariable(mSymbolTable, kEmptyImmutableString, namedType, SymbolType::Empty);
            TIntermSymbol *structDeclarator       = new TIntermSymbol(structVariable);
            TIntermDeclaration *structDeclaration = new TIntermDeclaration;
            structDeclaration->appendDeclarator(structDeclarator);
    
            TIntermSequence *newSequence = new TIntermSequence;
            newSequence->push_back(structDeclaration);
    
            // uniform <structName> <structUniformName>;
            TIntermSymbol *asSymbol = declarator->getAsSymbolNode();
            if (asSymbol && asSymbol->variable().symbolType() != SymbolType::Empty)
            {
                TIntermDeclaration *namedDecl = new TIntermDeclaration;
                TType *uniformType            = new TType(structure, false);
                uniformType->setQualifier(EvqUniform);
    
                TVariable *newVar        = new TVariable(mSymbolTable, asSymbol->getName(), uniformType,
                                                  asSymbol->variable().symbolType());
                TIntermSymbol *newSymbol = new TIntermSymbol(newVar);
                replacements[asSymbol->uniqueId().get()] = newSymbol;
                namedDecl->appendDeclarator(newSymbol);
    
                newSequence->push_back(namedDecl);
            }
    
            mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), decl,
                                            std::move(*newSequence));
        }
    };
    }  // anonymous namespace
    
    bool NameEmbeddedStructUniformsMetal(TCompiler *compiler,
                                         TIntermBlock *root,
                                         TSymbolTable *symbolTable)
    {
        Traverser nameStructs(symbolTable);
        root->traverse(&nameStructs);
        return nameStructs.updateTree(compiler, root);
    }
    }  // namespace sh