9f1cf6458c
* Initial implementation of migration between memory heaps - Missing OOM handling - Missing `_map` data safety when remapping - Copy may not have completed yet (needs some kind of fence) - Map may be unmapped before it is done being used. (needs scoped access) - SSBO accesses are all "writes" - maybe pass info in another way. - Missing keeping map type when resizing buffers (should this be done?) * Ensure migrated data is in place before flushing. * Fix issue where old waitable would be signalled. - There is a real issue where existing Auto<> references need to be replaced. * Swap bound Auto<> instances when swapping buffer backing * Fix conversion buffers * Don't try move buffers if the host has shared memory. * Make GPU methods return PinnedSpan with scope * Storage Hint * Fix stupidity * Fix rebase * Tweak rules Attempt to sidestep BOTW slowdown * Remove line * Migrate only when command buffers flush * Change backing swap log to debug * Address some feedback * Disallow backing swap when the flush lock is held by the current thread * Make PinnedSpan from ReadOnlySpan explicitly unsafe * Fix some small issues - Index buffer swap fixed - Allocate DeviceLocal buffers using a separate block list to images. * Remove alternative flags * Address feedback
54 lines
2 KiB
C#
54 lines
2 KiB
C#
using System;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace Ryujinx.Graphics.GAL
|
|
{
|
|
public unsafe struct PinnedSpan<T> : IDisposable where T : unmanaged
|
|
{
|
|
private void* _ptr;
|
|
private int _size;
|
|
private Action _disposeAction;
|
|
|
|
/// <summary>
|
|
/// Creates a new PinnedSpan from an existing ReadOnlySpan. The span *must* be pinned in memory.
|
|
/// The data must be guaranteed to live until disposeAction is called.
|
|
/// </summary>
|
|
/// <param name="span">Existing span</param>
|
|
/// <param name="disposeAction">Action to call on dispose</param>
|
|
/// <remarks>
|
|
/// If a dispose action is not provided, it is safe to assume the resource will be available until the next call.
|
|
/// </remarks>
|
|
public static PinnedSpan<T> UnsafeFromSpan(ReadOnlySpan<T> span, Action disposeAction = null)
|
|
{
|
|
return new PinnedSpan<T>(Unsafe.AsPointer(ref MemoryMarshal.GetReference(span)), span.Length, disposeAction);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new PinnedSpan from an existing unsafe region. The data must be guaranteed to live until disposeAction is called.
|
|
/// </summary>
|
|
/// <param name="ptr">Pointer to the region</param>
|
|
/// <param name="size">The total items of T the region contains</param>
|
|
/// <param name="disposeAction">Action to call on dispose</param>
|
|
/// <remarks>
|
|
/// If a dispose action is not provided, it is safe to assume the resource will be available until the next call.
|
|
/// </remarks>
|
|
public PinnedSpan(void* ptr, int size, Action disposeAction = null)
|
|
{
|
|
_ptr = ptr;
|
|
_size = size;
|
|
_disposeAction = disposeAction;
|
|
}
|
|
|
|
public ReadOnlySpan<T> Get()
|
|
{
|
|
return new ReadOnlySpan<T>(_ptr, _size * Unsafe.SizeOf<T>());
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_disposeAction?.Invoke();
|
|
}
|
|
}
|
|
}
|