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_MODIFYSTRUCT_H_ 8 #define COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_MODIFYSTRUCT_H_ 9 10 #include <cstring> 11 #include <unordered_map> 12 #include <unordered_set> 13 14 #include "compiler/translator/Compiler.h" 15 #include "compiler/translator/TranslatorMetalDirect/IdGen.h" 16 #include "compiler/translator/TranslatorMetalDirect/Layout.h" 17 #include "compiler/translator/TranslatorMetalDirect/Name.h" 18 #include "compiler/translator/TranslatorMetalDirect/ProgramPrelude.h" 19 #include "compiler/translator/TranslatorMetalDirect/SymbolEnv.h" 20 21 namespace sh 22 { 23 24 enum class ConvertType 25 { 26 OriginalToModified, 27 ModifiedToOriginal, 28 }; 29 30 // Configures how struct modification is performed. 31 class ModifyStructConfig 32 { 33 public: 34 struct Predicate 35 { 36 using Func = bool (*)(const TField &); FalsePredicate37 static bool False(const TField &) { return false; } TruePredicate38 static bool True(const TField &) { return true; } 39 }; 40 41 struct SaturateVector 42 { 43 // Valid return values are [0, 1, 2, 3, 4]. 44 // If original dim >= return value, the field remains untouched. 45 using Func = int (*)(const TField &); DontSaturateSaturateVector46 static int DontSaturate(const TField &) { return 0; } FullySaturateSaturateVector47 static int FullySaturate(const TField &) { return 4; } 48 }; 49 50 public: ModifyStructConfig(ConvertType convertType,bool allowPacking,bool allowPadding)51 ModifyStructConfig(ConvertType convertType, bool allowPacking, bool allowPadding) 52 : convertType(convertType), allowPacking(allowPacking), allowPadding(allowPadding) 53 {} 54 55 // Matrix field is split into multiple fields of row vectors. 56 Predicate::Func splitMatrixColumns = Predicate::False; 57 58 // Array fields are split into multiple fields of element type. 59 Predicate::Func inlineArray = Predicate::False; 60 61 // Struct fields have their subfields inlined directly. 62 Predicate::Func inlineStruct = Predicate::False; 63 64 // Struct fields are modified. 65 Predicate::Func recurseStruct = Predicate::False; 66 67 // Vector and scalar bool fields are promoted to uint fields. 68 Predicate::Func promoteBoolToUint = Predicate::False; 69 70 // Creates a new structure where scalar or vector fields are saturated vectors. 71 // e.g. `float -> float4`. 72 // e.g. `float2 -> float4`. 73 SaturateVector::Func saturateScalarOrVector = SaturateVector::DontSaturate; 74 75 // Creates a new structure where scalar or vector array fields are saturated. 76 // e.g. `float[10] -> float4[10]` 77 // e.g. `float2[10] -> float4[10]` 78 SaturateVector::Func saturateScalarOrVectorArrays = SaturateVector::DontSaturate; 79 80 // Creates a new structure where matrix fields are row-saturated. 81 // e.g. `float2x2 -> float2x4`. 82 SaturateVector::Func saturateMatrixRows = SaturateVector::DontSaturate; 83 84 TLayoutBlockStorage initialBlockStorage = kDefaultLayoutBlockStorage; 85 TLayoutMatrixPacking initialMatrixPacking = kDefaultLayoutMatrixPacking; 86 ConvertType convertType; 87 bool allowPacking; 88 bool allowPadding; 89 AddressSpace externalAddressSpace; 90 }; 91 92 struct ModifiedStructMachinery 93 { 94 const TStructure *modifiedStruct = nullptr; 95 TIntermFunctionDefinition *funcOriginalToModified = nullptr; 96 TIntermFunctionDefinition *funcModifiedToOriginal = nullptr; 97 getConverterModifiedStructMachinery98 TIntermFunctionDefinition *&getConverter(ConvertType convertType) 99 { 100 if (convertType == ConvertType::OriginalToModified) 101 { 102 return funcOriginalToModified; 103 } 104 else 105 { 106 return funcModifiedToOriginal; 107 } 108 } 109 }; 110 111 // Indexed by topological order. 112 class ModifiedStructMachineries 113 { 114 public: 115 size_t size() const; 116 const ModifiedStructMachinery &at(size_t index) const; 117 const ModifiedStructMachinery *find(const TStructure &s) const; 118 void insert(const TStructure &s, const ModifiedStructMachinery &machinery); 119 120 private: 121 std::unordered_map<const TStructure *, ModifiedStructMachinery> originalToMachinery; 122 std::vector<const TStructure *> ordering; 123 }; 124 125 // Returns true and `outMachinery` populated if modifications were performed. 126 // Returns false otherwise. 127 bool TryCreateModifiedStruct(TCompiler &compiler, 128 SymbolEnv &symbolEnv, 129 IdGen &idGen, 130 const ModifyStructConfig &config, 131 const TStructure &originalStruct, 132 const Name &modifiedStructName, 133 ModifiedStructMachineries &outMachineries, 134 const bool isUBO, 135 const bool allowPadding); 136 137 } // namespace sh 138 139 #endif // COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_MODIFYSTRUCT_H_ 140