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);
+ }
+ }
}
}
}