Path: blob/main_old/src/compiler/translator/BuiltInFunctionEmulator.cpp
1693 views
//1// Copyright 2002 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56#include "compiler/translator/BuiltInFunctionEmulator.h"7#include "angle_gl.h"8#include "compiler/translator/Symbol.h"9#include "compiler/translator/tree_util/IntermTraverse.h"1011namespace sh12{1314class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTraverser15{16public:17BuiltInFunctionEmulationMarker(BuiltInFunctionEmulator &emulator)18: TIntermTraverser(true, false, false), mEmulator(emulator)19{}2021bool visitUnary(Visit visit, TIntermUnary *node) override22{23if (node->getFunction())24{25bool needToEmulate = mEmulator.setFunctionCalled(node->getFunction());26if (needToEmulate)27node->setUseEmulatedFunction();28}29return true;30}3132bool visitAggregate(Visit visit, TIntermAggregate *node) override33{34// Here we handle all the math built-in functions, not just the ones that are currently35// identified as problematic.36if (!BuiltInGroup::IsMath(node->getOp()))37{38return true;39}40bool needToEmulate = mEmulator.setFunctionCalled(node->getFunction());41if (needToEmulate)42node->setUseEmulatedFunction();43return true;44}4546private:47BuiltInFunctionEmulator &mEmulator;48};4950BuiltInFunctionEmulator::BuiltInFunctionEmulator() {}5152void BuiltInFunctionEmulator::addEmulatedFunction(const TSymbolUniqueId &uniqueId,53const char *emulatedFunctionDefinition)54{55mEmulatedFunctions[uniqueId.get()] = std::string(emulatedFunctionDefinition);56}5758void BuiltInFunctionEmulator::addEmulatedFunctionWithDependency(59const TSymbolUniqueId &dependency,60const TSymbolUniqueId &uniqueId,61const char *emulatedFunctionDefinition)62{63mEmulatedFunctions[uniqueId.get()] = std::string(emulatedFunctionDefinition);64mFunctionDependencies[uniqueId.get()] = dependency.get();65}6667bool BuiltInFunctionEmulator::isOutputEmpty() const68{69return (mFunctions.size() == 0);70}7172void BuiltInFunctionEmulator::outputEmulatedFunctions(TInfoSinkBase &out) const73{74for (const auto &function : mFunctions)75{76const char *body = findEmulatedFunction(function);77ASSERT(body);78out << body;79out << "\n\n";80}81}8283const char *BuiltInFunctionEmulator::findEmulatedFunction(int uniqueId) const84{85for (const auto &queryFunction : mQueryFunctions)86{87const char *result = queryFunction(uniqueId);88if (result)89{90return result;91}92}9394const auto &result = mEmulatedFunctions.find(uniqueId);95if (result != mEmulatedFunctions.end())96{97return result->second.c_str();98}99100return nullptr;101}102103bool BuiltInFunctionEmulator::setFunctionCalled(const TFunction *function)104{105ASSERT(function != nullptr);106return setFunctionCalled(function->uniqueId().get());107}108109bool BuiltInFunctionEmulator::setFunctionCalled(int uniqueId)110{111if (!findEmulatedFunction(uniqueId))112{113return false;114}115116for (size_t i = 0; i < mFunctions.size(); ++i)117{118if (mFunctions[i] == uniqueId)119return true;120}121// If the function depends on another, mark the dependency as called.122auto dependency = mFunctionDependencies.find(uniqueId);123if (dependency != mFunctionDependencies.end())124{125setFunctionCalled((*dependency).second);126}127mFunctions.push_back(uniqueId);128return true;129}130131void BuiltInFunctionEmulator::markBuiltInFunctionsForEmulation(TIntermNode *root)132{133ASSERT(root);134135if (mEmulatedFunctions.empty() && mQueryFunctions.empty())136return;137138BuiltInFunctionEmulationMarker marker(*this);139root->traverse(&marker);140}141142void BuiltInFunctionEmulator::cleanup()143{144mFunctions.clear();145mFunctionDependencies.clear();146}147148void BuiltInFunctionEmulator::addFunctionMap(BuiltinQueryFunc queryFunc)149{150mQueryFunctions.push_back(queryFunc);151}152153// static154void BuiltInFunctionEmulator::WriteEmulatedFunctionName(TInfoSinkBase &out, const char *name)155{156ASSERT(name[strlen(name) - 1] != '(');157out << name << "_emu";158}159160} // namespace sh161162163