xref: /aosp_15_r20/external/angle/src/compiler/translator/tree_ops/msl/IntroduceVertexIndexID.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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/tree_ops/msl/IntroduceVertexIndexID.h"
8 #include "compiler/translator/IntermRebuild.h"
9 #include "compiler/translator/StaticType.h"
10 #include "compiler/translator/msl/AstHelpers.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("vertexIDMetal"),
21                                             SymbolType::AngleInternal,
22                                             TExtension::UNDEFINED,
23                                             StaticType::Get<EbtUInt, EbpHigh, EvqVertexID, 1, 1>());
24 
25 constexpr const TVariable kgl_instanceIdMetal(
26     BuiltInId::gl_InstanceID,
27     ImmutableString("instanceIdMod"),
28     SymbolType::AngleInternal,
29     TExtension::UNDEFINED,
30     StaticType::Get<EbtUInt, EbpHigh, EvqInstanceID, 1, 1>());
31 
32 constexpr const TVariable kgl_baseInstanceMetal(
33     BuiltInId::gl_BaseInstance,
34     ImmutableString("baseInstance"),
35     SymbolType::AngleInternal,
36     TExtension::UNDEFINED,
37     StaticType::Get<EbtUInt, EbpHigh, EvqInstanceID, 1, 1>());
38 
39 class Rewriter : public TIntermRebuild
40 {
41   public:
Rewriter(TCompiler & compiler)42     Rewriter(TCompiler &compiler) : TIntermRebuild(compiler, true, true) {}
43 
44   private:
visitFunctionDefinitionPre(TIntermFunctionDefinition & node)45     PreResult visitFunctionDefinitionPre(TIntermFunctionDefinition &node) override
46     {
47         if (node.getFunction()->isMain())
48         {
49             const TFunction *mainFunction = node.getFunction();
50             bool needsVertexId            = true;
51             bool needsInstanceId          = true;
52             std::vector<const TVariable *> mVariablesToIntroduce;
53             for (size_t i = 0; i < mainFunction->getParamCount(); ++i)
54             {
55                 const TVariable *param = mainFunction->getParam(i);
56                 Name instanceIDName =
57                     Pipeline{Pipeline::Type::InstanceId, nullptr}.getStructInstanceName(
58                         Pipeline::Variant::Modified);
59                 if (Name(*param) == instanceIDName)
60                 {
61                     needsInstanceId = false;
62                 }
63                 else if (param->getType().getQualifier() == TQualifier::EvqVertexID)
64                 {
65                     needsVertexId = false;
66                 }
67             }
68             if (needsInstanceId)
69             {
70                 // Ensure these variables are present because they are required for XFB emulation.
71                 mVariablesToIntroduce.push_back(&kgl_instanceIdMetal);
72                 mVariablesToIntroduce.push_back(&kgl_baseInstanceMetal);
73             }
74             if (needsVertexId)
75             {
76                 mVariablesToIntroduce.push_back(&kgl_VertexIDMetal);
77             }
78             const TFunction &newFunction = CloneFunctionAndAppendParams(
79                 mSymbolTable, nullptr, *node.getFunction(), mVariablesToIntroduce);
80             TIntermFunctionPrototype *newProto = new TIntermFunctionPrototype(&newFunction);
81             return new TIntermFunctionDefinition(newProto, node.getBody());
82         }
83         return node;
84     }
85 };
86 
87 }  // anonymous namespace
88 
89 ////////////////////////////////////////////////////////////////////////////////
90 
IntroduceVertexAndInstanceIndex(TCompiler & compiler,TIntermBlock & root)91 bool sh::IntroduceVertexAndInstanceIndex(TCompiler &compiler, TIntermBlock &root)
92 {
93     if (!Rewriter(compiler).rebuildRoot(root))
94     {
95         return false;
96     }
97     return true;
98 }
99