Move solution and projects to src
This commit is contained in:
parent
cd124bda58
commit
cee7121058
3466 changed files with 55 additions and 55 deletions
194
src/Ryujinx.Graphics.GAL/Multithreading/BufferMap.cs
Normal file
194
src/Ryujinx.Graphics.GAL/Multithreading/BufferMap.cs
Normal file
|
@ -0,0 +1,194 @@
|
|||
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 Dictionary<BufferHandle, BufferHandle> _bufferMap = new Dictionary<BufferHandle, BufferHandle>();
|
||||
private HashSet<BufferHandle> _inFlight = new HashSet<BufferHandle>();
|
||||
private AutoResetEvent _inFlightChanged = new AutoResetEvent(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.
|
||||
|
||||
BufferHandle result;
|
||||
|
||||
lock (_bufferMap)
|
||||
{
|
||||
if (!_bufferMap.TryGetValue(handle, out result))
|
||||
{
|
||||
result = BufferHandle.Null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
internal BufferHandle MapBufferBlocking(BufferHandle handle)
|
||||
{
|
||||
// Blocks until the handle is available.
|
||||
|
||||
BufferHandle result;
|
||||
|
||||
lock (_bufferMap)
|
||||
{
|
||||
if (_bufferMap.TryGetValue(handle, out 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];
|
||||
BufferHandle result;
|
||||
|
||||
if (!_bufferMap.TryGetValue(range.Handle, out 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;
|
||||
BufferHandle result;
|
||||
|
||||
if (!_bufferMap.TryGetValue(range.Handle, out 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;
|
||||
BufferHandle result;
|
||||
|
||||
if (!_bufferMap.TryGetValue(range.Handle, out 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;
|
||||
}
|
||||
}
|
||||
}
|
149
src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs
Normal file
149
src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs
Normal file
|
@ -0,0 +1,149 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Commands;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Commands.Buffer;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Commands.CounterEvent;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Commands.Program;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Commands.Sampler;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Commands.Texture;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Commands.Window;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading
|
||||
{
|
||||
static class CommandHelper
|
||||
{
|
||||
private delegate void CommandDelegate(Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer);
|
||||
|
||||
private static int _totalCommands = (int)Enum.GetValues<CommandType>().Max() + 1;
|
||||
private static CommandDelegate[] _lookup = new CommandDelegate[_totalCommands];
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static ref T GetCommand<T>(Span<byte> memory)
|
||||
{
|
||||
return ref Unsafe.As<byte, T>(ref MemoryMarshal.GetReference(memory));
|
||||
}
|
||||
|
||||
public static int GetMaxCommandSize()
|
||||
{
|
||||
return InitLookup() + 1; // 1 byte reserved for command size.
|
||||
}
|
||||
|
||||
private static int InitLookup()
|
||||
{
|
||||
int maxCommandSize = 0;
|
||||
|
||||
void Register<T>(CommandType commandType) where T : unmanaged, IGALCommand, IGALCommand<T>
|
||||
{
|
||||
maxCommandSize = Math.Max(maxCommandSize, Unsafe.SizeOf<T>());
|
||||
_lookup[(int)commandType] = (memory, threaded, renderer) => T.Run(ref GetCommand<T>(memory), threaded, renderer);
|
||||
}
|
||||
|
||||
Register<ActionCommand>(CommandType.Action);
|
||||
Register<CreateBufferCommand>(CommandType.CreateBuffer);
|
||||
Register<CreateProgramCommand>(CommandType.CreateProgram);
|
||||
Register<CreateSamplerCommand>(CommandType.CreateSampler);
|
||||
Register<CreateSyncCommand>(CommandType.CreateSync);
|
||||
Register<CreateTextureCommand>(CommandType.CreateTexture);
|
||||
Register<GetCapabilitiesCommand>(CommandType.GetCapabilities);
|
||||
Register<PreFrameCommand>(CommandType.PreFrame);
|
||||
Register<ReportCounterCommand>(CommandType.ReportCounter);
|
||||
Register<ResetCounterCommand>(CommandType.ResetCounter);
|
||||
Register<UpdateCountersCommand>(CommandType.UpdateCounters);
|
||||
|
||||
Register<BufferDisposeCommand>(CommandType.BufferDispose);
|
||||
Register<BufferGetDataCommand>(CommandType.BufferGetData);
|
||||
Register<BufferSetDataCommand>(CommandType.BufferSetData);
|
||||
|
||||
Register<CounterEventDisposeCommand>(CommandType.CounterEventDispose);
|
||||
Register<CounterEventFlushCommand>(CommandType.CounterEventFlush);
|
||||
|
||||
Register<ProgramDisposeCommand>(CommandType.ProgramDispose);
|
||||
Register<ProgramGetBinaryCommand>(CommandType.ProgramGetBinary);
|
||||
Register<ProgramCheckLinkCommand>(CommandType.ProgramCheckLink);
|
||||
|
||||
Register<SamplerDisposeCommand>(CommandType.SamplerDispose);
|
||||
|
||||
Register<TextureCopyToCommand>(CommandType.TextureCopyTo);
|
||||
Register<TextureCopyToScaledCommand>(CommandType.TextureCopyToScaled);
|
||||
Register<TextureCopyToSliceCommand>(CommandType.TextureCopyToSlice);
|
||||
Register<TextureCreateViewCommand>(CommandType.TextureCreateView);
|
||||
Register<TextureGetDataCommand>(CommandType.TextureGetData);
|
||||
Register<TextureGetDataSliceCommand>(CommandType.TextureGetDataSlice);
|
||||
Register<TextureReleaseCommand>(CommandType.TextureRelease);
|
||||
Register<TextureSetDataCommand>(CommandType.TextureSetData);
|
||||
Register<TextureSetDataSliceCommand>(CommandType.TextureSetDataSlice);
|
||||
Register<TextureSetDataSliceRegionCommand>(CommandType.TextureSetDataSliceRegion);
|
||||
Register<TextureSetStorageCommand>(CommandType.TextureSetStorage);
|
||||
|
||||
Register<WindowPresentCommand>(CommandType.WindowPresent);
|
||||
|
||||
Register<BarrierCommand>(CommandType.Barrier);
|
||||
Register<BeginTransformFeedbackCommand>(CommandType.BeginTransformFeedback);
|
||||
Register<ClearBufferCommand>(CommandType.ClearBuffer);
|
||||
Register<ClearRenderTargetColorCommand>(CommandType.ClearRenderTargetColor);
|
||||
Register<ClearRenderTargetDepthStencilCommand>(CommandType.ClearRenderTargetDepthStencil);
|
||||
Register<CommandBufferBarrierCommand>(CommandType.CommandBufferBarrier);
|
||||
Register<CopyBufferCommand>(CommandType.CopyBuffer);
|
||||
Register<DispatchComputeCommand>(CommandType.DispatchCompute);
|
||||
Register<DrawCommand>(CommandType.Draw);
|
||||
Register<DrawIndexedCommand>(CommandType.DrawIndexed);
|
||||
Register<DrawIndexedIndirectCommand>(CommandType.DrawIndexedIndirect);
|
||||
Register<DrawIndexedIndirectCountCommand>(CommandType.DrawIndexedIndirectCount);
|
||||
Register<DrawIndirectCommand>(CommandType.DrawIndirect);
|
||||
Register<DrawIndirectCountCommand>(CommandType.DrawIndirectCount);
|
||||
Register<DrawTextureCommand>(CommandType.DrawTexture);
|
||||
Register<EndHostConditionalRenderingCommand>(CommandType.EndHostConditionalRendering);
|
||||
Register<EndTransformFeedbackCommand>(CommandType.EndTransformFeedback);
|
||||
Register<SetAlphaTestCommand>(CommandType.SetAlphaTest);
|
||||
Register<SetBlendStateAdvancedCommand>(CommandType.SetBlendStateAdvanced);
|
||||
Register<SetBlendStateCommand>(CommandType.SetBlendState);
|
||||
Register<SetDepthBiasCommand>(CommandType.SetDepthBias);
|
||||
Register<SetDepthClampCommand>(CommandType.SetDepthClamp);
|
||||
Register<SetDepthModeCommand>(CommandType.SetDepthMode);
|
||||
Register<SetDepthTestCommand>(CommandType.SetDepthTest);
|
||||
Register<SetFaceCullingCommand>(CommandType.SetFaceCulling);
|
||||
Register<SetFrontFaceCommand>(CommandType.SetFrontFace);
|
||||
Register<SetStorageBuffersCommand>(CommandType.SetStorageBuffers);
|
||||
Register<SetTransformFeedbackBuffersCommand>(CommandType.SetTransformFeedbackBuffers);
|
||||
Register<SetUniformBuffersCommand>(CommandType.SetUniformBuffers);
|
||||
Register<SetImageCommand>(CommandType.SetImage);
|
||||
Register<SetIndexBufferCommand>(CommandType.SetIndexBuffer);
|
||||
Register<SetLineParametersCommand>(CommandType.SetLineParameters);
|
||||
Register<SetLogicOpStateCommand>(CommandType.SetLogicOpState);
|
||||
Register<SetMultisampleStateCommand>(CommandType.SetMultisampleState);
|
||||
Register<SetPatchParametersCommand>(CommandType.SetPatchParameters);
|
||||
Register<SetPointParametersCommand>(CommandType.SetPointParameters);
|
||||
Register<SetPolygonModeCommand>(CommandType.SetPolygonMode);
|
||||
Register<SetPrimitiveRestartCommand>(CommandType.SetPrimitiveRestart);
|
||||
Register<SetPrimitiveTopologyCommand>(CommandType.SetPrimitiveTopology);
|
||||
Register<SetProgramCommand>(CommandType.SetProgram);
|
||||
Register<SetRasterizerDiscardCommand>(CommandType.SetRasterizerDiscard);
|
||||
Register<SetRenderTargetColorMasksCommand>(CommandType.SetRenderTargetColorMasks);
|
||||
Register<SetRenderTargetScaleCommand>(CommandType.SetRenderTargetScale);
|
||||
Register<SetRenderTargetsCommand>(CommandType.SetRenderTargets);
|
||||
Register<SetScissorsCommand>(CommandType.SetScissor);
|
||||
Register<SetStencilTestCommand>(CommandType.SetStencilTest);
|
||||
Register<SetTextureAndSamplerCommand>(CommandType.SetTextureAndSampler);
|
||||
Register<SetUserClipDistanceCommand>(CommandType.SetUserClipDistance);
|
||||
Register<SetVertexAttribsCommand>(CommandType.SetVertexAttribs);
|
||||
Register<SetVertexBuffersCommand>(CommandType.SetVertexBuffers);
|
||||
Register<SetViewportsCommand>(CommandType.SetViewports);
|
||||
Register<TextureBarrierCommand>(CommandType.TextureBarrier);
|
||||
Register<TextureBarrierTiledCommand>(CommandType.TextureBarrierTiled);
|
||||
Register<TryHostConditionalRenderingCommand>(CommandType.TryHostConditionalRendering);
|
||||
Register<TryHostConditionalRenderingFlushCommand>(CommandType.TryHostConditionalRenderingFlush);
|
||||
Register<UpdateRenderScaleCommand>(CommandType.UpdateRenderScale);
|
||||
|
||||
return maxCommandSize;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void RunCommand(Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
_lookup[memory[memory.Length - 1]](memory, threaded, renderer);
|
||||
}
|
||||
}
|
||||
}
|
102
src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs
Normal file
102
src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs
Normal file
|
@ -0,0 +1,102 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading
|
||||
{
|
||||
enum CommandType : byte
|
||||
{
|
||||
Action,
|
||||
CreateBuffer,
|
||||
CreateProgram,
|
||||
CreateSampler,
|
||||
CreateSync,
|
||||
CreateTexture,
|
||||
GetCapabilities,
|
||||
Unused,
|
||||
PreFrame,
|
||||
ReportCounter,
|
||||
ResetCounter,
|
||||
UpdateCounters,
|
||||
|
||||
BufferDispose,
|
||||
BufferGetData,
|
||||
BufferSetData,
|
||||
|
||||
CounterEventDispose,
|
||||
CounterEventFlush,
|
||||
|
||||
ProgramDispose,
|
||||
ProgramGetBinary,
|
||||
ProgramCheckLink,
|
||||
|
||||
SamplerDispose,
|
||||
|
||||
TextureCopyTo,
|
||||
TextureCopyToScaled,
|
||||
TextureCopyToSlice,
|
||||
TextureCreateView,
|
||||
TextureGetData,
|
||||
TextureGetDataSlice,
|
||||
TextureRelease,
|
||||
TextureSetData,
|
||||
TextureSetDataSlice,
|
||||
TextureSetDataSliceRegion,
|
||||
TextureSetStorage,
|
||||
|
||||
WindowPresent,
|
||||
|
||||
Barrier,
|
||||
BeginTransformFeedback,
|
||||
ClearBuffer,
|
||||
ClearRenderTargetColor,
|
||||
ClearRenderTargetDepthStencil,
|
||||
CommandBufferBarrier,
|
||||
CopyBuffer,
|
||||
DispatchCompute,
|
||||
Draw,
|
||||
DrawIndexed,
|
||||
DrawIndexedIndirect,
|
||||
DrawIndexedIndirectCount,
|
||||
DrawIndirect,
|
||||
DrawIndirectCount,
|
||||
DrawTexture,
|
||||
EndHostConditionalRendering,
|
||||
EndTransformFeedback,
|
||||
SetAlphaTest,
|
||||
SetBlendStateAdvanced,
|
||||
SetBlendState,
|
||||
SetDepthBias,
|
||||
SetDepthClamp,
|
||||
SetDepthMode,
|
||||
SetDepthTest,
|
||||
SetFaceCulling,
|
||||
SetFrontFace,
|
||||
SetStorageBuffers,
|
||||
SetTransformFeedbackBuffers,
|
||||
SetUniformBuffers,
|
||||
SetImage,
|
||||
SetIndexBuffer,
|
||||
SetLineParameters,
|
||||
SetLogicOpState,
|
||||
SetMultisampleState,
|
||||
SetPatchParameters,
|
||||
SetPointParameters,
|
||||
SetPolygonMode,
|
||||
SetPrimitiveRestart,
|
||||
SetPrimitiveTopology,
|
||||
SetProgram,
|
||||
SetRasterizerDiscard,
|
||||
SetRenderTargetColorMasks,
|
||||
SetRenderTargetScale,
|
||||
SetRenderTargets,
|
||||
SetScissor,
|
||||
SetStencilTest,
|
||||
SetTextureAndSampler,
|
||||
SetUserClipDistance,
|
||||
SetVertexAttribs,
|
||||
SetVertexBuffers,
|
||||
SetViewports,
|
||||
TextureBarrier,
|
||||
TextureBarrierTiled,
|
||||
TryHostConditionalRendering,
|
||||
TryHostConditionalRenderingFlush,
|
||||
UpdateRenderScale
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct BarrierCommand : IGALCommand, IGALCommand<BarrierCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.Barrier;
|
||||
|
||||
public static void Run(ref BarrierCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.Barrier();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct BeginTransformFeedbackCommand : IGALCommand, IGALCommand<BeginTransformFeedbackCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.BeginTransformFeedback;
|
||||
private PrimitiveTopology _topology;
|
||||
|
||||
public void Set(PrimitiveTopology topology)
|
||||
{
|
||||
_topology = topology;
|
||||
}
|
||||
|
||||
public static void Run(ref BeginTransformFeedbackCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.BeginTransformFeedback(command._topology);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Buffer
|
||||
{
|
||||
struct BufferDisposeCommand : IGALCommand, IGALCommand<BufferDisposeCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.BufferDispose;
|
||||
private BufferHandle _buffer;
|
||||
|
||||
public void Set(BufferHandle buffer)
|
||||
{
|
||||
_buffer = buffer;
|
||||
}
|
||||
|
||||
public static void Run(ref BufferDisposeCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.DeleteBuffer(threaded.Buffers.MapBuffer(command._buffer));
|
||||
threaded.Buffers.UnassignBuffer(command._buffer);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Buffer
|
||||
{
|
||||
struct BufferGetDataCommand : IGALCommand, IGALCommand<BufferGetDataCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.BufferGetData;
|
||||
private BufferHandle _buffer;
|
||||
private int _offset;
|
||||
private int _size;
|
||||
private TableRef<ResultBox<PinnedSpan<byte>>> _result;
|
||||
|
||||
public void Set(BufferHandle buffer, int offset, int size, TableRef<ResultBox<PinnedSpan<byte>>> result)
|
||||
{
|
||||
_buffer = buffer;
|
||||
_offset = offset;
|
||||
_size = size;
|
||||
_result = result;
|
||||
}
|
||||
|
||||
public static void Run(ref BufferGetDataCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
PinnedSpan<byte> result = renderer.GetBufferData(threaded.Buffers.MapBuffer(command._buffer), command._offset, command._size);
|
||||
|
||||
command._result.Get(threaded).Result = result;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Buffer
|
||||
{
|
||||
struct BufferSetDataCommand : IGALCommand, IGALCommand<BufferSetDataCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.BufferSetData;
|
||||
private BufferHandle _buffer;
|
||||
private int _offset;
|
||||
private SpanRef<byte> _data;
|
||||
|
||||
public void Set(BufferHandle buffer, int offset, SpanRef<byte> data)
|
||||
{
|
||||
_buffer = buffer;
|
||||
_offset = offset;
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public static void Run(ref BufferSetDataCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
ReadOnlySpan<byte> data = command._data.Get(threaded);
|
||||
renderer.SetBufferData(threaded.Buffers.MapBuffer(command._buffer), command._offset, data);
|
||||
command._data.Dispose(threaded);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct ClearBufferCommand : IGALCommand, IGALCommand<ClearBufferCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.ClearBuffer;
|
||||
private BufferHandle _destination;
|
||||
private int _offset;
|
||||
private int _size;
|
||||
private uint _value;
|
||||
|
||||
public void Set(BufferHandle destination, int offset, int size, uint value)
|
||||
{
|
||||
_destination = destination;
|
||||
_offset = offset;
|
||||
_size = size;
|
||||
_value = value;
|
||||
}
|
||||
|
||||
public static void Run(ref ClearBufferCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.ClearBuffer(threaded.Buffers.MapBuffer(command._destination), command._offset, command._size, command._value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct ClearRenderTargetColorCommand : IGALCommand, IGALCommand<ClearRenderTargetColorCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.ClearRenderTargetColor;
|
||||
private int _index;
|
||||
private int _layer;
|
||||
private int _layerCount;
|
||||
private uint _componentMask;
|
||||
private ColorF _color;
|
||||
|
||||
public void Set(int index, int layer, int layerCount, uint componentMask, ColorF color)
|
||||
{
|
||||
_index = index;
|
||||
_layer = layer;
|
||||
_layerCount = layerCount;
|
||||
_componentMask = componentMask;
|
||||
_color = color;
|
||||
}
|
||||
|
||||
public static void Run(ref ClearRenderTargetColorCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.ClearRenderTargetColor(command._index, command._layer, command._layerCount, command._componentMask, command._color);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct ClearRenderTargetDepthStencilCommand : IGALCommand, IGALCommand<ClearRenderTargetDepthStencilCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.ClearRenderTargetDepthStencil;
|
||||
private int _layer;
|
||||
private int _layerCount;
|
||||
private float _depthValue;
|
||||
private bool _depthMask;
|
||||
private int _stencilValue;
|
||||
private int _stencilMask;
|
||||
|
||||
public void Set(int layer, int layerCount, float depthValue, bool depthMask, int stencilValue, int stencilMask)
|
||||
{
|
||||
_layer = layer;
|
||||
_layerCount = layerCount;
|
||||
_depthValue = depthValue;
|
||||
_depthMask = depthMask;
|
||||
_stencilValue = stencilValue;
|
||||
_stencilMask = stencilMask;
|
||||
}
|
||||
|
||||
public static void Run(ref ClearRenderTargetDepthStencilCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.ClearRenderTargetDepthStencil(command._layer, command._layerCount, command._depthValue, command._depthMask, command._stencilValue, command._stencilMask);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct CommandBufferBarrierCommand : IGALCommand, IGALCommand<CommandBufferBarrierCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.CommandBufferBarrier;
|
||||
|
||||
public static void Run(ref CommandBufferBarrierCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.CommandBufferBarrier();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct CopyBufferCommand : IGALCommand, IGALCommand<CopyBufferCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.CopyBuffer;
|
||||
private BufferHandle _source;
|
||||
private BufferHandle _destination;
|
||||
private int _srcOffset;
|
||||
private int _dstOffset;
|
||||
private int _size;
|
||||
|
||||
public void Set(BufferHandle source, BufferHandle destination, int srcOffset, int dstOffset, int size)
|
||||
{
|
||||
_source = source;
|
||||
_destination = destination;
|
||||
_srcOffset = srcOffset;
|
||||
_dstOffset = dstOffset;
|
||||
_size = size;
|
||||
}
|
||||
|
||||
public static void Run(ref CopyBufferCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.CopyBuffer(threaded.Buffers.MapBuffer(command._source), threaded.Buffers.MapBuffer(command._destination), command._srcOffset, command._dstOffset, command._size);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.CounterEvent
|
||||
{
|
||||
struct CounterEventDisposeCommand : IGALCommand, IGALCommand<CounterEventDisposeCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.CounterEventDispose;
|
||||
private TableRef<ThreadedCounterEvent> _event;
|
||||
|
||||
public void Set(TableRef<ThreadedCounterEvent> evt)
|
||||
{
|
||||
_event = evt;
|
||||
}
|
||||
|
||||
public static void Run(ref CounterEventDisposeCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
command._event.Get(threaded).Base.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.CounterEvent
|
||||
{
|
||||
struct CounterEventFlushCommand : IGALCommand, IGALCommand<CounterEventFlushCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.CounterEventFlush;
|
||||
private TableRef<ThreadedCounterEvent> _event;
|
||||
|
||||
public void Set(TableRef<ThreadedCounterEvent> evt)
|
||||
{
|
||||
_event = evt;
|
||||
}
|
||||
|
||||
public static void Run(ref CounterEventFlushCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
command._event.Get(threaded).Base.Flush();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct DispatchComputeCommand : IGALCommand, IGALCommand<DispatchComputeCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.DispatchCompute;
|
||||
private int _groupsX;
|
||||
private int _groupsY;
|
||||
private int _groupsZ;
|
||||
|
||||
public void Set(int groupsX, int groupsY, int groupsZ)
|
||||
{
|
||||
_groupsX = groupsX;
|
||||
_groupsY = groupsY;
|
||||
_groupsZ = groupsZ;
|
||||
}
|
||||
|
||||
public static void Run(ref DispatchComputeCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.DispatchCompute(command._groupsX, command._groupsY, command._groupsZ);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct DrawIndexedCommand : IGALCommand, IGALCommand<DrawIndexedCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.DrawIndexed;
|
||||
private int _indexCount;
|
||||
private int _instanceCount;
|
||||
private int _firstIndex;
|
||||
private int _firstVertex;
|
||||
private int _firstInstance;
|
||||
|
||||
public void Set(int indexCount, int instanceCount, int firstIndex, int firstVertex, int firstInstance)
|
||||
{
|
||||
_indexCount = indexCount;
|
||||
_instanceCount = instanceCount;
|
||||
_firstIndex = firstIndex;
|
||||
_firstVertex = firstVertex;
|
||||
_firstInstance = firstInstance;
|
||||
}
|
||||
|
||||
public static void Run(ref DrawIndexedCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.DrawIndexed(command._indexCount, command._instanceCount, command._firstIndex, command._firstVertex, command._firstInstance);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct DrawCommand : IGALCommand, IGALCommand<DrawCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.Draw;
|
||||
private int _vertexCount;
|
||||
private int _instanceCount;
|
||||
private int _firstVertex;
|
||||
private int _firstInstance;
|
||||
|
||||
public void Set(int vertexCount, int instanceCount, int firstVertex, int firstInstance)
|
||||
{
|
||||
_vertexCount = vertexCount;
|
||||
_instanceCount = instanceCount;
|
||||
_firstVertex = firstVertex;
|
||||
_firstInstance = firstInstance;
|
||||
}
|
||||
|
||||
public static void Run(ref DrawCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.Draw(command._vertexCount, command._instanceCount, command._firstVertex, command._firstInstance);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct DrawIndexedIndirectCommand : IGALCommand, IGALCommand<DrawIndexedIndirectCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.DrawIndexedIndirect;
|
||||
private BufferRange _indirectBuffer;
|
||||
|
||||
public void Set(BufferRange indirectBuffer)
|
||||
{
|
||||
_indirectBuffer = indirectBuffer;
|
||||
}
|
||||
|
||||
public static void Run(ref DrawIndexedIndirectCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.DrawIndexedIndirect(threaded.Buffers.MapBufferRange(command._indirectBuffer));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct DrawIndexedIndirectCountCommand : IGALCommand, IGALCommand<DrawIndexedIndirectCountCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.DrawIndexedIndirectCount;
|
||||
private BufferRange _indirectBuffer;
|
||||
private BufferRange _parameterBuffer;
|
||||
private int _maxDrawCount;
|
||||
private int _stride;
|
||||
|
||||
public void Set(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride)
|
||||
{
|
||||
_indirectBuffer = indirectBuffer;
|
||||
_parameterBuffer = parameterBuffer;
|
||||
_maxDrawCount = maxDrawCount;
|
||||
_stride = stride;
|
||||
}
|
||||
|
||||
public static void Run(ref DrawIndexedIndirectCountCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.DrawIndexedIndirectCount(
|
||||
threaded.Buffers.MapBufferRange(command._indirectBuffer),
|
||||
threaded.Buffers.MapBufferRange(command._parameterBuffer),
|
||||
command._maxDrawCount,
|
||||
command._stride
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct DrawIndirectCommand : IGALCommand, IGALCommand<DrawIndirectCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.DrawIndirect;
|
||||
private BufferRange _indirectBuffer;
|
||||
|
||||
public void Set(BufferRange indirectBuffer)
|
||||
{
|
||||
_indirectBuffer = indirectBuffer;
|
||||
}
|
||||
|
||||
public static void Run(ref DrawIndirectCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.DrawIndirect(threaded.Buffers.MapBufferRange(command._indirectBuffer));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct DrawIndirectCountCommand : IGALCommand, IGALCommand<DrawIndirectCountCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.DrawIndirectCount;
|
||||
private BufferRange _indirectBuffer;
|
||||
private BufferRange _parameterBuffer;
|
||||
private int _maxDrawCount;
|
||||
private int _stride;
|
||||
|
||||
public void Set(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride)
|
||||
{
|
||||
_indirectBuffer = indirectBuffer;
|
||||
_parameterBuffer = parameterBuffer;
|
||||
_maxDrawCount = maxDrawCount;
|
||||
_stride = stride;
|
||||
}
|
||||
|
||||
public static void Run(ref DrawIndirectCountCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.DrawIndirectCount(
|
||||
threaded.Buffers.MapBufferRange(command._indirectBuffer),
|
||||
threaded.Buffers.MapBufferRange(command._parameterBuffer),
|
||||
command._maxDrawCount,
|
||||
command._stride
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct DrawTextureCommand : IGALCommand, IGALCommand<DrawTextureCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.DrawTexture;
|
||||
private TableRef<ITexture> _texture;
|
||||
private TableRef<ISampler> _sampler;
|
||||
private Extents2DF _srcRegion;
|
||||
private Extents2DF _dstRegion;
|
||||
|
||||
public void Set(TableRef<ITexture> texture, TableRef<ISampler> sampler, Extents2DF srcRegion, Extents2DF dstRegion)
|
||||
{
|
||||
_texture = texture;
|
||||
_sampler = sampler;
|
||||
_srcRegion = srcRegion;
|
||||
_dstRegion = dstRegion;
|
||||
}
|
||||
|
||||
public static void Run(ref DrawTextureCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.DrawTexture(
|
||||
command._texture.GetAs<ThreadedTexture>(threaded)?.Base,
|
||||
command._sampler.GetAs<ThreadedSampler>(threaded)?.Base,
|
||||
command._srcRegion,
|
||||
command._dstRegion);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct EndHostConditionalRenderingCommand : IGALCommand, IGALCommand<EndHostConditionalRenderingCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.EndHostConditionalRendering;
|
||||
|
||||
public static void Run(ref EndHostConditionalRenderingCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.EndHostConditionalRendering();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct EndTransformFeedbackCommand : IGALCommand, IGALCommand<EndTransformFeedbackCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.EndTransformFeedback;
|
||||
|
||||
public static void Run(ref EndTransformFeedbackCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.EndTransformFeedback();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
interface IGALCommand
|
||||
{
|
||||
CommandType CommandType { get; }
|
||||
}
|
||||
|
||||
interface IGALCommand<T> where T : IGALCommand
|
||||
{
|
||||
abstract static void Run(ref T command, ThreadedRenderer threaded, IRenderer renderer);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Program
|
||||
{
|
||||
struct ProgramCheckLinkCommand : IGALCommand, IGALCommand<ProgramCheckLinkCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.ProgramCheckLink;
|
||||
private TableRef<ThreadedProgram> _program;
|
||||
private bool _blocking;
|
||||
private TableRef<ResultBox<ProgramLinkStatus>> _result;
|
||||
|
||||
public void Set(TableRef<ThreadedProgram> program, bool blocking, TableRef<ResultBox<ProgramLinkStatus>> result)
|
||||
{
|
||||
_program = program;
|
||||
_blocking = blocking;
|
||||
_result = result;
|
||||
}
|
||||
|
||||
public static void Run(ref ProgramCheckLinkCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
ProgramLinkStatus result = command._program.Get(threaded).Base.CheckProgramLink(command._blocking);
|
||||
|
||||
command._result.Get(threaded).Result = result;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Program
|
||||
{
|
||||
struct ProgramDisposeCommand : IGALCommand, IGALCommand<ProgramDisposeCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.ProgramDispose;
|
||||
private TableRef<ThreadedProgram> _program;
|
||||
|
||||
public void Set(TableRef<ThreadedProgram> program)
|
||||
{
|
||||
_program = program;
|
||||
}
|
||||
|
||||
public static void Run(ref ProgramDisposeCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
command._program.Get(threaded).Base.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Program
|
||||
{
|
||||
struct ProgramGetBinaryCommand : IGALCommand, IGALCommand<ProgramGetBinaryCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.ProgramGetBinary;
|
||||
private TableRef<ThreadedProgram> _program;
|
||||
private TableRef<ResultBox<byte[]>> _result;
|
||||
|
||||
public void Set(TableRef<ThreadedProgram> program, TableRef<ResultBox<byte[]>> result)
|
||||
{
|
||||
_program = program;
|
||||
_result = result;
|
||||
}
|
||||
|
||||
public static void Run(ref ProgramGetBinaryCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
byte[] result = command._program.Get(threaded).Base.GetBinary();
|
||||
|
||||
command._result.Get(threaded).Result = result;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
||||
{
|
||||
struct ActionCommand : IGALCommand, IGALCommand<ActionCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.Action;
|
||||
private TableRef<Action> _action;
|
||||
|
||||
public void Set(TableRef<Action> action)
|
||||
{
|
||||
_action = action;
|
||||
}
|
||||
|
||||
public static void Run(ref ActionCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
command._action.Get(threaded)();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
||||
{
|
||||
struct CreateBufferCommand : IGALCommand, IGALCommand<CreateBufferCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.CreateBuffer;
|
||||
private BufferHandle _threadedHandle;
|
||||
private int _size;
|
||||
private BufferHandle _storageHint;
|
||||
|
||||
public void Set(BufferHandle threadedHandle, int size, BufferHandle storageHint)
|
||||
{
|
||||
_threadedHandle = threadedHandle;
|
||||
_size = size;
|
||||
_storageHint = storageHint;
|
||||
}
|
||||
|
||||
public static void Run(ref CreateBufferCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
BufferHandle hint = BufferHandle.Null;
|
||||
|
||||
if (command._storageHint != BufferHandle.Null)
|
||||
{
|
||||
hint = threaded.Buffers.MapBuffer(command._storageHint);
|
||||
}
|
||||
|
||||
threaded.Buffers.AssignBuffer(command._threadedHandle, renderer.CreateBuffer(command._size, hint));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources.Programs;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
||||
{
|
||||
struct CreateProgramCommand : IGALCommand, IGALCommand<CreateProgramCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.CreateProgram;
|
||||
private TableRef<IProgramRequest> _request;
|
||||
|
||||
public void Set(TableRef<IProgramRequest> request)
|
||||
{
|
||||
_request = request;
|
||||
}
|
||||
|
||||
public static void Run(ref CreateProgramCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
IProgramRequest request = command._request.Get(threaded);
|
||||
|
||||
if (request.Threaded.Base == null)
|
||||
{
|
||||
request.Threaded.Base = request.Create(renderer);
|
||||
}
|
||||
|
||||
threaded.Programs.ProcessQueue();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
||||
{
|
||||
struct CreateSamplerCommand : IGALCommand, IGALCommand<CreateSamplerCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.CreateSampler;
|
||||
private TableRef<ThreadedSampler> _sampler;
|
||||
private SamplerCreateInfo _info;
|
||||
|
||||
public void Set(TableRef<ThreadedSampler> sampler, SamplerCreateInfo info)
|
||||
{
|
||||
_sampler = sampler;
|
||||
_info = info;
|
||||
}
|
||||
|
||||
public static void Run(ref CreateSamplerCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
command._sampler.Get(threaded).Base = renderer.CreateSampler(command._info);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
||||
{
|
||||
struct CreateSyncCommand : IGALCommand, IGALCommand<CreateSyncCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.CreateSync;
|
||||
private ulong _id;
|
||||
private bool _strict;
|
||||
|
||||
public void Set(ulong id, bool strict)
|
||||
{
|
||||
_id = id;
|
||||
_strict = strict;
|
||||
}
|
||||
|
||||
public static void Run(ref CreateSyncCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.CreateSync(command._id, command._strict);
|
||||
|
||||
threaded.Sync.AssignSync(command._id);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
||||
{
|
||||
struct CreateTextureCommand : IGALCommand, IGALCommand<CreateTextureCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.CreateTexture;
|
||||
private TableRef<ThreadedTexture> _texture;
|
||||
private TextureCreateInfo _info;
|
||||
private float _scale;
|
||||
|
||||
public void Set(TableRef<ThreadedTexture> texture, TextureCreateInfo info, float scale)
|
||||
{
|
||||
_texture = texture;
|
||||
_info = info;
|
||||
_scale = scale;
|
||||
}
|
||||
|
||||
public static void Run(ref CreateTextureCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
command._texture.Get(threaded).Base = renderer.CreateTexture(command._info, command._scale);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
||||
{
|
||||
struct GetCapabilitiesCommand : IGALCommand, IGALCommand<GetCapabilitiesCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.GetCapabilities;
|
||||
private TableRef<ResultBox<Capabilities>> _result;
|
||||
|
||||
public void Set(TableRef<ResultBox<Capabilities>> result)
|
||||
{
|
||||
_result = result;
|
||||
}
|
||||
|
||||
public static void Run(ref GetCapabilitiesCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
command._result.Get(threaded).Result = renderer.GetCapabilities();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
||||
{
|
||||
struct PreFrameCommand : IGALCommand, IGALCommand<PreFrameCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.PreFrame;
|
||||
|
||||
public static void Run(ref PreFrameCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.PreFrame();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
||||
{
|
||||
struct ReportCounterCommand : IGALCommand, IGALCommand<ReportCounterCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.ReportCounter;
|
||||
private TableRef<ThreadedCounterEvent> _event;
|
||||
private CounterType _type;
|
||||
private TableRef<EventHandler<ulong>> _resultHandler;
|
||||
private bool _hostReserved;
|
||||
|
||||
public void Set(TableRef<ThreadedCounterEvent> evt, CounterType type, TableRef<EventHandler<ulong>> resultHandler, bool hostReserved)
|
||||
{
|
||||
_event = evt;
|
||||
_type = type;
|
||||
_resultHandler = resultHandler;
|
||||
_hostReserved = hostReserved;
|
||||
}
|
||||
|
||||
public static void Run(ref ReportCounterCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
ThreadedCounterEvent evt = command._event.Get(threaded);
|
||||
|
||||
evt.Create(renderer, command._type, command._resultHandler.Get(threaded), command._hostReserved);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
||||
{
|
||||
struct ResetCounterCommand : IGALCommand, IGALCommand<ResetCounterCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.ResetCounter;
|
||||
private CounterType _type;
|
||||
|
||||
public void Set(CounterType type)
|
||||
{
|
||||
_type = type;
|
||||
}
|
||||
|
||||
public static void Run(ref ResetCounterCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.ResetCounter(command._type);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
||||
{
|
||||
struct UpdateCountersCommand : IGALCommand, IGALCommand<UpdateCountersCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.UpdateCounters;
|
||||
|
||||
public static void Run(ref UpdateCountersCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.UpdateCounters();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Sampler
|
||||
{
|
||||
struct SamplerDisposeCommand : IGALCommand, IGALCommand<SamplerDisposeCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SamplerDispose;
|
||||
private TableRef<ThreadedSampler> _sampler;
|
||||
|
||||
public void Set(TableRef<ThreadedSampler> sampler)
|
||||
{
|
||||
_sampler = sampler;
|
||||
}
|
||||
|
||||
public static void Run(ref SamplerDisposeCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
command._sampler.Get(threaded).Base.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetAlphaTestCommand : IGALCommand, IGALCommand<SetAlphaTestCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetAlphaTest;
|
||||
private bool _enable;
|
||||
private float _reference;
|
||||
private CompareOp _op;
|
||||
|
||||
public void Set(bool enable, float reference, CompareOp op)
|
||||
{
|
||||
_enable = enable;
|
||||
_reference = reference;
|
||||
_op = op;
|
||||
}
|
||||
|
||||
public static void Run(ref SetAlphaTestCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetAlphaTest(command._enable, command._reference, command._op);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetBlendStateAdvancedCommand : IGALCommand, IGALCommand<SetBlendStateAdvancedCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetBlendStateAdvanced;
|
||||
private AdvancedBlendDescriptor _blend;
|
||||
|
||||
public void Set(AdvancedBlendDescriptor blend)
|
||||
{
|
||||
_blend = blend;
|
||||
}
|
||||
|
||||
public static void Run(ref SetBlendStateAdvancedCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetBlendState(command._blend);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetBlendStateCommand : IGALCommand, IGALCommand<SetBlendStateCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetBlendState;
|
||||
private int _index;
|
||||
private BlendDescriptor _blend;
|
||||
|
||||
public void Set(int index, BlendDescriptor blend)
|
||||
{
|
||||
_index = index;
|
||||
_blend = blend;
|
||||
}
|
||||
|
||||
public static void Run(ref SetBlendStateCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetBlendState(command._index, command._blend);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetDepthBiasCommand : IGALCommand, IGALCommand<SetDepthBiasCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetDepthBias;
|
||||
private PolygonModeMask _enables;
|
||||
private float _factor;
|
||||
private float _units;
|
||||
private float _clamp;
|
||||
|
||||
public void Set(PolygonModeMask enables, float factor, float units, float clamp)
|
||||
{
|
||||
_enables = enables;
|
||||
_factor = factor;
|
||||
_units = units;
|
||||
_clamp = clamp;
|
||||
}
|
||||
|
||||
public static void Run(ref SetDepthBiasCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetDepthBias(command._enables, command._factor, command._units, command._clamp);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetDepthClampCommand : IGALCommand, IGALCommand<SetDepthClampCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetDepthClamp;
|
||||
private bool _clamp;
|
||||
|
||||
public void Set(bool clamp)
|
||||
{
|
||||
_clamp = clamp;
|
||||
}
|
||||
|
||||
public static void Run(ref SetDepthClampCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetDepthClamp(command._clamp);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetDepthModeCommand : IGALCommand, IGALCommand<SetDepthModeCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetDepthMode;
|
||||
private DepthMode _mode;
|
||||
|
||||
public void Set(DepthMode mode)
|
||||
{
|
||||
_mode = mode;
|
||||
}
|
||||
|
||||
public static void Run(ref SetDepthModeCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetDepthMode(command._mode);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetDepthTestCommand : IGALCommand, IGALCommand<SetDepthTestCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetDepthTest;
|
||||
private DepthTestDescriptor _depthTest;
|
||||
|
||||
public void Set(DepthTestDescriptor depthTest)
|
||||
{
|
||||
_depthTest = depthTest;
|
||||
}
|
||||
|
||||
public static void Run(ref SetDepthTestCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetDepthTest(command._depthTest);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetFaceCullingCommand : IGALCommand, IGALCommand<SetFaceCullingCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetFaceCulling;
|
||||
private bool _enable;
|
||||
private Face _face;
|
||||
|
||||
public void Set(bool enable, Face face)
|
||||
{
|
||||
_enable = enable;
|
||||
_face = face;
|
||||
}
|
||||
|
||||
public static void Run(ref SetFaceCullingCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetFaceCulling(command._enable, command._face);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetFrontFaceCommand : IGALCommand, IGALCommand<SetFrontFaceCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetFrontFace;
|
||||
private FrontFace _frontFace;
|
||||
|
||||
public void Set(FrontFace frontFace)
|
||||
{
|
||||
_frontFace = frontFace;
|
||||
}
|
||||
|
||||
public static void Run(ref SetFrontFaceCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetFrontFace(command._frontFace);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetImageCommand : IGALCommand, IGALCommand<SetImageCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetImage;
|
||||
private int _binding;
|
||||
private TableRef<ITexture> _texture;
|
||||
private Format _imageFormat;
|
||||
|
||||
public void Set(int binding, TableRef<ITexture> texture, Format imageFormat)
|
||||
{
|
||||
_binding = binding;
|
||||
_texture = texture;
|
||||
_imageFormat = imageFormat;
|
||||
}
|
||||
|
||||
public static void Run(ref SetImageCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetImage(command._binding, command._texture.GetAs<ThreadedTexture>(threaded)?.Base, command._imageFormat);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetIndexBufferCommand : IGALCommand, IGALCommand<SetIndexBufferCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetIndexBuffer;
|
||||
private BufferRange _buffer;
|
||||
private IndexType _type;
|
||||
|
||||
public void Set(BufferRange buffer, IndexType type)
|
||||
{
|
||||
_buffer = buffer;
|
||||
_type = type;
|
||||
}
|
||||
|
||||
public static void Run(ref SetIndexBufferCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
BufferRange range = threaded.Buffers.MapBufferRange(command._buffer);
|
||||
renderer.Pipeline.SetIndexBuffer(range, command._type);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetLineParametersCommand : IGALCommand, IGALCommand<SetLineParametersCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetLineParameters;
|
||||
private float _width;
|
||||
private bool _smooth;
|
||||
|
||||
public void Set(float width, bool smooth)
|
||||
{
|
||||
_width = width;
|
||||
_smooth = smooth;
|
||||
}
|
||||
|
||||
public static void Run(ref SetLineParametersCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetLineParameters(command._width, command._smooth);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetLogicOpStateCommand : IGALCommand, IGALCommand<SetLogicOpStateCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetLogicOpState;
|
||||
private bool _enable;
|
||||
private LogicalOp _op;
|
||||
|
||||
public void Set(bool enable, LogicalOp op)
|
||||
{
|
||||
_enable = enable;
|
||||
_op = op;
|
||||
}
|
||||
|
||||
public static void Run(ref SetLogicOpStateCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetLogicOpState(command._enable, command._op);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetMultisampleStateCommand : IGALCommand, IGALCommand<SetMultisampleStateCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetMultisampleState;
|
||||
private MultisampleDescriptor _multisample;
|
||||
|
||||
public void Set(MultisampleDescriptor multisample)
|
||||
{
|
||||
_multisample = multisample;
|
||||
}
|
||||
|
||||
public static void Run(ref SetMultisampleStateCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetMultisampleState(command._multisample);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using Ryujinx.Common.Memory;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetPatchParametersCommand : IGALCommand, IGALCommand<SetPatchParametersCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetPatchParameters;
|
||||
private int _vertices;
|
||||
private Array4<float> _defaultOuterLevel;
|
||||
private Array2<float> _defaultInnerLevel;
|
||||
|
||||
public void Set(int vertices, ReadOnlySpan<float> defaultOuterLevel, ReadOnlySpan<float> defaultInnerLevel)
|
||||
{
|
||||
_vertices = vertices;
|
||||
defaultOuterLevel.CopyTo(_defaultOuterLevel.AsSpan());
|
||||
defaultInnerLevel.CopyTo(_defaultInnerLevel.AsSpan());
|
||||
}
|
||||
|
||||
public static void Run(ref SetPatchParametersCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetPatchParameters(command._vertices, command._defaultOuterLevel.AsSpan(), command._defaultInnerLevel.AsSpan());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetPointParametersCommand : IGALCommand, IGALCommand<SetPointParametersCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetPointParameters;
|
||||
private float _size;
|
||||
private bool _isProgramPointSize;
|
||||
private bool _enablePointSprite;
|
||||
private Origin _origin;
|
||||
|
||||
public void Set(float size, bool isProgramPointSize, bool enablePointSprite, Origin origin)
|
||||
{
|
||||
_size = size;
|
||||
_isProgramPointSize = isProgramPointSize;
|
||||
_enablePointSprite = enablePointSprite;
|
||||
_origin = origin;
|
||||
}
|
||||
|
||||
public static void Run(ref SetPointParametersCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetPointParameters(command._size, command._isProgramPointSize, command._enablePointSprite, command._origin);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetPolygonModeCommand : IGALCommand, IGALCommand<SetPolygonModeCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetPolygonMode;
|
||||
private PolygonMode _frontMode;
|
||||
private PolygonMode _backMode;
|
||||
|
||||
public void Set(PolygonMode frontMode, PolygonMode backMode)
|
||||
{
|
||||
_frontMode = frontMode;
|
||||
_backMode = backMode;
|
||||
}
|
||||
|
||||
public static void Run(ref SetPolygonModeCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetPolygonMode(command._frontMode, command._backMode);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetPrimitiveRestartCommand : IGALCommand, IGALCommand<SetPrimitiveRestartCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetPrimitiveRestart;
|
||||
private bool _enable;
|
||||
private int _index;
|
||||
|
||||
public void Set(bool enable, int index)
|
||||
{
|
||||
_enable = enable;
|
||||
_index = index;
|
||||
}
|
||||
|
||||
public static void Run(ref SetPrimitiveRestartCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetPrimitiveRestart(command._enable, command._index);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetPrimitiveTopologyCommand : IGALCommand, IGALCommand<SetPrimitiveTopologyCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetPrimitiveTopology;
|
||||
private PrimitiveTopology _topology;
|
||||
|
||||
public void Set(PrimitiveTopology topology)
|
||||
{
|
||||
_topology = topology;
|
||||
}
|
||||
|
||||
public static void Run(ref SetPrimitiveTopologyCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetPrimitiveTopology(command._topology);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetProgramCommand : IGALCommand, IGALCommand<SetProgramCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetProgram;
|
||||
private TableRef<IProgram> _program;
|
||||
|
||||
public void Set(TableRef<IProgram> program)
|
||||
{
|
||||
_program = program;
|
||||
}
|
||||
|
||||
public static void Run(ref SetProgramCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
ThreadedProgram program = command._program.GetAs<ThreadedProgram>(threaded);
|
||||
|
||||
threaded.Programs.WaitForProgram(program);
|
||||
|
||||
renderer.Pipeline.SetProgram(program.Base);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetRasterizerDiscardCommand : IGALCommand, IGALCommand<SetRasterizerDiscardCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetRasterizerDiscard;
|
||||
private bool _discard;
|
||||
|
||||
public void Set(bool discard)
|
||||
{
|
||||
_discard = discard;
|
||||
}
|
||||
|
||||
public static void Run(ref SetRasterizerDiscardCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetRasterizerDiscard(command._discard);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetRenderTargetColorMasksCommand : IGALCommand, IGALCommand<SetRenderTargetColorMasksCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetRenderTargetColorMasks;
|
||||
private SpanRef<uint> _componentMask;
|
||||
|
||||
public void Set(SpanRef<uint> componentMask)
|
||||
{
|
||||
_componentMask = componentMask;
|
||||
}
|
||||
|
||||
public static void Run(ref SetRenderTargetColorMasksCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
ReadOnlySpan<uint> componentMask = command._componentMask.Get(threaded);
|
||||
renderer.Pipeline.SetRenderTargetColorMasks(componentMask);
|
||||
command._componentMask.Dispose(threaded);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetRenderTargetScaleCommand : IGALCommand, IGALCommand<SetRenderTargetScaleCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetRenderTargetScale;
|
||||
private float _scale;
|
||||
|
||||
public void Set(float scale)
|
||||
{
|
||||
_scale = scale;
|
||||
}
|
||||
|
||||
public static void Run(ref SetRenderTargetScaleCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetRenderTargetScale(command._scale);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetRenderTargetsCommand : IGALCommand, IGALCommand<SetRenderTargetsCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetRenderTargets;
|
||||
private TableRef<ITexture[]> _colors;
|
||||
private TableRef<ITexture> _depthStencil;
|
||||
|
||||
public void Set(TableRef<ITexture[]> colors, TableRef<ITexture> depthStencil)
|
||||
{
|
||||
_colors = colors;
|
||||
_depthStencil = depthStencil;
|
||||
}
|
||||
|
||||
public static void Run(ref SetRenderTargetsCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetRenderTargets(command._colors.Get(threaded).Select(color => ((ThreadedTexture)color)?.Base).ToArray(), command._depthStencil.GetAs<ThreadedTexture>(threaded)?.Base);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetScissorsCommand : IGALCommand, IGALCommand<SetScissorsCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetScissor;
|
||||
private SpanRef<Rectangle<int>> _scissors;
|
||||
|
||||
public void Set(SpanRef<Rectangle<int>> scissors)
|
||||
{
|
||||
_scissors = scissors;
|
||||
}
|
||||
|
||||
public static void Run(ref SetScissorsCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetScissors(command._scissors.Get(threaded));
|
||||
|
||||
command._scissors.Dispose(threaded);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetStencilTestCommand : IGALCommand, IGALCommand<SetStencilTestCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetStencilTest;
|
||||
private StencilTestDescriptor _stencilTest;
|
||||
|
||||
public void Set(StencilTestDescriptor stencilTest)
|
||||
{
|
||||
_stencilTest = stencilTest;
|
||||
}
|
||||
|
||||
public static void Run(ref SetStencilTestCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetStencilTest(command._stencilTest);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetStorageBuffersCommand : IGALCommand, IGALCommand<SetStorageBuffersCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetStorageBuffers;
|
||||
private SpanRef<BufferAssignment> _buffers;
|
||||
|
||||
public void Set(SpanRef<BufferAssignment> buffers)
|
||||
{
|
||||
_buffers = buffers;
|
||||
}
|
||||
|
||||
public static void Run(ref SetStorageBuffersCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
Span<BufferAssignment> buffers = command._buffers.Get(threaded);
|
||||
renderer.Pipeline.SetStorageBuffers(threaded.Buffers.MapBufferRanges(buffers));
|
||||
command._buffers.Dispose(threaded);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetTextureAndSamplerCommand : IGALCommand, IGALCommand<SetTextureAndSamplerCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetTextureAndSampler;
|
||||
private ShaderStage _stage;
|
||||
private int _binding;
|
||||
private TableRef<ITexture> _texture;
|
||||
private TableRef<ISampler> _sampler;
|
||||
|
||||
public void Set(ShaderStage stage, int binding, TableRef<ITexture> texture, TableRef<ISampler> sampler)
|
||||
{
|
||||
_stage = stage;
|
||||
_binding = binding;
|
||||
_texture = texture;
|
||||
_sampler = sampler;
|
||||
}
|
||||
|
||||
public static void Run(ref SetTextureAndSamplerCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetTextureAndSampler(command._stage, command._binding, command._texture.GetAs<ThreadedTexture>(threaded)?.Base, command._sampler.GetAs<ThreadedSampler>(threaded)?.Base);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetTransformFeedbackBuffersCommand : IGALCommand, IGALCommand<SetTransformFeedbackBuffersCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetTransformFeedbackBuffers;
|
||||
private SpanRef<BufferRange> _buffers;
|
||||
|
||||
public void Set(SpanRef<BufferRange> buffers)
|
||||
{
|
||||
_buffers = buffers;
|
||||
}
|
||||
|
||||
public static void Run(ref SetTransformFeedbackBuffersCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
Span<BufferRange> buffers = command._buffers.Get(threaded);
|
||||
renderer.Pipeline.SetTransformFeedbackBuffers(threaded.Buffers.MapBufferRanges(buffers));
|
||||
command._buffers.Dispose(threaded);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetUniformBuffersCommand : IGALCommand, IGALCommand<SetUniformBuffersCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetUniformBuffers;
|
||||
private SpanRef<BufferAssignment> _buffers;
|
||||
|
||||
public void Set(SpanRef<BufferAssignment> buffers)
|
||||
{
|
||||
_buffers = buffers;
|
||||
}
|
||||
|
||||
public static void Run(ref SetUniformBuffersCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
Span<BufferAssignment> buffers = command._buffers.Get(threaded);
|
||||
renderer.Pipeline.SetUniformBuffers(threaded.Buffers.MapBufferRanges(buffers));
|
||||
command._buffers.Dispose(threaded);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetUserClipDistanceCommand : IGALCommand, IGALCommand<SetUserClipDistanceCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetUserClipDistance;
|
||||
private int _index;
|
||||
private bool _enableClip;
|
||||
|
||||
public void Set(int index, bool enableClip)
|
||||
{
|
||||
_index = index;
|
||||
_enableClip = enableClip;
|
||||
}
|
||||
|
||||
public static void Run(ref SetUserClipDistanceCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetUserClipDistance(command._index, command._enableClip);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetVertexAttribsCommand : IGALCommand, IGALCommand<SetVertexAttribsCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetVertexAttribs;
|
||||
private SpanRef<VertexAttribDescriptor> _vertexAttribs;
|
||||
|
||||
public void Set(SpanRef<VertexAttribDescriptor> vertexAttribs)
|
||||
{
|
||||
_vertexAttribs = vertexAttribs;
|
||||
}
|
||||
|
||||
public static void Run(ref SetVertexAttribsCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
ReadOnlySpan<VertexAttribDescriptor> vertexAttribs = command._vertexAttribs.Get(threaded);
|
||||
renderer.Pipeline.SetVertexAttribs(vertexAttribs);
|
||||
command._vertexAttribs.Dispose(threaded);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetVertexBuffersCommand : IGALCommand, IGALCommand<SetVertexBuffersCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetVertexBuffers;
|
||||
private SpanRef<VertexBufferDescriptor> _vertexBuffers;
|
||||
|
||||
public void Set(SpanRef<VertexBufferDescriptor> vertexBuffers)
|
||||
{
|
||||
_vertexBuffers = vertexBuffers;
|
||||
}
|
||||
|
||||
public static void Run(ref SetVertexBuffersCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
Span<VertexBufferDescriptor> vertexBuffers = command._vertexBuffers.Get(threaded);
|
||||
renderer.Pipeline.SetVertexBuffers(threaded.Buffers.MapBufferRanges(vertexBuffers));
|
||||
command._vertexBuffers.Dispose(threaded);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetViewportsCommand : IGALCommand, IGALCommand<SetViewportsCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetViewports;
|
||||
private SpanRef<Viewport> _viewports;
|
||||
private bool _disableTransform;
|
||||
|
||||
public void Set(SpanRef<Viewport> viewports, bool disableTransform)
|
||||
{
|
||||
_viewports = viewports;
|
||||
_disableTransform = disableTransform;
|
||||
}
|
||||
|
||||
public static void Run(ref SetViewportsCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
ReadOnlySpan<Viewport> viewports = command._viewports.Get(threaded);
|
||||
renderer.Pipeline.SetViewports(viewports, command._disableTransform);
|
||||
command._viewports.Dispose(threaded);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture
|
||||
{
|
||||
struct TextureCopyToCommand : IGALCommand, IGALCommand<TextureCopyToCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.TextureCopyTo;
|
||||
private TableRef<ThreadedTexture> _texture;
|
||||
private TableRef<ThreadedTexture> _destination;
|
||||
private int _firstLayer;
|
||||
private int _firstLevel;
|
||||
|
||||
public void Set(TableRef<ThreadedTexture> texture, TableRef<ThreadedTexture> destination, int firstLayer, int firstLevel)
|
||||
{
|
||||
_texture = texture;
|
||||
_destination = destination;
|
||||
_firstLayer = firstLayer;
|
||||
_firstLevel = firstLevel;
|
||||
}
|
||||
|
||||
public static void Run(ref TextureCopyToCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
ThreadedTexture source = command._texture.Get(threaded);
|
||||
source.Base.CopyTo(command._destination.Get(threaded).Base, command._firstLayer, command._firstLevel);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture
|
||||
{
|
||||
struct TextureCopyToScaledCommand : IGALCommand, IGALCommand<TextureCopyToScaledCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.TextureCopyToScaled;
|
||||
private TableRef<ThreadedTexture> _texture;
|
||||
private TableRef<ThreadedTexture> _destination;
|
||||
private Extents2D _srcRegion;
|
||||
private Extents2D _dstRegion;
|
||||
private bool _linearFilter;
|
||||
|
||||
public void Set(TableRef<ThreadedTexture> texture, TableRef<ThreadedTexture> destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter)
|
||||
{
|
||||
_texture = texture;
|
||||
_destination = destination;
|
||||
_srcRegion = srcRegion;
|
||||
_dstRegion = dstRegion;
|
||||
_linearFilter = linearFilter;
|
||||
}
|
||||
|
||||
public static void Run(ref TextureCopyToScaledCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
ThreadedTexture source = command._texture.Get(threaded);
|
||||
source.Base.CopyTo(command._destination.Get(threaded).Base, command._srcRegion, command._dstRegion, command._linearFilter);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture
|
||||
{
|
||||
struct TextureCopyToSliceCommand : IGALCommand, IGALCommand<TextureCopyToSliceCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.TextureCopyToSlice;
|
||||
private TableRef<ThreadedTexture> _texture;
|
||||
private TableRef<ThreadedTexture> _destination;
|
||||
private int _srcLayer;
|
||||
private int _dstLayer;
|
||||
private int _srcLevel;
|
||||
private int _dstLevel;
|
||||
|
||||
public void Set(TableRef<ThreadedTexture> texture, TableRef<ThreadedTexture> destination, int srcLayer, int dstLayer, int srcLevel, int dstLevel)
|
||||
{
|
||||
_texture = texture;
|
||||
_destination = destination;
|
||||
_srcLayer = srcLayer;
|
||||
_dstLayer = dstLayer;
|
||||
_srcLevel = srcLevel;
|
||||
_dstLevel = dstLevel;
|
||||
}
|
||||
|
||||
public static void Run(ref TextureCopyToSliceCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
ThreadedTexture source = command._texture.Get(threaded);
|
||||
source.Base.CopyTo(command._destination.Get(threaded).Base, command._srcLayer, command._dstLayer, command._srcLevel, command._dstLevel);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture
|
||||
{
|
||||
struct TextureCreateViewCommand : IGALCommand, IGALCommand<TextureCreateViewCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.TextureCreateView;
|
||||
private TableRef<ThreadedTexture> _texture;
|
||||
private TableRef<ThreadedTexture> _destination;
|
||||
private TextureCreateInfo _info;
|
||||
private int _firstLayer;
|
||||
private int _firstLevel;
|
||||
|
||||
public void Set(TableRef<ThreadedTexture> texture, TableRef<ThreadedTexture> destination, TextureCreateInfo info, int firstLayer, int firstLevel)
|
||||
{
|
||||
_texture = texture;
|
||||
_destination = destination;
|
||||
_info = info;
|
||||
_firstLayer = firstLayer;
|
||||
_firstLevel = firstLevel;
|
||||
}
|
||||
|
||||
public static void Run(ref TextureCreateViewCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
ThreadedTexture source = command._texture.Get(threaded);
|
||||
command._destination.Get(threaded).Base = source.Base.CreateView(command._info, command._firstLayer, command._firstLevel);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture
|
||||
{
|
||||
struct TextureGetDataCommand : IGALCommand, IGALCommand<TextureGetDataCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.TextureGetData;
|
||||
private TableRef<ThreadedTexture> _texture;
|
||||
private TableRef<ResultBox<PinnedSpan<byte>>> _result;
|
||||
|
||||
public void Set(TableRef<ThreadedTexture> texture, TableRef<ResultBox<PinnedSpan<byte>>> result)
|
||||
{
|
||||
_texture = texture;
|
||||
_result = result;
|
||||
}
|
||||
|
||||
public static void Run(ref TextureGetDataCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
PinnedSpan<byte> result = command._texture.Get(threaded).Base.GetData();
|
||||
|
||||
command._result.Get(threaded).Result = result;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture
|
||||
{
|
||||
struct TextureGetDataSliceCommand : IGALCommand, IGALCommand<TextureGetDataSliceCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.TextureGetDataSlice;
|
||||
private TableRef<ThreadedTexture> _texture;
|
||||
private TableRef<ResultBox<PinnedSpan<byte>>> _result;
|
||||
private int _layer;
|
||||
private int _level;
|
||||
|
||||
public void Set(TableRef<ThreadedTexture> texture, TableRef<ResultBox<PinnedSpan<byte>>> result, int layer, int level)
|
||||
{
|
||||
_texture = texture;
|
||||
_result = result;
|
||||
_layer = layer;
|
||||
_level = level;
|
||||
}
|
||||
|
||||
public static void Run(ref TextureGetDataSliceCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
PinnedSpan<byte> result = command._texture.Get(threaded).Base.GetData(command._layer, command._level);
|
||||
|
||||
command._result.Get(threaded).Result = result;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture
|
||||
{
|
||||
struct TextureReleaseCommand : IGALCommand, IGALCommand<TextureReleaseCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.TextureRelease;
|
||||
private TableRef<ThreadedTexture> _texture;
|
||||
|
||||
public void Set(TableRef<ThreadedTexture> texture)
|
||||
{
|
||||
_texture = texture;
|
||||
}
|
||||
|
||||
public static void Run(ref TextureReleaseCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
command._texture.Get(threaded).Base.Release();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture
|
||||
{
|
||||
struct TextureSetDataCommand : IGALCommand, IGALCommand<TextureSetDataCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.TextureSetData;
|
||||
private TableRef<ThreadedTexture> _texture;
|
||||
private TableRef<byte[]> _data;
|
||||
|
||||
public void Set(TableRef<ThreadedTexture> texture, TableRef<byte[]> data)
|
||||
{
|
||||
_texture = texture;
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public static void Run(ref TextureSetDataCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
ThreadedTexture texture = command._texture.Get(threaded);
|
||||
texture.Base.SetData(new ReadOnlySpan<byte>(command._data.Get(threaded)));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture
|
||||
{
|
||||
struct TextureSetDataSliceCommand : IGALCommand, IGALCommand<TextureSetDataSliceCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.TextureSetDataSlice;
|
||||
private TableRef<ThreadedTexture> _texture;
|
||||
private TableRef<byte[]> _data;
|
||||
private int _layer;
|
||||
private int _level;
|
||||
|
||||
public void Set(TableRef<ThreadedTexture> texture, TableRef<byte[]> data, int layer, int level)
|
||||
{
|
||||
_texture = texture;
|
||||
_data = data;
|
||||
_layer = layer;
|
||||
_level = level;
|
||||
}
|
||||
|
||||
public static void Run(ref TextureSetDataSliceCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
ThreadedTexture texture = command._texture.Get(threaded);
|
||||
texture.Base.SetData(new ReadOnlySpan<byte>(command._data.Get(threaded)), command._layer, command._level);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture
|
||||
{
|
||||
struct TextureSetDataSliceRegionCommand : IGALCommand, IGALCommand<TextureSetDataSliceRegionCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.TextureSetDataSliceRegion;
|
||||
private TableRef<ThreadedTexture> _texture;
|
||||
private TableRef<byte[]> _data;
|
||||
private int _layer;
|
||||
private int _level;
|
||||
private Rectangle<int> _region;
|
||||
|
||||
public void Set(TableRef<ThreadedTexture> texture, TableRef<byte[]> data, int layer, int level, Rectangle<int> region)
|
||||
{
|
||||
_texture = texture;
|
||||
_data = data;
|
||||
_layer = layer;
|
||||
_level = level;
|
||||
_region = region;
|
||||
}
|
||||
|
||||
public static void Run(ref TextureSetDataSliceRegionCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
ThreadedTexture texture = command._texture.Get(threaded);
|
||||
texture.Base.SetData(new ReadOnlySpan<byte>(command._data.Get(threaded)), command._layer, command._level, command._region);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture
|
||||
{
|
||||
struct TextureSetStorageCommand : IGALCommand, IGALCommand<TextureSetStorageCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.TextureSetStorage;
|
||||
private TableRef<ThreadedTexture> _texture;
|
||||
private BufferRange _storage;
|
||||
|
||||
public void Set(TableRef<ThreadedTexture> texture, BufferRange storage)
|
||||
{
|
||||
_texture = texture;
|
||||
_storage = storage;
|
||||
}
|
||||
|
||||
public static void Run(ref TextureSetStorageCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
command._texture.Get(threaded).Base.SetStorage(threaded.Buffers.MapBufferRange(command._storage));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct TextureBarrierCommand : IGALCommand, IGALCommand<TextureBarrierCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.TextureBarrier;
|
||||
|
||||
public static void Run(ref TextureBarrierCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.TextureBarrier();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct TextureBarrierTiledCommand : IGALCommand, IGALCommand<TextureBarrierTiledCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.TextureBarrierTiled;
|
||||
|
||||
public static void Run(ref TextureBarrierTiledCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.TextureBarrierTiled();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct TryHostConditionalRenderingCommand : IGALCommand, IGALCommand<TryHostConditionalRenderingCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.TryHostConditionalRendering;
|
||||
private TableRef<ThreadedCounterEvent> _value;
|
||||
private ulong _compare;
|
||||
private bool _isEqual;
|
||||
|
||||
public void Set(TableRef<ThreadedCounterEvent> value, ulong compare, bool isEqual)
|
||||
{
|
||||
_value = value;
|
||||
_compare = compare;
|
||||
_isEqual = isEqual;
|
||||
}
|
||||
|
||||
public static void Run(ref TryHostConditionalRenderingCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.TryHostConditionalRendering(command._value.Get(threaded)?.Base, command._compare, command._isEqual);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct TryHostConditionalRenderingFlushCommand : IGALCommand, IGALCommand<TryHostConditionalRenderingFlushCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.TryHostConditionalRenderingFlush;
|
||||
private TableRef<ThreadedCounterEvent> _value;
|
||||
private TableRef<ThreadedCounterEvent> _compare;
|
||||
private bool _isEqual;
|
||||
|
||||
public void Set(TableRef<ThreadedCounterEvent> value, TableRef<ThreadedCounterEvent> compare, bool isEqual)
|
||||
{
|
||||
_value = value;
|
||||
_compare = compare;
|
||||
_isEqual = isEqual;
|
||||
}
|
||||
|
||||
public static void Run(ref TryHostConditionalRenderingFlushCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.TryHostConditionalRendering(command._value.Get(threaded)?.Base, command._compare.Get(threaded)?.Base, command._isEqual);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct UpdateRenderScaleCommand : IGALCommand, IGALCommand<UpdateRenderScaleCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.UpdateRenderScale;
|
||||
private SpanRef<float> _scales;
|
||||
private int _totalCount;
|
||||
private int _fragmentCount;
|
||||
|
||||
public void Set(SpanRef<float> scales, int totalCount, int fragmentCount)
|
||||
{
|
||||
_scales = scales;
|
||||
_totalCount = totalCount;
|
||||
_fragmentCount = fragmentCount;
|
||||
}
|
||||
|
||||
public static void Run(ref UpdateRenderScaleCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.UpdateRenderScale(command._scales.Get(threaded), command._totalCount, command._fragmentCount);
|
||||
command._scales.Dispose(threaded);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Window
|
||||
{
|
||||
struct WindowPresentCommand : IGALCommand, IGALCommand<WindowPresentCommand>
|
||||
{
|
||||
public CommandType CommandType => CommandType.WindowPresent;
|
||||
private TableRef<ThreadedTexture> _texture;
|
||||
private ImageCrop _crop;
|
||||
private TableRef<Action> _swapBuffersCallback;
|
||||
|
||||
public void Set(TableRef<ThreadedTexture> texture, ImageCrop crop, TableRef<Action> swapBuffersCallback)
|
||||
{
|
||||
_texture = texture;
|
||||
_crop = crop;
|
||||
_swapBuffersCallback = swapBuffersCallback;
|
||||
}
|
||||
|
||||
public static void Run(ref WindowPresentCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
threaded.SignalFrame();
|
||||
renderer.Window.Present(command._texture.Get(threaded)?.Base, command._crop, command._swapBuffersCallback.Get(threaded));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// A memory pool for passing through Span<T> resources with one producer and consumer.
|
||||
/// Data is copied on creation to part of the pool, then that region is reserved until it is disposed by the consumer.
|
||||
/// Similar to the command queue, this pool assumes that data is created and disposed in the same order.
|
||||
/// </summary>
|
||||
class CircularSpanPool
|
||||
{
|
||||
private ThreadedRenderer _renderer;
|
||||
private byte[] _pool;
|
||||
private int _size;
|
||||
|
||||
private int _producerPtr;
|
||||
private int _producerSkipPosition = -1;
|
||||
private int _consumerPtr;
|
||||
|
||||
public CircularSpanPool(ThreadedRenderer renderer, int size)
|
||||
{
|
||||
_renderer = renderer;
|
||||
_size = size;
|
||||
_pool = new byte[size];
|
||||
}
|
||||
|
||||
public SpanRef<T> Insert<T>(ReadOnlySpan<T> data) where T : unmanaged
|
||||
{
|
||||
int size = data.Length * Unsafe.SizeOf<T>();
|
||||
|
||||
// Wrapping aware circular queue.
|
||||
// If there's no space at the end of the pool for this span, we can't fragment it.
|
||||
// So just loop back around to the start. Remember the last skipped position.
|
||||
|
||||
bool wraparound = _producerPtr + size >= _size;
|
||||
int index = wraparound ? 0 : _producerPtr;
|
||||
|
||||
// _consumerPtr is from another thread, and we're taking it without a lock, so treat this as a snapshot in the past.
|
||||
// We know that it will always be before or equal to the producer pointer, and it cannot pass it.
|
||||
// This is enough to reason about if there is space in the queue for the data, even if we're checking against an outdated value.
|
||||
|
||||
int consumer = _consumerPtr;
|
||||
bool beforeConsumer = _producerPtr < consumer;
|
||||
|
||||
if (size > _size - 1 || (wraparound && beforeConsumer) || ((index < consumer || wraparound) && index + size >= consumer))
|
||||
{
|
||||
// Just get an array in the following situations:
|
||||
// - The data is too large to fit in the pool.
|
||||
// - A wraparound would happen but the consumer would be covered by it.
|
||||
// - The producer would catch up to the consumer as a result.
|
||||
|
||||
return new SpanRef<T>(_renderer, data.ToArray());
|
||||
}
|
||||
|
||||
data.CopyTo(MemoryMarshal.Cast<byte, T>(new Span<byte>(_pool).Slice(index, size)));
|
||||
|
||||
if (wraparound)
|
||||
{
|
||||
_producerSkipPosition = _producerPtr;
|
||||
}
|
||||
|
||||
_producerPtr = index + size;
|
||||
|
||||
return new SpanRef<T>(data.Length);
|
||||
}
|
||||
|
||||
public Span<T> Get<T>(int length) where T : unmanaged
|
||||
{
|
||||
int size = length * Unsafe.SizeOf<T>();
|
||||
|
||||
if (_consumerPtr == Interlocked.CompareExchange(ref _producerSkipPosition, -1, _consumerPtr))
|
||||
{
|
||||
_consumerPtr = 0;
|
||||
}
|
||||
|
||||
return MemoryMarshal.Cast<byte, T>(new Span<byte>(_pool).Slice(_consumerPtr, size));
|
||||
}
|
||||
|
||||
public void Dispose<T>(int length) where T : unmanaged
|
||||
{
|
||||
int size = length * Unsafe.SizeOf<T>();
|
||||
|
||||
_consumerPtr = _consumerPtr + size;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Model
|
||||
{
|
||||
public class ResultBox<T>
|
||||
{
|
||||
public T Result;
|
||||
}
|
||||
}
|
39
src/Ryujinx.Graphics.GAL/Multithreading/Model/SpanRef.cs
Normal file
39
src/Ryujinx.Graphics.GAL/Multithreading/Model/SpanRef.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Model
|
||||
{
|
||||
struct SpanRef<T> where T : unmanaged
|
||||
{
|
||||
private int _packedLengthId;
|
||||
|
||||
public SpanRef(ThreadedRenderer renderer, T[] data)
|
||||
{
|
||||
_packedLengthId = -(renderer.AddTableRef(data) + 1);
|
||||
}
|
||||
|
||||
public SpanRef(int length)
|
||||
{
|
||||
_packedLengthId = length;
|
||||
}
|
||||
|
||||
public Span<T> Get(ThreadedRenderer renderer)
|
||||
{
|
||||
if (_packedLengthId >= 0)
|
||||
{
|
||||
return renderer.SpanPool.Get<T>(_packedLengthId);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Span<T>((T[])renderer.RemoveTableRef(-(_packedLengthId + 1)));
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose(ThreadedRenderer renderer)
|
||||
{
|
||||
if (_packedLengthId > 0)
|
||||
{
|
||||
renderer.SpanPool.Dispose<T>(_packedLengthId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
22
src/Ryujinx.Graphics.GAL/Multithreading/Model/TableRef.cs
Normal file
22
src/Ryujinx.Graphics.GAL/Multithreading/Model/TableRef.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Model
|
||||
{
|
||||
struct TableRef<T>
|
||||
{
|
||||
private int _index;
|
||||
|
||||
public TableRef(ThreadedRenderer renderer, T reference)
|
||||
{
|
||||
_index = renderer.AddTableRef(reference);
|
||||
}
|
||||
|
||||
public T Get(ThreadedRenderer renderer)
|
||||
{
|
||||
return (T)renderer.RemoveTableRef(_index);
|
||||
}
|
||||
|
||||
public T2 GetAs<T2>(ThreadedRenderer renderer) where T2 : T
|
||||
{
|
||||
return (T2)renderer.RemoveTableRef(_index);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Resources.Programs;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Resources
|
||||
{
|
||||
/// <summary>
|
||||
/// A structure handling multithreaded compilation for programs.
|
||||
/// </summary>
|
||||
class ProgramQueue
|
||||
{
|
||||
private const int MaxConcurrentCompilations = 8;
|
||||
|
||||
private IRenderer _renderer;
|
||||
|
||||
private Queue<IProgramRequest> _toCompile;
|
||||
private List<ThreadedProgram> _inProgress;
|
||||
|
||||
public ProgramQueue(IRenderer renderer)
|
||||
{
|
||||
_renderer = renderer;
|
||||
|
||||
_toCompile = new Queue<IProgramRequest>();
|
||||
_inProgress = new List<ThreadedProgram>();
|
||||
}
|
||||
|
||||
public void Add(IProgramRequest request)
|
||||
{
|
||||
lock (_toCompile)
|
||||
{
|
||||
_toCompile.Enqueue(request);
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessQueue()
|
||||
{
|
||||
for (int i = 0; i < _inProgress.Count; i++)
|
||||
{
|
||||
ThreadedProgram program = _inProgress[i];
|
||||
|
||||
ProgramLinkStatus status = program.Base.CheckProgramLink(false);
|
||||
|
||||
if (status != ProgramLinkStatus.Incomplete)
|
||||
{
|
||||
program.Compiled = true;
|
||||
_inProgress.RemoveAt(i--);
|
||||
}
|
||||
}
|
||||
|
||||
int freeSpace = MaxConcurrentCompilations - _inProgress.Count;
|
||||
|
||||
for (int i = 0; i < freeSpace; i++)
|
||||
{
|
||||
// Begin compilation of some programs in the compile queue.
|
||||
IProgramRequest program;
|
||||
|
||||
lock (_toCompile)
|
||||
{
|
||||
if (!_toCompile.TryDequeue(out program))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (program.Threaded.Base != null)
|
||||
{
|
||||
ProgramLinkStatus status = program.Threaded.Base.CheckProgramLink(false);
|
||||
|
||||
if (status != ProgramLinkStatus.Incomplete)
|
||||
{
|
||||
// This program is already compiled. Keep going through the queue.
|
||||
program.Threaded.Compiled = true;
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
program.Threaded.Base = program.Create(_renderer);
|
||||
}
|
||||
|
||||
_inProgress.Add(program.Threaded);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process the queue until the given program has finished compiling.
|
||||
/// This will begin compilation of other programs on the queue as well.
|
||||
/// </summary>
|
||||
/// <param name="program">The program to wait for</param>
|
||||
public void WaitForProgram(ThreadedProgram program)
|
||||
{
|
||||
Span<SpinWait> spinWait = stackalloc SpinWait[1];
|
||||
|
||||
while (!program.Compiled)
|
||||
{
|
||||
ProcessQueue();
|
||||
|
||||
if (!program.Compiled)
|
||||
{
|
||||
spinWait[0].SpinOnce(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Resources.Programs
|
||||
{
|
||||
class BinaryProgramRequest : IProgramRequest
|
||||
{
|
||||
public ThreadedProgram Threaded { get; set; }
|
||||
|
||||
private byte[] _data;
|
||||
private bool _hasFragmentShader;
|
||||
private ShaderInfo _info;
|
||||
|
||||
public BinaryProgramRequest(ThreadedProgram program, byte[] data, bool hasFragmentShader, ShaderInfo info)
|
||||
{
|
||||
Threaded = program;
|
||||
|
||||
_data = data;
|
||||
_hasFragmentShader = hasFragmentShader;
|
||||
_info = info;
|
||||
}
|
||||
|
||||
public IProgram Create(IRenderer renderer)
|
||||
{
|
||||
return renderer.LoadProgramBinary(_data, _hasFragmentShader, _info);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Resources.Programs
|
||||
{
|
||||
interface IProgramRequest
|
||||
{
|
||||
ThreadedProgram Threaded { get; set; }
|
||||
IProgram Create(IRenderer renderer);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Resources.Programs
|
||||
{
|
||||
class SourceProgramRequest : IProgramRequest
|
||||
{
|
||||
public ThreadedProgram Threaded { get; set; }
|
||||
|
||||
private ShaderSource[] _shaders;
|
||||
private ShaderInfo _info;
|
||||
|
||||
public SourceProgramRequest(ThreadedProgram program, ShaderSource[] shaders, ShaderInfo info)
|
||||
{
|
||||
Threaded = program;
|
||||
|
||||
_shaders = shaders;
|
||||
_info = info;
|
||||
}
|
||||
|
||||
public IProgram Create(IRenderer renderer)
|
||||
{
|
||||
return renderer.CreateProgram(_shaders, _info);
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue