OSDN Git Service

Implement some common forms of OpLoad
[android-x86/external-swiftshader.git] / src / Pipeline / SpirvShader.hpp
1 // Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #ifndef sw_SpirvShader_hpp
16 #define sw_SpirvShader_hpp
17
18 #include "System/Types.hpp"
19 #include "Vulkan/VkDebug.hpp"
20 #include "ShaderCore.hpp"
21
22 #include <string>
23 #include <vector>
24 #include <unordered_map>
25 #include <cstdint>
26 #include <type_traits>
27 #include <memory>
28 #include <spirv/unified1/spirv.hpp>
29 #include <Device/Config.hpp>
30
31 namespace sw
32 {
33         class SpirvRoutine
34         {
35         public:
36                 using Value = Array<Float4>;
37                 std::unordered_map<uint32_t, std::unique_ptr<Value>> lvalues;
38                 std::unique_ptr<Value> inputs = std::unique_ptr<Value>(new Value(MAX_INTERFACE_COMPONENTS));
39                 std::unique_ptr<Value> outputs = std::unique_ptr<Value>(new Value(MAX_INTERFACE_COMPONENTS));
40
41                 void createLvalue(uint32_t id, uint32_t size)
42                 {
43                         lvalues.emplace(id, std::unique_ptr<Value>(new Value(size)));
44                 }
45         };
46
47         class SpirvShader
48         {
49         public:
50                 using InsnStore = std::vector<uint32_t>;
51                 InsnStore insns;
52
53                 /* Pseudo-iterator over SPIRV instructions, designed to support range-based-for. */
54                 class InsnIterator
55                 {
56                         InsnStore::const_iterator iter;
57
58                 public:
59                         spv::Op opcode() const
60                         {
61                                 return static_cast<spv::Op>(*iter & spv::OpCodeMask);
62                         }
63
64                         uint32_t wordCount() const
65                         {
66                                 return *iter >> spv::WordCountShift;
67                         }
68
69                         uint32_t word(uint32_t n) const
70                         {
71                                 ASSERT(n < wordCount());
72                                 return iter[n];
73                         }
74
75                         bool operator!=(InsnIterator const &other) const
76                         {
77                                 return iter != other.iter;
78                         }
79
80                         InsnIterator operator*() const
81                         {
82                                 return *this;
83                         }
84
85                         InsnIterator &operator++()
86                         {
87                                 iter += wordCount();
88                                 return *this;
89                         }
90
91                         InsnIterator const operator++(int)
92                         {
93                                 InsnIterator ret{*this};
94                                 iter += wordCount();
95                                 return ret;
96                         }
97
98                         InsnIterator(InsnIterator const &other) = default;
99
100                         InsnIterator() = default;
101
102                         explicit InsnIterator(InsnStore::const_iterator iter) : iter{iter}
103                         {
104                         }
105                 };
106
107                 /* range-based-for interface */
108                 InsnIterator begin() const
109                 {
110                         return InsnIterator{insns.cbegin() + 5};
111                 }
112
113                 InsnIterator end() const
114                 {
115                         return InsnIterator{insns.cend()};
116                 }
117
118                 class Object
119                 {
120                 public:
121                         InsnIterator definition;
122                         spv::StorageClass storageClass;
123                         uint32_t sizeInComponents = 0;
124                         bool isBuiltInBlock = false;
125                         uint32_t pointerBase = 0;
126
127                         enum class Kind
128                         {
129                                 Unknown,        /* for paranoia -- if we get left with an object in this state, the module was broken */
130                                 Type,
131                                 Variable,
132                                 InterfaceVariable,
133                                 Constant,
134                                 Value,
135                         } kind = Kind::Unknown;
136                 };
137
138                 int getSerialID() const
139                 {
140                         return serialID;
141                 }
142
143                 explicit SpirvShader(InsnStore const &insns);
144
145                 struct Modes
146                 {
147                         bool EarlyFragmentTests : 1;
148                         bool DepthReplacing : 1;
149                         bool DepthGreater : 1;
150                         bool DepthLess : 1;
151                         bool DepthUnchanged : 1;
152                         bool ContainsKill : 1;
153                         bool NeedsCentroid : 1;
154
155                         // Compute workgroup dimensions
156                         int LocalSizeX, LocalSizeY, LocalSizeZ;
157                 };
158
159                 Modes const &getModes() const
160                 {
161                         return modes;
162                 }
163
164                 enum AttribType : unsigned char
165                 {
166                         ATTRIBTYPE_FLOAT,
167                         ATTRIBTYPE_INT,
168                         ATTRIBTYPE_UINT,
169                         ATTRIBTYPE_UNUSED,
170
171                         ATTRIBTYPE_LAST = ATTRIBTYPE_UINT
172                 };
173
174                 bool hasBuiltinInput(spv::BuiltIn b) const
175                 {
176                         return inputBuiltins.find(b) != inputBuiltins.end();
177                 }
178
179                 struct Decorations
180                 {
181                         int32_t Location;
182                         int32_t Component;
183                         spv::BuiltIn BuiltIn;
184                         bool HasLocation : 1;
185                         bool HasComponent : 1;
186                         bool HasBuiltIn : 1;
187                         bool Flat : 1;
188                         bool Centroid : 1;
189                         bool NoPerspective : 1;
190                         bool Block : 1;
191                         bool BufferBlock : 1;
192
193                         Decorations()
194                                         : Location{-1}, Component{0}, BuiltIn{}, HasLocation{false}, HasComponent{false}, HasBuiltIn{false},
195                                           Flat{false},
196                                           Centroid{false}, NoPerspective{false}, Block{false},
197                                           BufferBlock{false}
198                         {
199                         }
200
201                         Decorations(Decorations const &) = default;
202
203                         void Apply(Decorations const &src);
204
205                         void Apply(spv::Decoration decoration, uint32_t arg);
206                 };
207
208                 std::unordered_map<uint32_t, Decorations> decorations;
209                 std::unordered_map<uint32_t, std::vector<Decorations>> memberDecorations;
210
211                 struct InterfaceComponent
212                 {
213                         AttribType Type;
214                         bool Flat : 1;
215                         bool Centroid : 1;
216                         bool NoPerspective : 1;
217
218                         InterfaceComponent()
219                                         : Type{ATTRIBTYPE_UNUSED}, Flat{false}, Centroid{false}, NoPerspective{false}
220                         {
221                         }
222                 };
223
224                 struct BuiltinMapping
225                 {
226                         uint32_t Id;
227                         uint32_t FirstComponent;
228                         uint32_t SizeInComponents;
229                 };
230
231                 std::vector<InterfaceComponent> inputs;
232                 std::vector<InterfaceComponent> outputs;
233
234                 void emitEarly(SpirvRoutine *routine) const;
235
236                 void emit(SpirvRoutine *routine) const;
237
238                 using BuiltInHash = std::hash<std::underlying_type<spv::BuiltIn>::type>;
239                 std::unordered_map<spv::BuiltIn, BuiltinMapping, BuiltInHash> inputBuiltins;
240                 std::unordered_map<spv::BuiltIn, BuiltinMapping, BuiltInHash> outputBuiltins;
241
242                 Object const &getType(uint32_t id) const
243                 {
244                         auto it = types.find(id);
245                         assert(it != types.end());
246                         return it->second;
247                 }
248
249                 Object const &getObject(uint32_t id) const
250                 {
251                         auto it = defs.find(id);
252                         assert(it != defs.end());
253                         return it->second;
254                 }
255
256         private:
257                 const int serialID;
258                 static volatile int serialCounter;
259                 Modes modes;
260                 std::unordered_map<uint32_t, Object> types;
261                 std::unordered_map<uint32_t, Object> defs;
262
263                 void ProcessExecutionMode(InsnIterator it);
264
265                 uint32_t ComputeTypeSize(InsnIterator insn);
266                 void ApplyDecorationsForId(Decorations *d, uint32_t id) const;
267                 void ApplyDecorationsForIdMember(Decorations *d, uint32_t id, uint32_t member) const;
268
269                 template<typename F>
270                 int VisitInterfaceInner(uint32_t id, Decorations d, F f) const;
271
272                 template<typename F>
273                 void VisitInterface(uint32_t id, F f) const;
274
275                 uint32_t GetConstantInt(uint32_t id) const;
276
277                 void ProcessInterfaceVariable(Object &object);
278         };
279 }
280
281 #endif  // sw_SpirvShader_hpp