summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar namkazy2020-03-30 18:47:50 +0700
committerGravatar namkazy2020-03-30 18:47:50 +0700
commit4f7bea403a3e7e7b10255b7f1ac5363822c65833 (patch)
treeb717b2511a278a509f46ca1248c097e6b214701d /src
parentshader_decode: merge GlobalAtomicOp to AtomicOp (diff)
downloadyuzu-4f7bea403a3e7e7b10255b7f1ac5363822c65833.tar.gz
yuzu-4f7bea403a3e7e7b10255b7f1ac5363822c65833.tar.xz
yuzu-4f7bea403a3e7e7b10255b7f1ac5363822c65833.zip
shader_decode: ATOM/ATOMS: add function to avoid code repetition
Diffstat (limited to 'src')
-rw-r--r--src/video_core/shader/decode/memory.cpp109
-rw-r--r--src/video_core/shader/node_helper.cpp14
2 files changed, 53 insertions, 70 deletions
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp
index 47edec71f..0883240fc 100644
--- a/src/video_core/shader/decode/memory.cpp
+++ b/src/video_core/shader/decode/memory.cpp
@@ -19,7 +19,6 @@ namespace VideoCommon::Shader {
19using Tegra::Shader::AtomicOp; 19using Tegra::Shader::AtomicOp;
20using Tegra::Shader::AtomicType; 20using Tegra::Shader::AtomicType;
21using Tegra::Shader::Attribute; 21using Tegra::Shader::Attribute;
22using Tegra::Shader::GlobalAtomicOp;
23using Tegra::Shader::GlobalAtomicType; 22using Tegra::Shader::GlobalAtomicType;
24using Tegra::Shader::Instruction; 23using Tegra::Shader::Instruction;
25using Tegra::Shader::OpCode; 24using Tegra::Shader::OpCode;
@@ -28,6 +27,34 @@ using Tegra::Shader::StoreType;
28 27
29namespace { 28namespace {
30 29
30Node getAtomOperation(AtomicOp op, bool is_signed, Node memory, Node data) {
31 switch (op) {
32 case AtomicOp::Add:
33 return SignedOperation(OperationCode::AtomicIAdd, is_signed, std::move(memory),
34 std::move(data));
35 case AtomicOp::Min:
36 return SignedOperation(OperationCode::AtomicIMin, is_signed, std::move(memory),
37 std::move(data));
38 case AtomicOp::Max:
39 return SignedOperation(OperationCode::AtomicIMax, is_signed, std::move(memory),
40 std::move(data));
41 case AtomicOp::And:
42 return SignedOperation(OperationCode::AtomicIAnd, is_signed, std::move(memory),
43 std::move(data));
44 case AtomicOp::Or:
45 return SignedOperation(OperationCode::AtomicIOr, is_signed, std::move(memory),
46 std::move(data));
47 case AtomicOp::Xor:
48 return SignedOperation(OperationCode::AtomicIXor, is_signed, std::move(memory),
49 std::move(data));
50 case AtomicOp::Exch:
51 return SignedOperation(OperationCode::AtomicIExchange, is_signed, std::move(memory),
52 std::move(data));
53 default:
54 return Immediate(0);
55 }
56}
57
31bool IsUnaligned(Tegra::Shader::UniformType uniform_type) { 58bool IsUnaligned(Tegra::Shader::UniformType uniform_type) {
32 return uniform_type == Tegra::Shader::UniformType::UnsignedByte || 59 return uniform_type == Tegra::Shader::UniformType::UnsignedByte ||
33 uniform_type == Tegra::Shader::UniformType::UnsignedShort; 60 uniform_type == Tegra::Shader::UniformType::UnsignedShort;
@@ -363,9 +390,9 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
363 break; 390 break;
364 } 391 }
365 case OpCode::Id::ATOM: { 392 case OpCode::Id::ATOM: {
366 UNIMPLEMENTED_IF_MSG(instr.atom.operation == GlobalAtomicOp::Inc || 393 UNIMPLEMENTED_IF_MSG(instr.atom.operation == AtomicOp::Inc ||
367 instr.atom.operation == GlobalAtomicOp::Dec || 394 instr.atom.operation == AtomicOp::Dec ||
368 instr.atom.operation == GlobalAtomicOp::SafeAdd, 395 instr.atom.operation == AtomicOp::SafeAdd,
369 "operation={}", static_cast<int>(instr.atom.operation.Value())); 396 "operation={}", static_cast<int>(instr.atom.operation.Value()));
370 UNIMPLEMENTED_IF_MSG(instr.atom.type == GlobalAtomicType::S64 || 397 UNIMPLEMENTED_IF_MSG(instr.atom.type == GlobalAtomicType::S64 ||
371 instr.atom.type == GlobalAtomicType::U64, 398 instr.atom.type == GlobalAtomicType::U64,
@@ -381,36 +408,8 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
381 const bool is_signed = 408 const bool is_signed =
382 instr.atoms.type == AtomicType::S32 || instr.atoms.type == AtomicType::S64; 409 instr.atoms.type == AtomicType::S32 || instr.atoms.type == AtomicType::S64;
383 Node gmem = MakeNode<GmemNode>(real_address, base_address, descriptor); 410 Node gmem = MakeNode<GmemNode>(real_address, base_address, descriptor);
384 Node data = GetRegister(instr.gpr20); 411 Node value = getAtomOperation(static_cast<AtomicOp>(instr.atom.operation), is_signed, gmem,
385 412 GetRegister(instr.gpr20));
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 }();
414 SetRegister(bb, instr.gpr0, std::move(value)); 413 SetRegister(bb, instr.gpr0, std::move(value));
415 break; 414 break;
416 } 415 }
@@ -426,39 +425,9 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
426 const s32 offset = instr.atoms.GetImmediateOffset(); 425 const s32 offset = instr.atoms.GetImmediateOffset();
427 Node address = GetRegister(instr.gpr8); 426 Node address = GetRegister(instr.gpr8);
428 address = Operation(OperationCode::IAdd, std::move(address), Immediate(offset)); 427 address = Operation(OperationCode::IAdd, std::move(address), Immediate(offset));
429 428 Node value =
430 Node memory = GetSharedMemory(std::move(address)); 429 getAtomOperation(static_cast<AtomicOp>(instr.atoms.operation), is_signed,
431 Node data = GetRegister(instr.gpr20); 430 GetSharedMemory(std::move(address)), GetRegister(instr.gpr20));
432
433 Node value = [&]() {
434 switch (instr.atoms.operation) {
435 case AtomicOp::Add:
436 return SignedOperation(OperationCode::AtomicIAdd, is_signed, std::move(memory),
437 std::move(data));
438 case AtomicOp::Min:
439 return SignedOperation(OperationCode::AtomicIMin, is_signed, std::move(memory),
440 std::move(data));
441 case AtomicOp::Max:
442 return SignedOperation(OperationCode::AtomicIMax, is_signed, std::move(memory),
443 std::move(data));
444 case AtomicOp::And:
445 return SignedOperation(OperationCode::AtomicIAnd, is_signed, std::move(memory),
446 std::move(data));
447 case AtomicOp::Or:
448 return SignedOperation(OperationCode::AtomicIOr, is_signed, std::move(memory),
449 std::move(data));
450 case AtomicOp::Xor:
451 return SignedOperation(OperationCode::AtomicIXor, is_signed, std::move(memory),
452 std::move(data));
453 case AtomicOp::Exch:
454 return SignedOperation(OperationCode::AtomicIExchange, is_signed, std::move(memory),
455 std::move(data));
456 default:
457 UNREACHABLE();
458 return Immediate(0);
459 }
460 }();
461
462 SetRegister(bb, instr.gpr0, std::move(value)); 431 SetRegister(bb, instr.gpr0, std::move(value));
463 break; 432 break;
464 } 433 }
@@ -492,9 +461,9 @@ std::tuple<Node, Node, GlobalMemoryBase> ShaderIR::TrackGlobalMemory(NodeBlock&
492 461
493 const auto [base_address, index, offset] = 462 const auto [base_address, index, offset] =
494 TrackCbuf(addr_register, global_code, static_cast<s64>(global_code.size())); 463 TrackCbuf(addr_register, global_code, static_cast<s64>(global_code.size()));
495 ASSERT_OR_EXECUTE_MSG(base_address != nullptr, 464 ASSERT_OR_EXECUTE_MSG(
496 { return std::make_tuple(nullptr, nullptr, GlobalMemoryBase{}); }, 465 base_address != nullptr, { return std::make_tuple(nullptr, nullptr, GlobalMemoryBase{}); },
497 "Global memory tracking failed"); 466 "Global memory tracking failed");
498 467
499 bb.push_back(Comment(fmt::format("Base address is c[0x{:x}][0x{:x}]", index, offset))); 468 bb.push_back(Comment(fmt::format("Base address is c[0x{:x}][0x{:x}]", index, offset)));
500 469
diff --git a/src/video_core/shader/node_helper.cpp b/src/video_core/shader/node_helper.cpp
index 76c56abb5..7bf4ff387 100644
--- a/src/video_core/shader/node_helper.cpp
+++ b/src/video_core/shader/node_helper.cpp
@@ -86,6 +86,20 @@ OperationCode SignedToUnsignedCode(OperationCode operation_code, bool is_signed)
86 return OperationCode::LogicalUNotEqual; 86 return OperationCode::LogicalUNotEqual;
87 case OperationCode::LogicalIGreaterEqual: 87 case OperationCode::LogicalIGreaterEqual:
88 return OperationCode::LogicalUGreaterEqual; 88 return OperationCode::LogicalUGreaterEqual;
89 case OperationCode::AtomicIExchange:
90 return OperationCode::AtomicUExchange;
91 case OperationCode::AtomicIAdd:
92 return OperationCode::AtomicUAdd;
93 case OperationCode::AtomicIMin:
94 return OperationCode::AtomicUMin;
95 case OperationCode::AtomicIMax:
96 return OperationCode::AtomicUMax;
97 case OperationCode::AtomicIAnd:
98 return OperationCode::AtomicUAnd;
99 case OperationCode::AtomicIOr:
100 return OperationCode::AtomicUOr;
101 case OperationCode::AtomicIXor:
102 return OperationCode::AtomicUXor;
89 case OperationCode::INegate: 103 case OperationCode::INegate:
90 UNREACHABLE_MSG("Can't negate an unsigned integer"); 104 UNREACHABLE_MSG("Can't negate an unsigned integer");
91 return {}; 105 return {};