Просмотр исходного кода

Add support for releasing a semaphore to DmaClass (#2926)

* Add support for releasing a semaphore to DmaClass

Fixes freezes in OpenGL games, primarily GameMaker ones such as Undertale.

* Address Feedback
riperiperi 4 лет назад
Родитель
Сommit
521a07e612
1 измененных файлов с 34 добавлено и 2 удалено
  1. 34 2
      Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs

+ 34 - 2
Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs

@@ -1,4 +1,5 @@
 using Ryujinx.Common;
+using Ryujinx.Common.Logging;
 using Ryujinx.Graphics.Device;
 using Ryujinx.Graphics.Gpu.Engine.Threed;
 using Ryujinx.Graphics.Texture;
@@ -98,11 +99,32 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
             }
         }
 
+        /// <summary>
+        /// Releases a semaphore for a given LaunchDma method call.
+        /// </summary>
+        /// <param name="argument">The LaunchDma call argument</param>
+        private void ReleaseSemaphore(int argument)
+        {
+            LaunchDmaSemaphoreType type = (LaunchDmaSemaphoreType)((argument >> 3) & 0x3);
+            if (type != LaunchDmaSemaphoreType.None)
+            {
+                ulong address = ((ulong)_state.State.SetSemaphoreA << 32) | _state.State.SetSemaphoreB;
+                if (type == LaunchDmaSemaphoreType.ReleaseOneWordSemaphore)
+                {
+                    _channel.MemoryManager.Write(address, _state.State.SetSemaphorePayload);
+                }
+                else /* if (type == LaunchDmaSemaphoreType.ReleaseFourWordSemaphore) */
+                {
+                    Logger.Warning?.Print(LogClass.Gpu, "DMA semaphore type ReleaseFourWordSemaphore was used, but is not currently implemented.");
+                }
+            }
+        }
+
         /// <summary>
         /// Performs a buffer to buffer, or buffer to texture copy.
         /// </summary>
-        /// <param name="argument">Method call argument</param>
-        private void LaunchDma(int argument)
+        /// <param name="argument">The LaunchDma call argument</param>
+        private void DmaCopy(int argument)
         {
             var memoryManager = _channel.MemoryManager;
 
@@ -296,5 +318,15 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
                 }
             }
         }
+
+        /// <summary>
+        /// Performs a buffer to buffer, or buffer to texture copy, then optionally releases a semaphore.
+        /// </summary>
+        /// <param name="argument">Method call argument</param>
+        private void LaunchDma(int argument)
+        {
+            DmaCopy(argument);
+            ReleaseSemaphore(argument);
+        }
     }
 }