Skip to content

Commit dd7ff88

Browse files
committed
Add multi draw indirect draw calls (#6392)
# Objective - Allows bevy users to dispatch `multi_draw_indirect`, `multi_draw_indexed_indirect`, `multi_draw_indirect_count`, `multi_draw_indexed_indirect_count` draw calls. - Fixes #6216 ## Solution - Added the corresponding wrapper methods to `TrackedRenderPass` --- ## Changelog > Added `multi_draw_*` draw calls to `TrackedRenderPass` Co-authored-by: Zhixing Zhang <me@neoto.xin>
1 parent 306c1ac commit dd7ff88

File tree

1 file changed

+160
-0
lines changed

1 file changed

+160
-0
lines changed

crates/bevy_render/src/render_phase/draw_state.rs

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,166 @@ impl<'a> TrackedRenderPass<'a> {
283283
.draw_indexed_indirect(indirect_buffer, indirect_offset);
284284
}
285285

286+
/// Dispatches multiple draw calls from the active vertex buffer(s) based on the contents of the `indirect_buffer`.
287+
/// `count` draw calls are issued.
288+
///
289+
/// The active vertex buffers can be set with [`TrackedRenderPass::set_vertex_buffer`].
290+
///
291+
/// `indirect_buffer` should contain `count` tightly packed elements of the following structure:
292+
///
293+
/// ```rust
294+
/// #[repr(C)]
295+
/// struct DrawIndirect {
296+
/// vertex_count: u32, // The number of vertices to draw.
297+
/// instance_count: u32, // The number of instances to draw.
298+
/// first_vertex: u32, // The Index of the first vertex to draw.
299+
/// first_instance: u32, // The instance ID of the first instance to draw.
300+
/// // has to be 0, unless [`Features::INDIRECT_FIRST_INSTANCE`] is enabled.
301+
/// }
302+
/// ```
303+
pub fn multi_draw_indirect(
304+
&mut self,
305+
indirect_buffer: &'a Buffer,
306+
indirect_offset: u64,
307+
count: u32,
308+
) {
309+
trace!(
310+
"multi draw indirect: {:?} {}, {}x",
311+
indirect_buffer,
312+
indirect_offset,
313+
count
314+
);
315+
self.pass
316+
.multi_draw_indirect(indirect_buffer, indirect_offset, count);
317+
}
318+
319+
/// Dispatches multiple draw calls from the active vertex buffer(s) based on the contents of the `indirect_buffer`.
320+
/// The count buffer is read to determine how many draws to issue.
321+
///
322+
/// The indirect buffer must be long enough to account for `max_count` draws, however only `count` elements
323+
/// will be read, where `count` is the value read from `count_buffer` capped at `max_count`.
324+
///
325+
/// The active vertex buffers can be set with [`TrackedRenderPass::set_vertex_buffer`].
326+
///
327+
/// `indirect_buffer` should contain `count` tightly packed elements of the following structure:
328+
///
329+
/// ```rust
330+
/// #[repr(C)]
331+
/// struct DrawIndirect {
332+
/// vertex_count: u32, // The number of vertices to draw.
333+
/// instance_count: u32, // The number of instances to draw.
334+
/// first_vertex: u32, // The Index of the first vertex to draw.
335+
/// first_instance: u32, // The instance ID of the first instance to draw.
336+
/// // has to be 0, unless [`Features::INDIRECT_FIRST_INSTANCE`] is enabled.
337+
/// }
338+
/// ```
339+
pub fn multi_draw_indirect_count(
340+
&mut self,
341+
indirect_buffer: &'a Buffer,
342+
indirect_offset: u64,
343+
count_buffer: &'a Buffer,
344+
count_offset: u64,
345+
max_count: u32,
346+
) {
347+
trace!(
348+
"multi draw indirect count: {:?} {}, ({:?} {})x, max {}x",
349+
indirect_buffer,
350+
indirect_offset,
351+
count_buffer,
352+
count_offset,
353+
max_count
354+
);
355+
self.pass.multi_draw_indirect_count(
356+
indirect_buffer,
357+
indirect_offset,
358+
count_buffer,
359+
count_offset,
360+
max_count,
361+
);
362+
}
363+
364+
/// Dispatches multiple draw calls from the active index buffer and the active vertex buffers,
365+
/// based on the contents of the `indirect_buffer`. `count` draw calls are issued.
366+
///
367+
/// The active index buffer can be set with [`TrackedRenderPass::set_index_buffer`], while the active
368+
/// vertex buffers can be set with [`TrackedRenderPass::set_vertex_buffer`].
369+
///
370+
/// `indirect_buffer` should contain `count` tightly packed elements of the following structure:
371+
///
372+
/// ```rust
373+
/// #[repr(C)]
374+
/// struct DrawIndexedIndirect {
375+
/// vertex_count: u32, // The number of vertices to draw.
376+
/// instance_count: u32, // The number of instances to draw.
377+
/// first_index: u32, // The base index within the index buffer.
378+
/// vertex_offset: i32, // The value added to the vertex index before indexing into the vertex buffer.
379+
/// first_instance: u32, // The instance ID of the first instance to draw.
380+
/// // has to be 0, unless [`Features::INDIRECT_FIRST_INSTANCE`] is enabled.
381+
/// }
382+
/// ```
383+
pub fn multi_draw_indexed_indirect(
384+
&mut self,
385+
indirect_buffer: &'a Buffer,
386+
indirect_offset: u64,
387+
count: u32,
388+
) {
389+
trace!(
390+
"multi draw indexed indirect: {:?} {}, {}x",
391+
indirect_buffer,
392+
indirect_offset,
393+
count
394+
);
395+
self.pass
396+
.multi_draw_indexed_indirect(indirect_buffer, indirect_offset, count);
397+
}
398+
399+
/// Dispatches multiple draw calls from the active index buffer and the active vertex buffers,
400+
/// based on the contents of the `indirect_buffer`. The count buffer is read to determine how many draws to issue.
401+
///
402+
/// The indirect buffer must be long enough to account for `max_count` draws, however only `count` elements
403+
/// will be read, where `count` is the value read from `count_buffer` capped at `max_count`.
404+
///
405+
/// The active index buffer can be set with [`TrackedRenderPass::set_index_buffer`], while the active
406+
/// vertex buffers can be set with [`TrackedRenderPass::set_vertex_buffer`].
407+
///
408+
/// `indirect_buffer` should contain `count` tightly packed elements of the following structure:
409+
///
410+
/// ```rust
411+
/// #[repr(C)]
412+
/// struct DrawIndexedIndirect {
413+
/// vertex_count: u32, // The number of vertices to draw.
414+
/// instance_count: u32, // The number of instances to draw.
415+
/// first_index: u32, // The base index within the index buffer.
416+
/// vertex_offset: i32, // The value added to the vertex index before indexing into the vertex buffer.
417+
/// first_instance: u32, // The instance ID of the first instance to draw.
418+
/// // has to be 0, unless [`Features::INDIRECT_FIRST_INSTANCE`] is enabled.
419+
/// }
420+
/// ```
421+
pub fn multi_draw_indexed_indirect_count(
422+
&mut self,
423+
indirect_buffer: &'a Buffer,
424+
indirect_offset: u64,
425+
count_buffer: &'a Buffer,
426+
count_offset: u64,
427+
max_count: u32,
428+
) {
429+
trace!(
430+
"multi draw indexed indirect count: {:?} {}, ({:?} {})x, max {}x",
431+
indirect_buffer,
432+
indirect_offset,
433+
count_buffer,
434+
count_offset,
435+
max_count
436+
);
437+
self.pass.multi_draw_indexed_indirect_count(
438+
indirect_buffer,
439+
indirect_offset,
440+
count_buffer,
441+
count_offset,
442+
max_count,
443+
);
444+
}
445+
286446
/// Sets the stencil reference.
287447
///
288448
/// Subsequent stencil tests will test against this value.

0 commit comments

Comments
 (0)