xref: /aosp_15_r20/external/angle/src/compiler/translator/spirv/BuiltinsWorkaround.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2019 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/spirv/BuiltinsWorkaround.h"
8 
9 #include "angle_gl.h"
10 #include "compiler/translator/Symbol.h"
11 #include "compiler/translator/SymbolTable.h"
12 #include "compiler/translator/tree_util/BuiltIn.h"
13 
14 namespace sh
15 {
16 
17 namespace
18 {
19 constexpr const ImmutableString kGlInstanceIDString("gl_InstanceID");
20 constexpr const ImmutableString kGlVertexIDString("gl_VertexID");
21 
22 class TBuiltinsWorkaround : public TIntermTraverser
23 {
24   public:
25     TBuiltinsWorkaround(TSymbolTable *symbolTable, const ShCompileOptions &options);
26 
27     void visitSymbol(TIntermSymbol *node) override;
28     bool visitDeclaration(Visit, TIntermDeclaration *node) override;
29 
30   private:
31     void ensureVersionIsAtLeast(int version);
32 
33     const ShCompileOptions &mCompileOptions;
34 
35     bool isBaseInstanceDeclared = false;
36 };
37 
TBuiltinsWorkaround(TSymbolTable * symbolTable,const ShCompileOptions & options)38 TBuiltinsWorkaround::TBuiltinsWorkaround(TSymbolTable *symbolTable, const ShCompileOptions &options)
39     : TIntermTraverser(true, false, false, symbolTable), mCompileOptions(options)
40 {}
41 
visitSymbol(TIntermSymbol * node)42 void TBuiltinsWorkaround::visitSymbol(TIntermSymbol *node)
43 {
44     if (node->variable().symbolType() == SymbolType::BuiltIn)
45     {
46         if (node->getName() == kGlInstanceIDString)
47         {
48             TIntermSymbol *instanceIndexRef =
49                 new TIntermSymbol(BuiltInVariable::gl_InstanceIndex());
50 
51             if (isBaseInstanceDeclared)
52             {
53                 TIntermSymbol *baseInstanceRef =
54                     new TIntermSymbol(BuiltInVariable::angle_BaseInstance());
55 
56                 TIntermBinary *subBaseInstance =
57                     new TIntermBinary(EOpSub, instanceIndexRef, baseInstanceRef);
58                 queueReplacement(subBaseInstance, OriginalNode::IS_DROPPED);
59             }
60             else
61             {
62                 queueReplacement(instanceIndexRef, OriginalNode::IS_DROPPED);
63             }
64         }
65         else if (node->getName() == kGlVertexIDString)
66         {
67             TIntermSymbol *vertexIndexRef = new TIntermSymbol(BuiltInVariable::gl_VertexIndex());
68             queueReplacement(vertexIndexRef, OriginalNode::IS_DROPPED);
69         }
70     }
71 }
72 
visitDeclaration(Visit,TIntermDeclaration * node)73 bool TBuiltinsWorkaround::visitDeclaration(Visit, TIntermDeclaration *node)
74 {
75     const TIntermSequence &sequence = *(node->getSequence());
76     ASSERT(!sequence.empty());
77 
78     for (TIntermNode *variableNode : sequence)
79     {
80         TIntermSymbol *variable = variableNode->getAsSymbolNode();
81         if (variable && variable->variable().symbolType() == SymbolType::BuiltIn)
82         {
83             if (variable->getName() == "angle_BaseInstance")
84             {
85                 isBaseInstanceDeclared = true;
86             }
87         }
88     }
89     return true;
90 }
91 
92 }  // anonymous namespace
93 
ShaderBuiltinsWorkaround(TCompiler * compiler,TIntermBlock * root,TSymbolTable * symbolTable,const ShCompileOptions & compileOptions)94 [[nodiscard]] bool ShaderBuiltinsWorkaround(TCompiler *compiler,
95                                             TIntermBlock *root,
96                                             TSymbolTable *symbolTable,
97                                             const ShCompileOptions &compileOptions)
98 {
99     TBuiltinsWorkaround builtins(symbolTable, compileOptions);
100     root->traverse(&builtins);
101     if (!builtins.updateTree(compiler, root))
102     {
103         return false;
104     }
105     return true;
106 }
107 
108 }  // namespace sh
109