From 23170da5a0092c2a9d2d5d0b49da5ee1f53637ac Mon Sep 17 00:00:00 2001
From: Thog <me@thog.eu>
Date: Thu, 30 Apr 2020 05:03:05 +0200
Subject: [PATCH] audren: implement Renderer Info output informations (#1179)

This implement the rendering information output informations of
RequestUpdate.

This is needed by some games to keep track of the count of update on the
DSP.
---
 .../AudioRendererManager/IAudioRenderer.cs     | 18 ++++++++++++++++++
 .../Types/RendererInfoOut.cs                   | 11 +++++++++++
 Ryujinx.HLE/Utilities/StructWriter.cs          |  5 +++++
 3 files changed, 34 insertions(+)
 create mode 100644 Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/Types/RendererInfoOut.cs

diff --git a/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/IAudioRenderer.cs b/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/IAudioRenderer.cs
index b2a07e475d..b9f1d8df79 100644
--- a/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/IAudioRenderer.cs
+++ b/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/IAudioRenderer.cs
@@ -40,6 +40,8 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRendererManager
 
         private PlayState _playState;
 
+        private ulong _elapsedFrameCount;
+
         public IAudioRenderer(
             Horizon                system,
             MemoryManager          memory,
@@ -63,6 +65,8 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRendererManager
 
             _effects = CreateArray<EffectContext>(rendererParams.EffectCount);
 
+            _elapsedFrameCount = 0;
+
             InitializeAudioOut();
 
             _playState = PlayState.Stopped;
@@ -264,6 +268,18 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRendererManager
                 writer.Write(effect.OutStatus);
             }
 
+            writer.SkipBytes(_params.SinkCount * 0x20);
+            writer.SkipBytes(outputHeader.PerformanceManagerSize);
+            writer.SkipBytes(outputHeader.BehaviorSize);
+
+            if (behaviorInfo.IsElapsedFrameCountSupported())
+            {
+                writer.Write(new RendererInfoOut
+                {
+                    ElapsedFrameCount = _elapsedFrameCount
+                });
+            }
+
             return ResultCode.Success;
         }
 
@@ -331,6 +347,8 @@ namespace Ryujinx.HLE.HOS.Services.Audio.AudioRendererManager
             {
                 AppendMixedBuffer(released[index]);
             }
+
+            _elapsedFrameCount++;
         }
 
         private void AppendMixedBuffer(long tag)
diff --git a/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/Types/RendererInfoOut.cs b/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/Types/RendererInfoOut.cs
new file mode 100644
index 0000000000..0ea89384ad
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Audio/AudioRendererManager/Types/RendererInfoOut.cs
@@ -0,0 +1,11 @@
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Services.Audio.AudioRendererManager
+{
+    [StructLayout(LayoutKind.Sequential, Size = 0x10, Pack = 4)]
+    struct RendererInfoOut
+    {
+        public ulong ElapsedFrameCount;
+        public ulong Reserved;
+    }
+}
diff --git a/Ryujinx.HLE/Utilities/StructWriter.cs b/Ryujinx.HLE/Utilities/StructWriter.cs
index b488b5d613..1237746fa4 100644
--- a/Ryujinx.HLE/Utilities/StructWriter.cs
+++ b/Ryujinx.HLE/Utilities/StructWriter.cs
@@ -21,5 +21,10 @@ namespace Ryujinx.HLE.Utilities
 
             Position += Marshal.SizeOf<T>();
         }
+
+        public void SkipBytes(long count)
+        {
+            Position += count;
+        }
     }
 }