Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/compiler/translator/BuiltInFunctionEmulator.cpp
1693 views
1
//
2
// Copyright 2002 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/BuiltInFunctionEmulator.h"
8
#include "angle_gl.h"
9
#include "compiler/translator/Symbol.h"
10
#include "compiler/translator/tree_util/IntermTraverse.h"
11
12
namespace sh
13
{
14
15
class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTraverser
16
{
17
public:
18
BuiltInFunctionEmulationMarker(BuiltInFunctionEmulator &emulator)
19
: TIntermTraverser(true, false, false), mEmulator(emulator)
20
{}
21
22
bool visitUnary(Visit visit, TIntermUnary *node) override
23
{
24
if (node->getFunction())
25
{
26
bool needToEmulate = mEmulator.setFunctionCalled(node->getFunction());
27
if (needToEmulate)
28
node->setUseEmulatedFunction();
29
}
30
return true;
31
}
32
33
bool visitAggregate(Visit visit, TIntermAggregate *node) override
34
{
35
// Here we handle all the math built-in functions, not just the ones that are currently
36
// identified as problematic.
37
if (!BuiltInGroup::IsMath(node->getOp()))
38
{
39
return true;
40
}
41
bool needToEmulate = mEmulator.setFunctionCalled(node->getFunction());
42
if (needToEmulate)
43
node->setUseEmulatedFunction();
44
return true;
45
}
46
47
private:
48
BuiltInFunctionEmulator &mEmulator;
49
};
50
51
BuiltInFunctionEmulator::BuiltInFunctionEmulator() {}
52
53
void BuiltInFunctionEmulator::addEmulatedFunction(const TSymbolUniqueId &uniqueId,
54
const char *emulatedFunctionDefinition)
55
{
56
mEmulatedFunctions[uniqueId.get()] = std::string(emulatedFunctionDefinition);
57
}
58
59
void BuiltInFunctionEmulator::addEmulatedFunctionWithDependency(
60
const TSymbolUniqueId &dependency,
61
const TSymbolUniqueId &uniqueId,
62
const char *emulatedFunctionDefinition)
63
{
64
mEmulatedFunctions[uniqueId.get()] = std::string(emulatedFunctionDefinition);
65
mFunctionDependencies[uniqueId.get()] = dependency.get();
66
}
67
68
bool BuiltInFunctionEmulator::isOutputEmpty() const
69
{
70
return (mFunctions.size() == 0);
71
}
72
73
void BuiltInFunctionEmulator::outputEmulatedFunctions(TInfoSinkBase &out) const
74
{
75
for (const auto &function : mFunctions)
76
{
77
const char *body = findEmulatedFunction(function);
78
ASSERT(body);
79
out << body;
80
out << "\n\n";
81
}
82
}
83
84
const char *BuiltInFunctionEmulator::findEmulatedFunction(int uniqueId) const
85
{
86
for (const auto &queryFunction : mQueryFunctions)
87
{
88
const char *result = queryFunction(uniqueId);
89
if (result)
90
{
91
return result;
92
}
93
}
94
95
const auto &result = mEmulatedFunctions.find(uniqueId);
96
if (result != mEmulatedFunctions.end())
97
{
98
return result->second.c_str();
99
}
100
101
return nullptr;
102
}
103
104
bool BuiltInFunctionEmulator::setFunctionCalled(const TFunction *function)
105
{
106
ASSERT(function != nullptr);
107
return setFunctionCalled(function->uniqueId().get());
108
}
109
110
bool BuiltInFunctionEmulator::setFunctionCalled(int uniqueId)
111
{
112
if (!findEmulatedFunction(uniqueId))
113
{
114
return false;
115
}
116
117
for (size_t i = 0; i < mFunctions.size(); ++i)
118
{
119
if (mFunctions[i] == uniqueId)
120
return true;
121
}
122
// If the function depends on another, mark the dependency as called.
123
auto dependency = mFunctionDependencies.find(uniqueId);
124
if (dependency != mFunctionDependencies.end())
125
{
126
setFunctionCalled((*dependency).second);
127
}
128
mFunctions.push_back(uniqueId);
129
return true;
130
}
131
132
void BuiltInFunctionEmulator::markBuiltInFunctionsForEmulation(TIntermNode *root)
133
{
134
ASSERT(root);
135
136
if (mEmulatedFunctions.empty() && mQueryFunctions.empty())
137
return;
138
139
BuiltInFunctionEmulationMarker marker(*this);
140
root->traverse(&marker);
141
}
142
143
void BuiltInFunctionEmulator::cleanup()
144
{
145
mFunctions.clear();
146
mFunctionDependencies.clear();
147
}
148
149
void BuiltInFunctionEmulator::addFunctionMap(BuiltinQueryFunc queryFunc)
150
{
151
mQueryFunctions.push_back(queryFunc);
152
}
153
154
// static
155
void BuiltInFunctionEmulator::WriteEmulatedFunctionName(TInfoSinkBase &out, const char *name)
156
{
157
ASSERT(name[strlen(name) - 1] != '(');
158
out << name << "_emu";
159
}
160
161
} // namespace sh
162
163