/ src / Ryujinx.Graphics.GAL / Multithreading / CommandHelper.cs
CommandHelper.cs
  1  using Ryujinx.Graphics.GAL.Multithreading.Commands;
  2  using Ryujinx.Graphics.GAL.Multithreading.Commands.Buffer;
  3  using Ryujinx.Graphics.GAL.Multithreading.Commands.CounterEvent;
  4  using Ryujinx.Graphics.GAL.Multithreading.Commands.ImageArray;
  5  using Ryujinx.Graphics.GAL.Multithreading.Commands.Program;
  6  using Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer;
  7  using Ryujinx.Graphics.GAL.Multithreading.Commands.Sampler;
  8  using Ryujinx.Graphics.GAL.Multithreading.Commands.Texture;
  9  using Ryujinx.Graphics.GAL.Multithreading.Commands.TextureArray;
 10  using Ryujinx.Graphics.GAL.Multithreading.Commands.Window;
 11  using System;
 12  using System.Linq;
 13  using System.Runtime.CompilerServices;
 14  using System.Runtime.InteropServices;
 15  
 16  namespace Ryujinx.Graphics.GAL.Multithreading
 17  {
 18      static class CommandHelper
 19      {
 20          private delegate void CommandDelegate(Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer);
 21  
 22          private static readonly int _totalCommands = (int)Enum.GetValues<CommandType>().Max() + 1;
 23          private static readonly CommandDelegate[] _lookup = new CommandDelegate[_totalCommands];
 24  
 25          [MethodImpl(MethodImplOptions.AggressiveInlining)]
 26          private static ref T GetCommand<T>(Span<byte> memory)
 27          {
 28              return ref Unsafe.As<byte, T>(ref MemoryMarshal.GetReference(memory));
 29          }
 30  
 31          public static int GetMaxCommandSize()
 32          {
 33              return InitLookup() + 1; // 1 byte reserved for command size.
 34          }
 35  
 36          private static int InitLookup()
 37          {
 38              int maxCommandSize = 0;
 39  
 40              void Register<T>(CommandType commandType) where T : unmanaged, IGALCommand, IGALCommand<T>
 41              {
 42                  maxCommandSize = Math.Max(maxCommandSize, Unsafe.SizeOf<T>());
 43                  _lookup[(int)commandType] = (memory, threaded, renderer) => T.Run(ref GetCommand<T>(memory), threaded, renderer);
 44              }
 45  
 46              Register<ActionCommand>(CommandType.Action);
 47              Register<CreateBufferAccessCommand>(CommandType.CreateBufferAccess);
 48              Register<CreateBufferSparseCommand>(CommandType.CreateBufferSparse);
 49              Register<CreateHostBufferCommand>(CommandType.CreateHostBuffer);
 50              Register<CreateImageArrayCommand>(CommandType.CreateImageArray);
 51              Register<CreateProgramCommand>(CommandType.CreateProgram);
 52              Register<CreateSamplerCommand>(CommandType.CreateSampler);
 53              Register<CreateSyncCommand>(CommandType.CreateSync);
 54              Register<CreateTextureCommand>(CommandType.CreateTexture);
 55              Register<CreateTextureArrayCommand>(CommandType.CreateTextureArray);
 56              Register<GetCapabilitiesCommand>(CommandType.GetCapabilities);
 57              Register<PreFrameCommand>(CommandType.PreFrame);
 58              Register<ReportCounterCommand>(CommandType.ReportCounter);
 59              Register<ResetCounterCommand>(CommandType.ResetCounter);
 60              Register<UpdateCountersCommand>(CommandType.UpdateCounters);
 61  
 62              Register<BufferDisposeCommand>(CommandType.BufferDispose);
 63              Register<BufferGetDataCommand>(CommandType.BufferGetData);
 64              Register<BufferSetDataCommand>(CommandType.BufferSetData);
 65  
 66              Register<CounterEventDisposeCommand>(CommandType.CounterEventDispose);
 67              Register<CounterEventFlushCommand>(CommandType.CounterEventFlush);
 68  
 69              Register<ImageArrayDisposeCommand>(CommandType.ImageArrayDispose);
 70              Register<ImageArraySetImagesCommand>(CommandType.ImageArraySetImages);
 71  
 72              Register<ProgramDisposeCommand>(CommandType.ProgramDispose);
 73              Register<ProgramGetBinaryCommand>(CommandType.ProgramGetBinary);
 74              Register<ProgramCheckLinkCommand>(CommandType.ProgramCheckLink);
 75  
 76              Register<SamplerDisposeCommand>(CommandType.SamplerDispose);
 77  
 78              Register<TextureCopyToCommand>(CommandType.TextureCopyTo);
 79              Register<TextureCopyToScaledCommand>(CommandType.TextureCopyToScaled);
 80              Register<TextureCopyToSliceCommand>(CommandType.TextureCopyToSlice);
 81              Register<TextureCopyToBufferCommand>(CommandType.TextureCopyToBuffer);
 82              Register<TextureCreateViewCommand>(CommandType.TextureCreateView);
 83              Register<TextureGetDataCommand>(CommandType.TextureGetData);
 84              Register<TextureGetDataSliceCommand>(CommandType.TextureGetDataSlice);
 85              Register<TextureReleaseCommand>(CommandType.TextureRelease);
 86              Register<TextureSetDataCommand>(CommandType.TextureSetData);
 87              Register<TextureSetDataSliceCommand>(CommandType.TextureSetDataSlice);
 88              Register<TextureSetDataSliceRegionCommand>(CommandType.TextureSetDataSliceRegion);
 89              Register<TextureSetStorageCommand>(CommandType.TextureSetStorage);
 90  
 91              Register<TextureArrayDisposeCommand>(CommandType.TextureArrayDispose);
 92              Register<TextureArraySetSamplersCommand>(CommandType.TextureArraySetSamplers);
 93              Register<TextureArraySetTexturesCommand>(CommandType.TextureArraySetTextures);
 94  
 95              Register<WindowPresentCommand>(CommandType.WindowPresent);
 96  
 97              Register<BarrierCommand>(CommandType.Barrier);
 98              Register<BeginTransformFeedbackCommand>(CommandType.BeginTransformFeedback);
 99              Register<ClearBufferCommand>(CommandType.ClearBuffer);
100              Register<ClearRenderTargetColorCommand>(CommandType.ClearRenderTargetColor);
101              Register<ClearRenderTargetDepthStencilCommand>(CommandType.ClearRenderTargetDepthStencil);
102              Register<CommandBufferBarrierCommand>(CommandType.CommandBufferBarrier);
103              Register<CopyBufferCommand>(CommandType.CopyBuffer);
104              Register<DispatchComputeCommand>(CommandType.DispatchCompute);
105              Register<DrawCommand>(CommandType.Draw);
106              Register<DrawIndexedCommand>(CommandType.DrawIndexed);
107              Register<DrawIndexedIndirectCommand>(CommandType.DrawIndexedIndirect);
108              Register<DrawIndexedIndirectCountCommand>(CommandType.DrawIndexedIndirectCount);
109              Register<DrawIndirectCommand>(CommandType.DrawIndirect);
110              Register<DrawIndirectCountCommand>(CommandType.DrawIndirectCount);
111              Register<DrawTextureCommand>(CommandType.DrawTexture);
112              Register<EndHostConditionalRenderingCommand>(CommandType.EndHostConditionalRendering);
113              Register<EndTransformFeedbackCommand>(CommandType.EndTransformFeedback);
114              Register<SetAlphaTestCommand>(CommandType.SetAlphaTest);
115              Register<SetBlendStateAdvancedCommand>(CommandType.SetBlendStateAdvanced);
116              Register<SetBlendStateCommand>(CommandType.SetBlendState);
117              Register<SetDepthBiasCommand>(CommandType.SetDepthBias);
118              Register<SetDepthClampCommand>(CommandType.SetDepthClamp);
119              Register<SetDepthModeCommand>(CommandType.SetDepthMode);
120              Register<SetDepthTestCommand>(CommandType.SetDepthTest);
121              Register<SetFaceCullingCommand>(CommandType.SetFaceCulling);
122              Register<SetFrontFaceCommand>(CommandType.SetFrontFace);
123              Register<SetStorageBuffersCommand>(CommandType.SetStorageBuffers);
124              Register<SetTransformFeedbackBuffersCommand>(CommandType.SetTransformFeedbackBuffers);
125              Register<SetUniformBuffersCommand>(CommandType.SetUniformBuffers);
126              Register<SetImageCommand>(CommandType.SetImage);
127              Register<SetImageArrayCommand>(CommandType.SetImageArray);
128              Register<SetImageArraySeparateCommand>(CommandType.SetImageArraySeparate);
129              Register<SetIndexBufferCommand>(CommandType.SetIndexBuffer);
130              Register<SetLineParametersCommand>(CommandType.SetLineParameters);
131              Register<SetLogicOpStateCommand>(CommandType.SetLogicOpState);
132              Register<SetMultisampleStateCommand>(CommandType.SetMultisampleState);
133              Register<SetPatchParametersCommand>(CommandType.SetPatchParameters);
134              Register<SetPointParametersCommand>(CommandType.SetPointParameters);
135              Register<SetPolygonModeCommand>(CommandType.SetPolygonMode);
136              Register<SetPrimitiveRestartCommand>(CommandType.SetPrimitiveRestart);
137              Register<SetPrimitiveTopologyCommand>(CommandType.SetPrimitiveTopology);
138              Register<SetProgramCommand>(CommandType.SetProgram);
139              Register<SetRasterizerDiscardCommand>(CommandType.SetRasterizerDiscard);
140              Register<SetRenderTargetColorMasksCommand>(CommandType.SetRenderTargetColorMasks);
141              Register<SetRenderTargetsCommand>(CommandType.SetRenderTargets);
142              Register<SetScissorsCommand>(CommandType.SetScissor);
143              Register<SetStencilTestCommand>(CommandType.SetStencilTest);
144              Register<SetTextureAndSamplerCommand>(CommandType.SetTextureAndSampler);
145              Register<SetTextureArrayCommand>(CommandType.SetTextureArray);
146              Register<SetTextureArraySeparateCommand>(CommandType.SetTextureArraySeparate);
147              Register<SetUserClipDistanceCommand>(CommandType.SetUserClipDistance);
148              Register<SetVertexAttribsCommand>(CommandType.SetVertexAttribs);
149              Register<SetVertexBuffersCommand>(CommandType.SetVertexBuffers);
150              Register<SetViewportsCommand>(CommandType.SetViewports);
151              Register<TextureBarrierCommand>(CommandType.TextureBarrier);
152              Register<TextureBarrierTiledCommand>(CommandType.TextureBarrierTiled);
153              Register<TryHostConditionalRenderingCommand>(CommandType.TryHostConditionalRendering);
154              Register<TryHostConditionalRenderingFlushCommand>(CommandType.TryHostConditionalRenderingFlush);
155  
156              return maxCommandSize;
157          }
158  
159          [MethodImpl(MethodImplOptions.AggressiveInlining)]
160          public static void RunCommand(Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer)
161          {
162              _lookup[memory[^1]](memory, threaded, renderer);
163          }
164      }
165  }