Edit

kc3-lang/angle/src/compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.cpp

Branch :

  • Show log

    Commit

  • Author : Kenneth Russell
    Date : 2021-07-28 00:36:12
    Hash : aec5e65c
    Message : Get direct-to-Metal backend to run angle_end2end_tests. Cherry-pick nameless struct fix from Apple in https://bugs.webkit.org/show_bug.cgi?id=227482 . Fix SeparateCompoundStructDeclarations pass to stop generating multiple declarations; thanks syoussefi@ for advice. Incorporate additional passes from TranslatorVulkan (MonomorphizeUnsupportedFunctionsInVulkanGLSL, RewriteArrayOfArrayOfOpaqueUniforms, SeparateStructFromUniformDeclarations) needed by RewriteStructSamplers pass in TranslatorMetalDirect. Fixes many assertion failures in GLSL tests. Moved these passes out of tree_ops/vulkan. Thanks again to syoussefi@ for advice and help. Disable a validation check related to the RewritePipelines pass. Skip two tests that were failing for other reasons. With these changes, angle_end2end_tests runs to completion when the direct-to-Metal backend is turned on. There are still ~1300 failures of the ~4000 tests which will be investigated next. Bug: angleproject:5505 Change-Id: Ibca77822543e8e8e8d2a8c862e92cdf74bfa3545 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3058524 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Kenneth Russell <kbr@chromium.org>

  • src/compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.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.
    //
    // SeparateStructFromUniformDeclarations: Separate struct declarations from uniform declarations.
    //
    
    #include "compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.h"
    
    #include "compiler/translator/SymbolTable.h"
    #include "compiler/translator/tree_util/IntermTraverse.h"
    #include "compiler/translator/tree_util/ReplaceVariable.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:
        explicit Traverser(TSymbolTable *symbolTable)
            : TIntermTraverser(true, false, false, symbolTable)
        {}
    
        bool visitDeclaration(Visit visit, TIntermDeclaration *decl) override
        {
            ASSERT(visit == PreVisit);
    
            if (!mInGlobalScope)
            {
                return true;
            }
    
            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)
            {
                doReplacement(decl, declarator, type);
                return false;
            }
    
            return true;
        }
    
        void visitSymbol(TIntermSymbol *symbol) override
        {
            const TVariable *variable = &symbol->variable();
            if (mVariableMap.count(variable) > 0)
            {
                queueReplacement(mVariableMap[variable]->deepCopy(), OriginalNode::IS_DROPPED);
            }
        }
    
      private:
        void doReplacement(TIntermDeclaration *decl, TIntermTyped *declarator, const TType &oldType)
        {
            const TStructure *structure = oldType.getStruct();
            if (structure->symbolType() == SymbolType::Empty)
            {
                // Handle nameless structs: uniform struct { ... } variable;
                structure = new TStructure(mSymbolTable, kEmptyImmutableString, &structure->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;
            newSequence.push_back(structDeclaration);
    
            // Redeclare the uniform with the (potentially) new struct type
            TIntermSymbol *asSymbol = declarator->getAsSymbolNode();
            ASSERT(asSymbol && asSymbol->variable().symbolType() != SymbolType::Empty);
    
            TIntermDeclaration *namedDecl = new TIntermDeclaration;
            TType *uniformType            = new TType(structure, false);
            uniformType->setQualifier(EvqUniform);
            uniformType->makeArrays(oldType.getArraySizes());
    
            TVariable *newVar        = new TVariable(mSymbolTable, asSymbol->getName(), uniformType,
                                              asSymbol->variable().symbolType());
            TIntermSymbol *newSymbol = new TIntermSymbol(newVar);
            namedDecl->appendDeclarator(newSymbol);
    
            newSequence.push_back(namedDecl);
    
            mVariableMap[&asSymbol->variable()] = newSymbol;
    
            mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), decl,
                                            std::move(newSequence));
        }
    
        VariableReplacementMap mVariableMap;
    };
    }  // anonymous namespace
    
    bool SeparateStructFromUniformDeclarations(TCompiler *compiler,
                                               TIntermBlock *root,
                                               TSymbolTable *symbolTable)
    {
        Traverser separateStructDecls(symbolTable);
        root->traverse(&separateStructDecls);
        return separateStructDecls.updateTree(compiler, root);
    }
    }  // namespace sh