Commit 5fec7ab2 by Olli Etuaho Committed by Commit Bot

Identify functions by unique id in BuiltInFunctionEmulator

Now that unique ids of all builtins are compile-time constants, we can use them to look up functions in BuiltInFunctionEmulator. This is simpler than using a custom struct with the name and parameters for identifying functions. This requires that we store a reference to a TFunction in those TIntermUnary nodes that were created based on a function. This decreases shader_translator binary size by about 6 KB on Windows. BUG=angleproject:2267 BUG=chromium:823856 TEST=angle_unittests Change-Id: Idd5a00c772c6f26dd36fdbbfbe161d22ab27c2fe Reviewed-on: https://chromium-review.googlesource.com/995372Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent f3614370
...@@ -156,6 +156,15 @@ generators = { ...@@ -156,6 +156,15 @@ generators = {
], ],
'script': 'src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py', 'script': 'src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py',
}, },
'Emulated HLSL functions': {
'inputs': [
'src/compiler/translator/emulated_builtin_function_data_hlsl.json'
],
'outputs': [
'src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp'
],
'script': 'src/compiler/translator/gen_emulated_builtin_function_tables.py'
},
'ESSL static builtins': { 'ESSL static builtins': {
'inputs': [ 'inputs': [
'src/compiler/translator/builtin_function_declarations.txt', 'src/compiler/translator/builtin_function_declarations.txt',
......
...@@ -68,7 +68,6 @@ ...@@ -68,7 +68,6 @@
'compiler/translator/Operator.h', 'compiler/translator/Operator.h',
'compiler/translator/OutputTree.cpp', 'compiler/translator/OutputTree.cpp',
'compiler/translator/OutputTree.h', 'compiler/translator/OutputTree.h',
'compiler/translator/ParamType.h',
'compiler/translator/ParseContext.cpp', 'compiler/translator/ParseContext.cpp',
'compiler/translator/ParseContext.h', 'compiler/translator/ParseContext.h',
'compiler/translator/ParseContext_autogen.h', 'compiler/translator/ParseContext_autogen.h',
......
...@@ -8,82 +8,15 @@ ...@@ -8,82 +8,15 @@
#define COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_ #define COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
#include "compiler/translator/InfoSink.h" #include "compiler/translator/InfoSink.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/ParamType.h"
namespace sh namespace sh
{ {
struct MiniFunctionId class TIntermNode;
{ class TFunction;
constexpr MiniFunctionId(TOperator op = EOpNull, class TSymbolUniqueId;
ParamType paramType1 = ParamType::Void,
ParamType paramType2 = ParamType::Void,
ParamType paramType3 = ParamType::Void,
ParamType paramType4 = ParamType::Void)
: op(op),
paramType1(paramType1),
paramType2(paramType2),
paramType3(paramType3),
paramType4(paramType4)
{
}
TOperator op;
ParamType paramType1;
ParamType paramType2;
ParamType paramType3;
ParamType paramType4;
};
class FunctionId final
{
public:
FunctionId();
FunctionId(TOperator op, const TType *param);
FunctionId(TOperator op, const TType *param1, const TType *param2);
FunctionId(TOperator op, const TType *param1, const TType *param2, const TType *param3);
FunctionId(TOperator op,
const TType *param1,
const TType *param2,
const TType *param3,
const TType *param4);
FunctionId(const FunctionId &) = default; using BuiltinQueryFunc = const char *(int);
FunctionId &operator=(const FunctionId &) = default;
bool operator==(const FunctionId &other) const;
bool operator<(const FunctionId &other) const;
FunctionId getCopy() const;
private:
friend bool operator==(const MiniFunctionId &miniId, const FunctionId &functionId);
TOperator mOp;
// The memory that these TType objects use is freed by PoolAllocator. The
// BuiltInFunctionEmulator's lifetime can extend until after the memory pool is freed, but
// that's not an issue since this class never destructs these objects.
const TType *mParam1;
const TType *mParam2;
const TType *mParam3;
const TType *mParam4;
};
inline bool operator==(ParamType paramType, const TType *type)
{
return SameParamType(paramType, type->getBasicType(), type->getNominalSize(),
type->getSecondarySize());
}
inline bool operator==(const MiniFunctionId &miniId, const FunctionId &functionId)
{
return miniId.op == functionId.mOp && miniId.paramType1 == functionId.mParam1 &&
miniId.paramType2 == functionId.mParam2 && miniId.paramType3 == functionId.mParam3 &&
miniId.paramType4 == functionId.mParam4;
}
using BuiltinQueryFunc = const char *(const FunctionId &);
// //
// This class decides which built-in functions need to be replaced with the emulated ones. It can be // This class decides which built-in functions need to be replaced with the emulated ones. It can be
...@@ -108,37 +41,12 @@ class BuiltInFunctionEmulator ...@@ -108,37 +41,12 @@ class BuiltInFunctionEmulator
void outputEmulatedFunctions(TInfoSinkBase &out) const; void outputEmulatedFunctions(TInfoSinkBase &out) const;
// Add functions that need to be emulated. // Add functions that need to be emulated.
FunctionId addEmulatedFunction(TOperator op, void addEmulatedFunction(const TSymbolUniqueId &uniqueId,
const TType *param, const char *emulatedFunctionDefinition);
const char *emulatedFunctionDefinition);
FunctionId addEmulatedFunction(TOperator op, void addEmulatedFunctionWithDependency(const TSymbolUniqueId &dependency,
const TType *param1, const TSymbolUniqueId &uniqueId,
const TType *param2, const char *emulatedFunctionDefinition);
const char *emulatedFunctionDefinition);
FunctionId addEmulatedFunction(TOperator op,
const TType *param1,
const TType *param2,
const TType *param3,
const char *emulatedFunctionDefinition);
FunctionId addEmulatedFunction(TOperator op,
const TType *param1,
const TType *param2,
const TType *param3,
const TType *param4,
const char *emulatedFunctionDefinition);
FunctionId addEmulatedFunctionWithDependency(const FunctionId &dependency,
TOperator op,
const TType *param1,
const TType *param2,
const char *emulatedFunctionDefinition);
FunctionId addEmulatedFunctionWithDependency(const FunctionId &dependency,
TOperator op,
const TType *param1,
const TType *param2,
const TType *param3,
const TType *param4,
const char *emulatedFunctionDefinition);
void addFunctionMap(BuiltinQueryFunc queryFunc); void addFunctionMap(BuiltinQueryFunc queryFunc);
...@@ -148,31 +56,20 @@ class BuiltInFunctionEmulator ...@@ -148,31 +56,20 @@ class BuiltInFunctionEmulator
// Records that a function is called by the shader and might need to be emulated. If the // Records that a function is called by the shader and might need to be emulated. If the
// function is not in mEmulatedFunctions, this becomes a no-op. Returns true if the function // function is not in mEmulatedFunctions, this becomes a no-op. Returns true if the function
// call needs to be replaced with an emulated one. // call needs to be replaced with an emulated one.
bool setFunctionCalled(TOperator op, const TType &param); bool setFunctionCalled(const TFunction *function);
bool setFunctionCalled(TOperator op, const TType &param1, const TType &param2); bool setFunctionCalled(int uniqueId);
bool setFunctionCalled(TOperator op,
const TType &param1,
const TType &param2,
const TType &param3);
bool setFunctionCalled(TOperator op,
const TType &param1,
const TType &param2,
const TType &param3,
const TType &param4);
bool setFunctionCalled(const FunctionId &functionId);
const char *findEmulatedFunction(const FunctionId &functionId) const; const char *findEmulatedFunction(int uniqueId) const;
// Map from function id to emulated function definition // Map from function unique id to emulated function definition
std::map<FunctionId, std::string> mEmulatedFunctions; std::map<int, std::string> mEmulatedFunctions;
// Map from dependent functions to their dependencies. This structure allows each function to // Map from dependent functions to their dependencies. This structure allows each function to
// have at most one dependency. // have at most one dependency.
std::map<FunctionId, FunctionId> mFunctionDependencies; std::map<int, int> mFunctionDependencies;
// Called function ids // Called function ids
std::vector<FunctionId> mFunctions; std::vector<int> mFunctions;
// Constexpr function tables. // Constexpr function tables.
std::vector<BuiltinQueryFunc *> mQueryFunctions; std::vector<BuiltinQueryFunc *> mQueryFunctions;
......
...@@ -7,9 +7,8 @@ ...@@ -7,9 +7,8 @@
#include "compiler/translator/BuiltInFunctionEmulatorGLSL.h" #include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
#include "angle_gl.h" #include "angle_gl.h"
#include "compiler/translator/BuiltInFunctionEmulator.h" #include "compiler/translator/BuiltInFunctionEmulator.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/VersionGLSL.h" #include "compiler/translator/VersionGLSL.h"
#include "compiler/translator/tree_util/BuiltIn_autogen.h"
namespace sh namespace sh
{ {
...@@ -19,8 +18,7 @@ void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *e ...@@ -19,8 +18,7 @@ void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *e
{ {
if (shaderType == GL_VERTEX_SHADER) if (shaderType == GL_VERTEX_SHADER)
{ {
const TType *int1 = StaticType::GetBasic<EbtInt>(); emu->addEmulatedFunction(BuiltInId::abs_Int1, "int abs_emu(int x) { return x * sign(x); }");
emu->addEmulatedFunction(EOpAbs, int1, "int abs_emu(int x) { return x * sign(x); }");
} }
} }
...@@ -31,17 +29,12 @@ void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator ...@@ -31,17 +29,12 @@ void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator
if (targetGLSLVersion < GLSL_VERSION_130) if (targetGLSLVersion < GLSL_VERSION_130)
return; return;
const TType *float1 = StaticType::GetBasic<EbtFloat>();
const TType *float2 = StaticType::GetBasic<EbtFloat, 2>();
const TType *float3 = StaticType::GetBasic<EbtFloat, 3>();
const TType *float4 = StaticType::GetBasic<EbtFloat, 4>();
// !(x > 0.0 || x < 0.0 || x == 0.0) will be optimized and always equal to false. // !(x > 0.0 || x < 0.0 || x == 0.0) will be optimized and always equal to false.
emu->addEmulatedFunction( emu->addEmulatedFunction(
EOpIsnan, float1, BuiltInId::isnan_Float1,
"bool isnan_emu(float x) { return (x > 0.0 || x < 0.0) ? false : x != 0.0; }"); "bool isnan_emu(float x) { return (x > 0.0 || x < 0.0) ? false : x != 0.0; }");
emu->addEmulatedFunction( emu->addEmulatedFunction(
EOpIsnan, float2, BuiltInId::isnan_Float2,
"bvec2 isnan_emu(vec2 x)\n" "bvec2 isnan_emu(vec2 x)\n"
"{\n" "{\n"
" bvec2 isnan;\n" " bvec2 isnan;\n"
...@@ -52,7 +45,7 @@ void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator ...@@ -52,7 +45,7 @@ void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator
" return isnan;\n" " return isnan;\n"
"}\n"); "}\n");
emu->addEmulatedFunction( emu->addEmulatedFunction(
EOpIsnan, float3, BuiltInId::isnan_Float3,
"bvec3 isnan_emu(vec3 x)\n" "bvec3 isnan_emu(vec3 x)\n"
"{\n" "{\n"
" bvec3 isnan;\n" " bvec3 isnan;\n"
...@@ -63,7 +56,7 @@ void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator ...@@ -63,7 +56,7 @@ void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator
" return isnan;\n" " return isnan;\n"
"}\n"); "}\n");
emu->addEmulatedFunction( emu->addEmulatedFunction(
EOpIsnan, float4, BuiltInId::isnan_Float4,
"bvec4 isnan_emu(vec4 x)\n" "bvec4 isnan_emu(vec4 x)\n"
"{\n" "{\n"
" bvec4 isnan;\n" " bvec4 isnan;\n"
...@@ -77,27 +70,21 @@ void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator ...@@ -77,27 +70,21 @@ void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator
void InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu) void InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu)
{ {
const TType *float1 = StaticType::GetBasic<EbtFloat>(); emu->addEmulatedFunction(BuiltInId::atan_Float1_Float1,
auto floatFuncId = emu->addEmulatedFunction( "emu_precision float atan_emu(emu_precision float y, emu_precision "
EOpAtan, float1, float1, "float x)\n"
"emu_precision float atan_emu(emu_precision float y, emu_precision " "{\n"
"float x)\n" " if (x > 0.0) return atan(y / x);\n"
"{\n" " else if (x < 0.0 && y >= 0.0) return atan(y / x) + 3.14159265;\n"
" if (x > 0.0) return atan(y / x);\n" " else if (x < 0.0 && y < 0.0) return atan(y / x) - 3.14159265;\n"
" else if (x < 0.0 && y >= 0.0) return atan(y / x) + 3.14159265;\n" " else return 1.57079632 * sign(y);\n"
" else if (x < 0.0 && y < 0.0) return atan(y / x) - 3.14159265;\n" "}\n");
" else return 1.57079632 * sign(y);\n" static const std::array<TSymbolUniqueId, 4> ids = {
"}\n"); BuiltInId::atan_Float1_Float1, BuiltInId::atan_Float2_Float2, BuiltInId::atan_Float3_Float3,
static const std::array<const TType *, 5> floatVecs = { BuiltInId::atan_Float4_Float4,
nullptr,
nullptr,
StaticType::GetBasic<EbtFloat, 2>(),
StaticType::GetBasic<EbtFloat, 3>(),
StaticType::GetBasic<EbtFloat, 4>(),
}; };
for (int dim = 2; dim <= 4; ++dim) for (int dim = 2; dim <= 4; ++dim)
{ {
const TType *floatVec = floatVecs[dim];
std::stringstream ss; std::stringstream ss;
ss << "emu_precision vec" << dim << " atan_emu(emu_precision vec" << dim ss << "emu_precision vec" << dim << " atan_emu(emu_precision vec" << dim
<< " y, emu_precision vec" << dim << " x)\n" << " y, emu_precision vec" << dim << " x)\n"
...@@ -114,7 +101,7 @@ void InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator * ...@@ -114,7 +101,7 @@ void InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *
} }
ss << ");\n" ss << ");\n"
"}\n"; "}\n";
emu->addEmulatedFunctionWithDependency(floatFuncId, EOpAtan, floatVec, floatVec, emu->addEmulatedFunctionWithDependency(BuiltInId::atan_Float1_Float1, ids[dim - 1],
ss.str().c_str()); ss.str().c_str());
} }
} }
...@@ -127,11 +114,8 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator ...@@ -127,11 +114,8 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator
// Emulate packUnorm2x16 and unpackUnorm2x16 (GLSL 4.10) // Emulate packUnorm2x16 and unpackUnorm2x16 (GLSL 4.10)
if (targetGLSLVersion < GLSL_VERSION_410) if (targetGLSLVersion < GLSL_VERSION_410)
{ {
const TType *float2 = StaticType::GetBasic<EbtFloat, 2>();
const TType *uint1 = StaticType::GetBasic<EbtUInt>();
// clang-format off // clang-format off
emu->addEmulatedFunction(EOpPackUnorm2x16, float2, emu->addEmulatedFunction(BuiltInId::packUnorm2x16_Float2,
"uint packUnorm2x16_emu(vec2 v)\n" "uint packUnorm2x16_emu(vec2 v)\n"
"{\n" "{\n"
" int x = int(round(clamp(v.x, 0.0, 1.0) * 65535.0));\n" " int x = int(round(clamp(v.x, 0.0, 1.0) * 65535.0));\n"
...@@ -139,7 +123,7 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator ...@@ -139,7 +123,7 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator
" return uint((y << 16) | (x & 0xFFFF));\n" " return uint((y << 16) | (x & 0xFFFF));\n"
"}\n"); "}\n");
emu->addEmulatedFunction(EOpUnpackUnorm2x16, uint1, emu->addEmulatedFunction(BuiltInId::unpackUnorm2x16_UInt1,
"vec2 unpackUnorm2x16_emu(uint u)\n" "vec2 unpackUnorm2x16_emu(uint u)\n"
"{\n" "{\n"
" float x = float(u & 0xFFFFu) / 65535.0;\n" " float x = float(u & 0xFFFFu) / 65535.0;\n"
...@@ -153,11 +137,8 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator ...@@ -153,11 +137,8 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator
// by using floatBitsToInt, floatBitsToUint, intBitsToFloat, and uintBitsToFloat (GLSL 3.30). // by using floatBitsToInt, floatBitsToUint, intBitsToFloat, and uintBitsToFloat (GLSL 3.30).
if (targetGLSLVersion >= GLSL_VERSION_330 && targetGLSLVersion < GLSL_VERSION_420) if (targetGLSLVersion >= GLSL_VERSION_330 && targetGLSLVersion < GLSL_VERSION_420)
{ {
const TType *float2 = StaticType::GetBasic<EbtFloat, 2>();
const TType *uint1 = StaticType::GetBasic<EbtUInt>();
// clang-format off // clang-format off
emu->addEmulatedFunction(EOpPackSnorm2x16, float2, emu->addEmulatedFunction(BuiltInId::packSnorm2x16_Float2,
"uint packSnorm2x16_emu(vec2 v)\n" "uint packSnorm2x16_emu(vec2 v)\n"
"{\n" "{\n"
" #if defined(GL_ARB_shading_language_packing)\n" " #if defined(GL_ARB_shading_language_packing)\n"
...@@ -168,7 +149,7 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator ...@@ -168,7 +149,7 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator
" return uint((y << 16) | (x & 0xFFFF));\n" " return uint((y << 16) | (x & 0xFFFF));\n"
" #endif\n" " #endif\n"
"}\n"); "}\n");
emu->addEmulatedFunction(EOpUnpackSnorm2x16, uint1, emu->addEmulatedFunction(BuiltInId::unpackSnorm2x16_UInt1,
"#if !defined(GL_ARB_shading_language_packing)\n" "#if !defined(GL_ARB_shading_language_packing)\n"
" float fromSnorm(uint x)\n" " float fromSnorm(uint x)\n"
" {\n" " {\n"
...@@ -189,7 +170,7 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator ...@@ -189,7 +170,7 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator
"}\n"); "}\n");
// Functions uint f32tof16(float val) and float f16tof32(uint val) are // Functions uint f32tof16(float val) and float f16tof32(uint val) are
// based on the OpenGL redbook Appendix Session "Floating-Point Formats Used in OpenGL". // based on the OpenGL redbook Appendix Session "Floating-Point Formats Used in OpenGL".
emu->addEmulatedFunction(EOpPackHalf2x16, float2, emu->addEmulatedFunction(BuiltInId::packHalf2x16_Float2,
"#if !defined(GL_ARB_shading_language_packing)\n" "#if !defined(GL_ARB_shading_language_packing)\n"
" uint f32tof16(float val)\n" " uint f32tof16(float val)\n"
" {\n" " {\n"
...@@ -236,7 +217,7 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator ...@@ -236,7 +217,7 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator
" return (y << 16) | x;\n" " return (y << 16) | x;\n"
" #endif\n" " #endif\n"
"}\n"); "}\n");
emu->addEmulatedFunction(EOpUnpackHalf2x16, uint1, emu->addEmulatedFunction(BuiltInId::unpackHalf2x16_UInt1,
"#if !defined(GL_ARB_shading_language_packing)\n" "#if !defined(GL_ARB_shading_language_packing)\n"
" float f16tof32(uint val)\n" " float f16tof32(uint val)\n"
" {\n" " {\n"
......
...@@ -4,17 +4,17 @@ ...@@ -4,17 +4,17 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
#include "compiler/translator/BuiltInFunctionEmulatorHLSL.h"
#include "angle_gl.h" #include "angle_gl.h"
#include "compiler/translator/BuiltInFunctionEmulator.h" #include "compiler/translator/BuiltInFunctionEmulator.h"
#include "compiler/translator/BuiltInFunctionEmulatorHLSL.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/VersionGLSL.h" #include "compiler/translator/VersionGLSL.h"
#include "compiler/translator/tree_util/BuiltIn_autogen.h"
namespace sh namespace sh
{ {
// Defined in emulated_builtin_functions_hlsl_autogen.cpp. // Defined in emulated_builtin_functions_hlsl_autogen.cpp.
const char *FindHLSLFunction(const FunctionId &functionID); const char *FindHLSLFunction(int uniqueId);
void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator *emu, void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator *emu,
int targetGLSLVersion) int targetGLSLVersion)
...@@ -22,12 +22,7 @@ void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator ...@@ -22,12 +22,7 @@ void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator
if (targetGLSLVersion < GLSL_VERSION_130) if (targetGLSLVersion < GLSL_VERSION_130)
return; return;
TType *float1 = new TType(EbtFloat); emu->addEmulatedFunction(BuiltInId::isnan_Float1,
TType *float2 = new TType(EbtFloat, 2);
TType *float3 = new TType(EbtFloat, 3);
TType *float4 = new TType(EbtFloat, 4);
emu->addEmulatedFunction(EOpIsnan, float1,
"bool isnan_emu(float x)\n" "bool isnan_emu(float x)\n"
"{\n" "{\n"
" return (x > 0.0 || x < 0.0) ? false : x != 0.0;\n" " return (x > 0.0 || x < 0.0) ? false : x != 0.0;\n"
...@@ -35,7 +30,7 @@ void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator ...@@ -35,7 +30,7 @@ void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator
"\n"); "\n");
emu->addEmulatedFunction( emu->addEmulatedFunction(
EOpIsnan, float2, BuiltInId::isnan_Float2,
"bool2 isnan_emu(float2 x)\n" "bool2 isnan_emu(float2 x)\n"
"{\n" "{\n"
" bool2 isnan;\n" " bool2 isnan;\n"
...@@ -47,7 +42,7 @@ void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator ...@@ -47,7 +42,7 @@ void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator
"}\n"); "}\n");
emu->addEmulatedFunction( emu->addEmulatedFunction(
EOpIsnan, float3, BuiltInId::isnan_Float3,
"bool3 isnan_emu(float3 x)\n" "bool3 isnan_emu(float3 x)\n"
"{\n" "{\n"
" bool3 isnan;\n" " bool3 isnan;\n"
...@@ -59,7 +54,7 @@ void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator ...@@ -59,7 +54,7 @@ void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator
"}\n"); "}\n");
emu->addEmulatedFunction( emu->addEmulatedFunction(
EOpIsnan, float4, BuiltInId::isnan_Float4,
"bool4 isnan_emu(float4 x)\n" "bool4 isnan_emu(float4 x)\n"
"{\n" "{\n"
" bool4 isnan;\n" " bool4 isnan;\n"
...@@ -73,43 +68,35 @@ void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator ...@@ -73,43 +68,35 @@ void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator
void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu) void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
{ {
TType *int1 = new TType(EbtInt);
TType *int2 = new TType(EbtInt, 2);
TType *int3 = new TType(EbtInt, 3);
TType *int4 = new TType(EbtInt, 4);
TType *uint1 = new TType(EbtUInt);
TType *uint2 = new TType(EbtUInt, 2);
TType *uint3 = new TType(EbtUInt, 3);
TType *uint4 = new TType(EbtUInt, 4);
emu->addFunctionMap(FindHLSLFunction); emu->addFunctionMap(FindHLSLFunction);
// (a + b2^16) * (c + d2^16) = ac + (ad + bc) * 2^16 + bd * 2^32 // (a + b2^16) * (c + d2^16) = ac + (ad + bc) * 2^16 + bd * 2^32
// Also note that below, a * d + ((a * c) >> 16) is guaranteed not to overflow, because: // Also note that below, a * d + ((a * c) >> 16) is guaranteed not to overflow, because:
// a <= 0xffff, d <= 0xffff, ((a * c) >> 16) <= 0xffff and 0xffff * 0xffff + 0xffff = 0xffff0000 // a <= 0xffff, d <= 0xffff, ((a * c) >> 16) <= 0xffff and 0xffff * 0xffff + 0xffff = 0xffff0000
FunctionId umulExtendedUint1 = emu->addEmulatedFunction( emu->addEmulatedFunction(BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
EOpUmulExtended, uint1, uint1, uint1, uint1, "void umulExtended_emu(uint x, uint y, out uint msb, out uint lsb)\n"
"void umulExtended_emu(uint x, uint y, out uint msb, out uint lsb)\n" "{\n"
"{\n" " lsb = x * y;\n"
" lsb = x * y;\n" " uint a = (x & 0xffffu);\n"
" uint a = (x & 0xffffu);\n" " uint b = (x >> 16);\n"
" uint b = (x >> 16);\n" " uint c = (y & 0xffffu);\n"
" uint c = (y & 0xffffu);\n" " uint d = (y >> 16);\n"
" uint d = (y >> 16);\n" " uint ad = a * d + ((a * c) >> 16);\n"
" uint ad = a * d + ((a * c) >> 16);\n" " uint bc = b * c;\n"
" uint bc = b * c;\n" " uint carry = uint(ad > (0xffffffffu - bc));\n"
" uint carry = uint(ad > (0xffffffffu - bc));\n" " msb = ((ad + bc) >> 16) + (carry << 16) + b * d;\n"
" msb = ((ad + bc) >> 16) + (carry << 16) + b * d;\n" "}\n");
"}\n");
emu->addEmulatedFunctionWithDependency( emu->addEmulatedFunctionWithDependency(
umulExtendedUint1, EOpUmulExtended, uint2, uint2, uint2, uint2, BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
BuiltInId::umulExtended_UInt2_UInt2_UInt2_UInt2,
"void umulExtended_emu(uint2 x, uint2 y, out uint2 msb, out uint2 lsb)\n" "void umulExtended_emu(uint2 x, uint2 y, out uint2 msb, out uint2 lsb)\n"
"{\n" "{\n"
" umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n" " umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
" umulExtended_emu(x.y, y.y, msb.y, lsb.y);\n" " umulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
"}\n"); "}\n");
emu->addEmulatedFunctionWithDependency( emu->addEmulatedFunctionWithDependency(
umulExtendedUint1, EOpUmulExtended, uint3, uint3, uint3, uint3, BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
BuiltInId::umulExtended_UInt3_UInt3_UInt3_UInt3,
"void umulExtended_emu(uint3 x, uint3 y, out uint3 msb, out uint3 lsb)\n" "void umulExtended_emu(uint3 x, uint3 y, out uint3 msb, out uint3 lsb)\n"
"{\n" "{\n"
" umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n" " umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
...@@ -117,7 +104,8 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu) ...@@ -117,7 +104,8 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
" umulExtended_emu(x.z, y.z, msb.z, lsb.z);\n" " umulExtended_emu(x.z, y.z, msb.z, lsb.z);\n"
"}\n"); "}\n");
emu->addEmulatedFunctionWithDependency( emu->addEmulatedFunctionWithDependency(
umulExtendedUint1, EOpUmulExtended, uint4, uint4, uint4, uint4, BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
BuiltInId::umulExtended_UInt4_UInt4_UInt4_UInt4,
"void umulExtended_emu(uint4 x, uint4 y, out uint4 msb, out uint4 lsb)\n" "void umulExtended_emu(uint4 x, uint4 y, out uint4 msb, out uint4 lsb)\n"
"{\n" "{\n"
" umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n" " umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
...@@ -130,8 +118,9 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu) ...@@ -130,8 +118,9 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
// result needs to be negative. // result needs to be negative.
// TODO(oetuaho): Note that this code doesn't take one edge case into account, where x or y is // TODO(oetuaho): Note that this code doesn't take one edge case into account, where x or y is
// -2^31. abs(-2^31) is undefined. // -2^31. abs(-2^31) is undefined.
FunctionId imulExtendedInt1 = emu->addEmulatedFunctionWithDependency( emu->addEmulatedFunctionWithDependency(
umulExtendedUint1, EOpImulExtended, int1, int1, int1, int1, BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
BuiltInId::imulExtended_Int1_Int1_Int1_Int1,
"void imulExtended_emu(int x, int y, out int msb, out int lsb)\n" "void imulExtended_emu(int x, int y, out int msb, out int lsb)\n"
"{\n" "{\n"
" uint unsignedMsb;\n" " uint unsignedMsb;\n"
...@@ -156,14 +145,14 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu) ...@@ -156,14 +145,14 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
" }\n" " }\n"
"}\n"); "}\n");
emu->addEmulatedFunctionWithDependency( emu->addEmulatedFunctionWithDependency(
imulExtendedInt1, EOpImulExtended, int2, int2, int2, int2, BuiltInId::imulExtended_Int1_Int1_Int1_Int1, BuiltInId::imulExtended_Int2_Int2_Int2_Int2,
"void imulExtended_emu(int2 x, int2 y, out int2 msb, out int2 lsb)\n" "void imulExtended_emu(int2 x, int2 y, out int2 msb, out int2 lsb)\n"
"{\n" "{\n"
" imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n" " imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
" imulExtended_emu(x.y, y.y, msb.y, lsb.y);\n" " imulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
"}\n"); "}\n");
emu->addEmulatedFunctionWithDependency( emu->addEmulatedFunctionWithDependency(
imulExtendedInt1, EOpImulExtended, int3, int3, int3, int3, BuiltInId::imulExtended_Int1_Int1_Int1_Int1, BuiltInId::imulExtended_Int3_Int3_Int3_Int3,
"void imulExtended_emu(int3 x, int3 y, out int3 msb, out int3 lsb)\n" "void imulExtended_emu(int3 x, int3 y, out int3 msb, out int3 lsb)\n"
"{\n" "{\n"
" imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n" " imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
...@@ -171,7 +160,7 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu) ...@@ -171,7 +160,7 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
" imulExtended_emu(x.z, y.z, msb.z, lsb.z);\n" " imulExtended_emu(x.z, y.z, msb.z, lsb.z);\n"
"}\n"); "}\n");
emu->addEmulatedFunctionWithDependency( emu->addEmulatedFunctionWithDependency(
imulExtendedInt1, EOpImulExtended, int4, int4, int4, int4, BuiltInId::imulExtended_Int1_Int1_Int1_Int1, BuiltInId::imulExtended_Int4_Int4_Int4_Int4,
"void imulExtended_emu(int4 x, int4 y, out int4 msb, out int4 lsb)\n" "void imulExtended_emu(int4 x, int4 y, out int4 msb, out int4 lsb)\n"
"{\n" "{\n"
" imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n" " imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
......
...@@ -588,7 +588,7 @@ bool TCompiler::checkAndSimplifyAST(TIntermBlock *root, ...@@ -588,7 +588,7 @@ bool TCompiler::checkAndSimplifyAST(TIntermBlock *root,
if (compileOptions & SH_REMOVE_POW_WITH_CONSTANT_EXPONENT) if (compileOptions & SH_REMOVE_POW_WITH_CONSTANT_EXPONENT)
{ {
RemovePow(root); RemovePow(root, &symbolTable);
} }
if (compileOptions & SH_REGENERATE_STRUCT_NAMES) if (compileOptions & SH_REGENERATE_STRUCT_NAMES)
......
...@@ -809,7 +809,9 @@ TIntermBinary::TIntermBinary(const TIntermBinary &node) ...@@ -809,7 +809,9 @@ TIntermBinary::TIntermBinary(const TIntermBinary &node)
} }
TIntermUnary::TIntermUnary(const TIntermUnary &node) TIntermUnary::TIntermUnary(const TIntermUnary &node)
: TIntermOperator(node), mUseEmulatedFunction(node.mUseEmulatedFunction) : TIntermOperator(node),
mUseEmulatedFunction(node.mUseEmulatedFunction),
mFunction(node.mFunction)
{ {
TIntermTyped *operandCopy = node.mOperand->deepCopy(); TIntermTyped *operandCopy = node.mOperand->deepCopy();
ASSERT(operandCopy != nullptr); ASSERT(operandCopy != nullptr);
...@@ -1049,8 +1051,8 @@ TIntermSwizzle::TIntermSwizzle(TIntermTyped *operand, const TVector<int> &swizzl ...@@ -1049,8 +1051,8 @@ TIntermSwizzle::TIntermSwizzle(TIntermTyped *operand, const TVector<int> &swizzl
promote(); promote();
} }
TIntermUnary::TIntermUnary(TOperator op, TIntermTyped *operand) TIntermUnary::TIntermUnary(TOperator op, TIntermTyped *operand, const TFunction *function)
: TIntermOperator(op), mOperand(operand), mUseEmulatedFunction(false) : TIntermOperator(op), mOperand(operand), mUseEmulatedFunction(false), mFunction(function)
{ {
promote(); promote();
} }
......
...@@ -505,7 +505,7 @@ class TIntermBinary : public TIntermOperator ...@@ -505,7 +505,7 @@ class TIntermBinary : public TIntermOperator
class TIntermUnary : public TIntermOperator class TIntermUnary : public TIntermOperator
{ {
public: public:
TIntermUnary(TOperator op, TIntermTyped *operand); TIntermUnary(TOperator op, TIntermTyped *operand, const TFunction *function);
TIntermTyped *deepCopy() const override { return new TIntermUnary(*this); } TIntermTyped *deepCopy() const override { return new TIntermUnary(*this); }
...@@ -518,6 +518,8 @@ class TIntermUnary : public TIntermOperator ...@@ -518,6 +518,8 @@ class TIntermUnary : public TIntermOperator
TIntermTyped *getOperand() { return mOperand; } TIntermTyped *getOperand() { return mOperand; }
TIntermTyped *fold(TDiagnostics *diagnostics) override; TIntermTyped *fold(TDiagnostics *diagnostics) override;
const TFunction *getFunction() const { return mFunction; }
void setUseEmulatedFunction() { mUseEmulatedFunction = true; } void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
bool getUseEmulatedFunction() { return mUseEmulatedFunction; } bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
...@@ -528,6 +530,8 @@ class TIntermUnary : public TIntermOperator ...@@ -528,6 +530,8 @@ class TIntermUnary : public TIntermOperator
// to work around driver bugs. // to work around driver bugs.
bool mUseEmulatedFunction; bool mUseEmulatedFunction;
const TFunction *const mFunction;
private: private:
void promote(); void promote();
......
//
// Copyright 2017 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ParamType:
// Helper type for built-in function emulator tables. Defines types for parameters.
#ifndef COMPILER_TRANSLATOR_PARAMTYPE_H_
#define COMPILER_TRANSLATOR_PARAMTYPE_H_
#include "common/angleutils.h"
#include "compiler/translator/BaseTypes.h"
namespace sh
{
enum class ParamType : uint8_t
{
Void,
Bool1,
Bool2,
Bool3,
Bool4,
Float1,
Float2,
Float3,
Float4,
Int1,
Int2,
Int3,
Int4,
Mat2,
Mat3,
Mat4,
Uint1,
Uint2,
Uint3,
Uint4,
Last,
};
struct ParamTypeInfo
{
ParamType self;
TBasicType basicType;
int primarySize;
int secondarySize;
};
constexpr ParamTypeInfo g_ParamTypeInfo[] = {
{ParamType::Void, EbtVoid, 1, 1}, {ParamType::Bool1, EbtBool, 1, 1},
{ParamType::Bool2, EbtBool, 2, 1}, {ParamType::Bool3, EbtBool, 3, 1},
{ParamType::Bool4, EbtBool, 4, 1}, {ParamType::Float1, EbtFloat, 1, 1},
{ParamType::Float2, EbtFloat, 2, 1}, {ParamType::Float3, EbtFloat, 3, 1},
{ParamType::Float4, EbtFloat, 4, 1}, {ParamType::Int1, EbtInt, 1, 1},
{ParamType::Int2, EbtInt, 2, 1}, {ParamType::Int3, EbtInt, 3, 1},
{ParamType::Int4, EbtInt, 4, 1}, {ParamType::Mat2, EbtFloat, 2, 2},
{ParamType::Mat3, EbtFloat, 3, 3}, {ParamType::Mat4, EbtFloat, 4, 4},
{ParamType::Uint1, EbtUInt, 1, 1}, {ParamType::Uint2, EbtUInt, 2, 1},
{ParamType::Uint3, EbtUInt, 3, 1}, {ParamType::Uint4, EbtUInt, 4, 1},
};
constexpr size_t ParamTypeIndex(ParamType paramType)
{
return static_cast<size_t>(paramType);
}
constexpr size_t NumParamTypes()
{
return ParamTypeIndex(ParamType::Last);
}
static_assert(ArraySize(g_ParamTypeInfo) == NumParamTypes(), "Invalid array size");
constexpr TBasicType GetBasicType(ParamType paramType)
{
return g_ParamTypeInfo[ParamTypeIndex(paramType)].basicType;
}
constexpr int GetPrimarySize(ParamType paramType)
{
return g_ParamTypeInfo[ParamTypeIndex(paramType)].primarySize;
}
constexpr int GetSecondarySize(ParamType paramType)
{
return g_ParamTypeInfo[ParamTypeIndex(paramType)].secondarySize;
}
constexpr bool SameParamType(ParamType paramType,
TBasicType basicType,
int primarySize,
int secondarySize)
{
return GetBasicType(paramType) == basicType && primarySize == GetPrimarySize(paramType) &&
secondarySize == GetSecondarySize(paramType);
}
} // namespace sh
#endif // COMPILER_TRANSLATOR_PARAMTYPE_H_
...@@ -4859,7 +4859,8 @@ TIntermCase *TParseContext::addDefault(const TSourceLoc &loc) ...@@ -4859,7 +4859,8 @@ TIntermCase *TParseContext::addDefault(const TSourceLoc &loc)
TIntermTyped *TParseContext::createUnaryMath(TOperator op, TIntermTyped *TParseContext::createUnaryMath(TOperator op,
TIntermTyped *child, TIntermTyped *child,
const TSourceLoc &loc) const TSourceLoc &loc,
const TFunction *func)
{ {
ASSERT(child != nullptr); ASSERT(child != nullptr);
...@@ -4907,7 +4908,7 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op, ...@@ -4907,7 +4908,7 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op,
} }
markStaticReadIfSymbol(child); markStaticReadIfSymbol(child);
TIntermUnary *node = new TIntermUnary(op, child); TIntermUnary *node = new TIntermUnary(op, child, func);
node->setLine(loc); node->setLine(loc);
return node->fold(mDiagnostics); return node->fold(mDiagnostics);
...@@ -4916,7 +4917,7 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op, ...@@ -4916,7 +4917,7 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op,
TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc) TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
{ {
ASSERT(op != EOpNull); ASSERT(op != EOpNull);
TIntermTyped *node = createUnaryMath(op, child, loc); TIntermTyped *node = createUnaryMath(op, child, loc, nullptr);
if (node == nullptr) if (node == nullptr)
{ {
return child; return child;
...@@ -5779,7 +5780,7 @@ TIntermTyped *TParseContext::addMethod(TFunctionLookup *fnCall, const TSourceLoc ...@@ -5779,7 +5780,7 @@ TIntermTyped *TParseContext::addMethod(TFunctionLookup *fnCall, const TSourceLoc
} }
else else
{ {
TIntermUnary *node = new TIntermUnary(EOpArrayLength, thisNode); TIntermUnary *node = new TIntermUnary(EOpArrayLength, thisNode, nullptr);
node->setLine(loc); node->setLine(loc);
return node->fold(mDiagnostics); return node->fold(mDiagnostics);
} }
...@@ -5837,7 +5838,8 @@ TIntermTyped *TParseContext::addNonConstructorFunctionCall(TFunctionLookup *fnCa ...@@ -5837,7 +5838,8 @@ TIntermTyped *TParseContext::addNonConstructorFunctionCall(TFunctionLookup *fnCa
{ {
// Treat it like a built-in unary operator. // Treat it like a built-in unary operator.
TIntermNode *unaryParamNode = fnCall->arguments().front(); TIntermNode *unaryParamNode = fnCall->arguments().front();
TIntermTyped *callNode = createUnaryMath(op, unaryParamNode->getAsTyped(), loc); TIntermTyped *callNode =
createUnaryMath(op, unaryParamNode->getAsTyped(), loc, fnCandidate);
ASSERT(callNode != nullptr); ASSERT(callNode != nullptr);
return callNode; return callNode;
} }
......
...@@ -549,7 +549,10 @@ class TParseContext : angle::NonCopyable ...@@ -549,7 +549,10 @@ class TParseContext : angle::NonCopyable
TIntermTyped *left, TIntermTyped *left,
TIntermTyped *right, TIntermTyped *right,
const TSourceLoc &loc); const TSourceLoc &loc);
TIntermTyped *createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc); TIntermTyped *createUnaryMath(TOperator op,
TIntermTyped *child,
const TSourceLoc &loc,
const TFunction *func);
TIntermTyped *addMethod(TFunctionLookup *fnCall, const TSourceLoc &loc); TIntermTyped *addMethod(TFunctionLookup *fnCall, const TSourceLoc &loc);
TIntermTyped *addConstructor(TFunctionLookup *fnCall, const TSourceLoc &line); TIntermTyped *addConstructor(TFunctionLookup *fnCall, const TSourceLoc &line);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -22,11 +22,6 @@ TSymbolUniqueId::TSymbolUniqueId(const TSymbol &symbol) : mId(symbol.uniqueId(). ...@@ -22,11 +22,6 @@ TSymbolUniqueId::TSymbolUniqueId(const TSymbol &symbol) : mId(symbol.uniqueId().
TSymbolUniqueId &TSymbolUniqueId::operator=(const TSymbolUniqueId &) = default; TSymbolUniqueId &TSymbolUniqueId::operator=(const TSymbolUniqueId &) = default;
int TSymbolUniqueId::get() const
{
return mId;
}
bool TSymbolUniqueId::operator==(const TSymbolUniqueId &other) const bool TSymbolUniqueId::operator==(const TSymbolUniqueId &other) const
{ {
return mId == other.mId; return mId == other.mId;
......
...@@ -25,7 +25,7 @@ class TSymbolUniqueId ...@@ -25,7 +25,7 @@ class TSymbolUniqueId
TSymbolUniqueId &operator=(const TSymbolUniqueId &); TSymbolUniqueId &operator=(const TSymbolUniqueId &);
bool operator==(const TSymbolUniqueId &) const; bool operator==(const TSymbolUniqueId &) const;
int get() const; constexpr int get() const { return mId; }
private: private:
friend class TSymbolTable; friend class TSymbolTable;
......
cc849405cb2fd922f9a269ab6594cb9b e7cb1a4f677413aec61815b10019f608
\ No newline at end of file \ No newline at end of file
...@@ -68,7 +68,7 @@ TEST(ImmutableStringTest, ScriptGeneratedHashesMatch) ...@@ -68,7 +68,7 @@ TEST(ImmutableStringTest, ScriptGeneratedHashesMatch)
""" """
# The header file has a "get" function for each variable. They are used in traversers. # The header file has a "get" function for each variable. They are used in traversers.
# Note that we don't currently include get_function_declarations, as they are unused. # It also declares id values of built-ins with human readable names, so they can be used to identify built-ins.
template_builtin_header = """// GENERATED FILE - DO NOT EDIT. template_builtin_header = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {variable_data_source_name} and // Generated by {script_name} using data from {variable_data_source_name} and
// {function_data_source_name}. // {function_data_source_name}.
...@@ -83,11 +83,21 @@ template_builtin_header = """// GENERATED FILE - DO NOT EDIT. ...@@ -83,11 +83,21 @@ template_builtin_header = """// GENERATED FILE - DO NOT EDIT.
#ifndef COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_ #ifndef COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_
#define COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_ #define COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_
#include "compiler/translator/SymbolUniqueId.h"
namespace sh namespace sh
{{ {{
class TVariable; class TVariable;
class BuiltInId
{{
public:
{builtin_id_declarations}
}}; // class BuiltInId
namespace BuiltInVariable namespace BuiltInVariable
{{ {{
...@@ -144,23 +154,15 @@ template_symboltable_cpp = """// GENERATED FILE - DO NOT EDIT. ...@@ -144,23 +154,15 @@ template_symboltable_cpp = """// GENERATED FILE - DO NOT EDIT.
#include "compiler/translator/SymbolTable.h" #include "compiler/translator/SymbolTable.h"
#include "angle_gl.h" #include "angle_gl.h"
#include "compiler/translator/tree_util/BuiltIn_autogen.h"
#include "compiler/translator/ImmutableString.h" #include "compiler/translator/ImmutableString.h"
#include "compiler/translator/StaticType.h" #include "compiler/translator/StaticType.h"
#include "compiler/translator/Symbol.h" #include "compiler/translator/Symbol.h"
#include "compiler/translator/SymbolUniqueId.h"
#include "compiler/translator/SymbolTable.h" #include "compiler/translator/SymbolTable.h"
namespace sh namespace sh
{{ {{
class BuiltInId
{{
public:
{builtin_id_declarations}
}}; // namespace BuiltInId
// Since some of the BuiltInId declarations are used outside of constexpr expressions, we need to // Since some of the BuiltInId declarations are used outside of constexpr expressions, we need to
// have these definitions without an initializer. C++17 should eventually remove the need for this. // have these definitions without an initializer. C++17 should eventually remove the need for this.
{builtin_id_definitions} {builtin_id_definitions}
...@@ -455,6 +457,13 @@ class TType: ...@@ -455,6 +457,13 @@ class TType:
mangled_name += get_basic_mangled_name(self.data['basic']) mangled_name += get_basic_mangled_name(self.data['basic'])
return mangled_name return mangled_name
def get_human_readable_name(self):
name = self.data['basic']
name += str(self.data['primarySize'])
if self.data['secondarySize'] > 1:
name += 'x' + str(self.data['secondarySize'])
return name
def is_vector(self): def is_vector(self):
return self.data['primarySize'] > 1 and self.data['secondarySize'] == 1 return self.data['primarySize'] > 1 and self.data['secondarySize'] == 1
...@@ -758,6 +767,12 @@ def get_function_mangled_name(function_name, parameters): ...@@ -758,6 +767,12 @@ def get_function_mangled_name(function_name, parameters):
mangled_name += param.get_mangled_name() mangled_name += param.get_mangled_name()
return mangled_name return mangled_name
def get_function_human_readable_name(function_name, parameters):
name = function_name
for param in parameters:
name += '_' + param.get_human_readable_name()
return name
ttype_mangled_name_variants = [] ttype_mangled_name_variants = []
for basic_type in basic_types_enumeration: for basic_type in basic_types_enumeration:
primary_sizes = [1] primary_sizes = [1]
...@@ -966,10 +981,13 @@ def process_single_function_group(condition, group_name, group): ...@@ -966,10 +981,13 @@ def process_single_function_group(condition, group_name, group):
template_args['param_count'] = len(parameters) template_args['param_count'] = len(parameters)
template_args['return_type'] = function_props['returnType'].get_statictype_string() template_args['return_type'] = function_props['returnType'].get_statictype_string()
template_args['mangled_name'] = get_function_mangled_name(function_name, parameters) template_args['mangled_name'] = get_function_mangled_name(function_name, parameters)
template_args['human_readable_name'] = get_function_human_readable_name(template_args['name_with_suffix'], parameters)
template_args['mangled_name_length'] = len(template_args['mangled_name']) template_args['mangled_name_length'] = len(template_args['mangled_name'])
template_builtin_id_declaration = ' static constexpr const TSymbolUniqueId {unique_name} = TSymbolUniqueId({id});' template_builtin_id_declaration = ' static constexpr const TSymbolUniqueId {human_readable_name} = TSymbolUniqueId({id});'
builtin_id_declarations.append(template_builtin_id_declaration.format(**template_args)) builtin_id_declarations.append(template_builtin_id_declaration.format(**template_args))
template_builtin_id_definition = 'constexpr const TSymbolUniqueId BuiltInId::{human_readable_name};'
builtin_id_definitions.append(template_builtin_id_definition.format(**template_args))
parameters_list = [] parameters_list = []
for param in parameters: for param in parameters:
...@@ -998,7 +1016,7 @@ def process_single_function_group(condition, group_name, group): ...@@ -998,7 +1016,7 @@ def process_single_function_group(condition, group_name, group):
template_parameter_list_declaration = 'constexpr const TVariable **{parameters_var_name} = nullptr;' template_parameter_list_declaration = 'constexpr const TVariable **{parameters_var_name} = nullptr;'
parameter_declarations[template_args['parameters_var_name']] = template_parameter_list_declaration.format(**template_args) parameter_declarations[template_args['parameters_var_name']] = template_parameter_list_declaration.format(**template_args)
template_function_declaration = 'constexpr const TFunction kFunction_{unique_name}(BuiltInId::{unique_name}, BuiltInName::{name_with_suffix}, TExtension::{extension}, BuiltInParameters::{parameters_var_name}, {param_count}, {return_type}, EOp{op}, {known_to_not_have_side_effects});' template_function_declaration = 'constexpr const TFunction kFunction_{unique_name}(BuiltInId::{human_readable_name}, BuiltInName::{name_with_suffix}, TExtension::{extension}, BuiltInParameters::{parameters_var_name}, {param_count}, {return_type}, EOp{op}, {known_to_not_have_side_effects});'
function_declarations.append(template_function_declaration.format(**template_args)) function_declarations.append(template_function_declaration.format(**template_args))
# If we can make sure that there's no other mangled name with the same length, function # If we can make sure that there's no other mangled name with the same length, function
......
...@@ -21,6 +21,7 @@ template_emulated_builtin_functions_hlsl = """// GENERATED FILE - DO NOT EDIT. ...@@ -21,6 +21,7 @@ template_emulated_builtin_functions_hlsl = """// GENERATED FILE - DO NOT EDIT.
// HLSL code for emulating GLSL builtin functions not present in HLSL. // HLSL code for emulating GLSL builtin functions not present in HLSL.
#include "compiler/translator/BuiltInFunctionEmulator.h" #include "compiler/translator/BuiltInFunctionEmulator.h"
#include "compiler/translator/tree_util/BuiltIn_autogen.h"
namespace sh namespace sh
{{ {{
...@@ -30,11 +31,11 @@ namespace ...@@ -30,11 +31,11 @@ namespace
struct FunctionPair struct FunctionPair
{{ {{
constexpr FunctionPair(const MiniFunctionId &idIn, const char *bodyIn) : id(idIn), body(bodyIn) constexpr FunctionPair(const TSymbolUniqueId &idIn, const char *bodyIn) : id(idIn.get()), body(bodyIn)
{{ {{
}} }}
MiniFunctionId id; int id;
const char *body; const char *body;
}}; }};
...@@ -42,12 +43,12 @@ constexpr FunctionPair g_hlslFunctions[] = {{ ...@@ -42,12 +43,12 @@ constexpr FunctionPair g_hlslFunctions[] = {{
{emulated_functions}}}; {emulated_functions}}};
}} // anonymous namespace }} // anonymous namespace
const char *FindHLSLFunction(const FunctionId &functionID) const char *FindHLSLFunction(int uniqueId)
{{ {{
for (size_t index = 0; index < ArraySize(g_hlslFunctions); ++index) for (size_t index = 0; index < ArraySize(g_hlslFunctions); ++index)
{{ {{
const auto &function = g_hlslFunctions[index]; const auto &function = g_hlslFunctions[index];
if (function.id == functionID) if (function.id == uniqueId)
{{ {{
return function.body; return function.body;
}} }}
...@@ -74,26 +75,18 @@ def load_json(path): ...@@ -74,26 +75,18 @@ def load_json(path):
return json.loads(file_data, object_pairs_hook=reject_duplicate_keys) return json.loads(file_data, object_pairs_hook=reject_duplicate_keys)
def enum_type(arg): def enum_type(arg):
# handle 'argtype argname' and 'out argtype argname' # handle 'argtype argname' and 'out argtype argname'
chunks = arg.split(' ') chunks = arg.split(' ')
arg_type = chunks[0] arg_type = chunks[0]
if len(chunks) == 3: if len(chunks) == 3:
arg_type = chunks[1] arg_type = chunks[1]
if arg_type == "float2x2": suffix = ""
return "Mat2" if not arg_type[-1].isdigit():
elif arg_type == "float3x3": suffix = '1'
return "Mat3" if arg_type[0:4] == 'uint':
elif arg_type == "float4x4": return 'UI' + arg_type[2:] + suffix
return "Mat4" return arg_type.capitalize() + suffix
suffix = ""
if not arg_type[-1].isdigit():
suffix = '1'
return arg_type.capitalize() + suffix
def caps(op):
return op[0].upper() + op[1:]
input_script = "emulated_builtin_function_data_hlsl.json" input_script = "emulated_builtin_function_data_hlsl.json"
hlsl_json = load_json(input_script) hlsl_json = load_json(input_script)
...@@ -109,7 +102,7 @@ def gen_emulated_function(data): ...@@ -109,7 +102,7 @@ def gen_emulated_function(data):
body = [ sig, '{' ] + [' ' + line for line in data['body']] + ['}'] body = [ sig, '{' ] + [' ' + line for line in data['body']] + ['}']
func += "{\n" func += "{\n"
func += "{ EOp" + caps(data['op']) + ", " + ", ".join("ParamType::" + enum_type(arg) for arg in data['args']) + " },\n" func += "BuiltInId::" + data['op'] + "_" + "_".join([enum_type(arg) for arg in data['args']]) + ",\n"
if 'helper' in data: if 'helper' in data:
func += '"' + '\\n"\n"'.join(data['helper']) + '\\n"\n' func += '"' + '\\n"\n"'.join(data['helper']) + '\\n"\n'
func += '"' + '\\n"\n"'.join(body) + '\\n"\n' func += '"' + '\\n"\n"'.join(body) + '\\n"\n'
......
...@@ -114,7 +114,8 @@ void AddArrayZeroInitForLoop(const TIntermTyped *initializedNode, ...@@ -114,7 +114,8 @@ void AddArrayZeroInitForLoop(const TIntermTyped *initializedNode,
TIntermConstantUnion *arraySizeNode = CreateIndexNode(initializedNode->getOutermostArraySize()); TIntermConstantUnion *arraySizeNode = CreateIndexNode(initializedNode->getOutermostArraySize());
TIntermBinary *indexSmallerThanSize = TIntermBinary *indexSmallerThanSize =
new TIntermBinary(EOpLessThan, indexSymbolNode->deepCopy(), arraySizeNode); new TIntermBinary(EOpLessThan, indexSymbolNode->deepCopy(), arraySizeNode);
TIntermUnary *indexIncrement = new TIntermUnary(EOpPreIncrement, indexSymbolNode->deepCopy()); TIntermUnary *indexIncrement =
new TIntermUnary(EOpPreIncrement, indexSymbolNode->deepCopy(), nullptr);
TIntermBlock *forLoopBody = new TIntermBlock(); TIntermBlock *forLoopBody = new TIntermBlock();
TIntermSequence *forLoopBodySeq = forLoopBody->getSequence(); TIntermSequence *forLoopBodySeq = forLoopBody->getSequence();
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "compiler/translator/tree_ops/RemovePow.h" #include "compiler/translator/tree_ops/RemovePow.h"
#include "compiler/translator/InfoSink.h" #include "compiler/translator/InfoSink.h"
#include "compiler/translator/tree_util/IntermNode_util.h"
#include "compiler/translator/tree_util/IntermTraverse.h" #include "compiler/translator/tree_util/IntermTraverse.h"
namespace sh namespace sh
...@@ -34,7 +35,7 @@ bool IsProblematicPow(TIntermTyped *node) ...@@ -34,7 +35,7 @@ bool IsProblematicPow(TIntermTyped *node)
class RemovePowTraverser : public TIntermTraverser class RemovePowTraverser : public TIntermTraverser
{ {
public: public:
RemovePowTraverser(); RemovePowTraverser(TSymbolTable *symbolTable);
bool visitAggregate(Visit visit, TIntermAggregate *node) override; bool visitAggregate(Visit visit, TIntermAggregate *node) override;
...@@ -45,8 +46,8 @@ class RemovePowTraverser : public TIntermTraverser ...@@ -45,8 +46,8 @@ class RemovePowTraverser : public TIntermTraverser
bool mNeedAnotherIteration; bool mNeedAnotherIteration;
}; };
RemovePowTraverser::RemovePowTraverser() RemovePowTraverser::RemovePowTraverser(TSymbolTable *symbolTable)
: TIntermTraverser(true, false, false), mNeedAnotherIteration(false) : TIntermTraverser(true, false, false, symbolTable), mNeedAnotherIteration(false)
{ {
} }
...@@ -57,14 +58,18 @@ bool RemovePowTraverser::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -57,14 +58,18 @@ bool RemovePowTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
TIntermTyped *x = node->getSequence()->at(0)->getAsTyped(); TIntermTyped *x = node->getSequence()->at(0)->getAsTyped();
TIntermTyped *y = node->getSequence()->at(1)->getAsTyped(); TIntermTyped *y = node->getSequence()->at(1)->getAsTyped();
TIntermUnary *log = new TIntermUnary(EOpLog2, x); TIntermSequence *logArgs = new TIntermSequence();
logArgs->push_back(x);
TIntermTyped *log = CreateBuiltInFunctionCallNode("log2", logArgs, *mSymbolTable, 100);
log->setLine(node->getLine()); log->setLine(node->getLine());
TOperator op = TIntermBinary::GetMulOpBasedOnOperands(y->getType(), log->getType()); TOperator op = TIntermBinary::GetMulOpBasedOnOperands(y->getType(), log->getType());
TIntermBinary *mul = new TIntermBinary(op, y, log); TIntermBinary *mul = new TIntermBinary(op, y, log);
mul->setLine(node->getLine()); mul->setLine(node->getLine());
TIntermUnary *exp = new TIntermUnary(EOpExp2, mul); TIntermSequence *expArgs = new TIntermSequence();
expArgs->push_back(mul);
TIntermTyped *exp = CreateBuiltInFunctionCallNode("exp2", expArgs, *mSymbolTable, 100);
exp->setLine(node->getLine()); exp->setLine(node->getLine());
queueReplacement(exp, OriginalNode::IS_DROPPED); queueReplacement(exp, OriginalNode::IS_DROPPED);
...@@ -82,9 +87,9 @@ bool RemovePowTraverser::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -82,9 +87,9 @@ bool RemovePowTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
} // namespace } // namespace
void RemovePow(TIntermNode *root) void RemovePow(TIntermNode *root, TSymbolTable *symbolTable)
{ {
RemovePowTraverser traverser; RemovePowTraverser traverser(symbolTable);
// Iterate as necessary, and reset the traverser between iterations. // Iterate as necessary, and reset the traverser between iterations.
do do
{ {
......
...@@ -14,8 +14,9 @@ ...@@ -14,8 +14,9 @@
namespace sh namespace sh
{ {
class TIntermNode; class TIntermNode;
class TSymbolTable;
void RemovePow(TIntermNode *root); void RemovePow(TIntermNode *root, TSymbolTable *symbolTable);
} // namespace sh } // namespace sh
#endif // COMPILER_TRANSLATOR_TREEOPS_REMOVEPOW_H_ #endif // COMPILER_TRANSLATOR_TREEOPS_REMOVEPOW_H_
...@@ -96,7 +96,7 @@ class DoWhileRewriter : public TIntermTraverser ...@@ -96,7 +96,7 @@ class DoWhileRewriter : public TIntermTraverser
breakBlock->getSequence()->push_back(breakStatement); breakBlock->getSequence()->push_back(breakStatement);
TIntermUnary *negatedCondition = TIntermUnary *negatedCondition =
new TIntermUnary(EOpLogicalNot, loop->getCondition()); new TIntermUnary(EOpLogicalNot, loop->getCondition(), nullptr);
TIntermIfElse *innerIf = new TIntermIfElse(negatedCondition, breakBlock, nullptr); TIntermIfElse *innerIf = new TIntermIfElse(negatedCondition, breakBlock, nullptr);
......
...@@ -92,7 +92,8 @@ TIntermNode *ElseBlockRewriter::rewriteIfElse(TIntermIfElse *ifElse) ...@@ -92,7 +92,8 @@ TIntermNode *ElseBlockRewriter::rewriteIfElse(TIntermIfElse *ifElse)
} }
TIntermSymbol *conditionSymbolElse = CreateTempSymbolNode(conditionVariable); TIntermSymbol *conditionSymbolElse = CreateTempSymbolNode(conditionVariable);
TIntermUnary *negatedCondition = new TIntermUnary(EOpLogicalNot, conditionSymbolElse); TIntermUnary *negatedCondition =
new TIntermUnary(EOpLogicalNot, conditionSymbolElse, nullptr);
TIntermIfElse *falseIfElse = TIntermIfElse *falseIfElse =
new TIntermIfElse(negatedCondition, ifElse->getFalseBlock(), negatedElse); new TIntermIfElse(negatedCondition, ifElse->getFalseBlock(), negatedElse);
falseBlock = EnsureBlock(falseIfElse); falseBlock = EnsureBlock(falseIfElse);
......
...@@ -75,7 +75,7 @@ bool Traverser::visitUnary(Visit visit, TIntermUnary *node) ...@@ -75,7 +75,7 @@ bool Traverser::visitUnary(Visit visit, TIntermUnary *node)
// Potential problem case detected, apply workaround: -(int) -> ~(int) + 1. // Potential problem case detected, apply workaround: -(int) -> ~(int) + 1.
// ~(int) // ~(int)
TIntermUnary *bitwiseNot = new TIntermUnary(EOpBitwiseNot, opr); TIntermUnary *bitwiseNot = new TIntermUnary(EOpBitwiseNot, opr, nullptr);
bitwiseNot->setLine(opr->getLine()); bitwiseNot->setLine(opr->getLine());
// Constant 1 (or 1u) // Constant 1 (or 1u)
...@@ -109,4 +109,4 @@ void RewriteUnaryMinusOperatorInt(TIntermNode *root) ...@@ -109,4 +109,4 @@ void RewriteUnaryMinusOperatorInt(TIntermNode *root)
Traverser::Apply(root); Traverser::Apply(root);
} }
} // namespace sh } // namespace sh
\ No newline at end of file
...@@ -88,7 +88,7 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node) ...@@ -88,7 +88,7 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node)
CreateTempAssignmentNode(resultVariable, node->getRight())); CreateTempAssignmentNode(resultVariable, node->getRight()));
TIntermUnary *notTempSymbol = TIntermUnary *notTempSymbol =
new TIntermUnary(EOpLogicalNot, CreateTempSymbolNode(resultVariable)); new TIntermUnary(EOpLogicalNot, CreateTempSymbolNode(resultVariable), nullptr);
TIntermIfElse *ifNode = new TIntermIfElse(notTempSymbol, assignRightBlock, nullptr); TIntermIfElse *ifNode = new TIntermIfElse(notTempSymbol, assignRightBlock, nullptr);
insertions.push_back(ifNode); insertions.push_back(ifNode);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -261,7 +261,7 @@ TIntermTyped *CreateBuiltInFunctionCallNode(const char *name, ...@@ -261,7 +261,7 @@ TIntermTyped *CreateBuiltInFunctionCallNode(const char *name,
TOperator op = fn->getBuiltInOp(); TOperator op = fn->getBuiltInOp();
if (op != EOpCallBuiltInFunction && arguments->size() == 1) if (op != EOpCallBuiltInFunction && arguments->size() == 1)
{ {
return new TIntermUnary(op, arguments->at(0)->getAsTyped()); return new TIntermUnary(op, arguments->at(0)->getAsTyped(), fn);
} }
return TIntermAggregate::CreateBuiltInFunctionCall(*fn, arguments); return TIntermAggregate::CreateBuiltInFunctionCall(*fn, arguments);
} }
......
...@@ -196,7 +196,7 @@ TEST_F(IntermNodeTest, DeepCopyUnaryNode) ...@@ -196,7 +196,7 @@ TEST_F(IntermNodeTest, DeepCopyUnaryNode)
{ {
TType type(EbtFloat, EbpHigh); TType type(EbtFloat, EbpHigh);
TIntermUnary *original = new TIntermUnary(EOpPreIncrement, createTestSymbol()); TIntermUnary *original = new TIntermUnary(EOpPreIncrement, createTestSymbol(), nullptr);
original->setLine(getTestSourceLoc()); original->setLine(getTestSourceLoc());
TIntermTyped *copyTyped = original->deepCopy(); TIntermTyped *copyTyped = original->deepCopy();
TIntermUnary *copy = copyTyped->getAsUnaryNode(); TIntermUnary *copy = copyTyped->getAsUnaryNode();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment