• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_MSL_MODIFYSTRUCT_H_
8 #define COMPILER_TRANSLATOR_MSL_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/msl/IdGen.h"
16 #include "compiler/translator/msl/Layout.h"
17 #include "compiler/translator/msl/Name.h"
18 #include "compiler/translator/msl/ProgramPrelude.h"
19 #include "compiler/translator/msl/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 = uint8_t (*)(const TField &);
DontSaturateSaturateVector46         static uint8_t DontSaturate(const TField &) { return 0; }
FullySaturateSaturateVector47         static uint8_t 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 uint32_t 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_MSL_MODIFYSTRUCT_H_
140