Edit

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

Branch :

  • Show log

    Commit

  • Author : Shahbaz Youssefi
    Date : 2021-04-09 12:29:22
    Hash : 1f8e35b5
    Message : Remove EvqBaseVertex and EvqBaseInstance qualifiers They are only used to mark angle_BaseVertex and angle_BaseInstance uniforms, but they make it complicated for the rest of the code to identify them as uniforms. Bug: angleproject:4889 Change-Id: I0c632bb595dc9a7fcda19db11ecb27539b1c33e6 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2818144 Reviewed-by: Tim Van Patten <timvp@google.com> Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>

  • src/compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.cpp
  • //
    // Copyright 2019 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.
    //
    // EmulateGLDrawID is an AST traverser to convert the gl_DrawID builtin
    // to a uniform int
    //
    // EmulateGLBaseVertex is an AST traverser to convert the gl_BaseVertex builtin
    // to a uniform int
    //
    // EmulateGLBaseInstance is an AST traverser to convert the gl_BaseInstance builtin
    // to a uniform int
    //
    
    #include "compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.h"
    
    #include "angle_gl.h"
    #include "compiler/translator/StaticType.h"
    #include "compiler/translator/Symbol.h"
    #include "compiler/translator/SymbolTable.h"
    #include "compiler/translator/tree_util/BuiltIn.h"
    #include "compiler/translator/tree_util/IntermTraverse.h"
    #include "compiler/translator/tree_util/ReplaceVariable.h"
    #include "compiler/translator/util.h"
    
    namespace sh
    {
    
    namespace
    {
    
    constexpr const ImmutableString kEmulatedGLDrawIDName("angle_DrawID");
    
    class FindGLDrawIDTraverser : public TIntermTraverser
    {
      public:
        FindGLDrawIDTraverser() : TIntermTraverser(true, false, false), mVariable(nullptr) {}
    
        const TVariable *getGLDrawIDBuiltinVariable() { return mVariable; }
    
      protected:
        void visitSymbol(TIntermSymbol *node) override
        {
            if (&node->variable() == BuiltInVariable::gl_DrawID())
            {
                mVariable = &node->variable();
            }
        }
    
      private:
        const TVariable *mVariable;
    };
    
    class AddBaseVertexToGLVertexIDTraverser : public TIntermTraverser
    {
      public:
        AddBaseVertexToGLVertexIDTraverser() : TIntermTraverser(true, false, false) {}
    
      protected:
        void visitSymbol(TIntermSymbol *node) override
        {
            if (&node->variable() == BuiltInVariable::gl_VertexID())
            {
    
                TIntermSymbol *baseVertexRef = new TIntermSymbol(BuiltInVariable::gl_BaseVertex());
    
                TIntermBinary *addBaseVertex = new TIntermBinary(EOpAdd, node, baseVertexRef);
                queueReplacement(addBaseVertex, OriginalNode::BECOMES_CHILD);
            }
        }
    };
    
    constexpr const ImmutableString kEmulatedGLBaseVertexName("angle_BaseVertex");
    
    class FindGLBaseVertexTraverser : public TIntermTraverser
    {
      public:
        FindGLBaseVertexTraverser() : TIntermTraverser(true, false, false), mVariable(nullptr) {}
    
        const TVariable *getGLBaseVertexBuiltinVariable() { return mVariable; }
    
      protected:
        void visitSymbol(TIntermSymbol *node) override
        {
            if (&node->variable() == BuiltInVariable::gl_BaseVertex())
            {
                mVariable = &node->variable();
            }
        }
    
      private:
        const TVariable *mVariable;
    };
    
    constexpr const ImmutableString kEmulatedGLBaseInstanceName("angle_BaseInstance");
    
    class FindGLBaseInstanceTraverser : public TIntermTraverser
    {
      public:
        FindGLBaseInstanceTraverser() : TIntermTraverser(true, false, false), mVariable(nullptr) {}
    
        const TVariable *getGLBaseInstanceBuiltinVariable() { return mVariable; }
    
      protected:
        void visitSymbol(TIntermSymbol *node) override
        {
            if (&node->variable() == BuiltInVariable::gl_BaseInstance())
            {
                mVariable = &node->variable();
            }
        }
    
      private:
        const TVariable *mVariable;
    };
    
    }  // namespace
    
    bool EmulateGLDrawID(TCompiler *compiler,
                         TIntermBlock *root,
                         TSymbolTable *symbolTable,
                         std::vector<sh::ShaderVariable> *uniforms,
                         bool shouldCollect)
    {
        FindGLDrawIDTraverser traverser;
        root->traverse(&traverser);
        const TVariable *builtInVariable = traverser.getGLDrawIDBuiltinVariable();
        if (builtInVariable)
        {
            const TType *type = StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>();
            const TVariable *drawID =
                new TVariable(symbolTable, kEmulatedGLDrawIDName, type, SymbolType::AngleInternal);
            const TIntermSymbol *drawIDSymbol = new TIntermSymbol(drawID);
    
            // AngleInternal variables don't get collected
            if (shouldCollect)
            {
                ShaderVariable uniform;
                uniform.name       = kEmulatedGLDrawIDName.data();
                uniform.mappedName = kEmulatedGLDrawIDName.data();
                uniform.type       = GLVariableType(*type);
                uniform.precision  = GLVariablePrecision(*type);
                uniform.staticUse  = symbolTable->isStaticallyUsed(*builtInVariable);
                uniform.active     = true;
                uniform.binding    = type->getLayoutQualifier().binding;
                uniform.location   = type->getLayoutQualifier().location;
                uniform.offset     = type->getLayoutQualifier().offset;
                uniform.readonly   = type->getMemoryQualifier().readonly;
                uniform.writeonly  = type->getMemoryQualifier().writeonly;
                uniforms->push_back(uniform);
            }
    
            DeclareGlobalVariable(root, drawID);
            if (!ReplaceVariableWithTyped(compiler, root, builtInVariable, drawIDSymbol))
            {
                return false;
            }
        }
    
        return true;
    }
    
    bool EmulateGLBaseVertexBaseInstance(TCompiler *compiler,
                                         TIntermBlock *root,
                                         TSymbolTable *symbolTable,
                                         std::vector<sh::ShaderVariable> *uniforms,
                                         bool shouldCollect,
                                         bool addBaseVertexToVertexID)
    {
        bool addBaseVertex = false, addBaseInstance = false;
        ShaderVariable uniformBaseVertex, uniformBaseInstance;
    
        if (addBaseVertexToVertexID)
        {
            // This is a workaround for Mac AMD GPU
            // Replace gl_VertexID with (gl_VertexID + gl_BaseVertex)
            AddBaseVertexToGLVertexIDTraverser traverserVertexID;
            root->traverse(&traverserVertexID);
            if (!traverserVertexID.updateTree(compiler, root))
            {
                return false;
            }
        }
    
        FindGLBaseVertexTraverser traverserBaseVertex;
        root->traverse(&traverserBaseVertex);
        const TVariable *builtInVariableBaseVertex =
            traverserBaseVertex.getGLBaseVertexBuiltinVariable();
    
        if (builtInVariableBaseVertex)
        {
            const TVariable *baseVertex           = BuiltInVariable::angle_BaseVertex();
            const TType &type                     = baseVertex->getType();
            const TIntermSymbol *baseVertexSymbol = new TIntermSymbol(baseVertex);
    
            // AngleInternal variables don't get collected
            if (shouldCollect)
            {
                uniformBaseVertex.name       = kEmulatedGLBaseVertexName.data();
                uniformBaseVertex.mappedName = kEmulatedGLBaseVertexName.data();
                uniformBaseVertex.type       = GLVariableType(type);
                uniformBaseVertex.precision  = GLVariablePrecision(type);
                uniformBaseVertex.staticUse = symbolTable->isStaticallyUsed(*builtInVariableBaseVertex);
                uniformBaseVertex.active    = true;
                uniformBaseVertex.binding   = type.getLayoutQualifier().binding;
                uniformBaseVertex.location  = type.getLayoutQualifier().location;
                uniformBaseVertex.offset    = type.getLayoutQualifier().offset;
                uniformBaseVertex.readonly  = type.getMemoryQualifier().readonly;
                uniformBaseVertex.writeonly = type.getMemoryQualifier().writeonly;
                addBaseVertex               = true;
            }
    
            DeclareGlobalVariable(root, baseVertex);
            if (!ReplaceVariableWithTyped(compiler, root, builtInVariableBaseVertex, baseVertexSymbol))
            {
                return false;
            }
        }
    
        FindGLBaseInstanceTraverser traverserInstance;
        root->traverse(&traverserInstance);
        const TVariable *builtInVariableBaseInstance =
            traverserInstance.getGLBaseInstanceBuiltinVariable();
    
        if (builtInVariableBaseInstance)
        {
            const TVariable *baseInstance           = BuiltInVariable::angle_BaseInstance();
            const TType &type                       = baseInstance->getType();
            const TIntermSymbol *baseInstanceSymbol = new TIntermSymbol(baseInstance);
    
            // AngleInternal variables don't get collected
            if (shouldCollect)
            {
                uniformBaseInstance.name       = kEmulatedGLBaseInstanceName.data();
                uniformBaseInstance.mappedName = kEmulatedGLBaseInstanceName.data();
                uniformBaseInstance.type       = GLVariableType(type);
                uniformBaseInstance.precision  = GLVariablePrecision(type);
                uniformBaseInstance.staticUse =
                    symbolTable->isStaticallyUsed(*builtInVariableBaseInstance);
                uniformBaseInstance.active    = true;
                uniformBaseInstance.binding   = type.getLayoutQualifier().binding;
                uniformBaseInstance.location  = type.getLayoutQualifier().location;
                uniformBaseInstance.offset    = type.getLayoutQualifier().offset;
                uniformBaseInstance.readonly  = type.getMemoryQualifier().readonly;
                uniformBaseInstance.writeonly = type.getMemoryQualifier().writeonly;
                addBaseInstance               = true;
            }
    
            DeclareGlobalVariable(root, baseInstance);
            if (!ReplaceVariableWithTyped(compiler, root, builtInVariableBaseInstance,
                                          baseInstanceSymbol))
            {
                return false;
            }
        }
    
        // Make sure the order in uniforms is the same as the traverse order
        if (addBaseInstance)
        {
            uniforms->push_back(uniformBaseInstance);
        }
        if (addBaseVertex)
        {
            uniforms->push_back(uniformBaseVertex);
        }
    
        return true;
    }
    
    }  // namespace sh