Эх сурвалжийг харах

Implement FIFO semaphore (#1286)

* Implement FIFO semaphore

* New enum for FIFO semaphore operation
gdkchan 5 жил өмнө
parent
commit
44d7fcff39

+ 27 - 1
Ryujinx.Graphics.Gpu/Engine/MethodFifo.cs

@@ -1,11 +1,37 @@
 using Ryujinx.Graphics.Gpu.State;
-using System;
 using System.Threading;
 
 namespace Ryujinx.Graphics.Gpu.Engine
 {
     partial class Methods
     {
+        /// <summary>
+        /// Writes a GPU counter to guest memory.
+        /// </summary>
+        /// <param name="state">Current GPU state</param>
+        /// <param name="argument">Method call argument</param>
+        public void Semaphore(GpuState state, int argument)
+        {
+            FifoSemaphoreOperation op = (FifoSemaphoreOperation)(argument & 3);
+
+            var semaphore = state.Get<SemaphoreState>(MethodOffset.Semaphore);
+
+            int value = semaphore.Payload;
+
+            if (op == FifoSemaphoreOperation.Counter)
+            {
+                // TODO: There's much more that should be done here.
+                // NVN only supports the "Accumulate" mode, so we
+                // can't currently guess which bits specify the
+                // reduction operation.
+                value += _context.MemoryAccessor.Read<int>(semaphore.Address.Pack());
+            }
+
+            _context.MemoryAccessor.Write(semaphore.Address.Pack(), value);
+
+            _context.AdvanceSequence();
+        }
+
         /// <summary>
         /// Waits for the GPU to be idle.
         /// </summary>

+ 6 - 7
Ryujinx.Graphics.Gpu/Engine/MethodReport.cs

@@ -21,14 +21,13 @@ namespace Ryujinx.Graphics.Gpu.Engine
         /// <param name="argument">Method call argument</param>
         private void Report(GpuState state, int argument)
         {
-            ReportMode mode = (ReportMode)(argument & 3);
-
+            SemaphoreOperation op = (SemaphoreOperation)(argument & 3);
             ReportCounterType type = (ReportCounterType)((argument >> 23) & 0x1f);
 
-            switch (mode)
+            switch (op)
             {
-                case ReportMode.Release: ReleaseSemaphore(state);    break;
-                case ReportMode.Counter: ReportCounter(state, type); break;
+                case SemaphoreOperation.Release: ReleaseSemaphore(state);    break;
+                case SemaphoreOperation.Counter: ReportCounter(state, type); break;
             }
         }
 
@@ -38,7 +37,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
         /// <param name="state">Current GPU state</param>
         private void ReleaseSemaphore(GpuState state)
         {
-            var rs = state.Get<ReportState>(MethodOffset.ReportState);
+            var rs = state.Get<SemaphoreState>(MethodOffset.ReportState);
 
             _context.MemoryAccessor.Write(rs.Address.Pack(), rs.Payload);
 
@@ -64,7 +63,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
         {
             CounterData counterData = new CounterData();
 
-            var rs = state.Get<ReportState>(MethodOffset.ReportState);
+            var rs = state.Get<SemaphoreState>(MethodOffset.ReportState);
 
             ulong gpuVa = rs.Address.Pack();
 

+ 2 - 1
Ryujinx.Graphics.Gpu/Engine/Methods.cs

@@ -104,6 +104,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
         /// <param name="state">GPU state where the triggers will be registered</param>
         public void RegisterCallbacksForFifo(GpuState state)
         {
+            state.RegisterCallback(MethodOffset.Semaphore,              Semaphore);
             state.RegisterCallback(MethodOffset.FenceAction,            FenceAction);
             state.RegisterCallback(MethodOffset.WaitForIdle,            WaitForIdle);
             state.RegisterCallback(MethodOffset.SendMacroCodeData,      SendMacroCodeData);
@@ -430,7 +431,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
             _context.Renderer.Pipeline.SetOrigin(origin);
 
             // The triangle rast flip flag only affects rasterization, the viewport is not flipped.
-            // Setting the origin mode to upper left on the host, however, not onlyy affects rasterization,
+            // Setting the origin mode to upper left on the host, however, not only affects rasterization,
             // but also flips the viewport.
             // We negate the effects of flipping the viewport by flipping it again using the viewport swizzle.
             if (origin == Origin.UpperLeft)

+ 9 - 0
Ryujinx.Graphics.Gpu/State/FifoSemaphoreOperation.cs

@@ -0,0 +1,9 @@
+namespace Ryujinx.Graphics.Gpu.State
+{
+    enum FifoSemaphoreOperation
+    {
+        Counter = 0,
+        Acquire = 1,
+        Release = 2
+    }
+}

+ 2 - 1
Ryujinx.Graphics.Gpu/State/MethodOffset.cs

@@ -8,7 +8,8 @@ namespace Ryujinx.Graphics.Gpu.State
     /// </remarks>
     enum MethodOffset
     {
-        BindChannel                     = 0x00,
+        BindChannel                     = 0x0,
+        Semaphore                       = 0x4,
         FenceValue                      = 0x1c,
         FenceAction                     = 0x1d,
         WaitForIdle                     = 0x44,

+ 2 - 2
Ryujinx.Graphics.Gpu/State/ReportMode.cs → Ryujinx.Graphics.Gpu/State/SemaphoreOperation.cs

@@ -1,9 +1,9 @@
 namespace Ryujinx.Graphics.Gpu.State
 {
     /// <summary>
-    /// GPU counter report mode.
+    /// GPU semaphore operation.
     /// </summary>
-    enum ReportMode
+    enum SemaphoreOperation
     {
         Release = 0,
         Acquire = 1,

+ 2 - 2
Ryujinx.Graphics.Gpu/State/ReportState.cs → Ryujinx.Graphics.Gpu/State/SemaphoreState.cs

@@ -1,9 +1,9 @@
 namespace Ryujinx.Graphics.Gpu.State
 {
     /// <summary>
-    /// GPU counter report state.
+    /// GPU semaphore state.
     /// </summary>
-    struct ReportState
+    struct SemaphoreState
     {
 #pragma warning disable CS0649
         public GpuVa Address;