Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add util::indirect::* helper structs #2365

Merged
merged 1 commit into from
Jan 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 9 additions & 104 deletions wgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2605,18 +2605,7 @@ impl<'a> RenderPass<'a> {
///
/// 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.
/// 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.
/// }
/// ```
/// The structure expected in `indirect_buffer` must conform to [`DrawIndirect`](crate::util::DrawIndirect).
pub fn draw_indirect(&mut self, indirect_buffer: &'a Buffer, indirect_offset: BufferAddress) {
self.id.draw_indirect(&indirect_buffer.id, indirect_offset);
}
Expand All @@ -2627,19 +2616,7 @@ impl<'a> RenderPass<'a> {
/// 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.
/// 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.
/// }
/// ```
/// The structure expected in `indirect_buffer` must conform to [`DrawIndexedIndirect`](crate::util::DrawIndexedIndirect).
pub fn draw_indexed_indirect(
&mut self,
indirect_buffer: &'a Buffer,
Expand All @@ -2664,17 +2641,7 @@ impl<'a> RenderPass<'a> {
///
/// 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.
/// }
/// ```
/// The structure expected in `indirect_buffer` must conform to [`DrawIndirect`](crate::util::DrawIndirect).
///
/// These draw structures are expected to be tightly packed.
pub fn multi_draw_indirect(
Expand All @@ -2693,18 +2660,7 @@ impl<'a> RenderPass<'a> {
/// 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.
/// }
/// ```
/// The structure expected in `indirect_buffer` must conform to [`DrawIndexedIndirect`](crate::util::DrawIndexedIndirect).
///
/// These draw structures are expected to be tightly packed.
pub fn multi_draw_indexed_indirect(
Expand All @@ -2728,17 +2684,7 @@ impl<'a> RenderPass<'a> {
///
/// 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.
/// }
/// ```
/// The structure expected in `indirect_buffer` must conform to [`DrawIndirect`](crate::util::DrawIndirect).
///
/// These draw structures are expected to be tightly packed.
///
Expand Down Expand Up @@ -2776,18 +2722,8 @@ impl<'a> RenderPass<'a> {
/// 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.
/// }
/// ```
/// The structure expected in `indirect_buffer` must conform to [`DrawIndexedIndirect`](crate::util::DrawIndexedIndirect).
///
/// These draw structures are expected to be tightly packed.
///
Expand Down Expand Up @@ -2938,17 +2874,7 @@ impl<'a> ComputePass<'a> {

/// Dispatches compute work operations, based on the contents of the `indirect_buffer`.
///
/// The structure expected in `indirect_buffer` is the following:
///
/// ```rust
/// // x, y and z denote the number of work groups to dispatch in each dimension.
/// #[repr(C)]
/// struct DispatchIndirect {
/// x: u32,
/// y: u32,
/// z: u32,
/// }
/// ```
/// The structure expected in `indirect_buffer` must conform to [`DispatchIndirect`](crate::util::DispatchIndirect).
pub fn dispatch_indirect(
&mut self,
indirect_buffer: &'a Buffer,
Expand Down Expand Up @@ -3094,17 +3020,7 @@ impl<'a> RenderBundleEncoder<'a> {
///
/// The active vertex buffers can be set with [`RenderBundleEncoder::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.
/// }
/// ```
/// The structure expected in `indirect_buffer` must conform to [`DrawIndirect`](crate::util::DrawIndirect).
pub fn draw_indirect(&mut self, indirect_buffer: &'a Buffer, indirect_offset: BufferAddress) {
self.id.draw_indirect(&indirect_buffer.id, indirect_offset);
}
Expand All @@ -3115,18 +3031,7 @@ impl<'a> RenderBundleEncoder<'a> {
/// The active index buffer can be set with [`RenderBundleEncoder::set_index_buffer`], while the active
/// vertex buffers can be set with [`RenderBundleEncoder::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.
/// }
/// ```
/// The structure expected in `indirect_buffer` must conform to [`DrawIndexedIndirect`](crate::util::DrawIndexedIndirect).
pub fn draw_indexed_indirect(
&mut self,
indirect_buffer: &'a Buffer,
Expand Down
25 changes: 2 additions & 23 deletions wgpu/src/util/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,7 @@ pub trait RenderEncoder<'a> {
///
/// The active vertex buffers can be set with [`RenderEncoder::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.
/// }
/// ```
/// The structure expected in `indirect_buffer` must conform to [`DrawIndirect`](crate::util::DrawIndirect).
fn draw_indirect(&mut self, indirect_buffer: &'a Buffer, indirect_offset: BufferAddress);

/// Draws indexed primitives using the active index buffer and the active vertex buffers,
Expand All @@ -69,18 +59,7 @@ pub trait RenderEncoder<'a> {
/// The active index buffer can be set with [`RenderEncoder::set_index_buffer`], while the active
/// vertex buffers can be set with [`RenderEncoder::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.
/// }
/// ```
/// The structure expected in `indirect_buffer` must conform to [`DrawIndexedIndirect`](crate::util::DrawIndexedIndirect).
fn draw_indexed_indirect(
&mut self,
indirect_buffer: &'a Buffer,
Expand Down
81 changes: 81 additions & 0 deletions wgpu/src/util/indirect.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/// The structure expected in `indirect_buffer` for [`RenderEncoder::draw_indirect`](crate::util::RenderEncoder::draw_indirect).
#[repr(C)]
#[derive(Copy, Clone, Debug, Default)]
pub struct DrawIndirect {
/// The number of vertices to draw.
pub vertex_count: u32,
/// The number of instances to draw.
pub instance_count: u32,
/// The Index of the first vertex to draw.
pub base_vertex: u32,
/// The instance ID of the first instance to draw.
/// Has to be 0, unless [`Features::INDIRECT_FIRST_INSTANCE`](crate::Features::INDIRECT_FIRST_INSTANCE) is enabled.
pub base_instance: u32,
}

impl DrawIndirect {
/// Returns the bytes representation of the struct, ready to be written in a [`Buffer`](crate::Buffer).
pub fn as_bytes(&self) -> &[u8] {
unsafe {
std::mem::transmute(std::slice::from_raw_parts(
self as *const _ as *const u8,
std::mem::size_of::<Self>(),
))
}
}
}

/// The structure expected in `indirect_buffer` for [`RenderEncoder::draw_indexed_indirect`](crate::util::RenderEncoder::draw_indexed_indirect).
#[repr(C)]
#[derive(Copy, Clone, Debug, Default)]
pub struct DrawIndexedIndirect {
/// The number of vertices to draw.
pub vertex_count: u32,
/// The number of instances to draw.
pub instance_count: u32,
/// The base index within the index buffer.
pub base_index: u32,
/// The value added to the vertex index before indexing into the vertex buffer.
pub vertex_offset: i32,
/// The instance ID of the first instance to draw.
/// Has to be 0, unless [`Features::INDIRECT_FIRST_INSTANCE`](crate::Features::INDIRECT_FIRST_INSTANCE) is enabled.
pub base_instance: u32,
}

impl DrawIndexedIndirect {
/// Returns the bytes representation of the struct, ready to be written in a [`Buffer`](crate::Buffer).
pub fn as_bytes(&self) -> &[u8] {
unsafe {
std::mem::transmute(std::slice::from_raw_parts(
self as *const _ as *const u8,
kvark marked this conversation as resolved.
Show resolved Hide resolved
std::mem::size_of::<Self>(),
))
}
}
}

/// The structure expected in `indirect_buffer` for [`ComputePass::dispatch_indirect`](crate::ComputePass::dispatch_indirect).
///
/// x, y and z denote the number of work groups to dispatch in each dimension.
#[repr(C)]
#[derive(Copy, Clone, Debug, Default)]
pub struct DispatchIndirect {
/// The number of work groups in X dimension.
pub x: u32,
/// The number of work groups in Y dimension.
pub y: u32,
/// The number of work groups in Z dimension.
pub z: u32,
}

impl DispatchIndirect {
/// Returns the bytes representation of the struct, ready to be written in a [`Buffer`](crate::Buffer).
pub fn as_bytes(&self) -> &[u8] {
unsafe {
std::mem::transmute(std::slice::from_raw_parts(
self as *const _ as *const u8,
std::mem::size_of::<Self>(),
))
}
}
}
2 changes: 2 additions & 0 deletions wgpu/src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
mod belt;
mod device;
mod encoder;
mod indirect;
mod init;

use std::future::Future;
Expand All @@ -15,6 +16,7 @@ use std::{
pub use belt::StagingBelt;
pub use device::{BufferInitDescriptor, DeviceExt};
pub use encoder::RenderEncoder;
pub use indirect::*;
pub use init::*;

/// Treat the given byte slice as a SPIR-V module.
Expand Down