From a0e6647860b689cd2c3d865e6b235b12ec96b89a Mon Sep 17 00:00:00 2001
From: riperiperi <rhy3756547@hotmail.com>
Date: Mon, 3 Feb 2020 19:11:22 +0000
Subject: [PATCH] Compare shader code using a span instead of individual reads.
 (#917)

* Compare shader code using a span instead of individual reads.

* Add comment for new parameter.

* Remove unnecessary Math.Min
---
 Ryujinx.Graphics.Gpu/Memory/MemoryAccessor.cs |  2 +-
 Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs  |  7 ++++++-
 Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs    | 10 ++--------
 3 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/Ryujinx.Graphics.Gpu/Memory/MemoryAccessor.cs b/Ryujinx.Graphics.Gpu/Memory/MemoryAccessor.cs
index 17c0006288..fbe2cbc423 100644
--- a/Ryujinx.Graphics.Gpu/Memory/MemoryAccessor.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/MemoryAccessor.cs
@@ -41,7 +41,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
         {
             ulong processVa = _context.MemoryManager.Translate(gpuVa);
 
-            ulong size = Math.Min(_context.MemoryManager.GetSubSize(gpuVa), maxSize);
+            ulong size = _context.MemoryManager.GetSubSize(gpuVa, maxSize);
 
             return _context.PhysicalMemory.GetSpan(processVa, size);
         }
diff --git a/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs b/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
index ffca6f339b..e89255c884 100644
--- a/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
@@ -237,14 +237,19 @@ namespace Ryujinx.Graphics.Gpu.Memory
         /// Gets the number of mapped or reserved pages on a given region.
         /// </summary>
         /// <param name="gpuVa">Start GPU virtual address of the region</param>
+        /// <param name="maxSize">Maximum size of the data</param>
         /// <returns>Mapped size in bytes of the specified region</returns>
-        internal ulong GetSubSize(ulong gpuVa)
+        internal ulong GetSubSize(ulong gpuVa, ulong maxSize)
         {
             ulong size = 0;
 
             while (GetPte(gpuVa + size) != PteUnmapped)
             {
                 size += PageSize;
+                if (size >= maxSize)
+                {
+                    return maxSize;
+                }
             }
 
             return size;
diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
index 8aa9b1c7b5..fc4bf778b9 100644
--- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
@@ -235,15 +235,9 @@ namespace Ryujinx.Graphics.Gpu.Shader
                 return false;
             }
 
-            for (int index = 0; index < shader.Code.Length; index++)
-            {
-                if (_context.MemoryAccessor.ReadInt32(gpuVa + (ulong)index * 4) != shader.Code[index])
-                {
-                    return true;
-                }
-            }
+            ReadOnlySpan<byte> memoryCode = _context.MemoryAccessor.GetSpan(gpuVa, (ulong)shader.Code.Length * 4);
 
-            return false;
+            return !MemoryMarshal.Cast<byte, int>(memoryCode).SequenceEqual(shader.Code);
         }
 
         /// <summary>