/ src / Ryujinx.Graphics.GAL / Multithreading / ThreadedPipeline.cs
ThreadedPipeline.cs
  1  using Ryujinx.Graphics.GAL.Multithreading.Commands;
  2  using Ryujinx.Graphics.GAL.Multithreading.Model;
  3  using Ryujinx.Graphics.GAL.Multithreading.Resources;
  4  using Ryujinx.Graphics.Shader;
  5  using System;
  6  using System.Linq;
  7  
  8  namespace Ryujinx.Graphics.GAL.Multithreading
  9  {
 10      public class ThreadedPipeline : IPipeline
 11      {
 12          private readonly ThreadedRenderer _renderer;
 13  
 14          public ThreadedPipeline(ThreadedRenderer renderer)
 15          {
 16              _renderer = renderer;
 17          }
 18  
 19          private TableRef<T> Ref<T>(T reference)
 20          {
 21              return new TableRef<T>(_renderer, reference);
 22          }
 23  
 24          public void Barrier()
 25          {
 26              _renderer.New<BarrierCommand>();
 27              _renderer.QueueCommand();
 28          }
 29  
 30          public void BeginTransformFeedback(PrimitiveTopology topology)
 31          {
 32              _renderer.New<BeginTransformFeedbackCommand>().Set(topology);
 33              _renderer.QueueCommand();
 34          }
 35  
 36          public void ClearBuffer(BufferHandle destination, int offset, int size, uint value)
 37          {
 38              _renderer.New<ClearBufferCommand>().Set(destination, offset, size, value);
 39              _renderer.QueueCommand();
 40          }
 41  
 42          public void ClearRenderTargetColor(int index, int layer, int layerCount, uint componentMask, ColorF color)
 43          {
 44              _renderer.New<ClearRenderTargetColorCommand>().Set(index, layer, layerCount, componentMask, color);
 45              _renderer.QueueCommand();
 46          }
 47  
 48          public void ClearRenderTargetDepthStencil(int layer, int layerCount, float depthValue, bool depthMask, int stencilValue, int stencilMask)
 49          {
 50              _renderer.New<ClearRenderTargetDepthStencilCommand>().Set(layer, layerCount, depthValue, depthMask, stencilValue, stencilMask);
 51              _renderer.QueueCommand();
 52          }
 53  
 54          public void CommandBufferBarrier()
 55          {
 56              _renderer.New<CommandBufferBarrierCommand>();
 57              _renderer.QueueCommand();
 58          }
 59  
 60          public void CopyBuffer(BufferHandle source, BufferHandle destination, int srcOffset, int dstOffset, int size)
 61          {
 62              _renderer.New<CopyBufferCommand>().Set(source, destination, srcOffset, dstOffset, size);
 63              _renderer.QueueCommand();
 64          }
 65  
 66          public void DispatchCompute(int groupsX, int groupsY, int groupsZ)
 67          {
 68              _renderer.New<DispatchComputeCommand>().Set(groupsX, groupsY, groupsZ);
 69              _renderer.QueueCommand();
 70          }
 71  
 72          public void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance)
 73          {
 74              _renderer.New<DrawCommand>().Set(vertexCount, instanceCount, firstVertex, firstInstance);
 75              _renderer.QueueCommand();
 76          }
 77  
 78          public void DrawIndexed(int indexCount, int instanceCount, int firstIndex, int firstVertex, int firstInstance)
 79          {
 80              _renderer.New<DrawIndexedCommand>().Set(indexCount, instanceCount, firstIndex, firstVertex, firstInstance);
 81              _renderer.QueueCommand();
 82          }
 83  
 84          public void DrawIndexedIndirect(BufferRange indirectBuffer)
 85          {
 86              _renderer.New<DrawIndexedIndirectCommand>().Set(indirectBuffer);
 87              _renderer.QueueCommand();
 88          }
 89  
 90          public void DrawIndexedIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride)
 91          {
 92              _renderer.New<DrawIndexedIndirectCountCommand>().Set(indirectBuffer, parameterBuffer, maxDrawCount, stride);
 93              _renderer.QueueCommand();
 94          }
 95  
 96          public void DrawIndirect(BufferRange indirectBuffer)
 97          {
 98              _renderer.New<DrawIndirectCommand>().Set(indirectBuffer);
 99              _renderer.QueueCommand();
100          }
101  
102          public void DrawIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride)
103          {
104              _renderer.New<DrawIndirectCountCommand>().Set(indirectBuffer, parameterBuffer, maxDrawCount, stride);
105              _renderer.QueueCommand();
106          }
107  
108          public void DrawTexture(ITexture texture, ISampler sampler, Extents2DF srcRegion, Extents2DF dstRegion)
109          {
110              _renderer.New<DrawTextureCommand>().Set(Ref(texture), Ref(sampler), srcRegion, dstRegion);
111              _renderer.QueueCommand();
112          }
113  
114          public void EndHostConditionalRendering()
115          {
116              _renderer.New<EndHostConditionalRenderingCommand>();
117              _renderer.QueueCommand();
118          }
119  
120          public void EndTransformFeedback()
121          {
122              _renderer.New<EndTransformFeedbackCommand>();
123              _renderer.QueueCommand();
124          }
125  
126          public void SetAlphaTest(bool enable, float reference, CompareOp op)
127          {
128              _renderer.New<SetAlphaTestCommand>().Set(enable, reference, op);
129              _renderer.QueueCommand();
130          }
131  
132          public void SetBlendState(AdvancedBlendDescriptor blend)
133          {
134              _renderer.New<SetBlendStateAdvancedCommand>().Set(blend);
135              _renderer.QueueCommand();
136          }
137  
138          public void SetBlendState(int index, BlendDescriptor blend)
139          {
140              _renderer.New<SetBlendStateCommand>().Set(index, blend);
141              _renderer.QueueCommand();
142          }
143  
144          public void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp)
145          {
146              _renderer.New<SetDepthBiasCommand>().Set(enables, factor, units, clamp);
147              _renderer.QueueCommand();
148          }
149  
150          public void SetDepthClamp(bool clamp)
151          {
152              _renderer.New<SetDepthClampCommand>().Set(clamp);
153              _renderer.QueueCommand();
154          }
155  
156          public void SetDepthMode(DepthMode mode)
157          {
158              _renderer.New<SetDepthModeCommand>().Set(mode);
159              _renderer.QueueCommand();
160          }
161  
162          public void SetDepthTest(DepthTestDescriptor depthTest)
163          {
164              _renderer.New<SetDepthTestCommand>().Set(depthTest);
165              _renderer.QueueCommand();
166          }
167  
168          public void SetFaceCulling(bool enable, Face face)
169          {
170              _renderer.New<SetFaceCullingCommand>().Set(enable, face);
171              _renderer.QueueCommand();
172          }
173  
174          public void SetFrontFace(FrontFace frontFace)
175          {
176              _renderer.New<SetFrontFaceCommand>().Set(frontFace);
177              _renderer.QueueCommand();
178          }
179  
180          public void SetImage(ShaderStage stage, int binding, ITexture texture)
181          {
182              _renderer.New<SetImageCommand>().Set(stage, binding, Ref(texture));
183              _renderer.QueueCommand();
184          }
185  
186          public void SetImageArray(ShaderStage stage, int binding, IImageArray array)
187          {
188              _renderer.New<SetImageArrayCommand>().Set(stage, binding, Ref(array));
189              _renderer.QueueCommand();
190          }
191  
192          public void SetImageArraySeparate(ShaderStage stage, int setIndex, IImageArray array)
193          {
194              _renderer.New<SetImageArraySeparateCommand>().Set(stage, setIndex, Ref(array));
195              _renderer.QueueCommand();
196          }
197  
198          public void SetIndexBuffer(BufferRange buffer, IndexType type)
199          {
200              _renderer.New<SetIndexBufferCommand>().Set(buffer, type);
201              _renderer.QueueCommand();
202          }
203  
204          public void SetLineParameters(float width, bool smooth)
205          {
206              _renderer.New<SetLineParametersCommand>().Set(width, smooth);
207              _renderer.QueueCommand();
208          }
209  
210          public void SetLogicOpState(bool enable, LogicalOp op)
211          {
212              _renderer.New<SetLogicOpStateCommand>().Set(enable, op);
213              _renderer.QueueCommand();
214          }
215  
216          public void SetMultisampleState(MultisampleDescriptor multisample)
217          {
218              _renderer.New<SetMultisampleStateCommand>().Set(multisample);
219              _renderer.QueueCommand();
220          }
221  
222          public void SetPatchParameters(int vertices, ReadOnlySpan<float> defaultOuterLevel, ReadOnlySpan<float> defaultInnerLevel)
223          {
224              _renderer.New<SetPatchParametersCommand>().Set(vertices, defaultOuterLevel, defaultInnerLevel);
225              _renderer.QueueCommand();
226          }
227  
228          public void SetPointParameters(float size, bool isProgramPointSize, bool enablePointSprite, Origin origin)
229          {
230              _renderer.New<SetPointParametersCommand>().Set(size, isProgramPointSize, enablePointSprite, origin);
231              _renderer.QueueCommand();
232          }
233  
234          public void SetPolygonMode(PolygonMode frontMode, PolygonMode backMode)
235          {
236              _renderer.New<SetPolygonModeCommand>().Set(frontMode, backMode);
237              _renderer.QueueCommand();
238          }
239  
240          public void SetPrimitiveRestart(bool enable, int index)
241          {
242              _renderer.New<SetPrimitiveRestartCommand>().Set(enable, index);
243              _renderer.QueueCommand();
244          }
245  
246          public void SetPrimitiveTopology(PrimitiveTopology topology)
247          {
248              _renderer.New<SetPrimitiveTopologyCommand>().Set(topology);
249              _renderer.QueueCommand();
250          }
251  
252          public void SetProgram(IProgram program)
253          {
254              _renderer.New<SetProgramCommand>().Set(Ref(program));
255              _renderer.QueueCommand();
256          }
257  
258          public void SetRasterizerDiscard(bool discard)
259          {
260              _renderer.New<SetRasterizerDiscardCommand>().Set(discard);
261              _renderer.QueueCommand();
262          }
263  
264          public void SetRenderTargetColorMasks(ReadOnlySpan<uint> componentMask)
265          {
266              _renderer.New<SetRenderTargetColorMasksCommand>().Set(_renderer.CopySpan(componentMask));
267              _renderer.QueueCommand();
268          }
269  
270          public void SetRenderTargets(ITexture[] colors, ITexture depthStencil)
271          {
272              _renderer.New<SetRenderTargetsCommand>().Set(Ref(colors.ToArray()), Ref(depthStencil));
273              _renderer.QueueCommand();
274          }
275  
276          public void SetScissors(ReadOnlySpan<Rectangle<int>> scissors)
277          {
278              _renderer.New<SetScissorsCommand>().Set(_renderer.CopySpan(scissors));
279              _renderer.QueueCommand();
280          }
281  
282          public void SetStencilTest(StencilTestDescriptor stencilTest)
283          {
284              _renderer.New<SetStencilTestCommand>().Set(stencilTest);
285              _renderer.QueueCommand();
286          }
287  
288          public void SetStorageBuffers(ReadOnlySpan<BufferAssignment> buffers)
289          {
290              _renderer.New<SetStorageBuffersCommand>().Set(_renderer.CopySpan(buffers));
291              _renderer.QueueCommand();
292          }
293  
294          public void SetTextureAndSampler(ShaderStage stage, int binding, ITexture texture, ISampler sampler)
295          {
296              _renderer.New<SetTextureAndSamplerCommand>().Set(stage, binding, Ref(texture), Ref(sampler));
297              _renderer.QueueCommand();
298          }
299  
300          public void SetTextureArray(ShaderStage stage, int binding, ITextureArray array)
301          {
302              _renderer.New<SetTextureArrayCommand>().Set(stage, binding, Ref(array));
303              _renderer.QueueCommand();
304          }
305  
306          public void SetTextureArraySeparate(ShaderStage stage, int setIndex, ITextureArray array)
307          {
308              _renderer.New<SetTextureArraySeparateCommand>().Set(stage, setIndex, Ref(array));
309              _renderer.QueueCommand();
310          }
311  
312          public void SetTransformFeedbackBuffers(ReadOnlySpan<BufferRange> buffers)
313          {
314              _renderer.New<SetTransformFeedbackBuffersCommand>().Set(_renderer.CopySpan(buffers));
315              _renderer.QueueCommand();
316          }
317  
318          public void SetUniformBuffers(ReadOnlySpan<BufferAssignment> buffers)
319          {
320              _renderer.New<SetUniformBuffersCommand>().Set(_renderer.CopySpan(buffers));
321              _renderer.QueueCommand();
322          }
323  
324          public void SetUserClipDistance(int index, bool enableClip)
325          {
326              _renderer.New<SetUserClipDistanceCommand>().Set(index, enableClip);
327              _renderer.QueueCommand();
328          }
329  
330          public void SetVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs)
331          {
332              _renderer.New<SetVertexAttribsCommand>().Set(_renderer.CopySpan(vertexAttribs));
333              _renderer.QueueCommand();
334          }
335  
336          public void SetVertexBuffers(ReadOnlySpan<VertexBufferDescriptor> vertexBuffers)
337          {
338              _renderer.New<SetVertexBuffersCommand>().Set(_renderer.CopySpan(vertexBuffers));
339              _renderer.QueueCommand();
340          }
341  
342          public void SetViewports(ReadOnlySpan<Viewport> viewports)
343          {
344              _renderer.New<SetViewportsCommand>().Set(_renderer.CopySpan(viewports));
345              _renderer.QueueCommand();
346          }
347  
348          public void TextureBarrier()
349          {
350              _renderer.New<TextureBarrierCommand>();
351              _renderer.QueueCommand();
352          }
353  
354          public void TextureBarrierTiled()
355          {
356              _renderer.New<TextureBarrierTiledCommand>();
357              _renderer.QueueCommand();
358          }
359  
360          public bool TryHostConditionalRendering(ICounterEvent value, ulong compare, bool isEqual)
361          {
362              var evt = value as ThreadedCounterEvent;
363              if (evt != null)
364              {
365                  if (compare == 0 && evt.Type == CounterType.SamplesPassed && evt.ClearCounter)
366                  {
367                      if (!evt.ReserveForHostAccess())
368                      {
369                          return false;
370                      }
371  
372                      _renderer.New<TryHostConditionalRenderingCommand>().Set(Ref(evt), compare, isEqual);
373                      _renderer.QueueCommand();
374                      return true;
375                  }
376              }
377  
378              _renderer.New<TryHostConditionalRenderingFlushCommand>().Set(Ref(evt), Ref<ThreadedCounterEvent>(null), isEqual);
379              _renderer.QueueCommand();
380              return false;
381          }
382  
383          public bool TryHostConditionalRendering(ICounterEvent value, ICounterEvent compare, bool isEqual)
384          {
385              _renderer.New<TryHostConditionalRenderingFlushCommand>().Set(Ref(value as ThreadedCounterEvent), Ref(compare as ThreadedCounterEvent), isEqual);
386              _renderer.QueueCommand();
387              return false;
388          }
389      }
390  }