From c119473c4083ec53c5de70e2536cd7eb5925ffbb Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Fri, 13 Mar 2020 23:04:20 +0700 Subject: [PATCH 01/13] shader_decode: add Atomic op for common usage --- src/video_core/shader/node.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h index a1828546ea..8f1d9bc95b 100644 --- a/src/video_core/shader/node.h +++ b/src/video_core/shader/node.h @@ -162,7 +162,21 @@ enum class OperationCode { AtomicImageXor, /// (MetaImage, int[N] coords) -> void AtomicImageExchange, /// (MetaImage, int[N] coords) -> void - AtomicAdd, /// (memory, {u}int) -> {u}int + AtomicUExchange, /// (memory, {u}int) -> {u}int + AtomicUAdd, /// (memory, {u}int) -> {u}int + AtomicUMin, /// (memory, {u}int) -> {u}int + AtomicUMax, /// (memory, {u}int) -> {u}int + AtomicUAnd, /// (memory, {u}int) -> {u}int + AtomicUOr, /// (memory, {u}int) -> {u}int + AtomicUXor, /// (memory, {u}int) -> {u}int + + AtomicIExchange, /// (memory, {u}int) -> {u}int + AtomicIAdd, /// (memory, {u}int) -> {u}int + AtomicIMin, /// (memory, {u}int) -> {u}int + AtomicIMax, /// (memory, {u}int) -> {u}int + AtomicIAnd, /// (memory, {u}int) -> {u}int + AtomicIOr, /// (memory, {u}int) -> {u}int + AtomicIXor, /// (memory, {u}int) -> {u}int Branch, /// (uint branch_target) -> void BranchIndirect, /// (uint branch_target) -> void From 2c780db5b9481b71b8d034db545d489bc656cfdd Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Fri, 13 Mar 2020 23:06:26 +0700 Subject: [PATCH 02/13] shader: node - update correct comment --- src/video_core/shader/node.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h index 8f1d9bc95b..5fcc9da602 100644 --- a/src/video_core/shader/node.h +++ b/src/video_core/shader/node.h @@ -162,21 +162,21 @@ enum class OperationCode { AtomicImageXor, /// (MetaImage, int[N] coords) -> void AtomicImageExchange, /// (MetaImage, int[N] coords) -> void - AtomicUExchange, /// (memory, {u}int) -> {u}int - AtomicUAdd, /// (memory, {u}int) -> {u}int - AtomicUMin, /// (memory, {u}int) -> {u}int - AtomicUMax, /// (memory, {u}int) -> {u}int - AtomicUAnd, /// (memory, {u}int) -> {u}int - AtomicUOr, /// (memory, {u}int) -> {u}int - AtomicUXor, /// (memory, {u}int) -> {u}int + AtomicUExchange, /// (memory, uint) -> uint + AtomicUAdd, /// (memory, uint) -> uint + AtomicUMin, /// (memory, uint) -> uint + AtomicUMax, /// (memory, uint) -> uint + AtomicUAnd, /// (memory, uint) -> uint + AtomicUOr, /// (memory, uint) -> uint + AtomicUXor, /// (memory, uint) -> uint - AtomicIExchange, /// (memory, {u}int) -> {u}int - AtomicIAdd, /// (memory, {u}int) -> {u}int - AtomicIMin, /// (memory, {u}int) -> {u}int - AtomicIMax, /// (memory, {u}int) -> {u}int - AtomicIAnd, /// (memory, {u}int) -> {u}int - AtomicIOr, /// (memory, {u}int) -> {u}int - AtomicIXor, /// (memory, {u}int) -> {u}int + AtomicIExchange, /// (memory, int) -> int + AtomicIAdd, /// (memory, int) -> int + AtomicIMin, /// (memory, int) -> int + AtomicIMax, /// (memory, int) -> int + AtomicIAnd, /// (memory, int) -> int + AtomicIOr, /// (memory, int) -> int + AtomicIXor, /// (memory, int) -> int Branch, /// (uint branch_target) -> void BranchIndirect, /// (uint branch_target) -> void From 552f0ff26713a2fd1fd9207e79574d35fd8d36dd Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Fri, 13 Mar 2020 23:07:05 +0700 Subject: [PATCH 03/13] gl_decompiler: add atomic op --- .../renderer_opengl/gl_shader_decompiler.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 8aa4a7ac95..9121a48bb4 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -2307,6 +2307,8 @@ private: ~Func() = delete; static constexpr std::string_view Add = "Add"; + static constexpr std::string_view Min = "Min"; + static constexpr std::string_view Max = "Max"; static constexpr std::string_view And = "And"; static constexpr std::string_view Or = "Or"; static constexpr std::string_view Xor = "Xor"; @@ -2457,7 +2459,21 @@ private: &GLSLDecompiler::AtomicImage, &GLSLDecompiler::AtomicImage, + &GLSLDecompiler::Atomic, &GLSLDecompiler::Atomic, + &GLSLDecompiler::Atomic, + &GLSLDecompiler::Atomic, + &GLSLDecompiler::Atomic, + &GLSLDecompiler::Atomic, + &GLSLDecompiler::Atomic, + + &GLSLDecompiler::Atomic, + &GLSLDecompiler::Atomic, + &GLSLDecompiler::Atomic, + &GLSLDecompiler::Atomic, + &GLSLDecompiler::Atomic, + &GLSLDecompiler::Atomic, + &GLSLDecompiler::Atomic, &GLSLDecompiler::Branch, &GLSLDecompiler::BranchIndirect, From a2cc80b605718833ece4bbbfb068a66a54f81965 Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Fri, 13 Mar 2020 23:08:04 +0700 Subject: [PATCH 04/13] vk_decompiler: add atomic op and handler function. --- .../renderer_vulkan/vk_shader_decompiler.cpp | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 51ecb55675..d67f08cf9c 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp @@ -1941,7 +1941,11 @@ private: return {}; } - Expression AtomicAdd(Operation operation) { + template + Expression Atomic(Operation operation) { + const Id type_def = GetTypeDefinition(result_type); + Id pointer; if (const auto smem = std::get_if(&*operation[0])) { pointer = GetSharedMemoryPointer(*smem); @@ -1949,14 +1953,15 @@ private: pointer = GetGlobalMemoryPointer(*gmem); } else { UNREACHABLE(); - return {Constant(t_uint, 0), Type::Uint}; + return {Constant(type_def, 0), result_type}; } - const Id scope = Constant(t_uint, static_cast(spv::Scope::Device)); - const Id semantics = Constant(t_uint, 0U); + const Id value = As(Visit(operation[1]), value_type); - const Id value = AsUint(Visit(operation[1])); - return {OpAtomicIAdd(t_uint, pointer, scope, semantics, value), Type::Uint}; + const Id scope = Constant(t_uint, static_cast(spv::Scope::Device)); + const Id semantics = Constant(type_def, 0); + + return {(this->*func)(type_def, pointer, scope, semantics, value), result_type}; } Expression Branch(Operation operation) { @@ -2545,7 +2550,21 @@ private: &SPIRVDecompiler::AtomicImageXor, &SPIRVDecompiler::AtomicImageExchange, - &SPIRVDecompiler::AtomicAdd, + &SPIRVDecompiler::Atomic<&Module::OpAtomicExchange, Type::Uint>, + &SPIRVDecompiler::Atomic<&Module::OpAtomicIAdd, Type::Uint>, + &SPIRVDecompiler::Atomic<&Module::OpAtomicUMin, Type::Uint>, + &SPIRVDecompiler::Atomic<&Module::OpAtomicUMax, Type::Uint>, + &SPIRVDecompiler::Atomic<&Module::OpAtomicAnd, Type::Uint>, + &SPIRVDecompiler::Atomic<&Module::OpAtomicOr, Type::Uint>, + &SPIRVDecompiler::Atomic<&Module::OpAtomicXor, Type::Uint>, + + &SPIRVDecompiler::Atomic<&Module::OpAtomicExchange, Type::Int>, + &SPIRVDecompiler::Atomic<&Module::OpAtomicIAdd, Type::Int>, + &SPIRVDecompiler::Atomic<&Module::OpAtomicSMin, Type::Int>, + &SPIRVDecompiler::Atomic<&Module::OpAtomicSMax, Type::Int>, + &SPIRVDecompiler::Atomic<&Module::OpAtomicAnd, Type::Int>, + &SPIRVDecompiler::Atomic<&Module::OpAtomicOr, Type::Int>, + &SPIRVDecompiler::Atomic<&Module::OpAtomicXor, Type::Int>, &SPIRVDecompiler::Branch, &SPIRVDecompiler::BranchIndirect, From 3dc09a62501b5d48053ffbba16c113b226c27d7b Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Fri, 13 Mar 2020 23:09:41 +0700 Subject: [PATCH 05/13] shader_decode: implement ATOMS instr partial. --- src/video_core/shader/decode/memory.cpp | 52 ++++++++++++++++++++----- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index b5fbc4d582..f5a6964bc0 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp @@ -376,16 +376,20 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { } Node gmem = MakeNode(real_address, base_address, descriptor); - Node value = Operation(OperationCode::AtomicAdd, std::move(gmem), GetRegister(instr.gpr20)); + Node value = + Operation(OperationCode::AtomicIAdd, std::move(gmem), GetRegister(instr.gpr20)); SetRegister(bb, instr.gpr0, std::move(value)); break; } case OpCode::Id::ATOMS: { - UNIMPLEMENTED_IF_MSG(instr.atoms.operation != AtomicOp::Add, "operation={}", - static_cast(instr.atoms.operation.Value())); - UNIMPLEMENTED_IF_MSG(instr.atoms.type != AtomicType::U32, "type={}", - static_cast(instr.atoms.type.Value())); - + UNIMPLEMENTED_IF_MSG(instr.atoms.operation == AtomicOp::Inc || + instr.atoms.operation == AtomicOp::Dec, + "operation={}", static_cast(instr.atoms.operation.Value())); + UNIMPLEMENTED_IF_MSG(instr.atoms.type == AtomicType::S64 || + instr.atoms.type == AtomicType::U64, + "type={}", static_cast(instr.atoms.type.Value())); + const bool is_signed = + instr.atoms.type == AtomicType::S32 || instr.atoms.type == AtomicType::S64; const s32 offset = instr.atoms.GetImmediateOffset(); Node address = GetRegister(instr.gpr8); address = Operation(OperationCode::IAdd, std::move(address), Immediate(offset)); @@ -393,7 +397,35 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { Node memory = GetSharedMemory(std::move(address)); Node data = GetRegister(instr.gpr20); - Node value = Operation(OperationCode::AtomicAdd, std::move(memory), std::move(data)); + Node value = [&]() { + switch (instr.atoms.operation) { + case AtomicOp::Add: + return SignedOperation(OperationCode::AtomicIAdd, is_signed, std::move(memory), + std::move(data)); + case AtomicOp::Min: + return SignedOperation(OperationCode::AtomicIMin, is_signed, std::move(memory), + std::move(data)); + case AtomicOp::Max: + return SignedOperation(OperationCode::AtomicIMax, is_signed, std::move(memory), + std::move(data)); + case AtomicOp::And: + return SignedOperation(OperationCode::AtomicIAnd, is_signed, std::move(memory), + std::move(data)); + case AtomicOp::Or: + return SignedOperation(OperationCode::AtomicIOr, is_signed, std::move(memory), + std::move(data)); + case AtomicOp::Xor: + return SignedOperation(OperationCode::AtomicIXor, is_signed, std::move(memory), + std::move(data)); + case AtomicOp::Exch: + return SignedOperation(OperationCode::AtomicIExchange, is_signed, std::move(memory), + std::move(data)); + default: + UNREACHABLE(); + return Immediate(0); + } + }(); + SetRegister(bb, instr.gpr0, std::move(value)); break; } @@ -427,9 +459,9 @@ std::tuple ShaderIR::TrackGlobalMemory(NodeBlock& const auto [base_address, index, offset] = TrackCbuf(addr_register, global_code, static_cast(global_code.size())); - ASSERT_OR_EXECUTE_MSG(base_address != nullptr, - { return std::make_tuple(nullptr, nullptr, GlobalMemoryBase{}); }, - "Global memory tracking failed"); + ASSERT_OR_EXECUTE_MSG( + base_address != nullptr, { return std::make_tuple(nullptr, nullptr, GlobalMemoryBase{}); }, + "Global memory tracking failed"); bb.push_back(Comment(fmt::format("Base address is c[0x{:x}][0x{:x}]", index, offset))); From 93cac0d2944c1c4d28f335f7060cfe5826050277 Mon Sep 17 00:00:00 2001 From: namkazy Date: Fri, 13 Mar 2020 23:45:43 +0700 Subject: [PATCH 06/13] clang-format --- src/video_core/shader/decode/memory.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index f5a6964bc0..98ae474e66 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp @@ -459,9 +459,9 @@ std::tuple ShaderIR::TrackGlobalMemory(NodeBlock& const auto [base_address, index, offset] = TrackCbuf(addr_register, global_code, static_cast(global_code.size())); - ASSERT_OR_EXECUTE_MSG( - base_address != nullptr, { return std::make_tuple(nullptr, nullptr, GlobalMemoryBase{}); }, - "Global memory tracking failed"); + ASSERT_OR_EXECUTE_MSG(base_address != nullptr, + { return std::make_tuple(nullptr, nullptr, GlobalMemoryBase{}); }, + "Global memory tracking failed"); bb.push_back(Comment(fmt::format("Base address is c[0x{:x}][0x{:x}]", index, offset))); From 972485ff18c9929faa07d1091634715e4c7f7eb4 Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Sat, 14 Mar 2020 01:23:47 +0700 Subject: [PATCH 07/13] shader_decode: implement ATOM operation for S32 and U32 --- src/video_core/shader/decode/memory.cpp | 45 +++++++++++++++++++++---- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index 98ae474e66..47edec71f4 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) { break; } case OpCode::Id::ATOM: { - UNIMPLEMENTED_IF_MSG(instr.atom.operation != GlobalAtomicOp::Add, "operation={}", - static_cast(instr.atom.operation.Value())); - UNIMPLEMENTED_IF_MSG(instr.atom.type != GlobalAtomicType::S32, "type={}", - static_cast(instr.atom.type.Value())); + UNIMPLEMENTED_IF_MSG(instr.atom.operation == GlobalAtomicOp::Inc || + instr.atom.operation == GlobalAtomicOp::Dec || + instr.atom.operation == GlobalAtomicOp::SafeAdd, + "operation={}", static_cast(instr.atom.operation.Value())); + UNIMPLEMENTED_IF_MSG(instr.atom.type == GlobalAtomicType::S64 || + instr.atom.type == GlobalAtomicType::U64, + "type={}", static_cast(instr.atom.type.Value())); const auto [real_address, base_address, descriptor] = TrackGlobalMemory(bb, instr, true, true); @@ -375,9 +378,39 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { break; } + const bool is_signed = + instr.atoms.type == AtomicType::S32 || instr.atoms.type == AtomicType::S64; Node gmem = MakeNode(real_address, base_address, descriptor); - Node value = - Operation(OperationCode::AtomicIAdd, std::move(gmem), GetRegister(instr.gpr20)); + Node data = GetRegister(instr.gpr20); + + Node value = [&]() { + switch (instr.atoms.operation) { + case AtomicOp::Add: + return SignedOperation(OperationCode::AtomicIAdd, is_signed, std::move(gmem), + std::move(data)); + case AtomicOp::Min: + return SignedOperation(OperationCode::AtomicIMin, is_signed, std::move(gmem), + std::move(data)); + case AtomicOp::Max: + return SignedOperation(OperationCode::AtomicIMax, is_signed, std::move(gmem), + std::move(data)); + case AtomicOp::And: + return SignedOperation(OperationCode::AtomicIAnd, is_signed, std::move(gmem), + std::move(data)); + case AtomicOp::Or: + return SignedOperation(OperationCode::AtomicIOr, is_signed, std::move(gmem), + std::move(data)); + case AtomicOp::Xor: + return SignedOperation(OperationCode::AtomicIXor, is_signed, std::move(gmem), + std::move(data)); + case AtomicOp::Exch: + return SignedOperation(OperationCode::AtomicIExchange, is_signed, std::move(gmem), + std::move(data)); + default: + UNREACHABLE(); + return Immediate(0); + } + }(); SetRegister(bb, instr.gpr0, std::move(value)); break; } From c8f6d9effd32a61be435cc08310bd94d2597cc97 Mon Sep 17 00:00:00 2001 From: namkazy Date: Mon, 30 Mar 2020 18:47:00 +0700 Subject: [PATCH 08/13] shader_decode: merge GlobalAtomicOp to AtomicOp --- src/video_core/engines/shader_bytecode.h | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 49dc5abe08..930b605af3 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h @@ -231,18 +231,6 @@ enum class AtomicOp : u64 { Or = 6, Xor = 7, Exch = 8, -}; - -enum class GlobalAtomicOp : u64 { - Add = 0, - Min = 1, - Max = 2, - Inc = 3, - Dec = 4, - And = 5, - Or = 6, - Xor = 7, - Exch = 8, SafeAdd = 10, }; @@ -1001,7 +989,7 @@ union Instruction { } stg; union { - BitField<52, 4, GlobalAtomicOp> operation; + BitField<52, 4, AtomicOp> operation; BitField<49, 3, GlobalAtomicType> type; BitField<28, 20, s64> offset; } atom; From 4f7bea403a3e7e7b10255b7f1ac5363822c65833 Mon Sep 17 00:00:00 2001 From: namkazy Date: Mon, 30 Mar 2020 18:47:50 +0700 Subject: [PATCH 09/13] shader_decode: ATOM/ATOMS: add function to avoid code repetition --- src/video_core/shader/decode/memory.cpp | 109 +++++++++--------------- 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 47edec71f4..0883240fc8 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp @@ -19,7 +19,6 @@ namespace VideoCommon::Shader { using Tegra::Shader::AtomicOp; using Tegra::Shader::AtomicType; using Tegra::Shader::Attribute; -using Tegra::Shader::GlobalAtomicOp; using Tegra::Shader::GlobalAtomicType; using Tegra::Shader::Instruction; using Tegra::Shader::OpCode; @@ -28,6 +27,34 @@ using Tegra::Shader::StoreType; namespace { +Node getAtomOperation(AtomicOp op, bool is_signed, Node memory, Node data) { + switch (op) { + case AtomicOp::Add: + return SignedOperation(OperationCode::AtomicIAdd, is_signed, std::move(memory), + std::move(data)); + case AtomicOp::Min: + return SignedOperation(OperationCode::AtomicIMin, is_signed, std::move(memory), + std::move(data)); + case AtomicOp::Max: + return SignedOperation(OperationCode::AtomicIMax, is_signed, std::move(memory), + std::move(data)); + case AtomicOp::And: + return SignedOperation(OperationCode::AtomicIAnd, is_signed, std::move(memory), + std::move(data)); + case AtomicOp::Or: + return SignedOperation(OperationCode::AtomicIOr, is_signed, std::move(memory), + std::move(data)); + case AtomicOp::Xor: + return SignedOperation(OperationCode::AtomicIXor, is_signed, std::move(memory), + std::move(data)); + case AtomicOp::Exch: + return SignedOperation(OperationCode::AtomicIExchange, is_signed, std::move(memory), + std::move(data)); + default: + return Immediate(0); + } +} + bool IsUnaligned(Tegra::Shader::UniformType uniform_type) { return uniform_type == Tegra::Shader::UniformType::UnsignedByte || uniform_type == Tegra::Shader::UniformType::UnsignedShort; @@ -363,9 +390,9 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { break; } case OpCode::Id::ATOM: { - UNIMPLEMENTED_IF_MSG(instr.atom.operation == GlobalAtomicOp::Inc || - instr.atom.operation == GlobalAtomicOp::Dec || - instr.atom.operation == GlobalAtomicOp::SafeAdd, + UNIMPLEMENTED_IF_MSG(instr.atom.operation == AtomicOp::Inc || + instr.atom.operation == AtomicOp::Dec || + instr.atom.operation == AtomicOp::SafeAdd, "operation={}", static_cast(instr.atom.operation.Value())); UNIMPLEMENTED_IF_MSG(instr.atom.type == GlobalAtomicType::S64 || instr.atom.type == GlobalAtomicType::U64, @@ -381,36 +408,8 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { const bool is_signed = instr.atoms.type == AtomicType::S32 || instr.atoms.type == AtomicType::S64; Node gmem = MakeNode(real_address, base_address, descriptor); - Node data = GetRegister(instr.gpr20); - - Node value = [&]() { - switch (instr.atoms.operation) { - case AtomicOp::Add: - return SignedOperation(OperationCode::AtomicIAdd, is_signed, std::move(gmem), - std::move(data)); - case AtomicOp::Min: - return SignedOperation(OperationCode::AtomicIMin, is_signed, std::move(gmem), - std::move(data)); - case AtomicOp::Max: - return SignedOperation(OperationCode::AtomicIMax, is_signed, std::move(gmem), - std::move(data)); - case AtomicOp::And: - return SignedOperation(OperationCode::AtomicIAnd, is_signed, std::move(gmem), - std::move(data)); - case AtomicOp::Or: - return SignedOperation(OperationCode::AtomicIOr, is_signed, std::move(gmem), - std::move(data)); - case AtomicOp::Xor: - return SignedOperation(OperationCode::AtomicIXor, is_signed, std::move(gmem), - std::move(data)); - case AtomicOp::Exch: - return SignedOperation(OperationCode::AtomicIExchange, is_signed, std::move(gmem), - std::move(data)); - default: - UNREACHABLE(); - return Immediate(0); - } - }(); + Node value = getAtomOperation(static_cast(instr.atom.operation), is_signed, gmem, + GetRegister(instr.gpr20)); SetRegister(bb, instr.gpr0, std::move(value)); break; } @@ -426,39 +425,9 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { const s32 offset = instr.atoms.GetImmediateOffset(); Node address = GetRegister(instr.gpr8); address = Operation(OperationCode::IAdd, std::move(address), Immediate(offset)); - - Node memory = GetSharedMemory(std::move(address)); - Node data = GetRegister(instr.gpr20); - - Node value = [&]() { - switch (instr.atoms.operation) { - case AtomicOp::Add: - return SignedOperation(OperationCode::AtomicIAdd, is_signed, std::move(memory), - std::move(data)); - case AtomicOp::Min: - return SignedOperation(OperationCode::AtomicIMin, is_signed, std::move(memory), - std::move(data)); - case AtomicOp::Max: - return SignedOperation(OperationCode::AtomicIMax, is_signed, std::move(memory), - std::move(data)); - case AtomicOp::And: - return SignedOperation(OperationCode::AtomicIAnd, is_signed, std::move(memory), - std::move(data)); - case AtomicOp::Or: - return SignedOperation(OperationCode::AtomicIOr, is_signed, std::move(memory), - std::move(data)); - case AtomicOp::Xor: - return SignedOperation(OperationCode::AtomicIXor, is_signed, std::move(memory), - std::move(data)); - case AtomicOp::Exch: - return SignedOperation(OperationCode::AtomicIExchange, is_signed, std::move(memory), - std::move(data)); - default: - UNREACHABLE(); - return Immediate(0); - } - }(); - + Node value = + getAtomOperation(static_cast(instr.atoms.operation), is_signed, + GetSharedMemory(std::move(address)), GetRegister(instr.gpr20)); SetRegister(bb, instr.gpr0, std::move(value)); break; } @@ -492,9 +461,9 @@ std::tuple ShaderIR::TrackGlobalMemory(NodeBlock& const auto [base_address, index, offset] = TrackCbuf(addr_register, global_code, static_cast(global_code.size())); - ASSERT_OR_EXECUTE_MSG(base_address != nullptr, - { return std::make_tuple(nullptr, nullptr, GlobalMemoryBase{}); }, - "Global memory tracking failed"); + ASSERT_OR_EXECUTE_MSG( + base_address != nullptr, { return std::make_tuple(nullptr, nullptr, GlobalMemoryBase{}); }, + "Global memory tracking failed"); bb.push_back(Comment(fmt::format("Base address is c[0x{:x}][0x{:x}]", index, offset))); diff --git a/src/video_core/shader/node_helper.cpp b/src/video_core/shader/node_helper.cpp index 76c56abb5a..7bf4ff3878 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) return OperationCode::LogicalUNotEqual; case OperationCode::LogicalIGreaterEqual: return OperationCode::LogicalUGreaterEqual; + case OperationCode::AtomicIExchange: + return OperationCode::AtomicUExchange; + case OperationCode::AtomicIAdd: + return OperationCode::AtomicUAdd; + case OperationCode::AtomicIMin: + return OperationCode::AtomicUMin; + case OperationCode::AtomicIMax: + return OperationCode::AtomicUMax; + case OperationCode::AtomicIAnd: + return OperationCode::AtomicUAnd; + case OperationCode::AtomicIOr: + return OperationCode::AtomicUOr; + case OperationCode::AtomicIXor: + return OperationCode::AtomicUXor; case OperationCode::INegate: UNREACHABLE_MSG("Can't negate an unsigned integer"); return {}; From c2665ec9c232f473ecb9301da7181159505a1c76 Mon Sep 17 00:00:00 2001 From: namkazy Date: Mon, 30 Mar 2020 18:48:22 +0700 Subject: [PATCH 10/13] gl_decompiler: min/max op not implement yet --- src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 9121a48bb4..c7d24cf141 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -2114,6 +2114,10 @@ private: template Expression Atomic(Operation operation) { + if ((opname == Func::Min || opname == Func::Max) && type == Type::Int) { + UNIMPLEMENTED_MSG("Unimplemented Min & Max for atomic operations"); + return {}; + } return {fmt::format("atomic{}({}, {})", opname, Visit(operation[0]).GetCode(), Visit(operation[1]).As(type)), type}; From cb0a4151f8bfad4d41c26ddeedcf1293f21bd487 Mon Sep 17 00:00:00 2001 From: namkazy Date: Mon, 30 Mar 2020 20:46:21 +0700 Subject: [PATCH 11/13] clang-format --- src/video_core/shader/decode/memory.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index 0883240fc8..e59bfa25e7 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp @@ -461,9 +461,9 @@ std::tuple ShaderIR::TrackGlobalMemory(NodeBlock& const auto [base_address, index, offset] = TrackCbuf(addr_register, global_code, static_cast(global_code.size())); - ASSERT_OR_EXECUTE_MSG( - base_address != nullptr, { return std::make_tuple(nullptr, nullptr, GlobalMemoryBase{}); }, - "Global memory tracking failed"); + ASSERT_OR_EXECUTE_MSG(base_address != nullptr, + { return std::make_tuple(nullptr, nullptr, GlobalMemoryBase{}); }, + "Global memory tracking failed"); bb.push_back(Comment(fmt::format("Base address is c[0x{:x}][0x{:x}]", index, offset))); From defb9642dab15dc51c769bb3aced897c76fbc0dd Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Tue, 31 Mar 2020 08:02:44 +0700 Subject: [PATCH 12/13] shader_decode: fix by suggestion --- src/video_core/shader/decode/memory.cpp | 49 +++++++++++-------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index e59bfa25e7..0caa5062d3 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp @@ -27,32 +27,27 @@ using Tegra::Shader::StoreType; namespace { -Node getAtomOperation(AtomicOp op, bool is_signed, Node memory, Node data) { - switch (op) { - case AtomicOp::Add: - return SignedOperation(OperationCode::AtomicIAdd, is_signed, std::move(memory), +Node GetAtomOperation(AtomicOp op, bool is_signed, Node memory, Node data) { + const OperationCode operation_code = [op] { + switch (op) { + case AtomicOp::Add: + return OperationCode::AtomicIAdd; + case AtomicOp::Min: + return OperationCode::AtomicIMin; + case AtomicOp::Max: + return OperationCode::AtomicIMax; + case AtomicOp::And: + return OperationCode::AtomicIAnd; + case AtomicOp::Or: + return OperationCode::AtomicIOr; + case AtomicOp::Xor: + return OperationCode::AtomicIXor; + case AtomicOp::Exch: + return OperationCode::AtomicIExchange; + } + }(); + return SignedOperation(operation_code, is_signed, std::move(memory), std::move(data)); - case AtomicOp::Min: - return SignedOperation(OperationCode::AtomicIMin, is_signed, std::move(memory), - std::move(data)); - case AtomicOp::Max: - return SignedOperation(OperationCode::AtomicIMax, is_signed, std::move(memory), - std::move(data)); - case AtomicOp::And: - return SignedOperation(OperationCode::AtomicIAnd, is_signed, std::move(memory), - std::move(data)); - case AtomicOp::Or: - return SignedOperation(OperationCode::AtomicIOr, is_signed, std::move(memory), - std::move(data)); - case AtomicOp::Xor: - return SignedOperation(OperationCode::AtomicIXor, is_signed, std::move(memory), - std::move(data)); - case AtomicOp::Exch: - return SignedOperation(OperationCode::AtomicIExchange, is_signed, std::move(memory), - std::move(data)); - default: - return Immediate(0); - } } bool IsUnaligned(Tegra::Shader::UniformType uniform_type) { @@ -408,7 +403,7 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { const bool is_signed = instr.atoms.type == AtomicType::S32 || instr.atoms.type == AtomicType::S64; Node gmem = MakeNode(real_address, base_address, descriptor); - Node value = getAtomOperation(static_cast(instr.atom.operation), is_signed, gmem, + Node value = GetAtomOperation(static_cast(instr.atom.operation), is_signed, gmem, GetRegister(instr.gpr20)); SetRegister(bb, instr.gpr0, std::move(value)); break; @@ -426,7 +421,7 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { Node address = GetRegister(instr.gpr8); address = Operation(OperationCode::IAdd, std::move(address), Immediate(offset)); Node value = - getAtomOperation(static_cast(instr.atoms.operation), is_signed, + GetAtomOperation(static_cast(instr.atoms.operation), is_signed, GetSharedMemory(std::move(address)), GetRegister(instr.gpr20)); SetRegister(bb, instr.gpr0, std::move(value)); break; From 238c35b2c9b0c89d2fd836c0c99a31999fa15b06 Mon Sep 17 00:00:00 2001 From: Nguyen Dac Nam Date: Tue, 31 Mar 2020 08:08:06 +0700 Subject: [PATCH 13/13] clang-format --- src/video_core/shader/decode/memory.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index 0caa5062d3..28a49addd1 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp @@ -46,8 +46,7 @@ Node GetAtomOperation(AtomicOp op, bool is_signed, Node memory, Node data) { return OperationCode::AtomicIExchange; } }(); - return SignedOperation(operation_code, is_signed, std::move(memory), - std::move(data)); + return SignedOperation(operation_code, is_signed, std::move(memory), std::move(data)); } bool IsUnaligned(Tegra::Shader::UniformType uniform_type) {