diff --git a/sources/engine/Stride.Graphics/IndirectDrawingArgs.cs b/sources/engine/Stride.Graphics/IndirectDrawingArgs.cs new file mode 100644 index 0000000000..f09269b5b6 --- /dev/null +++ b/sources/engine/Stride.Graphics/IndirectDrawingArgs.cs @@ -0,0 +1,33 @@ +// Copyright (c) Stride contributors (https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using System; +using Stride.Core.Serialization; +using Stride.Core.Serialization.Serializers; + +namespace Stride.Graphics +{ + public class IndirectDrawingArgs + { + /// + /// Creates an instance of for DrawAuto with a stream-out vertex buffer. + /// + public IndirectDrawingArgs() + { + DrawAuto = true; + } + + /// + /// Creates an instance of for DrawIndirect with a buffer containing the draw arguments. + /// + public IndirectDrawingArgs(Buffer argumentBuffer, int alignedByteOffset = 0) + { + if (argumentBuffer == null) throw new ArgumentNullException("argmentBuffer"); + ArgumentBuffer = argumentBuffer; + AlignedByteOffset = alignedByteOffset; + } + + public readonly bool DrawAuto; + public readonly Buffer ArgumentBuffer; + public readonly int AlignedByteOffset; + } +} diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/MaterialRenderFeature.cs b/sources/engine/Stride.Rendering/Rendering/Materials/MaterialRenderFeature.cs index 7c28fe83d1..cf0ffdd329 100644 --- a/sources/engine/Stride.Rendering/Rendering/Materials/MaterialRenderFeature.cs +++ b/sources/engine/Stride.Rendering/Rendering/Materials/MaterialRenderFeature.cs @@ -136,11 +136,12 @@ public override void PrepareEffectPermutations(RenderDrawContext context) var oldMeshDraw = renderMesh.ActiveMeshDraw; tessellationMeshDraw = new MeshDraw { - VertexBuffers = oldMeshDraw.VertexBuffers, - IndexBuffer = oldMeshDraw.IndexBuffer, + PrimitiveType = tessellationState.Method.GetPrimitiveType(), DrawCount = oldMeshDraw.DrawCount, StartLocation = oldMeshDraw.StartLocation, - PrimitiveType = tessellationState.Method.GetPrimitiveType(), + VertexBuffers = oldMeshDraw.VertexBuffers, + IndexBuffer = oldMeshDraw.IndexBuffer, + IndirectDrawing = oldMeshDraw.IndirectDrawing, }; // adapt the primitive type and index buffer to the tessellation used diff --git a/sources/engine/Stride.Rendering/Rendering/MeshDraw.cs b/sources/engine/Stride.Rendering/Rendering/MeshDraw.cs index 034d202d6e..25a5a7e48d 100644 --- a/sources/engine/Stride.Rendering/Rendering/MeshDraw.cs +++ b/sources/engine/Stride.Rendering/Rendering/MeshDraw.cs @@ -19,5 +19,8 @@ public class MeshDraw public VertexBufferBinding[] VertexBuffers; public IndexBufferBinding IndexBuffer; + + [DataMemberIgnore] + public IndirectDrawingArgs IndirectDrawing; } } diff --git a/sources/engine/Stride.Rendering/Rendering/MeshRenderFeature.cs b/sources/engine/Stride.Rendering/Rendering/MeshRenderFeature.cs index 44c9d4d4f3..8ec0995821 100644 --- a/sources/engine/Stride.Rendering/Rendering/MeshRenderFeature.cs +++ b/sources/engine/Stride.Rendering/Rendering/MeshRenderFeature.cs @@ -215,19 +215,47 @@ public override void Draw(RenderDrawContext context, RenderView renderView, Rend commandList.SetDescriptorSets(0, descriptorSetsLocal); // Draw - if (drawData.IndexBuffer == null) + if (drawData.IndexBuffer is null) { - if (renderMesh.InstanceCount > 0) - commandList.DrawInstanced(drawData.DrawCount, renderMesh.InstanceCount, drawData.StartLocation); - else - commandList.Draw(drawData.DrawCount, drawData.StartLocation); + if (drawData.IndirectDrawing is null) //direct drawing + { + if (renderMesh.InstanceCount > 0) + commandList.DrawInstanced(drawData.DrawCount, renderMesh.InstanceCount, drawData.StartLocation); + else + commandList.Draw(drawData.DrawCount, drawData.StartLocation); + } + else // indirect drawing + { + if (drawData.IndirectDrawing.DrawAuto) + { + commandList.DrawAuto(); + } + else + { + commandList.DrawInstanced(drawData.IndirectDrawing.ArgumentBuffer, drawData.IndirectDrawing.AlignedByteOffset); + } + } } else { - if (renderMesh.InstanceCount > 0) - commandList.DrawIndexedInstanced(drawData.DrawCount, renderMesh.InstanceCount, drawData.StartLocation); - else - commandList.DrawIndexed(drawData.DrawCount, drawData.StartLocation); + if (drawData.IndirectDrawing is null) //direct drawing + { + if (renderMesh.InstanceCount > 0) + commandList.DrawIndexedInstanced(drawData.DrawCount, renderMesh.InstanceCount, drawData.StartLocation); + else + commandList.DrawIndexed(drawData.DrawCount, drawData.StartLocation); + } + else // indirect drawing + { + if (drawData.IndirectDrawing.DrawAuto) + { + // throw exception? DrawAuto should not have an index buffer, as it always comes from the stream out stage + } + else + { + commandList.DrawIndexedInstanced(drawData.IndirectDrawing.ArgumentBuffer, drawData.IndirectDrawing.AlignedByteOffset); + } + } } } }