summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/engines/shader_bytecode.h37
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp12
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp7
-rw-r--r--src/video_core/shader/decode/memory.cpp19
-rw-r--r--src/video_core/shader/node.h2
5 files changed, 74 insertions, 3 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 57b57c647..6f98bd827 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -215,6 +215,18 @@ enum class F2fRoundingOp : u64 {
215 Trunc = 11, 215 Trunc = 11,
216}; 216};
217 217
218enum class AtomicOp : u64 {
219 Add = 0,
220 Min = 1,
221 Max = 2,
222 Inc = 3,
223 Dec = 4,
224 And = 5,
225 Or = 6,
226 Xor = 7,
227 Exch = 8,
228};
229
218enum class UniformType : u64 { 230enum class UniformType : u64 {
219 UnsignedByte = 0, 231 UnsignedByte = 0,
220 SignedByte = 1, 232 SignedByte = 1,
@@ -236,6 +248,13 @@ enum class StoreType : u64 {
236 Bits128 = 6, 248 Bits128 = 6,
237}; 249};
238 250
251enum class AtomicType : u64 {
252 U32 = 0,
253 S32 = 1,
254 U64 = 2,
255 S64 = 3,
256};
257
239enum class IMinMaxExchange : u64 { 258enum class IMinMaxExchange : u64 {
240 None = 0, 259 None = 0,
241 XLo = 1, 260 XLo = 1,
@@ -939,6 +958,16 @@ union Instruction {
939 } stg; 958 } stg;
940 959
941 union { 960 union {
961 BitField<52, 4, AtomicOp> operation;
962 BitField<28, 2, AtomicType> type;
963 BitField<30, 22, s64> offset;
964
965 s32 GetImmediateOffset() const {
966 return static_cast<s32>(offset << 2);
967 }
968 } atoms;
969
970 union {
942 BitField<32, 1, PhysicalAttributeDirection> direction; 971 BitField<32, 1, PhysicalAttributeDirection> direction;
943 BitField<47, 3, AttributeSize> size; 972 BitField<47, 3, AttributeSize> size;
944 BitField<20, 11, u64> address; 973 BitField<20, 11, u64> address;
@@ -1659,9 +1688,10 @@ public:
1659 ST_A, 1688 ST_A,
1660 ST_L, 1689 ST_L,
1661 ST_S, 1690 ST_S,
1662 ST, // Store in generic memory 1691 ST, // Store in generic memory
1663 STG, // Store in global memory 1692 STG, // Store in global memory
1664 AL2P, // Transforms attribute memory into physical memory 1693 ATOMS, // Atomic operation on shared memory
1694 AL2P, // Transforms attribute memory into physical memory
1665 TEX, 1695 TEX,
1666 TEX_B, // Texture Load Bindless 1696 TEX_B, // Texture Load Bindless
1667 TXQ, // Texture Query 1697 TXQ, // Texture Query
@@ -1964,6 +1994,7 @@ private:
1964 INST("1110111101010---", Id::ST_L, Type::Memory, "ST_L"), 1994 INST("1110111101010---", Id::ST_L, Type::Memory, "ST_L"),
1965 INST("101-------------", Id::ST, Type::Memory, "ST"), 1995 INST("101-------------", Id::ST, Type::Memory, "ST"),
1966 INST("1110111011011---", Id::STG, Type::Memory, "STG"), 1996 INST("1110111011011---", Id::STG, Type::Memory, "STG"),
1997 INST("11101100--------", Id::ATOMS, Type::Memory, "ATOMS"),
1967 INST("1110111110100---", Id::AL2P, Type::Memory, "AL2P"), 1998 INST("1110111110100---", Id::AL2P, Type::Memory, "AL2P"),
1968 INST("110000----111---", Id::TEX, Type::Texture, "TEX"), 1999 INST("110000----111---", Id::TEX, Type::Texture, "TEX"),
1969 INST("1101111010111---", Id::TEX_B, Type::Texture, "TEX_B"), 2000 INST("1101111010111---", Id::TEX_B, Type::Texture, "TEX_B"),
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index f9f7a97b5..19751939a 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -1856,6 +1856,16 @@ private:
1856 Type::Uint}; 1856 Type::Uint};
1857 } 1857 }
1858 1858
1859 template <const std::string_view& opname, Type type>
1860 Expression Atomic(Operation operation) {
1861 ASSERT(stage == ShaderType::Compute);
1862 auto& smem = std::get<SmemNode>(*operation[0]);
1863
1864 return {fmt::format("atomic{}(smem[{} >> 2], {})", opname, Visit(smem.GetAddress()).AsInt(),
1865 Visit(operation[1]).As(type)),
1866 type};
1867 }
1868
1859 Expression Branch(Operation operation) { 1869 Expression Branch(Operation operation) {
1860 const auto target = std::get_if<ImmediateNode>(&*operation[0]); 1870 const auto target = std::get_if<ImmediateNode>(&*operation[0]);
1861 UNIMPLEMENTED_IF(!target); 1871 UNIMPLEMENTED_IF(!target);
@@ -2194,6 +2204,8 @@ private:
2194 &GLSLDecompiler::AtomicImage<Func::Xor>, 2204 &GLSLDecompiler::AtomicImage<Func::Xor>,
2195 &GLSLDecompiler::AtomicImage<Func::Exchange>, 2205 &GLSLDecompiler::AtomicImage<Func::Exchange>,
2196 2206
2207 &GLSLDecompiler::Atomic<Func::Add, Type::Uint>,
2208
2197 &GLSLDecompiler::Branch, 2209 &GLSLDecompiler::Branch,
2198 &GLSLDecompiler::BranchIndirect, 2210 &GLSLDecompiler::BranchIndirect,
2199 &GLSLDecompiler::PushFlowStack, 2211 &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 8fe852ce8..0cf97cafa 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
@@ -1796,6 +1796,11 @@ private:
1796 return {}; 1796 return {};
1797 } 1797 }
1798 1798
1799 Expression UAtomicAdd(Operation) {
1800 UNIMPLEMENTED();
1801 return {};
1802 }
1803
1799 Expression Branch(Operation operation) { 1804 Expression Branch(Operation operation) {
1800 const auto& target = std::get<ImmediateNode>(*operation[0]); 1805 const auto& target = std::get<ImmediateNode>(*operation[0]);
1801 OpStore(jmp_to, Constant(t_uint, target.GetValue())); 1806 OpStore(jmp_to, Constant(t_uint, target.GetValue()));
@@ -2373,6 +2378,8 @@ private:
2373 &SPIRVDecompiler::AtomicImageXor, 2378 &SPIRVDecompiler::AtomicImageXor,
2374 &SPIRVDecompiler::AtomicImageExchange, 2379 &SPIRVDecompiler::AtomicImageExchange,
2375 2380
2381 &SPIRVDecompiler::UAtomicAdd,
2382
2376 &SPIRVDecompiler::Branch, 2383 &SPIRVDecompiler::Branch,
2377 &SPIRVDecompiler::BranchIndirect, 2384 &SPIRVDecompiler::BranchIndirect,
2378 &SPIRVDecompiler::PushFlowStack, 2385 &SPIRVDecompiler::PushFlowStack,
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp
index 8cc84e935..7591a715f 100644
--- a/src/video_core/shader/decode/memory.cpp
+++ b/src/video_core/shader/decode/memory.cpp
@@ -16,6 +16,8 @@
16 16
17namespace VideoCommon::Shader { 17namespace VideoCommon::Shader {
18 18
19using Tegra::Shader::AtomicOp;
20using Tegra::Shader::AtomicType;
19using Tegra::Shader::Attribute; 21using Tegra::Shader::Attribute;
20using Tegra::Shader::Instruction; 22using Tegra::Shader::Instruction;
21using Tegra::Shader::OpCode; 23using Tegra::Shader::OpCode;
@@ -333,6 +335,23 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
333 } 335 }
334 break; 336 break;
335 } 337 }
338 case OpCode::Id::ATOMS: {
339 UNIMPLEMENTED_IF_MSG(instr.atoms.operation != AtomicOp::Add, "operation={}",
340 static_cast<int>(instr.atoms.operation.Value()));
341 UNIMPLEMENTED_IF_MSG(instr.atoms.type != AtomicType::U32, "type={}",
342 static_cast<int>(instr.atoms.type.Value()));
343
344 const s32 offset = instr.atoms.GetImmediateOffset();
345 Node address = GetRegister(instr.gpr8);
346 address = Operation(OperationCode::IAdd, std::move(address), Immediate(offset));
347
348 Node memory = GetSharedMemory(std::move(address));
349 Node data = GetRegister(instr.gpr20);
350
351 Node value = Operation(OperationCode::UAtomicAdd, std::move(memory), std::move(data));
352 SetRegister(bb, instr.gpr0, std::move(value));
353 break;
354 }
336 case OpCode::Id::AL2P: { 355 case OpCode::Id::AL2P: {
337 // Ignore al2p.direction since we don't care about it. 356 // Ignore al2p.direction since we don't care about it.
338 357
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h
index 4e155542a..075c7d07c 100644
--- a/src/video_core/shader/node.h
+++ b/src/video_core/shader/node.h
@@ -162,6 +162,8 @@ enum class OperationCode {
162 AtomicImageXor, /// (MetaImage, int[N] coords) -> void 162 AtomicImageXor, /// (MetaImage, int[N] coords) -> void
163 AtomicImageExchange, /// (MetaImage, int[N] coords) -> void 163 AtomicImageExchange, /// (MetaImage, int[N] coords) -> void
164 164
165 UAtomicAdd, /// (smem, uint) -> uint
166
165 Branch, /// (uint branch_target) -> void 167 Branch, /// (uint branch_target) -> void
166 BranchIndirect, /// (uint branch_target) -> void 168 BranchIndirect, /// (uint branch_target) -> void
167 PushFlowStack, /// (uint branch_target) -> void 169 PushFlowStack, /// (uint branch_target) -> void