瀏覽代碼

Change NvMap ID allocation to match nvservices (#3741)

* Change NvMap ID allocation to match nvservices

* Move NvMapIdDictionary to Types
gdkchan 3 年之前
父節點
當前提交
599d485bff

+ 4 - 20
Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/NvMapDeviceFile.cs

@@ -3,7 +3,6 @@ using Ryujinx.Common.Logging;
 using Ryujinx.Graphics.Gpu.Memory;
 using Ryujinx.Memory;
 using System;
-using System.Collections.Concurrent;
 
 namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
 {
@@ -11,13 +10,10 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
     {
         private const int FlagNotFreedYet = 1;
 
-        private static ConcurrentDictionary<ulong, IdDictionary> _maps = new ConcurrentDictionary<ulong, IdDictionary>();
+        private static NvMapIdDictionary _maps = new NvMapIdDictionary();
 
         public NvMapDeviceFile(ServiceCtx context, IVirtualMemoryManager memory, ulong owner) : base(context, owner)
         {
-            IdDictionary dict = _maps.GetOrAdd(Owner, (key) => new IdDictionary());
-
-            dict.Add(0, new NvMapHandle());
         }
 
         public override NvInternalResult Ioctl(NvIoctl command, Span<byte> arguments)
@@ -232,19 +228,12 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
 
         private int CreateHandleFromMap(NvMapHandle map)
         {
-            IdDictionary dict = _maps.GetOrAdd(Owner, (key) => new IdDictionary());
-
-            return dict.Add(map);
+            return _maps.Add(map);
         }
 
         private static bool DeleteMapWithHandle(ulong pid, int handle)
         {
-            if (_maps.TryGetValue(pid, out IdDictionary dict))
-            {
-                return dict.Delete(handle) != null;
-            }
-
-            return false;
+            return _maps.Delete(handle) != null;
         }
 
         public static void IncrementMapRefCount(ulong pid, int handle)
@@ -277,12 +266,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
 
         public static NvMapHandle GetMapFromHandle(ulong pid, int handle)
         {
-            if (_maps.TryGetValue(pid, out IdDictionary dict))
-            {
-                return dict.GetData<NvMapHandle>(handle);
-            }
-
-            return null;
+            return _maps.Get(handle);
         }
     }
 }

+ 61 - 0
Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvMap/Types/NvMapIdDictionary.cs

@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Threading;
+
+namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap
+{
+    class NvMapIdDictionary
+    {
+        private readonly ConcurrentDictionary<int, NvMapHandle> _nvmapHandles;
+        private int _id;
+
+        public ICollection<NvMapHandle> Values => _nvmapHandles.Values;
+
+        public NvMapIdDictionary()
+        {
+            _nvmapHandles = new ConcurrentDictionary<int, NvMapHandle>();
+        }
+
+        public int Add(NvMapHandle handle)
+        {
+            int id = Interlocked.Add(ref _id, 4);
+
+            if (id != 0 && _nvmapHandles.TryAdd(id, handle))
+            {
+                return id;
+            }
+
+            throw new InvalidOperationException("NvMap ID overflow.");
+        }
+
+        public NvMapHandle Get(int id)
+        {
+            if (_nvmapHandles.TryGetValue(id, out NvMapHandle handle))
+            {
+                return handle;
+            }
+
+            return null;
+        }
+
+        public NvMapHandle Delete(int id)
+        {
+            if (_nvmapHandles.TryRemove(id, out NvMapHandle handle))
+            {
+                return handle;
+            }
+
+            return null;
+        }
+
+        public ICollection<NvMapHandle> Clear()
+        {
+            ICollection<NvMapHandle> values = _nvmapHandles.Values;
+
+            _nvmapHandles.Clear();
+
+            return values;
+        }
+    }
+}