summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/spirv/emit_spirv.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/backend/spirv/emit_spirv.h')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv.h314
1 files changed, 311 insertions, 3 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h
index 99cc8e08a..3f4b68a7d 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv.h
+++ b/src/shader_recompiler/backend/spirv/emit_spirv.h
@@ -4,18 +4,326 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <sirit/sirit.h>
8
9#include <boost/container/flat_map.hpp>
10
11#include "common/common_types.h"
7#include "shader_recompiler/frontend/ir/microinstruction.h" 12#include "shader_recompiler/frontend/ir/microinstruction.h"
8#include "shader_recompiler/frontend/ir/program.h" 13#include "shader_recompiler/frontend/ir/program.h"
9 14
10namespace Shader::Backend::SPIRV { 15namespace Shader::Backend::SPIRV {
11 16
17using Sirit::Id;
18
19class DefMap {
20public:
21 void Define(IR::Inst* inst, Id def_id) {
22 const InstInfo info{.use_count{inst->UseCount()}, .def_id{def_id}};
23 const auto it{map.insert(map.end(), std::make_pair(inst, info))};
24 if (it == map.end()) {
25 throw LogicError("Defining already defined instruction");
26 }
27 }
28
29 [[nodiscard]] Id Consume(IR::Inst* inst) {
30 const auto it{map.find(inst)};
31 if (it == map.end()) {
32 throw LogicError("Consuming undefined instruction");
33 }
34 const Id def_id{it->second.def_id};
35 if (--it->second.use_count == 0) {
36 map.erase(it);
37 }
38 return def_id;
39 }
40
41private:
42 struct InstInfo {
43 int use_count;
44 Id def_id;
45 };
46
47 boost::container::flat_map<IR::Inst*, InstInfo> map;
48};
49
50class VectorTypes {
51public:
52 void Define(Sirit::Module& sirit_ctx, Id base_type, std::string_view name) {
53 defs[0] = sirit_ctx.Name(base_type, name);
54
55 std::array<char, 6> def_name;
56 for (int i = 1; i < 4; ++i) {
57 const std::string_view def_name_view(
58 def_name.data(),
59 fmt::format_to_n(def_name.data(), def_name.size(), "{}x{}", name, i + 1).size);
60 defs[i] = sirit_ctx.Name(sirit_ctx.TypeVector(base_type, i + 1), def_name_view);
61 }
62 }
63
64 [[nodiscard]] Id operator[](size_t size) const noexcept {
65 return defs[size - 1];
66 }
67
68private:
69 std::array<Id, 4> defs;
70};
71
72class EmitContext final : public Sirit::Module {
73public:
74 explicit EmitContext(IR::Program& program);
75 ~EmitContext();
76
77 [[nodiscard]] Id Def(const IR::Value& value) {
78 if (!value.IsImmediate()) {
79 return def_map.Consume(value.Inst());
80 }
81 switch (value.Type()) {
82 case IR::Type::U32:
83 return Constant(u32[1], value.U32());
84 case IR::Type::F32:
85 return Constant(f32[1], value.F32());
86 default:
87 throw NotImplementedException("Immediate type {}", value.Type());
88 }
89 }
90
91 void Define(IR::Inst* inst, Id def_id) {
92 def_map.Define(inst, def_id);
93 }
94
95 [[nodiscard]] Id BlockLabel(IR::Block* block) const {
96 const auto it{std::ranges::lower_bound(block_label_map, block, {},
97 &std::pair<IR::Block*, Id>::first)};
98 if (it == block_label_map.end()) {
99 throw LogicError("Undefined block");
100 }
101 return it->second;
102 }
103
104 Id void_id{};
105 Id u1{};
106 VectorTypes f32;
107 VectorTypes u32;
108 VectorTypes f16;
109 VectorTypes f64;
110
111 Id workgroup_id{};
112 Id local_invocation_id{};
113
114private:
115 DefMap def_map;
116 std::vector<std::pair<IR::Block*, Id>> block_label_map;
117};
118
12class EmitSPIRV { 119class EmitSPIRV {
13public: 120public:
121 explicit EmitSPIRV(IR::Program& program);
122
14private: 123private:
124 void EmitInst(EmitContext& ctx, IR::Inst* inst);
125
15 // Microinstruction emitters 126 // Microinstruction emitters
16#define OPCODE(name, result_type, ...) void Emit##name(EmitContext& ctx, IR::Inst* inst); 127 void EmitPhi(EmitContext& ctx);
17#include "shader_recompiler/frontend/ir/opcodes.inc" 128 void EmitVoid(EmitContext& ctx);
18#undef OPCODE 129 void EmitIdentity(EmitContext& ctx);
130 void EmitBranch(EmitContext& ctx, IR::Inst* inst);
131 void EmitBranchConditional(EmitContext& ctx, IR::Inst* inst);
132 void EmitExit(EmitContext& ctx);
133 void EmitReturn(EmitContext& ctx);
134 void EmitUnreachable(EmitContext& ctx);
135 void EmitGetRegister(EmitContext& ctx);
136 void EmitSetRegister(EmitContext& ctx);
137 void EmitGetPred(EmitContext& ctx);
138 void EmitSetPred(EmitContext& ctx);
139 Id EmitGetCbuf(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset);
140 void EmitGetAttribute(EmitContext& ctx);
141 void EmitSetAttribute(EmitContext& ctx);
142 void EmitGetAttributeIndexed(EmitContext& ctx);
143 void EmitSetAttributeIndexed(EmitContext& ctx);
144 void EmitGetZFlag(EmitContext& ctx);
145 void EmitGetSFlag(EmitContext& ctx);
146 void EmitGetCFlag(EmitContext& ctx);
147 void EmitGetOFlag(EmitContext& ctx);
148 void EmitSetZFlag(EmitContext& ctx);
149 void EmitSetSFlag(EmitContext& ctx);
150 void EmitSetCFlag(EmitContext& ctx);
151 void EmitSetOFlag(EmitContext& ctx);
152 Id EmitWorkgroupId(EmitContext& ctx);
153 Id EmitLocalInvocationId(EmitContext& ctx);
154 void EmitUndef1(EmitContext& ctx);
155 void EmitUndef8(EmitContext& ctx);
156 void EmitUndef16(EmitContext& ctx);
157 void EmitUndef32(EmitContext& ctx);
158 void EmitUndef64(EmitContext& ctx);
159 void EmitLoadGlobalU8(EmitContext& ctx);
160 void EmitLoadGlobalS8(EmitContext& ctx);
161 void EmitLoadGlobalU16(EmitContext& ctx);
162 void EmitLoadGlobalS16(EmitContext& ctx);
163 void EmitLoadGlobal32(EmitContext& ctx);
164 void EmitLoadGlobal64(EmitContext& ctx);
165 void EmitLoadGlobal128(EmitContext& ctx);
166 void EmitWriteGlobalU8(EmitContext& ctx);
167 void EmitWriteGlobalS8(EmitContext& ctx);
168 void EmitWriteGlobalU16(EmitContext& ctx);
169 void EmitWriteGlobalS16(EmitContext& ctx);
170 void EmitWriteGlobal32(EmitContext& ctx);
171 void EmitWriteGlobal64(EmitContext& ctx);
172 void EmitWriteGlobal128(EmitContext& ctx);
173 void EmitLoadStorageU8(EmitContext& ctx);
174 void EmitLoadStorageS8(EmitContext& ctx);
175 void EmitLoadStorageU16(EmitContext& ctx);
176 void EmitLoadStorageS16(EmitContext& ctx);
177 Id EmitLoadStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset);
178 void EmitLoadStorage64(EmitContext& ctx);
179 void EmitLoadStorage128(EmitContext& ctx);
180 void EmitWriteStorageU8(EmitContext& ctx);
181 void EmitWriteStorageS8(EmitContext& ctx);
182 void EmitWriteStorageU16(EmitContext& ctx);
183 void EmitWriteStorageS16(EmitContext& ctx);
184 void EmitWriteStorage32(EmitContext& ctx);
185 void EmitWriteStorage64(EmitContext& ctx);
186 void EmitWriteStorage128(EmitContext& ctx);
187 void EmitCompositeConstructU32x2(EmitContext& ctx);
188 void EmitCompositeConstructU32x3(EmitContext& ctx);
189 void EmitCompositeConstructU32x4(EmitContext& ctx);
190 void EmitCompositeExtractU32x2(EmitContext& ctx);
191 Id EmitCompositeExtractU32x3(EmitContext& ctx, Id vector, u32 index);
192 void EmitCompositeExtractU32x4(EmitContext& ctx);
193 void EmitCompositeConstructF16x2(EmitContext& ctx);
194 void EmitCompositeConstructF16x3(EmitContext& ctx);
195 void EmitCompositeConstructF16x4(EmitContext& ctx);
196 void EmitCompositeExtractF16x2(EmitContext& ctx);
197 void EmitCompositeExtractF16x3(EmitContext& ctx);
198 void EmitCompositeExtractF16x4(EmitContext& ctx);
199 void EmitCompositeConstructF32x2(EmitContext& ctx);
200 void EmitCompositeConstructF32x3(EmitContext& ctx);
201 void EmitCompositeConstructF32x4(EmitContext& ctx);
202 void EmitCompositeExtractF32x2(EmitContext& ctx);
203 void EmitCompositeExtractF32x3(EmitContext& ctx);
204 void EmitCompositeExtractF32x4(EmitContext& ctx);
205 void EmitCompositeConstructF64x2(EmitContext& ctx);
206 void EmitCompositeConstructF64x3(EmitContext& ctx);
207 void EmitCompositeConstructF64x4(EmitContext& ctx);
208 void EmitCompositeExtractF64x2(EmitContext& ctx);
209 void EmitCompositeExtractF64x3(EmitContext& ctx);
210 void EmitCompositeExtractF64x4(EmitContext& ctx);
211 void EmitSelect8(EmitContext& ctx);
212 void EmitSelect16(EmitContext& ctx);
213 void EmitSelect32(EmitContext& ctx);
214 void EmitSelect64(EmitContext& ctx);
215 void EmitBitCastU16F16(EmitContext& ctx);
216 Id EmitBitCastU32F32(EmitContext& ctx, Id value);
217 void EmitBitCastU64F64(EmitContext& ctx);
218 void EmitBitCastF16U16(EmitContext& ctx);
219 Id EmitBitCastF32U32(EmitContext& ctx, Id value);
220 void EmitBitCastF64U64(EmitContext& ctx);
221 void EmitPackUint2x32(EmitContext& ctx);
222 void EmitUnpackUint2x32(EmitContext& ctx);
223 void EmitPackFloat2x16(EmitContext& ctx);
224 void EmitUnpackFloat2x16(EmitContext& ctx);
225 void EmitPackDouble2x32(EmitContext& ctx);
226 void EmitUnpackDouble2x32(EmitContext& ctx);
227 void EmitGetZeroFromOp(EmitContext& ctx);
228 void EmitGetSignFromOp(EmitContext& ctx);
229 void EmitGetCarryFromOp(EmitContext& ctx);
230 void EmitGetOverflowFromOp(EmitContext& ctx);
231 void EmitFPAbs16(EmitContext& ctx);
232 void EmitFPAbs32(EmitContext& ctx);
233 void EmitFPAbs64(EmitContext& ctx);
234 Id EmitFPAdd16(EmitContext& ctx, IR::Inst* inst, Id a, Id b);
235 Id EmitFPAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b);
236 Id EmitFPAdd64(EmitContext& ctx, IR::Inst* inst, Id a, Id b);
237 Id EmitFPFma16(EmitContext& ctx, IR::Inst* inst, Id a, Id b, Id c);
238 Id EmitFPFma32(EmitContext& ctx, IR::Inst* inst, Id a, Id b, Id c);
239 Id EmitFPFma64(EmitContext& ctx, IR::Inst* inst, Id a, Id b, Id c);
240 void EmitFPMax32(EmitContext& ctx);
241 void EmitFPMax64(EmitContext& ctx);
242 void EmitFPMin32(EmitContext& ctx);
243 void EmitFPMin64(EmitContext& ctx);
244 Id EmitFPMul16(EmitContext& ctx, IR::Inst* inst, Id a, Id b);
245 Id EmitFPMul32(EmitContext& ctx, IR::Inst* inst, Id a, Id b);
246 Id EmitFPMul64(EmitContext& ctx, IR::Inst* inst, Id a, Id b);
247 void EmitFPNeg16(EmitContext& ctx);
248 void EmitFPNeg32(EmitContext& ctx);
249 void EmitFPNeg64(EmitContext& ctx);
250 void EmitFPRecip32(EmitContext& ctx);
251 void EmitFPRecip64(EmitContext& ctx);
252 void EmitFPRecipSqrt32(EmitContext& ctx);
253 void EmitFPRecipSqrt64(EmitContext& ctx);
254 void EmitFPSqrt(EmitContext& ctx);
255 void EmitFPSin(EmitContext& ctx);
256 void EmitFPSinNotReduced(EmitContext& ctx);
257 void EmitFPExp2(EmitContext& ctx);
258 void EmitFPExp2NotReduced(EmitContext& ctx);
259 void EmitFPCos(EmitContext& ctx);
260 void EmitFPCosNotReduced(EmitContext& ctx);
261 void EmitFPLog2(EmitContext& ctx);
262 void EmitFPSaturate16(EmitContext& ctx);
263 void EmitFPSaturate32(EmitContext& ctx);
264 void EmitFPSaturate64(EmitContext& ctx);
265 void EmitFPRoundEven16(EmitContext& ctx);
266 void EmitFPRoundEven32(EmitContext& ctx);
267 void EmitFPRoundEven64(EmitContext& ctx);
268 void EmitFPFloor16(EmitContext& ctx);
269 void EmitFPFloor32(EmitContext& ctx);
270 void EmitFPFloor64(EmitContext& ctx);
271 void EmitFPCeil16(EmitContext& ctx);
272 void EmitFPCeil32(EmitContext& ctx);
273 void EmitFPCeil64(EmitContext& ctx);
274 void EmitFPTrunc16(EmitContext& ctx);
275 void EmitFPTrunc32(EmitContext& ctx);
276 void EmitFPTrunc64(EmitContext& ctx);
277 Id EmitIAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b);
278 void EmitIAdd64(EmitContext& ctx);
279 Id EmitISub32(EmitContext& ctx, Id a, Id b);
280 void EmitISub64(EmitContext& ctx);
281 Id EmitIMul32(EmitContext& ctx, Id a, Id b);
282 void EmitINeg32(EmitContext& ctx);
283 void EmitIAbs32(EmitContext& ctx);
284 Id EmitShiftLeftLogical32(EmitContext& ctx, Id base, Id shift);
285 void EmitShiftRightLogical32(EmitContext& ctx);
286 void EmitShiftRightArithmetic32(EmitContext& ctx);
287 void EmitBitwiseAnd32(EmitContext& ctx);
288 void EmitBitwiseOr32(EmitContext& ctx);
289 void EmitBitwiseXor32(EmitContext& ctx);
290 void EmitBitFieldInsert(EmitContext& ctx);
291 void EmitBitFieldSExtract(EmitContext& ctx);
292 Id EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count);
293 void EmitSLessThan(EmitContext& ctx);
294 void EmitULessThan(EmitContext& ctx);
295 void EmitIEqual(EmitContext& ctx);
296 void EmitSLessThanEqual(EmitContext& ctx);
297 void EmitULessThanEqual(EmitContext& ctx);
298 void EmitSGreaterThan(EmitContext& ctx);
299 void EmitUGreaterThan(EmitContext& ctx);
300 void EmitINotEqual(EmitContext& ctx);
301 void EmitSGreaterThanEqual(EmitContext& ctx);
302 Id EmitUGreaterThanEqual(EmitContext& ctx, Id lhs, Id rhs);
303 void EmitLogicalOr(EmitContext& ctx);
304 void EmitLogicalAnd(EmitContext& ctx);
305 void EmitLogicalXor(EmitContext& ctx);
306 void EmitLogicalNot(EmitContext& ctx);
307 void EmitConvertS16F16(EmitContext& ctx);
308 void EmitConvertS16F32(EmitContext& ctx);
309 void EmitConvertS16F64(EmitContext& ctx);
310 void EmitConvertS32F16(EmitContext& ctx);
311 void EmitConvertS32F32(EmitContext& ctx);
312 void EmitConvertS32F64(EmitContext& ctx);
313 void EmitConvertS64F16(EmitContext& ctx);
314 void EmitConvertS64F32(EmitContext& ctx);
315 void EmitConvertS64F64(EmitContext& ctx);
316 void EmitConvertU16F16(EmitContext& ctx);
317 void EmitConvertU16F32(EmitContext& ctx);
318 void EmitConvertU16F64(EmitContext& ctx);
319 void EmitConvertU32F16(EmitContext& ctx);
320 void EmitConvertU32F32(EmitContext& ctx);
321 void EmitConvertU32F64(EmitContext& ctx);
322 void EmitConvertU64F16(EmitContext& ctx);
323 void EmitConvertU64F32(EmitContext& ctx);
324 void EmitConvertU64F64(EmitContext& ctx);
325 void EmitConvertU64U32(EmitContext& ctx);
326 void EmitConvertU32U64(EmitContext& ctx);
19}; 327};
20 328
21} // namespace Shader::Backend::SPIRV 329} // namespace Shader::Backend::SPIRV