From 1df6c07f78c4c3b8c7fc679d7466f79a10c2d496 Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
Date: Mon, 4 Dec 2023 16:30:19 -0300
Subject: Implement support for multi-range buffers using Vulkan sparse
 mappings (#5427)

* Pass MultiRange to BufferManager

* Implement support for multi-range buffers using Vulkan sparse mappings

* Use multi-range for remaining buffers, delete old methods

* Assume that more buffers are contiguous

* Dispose multi-range buffers after they are removed from the list

* Properly init BufferBounds for constant and storage buffers

* Do not try reading zero bytes data from an unmapped address on the shader cache + PR feedback

* Fix misaligned sparse buffer offsets

* Null check can be simplified

* PR feedback
---
 src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

(limited to 'src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs')

diff --git a/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
index 38be262a..af682e42 100644
--- a/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
+++ b/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
@@ -730,8 +730,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
 
             codeA ??= memoryManager.GetSpan(vertexA.Address, vertexA.Size).ToArray();
             codeB ??= memoryManager.GetSpan(currentStage.Address, currentStage.Size).ToArray();
-            byte[] cb1DataA = memoryManager.Physical.GetSpan(cb1DataAddress, vertexA.Cb1DataSize).ToArray();
-            byte[] cb1DataB = memoryManager.Physical.GetSpan(cb1DataAddress, currentStage.Cb1DataSize).ToArray();
+            byte[] cb1DataA = ReadArray(memoryManager, cb1DataAddress, vertexA.Cb1DataSize);
+            byte[] cb1DataB = ReadArray(memoryManager, cb1DataAddress, currentStage.Cb1DataSize);
 
             ShaderDumpPaths pathsA = default;
             ShaderDumpPaths pathsB = default;
@@ -770,7 +770,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
                 ? channel.BufferManager.GetComputeUniformBufferAddress(1)
                 : channel.BufferManager.GetGraphicsUniformBufferAddress(StageToStageIndex(context.Stage), 1);
 
-            byte[] cb1Data = memoryManager.Physical.GetSpan(cb1DataAddress, context.Cb1DataSize).ToArray();
+            byte[] cb1Data = ReadArray(memoryManager, cb1DataAddress, context.Cb1DataSize);
             code ??= memoryManager.GetSpan(context.Address, context.Size).ToArray();
 
             ShaderDumpPaths paths = dumper?.Dump(code, context.Stage == ShaderStage.Compute) ?? default;
@@ -781,6 +781,23 @@ namespace Ryujinx.Graphics.Gpu.Shader
             return new TranslatedShader(new CachedShaderStage(program.Info, code, cb1Data), program);
         }
 
+        /// <summary>
+        /// Reads data from physical memory, returns an empty array if the memory is unmapped or size is 0.
+        /// </summary>
+        /// <param name="memoryManager">Memory manager with the physical memory to read from</param>
+        /// <param name="address">Physical address of the region to read</param>
+        /// <param name="size">Size in bytes of the data</param>
+        /// <returns>An array with the data at the specified memory location</returns>
+        private static byte[] ReadArray(MemoryManager memoryManager, ulong address, int size)
+        {
+            if (address == MemoryManager.PteUnmapped || size == 0)
+            {
+                return Array.Empty<byte>();
+            }
+
+            return memoryManager.Physical.GetSpan(address, size).ToArray();
+        }
+
         /// <summary>
         /// Gets the index of a stage from a <see cref="ShaderStage"/>.
         /// </summary>
-- 
cgit v1.2.3-70-g09d2