CommandHelper.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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.Program;
  5. using Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer;
  6. using Ryujinx.Graphics.GAL.Multithreading.Commands.Sampler;
  7. using Ryujinx.Graphics.GAL.Multithreading.Commands.Texture;
  8. using Ryujinx.Graphics.GAL.Multithreading.Commands.Window;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Linq;
  12. using System.Reflection;
  13. using System.Runtime.CompilerServices;
  14. using System.Runtime.InteropServices;
  15. namespace Ryujinx.Graphics.GAL.Multithreading
  16. {
  17. static class CommandHelper
  18. {
  19. private delegate void CommandDelegate(Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer);
  20. private static int _totalCommands = (int)Enum.GetValues<CommandType>().Max() + 1;
  21. private static CommandDelegate[] _lookup = new CommandDelegate[_totalCommands];
  22. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  23. private static ref T GetCommand<T>(Span<byte> memory)
  24. {
  25. return ref Unsafe.As<byte, T>(ref MemoryMarshal.GetReference(memory));
  26. }
  27. public static int GetMaxCommandSize()
  28. {
  29. Assembly assembly = typeof(CommandHelper).Assembly;
  30. IEnumerable<Type> commands = assembly.GetTypes().Where(type => typeof(IGALCommand).IsAssignableFrom(type) && type.IsValueType);
  31. int maxSize = commands.Max(command =>
  32. {
  33. MethodInfo method = typeof(Unsafe).GetMethod(nameof(Unsafe.SizeOf));
  34. MethodInfo generic = method.MakeGenericMethod(command);
  35. int size = (int)generic.Invoke(null, null);
  36. return size;
  37. });
  38. InitLookup();
  39. return maxSize + 1; // 1 byte reserved for command size.
  40. }
  41. private static void InitLookup()
  42. {
  43. _lookup[(int)CommandType.Action] = (memory, threaded, renderer) =>
  44. ActionCommand.Run(ref GetCommand<ActionCommand>(memory), threaded, renderer);
  45. _lookup[(int)CommandType.CreateBuffer] = (memory, threaded, renderer) =>
  46. CreateBufferCommand.Run(ref GetCommand<CreateBufferCommand>(memory), threaded, renderer);
  47. _lookup[(int)CommandType.CreateProgram] = (memory, threaded, renderer) =>
  48. CreateProgramCommand.Run(ref GetCommand<CreateProgramCommand>(memory), threaded, renderer);
  49. _lookup[(int)CommandType.CreateSampler] = (memory, threaded, renderer) =>
  50. CreateSamplerCommand.Run(ref GetCommand<CreateSamplerCommand>(memory), threaded, renderer);
  51. _lookup[(int)CommandType.CreateSync] = (memory, threaded, renderer) =>
  52. CreateSyncCommand.Run(ref GetCommand<CreateSyncCommand>(memory), threaded, renderer);
  53. _lookup[(int)CommandType.CreateTexture] = (memory, threaded, renderer) =>
  54. CreateTextureCommand.Run(ref GetCommand<CreateTextureCommand>(memory), threaded, renderer);
  55. _lookup[(int)CommandType.GetCapabilities] = (memory, threaded, renderer) =>
  56. GetCapabilitiesCommand.Run(ref GetCommand<GetCapabilitiesCommand>(memory), threaded, renderer);
  57. _lookup[(int)CommandType.PreFrame] = (memory, threaded, renderer) =>
  58. PreFrameCommand.Run(ref GetCommand<PreFrameCommand>(memory), threaded, renderer);
  59. _lookup[(int)CommandType.ReportCounter] = (memory, threaded, renderer) =>
  60. ReportCounterCommand.Run(ref GetCommand<ReportCounterCommand>(memory), threaded, renderer);
  61. _lookup[(int)CommandType.ResetCounter] = (memory, threaded, renderer) =>
  62. ResetCounterCommand.Run(ref GetCommand<ResetCounterCommand>(memory), threaded, renderer);
  63. _lookup[(int)CommandType.UpdateCounters] = (memory, threaded, renderer) =>
  64. UpdateCountersCommand.Run(ref GetCommand<UpdateCountersCommand>(memory), threaded, renderer);
  65. _lookup[(int)CommandType.BufferDispose] = (memory, threaded, renderer) =>
  66. BufferDisposeCommand.Run(ref GetCommand<BufferDisposeCommand>(memory), threaded, renderer);
  67. _lookup[(int)CommandType.BufferGetData] = (memory, threaded, renderer) =>
  68. BufferGetDataCommand.Run(ref GetCommand<BufferGetDataCommand>(memory), threaded, renderer);
  69. _lookup[(int)CommandType.BufferSetData] = (memory, threaded, renderer) =>
  70. BufferSetDataCommand.Run(ref GetCommand<BufferSetDataCommand>(memory), threaded, renderer);
  71. _lookup[(int)CommandType.CounterEventDispose] = (memory, threaded, renderer) =>
  72. CounterEventDisposeCommand.Run(ref GetCommand<CounterEventDisposeCommand>(memory), threaded, renderer);
  73. _lookup[(int)CommandType.CounterEventFlush] = (memory, threaded, renderer) =>
  74. CounterEventFlushCommand.Run(ref GetCommand<CounterEventFlushCommand>(memory), threaded, renderer);
  75. _lookup[(int)CommandType.ProgramDispose] = (memory, threaded, renderer) =>
  76. ProgramDisposeCommand.Run(ref GetCommand<ProgramDisposeCommand>(memory), threaded, renderer);
  77. _lookup[(int)CommandType.ProgramGetBinary] = (memory, threaded, renderer) =>
  78. ProgramGetBinaryCommand.Run(ref GetCommand<ProgramGetBinaryCommand>(memory), threaded, renderer);
  79. _lookup[(int)CommandType.ProgramCheckLink] = (memory, threaded, renderer) =>
  80. ProgramCheckLinkCommand.Run(ref GetCommand<ProgramCheckLinkCommand>(memory), threaded, renderer);
  81. _lookup[(int)CommandType.SamplerDispose] = (memory, threaded, renderer) =>
  82. SamplerDisposeCommand.Run(ref GetCommand<SamplerDisposeCommand>(memory), threaded, renderer);
  83. _lookup[(int)CommandType.TextureCopyTo] = (memory, threaded, renderer) =>
  84. TextureCopyToCommand.Run(ref GetCommand<TextureCopyToCommand>(memory), threaded, renderer);
  85. _lookup[(int)CommandType.TextureCopyToScaled] = (memory, threaded, renderer) =>
  86. TextureCopyToScaledCommand.Run(ref GetCommand<TextureCopyToScaledCommand>(memory), threaded, renderer);
  87. _lookup[(int)CommandType.TextureCopyToSlice] = (memory, threaded, renderer) =>
  88. TextureCopyToSliceCommand.Run(ref GetCommand<TextureCopyToSliceCommand>(memory), threaded, renderer);
  89. _lookup[(int)CommandType.TextureCreateView] = (memory, threaded, renderer) =>
  90. TextureCreateViewCommand.Run(ref GetCommand<TextureCreateViewCommand>(memory), threaded, renderer);
  91. _lookup[(int)CommandType.TextureGetData] = (memory, threaded, renderer) =>
  92. TextureGetDataCommand.Run(ref GetCommand<TextureGetDataCommand>(memory), threaded, renderer);
  93. _lookup[(int)CommandType.TextureGetDataSlice] = (memory, threaded, renderer) =>
  94. TextureGetDataSliceCommand.Run(ref GetCommand<TextureGetDataSliceCommand>(memory), threaded, renderer);
  95. _lookup[(int)CommandType.TextureRelease] = (memory, threaded, renderer) =>
  96. TextureReleaseCommand.Run(ref GetCommand<TextureReleaseCommand>(memory), threaded, renderer);
  97. _lookup[(int)CommandType.TextureSetData] = (memory, threaded, renderer) =>
  98. TextureSetDataCommand.Run(ref GetCommand<TextureSetDataCommand>(memory), threaded, renderer);
  99. _lookup[(int)CommandType.TextureSetDataSlice] = (memory, threaded, renderer) =>
  100. TextureSetDataSliceCommand.Run(ref GetCommand<TextureSetDataSliceCommand>(memory), threaded, renderer);
  101. _lookup[(int)CommandType.TextureSetDataSliceRegion] = (memory, threaded, renderer) =>
  102. TextureSetDataSliceRegionCommand.Run(ref GetCommand<TextureSetDataSliceRegionCommand>(memory), threaded, renderer);
  103. _lookup[(int)CommandType.TextureSetStorage] = (memory, threaded, renderer) =>
  104. TextureSetStorageCommand.Run(ref GetCommand<TextureSetStorageCommand>(memory), threaded, renderer);
  105. _lookup[(int)CommandType.WindowPresent] = (memory, threaded, renderer) =>
  106. WindowPresentCommand.Run(ref GetCommand<WindowPresentCommand>(memory), threaded, renderer);
  107. _lookup[(int)CommandType.Barrier] = (memory, threaded, renderer) =>
  108. BarrierCommand.Run(ref GetCommand<BarrierCommand>(memory), threaded, renderer);
  109. _lookup[(int)CommandType.BeginTransformFeedback] = (memory, threaded, renderer) =>
  110. BeginTransformFeedbackCommand.Run(ref GetCommand<BeginTransformFeedbackCommand>(memory), threaded, renderer);
  111. _lookup[(int)CommandType.ClearBuffer] = (memory, threaded, renderer) =>
  112. ClearBufferCommand.Run(ref GetCommand<ClearBufferCommand>(memory), threaded, renderer);
  113. _lookup[(int)CommandType.ClearRenderTargetColor] = (memory, threaded, renderer) =>
  114. ClearRenderTargetColorCommand.Run(ref GetCommand<ClearRenderTargetColorCommand>(memory), threaded, renderer);
  115. _lookup[(int)CommandType.ClearRenderTargetDepthStencil] = (memory, threaded, renderer) =>
  116. ClearRenderTargetDepthStencilCommand.Run(ref GetCommand<ClearRenderTargetDepthStencilCommand>(memory), threaded, renderer);
  117. _lookup[(int)CommandType.CommandBufferBarrier] = (memory, threaded, renderer) =>
  118. CommandBufferBarrierCommand.Run(ref GetCommand<CommandBufferBarrierCommand>(memory), threaded, renderer);
  119. _lookup[(int)CommandType.CopyBuffer] = (memory, threaded, renderer) =>
  120. CopyBufferCommand.Run(ref GetCommand<CopyBufferCommand>(memory), threaded, renderer);
  121. _lookup[(int)CommandType.DispatchCompute] = (memory, threaded, renderer) =>
  122. DispatchComputeCommand.Run(ref GetCommand<DispatchComputeCommand>(memory), threaded, renderer);
  123. _lookup[(int)CommandType.Draw] = (memory, threaded, renderer) =>
  124. DrawCommand.Run(ref GetCommand<DrawCommand>(memory), threaded, renderer);
  125. _lookup[(int)CommandType.DrawIndexed] = (memory, threaded, renderer) =>
  126. DrawIndexedCommand.Run(ref GetCommand<DrawIndexedCommand>(memory), threaded, renderer);
  127. _lookup[(int)CommandType.DrawIndexedIndirect] = (memory, threaded, renderer) =>
  128. DrawIndexedIndirectCommand.Run(ref GetCommand<DrawIndexedIndirectCommand>(memory), threaded, renderer);
  129. _lookup[(int)CommandType.DrawIndexedIndirectCount] = (memory, threaded, renderer) =>
  130. DrawIndexedIndirectCountCommand.Run(ref GetCommand<DrawIndexedIndirectCountCommand>(memory), threaded, renderer);
  131. _lookup[(int)CommandType.DrawIndirect] = (memory, threaded, renderer) =>
  132. DrawIndirectCommand.Run(ref GetCommand<DrawIndirectCommand>(memory), threaded, renderer);
  133. _lookup[(int)CommandType.DrawIndirectCount] = (memory, threaded, renderer) =>
  134. DrawIndirectCountCommand.Run(ref GetCommand<DrawIndirectCountCommand>(memory), threaded, renderer);
  135. _lookup[(int)CommandType.DrawTexture] = (memory, threaded, renderer) =>
  136. DrawTextureCommand.Run(ref GetCommand<DrawTextureCommand>(memory), threaded, renderer);
  137. _lookup[(int)CommandType.EndHostConditionalRendering] = (memory, threaded, renderer) =>
  138. EndHostConditionalRenderingCommand.Run(renderer);
  139. _lookup[(int)CommandType.EndTransformFeedback] = (memory, threaded, renderer) =>
  140. EndTransformFeedbackCommand.Run(ref GetCommand<EndTransformFeedbackCommand>(memory), threaded, renderer);
  141. _lookup[(int)CommandType.SetAlphaTest] = (memory, threaded, renderer) =>
  142. SetAlphaTestCommand.Run(ref GetCommand<SetAlphaTestCommand>(memory), threaded, renderer);
  143. _lookup[(int)CommandType.SetBlendState] = (memory, threaded, renderer) =>
  144. SetBlendStateCommand.Run(ref GetCommand<SetBlendStateCommand>(memory), threaded, renderer);
  145. _lookup[(int)CommandType.SetDepthBias] = (memory, threaded, renderer) =>
  146. SetDepthBiasCommand.Run(ref GetCommand<SetDepthBiasCommand>(memory), threaded, renderer);
  147. _lookup[(int)CommandType.SetDepthClamp] = (memory, threaded, renderer) =>
  148. SetDepthClampCommand.Run(ref GetCommand<SetDepthClampCommand>(memory), threaded, renderer);
  149. _lookup[(int)CommandType.SetDepthMode] = (memory, threaded, renderer) =>
  150. SetDepthModeCommand.Run(ref GetCommand<SetDepthModeCommand>(memory), threaded, renderer);
  151. _lookup[(int)CommandType.SetDepthTest] = (memory, threaded, renderer) =>
  152. SetDepthTestCommand.Run(ref GetCommand<SetDepthTestCommand>(memory), threaded, renderer);
  153. _lookup[(int)CommandType.SetFaceCulling] = (memory, threaded, renderer) =>
  154. SetFaceCullingCommand.Run(ref GetCommand<SetFaceCullingCommand>(memory), threaded, renderer);
  155. _lookup[(int)CommandType.SetFrontFace] = (memory, threaded, renderer) =>
  156. SetFrontFaceCommand.Run(ref GetCommand<SetFrontFaceCommand>(memory), threaded, renderer);
  157. _lookup[(int)CommandType.SetStorageBuffers] = (memory, threaded, renderer) =>
  158. SetStorageBuffersCommand.Run(ref GetCommand<SetStorageBuffersCommand>(memory), threaded, renderer);
  159. _lookup[(int)CommandType.SetTransformFeedbackBuffers] = (memory, threaded, renderer) =>
  160. SetTransformFeedbackBuffersCommand.Run(ref GetCommand<SetTransformFeedbackBuffersCommand>(memory), threaded, renderer);
  161. _lookup[(int)CommandType.SetUniformBuffers] = (memory, threaded, renderer) =>
  162. SetUniformBuffersCommand.Run(ref GetCommand<SetUniformBuffersCommand>(memory), threaded, renderer);
  163. _lookup[(int)CommandType.SetImage] = (memory, threaded, renderer) =>
  164. SetImageCommand.Run(ref GetCommand<SetImageCommand>(memory), threaded, renderer);
  165. _lookup[(int)CommandType.SetIndexBuffer] = (memory, threaded, renderer) =>
  166. SetIndexBufferCommand.Run(ref GetCommand<SetIndexBufferCommand>(memory), threaded, renderer);
  167. _lookup[(int)CommandType.SetLineParameters] = (memory, threaded, renderer) =>
  168. SetLineParametersCommand.Run(ref GetCommand<SetLineParametersCommand>(memory), threaded, renderer);
  169. _lookup[(int)CommandType.SetLogicOpState] = (memory, threaded, renderer) =>
  170. SetLogicOpStateCommand.Run(ref GetCommand<SetLogicOpStateCommand>(memory), threaded, renderer);
  171. _lookup[(int)CommandType.SetMultisampleState] = (memory, threaded, renderer) =>
  172. SetMultisampleStateCommand.Run(ref GetCommand<SetMultisampleStateCommand>(memory), threaded, renderer);
  173. _lookup[(int)CommandType.SetPatchParameters] = (memory, threaded, renderer) =>
  174. SetPatchParametersCommand.Run(ref GetCommand<SetPatchParametersCommand>(memory), threaded, renderer);
  175. _lookup[(int)CommandType.SetPointParameters] = (memory, threaded, renderer) =>
  176. SetPointParametersCommand.Run(ref GetCommand<SetPointParametersCommand>(memory), threaded, renderer);
  177. _lookup[(int)CommandType.SetPolygonMode] = (memory, threaded, renderer) =>
  178. SetPolygonModeCommand.Run(ref GetCommand<SetPolygonModeCommand>(memory), threaded, renderer);
  179. _lookup[(int)CommandType.SetPrimitiveRestart] = (memory, threaded, renderer) =>
  180. SetPrimitiveRestartCommand.Run(ref GetCommand<SetPrimitiveRestartCommand>(memory), threaded, renderer);
  181. _lookup[(int)CommandType.SetPrimitiveTopology] = (memory, threaded, renderer) =>
  182. SetPrimitiveTopologyCommand.Run(ref GetCommand<SetPrimitiveTopologyCommand>(memory), threaded, renderer);
  183. _lookup[(int)CommandType.SetProgram] = (memory, threaded, renderer) =>
  184. SetProgramCommand.Run(ref GetCommand<SetProgramCommand>(memory), threaded, renderer);
  185. _lookup[(int)CommandType.SetRasterizerDiscard] = (memory, threaded, renderer) =>
  186. SetRasterizerDiscardCommand.Run(ref GetCommand<SetRasterizerDiscardCommand>(memory), threaded, renderer);
  187. _lookup[(int)CommandType.SetRenderTargetColorMasks] = (memory, threaded, renderer) =>
  188. SetRenderTargetColorMasksCommand.Run(ref GetCommand<SetRenderTargetColorMasksCommand>(memory), threaded, renderer);
  189. _lookup[(int)CommandType.SetRenderTargetScale] = (memory, threaded, renderer) =>
  190. SetRenderTargetScaleCommand.Run(ref GetCommand<SetRenderTargetScaleCommand>(memory), threaded, renderer);
  191. _lookup[(int)CommandType.SetRenderTargets] = (memory, threaded, renderer) =>
  192. SetRenderTargetsCommand.Run(ref GetCommand<SetRenderTargetsCommand>(memory), threaded, renderer);
  193. _lookup[(int)CommandType.SetScissor] = (memory, threaded, renderer) =>
  194. SetScissorsCommand.Run(ref GetCommand<SetScissorsCommand>(memory), threaded, renderer);
  195. _lookup[(int)CommandType.SetStencilTest] = (memory, threaded, renderer) =>
  196. SetStencilTestCommand.Run(ref GetCommand<SetStencilTestCommand>(memory), threaded, renderer);
  197. _lookup[(int)CommandType.SetTextureAndSampler] = (memory, threaded, renderer) =>
  198. SetTextureAndSamplerCommand.Run(ref GetCommand<SetTextureAndSamplerCommand>(memory), threaded, renderer);
  199. _lookup[(int)CommandType.SetUserClipDistance] = (memory, threaded, renderer) =>
  200. SetUserClipDistanceCommand.Run(ref GetCommand<SetUserClipDistanceCommand>(memory), threaded, renderer);
  201. _lookup[(int)CommandType.SetVertexAttribs] = (memory, threaded, renderer) =>
  202. SetVertexAttribsCommand.Run(ref GetCommand<SetVertexAttribsCommand>(memory), threaded, renderer);
  203. _lookup[(int)CommandType.SetVertexBuffers] = (memory, threaded, renderer) =>
  204. SetVertexBuffersCommand.Run(ref GetCommand<SetVertexBuffersCommand>(memory), threaded, renderer);
  205. _lookup[(int)CommandType.SetViewports] = (memory, threaded, renderer) =>
  206. SetViewportsCommand.Run(ref GetCommand<SetViewportsCommand>(memory), threaded, renderer);
  207. _lookup[(int)CommandType.TextureBarrier] = (memory, threaded, renderer) =>
  208. TextureBarrierCommand.Run(ref GetCommand<TextureBarrierCommand>(memory), threaded, renderer);
  209. _lookup[(int)CommandType.TextureBarrierTiled] = (memory, threaded, renderer) =>
  210. TextureBarrierTiledCommand.Run(ref GetCommand<TextureBarrierTiledCommand>(memory), threaded, renderer);
  211. _lookup[(int)CommandType.TryHostConditionalRendering] = (memory, threaded, renderer) =>
  212. TryHostConditionalRenderingCommand.Run(ref GetCommand<TryHostConditionalRenderingCommand>(memory), threaded, renderer);
  213. _lookup[(int)CommandType.TryHostConditionalRenderingFlush] = (memory, threaded, renderer) =>
  214. TryHostConditionalRenderingFlushCommand.Run(ref GetCommand<TryHostConditionalRenderingFlushCommand>(memory), threaded, renderer);
  215. _lookup[(int)CommandType.UpdateRenderScale] = (memory, threaded, renderer) =>
  216. UpdateRenderScaleCommand.Run(ref GetCommand<UpdateRenderScaleCommand>(memory), threaded, renderer);
  217. }
  218. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  219. public static void RunCommand(Span<byte> memory, ThreadedRenderer threaded, IRenderer renderer)
  220. {
  221. _lookup[memory[memory.Length - 1]](memory, threaded, renderer);
  222. }
  223. }
  224. }