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
21namespace sh
22{
23
24namespace
25{
26
27constexpr const ImmutableString kEmulatedGLDrawIDName("angle_DrawID");
28
29class 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
52void 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