Textures : Increase the amount of VRAM Cache available for Textures based on selected DRAM. (#36)

This commit is contained in:
MaxLastBreath 2024-11-01 13:46:29 +02:00 committed by GitHub
parent fb4ab5ea08
commit 9305d171e7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 45 additions and 15 deletions

View file

@ -152,16 +152,17 @@ namespace Ryujinx.Graphics.Gpu
/// Creates a new GPU memory manager. /// Creates a new GPU memory manager.
/// </summary> /// </summary>
/// <param name="pid">ID of the process that owns the memory manager</param> /// <param name="pid">ID of the process that owns the memory manager</param>
/// <param name="cpuMemorySize">The amount of physical CPU Memory Avaiable on the device.</param>
/// <returns>The memory manager</returns> /// <returns>The memory manager</returns>
/// <exception cref="ArgumentException">Thrown when <paramref name="pid"/> is invalid</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="pid"/> is invalid</exception>
public MemoryManager CreateMemoryManager(ulong pid) public MemoryManager CreateMemoryManager(ulong pid, ulong cpuMemorySize)
{ {
if (!PhysicalMemoryRegistry.TryGetValue(pid, out var physicalMemory)) if (!PhysicalMemoryRegistry.TryGetValue(pid, out var physicalMemory))
{ {
throw new ArgumentException("The PID is invalid or the process was not registered", nameof(pid)); throw new ArgumentException("The PID is invalid or the process was not registered", nameof(pid));
} }
return new MemoryManager(physicalMemory); return new MemoryManager(physicalMemory, cpuMemorySize);
} }
/// <summary> /// <summary>

View file

@ -1,3 +1,4 @@
using Ryujinx.Common.Logging;
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
@ -47,11 +48,17 @@ namespace Ryujinx.Graphics.Gpu.Image
{ {
private const int MinCountForDeletion = 32; private const int MinCountForDeletion = 32;
private const int MaxCapacity = 2048; 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 MinTextureSizeCapacity = 512 * 1024 * 1024;
private const ulong MaxTextureSizeCapacity = 4UL * 1024 * 1024 * 1024; private const ulong DefaultTextureSizeCapacity = 1 * GiB;
private const ulong DefaultTextureSizeCapacity = 1UL * 1024 * 1024 * 1024; 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 const float MemoryScaleFactor = 0.50f;
private ulong _maxCacheMemoryUsage = 0; private ulong _maxCacheMemoryUsage = DefaultTextureSizeCapacity;
private readonly LinkedList<Texture> _textures; private readonly LinkedList<Texture> _textures;
private ulong _totalSize; private ulong _totalSize;
@ -66,18 +73,38 @@ namespace Ryujinx.Graphics.Gpu.Image
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// If the backend GPU has 0 memory capacity, the cache size defaults to `DefaultTextureSizeCapacity`. /// 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.
/// </remarks> /// </remarks>
/// <param name="context">The GPU context that the cache belongs to</param> /// <param name="context">The GPU context that the cache belongs to</param>
public void Initialize(GpuContext context) /// <param name="cpuMemorySize">The amount of physical CPU Memory Avaiable on the device.</param>
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); var cacheMemory = (ulong)(context.Capabilities.MaximumGpuMemory * MemoryScaleFactor);
_maxCacheMemoryUsage = Math.Clamp(cacheMemory, MinTextureSizeCapacity, MaxTextureSizeCapacity); _maxCacheMemoryUsage = Math.Clamp(cacheMemory, MinTextureSizeCapacity, MaxTextureSizeCapacity);
if (context.Capabilities.MaximumGpuMemory == 0) Logger.Info?.Print(LogClass.Gpu, $"AutoDelete Cache Allocated VRAM : {_maxCacheMemoryUsage / GiB} GiB");
{
_maxCacheMemoryUsage = DefaultTextureSizeCapacity;
}
} }
/// <summary> /// <summary>

View file

@ -71,9 +71,10 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <summary> /// <summary>
/// Initializes the cache, setting the maximum texture capacity for the specified GPU context. /// Initializes the cache, setting the maximum texture capacity for the specified GPU context.
/// </summary> /// </summary>
public void Initialize() /// <param name="cpuMemorySize">The amount of physical CPU Memory Avaiable on the device.</param>
public void Initialize(ulong cpuMemorySize)
{ {
_cache.Initialize(_context); _cache.Initialize(_context, cpuMemorySize);
} }
/// <summary> /// <summary>

View file

@ -55,7 +55,8 @@ namespace Ryujinx.Graphics.Gpu.Memory
/// Creates a new instance of the GPU memory manager. /// Creates a new instance of the GPU memory manager.
/// </summary> /// </summary>
/// <param name="physicalMemory">Physical memory that this memory manager will map into</param> /// <param name="physicalMemory">Physical memory that this memory manager will map into</param>
internal MemoryManager(PhysicalMemory physicalMemory) /// <param name="cpuMemorySize">The amount of physical CPU Memory Avaiable on the device.</param>
internal MemoryManager(PhysicalMemory physicalMemory, ulong cpuMemorySize)
{ {
Physical = physicalMemory; Physical = physicalMemory;
VirtualRangeCache = new VirtualRangeCache(this); VirtualRangeCache = new VirtualRangeCache(this);
@ -65,7 +66,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
MemoryUnmapped += Physical.BufferCache.MemoryUnmappedHandler; MemoryUnmapped += Physical.BufferCache.MemoryUnmappedHandler;
MemoryUnmapped += VirtualRangeCache.MemoryUnmappedHandler; MemoryUnmapped += VirtualRangeCache.MemoryUnmappedHandler;
MemoryUnmapped += CounterCache.MemoryUnmappedHandler; MemoryUnmapped += CounterCache.MemoryUnmappedHandler;
Physical.TextureCache.Initialize(); Physical.TextureCache.Initialize(cpuMemorySize);
} }
/// <summary> /// <summary>

View file

@ -42,7 +42,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
public NvHostAsGpuDeviceFile(ServiceCtx context, IVirtualMemoryManager memory, ulong owner) : base(context, owner) 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(); _memoryAllocator = new NvMemoryAllocator();
} }