diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 7422f140b2..d85483a7cf 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -26,14 +26,14 @@ vulkan = ["wgc/gfx-backend-vulkan"] package = "wgpu-core" version = "0.5" git = "https://github.com/gfx-rs/wgpu" -rev = "3b6e128877d74f8310967e377c5193fd4105ee13" +rev = "43c67ac59c2dedaa4d78601bc460aab7c3257973" features = ["raw-window-handle"] [dependencies.wgt] package = "wgpu-types" version = "0.5" git = "https://github.com/gfx-rs/wgpu" -rev = "3b6e128877d74f8310967e377c5193fd4105ee13" +rev = "43c67ac59c2dedaa4d78601bc460aab7c3257973" [dependencies] arrayvec = "0.5" diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 05fe83abf3..62c7fed3b1 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -138,6 +138,61 @@ mod pass_impl { ) { wgpu_render_pass_draw_indexed_indirect(self, *indirect_buffer, indirect_offset) } + fn multi_draw_indirect( + &mut self, + indirect_buffer: &wgc::id::BufferId, + indirect_offset: wgt::BufferAddress, + count: u32, + ) { + wgpu_render_pass_multi_draw_indirect(self, *indirect_buffer, indirect_offset, count) + } + fn multi_draw_indexed_indirect( + &mut self, + indirect_buffer: &wgc::id::BufferId, + indirect_offset: wgt::BufferAddress, + count: u32, + ) { + wgpu_render_pass_multi_draw_indexed_indirect( + self, + *indirect_buffer, + indirect_offset, + count, + ) + } + fn multi_draw_indirect_count( + &mut self, + indirect_buffer: &wgc::id::BufferId, + indirect_offset: wgt::BufferAddress, + count_buffer: &wgc::id::BufferId, + count_buffer_offset: wgt::BufferAddress, + max_count: u32, + ) { + wgpu_render_pass_multi_draw_indirect_count( + self, + *indirect_buffer, + indirect_offset, + *count_buffer, + count_buffer_offset, + max_count, + ) + } + fn multi_draw_indexed_indirect_count( + &mut self, + indirect_buffer: &wgc::id::BufferId, + indirect_offset: wgt::BufferAddress, + count_buffer: &wgc::id::BufferId, + count_buffer_offset: wgt::BufferAddress, + max_count: u32, + ) { + wgpu_render_pass_multi_draw_indexed_indirect_count( + self, + *indirect_buffer, + indirect_offset, + *count_buffer, + count_buffer_offset, + max_count, + ) + } } impl crate::RenderPassInner for wgc::command::RenderPass { @@ -266,6 +321,42 @@ mod pass_impl { ) { wgpu_render_pass_bundle_indexed_indirect(self, *indirect_buffer, indirect_offset) } + fn multi_draw_indirect( + &mut self, + _indirect_buffer: &wgc::id::BufferId, + _indirect_offset: wgt::BufferAddress, + _count: u32, + ) { + unimplemented!() + } + fn multi_draw_indexed_indirect( + &mut self, + _indirect_buffer: &wgc::id::BufferId, + _indirect_offset: wgt::BufferAddress, + _count: u32, + ) { + unimplemented!() + } + fn multi_draw_indirect_count( + &mut self, + _indirect_buffer: &wgc::id::BufferId, + _indirect_offset: wgt::BufferAddress, + _count_buffer: &wgc::id::BufferId, + _count_buffer_offset: wgt::BufferAddress, + _max_count: u32, + ) { + unimplemented!() + } + fn multi_draw_indexed_indirect_count( + &mut self, + _indirect_buffer: &wgc::id::BufferId, + _indirect_offset: wgt::BufferAddress, + _count_buffer: &wgc::id::BufferId, + _count_buffer_offset: wgt::BufferAddress, + _max_count: u32, + ) { + unimplemented!() + } } } diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index ed6f39b590..5e5408fcd1 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -164,6 +164,44 @@ impl crate::RenderInner for RenderPass { self.0 .draw_indexed_indirect_with_f64(&indirect_buffer.0, indirect_offset as f64); } + fn multi_draw_indirect( + &mut self, + _indirect_buffer: &Sendable, + _indirect_offset: wgt::BufferAddress, + _count: u32, + ) { + panic!("MULTI_DRAW_INDIRECT feature must be enabled to call multi_draw_indirect") + } + fn multi_draw_indexed_indirect( + &mut self, + _indirect_buffer: &Sendable, + _indirect_offset: wgt::BufferAddress, + _count: u32, + ) { + panic!("MULTI_DRAW_INDIRECT feature must be enabled to call multi_draw_indexed_indirect") + } + fn multi_draw_indirect_count( + &mut self, + _indirect_buffer: &Sendable, + _indirect_offset: wgt::BufferAddress, + _count_buffer: &Sendable, + _count_buffer_offset: wgt::BufferAddress, + _max_count: u32, + ) { + panic!( + "MULTI_DRAW_INDIRECT_COUNT feature must be enabled to call multi_draw_indirect_count" + ) + } + fn multi_draw_indexed_indirect_count( + &mut self, + _indirect_buffer: &Sendable, + _indirect_offset: wgt::BufferAddress, + _count_buffer: &Sendable, + _count_buffer_offset: wgt::BufferAddress, + _max_count: u32, + ) { + panic!("MULTI_DRAW_INDIRECT_COUNT feature must be enabled to call multi_draw_indexed_indirect_count") + } } impl crate::RenderPassInner for RenderPass { diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 7dfdc3fd67..19f850a0db 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -84,6 +84,34 @@ trait RenderInner { indirect_buffer: &Ctx::BufferId, indirect_offset: BufferAddress, ); + fn multi_draw_indirect( + &mut self, + indirect_buffer: &Ctx::BufferId, + indirect_offset: BufferAddress, + count: u32, + ); + fn multi_draw_indexed_indirect( + &mut self, + indirect_buffer: &Ctx::BufferId, + indirect_offset: BufferAddress, + count: u32, + ); + fn multi_draw_indirect_count( + &mut self, + indirect_buffer: &Ctx::BufferId, + indirect_offset: BufferAddress, + count_buffer: &Ctx::BufferId, + count_buffer_offset: BufferAddress, + max_count: u32, + ); + fn multi_draw_indexed_indirect_count( + &mut self, + indirect_buffer: &Ctx::BufferId, + indirect_offset: BufferAddress, + count_buffer: &Ctx::BufferId, + count_buffer_offset: BufferAddress, + max_count: u32, + ); } trait RenderPassInner: RenderInner { @@ -1850,6 +1878,168 @@ impl<'a> RenderPass<'a> { .draw_indexed_indirect(&indirect_buffer.id, indirect_offset); } + /// Disptaches multiple draw calls from the active vertex buffer(s) based on the contents of the `indirect_buffer`. + /// `count` draw calls are issued. + /// + /// [`Features::MULTI_DRAW_INDIRECT`] must be enabled on the device in order to call this function. + /// + /// The active vertex buffers can be set with [`RenderPass::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. + /// base_vertex: u32, // The Index of the first vertex to draw. + /// base_instance: u32, // The instance ID of the first instance to draw. + /// } + /// ``` + /// + /// These draw structures are expected to be tightly packed. + pub fn multi_draw_indirect( + &mut self, + indirect_buffer: &'a Buffer, + indirect_offset: BufferAddress, + count: u32, + ) { + self.id + .multi_draw_indirect(&indirect_buffer.id, indirect_offset, count); + } + + /// Disptaches multiple draw calls from the active index buffer and the active vertex buffers, + /// based on the contents of the `indirect_buffer`. `count` draw calls are issued. + /// + /// [`Features::MULTI_DRAW_INDIRECT`] must be enabled on the device in order to call this function. + /// + /// The active index buffer can be set with [`RenderPass::set_index_buffer`], while the active + /// vertex buffers can be set with [`RenderPass::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. + /// base_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. + /// base_instance: u32, // The instance ID of the first instance to draw. + /// } + /// ``` + /// + /// These draw structures are expected to be tightly packed. + pub fn multi_draw_indexed_indirect( + &mut self, + indirect_buffer: &'a Buffer, + indirect_offset: BufferAddress, + count: u32, + ) { + self.id + .multi_draw_indexed_indirect(&indirect_buffer.id, indirect_offset, count); + } + + /// Disptaches multiple draw calls from the active vertex buffer(s) based on the contents of the `indirect_buffer`. + /// The count buffer is read to determine how many draws to issue. + /// + /// The indirect buffer must be long enough to account for `max_count` draws, however only `count` will + /// draws will be read. If `count` is greater than `max_count`, `max_count` will be used. + /// + /// [`Features::MULTI_DRAW_INDIRECT_COUNT`] must be enabled on the device in order to call this function. + /// + /// The active vertex buffers can be set with [`RenderPass::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. + /// base_vertex: u32, // The Index of the first vertex to draw. + /// base_instance: u32, // The instance ID of the first instance to draw. + /// } + /// ``` + /// + /// These draw structures are expected to be tightly packed. + /// + /// The structure expected in `count_buffer` is the following: + /// + /// ```rust + /// #[repr(C)] + /// struct DrawIndirectCount { + /// count: u32, // Number of draw calls to issue. + /// } + /// ``` + pub fn multi_draw_indirect_count( + &mut self, + indirect_buffer: &'a Buffer, + indirect_offset: BufferAddress, + count_buffer: &'a Buffer, + count_offset: BufferAddress, + max_count: u32, + ) { + self.id.multi_draw_indirect_count( + &indirect_buffer.id, + indirect_offset, + &count_buffer.id, + count_offset, + max_count, + ); + } + + /// Disptaches multiple draw calls from the active index buffer and the active vertex buffers, + /// based on the contents of the `indirect_buffer`. The count buffer is read to determine how many draws to issue. + /// + /// The indirect buffer must be long enough to account for `max_count` draws, however only `count` will + /// draws will be read. If `count` is greater than `max_count`, `max_count` will be used. + /// + /// [`Features::MULTI_DRAW_INDIRECT_COUNT`] must be enabled on the device in order to call this function. + /// + /// The active index buffer can be set with [`RenderPass::set_index_buffer`], while the active + /// vertex buffers can be set with [`RenderPass::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. + /// base_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. + /// base_instance: u32, // The instance ID of the first instance to draw. + /// } + /// ``` + /// + /// These draw structures are expected to be tightly packed. + /// + /// The structure expected in `count_buffer` is the following: + /// + /// ```rust + /// #[repr(C)] + /// struct DrawIndexedIndirectCount { + /// count: u32, // Number of draw calls to issue. + /// } + /// ``` + pub fn multi_draw_indexed_indirect_count( + &mut self, + indirect_buffer: &'a Buffer, + indirect_offset: BufferAddress, + count_buffer: &'a Buffer, + count_offset: BufferAddress, + max_count: u32, + ) { + self.id.multi_draw_indexed_indirect_count( + &indirect_buffer.id, + indirect_offset, + &count_buffer.id, + count_offset, + max_count, + ); + } + /// Execute a [render bundle][RenderBundle], which is a set of pre-recorded commands /// that can be run together. pub fn execute_bundles>(&mut self, render_bundles: I) {