diff options
| author | 2020-03-30 18:47:50 +0700 | |
|---|---|---|
| committer | 2020-03-30 18:47:50 +0700 | |
| commit | 4f7bea403a3e7e7b10255b7f1ac5363822c65833 (patch) | |
| tree | b717b2511a278a509f46ca1248c097e6b214701d /src | |
| parent | shader_decode: merge GlobalAtomicOp to AtomicOp (diff) | |
| download | yuzu-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.cpp | 109 | ||||
| -rw-r--r-- | src/video_core/shader/node_helper.cpp | 14 |
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 { | |||
| 19 | using Tegra::Shader::AtomicOp; | 19 | using Tegra::Shader::AtomicOp; |
| 20 | using Tegra::Shader::AtomicType; | 20 | using Tegra::Shader::AtomicType; |
| 21 | using Tegra::Shader::Attribute; | 21 | using Tegra::Shader::Attribute; |
| 22 | using Tegra::Shader::GlobalAtomicOp; | ||
| 23 | using Tegra::Shader::GlobalAtomicType; | 22 | using Tegra::Shader::GlobalAtomicType; |
| 24 | using Tegra::Shader::Instruction; | 23 | using Tegra::Shader::Instruction; |
| 25 | using Tegra::Shader::OpCode; | 24 | using Tegra::Shader::OpCode; |
| @@ -28,6 +27,34 @@ using Tegra::Shader::StoreType; | |||
| 28 | 27 | ||
| 29 | namespace { | 28 | namespace { |
| 30 | 29 | ||
| 30 | Node 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 | |||
| 31 | bool IsUnaligned(Tegra::Shader::UniformType uniform_type) { | 58 | bool 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 {}; |