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 }