summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/glasm/emit_glasm_atomic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/backend/glasm/emit_glasm_atomic.cpp')
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_atomic.cpp291
1 files changed, 291 insertions, 0 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_atomic.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_atomic.cpp
index e69de29bb..fe44c3d15 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_atomic.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_atomic.cpp
@@ -0,0 +1,291 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "shader_recompiler/backend/glasm/emit_context.h"
6#include "shader_recompiler/backend/glasm/emit_glasm_instructions.h"
7#include "shader_recompiler/frontend/ir/value.h"
8
9namespace Shader::Backend::GLASM {
10namespace {
11void StorageOp(EmitContext& ctx, const IR::Value& binding, ScalarU32 offset,
12 std::string_view then_expr, std::string_view else_expr = {}) {
13 // Operate on bindless SSBO, call the expression with bounds checking
14 // address = c[binding].xy
15 // length = c[binding].z
16 const u32 sb_binding{binding.U32()};
17 ctx.Add("PK64.U DC,c[{}];" // pointer = address
18 "CVT.U64.U32 DC.z,{};" // offset = uint64_t(offset)
19 "ADD.U64 DC.x,DC.x,DC.z;" // pointer += offset
20 "SLT.U.CC RC.x,{},c[{}].z;", // cc = offset < length
21 sb_binding, offset, offset, sb_binding);
22 if (else_expr.empty()) {
23 ctx.Add("IF NE.x;{}ENDIF;", then_expr);
24 } else {
25 ctx.Add("IF NE.x;{}ELSE;{}ENDIF;", then_expr, else_expr);
26 }
27}
28
29template <typename ValueType>
30void Atom(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, ScalarU32 offset,
31 ValueType value, std::string_view operation, std::string_view size) {
32 const Register ret{ctx.reg_alloc.Define(inst)};
33 StorageOp(ctx, binding, offset,
34 fmt::format("ATOM.{}.{} {},{},DC.x;", operation, size, ret, value));
35}
36} // namespace
37
38void EmitStorageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
39 ScalarU32 offset, ScalarU32 value) {
40 Atom(ctx, inst, binding, offset, value, "ADD", "U32");
41}
42
43void EmitStorageAtomicSMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
44 ScalarU32 offset, ScalarS32 value) {
45 Atom(ctx, inst, binding, offset, value, "MIN", "S32");
46}
47
48void EmitStorageAtomicUMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
49 ScalarU32 offset, ScalarU32 value) {
50 Atom(ctx, inst, binding, offset, value, "MIN", "U32");
51}
52
53void EmitStorageAtomicSMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
54 ScalarU32 offset, ScalarS32 value) {
55 Atom(ctx, inst, binding, offset, value, "MAX", "S32");
56}
57
58void EmitStorageAtomicUMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
59 ScalarU32 offset, ScalarU32 value) {
60 Atom(ctx, inst, binding, offset, value, "MAX", "U32");
61}
62
63void EmitStorageAtomicInc32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
64 ScalarU32 offset, ScalarU32 value) {
65 Atom(ctx, inst, binding, offset, value, "IWRAP", "U32");
66}
67
68void EmitStorageAtomicDec32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
69 ScalarU32 offset, ScalarU32 value) {
70 Atom(ctx, inst, binding, offset, value, "DWRAP", "U32");
71}
72
73void EmitStorageAtomicAnd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
74 ScalarU32 offset, ScalarU32 value) {
75 Atom(ctx, inst, binding, offset, value, "AND", "U32");
76}
77
78void EmitStorageAtomicOr32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
79 ScalarU32 offset, ScalarU32 value) {
80 Atom(ctx, inst, binding, offset, value, "OR", "U32");
81}
82
83void EmitStorageAtomicXor32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
84 ScalarU32 offset, ScalarU32 value) {
85 Atom(ctx, inst, binding, offset, value, "XOR", "U32");
86}
87
88void EmitStorageAtomicExchange32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
89 ScalarU32 offset, ScalarU32 value) {
90 Atom(ctx, inst, binding, offset, value, "EXCH", "U32");
91}
92
93void EmitStorageAtomicIAdd64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
94 ScalarU32 offset, Register value) {
95 Atom(ctx, inst, binding, offset, value, "ADD", "U64");
96}
97
98void EmitStorageAtomicSMin64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
99 ScalarU32 offset, Register value) {
100 Atom(ctx, inst, binding, offset, value, "MIN", "S64");
101}
102
103void EmitStorageAtomicUMin64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
104 ScalarU32 offset, Register value) {
105 Atom(ctx, inst, binding, offset, value, "MIN", "U64");
106}
107
108void EmitStorageAtomicSMax64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
109 ScalarU32 offset, Register value) {
110 Atom(ctx, inst, binding, offset, value, "MAX", "S64");
111}
112
113void EmitStorageAtomicUMax64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
114 ScalarU32 offset, Register value) {
115 Atom(ctx, inst, binding, offset, value, "MAX", "U64");
116}
117
118void EmitStorageAtomicAnd64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
119 ScalarU32 offset, Register value) {
120 Atom(ctx, inst, binding, offset, value, "AND", "U64");
121}
122
123void EmitStorageAtomicOr64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
124 ScalarU32 offset, Register value) {
125 Atom(ctx, inst, binding, offset, value, "OR", "U64");
126}
127
128void EmitStorageAtomicXor64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
129 ScalarU32 offset, Register value) {
130 Atom(ctx, inst, binding, offset, value, "XOR", "U64");
131}
132
133void EmitStorageAtomicExchange64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
134 ScalarU32 offset, Register value) {
135 Atom(ctx, inst, binding, offset, value, "EXCH", "U64");
136}
137
138void EmitStorageAtomicAddF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
139 ScalarU32 offset, ScalarF32 value) {
140 Atom(ctx, inst, binding, offset, value, "ADD", "F32");
141}
142
143void EmitStorageAtomicAddF16x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
144 ScalarU32 offset, Register value) {
145 Atom(ctx, inst, binding, offset, value, "ADD", "F16x2");
146}
147
148void EmitStorageAtomicAddF32x2([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
149 [[maybe_unused]] const IR::Value& binding,
150 [[maybe_unused]] ScalarU32 offset, [[maybe_unused]] Register value) {
151 throw NotImplementedException("GLASM instruction");
152}
153
154void EmitStorageAtomicMinF16x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
155 ScalarU32 offset, Register value) {
156 Atom(ctx, inst, binding, offset, value, "MIN", "F16x2");
157}
158
159void EmitStorageAtomicMinF32x2([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
160 [[maybe_unused]] const IR::Value& binding,
161 [[maybe_unused]] ScalarU32 offset, [[maybe_unused]] Register value) {
162 throw NotImplementedException("GLASM instruction");
163}
164
165void EmitStorageAtomicMaxF16x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
166 ScalarU32 offset, Register value) {
167 Atom(ctx, inst, binding, offset, value, "MAX", "F16x2");
168}
169
170void EmitStorageAtomicMaxF32x2([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
171 [[maybe_unused]] const IR::Value& binding,
172 [[maybe_unused]] ScalarU32 offset, [[maybe_unused]] Register value) {
173 throw NotImplementedException("GLASM instruction");
174}
175
176void EmitGlobalAtomicIAdd32(EmitContext&) {
177 throw NotImplementedException("GLASM instruction");
178}
179
180void EmitGlobalAtomicSMin32(EmitContext&) {
181 throw NotImplementedException("GLASM instruction");
182}
183
184void EmitGlobalAtomicUMin32(EmitContext&) {
185 throw NotImplementedException("GLASM instruction");
186}
187
188void EmitGlobalAtomicSMax32(EmitContext&) {
189 throw NotImplementedException("GLASM instruction");
190}
191
192void EmitGlobalAtomicUMax32(EmitContext&) {
193 throw NotImplementedException("GLASM instruction");
194}
195
196void EmitGlobalAtomicInc32(EmitContext&) {
197 throw NotImplementedException("GLASM instruction");
198}
199
200void EmitGlobalAtomicDec32(EmitContext&) {
201 throw NotImplementedException("GLASM instruction");
202}
203
204void EmitGlobalAtomicAnd32(EmitContext&) {
205 throw NotImplementedException("GLASM instruction");
206}
207
208void EmitGlobalAtomicOr32(EmitContext&) {
209 throw NotImplementedException("GLASM instruction");
210}
211
212void EmitGlobalAtomicXor32(EmitContext&) {
213 throw NotImplementedException("GLASM instruction");
214}
215
216void EmitGlobalAtomicExchange32(EmitContext&) {
217 throw NotImplementedException("GLASM instruction");
218}
219
220void EmitGlobalAtomicIAdd64(EmitContext&) {
221 throw NotImplementedException("GLASM instruction");
222}
223
224void EmitGlobalAtomicSMin64(EmitContext&) {
225 throw NotImplementedException("GLASM instruction");
226}
227
228void EmitGlobalAtomicUMin64(EmitContext&) {
229 throw NotImplementedException("GLASM instruction");
230}
231
232void EmitGlobalAtomicSMax64(EmitContext&) {
233 throw NotImplementedException("GLASM instruction");
234}
235
236void EmitGlobalAtomicUMax64(EmitContext&) {
237 throw NotImplementedException("GLASM instruction");
238}
239
240void EmitGlobalAtomicInc64(EmitContext&) {
241 throw NotImplementedException("GLASM instruction");
242}
243
244void EmitGlobalAtomicDec64(EmitContext&) {
245 throw NotImplementedException("GLASM instruction");
246}
247
248void EmitGlobalAtomicAnd64(EmitContext&) {
249 throw NotImplementedException("GLASM instruction");
250}
251
252void EmitGlobalAtomicOr64(EmitContext&) {
253 throw NotImplementedException("GLASM instruction");
254}
255
256void EmitGlobalAtomicXor64(EmitContext&) {
257 throw NotImplementedException("GLASM instruction");
258}
259
260void EmitGlobalAtomicExchange64(EmitContext&) {
261 throw NotImplementedException("GLASM instruction");
262}
263
264void EmitGlobalAtomicAddF32(EmitContext&) {
265 throw NotImplementedException("GLASM instruction");
266}
267
268void EmitGlobalAtomicAddF16x2(EmitContext&) {
269 throw NotImplementedException("GLASM instruction");
270}
271
272void EmitGlobalAtomicAddF32x2(EmitContext&) {
273 throw NotImplementedException("GLASM instruction");
274}
275
276void EmitGlobalAtomicMinF16x2(EmitContext&) {
277 throw NotImplementedException("GLASM instruction");
278}
279
280void EmitGlobalAtomicMinF32x2(EmitContext&) {
281 throw NotImplementedException("GLASM instruction");
282}
283
284void EmitGlobalAtomicMaxF16x2(EmitContext&) {
285 throw NotImplementedException("GLASM instruction");
286}
287
288void EmitGlobalAtomicMaxF32x2(EmitContext&) {
289 throw NotImplementedException("GLASM instruction");
290}
291} // namespace Shader::Backend::GLASM