mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2024-10-01 12:30:00 +02:00
7c989f88bd
* dotnet format style --severity info Some changes were manually reverted. * dotnet format analyzers --serverity info Some changes have been minimally adapted. * Restore a few unused methods and variables * Silence dotnet format IDE0052 warnings * Address dotnet format CA1816 warnings * Address or silence dotnet format CA1069 warnings * Address remaining dotnet format analyzer warnings * Address review comments * Address most dotnet format whitespace warnings * Apply dotnet format whitespace formatting A few of them have been manually reverted and the corresponding warning was silenced * Revert formatting changes for while and for-loops * Another rebase, another dotnet format run * Run dotnet format whitespace after rebase * Run dotnet format style after rebase * Run dotnet format analyzers after rebase * Run dotnet format after rebase and remove unused usings - analyzers - style - whitespace * Disable 'prefer switch expression' rule * Add comments to disabled warnings * Simplify properties and array initialization, Use const when possible, Remove trailing commas * Start working on disabled warnings * Address IDE0251 warnings * Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas" This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e. * dotnet format whitespace after rebase * First dotnet format pass * Address review feedback * Add trailing commas * Remove SuppressMessage for IDE0066 * Make explicit Equals implementation implicit
188 lines
5.6 KiB
C#
188 lines
5.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading;
|
|
|
|
namespace Ryujinx.Graphics.GAL.Multithreading
|
|
{
|
|
/// <summary>
|
|
/// Buffer handles given to the client are not the same as those provided by the backend,
|
|
/// as their handle is created at a later point on the queue.
|
|
/// The handle returned is a unique identifier that will map to the real buffer when it is available.
|
|
/// Note that any uses within the queue should be safe, but outside you must use MapBufferBlocking.
|
|
/// </summary>
|
|
class BufferMap
|
|
{
|
|
private ulong _bufferHandle = 0;
|
|
|
|
private readonly Dictionary<BufferHandle, BufferHandle> _bufferMap = new();
|
|
private readonly HashSet<BufferHandle> _inFlight = new();
|
|
private readonly AutoResetEvent _inFlightChanged = new(false);
|
|
|
|
internal BufferHandle CreateBufferHandle()
|
|
{
|
|
ulong handle64 = Interlocked.Increment(ref _bufferHandle);
|
|
|
|
BufferHandle threadedHandle = Unsafe.As<ulong, BufferHandle>(ref handle64);
|
|
|
|
lock (_inFlight)
|
|
{
|
|
_inFlight.Add(threadedHandle);
|
|
}
|
|
|
|
return threadedHandle;
|
|
}
|
|
|
|
internal void AssignBuffer(BufferHandle threadedHandle, BufferHandle realHandle)
|
|
{
|
|
lock (_bufferMap)
|
|
{
|
|
_bufferMap[threadedHandle] = realHandle;
|
|
}
|
|
|
|
lock (_inFlight)
|
|
{
|
|
_inFlight.Remove(threadedHandle);
|
|
}
|
|
|
|
_inFlightChanged.Set();
|
|
}
|
|
|
|
internal void UnassignBuffer(BufferHandle threadedHandle)
|
|
{
|
|
lock (_bufferMap)
|
|
{
|
|
_bufferMap.Remove(threadedHandle);
|
|
}
|
|
}
|
|
|
|
internal BufferHandle MapBuffer(BufferHandle handle)
|
|
{
|
|
// Maps a threaded buffer to a backend one.
|
|
// Threaded buffers are returned on creation as the buffer
|
|
// isn't actually created until the queue runs the command.
|
|
|
|
lock (_bufferMap)
|
|
{
|
|
if (!_bufferMap.TryGetValue(handle, out BufferHandle result))
|
|
{
|
|
result = BufferHandle.Null;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
internal BufferHandle MapBufferBlocking(BufferHandle handle)
|
|
{
|
|
// Blocks until the handle is available.
|
|
|
|
|
|
lock (_bufferMap)
|
|
{
|
|
if (_bufferMap.TryGetValue(handle, out BufferHandle result))
|
|
{
|
|
return result;
|
|
}
|
|
}
|
|
|
|
bool signal = false;
|
|
|
|
while (true)
|
|
{
|
|
lock (_inFlight)
|
|
{
|
|
if (!_inFlight.Contains(handle))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
_inFlightChanged.WaitOne();
|
|
signal = true;
|
|
}
|
|
|
|
if (signal)
|
|
{
|
|
// Signal other threads which might still be waiting.
|
|
_inFlightChanged.Set();
|
|
}
|
|
|
|
return MapBuffer(handle);
|
|
}
|
|
|
|
internal BufferRange MapBufferRange(BufferRange range)
|
|
{
|
|
return new BufferRange(MapBuffer(range.Handle), range.Offset, range.Size);
|
|
}
|
|
|
|
internal Span<BufferRange> MapBufferRanges(Span<BufferRange> ranges)
|
|
{
|
|
// Rewrite the buffer ranges to point to the mapped handles.
|
|
|
|
lock (_bufferMap)
|
|
{
|
|
for (int i = 0; i < ranges.Length; i++)
|
|
{
|
|
ref BufferRange range = ref ranges[i];
|
|
|
|
if (!_bufferMap.TryGetValue(range.Handle, out BufferHandle result))
|
|
{
|
|
result = BufferHandle.Null;
|
|
}
|
|
|
|
range = new BufferRange(result, range.Offset, range.Size);
|
|
}
|
|
}
|
|
|
|
return ranges;
|
|
}
|
|
|
|
internal Span<BufferAssignment> MapBufferRanges(Span<BufferAssignment> ranges)
|
|
{
|
|
// Rewrite the buffer ranges to point to the mapped handles.
|
|
|
|
lock (_bufferMap)
|
|
{
|
|
for (int i = 0; i < ranges.Length; i++)
|
|
{
|
|
ref BufferAssignment assignment = ref ranges[i];
|
|
BufferRange range = assignment.Range;
|
|
|
|
if (!_bufferMap.TryGetValue(range.Handle, out BufferHandle result))
|
|
{
|
|
result = BufferHandle.Null;
|
|
}
|
|
|
|
assignment = new BufferAssignment(ranges[i].Binding, new BufferRange(result, range.Offset, range.Size));
|
|
}
|
|
}
|
|
|
|
return ranges;
|
|
}
|
|
|
|
internal Span<VertexBufferDescriptor> MapBufferRanges(Span<VertexBufferDescriptor> ranges)
|
|
{
|
|
// Rewrite the buffer ranges to point to the mapped handles.
|
|
|
|
lock (_bufferMap)
|
|
{
|
|
for (int i = 0; i < ranges.Length; i++)
|
|
{
|
|
BufferRange range = ranges[i].Buffer;
|
|
|
|
if (!_bufferMap.TryGetValue(range.Handle, out BufferHandle result))
|
|
{
|
|
result = BufferHandle.Null;
|
|
}
|
|
|
|
range = new BufferRange(result, range.Offset, range.Size);
|
|
|
|
ranges[i] = new VertexBufferDescriptor(range, ranges[i].Stride, ranges[i].Divisor);
|
|
}
|
|
}
|
|
|
|
return ranges;
|
|
}
|
|
}
|
|
}
|