From 9305d171e70f53b786f13b6672db77d24614d192 Mon Sep 17 00:00:00 2001
From: MaxLastBreath <136052075+MaxLastBreath@users.noreply.github.com>
Date: Fri, 1 Nov 2024 13:46:29 +0200
Subject: [PATCH] Textures : Increase the amount of VRAM Cache available for
Textures based on selected DRAM. (#36)
---
src/Ryujinx.Graphics.Gpu/GpuContext.cs | 5 ++-
.../Image/AutoDeleteCache.cs | 43 +++++++++++++++----
.../Image/TextureCache.cs | 5 ++-
.../Memory/MemoryManager.cs | 5 ++-
.../NvHostAsGpu/NvHostAsGpuDeviceFile.cs | 2 +-
5 files changed, 45 insertions(+), 15 deletions(-)
diff --git a/src/Ryujinx.Graphics.Gpu/GpuContext.cs b/src/Ryujinx.Graphics.Gpu/GpuContext.cs
index 048d32fb7..fb529e914 100644
--- a/src/Ryujinx.Graphics.Gpu/GpuContext.cs
+++ b/src/Ryujinx.Graphics.Gpu/GpuContext.cs
@@ -152,16 +152,17 @@ namespace Ryujinx.Graphics.Gpu
/// Creates a new GPU memory manager.
///
/// ID of the process that owns the memory manager
+ /// The amount of physical CPU Memory Avaiable on the device.
/// The memory manager
/// Thrown when is invalid
- public MemoryManager CreateMemoryManager(ulong pid)
+ public MemoryManager CreateMemoryManager(ulong pid, ulong cpuMemorySize)
{
if (!PhysicalMemoryRegistry.TryGetValue(pid, out var physicalMemory))
{
throw new ArgumentException("The PID is invalid or the process was not registered", nameof(pid));
}
- return new MemoryManager(physicalMemory);
+ return new MemoryManager(physicalMemory, cpuMemorySize);
}
///
diff --git a/src/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs b/src/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs
index ad6c1fecb..74967b190 100644
--- a/src/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs
+++ b/src/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Common.Logging;
using System;
using System.Collections;
using System.Collections.Generic;
@@ -47,11 +48,17 @@ namespace Ryujinx.Graphics.Gpu.Image
{
private const int MinCountForDeletion = 32;
private const int MaxCapacity = 2048;
+ private const ulong GiB = 1024 * 1024 * 1024;
+ private ulong MaxTextureSizeCapacity = 4UL * GiB;
private const ulong MinTextureSizeCapacity = 512 * 1024 * 1024;
- private const ulong MaxTextureSizeCapacity = 4UL * 1024 * 1024 * 1024;
- private const ulong DefaultTextureSizeCapacity = 1UL * 1024 * 1024 * 1024;
+ private const ulong DefaultTextureSizeCapacity = 1 * GiB;
+ private const ulong TextureSizeCapacity6GiB = 4 * GiB;
+ private const ulong TextureSizeCapacity8GiB = 6 * GiB;
+ private const ulong TextureSizeCapacity12GiB = 12 * GiB;
+
+
private const float MemoryScaleFactor = 0.50f;
- private ulong _maxCacheMemoryUsage = 0;
+ private ulong _maxCacheMemoryUsage = DefaultTextureSizeCapacity;
private readonly LinkedList _textures;
private ulong _totalSize;
@@ -66,18 +73,38 @@ namespace Ryujinx.Graphics.Gpu.Image
///
///
/// If the backend GPU has 0 memory capacity, the cache size defaults to `DefaultTextureSizeCapacity`.
+ ///
+ /// Reads the current Device total CPU Memory, to determine the maximum amount of Vram available. Capped to 50% of Current GPU Memory.
///
/// The GPU context that the cache belongs to
- public void Initialize(GpuContext context)
+ /// The amount of physical CPU Memory Avaiable on the device.
+ public void Initialize(GpuContext context, ulong cpuMemorySize)
{
+ var cpuMemorySizeGiB = cpuMemorySize / GiB;
+
+ if (cpuMemorySizeGiB < 6 || context.Capabilities.MaximumGpuMemory == 0)
+ {
+ _maxCacheMemoryUsage = DefaultTextureSizeCapacity;
+ return;
+ }
+ else if (cpuMemorySizeGiB == 6)
+ {
+ MaxTextureSizeCapacity = TextureSizeCapacity6GiB;
+ }
+ else if (cpuMemorySizeGiB == 8)
+ {
+ MaxTextureSizeCapacity = TextureSizeCapacity8GiB;
+ }
+ else
+ {
+ MaxTextureSizeCapacity = TextureSizeCapacity12GiB;
+ }
+
var cacheMemory = (ulong)(context.Capabilities.MaximumGpuMemory * MemoryScaleFactor);
_maxCacheMemoryUsage = Math.Clamp(cacheMemory, MinTextureSizeCapacity, MaxTextureSizeCapacity);
- if (context.Capabilities.MaximumGpuMemory == 0)
- {
- _maxCacheMemoryUsage = DefaultTextureSizeCapacity;
- }
+ Logger.Info?.Print(LogClass.Gpu, $"AutoDelete Cache Allocated VRAM : {_maxCacheMemoryUsage / GiB} GiB");
}
///
diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
index 1587e2018..2cfd9af5b 100644
--- a/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
+++ b/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
@@ -71,9 +71,10 @@ namespace Ryujinx.Graphics.Gpu.Image
///
/// Initializes the cache, setting the maximum texture capacity for the specified GPU context.
///
- public void Initialize()
+ /// The amount of physical CPU Memory Avaiable on the device.
+ public void Initialize(ulong cpuMemorySize)
{
- _cache.Initialize(_context);
+ _cache.Initialize(_context, cpuMemorySize);
}
///
diff --git a/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs b/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
index d1065431d..59e618c02 100644
--- a/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
+++ b/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
@@ -55,7 +55,8 @@ namespace Ryujinx.Graphics.Gpu.Memory
/// Creates a new instance of the GPU memory manager.
///
/// Physical memory that this memory manager will map into
- internal MemoryManager(PhysicalMemory physicalMemory)
+ /// The amount of physical CPU Memory Avaiable on the device.
+ internal MemoryManager(PhysicalMemory physicalMemory, ulong cpuMemorySize)
{
Physical = physicalMemory;
VirtualRangeCache = new VirtualRangeCache(this);
@@ -65,7 +66,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
MemoryUnmapped += Physical.BufferCache.MemoryUnmappedHandler;
MemoryUnmapped += VirtualRangeCache.MemoryUnmappedHandler;
MemoryUnmapped += CounterCache.MemoryUnmappedHandler;
- Physical.TextureCache.Initialize();
+ Physical.TextureCache.Initialize(cpuMemorySize);
}
///
diff --git a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs
index ff9a67644..0f5d7547c 100644
--- a/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs
@@ -42,7 +42,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
public NvHostAsGpuDeviceFile(ServiceCtx context, IVirtualMemoryManager memory, ulong owner) : base(context, owner)
{
- _asContext = new AddressSpaceContext(context.Device.Gpu.CreateMemoryManager(owner));
+ _asContext = new AddressSpaceContext(context.Device.Gpu.CreateMemoryManager(owner, context.Device.Memory.Size));
_memoryAllocator = new NvMemoryAllocator();
}