Add a Multithreading layer for the GAL, multi-thread shader compilation at runtime (#2501)
* Initial Implementation
About as fast as nvidia GL multithreading, can be improved with faster command queuing.
* Struct based command list
Speeds up a bit. Still a lot of time lost to resource copy.
* Do shader init while the render thread is active.
* Introduce circular span pool V1
Ideally should be able to use structs instead of references for storing these spans on commands. Will try that next.
* Refactor SpanRef some more
Use a struct to represent SpanRef, rather than a reference.
* Flush buffers on background thread
* Use a span for UpdateRenderScale.
Much faster than copying the array.
* Calculate command size using reflection
* WIP parallel shaders
* Some minor optimisation
* Only 2 max refs per command now.
The command with 3 refs is gone. 😌
* Don't cast on the GPU side
* Remove redundant casts, force sync on window present
* Fix Shader Cache
* Fix host shader save.
* Fixup to work with new renderer stuff
* Make command Run static, use array of delegates as lookup
Profile says this takes less time than the previous way.
* Bring up to date
* Add settings toggle. Fix Muiltithreading Off mode.
* Fix warning.
* Release tracking lock for flushes
* Fix Conditional Render fast path with threaded gal
* Make handle iteration safe when releasing the lock
This is mostly temporary.
* Attempt to set backend threading on driver
Only really works on nvidia before launching a game.
* Fix race condition with BufferModifiedRangeList, exceptions in tracking actions
* Update buffer set commands
* Some cleanup
* Only use stutter workaround when using opengl renderer non-threaded
* Add host-conditional reservation of counter events
There has always been the possibility that conditional rendering could use a query object just as it is disposed by the counter queue. This change makes it so that when the host decides to use host conditional rendering, the query object is reserved so that it cannot be deleted. Counter events can optionally start reserved, as the threaded implementation can reserve them before the backend creates them, and there would otherwise be a short amount of time where the counter queue could dispose the event before a call to reserve it could be made.
* Address Feedback
* Make counter flush tracked again.
Hopefully does not cause any issues this time.
* Wait for FlushTo on the main queue thread.
Currently assumes only one thread will want to FlushTo (in this case, the GPU thread)
* Add SDL2 headless integration
* Add HLE macro commands.
Co-authored-by: Mary <mary@mary.zone>
This commit is contained in:
parent
501c3d5cea
commit
ec3e848d79
143 changed files with 4491 additions and 200 deletions
|
@ -0,0 +1,12 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct BarrierCommand : IGALCommand
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
ReadOnlySpan<byte> result = renderer.GetBufferData(threaded.Buffers.MapBuffer(command._buffer), command._offset, command._size);
|
||||
|
||||
command._result.Get(threaded).Result = new PinnedSpan<byte>(result);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Buffer
|
||||
{
|
||||
struct BufferSetDataCommand : IGALCommand
|
||||
{
|
||||
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
|
||||
{
|
||||
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,22 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct ClearRenderTargetColorCommand : IGALCommand
|
||||
{
|
||||
public CommandType CommandType => CommandType.ClearRenderTargetColor;
|
||||
private int _index;
|
||||
private uint _componentMask;
|
||||
private ColorF _color;
|
||||
|
||||
public void Set(int index, uint componentMask, ColorF color)
|
||||
{
|
||||
_index = index;
|
||||
_componentMask = componentMask;
|
||||
_color = color;
|
||||
}
|
||||
|
||||
public static void Run(ref ClearRenderTargetColorCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.ClearRenderTargetColor(command._index, command._componentMask, command._color);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct ClearRenderTargetDepthStencilCommand : IGALCommand
|
||||
{
|
||||
public CommandType CommandType => CommandType.ClearRenderTargetDepthStencil;
|
||||
private float _depthValue;
|
||||
private bool _depthMask;
|
||||
private int _stencilValue;
|
||||
private int _stencilMask;
|
||||
|
||||
public void Set(float depthValue, bool depthMask, int stencilValue, int stencilMask)
|
||||
{
|
||||
_depthValue = depthValue;
|
||||
_depthMask = depthMask;
|
||||
_stencilValue = stencilValue;
|
||||
_stencilMask = stencilMask;
|
||||
}
|
||||
|
||||
public static void Run(ref ClearRenderTargetDepthStencilCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.ClearRenderTargetDepthStencil(command._depthValue, command._depthMask, command._stencilValue, command._stencilMask);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct CommandBufferBarrierCommand : IGALCommand
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
26
Ryujinx.Graphics.GAL/Multithreading/Commands/DrawCommand.cs
Normal file
26
Ryujinx.Graphics.GAL/Multithreading/Commands/DrawCommand.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct DrawIndexedCommand : IGALCommand
|
||||
{
|
||||
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
|
||||
{
|
||||
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,12 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct EndHostConditionalRenderingCommand : IGALCommand
|
||||
{
|
||||
public CommandType CommandType => CommandType.EndHostConditionalRendering;
|
||||
|
||||
public static void Run(IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.EndHostConditionalRendering();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct EndTransformFeedbackCommand : IGALCommand
|
||||
{
|
||||
public CommandType CommandType => CommandType.EndTransformFeedback;
|
||||
|
||||
public static void Run(ref EndTransformFeedbackCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.EndTransformFeedback();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
interface IGALCommand
|
||||
{
|
||||
CommandType CommandType { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct MultiDrawIndexedIndirectCountCommand : IGALCommand
|
||||
{
|
||||
public CommandType CommandType => CommandType.MultiDrawIndexedIndirectCount;
|
||||
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 MultiDrawIndexedIndirectCountCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.MultiDrawIndexedIndirectCount(
|
||||
threaded.Buffers.MapBufferRange(command._indirectBuffer),
|
||||
threaded.Buffers.MapBufferRange(command._parameterBuffer),
|
||||
command._maxDrawCount,
|
||||
command._stride
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct MultiDrawIndirectCountCommand : IGALCommand
|
||||
{
|
||||
public CommandType CommandType => CommandType.MultiDrawIndirectCount;
|
||||
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 MultiDrawIndirectCountCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.MultiDrawIndirectCount(
|
||||
threaded.Buffers.MapBufferRange(command._indirectBuffer),
|
||||
threaded.Buffers.MapBufferRange(command._parameterBuffer),
|
||||
command._maxDrawCount,
|
||||
command._stride
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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,22 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
||||
{
|
||||
struct CompileShaderCommand : IGALCommand
|
||||
{
|
||||
public CommandType CommandType => CommandType.CompileShader;
|
||||
private TableRef<ThreadedShader> _shader;
|
||||
|
||||
public void Set(TableRef<ThreadedShader> shader)
|
||||
{
|
||||
_shader = shader;
|
||||
}
|
||||
|
||||
public static void Run(ref CompileShaderCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
ThreadedShader shader = command._shader.Get(threaded);
|
||||
shader.EnsureCreated();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
||||
{
|
||||
struct CreateBufferCommand : IGALCommand
|
||||
{
|
||||
public CommandType CommandType => CommandType.CreateBuffer;
|
||||
private BufferHandle _threadedHandle;
|
||||
private int _size;
|
||||
|
||||
public void Set(BufferHandle threadedHandle, int size)
|
||||
{
|
||||
_threadedHandle = threadedHandle;
|
||||
_size = size;
|
||||
}
|
||||
|
||||
public static void Run(ref CreateBufferCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
threaded.Buffers.AssignBuffer(command._threadedHandle, renderer.CreateBuffer(command._size));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
{
|
||||
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
|
||||
{
|
||||
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,20 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
||||
{
|
||||
struct CreateSyncCommand : IGALCommand
|
||||
{
|
||||
public CommandType CommandType => CommandType.CreateSync;
|
||||
private ulong _id;
|
||||
|
||||
public void Set(ulong id)
|
||||
{
|
||||
_id = id;
|
||||
}
|
||||
|
||||
public static void Run(ref CreateSyncCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.CreateSync(command._id);
|
||||
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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,14 @@
|
|||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
||||
{
|
||||
struct PreFrameCommand : IGALCommand
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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,20 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetBlendStateCommand : IGALCommand
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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,24 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetPointParametersCommand : IGALCommand
|
||||
{
|
||||
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 SetPrimitiveRestartCommand : IGALCommand
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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,23 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetSamplerCommand : IGALCommand
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetSampler;
|
||||
private int _index;
|
||||
private TableRef<ISampler> _sampler;
|
||||
|
||||
public void Set(int index, TableRef<ISampler> sampler)
|
||||
{
|
||||
_index = index;
|
||||
_sampler = sampler;
|
||||
}
|
||||
|
||||
public static void Run(ref SetSamplerCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetSampler(command._index, command._sampler.GetAs<ThreadedSampler>(threaded)?.Base);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetScissorCommand : IGALCommand
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetScissor;
|
||||
private int _index;
|
||||
private bool _enable;
|
||||
private int _x;
|
||||
private int _y;
|
||||
private int _width;
|
||||
private int _height;
|
||||
|
||||
public void Set(int index, bool enable, int x, int y, int width, int height)
|
||||
{
|
||||
_index = index;
|
||||
_enable = enable;
|
||||
_x = x;
|
||||
_y = y;
|
||||
_width = width;
|
||||
_height = height;
|
||||
}
|
||||
|
||||
public static void Run(ref SetScissorCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetScissor(command._index, command._enable, command._x, command._y, command._width, command._height);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetStencilTestCommand : IGALCommand
|
||||
{
|
||||
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,25 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetStorageBuffersCommand : IGALCommand
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetStorageBuffers;
|
||||
private int _first;
|
||||
private SpanRef<BufferRange> _buffers;
|
||||
|
||||
public void Set(int first, SpanRef<BufferRange> buffers)
|
||||
{
|
||||
_first = first;
|
||||
_buffers = buffers;
|
||||
}
|
||||
|
||||
public static void Run(ref SetStorageBuffersCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
Span<BufferRange> buffers = command._buffers.Get(threaded);
|
||||
renderer.Pipeline.SetStorageBuffers(command._first, threaded.Buffers.MapBufferRanges(buffers));
|
||||
command._buffers.Dispose(threaded);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetTextureCommand : IGALCommand
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetTexture;
|
||||
private int _binding;
|
||||
private TableRef<ITexture> _texture;
|
||||
|
||||
public void Set(int binding, TableRef<ITexture> texture)
|
||||
{
|
||||
_binding = binding;
|
||||
_texture = texture;
|
||||
}
|
||||
|
||||
public static void Run(ref SetTextureCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetTexture(command._binding, command._texture.GetAs<ThreadedTexture>(threaded)?.Base);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetTransformFeedbackBuffersCommand : IGALCommand
|
||||
{
|
||||
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,25 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetUniformBuffersCommand : IGALCommand
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetUniformBuffers;
|
||||
private int _first;
|
||||
private SpanRef<BufferRange> _buffers;
|
||||
|
||||
public void Set(int first, SpanRef<BufferRange> buffers)
|
||||
{
|
||||
_first = first;
|
||||
_buffers = buffers;
|
||||
}
|
||||
|
||||
public static void Run(ref SetUniformBuffersCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
Span<BufferRange> buffers = command._buffers.Get(threaded);
|
||||
renderer.Pipeline.SetUniformBuffers(command._first, threaded.Buffers.MapBufferRanges(buffers));
|
||||
command._buffers.Dispose(threaded);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetUserClipDistanceCommand : IGALCommand
|
||||
{
|
||||
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
|
||||
{
|
||||
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,24 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetVertexBuffersCommand : IGALCommand
|
||||
{
|
||||
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,26 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetViewportsCommand : IGALCommand
|
||||
{
|
||||
public CommandType CommandType => CommandType.SetViewports;
|
||||
private int _first;
|
||||
private SpanRef<Viewport> _viewports;
|
||||
|
||||
public void Set(int first, SpanRef<Viewport> viewports)
|
||||
{
|
||||
_first = first;
|
||||
_viewports = viewports;
|
||||
}
|
||||
|
||||
public static void Run(ref SetViewportsCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
ReadOnlySpan<Viewport> viewports = command._viewports.Get(threaded);
|
||||
renderer.Pipeline.SetViewports(command._first, viewports);
|
||||
command._viewports.Dispose(threaded);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Shader
|
||||
{
|
||||
struct ShaderDisposeCommand : IGALCommand
|
||||
{
|
||||
public CommandType CommandType => CommandType.ShaderDispose;
|
||||
private TableRef<ThreadedShader> _shader;
|
||||
|
||||
public void Set(TableRef<ThreadedShader> shader)
|
||||
{
|
||||
_shader = shader;
|
||||
}
|
||||
|
||||
public static void Run(ref ShaderDisposeCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
command._shader.Get(threaded).Base.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
ReadOnlySpan<byte> result = command._texture.Get(threaded).Base.GetData();
|
||||
|
||||
command._result.Get(threaded).Result = new PinnedSpan<byte>(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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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,23 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture
|
||||
{
|
||||
struct TextureSetStorageCommand : IGALCommand
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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,28 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct UpdateRenderScaleCommand : IGALCommand
|
||||
{
|
||||
public CommandType CommandType => CommandType.UpdateRenderScale;
|
||||
private ShaderStage _stage;
|
||||
private SpanRef<float> _scales;
|
||||
private int _textureCount;
|
||||
private int _imageCount;
|
||||
|
||||
public void Set(ShaderStage stage, SpanRef<float> scales, int textureCount, int imageCount)
|
||||
{
|
||||
_stage = stage;
|
||||
_scales = scales;
|
||||
_textureCount = textureCount;
|
||||
_imageCount = imageCount;
|
||||
}
|
||||
|
||||
public static void Run(ref UpdateRenderScaleCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.UpdateRenderScale(command._stage, command._scales.Get(threaded), command._textureCount, command._imageCount);
|
||||
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
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue