Skip to content

Commit

Permalink
Merge 7c7b055 into c2e4c8f
Browse files Browse the repository at this point in the history
  • Loading branch information
riperiperi committed May 22, 2023
2 parents c2e4c8f + 7c7b055 commit 7d970aa
Show file tree
Hide file tree
Showing 20 changed files with 1,265 additions and 127 deletions.
4 changes: 3 additions & 1 deletion src/Ryujinx.Graphics.GAL/BufferRange.cs
Expand Up @@ -10,12 +10,14 @@ namespace Ryujinx.Graphics.GAL

public int Offset { get; }
public int Size { get; }
public bool Write { get; }

public BufferRange(BufferHandle handle, int offset, int size)
public BufferRange(BufferHandle handle, int offset, int size, bool write = false)
{
Handle = handle;
Offset = offset;
Size = size;
Write = write;
}
}
}
8 changes: 4 additions & 4 deletions src/Ryujinx.Graphics.GAL/Multithreading/BufferMap.cs
Expand Up @@ -116,7 +116,7 @@ internal BufferHandle MapBufferBlocking(BufferHandle handle)

internal BufferRange MapBufferRange(BufferRange range)
{
return new BufferRange(MapBuffer(range.Handle), range.Offset, range.Size);
return new BufferRange(MapBuffer(range.Handle), range.Offset, range.Size, range.Write);
}

internal Span<BufferRange> MapBufferRanges(Span<BufferRange> ranges)
Expand All @@ -135,7 +135,7 @@ internal Span<BufferRange> MapBufferRanges(Span<BufferRange> ranges)
result = BufferHandle.Null;
}

range = new BufferRange(result, range.Offset, range.Size);
range = new BufferRange(result, range.Offset, range.Size, range.Write);
}
}

Expand All @@ -159,7 +159,7 @@ internal Span<BufferAssignment> MapBufferRanges(Span<BufferAssignment> ranges)
result = BufferHandle.Null;
}

assignment = new BufferAssignment(ranges[i].Binding, new BufferRange(result, range.Offset, range.Size));
assignment = new BufferAssignment(ranges[i].Binding, new BufferRange(result, range.Offset, range.Size, range.Write));
}
}

Expand All @@ -182,7 +182,7 @@ internal Span<VertexBufferDescriptor> MapBufferRanges(Span<VertexBufferDescripto
result = BufferHandle.Null;
}

range = new BufferRange(result, range.Offset, range.Size);
range = new BufferRange(result, range.Offset, range.Size, range.Write);

ranges[i] = new VertexBufferDescriptor(range, ranges[i].Stride, ranges[i].Divisor);
}
Expand Down
14 changes: 9 additions & 5 deletions src/Ryujinx.Graphics.Gpu/Memory/Buffer.cs
Expand Up @@ -140,18 +140,21 @@ public Buffer(GpuContext context, PhysicalMemory physicalMemory, ulong address,
}

/// <summary>
/// Gets a sub-range from the buffer, from a start address till the end of the buffer.
/// Gets a sub-range from the buffer, from a start address til a page boundary after the given size.
/// </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>
/// <param name="size">Size in bytes of the sub-range, must be less than or equal to the buffer size</param>
/// <param name="write">Whether the buffer will be written to by this use</param>
/// <returns>The buffer sub-range</returns>
public BufferRange GetRange(ulong address)
public BufferRange GetRangeAligned(ulong address, ulong size, bool write)
{
ulong end = ((address + size + MemoryManager.PageMask) & ~MemoryManager.PageMask) - Address;
ulong offset = address - Address;

return new BufferRange(Handle, (int)offset, (int)(Size - offset));
return new BufferRange(Handle, (int)offset, (int)(end - offset), write);
}

/// <summary>
Expand All @@ -162,12 +165,13 @@ public BufferRange GetRange(ulong address)
/// </remarks>
/// <param name="address">Start address of the sub-range, must be greater than or equal to the buffer address</param>
/// <param name="size">Size in bytes of the sub-range, must be less than or equal to the buffer size</param>
/// <param name="write">Whether the buffer will be written to by this use</param>
/// <returns>The buffer sub-range</returns>
public BufferRange GetRange(ulong address, ulong size)
public BufferRange GetRange(ulong address, ulong size, bool write)
{
int offset = (int)(address - Address);

return new BufferRange(Handle, offset, (int)size);
return new BufferRange(Handle, offset, (int)size, write);
}

/// <summary>
Expand Down
20 changes: 16 additions & 4 deletions src/Ryujinx.Graphics.Gpu/Memory/BufferCache.cs
Expand Up @@ -372,15 +372,27 @@ public void ClearBuffer(MemoryManager memoryManager, ulong gpuVa, ulong size, ui
}

