diff options
| author | 2020-04-06 02:24:47 -0300 | |
|---|---|---|
| committer | 2020-04-06 02:24:47 -0300 | |
| commit | 3185245845f7487c3b832035b0c19fdc4f1a8262 (patch) | |
| tree | c002fb721c5db8fc5f035bbf218e423b8d982f85 /src/video_core/shader | |
| parent | shader/memory: Add "using std::move" (diff) | |
| download | yuzu-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.cpp | 16 | ||||
| -rw-r--r-- | src/video_core/shader/node.h | 14 |
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 |