diff options
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 24 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | 65 | ||||
| -rw-r--r-- | src/video_core/shader/decode/memory.cpp | 16 | ||||
| -rw-r--r-- | src/video_core/shader/node.h | 14 |
5 files changed, 99 insertions, 28 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 930b605af..a31947ef3 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -989,6 +989,12 @@ union Instruction { | |||
| 989 | } stg; | 989 | } stg; |
| 990 | 990 | ||
| 991 | union { | 991 | union { |
| 992 | BitField<23, 3, AtomicOp> operation; | ||
| 993 | BitField<48, 1, u64> extended; | ||
| 994 | BitField<20, 3, GlobalAtomicType> type; | ||
| 995 | } red; | ||
| 996 | |||
| 997 | union { | ||
| 992 | BitField<52, 4, AtomicOp> operation; | 998 | BitField<52, 4, AtomicOp> operation; |
| 993 | BitField<49, 3, GlobalAtomicType> type; | 999 | BitField<49, 3, GlobalAtomicType> type; |
| 994 | BitField<28, 20, s64> offset; | 1000 | BitField<28, 20, s64> offset; |
| @@ -1733,6 +1739,7 @@ public: | |||
| 1733 | ST_S, | 1739 | ST_S, |
| 1734 | ST, // Store in generic memory | 1740 | ST, // Store in generic memory |
| 1735 | STG, // Store in global memory | 1741 | STG, // Store in global memory |
| 1742 | RED, // Reduction operation | ||
| 1736 | ATOM, // Atomic operation on global memory | 1743 | ATOM, // Atomic operation on global memory |
| 1737 | ATOMS, // Atomic operation on shared memory | 1744 | ATOMS, // Atomic operation on shared memory |
| 1738 | AL2P, // Transforms attribute memory into physical memory | 1745 | AL2P, // Transforms attribute memory into physical memory |
| @@ -2039,6 +2046,7 @@ private: | |||
| 2039 | INST("1110111101010---", Id::ST_L, Type::Memory, "ST_L"), | 2046 | INST("1110111101010---", Id::ST_L, Type::Memory, "ST_L"), |
| 2040 | INST("101-------------", Id::ST, Type::Memory, "ST"), | 2047 | INST("101-------------", Id::ST, Type::Memory, "ST"), |
| 2041 | INST("1110111011011---", Id::STG, Type::Memory, "STG"), | 2048 | INST("1110111011011---", Id::STG, Type::Memory, "STG"), |
| 2049 | INST("1110101111111---", Id::RED, Type::Memory, "RED"), | ||
| 2042 | INST("11101101--------", Id::ATOM, Type::Memory, "ATOM"), | 2050 | INST("11101101--------", Id::ATOM, Type::Memory, "ATOM"), |
| 2043 | INST("11101100--------", Id::ATOMS, Type::Memory, "ATOMS"), | 2051 | INST("11101100--------", Id::ATOMS, Type::Memory, "ATOMS"), |
| 2044 | INST("1110111110100---", Id::AL2P, Type::Memory, "AL2P"), | 2052 | INST("1110111110100---", Id::AL2P, Type::Memory, "AL2P"), |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index c7d24cf14..a25280a47 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -2119,8 +2119,14 @@ private: | |||
| 2119 | return {}; | 2119 | return {}; |
| 2120 | } | 2120 | } |
| 2121 | return {fmt::format("atomic{}({}, {})", opname, Visit(operation[0]).GetCode(), | 2121 | return {fmt::format("atomic{}({}, {})", opname, Visit(operation[0]).GetCode(), |
| 2122 | Visit(operation[1]).As(type)), | 2122 | Visit(operation[1]).AsUint()), |
| 2123 | type}; | 2123 | Type::Uint}; |
| 2124 | } | ||
| 2125 | |||
| 2126 | template <const std::string_view& opname, Type type> | ||
| 2127 | Expression Reduce(Operation operation) { | ||
| 2128 | code.AddLine("{};", Atomic<opname, type>(operation).GetCode()); | ||
| 2129 | return {}; | ||
| 2124 | } | 2130 | } |
| 2125 | 2131 | ||
| 2126 | Expression Branch(Operation operation) { | 2132 | Expression Branch(Operation operation) { |
| @@ -2479,6 +2485,20 @@ private: | |||
| 2479 | &GLSLDecompiler::Atomic<Func::Or, Type::Int>, | 2485 | &GLSLDecompiler::Atomic<Func::Or, Type::Int>, |
| 2480 | &GLSLDecompiler::Atomic<Func::Xor, Type::Int>, | 2486 | &GLSLDecompiler::Atomic<Func::Xor, Type::Int>, |
| 2481 | 2487 | ||
| 2488 | &GLSLDecompiler::Reduce<Func::Add, Type::Uint>, | ||
| 2489 | &GLSLDecompiler::Reduce<Func::Min, Type::Uint>, | ||
| 2490 | &GLSLDecompiler::Reduce<Func::Max, Type::Uint>, | ||
| 2491 | &GLSLDecompiler::Reduce<Func::And, Type::Uint>, | ||
| 2492 | &GLSLDecompiler::Reduce<Func::Or, Type::Uint>, | ||
| 2493 | &GLSLDecompiler::Reduce<Func::Xor, Type::Uint>, | ||
| 2494 | |||
| 2495 | &GLSLDecompiler::Reduce<Func::Add, Type::Int>, | ||
| 2496 | &GLSLDecompiler::Reduce<Func::Min, Type::Int>, | ||
| 2497 | &GLSLDecompiler::Reduce<Func::Max, Type::Int>, | ||
| 2498 | &GLSLDecompiler::Reduce<Func::And, Type::Int>, | ||
| 2499 | &GLSLDecompiler::Reduce<Func::Or, Type::Int>, | ||
| 2500 | &GLSLDecompiler::Reduce<Func::Xor, Type::Int>, | ||
| 2501 | |||
| 2482 | &GLSLDecompiler::Branch, | 2502 | &GLSLDecompiler::Branch, |
| 2483 | &GLSLDecompiler::BranchIndirect, | 2503 | &GLSLDecompiler::BranchIndirect, |
| 2484 | &GLSLDecompiler::PushFlowStack, | 2504 | &GLSLDecompiler::PushFlowStack, |
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index d67f08cf9..24d3ca08f 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | |||
| @@ -1941,11 +1941,8 @@ private: | |||
| 1941 | return {}; | 1941 | return {}; |
| 1942 | } | 1942 | } |
| 1943 | 1943 | ||
| 1944 | template <Id (Module::*func)(Id, Id, Id, Id, Id), Type result_type, | 1944 | template <Id (Module::*func)(Id, Id, Id, Id, Id)> |
| 1945 | Type value_type = result_type> | ||
| 1946 | Expression Atomic(Operation operation) { | 1945 | Expression Atomic(Operation operation) { |
| 1947 | const Id type_def = GetTypeDefinition(result_type); | ||
| 1948 | |||
| 1949 | Id pointer; | 1946 | Id pointer; |
| 1950 | if (const auto smem = std::get_if<SmemNode>(&*operation[0])) { | 1947 | if (const auto smem = std::get_if<SmemNode>(&*operation[0])) { |
| 1951 | pointer = GetSharedMemoryPointer(*smem); | 1948 | pointer = GetSharedMemoryPointer(*smem); |
| @@ -1953,15 +1950,19 @@ private: | |||
| 1953 | pointer = GetGlobalMemoryPointer(*gmem); | 1950 | pointer = GetGlobalMemoryPointer(*gmem); |
| 1954 | } else { | 1951 | } else { |
| 1955 | UNREACHABLE(); | 1952 | UNREACHABLE(); |
| 1956 | return {Constant(type_def, 0), result_type}; | 1953 | return {v_float_zero, Type::Float}; |
| 1957 | } | 1954 | } |
| 1958 | |||
| 1959 | const Id value = As(Visit(operation[1]), value_type); | ||
| 1960 | |||
| 1961 | const Id scope = Constant(t_uint, static_cast<u32>(spv::Scope::Device)); | 1955 | const Id scope = Constant(t_uint, static_cast<u32>(spv::Scope::Device)); |
| 1962 | const Id semantics = Constant(type_def, 0); | 1956 | const Id semantics = Constant(t_uint, 0); |
| 1957 | const Id value = AsUint(Visit(operation[1])); | ||
| 1958 | |||
| 1959 | return {(this->*func)(t_uint, pointer, scope, semantics, value), Type::Uint}; | ||
| 1960 | } | ||
| 1963 | 1961 | ||
| 1964 | return {(this->*func)(type_def, pointer, scope, semantics, value), result_type}; | 1962 | template <Id (Module::*func)(Id, Id, Id, Id, Id)> |
| 1963 | Expression Reduce(Operation operation) { | ||
| 1964 | Atomic<func>(operation); | ||
| 1965 | return {}; | ||
| 1965 | } | 1966 | } |
| 1966 | 1967 | ||
| 1967 | Expression Branch(Operation operation) { | 1968 | Expression Branch(Operation operation) { |
| @@ -2550,21 +2551,35 @@ private: | |||
| 2550 | &SPIRVDecompiler::AtomicImageXor, | 2551 | &SPIRVDecompiler::AtomicImageXor, |
| 2551 | &SPIRVDecompiler::AtomicImageExchange, | 2552 | &SPIRVDecompiler::AtomicImageExchange, |
| 2552 | 2553 | ||
| 2553 | &SPIRVDecompiler::Atomic<&Module::OpAtomicExchange, Type::Uint>, | 2554 | &SPIRVDecompiler::Atomic<&Module::OpAtomicExchange>, |
| 2554 | &SPIRVDecompiler::Atomic<&Module::OpAtomicIAdd, Type::Uint>, | 2555 | &SPIRVDecompiler::Atomic<&Module::OpAtomicIAdd>, |
| 2555 | &SPIRVDecompiler::Atomic<&Module::OpAtomicUMin, Type::Uint>, | 2556 | &SPIRVDecompiler::Atomic<&Module::OpAtomicUMin>, |
| 2556 | &SPIRVDecompiler::Atomic<&Module::OpAtomicUMax, Type::Uint>, | 2557 | &SPIRVDecompiler::Atomic<&Module::OpAtomicUMax>, |
| 2557 | &SPIRVDecompiler::Atomic<&Module::OpAtomicAnd, Type::Uint>, | 2558 | &SPIRVDecompiler::Atomic<&Module::OpAtomicAnd>, |
| 2558 | &SPIRVDecompiler::Atomic<&Module::OpAtomicOr, Type::Uint>, | 2559 | &SPIRVDecompiler::Atomic<&Module::OpAtomicOr>, |
| 2559 | &SPIRVDecompiler::Atomic<&Module::OpAtomicXor, Type::Uint>, | 2560 | &SPIRVDecompiler::Atomic<&Module::OpAtomicXor>, |
| 2560 | 2561 | ||
| 2561 | &SPIRVDecompiler::Atomic<&Module::OpAtomicExchange, Type::Int>, | 2562 | &SPIRVDecompiler::Atomic<&Module::OpAtomicExchange>, |
| 2562 | &SPIRVDecompiler::Atomic<&Module::OpAtomicIAdd, Type::Int>, | 2563 | &SPIRVDecompiler::Atomic<&Module::OpAtomicIAdd>, |
| 2563 | &SPIRVDecompiler::Atomic<&Module::OpAtomicSMin, Type::Int>, | 2564 | &SPIRVDecompiler::Atomic<&Module::OpAtomicSMin>, |
| 2564 | &SPIRVDecompiler::Atomic<&Module::OpAtomicSMax, Type::Int>, | 2565 | &SPIRVDecompiler::Atomic<&Module::OpAtomicSMax>, |
| 2565 | &SPIRVDecompiler::Atomic<&Module::OpAtomicAnd, Type::Int>, | 2566 | &SPIRVDecompiler::Atomic<&Module::OpAtomicAnd>, |
| 2566 | &SPIRVDecompiler::Atomic<&Module::OpAtomicOr, Type::Int>, | 2567 | &SPIRVDecompiler::Atomic<&Module::OpAtomicOr>, |
| 2567 | &SPIRVDecompiler::Atomic<&Module::OpAtomicXor, Type::Int>, | 2568 | &SPIRVDecompiler::Atomic<&Module::OpAtomicXor>, |
| 2569 | |||
| 2570 | &SPIRVDecompiler::Reduce<&Module::OpAtomicIAdd>, | ||
| 2571 | &SPIRVDecompiler::Reduce<&Module::OpAtomicUMin>, | ||
| 2572 | &SPIRVDecompiler::Reduce<&Module::OpAtomicUMax>, | ||
| 2573 | &SPIRVDecompiler::Reduce<&Module::OpAtomicAnd>, | ||
| 2574 | &SPIRVDecompiler::Reduce<&Module::OpAtomicOr>, | ||
| 2575 | &SPIRVDecompiler::Reduce<&Module::OpAtomicXor>, | ||
| 2576 | |||
| 2577 | &SPIRVDecompiler::Reduce<&Module::OpAtomicIAdd>, | ||
| 2578 | &SPIRVDecompiler::Reduce<&Module::OpAtomicSMin>, | ||
| 2579 | &SPIRVDecompiler::Reduce<&Module::OpAtomicSMax>, | ||
| 2580 | &SPIRVDecompiler::Reduce<&Module::OpAtomicAnd>, | ||
| 2581 | &SPIRVDecompiler::Reduce<&Module::OpAtomicOr>, | ||
| 2582 | &SPIRVDecompiler::Reduce<&Module::OpAtomicXor>, | ||
| 2568 | 2583 | ||
| 2569 | &SPIRVDecompiler::Branch, | 2584 | &SPIRVDecompiler::Branch, |
| 2570 | &SPIRVDecompiler::BranchIndirect, | 2585 | &SPIRVDecompiler::BranchIndirect, |
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 |