1 // Copyright 2018 The SwiftShader Authors. All Rights Reserved.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
15 #ifndef sw_SpirvShader_hpp
16 #define sw_SpirvShader_hpp
18 #include "System/Types.hpp"
19 #include "Vulkan/VkDebug.hpp"
23 #include <unordered_map>
25 #include <type_traits>
26 #include <spirv/unified1/spirv.hpp>
33 using InsnStore = std::vector<uint32_t>;
36 /* Pseudo-iterator over SPIRV instructions, designed to support range-based-for. */
39 InsnStore::const_iterator iter;
42 spv::Op opcode() const
44 return static_cast<spv::Op>(*iter & spv::OpCodeMask);
47 uint32_t wordCount() const
49 return *iter >> spv::WordCountShift;
52 uint32_t word(uint32_t n) const
54 ASSERT(n < wordCount());
58 bool operator!=(InsnIterator const &other) const
60 return iter != other.iter;
63 InsnIterator operator*() const
68 InsnIterator &operator++()
74 InsnIterator const operator++(int)
76 InsnIterator ret{*this};
81 InsnIterator(InsnIterator const &other) = default;
83 InsnIterator() = default;
85 explicit InsnIterator(InsnStore::const_iterator iter) : iter{iter}
90 /* range-based-for interface */
91 InsnIterator begin() const
93 return InsnIterator{insns.cbegin() + 5};
96 InsnIterator end() const
98 return InsnIterator{insns.cend()};
104 InsnIterator definition;
105 spv::StorageClass storageClass;
106 uint32_t sizeInComponents = 0;
107 bool isBuiltInBlock = false;
111 Unknown, /* for paranoia -- if we get left with an object in this state, the module was broken */
116 } kind = Kind::Unknown;
119 int getSerialID() const
124 explicit SpirvShader(InsnStore const &insns);
128 bool EarlyFragmentTests : 1;
129 bool DepthReplacing : 1;
130 bool DepthGreater : 1;
132 bool DepthUnchanged : 1;
133 bool ContainsKill : 1;
135 // Compute workgroup dimensions
136 int LocalSizeX, LocalSizeY, LocalSizeZ;
139 Modes const &getModes() const
144 enum AttribType : unsigned char
151 ATTRIBTYPE_LAST = ATTRIBTYPE_UINT
154 bool hasBuiltinInput(spv::BuiltIn b) const
156 return inputBuiltins.find(b) != inputBuiltins.end();
163 spv::BuiltIn BuiltIn;
164 bool HasLocation : 1;
165 bool HasComponent : 1;
169 bool NoPerspective : 1;
171 bool BufferBlock : 1;
174 : Location{-1}, Component{0}, BuiltIn{}, HasLocation{false}, HasComponent{false}, HasBuiltIn{false},
176 Centroid{false}, NoPerspective{false}, Block{false},
181 Decorations(Decorations const &) = default;
183 void Apply(Decorations const &src);
185 void Apply(spv::Decoration decoration, uint32_t arg);
188 std::unordered_map<uint32_t, Decorations> decorations;
189 std::unordered_map<uint32_t, std::vector<Decorations>> memberDecorations;
191 struct InterfaceComponent
196 bool NoPerspective : 1;
199 : Type{ATTRIBTYPE_UNUSED}, Flat{false}, Centroid{false}, NoPerspective{false}
204 struct BuiltinMapping
207 uint32_t FirstComponent;
208 uint32_t SizeInComponents;
211 std::vector<InterfaceComponent> inputs;
212 std::vector<InterfaceComponent> outputs;
216 static volatile int serialCounter;
218 std::unordered_map<uint32_t, Object> types;
219 std::unordered_map<uint32_t, Object> defs;
221 using BuiltInHash = std::hash<std::underlying_type<spv::BuiltIn>::type>;
222 std::unordered_map<spv::BuiltIn, BuiltinMapping, BuiltInHash> inputBuiltins;
223 std::unordered_map<spv::BuiltIn, BuiltinMapping, BuiltInHash> outputBuiltins;
225 Object const &getType(uint32_t id) const
227 auto it = types.find(id);
228 assert(it != types.end());
232 void ProcessExecutionMode(InsnIterator it);
234 uint32_t ComputeTypeSize(InsnIterator insn);
236 void PopulateInterfaceSlot(std::vector<InterfaceComponent> *iface, Decorations const &d, AttribType type);
238 int PopulateInterfaceInner(std::vector<InterfaceComponent> *iface, uint32_t id, Decorations d);
240 void PopulateInterface(std::vector<InterfaceComponent> *iface, uint32_t id);
242 uint32_t GetConstantInt(uint32_t id);
244 void ProcessInterfaceVariable(Object const &object);
248 #endif // sw_SpirvShader_hpp