Limit compute storage buffer size (#5028)

This commit is contained in:
gdkchan 2023-05-20 13:15:07 -03:00 committed by GitHub
parent 69a9de33d3
commit fb27042e01
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 24 deletions

View file

@ -40,22 +40,6 @@ namespace Ryujinx.Graphics.Gpu
/// </summary> /// </summary>
public const int TotalTransformFeedbackBuffers = 4; public const int TotalTransformFeedbackBuffers = 4;
/// <summary>
/// Maximum number of textures on a single shader stage.
/// </summary>
/// <remarks>
/// The maximum number of textures is API limited, the hardware supports an unlimited amount.
/// </remarks>
public const int TotalTextures = 32;
/// <summary>
/// Maximum number of images on a single shader stage.
/// </summary>
/// <remarks>
/// The maximum number of images is API limited, the hardware supports an unlimited amount.
/// </remarks>
public const int TotalImages = 8;
/// <summary> /// <summary>
/// Maximum number of render target color buffers. /// Maximum number of render target color buffers.
/// </summary> /// </summary>
@ -100,5 +84,15 @@ namespace Ryujinx.Graphics.Gpu
/// Expected byte alignment for storage buffers /// Expected byte alignment for storage buffers
/// </summary> /// </summary>
public const int StorageAlignment = 16; public const int StorageAlignment = 16;
/// <summary>
/// Number of the uniform buffer reserved by the driver to store the storage buffer base addresses.
/// </summary>
public const int DriverReservedUniformBuffer = 0;
/// <summary>
/// Maximum size that an storage buffer is assumed to have when the correct size is unknown.
/// </summary>
public const ulong MaxUnknownStorageSize = 0x100000;
} }
} }

View file

@ -162,7 +162,19 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
SbDescriptor sbDescriptor = _channel.MemoryManager.Physical.Read<SbDescriptor>(sbDescAddress); SbDescriptor sbDescriptor = _channel.MemoryManager.Physical.Read<SbDescriptor>(sbDescAddress);
_channel.BufferManager.SetComputeStorageBuffer(sb.Slot, sbDescriptor.PackAddress(), (uint)sbDescriptor.Size, sb.Flags); uint size;
if (sb.SbCbSlot == Constants.DriverReservedUniformBuffer)
{
// Only trust the SbDescriptor size if it comes from slot 0.
size = (uint)sbDescriptor.Size;
}
else
{
// TODO: Use full mapped size and somehow speed up buffer sync.
size = (uint)_channel.MemoryManager.GetMappedSize(sbDescriptor.PackAddress(), Constants.MaxUnknownStorageSize);
}
_channel.BufferManager.SetComputeStorageBuffer(sb.Slot, sbDescriptor.PackAddress(), size, sb.Flags);
} }
if ((_channel.BufferManager.HasUnalignedStorageBuffers) != hasUnaligned) if ((_channel.BufferManager.HasUnalignedStorageBuffers) != hasUnaligned)

View file

@ -23,8 +23,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
public const int PrimitiveRestartStateIndex = 12; public const int PrimitiveRestartStateIndex = 12;
public const int RenderTargetStateIndex = 27; public const int RenderTargetStateIndex = 27;
private const ulong MaxUnknownStorageSize = 0x100000;
private readonly GpuContext _context; private readonly GpuContext _context;
private readonly GpuChannel _channel; private readonly GpuChannel _channel;
private readonly DeviceStateWithShadow<ThreedClassState> _state; private readonly DeviceStateWithShadow<ThreedClassState> _state;
@ -359,7 +357,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
SbDescriptor sbDescriptor = _channel.MemoryManager.Physical.Read<SbDescriptor>(sbDescAddress); SbDescriptor sbDescriptor = _channel.MemoryManager.Physical.Read<SbDescriptor>(sbDescAddress);
uint size; uint size;
if (sb.SbCbSlot == 0) if (sb.SbCbSlot == Constants.DriverReservedUniformBuffer)
{ {
// Only trust the SbDescriptor size if it comes from slot 0. // Only trust the SbDescriptor size if it comes from slot 0.
size = (uint)sbDescriptor.Size; size = (uint)sbDescriptor.Size;
@ -367,7 +365,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
else else
{ {
// TODO: Use full mapped size and somehow speed up buffer sync. // TODO: Use full mapped size and somehow speed up buffer sync.
size = (uint)_channel.MemoryManager.GetMappedSize(sbDescriptor.PackAddress(), MaxUnknownStorageSize); size = (uint)_channel.MemoryManager.GetMappedSize(sbDescriptor.PackAddress(), Constants.MaxUnknownStorageSize);
} }
_channel.BufferManager.SetGraphicsStorageBuffer(stage, sb.Slot, sbDescriptor.PackAddress(), size, sb.Flags); _channel.BufferManager.SetGraphicsStorageBuffer(stage, sb.Slot, sbDescriptor.PackAddress(), size, sb.Flags);

View file

@ -1,4 +1,5 @@
using Ryujinx.Graphics.GAL; using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
using Silk.NET.Vulkan; using Silk.NET.Vulkan;
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@ -95,16 +96,27 @@ namespace Ryujinx.Graphics.Vulkan
return Unsafe.As<ulong, BufferHandle>(ref handle64); return Unsafe.As<ulong, BufferHandle>(ref handle64);
} }
public BufferHandle CreateWithHandle(VulkanRenderer gd, int size, BufferAllocationType baseType = BufferAllocationType.HostMapped, BufferHandle storageHint = default) public BufferHandle CreateWithHandle(
VulkanRenderer gd,
int size,
BufferAllocationType baseType = BufferAllocationType.HostMapped,
BufferHandle storageHint = default)
{ {
return CreateWithHandle(gd, size, out _, baseType, storageHint); return CreateWithHandle(gd, size, out _, baseType, storageHint);
} }
public BufferHandle CreateWithHandle(VulkanRenderer gd, int size, out BufferHolder holder, BufferAllocationType baseType = BufferAllocationType.HostMapped, BufferHandle storageHint = default) public BufferHandle CreateWithHandle(
VulkanRenderer gd,
int size,
out BufferHolder holder,
BufferAllocationType baseType = BufferAllocationType.HostMapped,
BufferHandle storageHint = default)
{ {
holder = Create(gd, size, baseType: baseType, storageHint: storageHint); holder = Create(gd, size, baseType: baseType, storageHint: storageHint);
if (holder == null) if (holder == null)
{ {
Logger.Error?.Print(LogClass.Gpu, $"Failed to create buffer with size 0x{size:X} and type \"{baseType}\".");
return BufferHandle.Null; return BufferHandle.Null;
} }