Compare commits

..

8 Commits

Author SHA1 Message Date
sunshineinabox
ca7cc52349 Whitespace 2024-09-30 21:11:41 -07:00
sunshineinabox
45ce25e847 Upon closer inspection actually descriptorIndex is only iterrated when there is a valid buffer, but bindings are always i+1. This could lead to potential errors. 2024-09-30 21:06:06 -07:00
sunshineinabox
8b0520d2cf
Merge branch 'master' into MoreDynamicStatesPartOne 2024-09-30 19:57:10 -07:00
gdkchan
7d158acc3b
Do not try to create a texture pool if shader does not use textures (#7379) 2024-09-30 11:41:07 -03:00
e2dk4r
5dbba07e33
sdl: set app name (#7370)
Ryujinx was not hinting application name, so on some platforms (e.g.
Linux) volume control shows Ryujinx as 'SDL Application'. This can cause
confusion.

This commit fixes name in volume control applets on some platforms.

see: https://wiki.libsdl.org/SDL2/SDL_HINT_APP_NAME
2024-09-28 10:44:23 +02:00
MaxLastBreath
d86249cb0a
Convert MaxTextureCacheCapacity to Dynamic MaxTextureCacheCapacity for High Resolution Mod support. (#7307)
* Add Texture Size Capacity and 8GB Dram Build

* Update AutoDeleteCache.cs

* Dynamic Texture Cache (WIP)

* Change to float Multiplier, in-case it needs fine-tuning.

* Delete src/src.sln

* Update AutoDeleteCache.cs

* Format

* Fix Formatting

* Add DefaultTextureSizeCapacity and MemoryScaleFactor

- Also remove redundant New Lines

* Fix 4GB dram crashing

* Format newline

* Refractor

- Added Initialize() function to TextureCache and AutoDeleteCache
- Removed GetMaxTextureCapacity() function and instead added _maxCacheMemoryUsage
- Added private const MaxTextureSizeCapacity to AutoDelete Cache
- Added TextureCache.Initialize() to MemoryManager in order to fetch MaxGpuMemory at the right time.
- Moved and Changed Logger.Info for Gpu Memory to Logger.Notice and Moved it to PrintGpuInformation function.
- Opted to use a ternary operator for the Initialize function, I think it looks cleaner than bunch of if statements.

* Update src/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs

Co-authored-by: gdkchan <gab.dark.100@gmail.com>

* maxMemory to CacheMemory, use Clamp instead of Ternary. Changed MinTextureCapacity 1GiB to 512 MiB

* Update src/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs

Co-authored-by: gdkchan <gab.dark.100@gmail.com>

* Format comment

* comment context

* Increase TextureSize capacity for OpenGL back to 1024

- Added a new const ulong for OpenGLTextureSizeCapacity

* Fix changes from last commit.

* Adjust last OpenGL changes.

* Remove garbage VSC file

* Update src/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs

Co-authored-by: gdkchan <gab.dark.100@gmail.com>

* Update src/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs

Co-authored-by: gdkchan <gab.dark.100@gmail.com>

* Update src/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs

Co-authored-by: gdkchan <gab.dark.100@gmail.com>

---------

Co-authored-by: gdkchan <gab.dark.100@gmail.com>
2024-09-26 14:33:38 -03:00
riperiperi
04d68ca616
GPU: Ensure all clip distances are initialized when used (#7363)
* GPU: Ensure all clip distances are initialized when used

* Shader cache version
2024-09-26 14:19:12 -03:00
Jason Youngberg
050f22977f
Update bug_report.yml to provide better instructions for finding log file (#7333) 2024-09-24 11:10:36 +02:00
11 changed files with 98 additions and 17 deletions

View File

@ -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
required: false

View File

@ -75,6 +75,8 @@ namespace Ryujinx.Graphics.GAL
public readonly int GatherBiasPrecision;
public readonly ulong MaximumGpuMemory;
public Capabilities(
TargetApi api,
string vendorName,
@ -139,7 +141,8 @@ namespace Ryujinx.Graphics.GAL
int shaderSubgroupSize,
int storageBufferOffsetAlignment,
int textureBufferOffsetAlignment,
int gatherBiasPrecision)
int gatherBiasPrecision,
ulong maximumGpuMemory)
{
Api = api;
VendorName = vendorName;
@ -205,6 +208,7 @@ namespace Ryujinx.Graphics.GAL
StorageBufferOffsetAlignment = storageBufferOffsetAlignment;
TextureBufferOffsetAlignment = textureBufferOffsetAlignment;
GatherBiasPrecision = gatherBiasPrecision;
MaximumGpuMemory = maximumGpuMemory;
}
}
}

View File

@ -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<Texture> _textures;
private ulong _totalSize;
@ -56,6 +61,25 @@ namespace Ryujinx.Graphics.Gpu.Image
private readonly Dictionary<TextureDescriptor, ShortTextureCacheEntry> _shortCacheLookup;
/// <summary>
/// Initializes the cache, setting the maximum texture capacity for the specified GPU context.
/// </summary>
/// <remarks>
/// If the backend GPU has 0 memory capacity, the cache size defaults to `DefaultTextureSizeCapacity`.
/// </remarks>
/// <param name="context">The GPU context that the cache belongs to</param>
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;
}
}
/// <summary>
/// Creates a new instance of the automatic deletion cache.
/// </summary>
@ -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();
}

