rjx-mirror/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs
gdkchan 7fea26e97e
Remove use of reflection on GAL multithreading (#4287)
* Introduce new IGALCommand<T> interface and use it

* Remove use of reflection on GAL multithreading

* Unmanaged constraint
2023-01-22 01:07:43 +01:00

148 lines
8.5 KiB
C#

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<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);
}
}
}