From b2c976ad0e5dbbcae16c419628c144a7f28e0d17 Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Sun, 19 Jan 2020 16:37:39 -0300
Subject: [PATCH] vk_shader_decompiler: Implement UAtomicAdd (ATOMS) on SPIR-V

Also updates sirit to include atomic instructions.
---
 externals/sirit                                    |  2 +-
 .../renderer_vulkan/vk_shader_decompiler.cpp       | 14 +++++++++++---
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/externals/sirit b/externals/sirit
index 9f4d057aa2..a712959f1e 160000
--- a/externals/sirit
+++ b/externals/sirit
@@ -1 +1 @@
-Subproject commit 9f4d057aa28c4e9509bdc767afb27b4aee303b7e
+Subproject commit a712959f1e373a33b48042b5934e288a243d5954
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
index 0cf97cafac..dd6d2ef030 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
@@ -1796,9 +1796,17 @@ private:
         return {};
     }
 
-    Expression UAtomicAdd(Operation) {
-        UNIMPLEMENTED();
-        return {};
+    Expression UAtomicAdd(Operation operation) {
+        const auto& smem = std::get<SmemNode>(*operation[0]);
+        Id address = AsUint(Visit(smem.GetAddress()));
+        address = OpShiftRightLogical(t_uint, address, Constant(t_uint, 2U));
+        const Id pointer = OpAccessChain(t_smem_uint, shared_memory, address);
+
+        const Id scope = Constant(t_uint, static_cast<u32>(spv::Scope::Device));
+        const Id semantics = Constant(t_uint, 0U);
+
+        const Id value = AsUint(Visit(operation[1]));
+        return {OpAtomicIAdd(t_uint, pointer, scope, semantics, value), Type::Uint};
     }
 
     Expression Branch(Operation operation) {