summaryrefslogtreecommitdiff
path: root/src/video_core/shader
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-04-06 02:24:47 -0300
committerGravatar ReinUsesLisp2020-04-06 02:24:47 -0300
commit3185245845f7487c3b832035b0c19fdc4f1a8262 (patch)
treec002fb721c5db8fc5f035bbf218e423b8d982f85 /src/video_core/shader
parentshader/memory: Add "using std::move" (diff)
downloadyuzu-3185245845f7487c3b832035b0c19fdc4f1a8262.tar.gz
yuzu-3185245845f7487c3b832035b0c19fdc4f1a8262.tar.xz
yuzu-3185245845f7487c3b832035b0c19fdc4f1a8262.zip
shader/memory: Implement RED.E.ADD
Implements a reduction operation. It's an atomic operation that doesn't return a value. This commit introduces another primitive because some shading languages might have a primitive for reduction operations.
Diffstat (limited to 'src/video_core/shader')
-rw-r--r--src/video_core/shader/decode/memory.cpp16
-rw-r--r--src/video_core/shader/node.h14
2 files changed, 29 insertions, 1 deletions
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp
index 1a93540fe..8112ead3e 100644
--- a/src/video_core/shader/decode/memory.cpp
+++ b/src/video_core/shader/decode/memory.cpp
@@ -378,13 +378,27 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
378 378
379 if (IsUnaligned(type)) { 379 if (IsUnaligned(type)) {
380 const u32 mask = GetUnalignedMask(type); 380 const u32 mask = GetUnalignedMask(type);
381 value = InsertUnaligned(gmem, std::move(value), real_address, mask, size); 381 value = InsertUnaligned(gmem, move(value), real_address, mask, size);
382 } 382 }
383 383
384 bb.push_back(Operation(OperationCode::Assign, gmem, value)); 384 bb.push_back(Operation(OperationCode::Assign, gmem, value));
385 } 385 }
386 break; 386 break;
387 } 387 }
388 case OpCode::Id::RED: {
389 UNIMPLEMENTED_IF_MSG(instr.red.type != GlobalAtomicType::U32);
390 UNIMPLEMENTED_IF_MSG(instr.red.operation != AtomicOp::Add);
391 const auto [real_address, base_address, descriptor] =
392 TrackGlobalMemory(bb, instr, true, true);
393 if (!real_address || !base_address) {
394 // Tracking failed, skip atomic.
395 break;
396 }
397 Node gmem = MakeNode<GmemNode>(real_address, base_address, descriptor);
398 Node value = GetRegister(instr.gpr0);
399 bb.push_back(Operation(OperationCode::ReduceIAdd, move(gmem), move(value)));
400 break;
401 }
388 case OpCode::Id::ATOM: { 402 case OpCode::Id::ATOM: {
389 UNIMPLEMENTED_IF_MSG(instr.atom.operation == AtomicOp::Inc || 403 UNIMPLEMENTED_IF_MSG(instr.atom.operation == AtomicOp::Inc ||
390 instr.atom.operation == AtomicOp::Dec || 404 instr.atom.operation == AtomicOp::Dec ||
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h
index 5fcc9da60..3eee961f5 100644
--- a/src/video_core/shader/node.h
+++ b/src/video_core/shader/node.h
@@ -178,6 +178,20 @@ enum class OperationCode {
178 AtomicIOr, /// (memory, int) -> int 178 AtomicIOr, /// (memory, int) -> int
179 AtomicIXor, /// (memory, int) -> int 179 AtomicIXor, /// (memory, int) -> int
180 180
181 ReduceUAdd, /// (memory, uint) -> void
182 ReduceUMin, /// (memory, uint) -> void
183 ReduceUMax, /// (memory, uint) -> void
184 ReduceUAnd, /// (memory, uint) -> void
185 ReduceUOr, /// (memory, uint) -> void
186 ReduceUXor, /// (memory, uint) -> void
187
188 ReduceIAdd, /// (memory, int) -> void
189 ReduceIMin, /// (memory, int) -> void
190 ReduceIMax, /// (memory, int) -> void
191 ReduceIAnd, /// (memory, int) -> void
192 ReduceIOr, /// (memory, int) -> void
193 ReduceIXor, /// (memory, int) -> void
194
181 Branch, /// (uint branch_target) -> void 195 Branch, /// (uint branch_target) -> void
182 BranchIndirect, /// (uint branch_target) -> void 196 BranchIndirect, /// (uint branch_target) -> void
183 PushFlowStack, /// (uint branch_target) -> void 197 PushFlowStack, /// (uint branch_target) -> void