Limit compute storage buffer size (#5028)
This commit is contained in:
parent
69a9de33d3
commit
fb27042e01
4 changed files with 40 additions and 24 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue