Allow out of bounds storage buffer access by aligning their sizes (#1870)

* Allow out of bounds storage buffer access by aligning their sizes

* Use correct size

* Fix typo and comment on the reason for the change
This commit is contained in:
gdkchan 2021-01-24 19:22:19 -03:00 committed by GitHub
parent 8d4bee3ea9
commit f94acdb4ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 2 deletions

View file

@ -88,6 +88,21 @@ namespace Ryujinx.Graphics.Gpu.Memory
_modifiedDelegate = new Action<ulong, ulong>(RegionModified);
}
/// <summary>
/// Gets a sub-range from the buffer, from a start address till the end of the buffer.
/// </summary>
/// <remarks>
/// This can be used to bind and use sub-ranges of the buffer on the host API.
/// </remarks>
/// <param name="address">Start address of the sub-range, must be greater than or equal to the buffer address</param>
/// <returns>The buffer sub-range</returns>
public BufferRange GetRange(ulong address)
{
ulong offset = address - Address;
return new BufferRange(Handle, (int)offset, (int)(Size - offset));
}
/// <summary>
/// Gets a sub-range from the buffer.
/// </summary>

View file

@ -591,7 +591,12 @@ namespace Ryujinx.Graphics.Gpu.Memory
if (bounds.Address != 0)
{
sRanges[bindingInfo.Binding] = GetBufferRange(bounds.Address, bounds.Size, bounds.Flags.HasFlag(BufferUsageFlags.Write));
// The storage buffer size is not reliable (it might be lower than the actual size),
// so we bind the entire buffer to allow otherwise out of range accesses to work.
sRanges[bindingInfo.Binding] = GetBufferRangeTillEnd(
bounds.Address,
bounds.Size,
bounds.Flags.HasFlag(BufferUsageFlags.Write));
}
}
@ -764,7 +769,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
if (bounds.Address != 0)
{
ranges[bindingInfo.Binding] = GetBufferRange(bounds.Address, bounds.Size, bounds.Flags.HasFlag(BufferUsageFlags.Write));
ranges[bindingInfo.Binding] = isStorage
? GetBufferRangeTillEnd(bounds.Address, bounds.Size, bounds.Flags.HasFlag(BufferUsageFlags.Write))
: GetBufferRange(bounds.Address, bounds.Size, bounds.Flags.HasFlag(BufferUsageFlags.Write));
}
}
}
@ -895,6 +902,18 @@ namespace Ryujinx.Graphics.Gpu.Memory
buffer.SignalModified(address, size);
}
/// <summary>
/// Gets a buffer sub-range starting at a given memory address.
/// </summary>
/// <param name="address">Start address of the memory range</param>
/// <param name="size">Size in bytes of the memory range</param>
/// <param name="write">Whether the buffer will be written to by this use</param>
/// <returns>The buffer sub-range starting at the given memory address</returns>
private BufferRange GetBufferRangeTillEnd(ulong address, ulong size, bool write = false)
{
return GetBuffer(address, size, write).GetRange(address);
}
/// <summary>
/// Gets a buffer sub-range for a given memory range.
/// </summary>