View File

@ -68,6 +68,14 @@ namespace Ryujinx.Graphics.Gpu.Image
_cache = new AutoDeleteCache();
}
/// <summary>
/// Initializes the cache, setting the maximum texture capacity for the specified GPU context.
/// </summary>
public void Initialize()
{
_cache.Initialize(_context);
}
/// <summary>
/// Handles marking of textures written to a memory region being (partially) remapped.
/// </summary>

View File

@ -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();
}
/// <summary>

View File

@ -743,7 +743,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
constantBufferUsePerStageMask &= ~(1 << index);
}
if (checkTextures)
if (checkTextures && _allTextures.Length > 0)
{
TexturePool pool = channel.TextureManager.GetTexturePool(poolState.TexturePoolGpuVa, poolState.TexturePoolMaximumId);

View File

@ -206,7 +206,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<byte> data)

View File

@ -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)

View File

@ -100,6 +100,8 @@ namespace Ryujinx.Graphics.Vulkan
public ulong DrawCount { get; private set; }
public bool RenderPassActive { get; private set; }
private readonly int[] _vertexBufferBindings;
public unsafe PipelineBase(VulkanRenderer gd, Device device)
{
Gd = gd;
@ -138,7 +140,11 @@ namespace Ryujinx.Graphics.Vulkan
_bindingsSet = false;
_newState.Internal.VertexBindingDescriptions[0] = new VertexInputBindingDescription(0, _supportExtDynamic && (!Gd.IsMoltenVk || Gd.SupportsMTL31) ? null : 0, VertexInputRate.Vertex);
_vertexBufferBindings = new int[Constants.MaxVertexBuffers];
for (int i = 0; i < Constants.MaxVertexBuffers; i++)
{
_vertexBufferBindings[i] = i + 1;
}
_newState.Initialize(gd.Capabilities);
}
@ -1397,6 +1403,8 @@ namespace Ryujinx.Graphics.Vulkan
if (!_bindingsSet)
{
_newState.Internal.VertexBindingDescriptions[0] = new VertexInputBindingDescription(0, _supportExtDynamic && (!Gd.IsMoltenVk || Gd.SupportsMTL31) ? null : 0, VertexInputRate.Vertex);
for (int i = 1; i < count; i++)
{
_newState.Internal.VertexBindingDescriptions[i] = new VertexInputBindingDescription((uint)i);
@ -1431,17 +1439,22 @@ namespace Ryujinx.Graphics.Vulkan
if (_supportExtDynamic && (!Gd.IsMoltenVk || Gd.SupportsMTL31))
{
if (_newState.Internal.VertexBindingDescriptions[descriptorIndex].InputRate != inputRate)
if (_newState.Internal.VertexBindingDescriptions[descriptorIndex].InputRate != inputRate ||
_newState.Internal.VertexBindingDescriptions[descriptorIndex].Binding != _vertexBufferBindings[i])
{
_newState.Internal.VertexBindingDescriptions[descriptorIndex].InputRate = inputRate;
_newState.Internal.VertexBindingDescriptions[descriptorIndex].Binding = (uint)_vertexBufferBindings[i];
vertexBindingDescriptionChanged = true;
}
}
else
{
if (_newState.Internal.VertexBindingDescriptions[descriptorIndex].InputRate != inputRate || _newState.Internal.VertexBindingDescriptions[descriptorIndex].Stride != vertexBuffer.Stride)
if (_newState.Internal.VertexBindingDescriptions[descriptorIndex].InputRate != inputRate ||
_newState.Internal.VertexBindingDescriptions[descriptorIndex].Stride != vertexBuffer.Stride ||
_newState.Internal.VertexBindingDescriptions[descriptorIndex].Binding != _vertexBufferBindings[i])
{
_newState.Internal.VertexBindingDescriptions[descriptorIndex].Binding = (uint)_vertexBufferBindings[i];
_newState.Internal.VertexBindingDescriptions[descriptorIndex].Stride = (uint)vertexBuffer.Stride;
_newState.Internal.VertexBindingDescriptions[descriptorIndex].InputRate = inputRate;
@ -1463,7 +1476,7 @@ namespace Ryujinx.Graphics.Vulkan
}
}
ref var buffer = ref _vertexBuffers[descriptorIndex];
ref var buffer = ref _vertexBuffers[_vertexBufferBindings[i]];
int oldScalarAlign = buffer.AttributeScalarAlignment;
if (Gd.Capabilities.VertexBufferAlignment < 2 &&
@ -1480,7 +1493,7 @@ namespace Ryujinx.Graphics.Vulkan
vbSize,
vertexBuffer.Stride);
buffer.BindVertexBuffer(Gd, Cbs, (uint)descriptorIndex, ref _newState, _vertexBufferUpdater);
buffer.BindVertexBuffer(Gd, Cbs, (uint)_vertexBufferBindings[i], ref _newState, _vertexBufferUpdater);
}
}
else
@ -1496,7 +1509,7 @@ namespace Ryujinx.Graphics.Vulkan
vbSize,
vertexBuffer.Stride);
_vertexBuffersDirty |= 1UL << descriptorIndex;
_vertexBuffersDirty |= 1UL << _vertexBufferBindings[i];
}
buffer.AttributeScalarAlignment = oldScalarAlign;

View File

@ -812,7 +812,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()
@ -896,6 +915,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)

View File

@ -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");