From 40b36927f51e2b12a6810b069acb3b7ab73c3dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kurt=20K=C3=BChnert?= Date: Mon, 28 Feb 2022 10:26:49 +0000 Subject: [PATCH] Expose draw indirect (#4056) # Objective - Currently there is now way of making an indirect draw call from a tracked render pass. - This is a very useful feature for GPU based rendering. ## Solution - Expose the `draw_indirect` and `draw_indexed_indirect` methods from the wgpu `RenderPass` in the `TrackedRenderPass`. ## Alternative - #3595: Expose the underlying `RenderPass` directly --- .../src/render_phase/draw_state.rs | 56 ++++++++++++++++++- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/crates/bevy_render/src/render_phase/draw_state.rs b/crates/bevy_render/src/render_phase/draw_state.rs index 7b17c63277..81a5f9590d 100644 --- a/crates/bevy_render/src/render_phase/draw_state.rs +++ b/crates/bevy_render/src/render_phase/draw_state.rs @@ -1,7 +1,7 @@ use crate::{ prelude::Color, render_resource::{ - BindGroup, BindGroupId, BufferId, BufferSlice, RenderPipeline, RenderPipelineId, + BindGroup, BindGroupId, Buffer, BufferId, BufferSlice, RenderPipeline, RenderPipelineId, ShaderStages, }, }; @@ -233,9 +233,61 @@ impl<'a> TrackedRenderPass<'a> { self.pass.draw_indexed(indices, base_vertex, instances); } + /// Draws primitives from the active vertex buffer(s) based on the contents of the `indirect_buffer`. + /// + /// The active vertex buffers can be set with [`TrackedRenderPass::set_vertex_buffer`]. + /// + /// The structure expected in `indirect_buffer` is the following: + /// + /// ```rust + /// #[repr(C)] + /// struct DrawIndirect { + /// vertex_count: u32, // The number of vertices to draw. + /// instance_count: u32, // The number of instances to draw. + /// first_vertex: u32, // The Index of the first vertex to draw. + /// first_instance: u32, // The instance ID of the first instance to draw. + /// // has to be 0, unless [`Features::INDIRECT_FIRST_INSTANCE`] is enabled. + /// } + /// ``` + pub fn draw_indirect(&mut self, indirect_buffer: &'a Buffer, indirect_offset: u64) { + trace!("draw indirect: {:?} {}", indirect_buffer, indirect_offset); + self.pass.draw_indirect(indirect_buffer, indirect_offset); + } + + /// Draws indexed primitives using the active index buffer and the active vertex buffers, + /// based on the contents of the `indirect_buffer`. + /// + /// The active index buffer can be set with [`TrackedRenderPass::set_index_buffer`], while the active + /// vertex buffers can be set with [`TrackedRenderPass::set_vertex_buffer`]. + /// + /// The structure expected in `indirect_buffer` is the following: + /// + /// ```rust + /// #[repr(C)] + /// struct DrawIndexedIndirect { + /// vertex_count: u32, // The number of vertices to draw. + /// instance_count: u32, // The number of instances to draw. + /// first_index: u32, // The base index within the index buffer. + /// vertex_offset: i32, // The value added to the vertex index before indexing into the vertex buffer. + /// first_instance: u32, // The instance ID of the first instance to draw. + /// // has to be 0, unless [`Features::INDIRECT_FIRST_INSTANCE`] is enabled. + /// } + /// ``` + pub fn draw_indexed_indirect(&mut self, indirect_buffer: &'a Buffer, indirect_offset: u64) { + trace!( + "draw indexed indirect: {:?} {}", + indirect_buffer, + indirect_offset + ); + self.pass + .draw_indexed_indirect(indirect_buffer, indirect_offset); + } + + /// Sets the stencil reference. + /// + /// Subsequent stencil tests will test against this value. pub fn set_stencil_reference(&mut self, reference: u32) { trace!("set stencil reference: {}", reference); - self.pass.set_stencil_reference(reference); }