From ef81658fbd5b2aa23bf7e71b22a636da9a16c67b Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
Date: Wed, 18 Sep 2024 15:48:55 -0300
Subject: Implement support for shader ATOM.EXCH instruction (#7320)

* Implement support for shader ATOM.EXCH instruction

* Shader cache version bump

* Check type
---
 .../Shader/DiskCache/DiskCacheHostStorage.cs       |  2 +-
 .../Instructions/InstEmitMemory.cs                 | 51 ++++++++++++++--------
 2 files changed, 33 insertions(+), 20 deletions(-)

(limited to 'src')

diff --git a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
index c1f59201..e1e696ca 100644
--- a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
+++ b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
         private const ushort FileFormatVersionMajor = 1;
         private const ushort FileFormatVersionMinor = 2;
         private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
-        private const uint CodeGenVersion = 7131;
+        private const uint CodeGenVersion = 7320;
 
         private const string SharedTocFileName = "shared.toc";
         private const string SharedDataFileName = "shared.data";
diff --git a/src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs b/src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
index 40129252..3fcb821d 100644
--- a/src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
+++ b/src/Ryujinx.Graphics.Shader/Instructions/InstEmitMemory.cs
@@ -222,20 +222,38 @@ namespace Ryujinx.Graphics.Shader.Instructions
                         context.TranslatorContext.GpuAccessor.Log($"Invalid reduction type: {type}.");
                     }
                     break;
-                case AtomOp.And:
-                    if (type == AtomSize.S32 || type == AtomSize.U32)
+                case AtomOp.Min:
+                    if (type == AtomSize.S32)
                     {
-                        res = context.AtomicAnd(storageKind, e0, e1, value);
+                        res = context.AtomicMinS32(storageKind, e0, e1, value);
+                    }
+                    else if (type == AtomSize.U32)
+                    {
+                        res = context.AtomicMinU32(storageKind, e0, e1, value);
                     }
                     else
                     {
                         context.TranslatorContext.GpuAccessor.Log($"Invalid reduction type: {type}.");
                     }
                     break;
-                case AtomOp.Xor:
+                case AtomOp.Max:
+                    if (type == AtomSize.S32)
+                    {
+                        res = context.AtomicMaxS32(storageKind, e0, e1, value);
+                    }
+                    else if (type == AtomSize.U32)
+                    {
+                        res = context.AtomicMaxU32(storageKind, e0, e1, value);
+                    }
+                    else
+                    {
+                        context.TranslatorContext.GpuAccessor.Log($"Invalid reduction type: {type}.");
+                    }
+                    break;
+                case AtomOp.And:
                     if (type == AtomSize.S32 || type == AtomSize.U32)
                     {
-                        res = context.AtomicXor(storageKind, e0, e1, value);
+                        res = context.AtomicAnd(storageKind, e0, e1, value);
                     }
                     else
                     {
@@ -252,34 +270,29 @@ namespace Ryujinx.Graphics.Shader.Instructions
                         context.TranslatorContext.GpuAccessor.Log($"Invalid reduction type: {type}.");
                     }
                     break;
-                case AtomOp.Max:
-                    if (type == AtomSize.S32)
-                    {
-                        res = context.AtomicMaxS32(storageKind, e0, e1, value);
-                    }
-                    else if (type == AtomSize.U32)
+                case AtomOp.Xor:
+                    if (type == AtomSize.S32 || type == AtomSize.U32)
                     {
-                        res = context.AtomicMaxU32(storageKind, e0, e1, value);
+                        res = context.AtomicXor(storageKind, e0, e1, value);
                     }
                     else
                     {
                         context.TranslatorContext.GpuAccessor.Log($"Invalid reduction type: {type}.");
                     }
                     break;
-                case AtomOp.Min:
-                    if (type == AtomSize.S32)
-                    {
-                        res = context.AtomicMinS32(storageKind, e0, e1, value);
-                    }
-                    else if (type == AtomSize.U32)
+                case AtomOp.Exch:
+                    if (type == AtomSize.S32 || type == AtomSize.U32)
                     {
-                        res = context.AtomicMinU32(storageKind, e0, e1, value);
+                        res = context.AtomicSwap(storageKind, e0, e1, value);
                     }
                     else
                     {
                         context.TranslatorContext.GpuAccessor.Log($"Invalid reduction type: {type}.");
                     }
                     break;
+                default:
+                    context.TranslatorContext.GpuAccessor.Log($"Invalid atomic operation: {op}.");
+                    break;
             }
 
             return res;
-- 
cgit v1.2.3-70-g09d2