diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 68be1f5e0..ffb5d5f8b 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -23,7 +23,7 @@ body:
attributes:
label: Log file
description: A log file will help our developers to better diagnose and fix the issue.
- placeholder: Logs files can be found under "Logs" folder in Ryujinx program folder. You can drag and drop the log on to the text area
+ placeholder: Logs files can be found under "Logs" folder in Ryujinx program folder. They can also be accessed by opening Ryujinx, then going to File > Open Logs Folder. You can drag and drop the log on to the text area (do not copy paste).
validations:
required: true
- type: input
@@ -83,4 +83,4 @@ body:
- Additional info about your environment:
- Any other information relevant to your issue.
validations:
- required: false
\ No newline at end of file
+ required: false
diff --git a/Directory.Packages.props b/Directory.Packages.props
index c97babaaf..301024cf8 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -47,6 +47,6 @@
-
+
\ No newline at end of file
diff --git a/src/Ryujinx.Graphics.GAL/Capabilities.cs b/src/Ryujinx.Graphics.GAL/Capabilities.cs
index a5c6eb5c8..1eec80e51 100644
--- a/src/Ryujinx.Graphics.GAL/Capabilities.cs
+++ b/src/Ryujinx.Graphics.GAL/Capabilities.cs
@@ -71,6 +71,8 @@ namespace Ryujinx.Graphics.GAL
public readonly int GatherBiasPrecision;
+ public readonly ulong MaximumGpuMemory;
+
public Capabilities(
TargetApi api,
string vendorName,
@@ -131,7 +133,8 @@ namespace Ryujinx.Graphics.GAL
int shaderSubgroupSize,
int storageBufferOffsetAlignment,
int textureBufferOffsetAlignment,
- int gatherBiasPrecision)
+ int gatherBiasPrecision,
+ ulong maximumGpuMemory)
{
Api = api;
VendorName = vendorName;
@@ -193,6 +196,7 @@ namespace Ryujinx.Graphics.GAL
StorageBufferOffsetAlignment = storageBufferOffsetAlignment;
TextureBufferOffsetAlignment = textureBufferOffsetAlignment;
GatherBiasPrecision = gatherBiasPrecision;
+ MaximumGpuMemory = maximumGpuMemory;
}
}
}
diff --git a/src/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs b/src/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs
index 5e66a3b54..ad6c1fecb 100644
--- a/src/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs
+++ b/src/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections;
using System.Collections.Generic;
@@ -46,7 +47,11 @@ namespace Ryujinx.Graphics.Gpu.Image
{
private const int MinCountForDeletion = 32;
private const int MaxCapacity = 2048;
- private const ulong MaxTextureSizeCapacity = 1024 * 1024 * 1024; // MB;
+ 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 float MemoryScaleFactor = 0.50f;
+ private ulong _maxCacheMemoryUsage = 0;
private readonly LinkedList _textures;
private ulong _totalSize;
@@ -56,6 +61,25 @@ namespace Ryujinx.Graphics.Gpu.Image
private readonly Dictionary _shortCacheLookup;
+ ///
+ /// Initializes the cache, setting the maximum texture capacity for the specified GPU context.
+ ///
+ ///
+ /// If the backend GPU has 0 memory capacity, the cache size defaults to `DefaultTextureSizeCapacity`.
+ ///
+ /// The GPU context that the cache belongs to
+ public void Initialize(GpuContext context)
+ {
+ var cacheMemory = (ulong)(context.Capabilities.MaximumGpuMemory * MemoryScaleFactor);
+
+ _maxCacheMemoryUsage = Math.Clamp(cacheMemory, MinTextureSizeCapacity, MaxTextureSizeCapacity);
+
+ if (context.Capabilities.MaximumGpuMemory == 0)
+ {
+ _maxCacheMemoryUsage = DefaultTextureSizeCapacity;
+ }
+ }
+
///
/// Creates a new instance of the automatic deletion cache.
///
@@ -85,7 +109,7 @@ namespace Ryujinx.Graphics.Gpu.Image
texture.CacheNode = _textures.AddLast(texture);
if (_textures.Count > MaxCapacity ||
- (_totalSize > MaxTextureSizeCapacity && _textures.Count >= MinCountForDeletion))
+ (_totalSize > _maxCacheMemoryUsage && _textures.Count >= MinCountForDeletion))
{
RemoveLeastUsedTexture();
}
@@ -110,7 +134,7 @@ namespace Ryujinx.Graphics.Gpu.Image
_textures.AddLast(texture.CacheNode);
}
- if (_totalSize > MaxTextureSizeCapacity && _textures.Count >= MinCountForDeletion)
+ if (_totalSize > _maxCacheMemoryUsage && _textures.Count >= MinCountForDeletion)
{
RemoveLeastUsedTexture();
}
diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
index 5a3319b06..1587e2018 100644
--- a/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
+++ b/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs
@@ -68,6 +68,14 @@ namespace Ryujinx.Graphics.Gpu.Image
_cache = new AutoDeleteCache();
}
+ ///
+ /// Initializes the cache, setting the maximum texture capacity for the specified GPU context.
+ ///
+ public void Initialize()
+ {
+ _cache.Initialize(_context);
+ }
+
///
/// Handles marking of textures written to a memory region being (partially) remapped.
///
diff --git a/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs b/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
index 59a940a4f..d1065431d 100644
--- a/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
+++ b/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
@@ -1,4 +1,5 @@
using Ryujinx.Common.Memory;
+using Ryujinx.Graphics.Gpu.Image;
using Ryujinx.Memory;
using Ryujinx.Memory.Range;
using System;
@@ -64,6 +65,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
MemoryUnmapped += Physical.BufferCache.MemoryUnmappedHandler;
MemoryUnmapped += VirtualRangeCache.MemoryUnmappedHandler;
MemoryUnmapped += CounterCache.MemoryUnmappedHandler;
+ Physical.TextureCache.Initialize();
}
///
diff --git a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
index a5c5abd4b..c36fc0ada 100644
--- a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
+++ b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 2;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
- private const uint CodeGenVersion = 7331;
+ private const uint CodeGenVersion = 7353;
private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data";
diff --git a/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs b/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs
index ba9cd45c6..9fcdf1ad7 100644
--- a/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs
+++ b/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs
@@ -202,7 +202,8 @@ namespace Ryujinx.Graphics.OpenGL
shaderSubgroupSize: Constants.MaxSubgroupSize,
storageBufferOffsetAlignment: HwCapabilities.StorageBufferOffsetAlignment,
textureBufferOffsetAlignment: HwCapabilities.TextureBufferOffsetAlignment,
- gatherBiasPrecision: intelWindows || amdWindows ? 8 : 0); // Precision is 8 for these vendors on Vulkan.
+ gatherBiasPrecision: intelWindows || amdWindows ? 8 : 0, // Precision is 8 for these vendors on Vulkan.
+ maximumGpuMemory: 0);
}
public void SetBufferData(BufferHandle buffer, int offset, ReadOnlySpan data)
diff --git a/src/Ryujinx.Graphics.Shader/Translation/Translator.cs b/src/Ryujinx.Graphics.Shader/Translation/Translator.cs
index 6a31ea2e7..d1fbca0eb 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/Translator.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/Translator.cs
@@ -190,7 +190,7 @@ namespace Ryujinx.Graphics.Shader.Translation
if (stage == ShaderStage.Vertex)
{
- InitializePositionOutput(context);
+ InitializeVertexOutputs(context);
}
UInt128 usedAttributes = context.TranslatorContext.AttributeUsage.NextInputAttributesComponents;
@@ -236,12 +236,20 @@ namespace Ryujinx.Graphics.Shader.Translation
}
}
- private static void InitializePositionOutput(EmitterContext context)
+ private static void InitializeVertexOutputs(EmitterContext context)
{
for (int c = 0; c < 4; c++)
{
context.Store(StorageKind.Output, IoVariable.Position, null, Const(c), ConstF(c == 3 ? 1f : 0f));
}
+
+ if (context.Program.ClipDistancesWritten != 0)
+ {
+ for (int i = 0; i < 8; i++)
+ {
+ context.Store(StorageKind.Output, IoVariable.ClipDistance, null, Const(i), ConstF(0f));
+ }
+ }
}
private static void InitializeOutput(EmitterContext context, int location, bool perPatch)
diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
index 33e41ab48..0faaec82a 100644
--- a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
+++ b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
@@ -781,7 +781,26 @@ namespace Ryujinx.Graphics.Vulkan
shaderSubgroupSize: (int)Capabilities.SubgroupSize,
storageBufferOffsetAlignment: (int)limits.MinStorageBufferOffsetAlignment,
textureBufferOffsetAlignment: (int)limits.MinTexelBufferOffsetAlignment,
- gatherBiasPrecision: IsIntelWindows || IsAmdWindows ? (int)Capabilities.SubTexelPrecisionBits : 0);
+ gatherBiasPrecision: IsIntelWindows || IsAmdWindows ? (int)Capabilities.SubTexelPrecisionBits : 0,
+ maximumGpuMemory: GetTotalGPUMemory());
+ }
+
+ private ulong GetTotalGPUMemory()
+ {
+ ulong totalMemory = 0;
+
+ Api.GetPhysicalDeviceMemoryProperties(_physicalDevice.PhysicalDevice, out PhysicalDeviceMemoryProperties memoryProperties);
+
+ for (int i = 0; i < memoryProperties.MemoryHeapCount; i++)
+ {
+ var heap = memoryProperties.MemoryHeaps[i];
+ if ((heap.Flags & MemoryHeapFlags.DeviceLocalBit) == MemoryHeapFlags.DeviceLocalBit)
+ {
+ totalMemory += heap.Size;
+ }
+ }
+
+ return totalMemory;
}
public HardwareInfo GetHardwareInfo()
@@ -865,6 +884,7 @@ namespace Ryujinx.Graphics.Vulkan
private void PrintGpuInformation()
{
Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})");
+ Logger.Notice.Print(LogClass.Gpu, $"GPU Memory: {GetTotalGPUMemory() / (1024 * 1024)} MiB");
}
public void Initialize(GraphicsDebugLevel logLevel)
diff --git a/src/Ryujinx.SDL2.Common/SDL2Driver.cs b/src/Ryujinx.SDL2.Common/SDL2Driver.cs
index ed6d94190..9827156d0 100644
--- a/src/Ryujinx.SDL2.Common/SDL2Driver.cs
+++ b/src/Ryujinx.SDL2.Common/SDL2Driver.cs
@@ -53,6 +53,7 @@ namespace Ryujinx.SDL2.Common
return;
}
+ SDL_SetHint(SDL_HINT_APP_NAME, "Ryujinx");
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");