/// <summary>
/// Gets a buffer sub-range starting at a given memory address.
/// Gets a buffer sub-range for a given GPU memory range.
/// </summary>
/// <param name="memoryManager">GPU memory manager where the buffer is mapped</param>
/// <param name="gpuVa">Start GPU virtual address of the buffer</param>
/// <param name="size">Size in bytes of the buffer</param>
/// <returns>The buffer sub-range for the given range</returns>
public BufferRange GetGpuBufferRange(MemoryManager memoryManager, ulong gpuVa, ulong size)
{
return GetBufferRange(TranslateAndCreateBuffer(memoryManager, gpuVa, size), size);
}

/// <summary>
/// Gets a buffer sub-range from a start address til a page boundary after the given size.
/// </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>
public BufferRange GetBufferRangeTillEnd(ulong address, ulong size, bool write = false)
public BufferRange GetBufferRangeAligned(ulong address, ulong size, bool write = false)
{
return GetBuffer(address, size, write).GetRange(address);
return GetBuffer(address, size, write).GetRangeAligned(address, size, write);
}

/// <summary>
Expand All @@ -392,7 +404,7 @@ public BufferRange GetBufferRangeTillEnd(ulong address, ulong size, bool write =
/// <returns>The buffer sub-range for the given range</returns>
public BufferRange GetBufferRange(ulong address, ulong size, bool write = false)
{
return GetBuffer(address, size, write).GetRange(address, size);
return GetBuffer(address, size, write).GetRange(address, size, write);
}

/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions src/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs
Expand Up @@ -623,7 +623,7 @@ private void BindBuffers(BufferCache bufferCache, BuffersPerStage[] bindings, bo
{
var isWrite = bounds.Flags.HasFlag(BufferUsageFlags.Write);
var range = isStorage
? bufferCache.GetBufferRangeTillEnd(bounds.Address, bounds.Size, isWrite)
? bufferCache.GetBufferRangeAligned(bounds.Address, bounds.Size, isWrite)
: bufferCache.GetBufferRange(bounds.Address, bounds.Size);

ranges[rangesCount++] = new BufferAssignment(bindingInfo.Binding, range);
Expand Down Expand Up @@ -660,7 +660,7 @@ private void BindBuffers(BufferCache bufferCache, BuffersPerStage buffers, bool
{
var isWrite = bounds.Flags.HasFlag(BufferUsageFlags.Write);
var range = isStorage
? bufferCache.GetBufferRangeTillEnd(bounds.Address, bounds.Size, isWrite)
? bufferCache.GetBufferRangeAligned(bounds.Address, bounds.Size, isWrite)
: bufferCache.GetBufferRange(bounds.Address, bounds.Size);

ranges[rangesCount++] = new BufferAssignment(bindingInfo.Binding, range);
Expand Down
25 changes: 23 additions & 2 deletions src/Ryujinx.Graphics.Vulkan/Auto.cs
Expand Up @@ -18,6 +18,12 @@ interface IAutoPrivate : IAuto
void AddCommandBufferDependencies(CommandBufferScoped cbs);
}

interface IMirrorable<T> where T : IDisposable
{
Auto<T> GetMirrorable(CommandBufferScoped cbs, ref int offset, int size, out bool mirrored);
void ClearMirrors(CommandBufferScoped cbs, int offset, int size);
}

class Auto<T> : IAutoPrivate, IDisposable where T : IDisposable
{
private int _referenceCount;
Expand All @@ -26,6 +32,7 @@ class Auto<T> : IAutoPrivate, IDisposable where T : IDisposable
private readonly BitMap _cbOwnership;
private readonly MultiFenceHolder _waitable;
private readonly IAutoPrivate[] _referencedObjs;
private readonly IMirrorable<T> _mirrorable;

private bool _disposed;
private bool _destroyed;
Expand All @@ -37,6 +44,11 @@ public Auto(T value)
_cbOwnership = new BitMap(CommandBufferPool.MaxCommandBuffers);
}

public Auto(T value, IMirrorable<T> mirrorable, MultiFenceHolder waitable, params IAutoPrivate[] referencedObjs) : this(value, waitable, referencedObjs)
{
_mirrorable = mirrorable;
}

public Auto(T value, MultiFenceHolder waitable, params IAutoPrivate[] referencedObjs) : this(value)
{
_waitable = waitable;
Expand All @@ -48,9 +60,18 @@ public Auto(T value, MultiFenceHolder waitable, params IAutoPrivate[] referenced
}
}

public T Get(CommandBufferScoped cbs, int offset, int size)
public T GetMirrorable(CommandBufferScoped cbs, ref int offset, int size, out bool mirrored)
{
mirrored = false;
var mirror = _mirrorable?.GetMirrorable(cbs, ref offset, size, out mirrored);
mirror._waitable?.AddBufferUse(cbs.CommandBufferIndex, offset, size, false);
return mirror.Get(cbs);
}

public T Get(CommandBufferScoped cbs, int offset, int size, bool write = false)
{
_waitable?.AddBufferUse(cbs.CommandBufferIndex, offset, size);
_mirrorable?.ClearMirrors(cbs, offset, size);
_waitable?.AddBufferUse(cbs.CommandBufferIndex, offset, size, write);
return Get(cbs);
}

Expand Down

0 comments on commit 7d970aa

Please sign in to comment.