1 | // |
2 | // Copyright 2018 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 | // EmulateGLDrawID is an AST traverser to convert the gl_DrawID builtin |
7 | // to a uniform int |
8 | // |
9 | |
10 | #include "compiler/translator/tree_ops/EmulateGLDrawID.h" |
11 | |
12 | #include "angle_gl.h" |
13 | #include "compiler/translator/StaticType.h" |
14 | #include "compiler/translator/Symbol.h" |
15 | #include "compiler/translator/SymbolTable.h" |
16 | #include "compiler/translator/tree_util/BuiltIn_autogen.h" |
17 | #include "compiler/translator/tree_util/IntermTraverse.h" |
18 | #include "compiler/translator/tree_util/ReplaceVariable.h" |
19 | #include "compiler/translator/util.h" |
20 | |
21 | namespace sh |
22 | { |
23 | |
24 | namespace |
25 | { |
26 | |
27 | constexpr const ImmutableString kEmulatedGLDrawIDName("angle_DrawID" ); |
28 | |
29 | class FindGLDrawIDTraverser : public TIntermTraverser |
30 | { |
31 | public: |
32 | FindGLDrawIDTraverser() : TIntermTraverser(true, false, false), mVariable(nullptr) {} |
33 | |
34 | const TVariable *getGLDrawIDBuiltinVariable() { return mVariable; } |
35 | |
36 | protected: |
37 | void visitSymbol(TIntermSymbol *node) override |
38 | { |
39 | if (&node->variable() == BuiltInVariable::gl_DrawID() || |
40 | &node->variable() == BuiltInVariable::gl_DrawIDESSL1()) |
41 | { |
42 | mVariable = &node->variable(); |
43 | } |
44 | } |
45 | |
46 | private: |
47 | const TVariable *mVariable; |
48 | }; |
49 | |
50 | } // namespace |
51 | |
52 | void EmulateGLDrawID(TIntermBlock *root, |
53 | TSymbolTable *symbolTable, |
54 | std::vector<sh::Uniform> *uniforms, |
55 | bool shouldCollect) |
56 | { |
57 | FindGLDrawIDTraverser traverser; |
58 | root->traverse(&traverser); |
59 | const TVariable *builtInVariable = traverser.getGLDrawIDBuiltinVariable(); |
60 | if (builtInVariable) |
61 | { |
62 | const TType *type = StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>(); |
63 | const TVariable *drawID = |
64 | new TVariable(symbolTable, kEmulatedGLDrawIDName, type, SymbolType::AngleInternal); |
65 | |
66 | // AngleInternal variables don't get collected |
67 | if (shouldCollect) |
68 | { |
69 | Uniform uniform; |
70 | uniform.name = kEmulatedGLDrawIDName.data(); |
71 | uniform.mappedName = kEmulatedGLDrawIDName.data(); |
72 | uniform.type = GLVariableType(*type); |
73 | uniform.precision = GLVariablePrecision(*type); |
74 | uniform.staticUse = symbolTable->isStaticallyUsed(*builtInVariable); |
75 | uniform.active = true; |
76 | uniform.binding = type->getLayoutQualifier().binding; |
77 | uniform.location = type->getLayoutQualifier().location; |
78 | uniform.offset = type->getLayoutQualifier().offset; |
79 | uniform.readonly = type->getMemoryQualifier().readonly; |
80 | uniform.writeonly = type->getMemoryQualifier().writeonly; |
81 | uniforms->push_back(uniform); |
82 | } |
83 | |
84 | DeclareGlobalVariable(root, drawID); |
85 | ReplaceVariable(root, builtInVariable, drawID); |
86 | } |
87 | } |
88 | |
89 | } // namespace sh |
90 | |