mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2024-12-16 15:16:34 +00:00
Compare commits
8 Commits
6216566166
...
ca7cc52349
Author | SHA1 | Date | |
---|---|---|---|
|
ca7cc52349 | ||
|
45ce25e847 | ||
|
8b0520d2cf | ||
|
7d158acc3b | ||
|
5dbba07e33 | ||
|
d86249cb0a | ||
|
04d68ca616 | ||
|
050f22977f |
4
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
4
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user