• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2020 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 #include "compiler/translator/TranslatorMetalDirect/IntroduceVertexIndexID.h"
8 #include "compiler/translator/StaticType.h"
9 #include "compiler/translator/TranslatorMetalDirect/AstHelpers.h"
10 #include "compiler/translator/TranslatorMetalDirect/IntermRebuild.h"
11 #include "compiler/translator/tree_util/BuiltIn.h"
12 using namespace sh;
13 
14 ////////////////////////////////////////////////////////////////////////////////
15 
16 namespace
17 {
18 
19 constexpr const TVariable kgl_VertexIDMetal(BuiltInId::gl_VertexID,
20                                             ImmutableString("gl_VertexID"),
21                                             SymbolType::BuiltIn,
22                                             TExtension::UNDEFINED,
23                                             StaticType::Get<EbtUInt, EbpHigh, EvqVertexID, 1, 1>());
24 
25 constexpr const TVariable kgl_instanceIdMetal(
26     BuiltInId::gl_VertexID,
27     ImmutableString("instanceIdMod"),
28     SymbolType::AngleInternal,
29     TExtension::UNDEFINED,
30     StaticType::Get<EbtUInt, EbpHigh, EvqInstanceID, 1, 1>());
31 
32 class Rewriter : public TIntermRebuild
33 {
34   public:
Rewriter(TCompiler & compiler)35     Rewriter(TCompiler &compiler) : TIntermRebuild(compiler, true, true) {}
36 
37   private:
visitFunctionDefinitionPre(TIntermFunctionDefinition & node)38     PreResult visitFunctionDefinitionPre(TIntermFunctionDefinition &node) override
39     {
40         if (node.getFunction()->isMain())
41         {
42             const TFunction *mainFunction = node.getFunction();
43             bool needsVertexId            = true;
44             bool needsInstanceId          = true;
45             std::vector<const TVariable *> mVariablesToIntroduce;
46             for (size_t i = 0; i < mainFunction->getParamCount(); ++i)
47             {
48                 const TVariable *param = mainFunction->getParam(i);
49                 Name instanceIDName =
50                     Pipeline{Pipeline::Type::InstanceId, nullptr}.getStructInstanceName(
51                         Pipeline::Variant::Modified);
52                 if (Name(*param) == instanceIDName)
53                 {
54                     needsInstanceId = false;
55                 }
56                 else if (param->getType().getQualifier() == TQualifier::EvqVertexID)
57                 {
58                     needsVertexId = false;
59                 }
60             }
61             if (needsInstanceId)
62             {
63                 mVariablesToIntroduce.push_back(&kgl_instanceIdMetal);
64             }
65             if (needsVertexId)
66             {
67                 mVariablesToIntroduce.push_back(&kgl_VertexIDMetal);
68             }
69             const TFunction &newFunction = CloneFunctionAndAppendParams(
70                 mSymbolTable, nullptr, *node.getFunction(), mVariablesToIntroduce);
71             TIntermFunctionPrototype *newProto = new TIntermFunctionPrototype(&newFunction);
72             return new TIntermFunctionDefinition(newProto, node.getBody());
73         }
74         return node;
75     }
76 };
77 
78 }  // anonymous namespace
79 
80 ////////////////////////////////////////////////////////////////////////////////
81 
IntroduceVertexAndInstanceIndex(TCompiler & compiler,TIntermBlock & root)82 bool sh::IntroduceVertexAndInstanceIndex(TCompiler &compiler, TIntermBlock &root)
83 {
84     if (!Rewriter(compiler).rebuildRoot(root))
85     {
86         return false;
87     }
88     return true;
89 }
90