summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/glasm
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/backend/glasm')
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_instructions.h22
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_memory.cpp117
2 files changed, 89 insertions, 50 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
index 4dee9daf9..5e038b332 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
@@ -79,17 +79,17 @@ void EmitUndefU8(EmitContext& ctx);
79void EmitUndefU16(EmitContext& ctx); 79void EmitUndefU16(EmitContext& ctx);
80void EmitUndefU32(EmitContext& ctx); 80void EmitUndefU32(EmitContext& ctx);
81void EmitUndefU64(EmitContext& ctx); 81void EmitUndefU64(EmitContext& ctx);
82void EmitLoadGlobalU8(EmitContext& ctx); 82void EmitLoadGlobalU8(EmitContext& ctx, IR::Inst& inst, Register address);
83void EmitLoadGlobalS8(EmitContext& ctx); 83void EmitLoadGlobalS8(EmitContext& ctx, IR::Inst& inst, Register address);
84void EmitLoadGlobalU16(EmitContext& ctx); 84void EmitLoadGlobalU16(EmitContext& ctx, IR::Inst& inst, Register address);
85void EmitLoadGlobalS16(EmitContext& ctx); 85void EmitLoadGlobalS16(EmitContext& ctx, IR::Inst& inst, Register address);
86void EmitLoadGlobal32(EmitContext& ctx, Register address); 86void EmitLoadGlobal32(EmitContext& ctx, IR::Inst& inst, Register address);
87void EmitLoadGlobal64(EmitContext& ctx, Register address); 87void EmitLoadGlobal64(EmitContext& ctx, IR::Inst& inst, Register address);
88void EmitLoadGlobal128(EmitContext& ctx, Register address); 88void EmitLoadGlobal128(EmitContext& ctx, IR::Inst& inst, Register address);
89void EmitWriteGlobalU8(EmitContext& ctx); 89void EmitWriteGlobalU8(EmitContext& ctx, Register address, Register value);
90void EmitWriteGlobalS8(EmitContext& ctx); 90void EmitWriteGlobalS8(EmitContext& ctx, Register address, Register value);
91void EmitWriteGlobalU16(EmitContext& ctx); 91void EmitWriteGlobalU16(EmitContext& ctx, Register address, Register value);
92void EmitWriteGlobalS16(EmitContext& ctx); 92void EmitWriteGlobalS16(EmitContext& ctx, Register address, Register value);
93void EmitWriteGlobal32(EmitContext& ctx, Register address, ScalarU32 value); 93void EmitWriteGlobal32(EmitContext& ctx, Register address, ScalarU32 value);
94void EmitWriteGlobal64(EmitContext& ctx, Register address, Register value); 94void EmitWriteGlobal64(EmitContext& ctx, Register address, Register value);
95void EmitWriteGlobal128(EmitContext& ctx, Register address, Register value); 95void EmitWriteGlobal128(EmitContext& ctx, Register address, Register value);
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_memory.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_memory.cpp
index dd307a9a3..33af83212 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_memory.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_memory.cpp
@@ -29,8 +29,39 @@ void StorageOp(EmitContext& ctx, const IR::Value& binding, ScalarU32 offset,
29 } 29 }
30} 30}
31 31
32void GlobalStorageOp(EmitContext& ctx, Register address, std::string_view then_expr,
33 std::string_view else_expr = {}) {
34 const size_t num_buffers{ctx.info.storage_buffers_descriptors.size()};
35 for (size_t index = 0; index < num_buffers; ++index) {
36 if (!ctx.info.nvn_buffer_used[index]) {
37 continue;
38 }
39 const auto& ssbo{ctx.info.storage_buffers_descriptors[index]};
40 ctx.Add("LDC.U64 DC.x,c[{}];" // ssbo_addr
41 "LDC.U32 RC.x,c[{}];" // ssbo_size_u32
42 "CVT.U64.U32 DC.y,RC.x;" // ssbo_size = ssbo_size_u32
43 "ADD.U64 DC.y,DC.y,DC.x;" // ssbo_end = ssbo_addr + ssbo_size
44 "SGE.U64 RC.x,{}.x,DC.x;" // a = input_addr >= ssbo_addr ? -1 : 1
45 "SLT.U64 RC.y,{}.x,DC.y;" // b = input_addr < ssbo_end ? -1 : 1
46 "AND.U.CC RC.x,RC.x,RC.y;"
47 "IF NE.x;" // a && b
48 "SUB.U64 DC.x,{}.x,DC.x;" // offset = input_addr - ssbo_addr
49 "PK64.U DC.y,c[{}];" // host_ssbo = cbuf
50 "ADD.U64 DC.x,DC.x,DC.y;" // host_addr = host_ssbo + offset
51 "{}",
52 "ELSE;", index, index, ssbo.cbuf_offset, ssbo.cbuf_offset + 8, address, address,
53 address, index, then_expr);
54 }
55 if (!else_expr.empty()) {
56 ctx.Add("{}", else_expr);
57 }
58 for (size_t index = 0; index < num_buffers; ++index) {
59 ctx.Add("ENDIF;");
60 }
61}
62
32template <typename ValueType> 63template <typename ValueType>
33void Store(EmitContext& ctx, const IR::Value& binding, ScalarU32 offset, ValueType value, 64void Write(EmitContext& ctx, const IR::Value& binding, ScalarU32 offset, ValueType value,
34 std::string_view size) { 65 std::string_view size) {
35 StorageOp(ctx, binding, offset, fmt::format("STORE.{} {},DC.x;", size, value)); 66 StorageOp(ctx, binding, offset, fmt::format("STORE.{} {},DC.x;", size, value));
36} 67}
@@ -41,65 +72,73 @@ void Load(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, ScalarU32
41 StorageOp(ctx, binding, offset, fmt::format("LOAD.{} {},DC.x;", size, ret), 72 StorageOp(ctx, binding, offset, fmt::format("LOAD.{} {},DC.x;", size, ret),
42 fmt::format("MOV.U {},{{0,0,0,0}};", ret)); 73 fmt::format("MOV.U {},{{0,0,0,0}};", ret));
43} 74}
75
76template <typename ValueType>
77void GlobalWrite(EmitContext& ctx, Register address, ValueType value, std::string_view size) {
78 GlobalStorageOp(ctx, address, fmt::format("STORE.{} {},DC.x;", size, value));
79}
80
81void GlobalLoad(EmitContext& ctx, IR::Inst& inst, Register address, std::string_view size) {
82 const Register ret{ctx.reg_alloc.Define(inst)};
83 GlobalStorageOp(ctx, address, fmt::format("LOAD.{} {},DC.x;", size, ret),
84 fmt::format("MOV.S {},0;", ret));
85}
44} // Anonymous namespace 86} // Anonymous namespace
45 87
46void EmitLoadGlobalU8([[maybe_unused]] EmitContext& ctx) { 88void EmitLoadGlobalU8(EmitContext& ctx, IR::Inst& inst, Register address) {
47 throw NotImplementedException("GLASM instruction"); 89 GlobalLoad(ctx, inst, address, "U8");
48} 90}
49 91
50void EmitLoadGlobalS8([[maybe_unused]] EmitContext& ctx) { 92void EmitLoadGlobalS8(EmitContext& ctx, IR::Inst& inst, Register address) {
51 throw NotImplementedException("GLASM instruction"); 93 GlobalLoad(ctx, inst, address, "S8");
52} 94}
53 95
54void EmitLoadGlobalU16([[maybe_unused]] EmitContext& ctx) { 96void EmitLoadGlobalU16(EmitContext& ctx, IR::Inst& inst, Register address) {
55 throw NotImplementedException("GLASM instruction"); 97 GlobalLoad(ctx, inst, address, "U16");
56} 98}
57 99
58void EmitLoadGlobalS16([[maybe_unused]] EmitContext& ctx) { 100void EmitLoadGlobalS16(EmitContext& ctx, IR::Inst& inst, Register address) {
59 throw NotImplementedException("GLASM instruction"); 101 GlobalLoad(ctx, inst, address, "S16");
60} 102}
61 103
62void EmitLoadGlobal32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register address) { 104void EmitLoadGlobal32(EmitContext& ctx, IR::Inst& inst, Register address) {
63 throw NotImplementedException("GLASM instruction"); 105 GlobalLoad(ctx, inst, address, "U32");
64} 106}
65 107
66void EmitLoadGlobal64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register address) { 108void EmitLoadGlobal64(EmitContext& ctx, IR::Inst& inst, Register address) {
67 throw NotImplementedException("GLASM instruction"); 109 GlobalLoad(ctx, inst, address, "U32X2");
68} 110}
69 111
70void EmitLoadGlobal128([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register address) { 112void EmitLoadGlobal128(EmitContext& ctx, IR::Inst& inst, Register address) {
71 throw NotImplementedException("GLASM instruction"); 113 GlobalLoad(ctx, inst, address, "U32X4");
72} 114}
73 115
74void EmitWriteGlobalU8([[maybe_unused]] EmitContext& ctx) { 116void EmitWriteGlobalU8(EmitContext& ctx, Register address, Register value) {
75 throw NotImplementedException("GLASM instruction"); 117 GlobalWrite(ctx, address, value, "U8");
76} 118}
77 119
78void EmitWriteGlobalS8([[maybe_unused]] EmitContext& ctx) { 120void EmitWriteGlobalS8(EmitContext& ctx, Register address, Register value) {
79 throw NotImplementedException("GLASM instruction"); 121 GlobalWrite(ctx, address, value, "S8");
80} 122}
81 123
82void EmitWriteGlobalU16([[maybe_unused]] EmitContext& ctx) { 124void EmitWriteGlobalU16(EmitContext& ctx, Register address, Register value) {
83 throw NotImplementedException("GLASM instruction"); 125 GlobalWrite(ctx, address, value, "U16");
84} 126}
85 127
86void EmitWriteGlobalS16([[maybe_unused]] EmitContext& ctx) { 128void EmitWriteGlobalS16(EmitContext& ctx, Register address, Register value) {
87 throw NotImplementedException("GLASM instruction"); 129 GlobalWrite(ctx, address, value, "S16");
88} 130}
89 131
90void EmitWriteGlobal32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register address, 132void EmitWriteGlobal32(EmitContext& ctx, Register address, ScalarU32 value) {
91 [[maybe_unused]] ScalarU32 value) { 133 GlobalWrite(ctx, address, value, "U32");
92 throw NotImplementedException("GLASM instruction");
93} 134}
94 135
95void EmitWriteGlobal64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register address, 136void EmitWriteGlobal64(EmitContext& ctx, Register address, Register value) {
96 [[maybe_unused]] Register value) { 137 GlobalWrite(ctx, address, value, "U32X2");
97 throw NotImplementedException("GLASM instruction");
98} 138}
99 139
100void EmitWriteGlobal128([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register address, 140void EmitWriteGlobal128(EmitContext& ctx, Register address, Register value) {
101 [[maybe_unused]] Register value) { 141 GlobalWrite(ctx, address, value, "U32X4");
102 throw NotImplementedException("GLASM instruction");
103} 142}
104 143
105void EmitLoadStorageU8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 144void EmitLoadStorageU8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
@@ -139,37 +178,37 @@ void EmitLoadStorage128(EmitContext& ctx, IR::Inst& inst, const IR::Value& bindi
139 178
140void EmitWriteStorageU8(EmitContext& ctx, const IR::Value& binding, ScalarU32 offset, 179void EmitWriteStorageU8(EmitContext& ctx, const IR::Value& binding, ScalarU32 offset,
141 ScalarU32 value) { 180 ScalarU32 value) {
142 Store(ctx, binding, offset, value, "U8"); 181 Write(ctx, binding, offset, value, "U8");
143} 182}
144 183
145void EmitWriteStorageS8(EmitContext& ctx, const IR::Value& binding, ScalarU32 offset, 184void EmitWriteStorageS8(EmitContext& ctx, const IR::Value& binding, ScalarU32 offset,
146 ScalarS32 value) { 185 ScalarS32 value) {
147 Store(ctx, binding, offset, value, "S8"); 186 Write(ctx, binding, offset, value, "S8");
148} 187}
149 188
150void EmitWriteStorageU16(EmitContext& ctx, const IR::Value& binding, ScalarU32 offset, 189void EmitWriteStorageU16(EmitContext& ctx, const IR::Value& binding, ScalarU32 offset,
151 ScalarU32 value) { 190 ScalarU32 value) {
152 Store(ctx, binding, offset, value, "U16"); 191 Write(ctx, binding, offset, value, "U16");
153} 192}
154 193
155void EmitWriteStorageS16(EmitContext& ctx, const IR::Value& binding, ScalarU32 offset, 194void EmitWriteStorageS16(EmitContext& ctx, const IR::Value& binding, ScalarU32 offset,
156 ScalarS32 value) { 195 ScalarS32 value) {
157 Store(ctx, binding, offset, value, "S16"); 196 Write(ctx, binding, offset, value, "S16");
158} 197}
159 198
160void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, ScalarU32 offset, 199void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, ScalarU32 offset,
161 ScalarU32 value) { 200 ScalarU32 value) {
162 Store(ctx, binding, offset, value, "U32"); 201 Write(ctx, binding, offset, value, "U32");
163} 202}
164 203
165void EmitWriteStorage64(EmitContext& ctx, const IR::Value& binding, ScalarU32 offset, 204void EmitWriteStorage64(EmitContext& ctx, const IR::Value& binding, ScalarU32 offset,
166 Register value) { 205 Register value) {
167 Store(ctx, binding, offset, value, "U32X2"); 206 Write(ctx, binding, offset, value, "U32X2");
168} 207}
169 208
170void EmitWriteStorage128(EmitContext& ctx, const IR::Value& binding, ScalarU32 offset, 209void EmitWriteStorage128(EmitContext& ctx, const IR::Value& binding, ScalarU32 offset,
171 Register value) { 210 Register value) {
172 Store(ctx, binding, offset, value, "U32X4"); 211 Write(ctx, binding, offset, value, "U32X4");
173} 212}
174 213
175} // namespace Shader::Backend::GLASM 214} // namespace Shader::Backend::GLASM