summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Nguyen Dac Nam2020-03-14 01:23:47 +0700
committerGravatar namkazy2020-03-30 17:44:48 +0700
commit972485ff18c9929faa07d1091634715e4c7f7eb4 (patch)
tree7c162353f15bdf06c0748c5b0e19a6f263f52bd9 /src
parentclang-format (diff)
downloadyuzu-972485ff18c9929faa07d1091634715e4c7f7eb4.tar.gz
yuzu-972485ff18c9929faa07d1091634715e4c7f7eb4.tar.xz
yuzu-972485ff18c9929faa07d1091634715e4c7f7eb4.zip
shader_decode: implement ATOM operation for S32 and U32
Diffstat (limited to 'src')
-rw-r--r--src/video_core/shader/decode/memory.cpp45
1 files changed, 39 insertions, 6 deletions
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp
index 98ae474e6..47edec71f 100644
--- a/src/video_core/shader/decode/memory.cpp
+++ b/src/video_core/shader/decode/memory.cpp
@@ -363,10 +363,13 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
363 break; 363 break;
364 } 364 }
365 case OpCode::Id::ATOM: { 365 case OpCode::Id::ATOM: {
366 UNIMPLEMENTED_IF_MSG(instr.atom.operation != GlobalAtomicOp::Add, "operation={}", 366 UNIMPLEMENTED_IF_MSG(instr.atom.operation == GlobalAtomicOp::Inc ||
367 static_cast<int>(instr.atom.operation.Value())); 367 instr.atom.operation == GlobalAtomicOp::Dec ||
368 UNIMPLEMENTED_IF_MSG(instr.atom.type != GlobalAtomicType::S32, "type={}", 368 instr.atom.operation == GlobalAtomicOp::SafeAdd,
369 static_cast<int>(instr.atom.type.Value())); 369 "operation={}", static_cast<int>(instr.atom.operation.Value()));
370 UNIMPLEMENTED_IF_MSG(instr.atom.type == GlobalAtomicType::S64 ||
371 instr.atom.type == GlobalAtomicType::U64,
372 "type={}", static_cast<int>(instr.atom.type.Value()));
370 373
371 const auto [real_address, base_address, descriptor] = 374 const auto [real_address, base_address, descriptor] =
372 TrackGlobalMemory(bb, instr, true, true); 375 TrackGlobalMemory(bb, instr, true, true);
@@ -375,9 +378,39 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
375 break; 378 break;
376 } 379 }
377 380
381 const bool is_signed =
382 instr.atoms.type == AtomicType::S32 || instr.atoms.type == AtomicType::S64;
378 Node gmem = MakeNode<GmemNode>(real_address, base_address, descriptor); 383 Node gmem = MakeNode<GmemNode>(real_address, base_address, descriptor);
379 Node value = 384 Node data = GetRegister(instr.gpr20);
380 Operation(OperationCode::AtomicIAdd, std::move(gmem), GetRegister(instr.gpr20)); 385
386 Node value = [&]() {
387 switch (instr.atoms.operation) {
388 case AtomicOp::Add:
389 return SignedOperation(OperationCode::AtomicIAdd, is_signed, std::move(gmem),
390 std::move(data));
391 case AtomicOp::Min:
392 return SignedOperation(OperationCode::AtomicIMin, is_signed, std::move(gmem),
393 std::move(data));
394 case AtomicOp::Max:
395 return SignedOperation(OperationCode::AtomicIMax, is_signed, std::move(gmem),
396 std::move(data));
397 case AtomicOp::And:
398 return SignedOperation(OperationCode::AtomicIAnd, is_signed, std::move(gmem),
399 std::move(data));
400 case AtomicOp::Or:
401 return SignedOperation(OperationCode::AtomicIOr, is_signed, std::move(gmem),
402 std::move(data));
403 case AtomicOp::Xor:
404 return SignedOperation(OperationCode::AtomicIXor, is_signed, std::move(gmem),
405 std::move(data));
406 case AtomicOp::Exch:
407 return SignedOperation(OperationCode::AtomicIExchange, is_signed, std::move(gmem),
408 std::move(data));
409 default:
410 UNREACHABLE();
411 return Immediate(0);
412 }
413 }();
381 SetRegister(bb, instr.gpr0, std::move(value)); 414 SetRegister(bb, instr.gpr0, std::move(value));
382 break; 415 break;
383 } 416 }