1 // 2 // Copyright 2020 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 #ifndef COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_SYMBOLENV_H_ 8 #define COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_SYMBOLENV_H_ 9 10 #include <unordered_set> 11 12 #include "compiler/translator/Compiler.h" 13 #include "compiler/translator/TranslatorMetalDirect/Name.h" 14 #include "compiler/translator/TranslatorMetalDirect/Reference.h" 15 #include "compiler/translator/Types.h" 16 17 namespace sh 18 { 19 20 enum class AddressSpace 21 { 22 Constant, 23 Device, 24 Thread, 25 }; 26 27 char const *toString(AddressSpace space); 28 29 class VarField 30 { 31 public: VarField(const TVariable & var)32 VarField(const TVariable &var) : mVariable(&var) {} VarField(const TField & field)33 VarField(const TField &field) : mField(&field) {} 34 variable()35 ANGLE_INLINE const TVariable *variable() const { return mVariable; } 36 field()37 ANGLE_INLINE const TField *field() const { return mField; } 38 39 ANGLE_INLINE bool operator==(const VarField &other) const 40 { 41 return mVariable == other.mVariable && mField == other.mField; 42 } 43 44 private: 45 const TVariable *mVariable = nullptr; 46 const TField *mField = nullptr; 47 }; 48 49 } // namespace sh 50 51 namespace std 52 { 53 54 template <> 55 struct hash<sh::VarField> 56 { 57 size_t operator()(const sh::VarField &x) const 58 { 59 const sh::TVariable *var = x.variable(); 60 if (var) 61 { 62 return std::hash<const sh::TVariable *>()(var); 63 } 64 const sh::TField *field = x.field(); 65 return std::hash<const sh::TField *>()(field); 66 } 67 }; 68 69 } // namespace std 70 71 namespace sh 72 { 73 74 class TemplateArg 75 { 76 public: 77 enum class Kind 78 { 79 Bool, 80 Int, 81 UInt, 82 Type, 83 }; 84 85 union Value 86 { 87 Value(bool value) : b(value) {} 88 Value(int value) : i(value) {} 89 Value(unsigned value) : u(value) {} 90 Value(const TType &value) : t(&value) {} 91 92 bool b; 93 int i; 94 unsigned u; 95 const TType *t; 96 }; 97 98 TemplateArg(bool value); 99 TemplateArg(int value); 100 TemplateArg(unsigned value); 101 TemplateArg(const TType &value); 102 103 bool operator==(const TemplateArg &other) const; 104 bool operator<(const TemplateArg &other) const; 105 106 Kind kind() const { return mKind; } 107 Value value() const { return mValue; } 108 109 public: 110 Kind mKind; 111 Value mValue; 112 }; 113 114 // An environment for creating and uniquely sharing TSymbol objects. 115 class SymbolEnv 116 { 117 class TemplateName 118 { 119 Name baseName; 120 std::vector<TemplateArg> templateArgs; 121 122 public: 123 bool operator==(const TemplateName &other) const; 124 bool operator<(const TemplateName &other) const; 125 126 bool empty() const; 127 void clear(); 128 129 Name fullName(std::string &buffer) const; 130 131 void assign(const Name &name, size_t argCount, const TemplateArg *args); 132 }; 133 134 using TypeRef = CRef<TType>; 135 using Sig = std::vector<TypeRef>; // Param0, Param1, ... ParamN, Return 136 using SigToFunc = std::map<Sig, TFunction *>; 137 using Overloads = std::map<TemplateName, SigToFunc>; 138 using AngleStructs = std::map<ImmutableString, TStructure *>; 139 using TextureStructs = std::map<TBasicType, TStructure *>; 140 141 public: 142 SymbolEnv(TCompiler &compiler, TIntermBlock &root); 143 144 TSymbolTable &symbolTable() { return mSymbolTable; } 145 146 // There exist Angle rewrites that can lead to incoherent structs 147 // 148 // Example 149 // struct A { ... } 150 // struct B { A' a; } // A' has same name as A but is not identical. 151 // becomes 152 // struct A { ... } 153 // struct B { A a; } 154 // 155 // This notably happens when A contains a sampler in the original GLSL code but is rewritten to 156 // not have a sampler, yet the A' struct field still contains the sampler field. 157 const TStructure &remap(const TStructure &s) const; 158 159 // Like `TStructure &remap(const TStructure &s)` but additionally maps null to null. 160 const TStructure *remap(const TStructure *s) const; 161 162 const TFunction &getFunctionOverload(const Name &name, 163 const TType &returnType, 164 size_t paramCount, 165 const TType **paramTypes, 166 size_t templateArgCount = 0, 167 const TemplateArg *templateArgs = nullptr); 168 169 TIntermAggregate &callFunctionOverload(const Name &name, 170 const TType &returnType, 171 TIntermSequence &args, 172 size_t templateArgCount = 0, 173 const TemplateArg *templateArgs = nullptr); 174 175 const TStructure &newStructure(const Name &name, TFieldList &fields); 176 177 const TStructure &getTextureEnv(TBasicType samplerType); 178 const TStructure &getSamplerStruct(); 179 180 void markAsPointer(VarField x, AddressSpace space); 181 void removePointer(VarField x); 182 const AddressSpace *isPointer(VarField x) const; 183 184 void markAsReference(VarField x, AddressSpace space); 185 void removeAsReference(VarField x); 186 const AddressSpace *isReference(VarField x) const; 187 188 void markAsPacked(const TField &field); 189 bool isPacked(const TField &field) const; 190 191 void markAsUBO(VarField x); 192 bool isUBO(VarField x) const; 193 194 private: 195 const TFunction &getFunctionOverloadImpl(); 196 197 void markSpace(VarField x, AddressSpace space, std::unordered_map<VarField, AddressSpace> &map); 198 void removeSpace(VarField x, std::unordered_map<VarField, AddressSpace> &map); 199 const AddressSpace *isSpace(VarField x, 200 const std::unordered_map<VarField, AddressSpace> &map) const; 201 202 private: 203 TSymbolTable &mSymbolTable; 204 205 std::map<Name, const TStructure *> mNameToStruct; 206 Overloads mOverloads; 207 Sig mReusableSigBuffer; 208 TemplateName mReusableTemplateNameBuffer; 209 std::string mReusableStringBuffer; 210 211 AngleStructs mAngleStructs; 212 std::unordered_map<TBasicType, const TStructure *> mTextureEnvs; 213 const TStructure *mSampler = nullptr; 214 215 std::unordered_map<VarField, AddressSpace> mPointers; 216 std::unordered_map<VarField, AddressSpace> mReferences; 217 std::unordered_set<const TField *> mPackedFields; 218 std::unordered_set<VarField> mUboFields; 219 }; 220 221 Name GetTextureTypeName(TBasicType samplerType); 222 223 } // namespace sh 224 225 #endif // COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_SYMBOLENV_H_ 226