wgpu/api/
render_pipeline.rs

1use core::num::NonZeroU32;
2
3use crate::*;
4
5/// Handle to a rendering (graphics) pipeline.
6///
7/// A `RenderPipeline` object represents a graphics pipeline and its stages, bindings, vertex
8/// buffers and targets. It can be created with [`Device::create_render_pipeline`].
9///
10/// Corresponds to [WebGPU `GPURenderPipeline`](https://gpuweb.github.io/gpuweb/#render-pipeline).
11#[derive(Debug, Clone)]
12pub struct RenderPipeline {
13    pub(crate) inner: dispatch::DispatchRenderPipeline,
14}
15#[cfg(send_sync)]
16static_assertions::assert_impl_all!(RenderPipeline: Send, Sync);
17
18crate::cmp::impl_eq_ord_hash_proxy!(RenderPipeline => .inner);
19
20impl RenderPipeline {
21    /// Get an object representing the bind group layout at a given index.
22    ///
23    /// If this pipeline was created with a [default layout][RenderPipelineDescriptor::layout], then
24    /// bind groups created with the returned `BindGroupLayout` can only be used with this pipeline.
25    ///
26    /// This method will raise a validation error if there is no bind group layout at `index`.
27    pub fn get_bind_group_layout(&self, index: u32) -> BindGroupLayout {
28        let layout = self.inner.get_bind_group_layout(index);
29        BindGroupLayout { inner: layout }
30    }
31
32    #[cfg(custom)]
33    /// Returns custom implementation of RenderPipeline (if custom backend and is internally T)
34    pub fn as_custom<T: custom::RenderPipelineInterface>(&self) -> Option<&T> {
35        self.inner.as_custom()
36    }
37}
38
39/// Specifies an interpretation of the bytes of a vertex buffer as vertex attributes.
40///
41/// Use this in a [`RenderPipelineDescriptor`] to describe the format of the vertex buffers that
42/// are passed to [`RenderPass::set_vertex_buffer()`].
43///
44/// Corresponds to [WebGPU `GPUVertexBufferLayout`](
45/// https://gpuweb.github.io/gpuweb/#dictdef-gpuvertexbufferlayout).
46///
47/// # Example
48///
49/// The following example defines a `struct` with three fields,
50/// and a [`VertexBufferLayout`] that contains [`VertexAttribute`]s for each field,
51/// using the [`vertex_attr_array!`] macro to compute attribute offsets:
52///
53/// ```
54/// #[repr(C, packed)]
55/// struct Vertex {
56///     foo: [f32; 2],
57///     bar: f32,
58///     baz: [u16; 4],
59/// }
60///
61/// impl Vertex {
62///     /// Layout to use with a buffer whose contents are a `[Vertex]`.
63///     pub const LAYOUT: wgpu::VertexBufferLayout<'static> = wgpu::VertexBufferLayout {
64///         array_stride: size_of::<Self>() as wgpu::BufferAddress,
65///         step_mode: wgpu::VertexStepMode::Vertex,
66///         attributes: &wgpu::vertex_attr_array![
67///             0 => Float32x2,
68///             1 => Float32,
69///             2 => Uint16x4,
70///         ],
71///     };
72/// }
73///
74/// # assert_eq!(Vertex::LAYOUT.attributes[2].offset, Vertex::LAYOUT.array_stride - 2 * 4);
75#[derive(Clone, Debug, Hash, Eq, PartialEq)]
76pub struct VertexBufferLayout<'a> {
77    /// The stride, in bytes, between elements of this buffer (between vertices).
78    ///
79    /// This must be a multiple of [`VERTEX_ALIGNMENT`].
80    pub array_stride: BufferAddress,
81    /// How often this vertex buffer is "stepped" forward.
82    pub step_mode: VertexStepMode,
83    /// The list of attributes which comprise a single vertex.
84    pub attributes: &'a [VertexAttribute],
85}
86static_assertions::assert_impl_all!(VertexBufferLayout<'_>: Send, Sync);
87
88/// Describes the vertex processing in a render pipeline.
89///
90/// For use in [`RenderPipelineDescriptor`].
91///
92/// Corresponds to [WebGPU `GPUVertexState`](
93/// https://gpuweb.github.io/gpuweb/#dictdef-gpuvertexstate).
94#[derive(Clone, Debug)]
95pub struct VertexState<'a> {
96    /// The compiled shader module for this stage.
97    pub module: &'a ShaderModule,
98    /// The name of the entry point in the compiled shader to use.
99    ///
100    /// If [`Some`], there must be a vertex-stage shader entry point with this name in `module`.
101    /// Otherwise, expect exactly one vertex-stage entry point in `module`, which will be
102    /// selected.
103    // NOTE: keep phrasing in sync. with `ComputePipelineDescriptor::entry_point`
104    // NOTE: keep phrasing in sync. with `FragmentState::entry_point`
105    pub entry_point: Option<&'a str>,
106    /// Advanced options for when this pipeline is compiled
107    ///
108    /// This implements `Default`, and for most users can be set to `Default::default()`
109    pub compilation_options: PipelineCompilationOptions<'a>,
110    /// The format of any vertex buffers used with this pipeline via
111    /// [`RenderPass::set_vertex_buffer()`].
112    ///
113    /// The attribute locations and types specified in this layout must match the
114    /// locations and types of the inputs to the `entry_point` function.
115    pub buffers: &'a [VertexBufferLayout<'a>],
116}
117#[cfg(send_sync)]
118static_assertions::assert_impl_all!(VertexState<'_>: Send, Sync);
119
120/// Describes the fragment processing in a render pipeline.
121///
122/// For use in [`RenderPipelineDescriptor`].
123///
124/// Corresponds to [WebGPU `GPUFragmentState`](
125/// https://gpuweb.github.io/gpuweb/#dictdef-gpufragmentstate).
126#[derive(Clone, Debug)]
127pub struct FragmentState<'a> {
128    /// The compiled shader module for this stage.
129    pub module: &'a ShaderModule,
130    /// The name of the entry point in the compiled shader to use.
131    ///
132    /// If [`Some`], there must be a `@fragment` shader entry point with this name in `module`.
133    /// Otherwise, expect exactly one fragment-stage entry point in `module`, which will be
134    /// selected.
135    // NOTE: keep phrasing in sync. with `ComputePipelineDescriptor::entry_point`
136    // NOTE: keep phrasing in sync. with `VertexState::entry_point`
137    pub entry_point: Option<&'a str>,
138    /// Advanced options for when this pipeline is compiled
139    ///
140    /// This implements `Default`, and for most users can be set to `Default::default()`
141    pub compilation_options: PipelineCompilationOptions<'a>,
142    /// The color state of the render targets.
143    pub targets: &'a [Option<ColorTargetState>],
144}
145#[cfg(send_sync)]
146static_assertions::assert_impl_all!(FragmentState<'_>: Send, Sync);
147
148/// Describes the task shader stage in a mesh shader pipeline.
149///
150/// For use in [`MeshPipelineDescriptor`]
151#[derive(Clone, Debug)]
152pub struct TaskState<'a> {
153    /// The compiled shader module for this stage.
154    pub module: &'a ShaderModule,
155
156    /// The name of the task shader entry point in the shader module to use.
157    ///
158    /// If [`Some`], there must be a task shader entry point with the given name
159    /// in `module`. Otherwise, there must be exactly one task shader entry
160    /// point in `module`, which will be selected.
161    pub entry_point: Option<&'a str>,
162
163    /// Advanced options for when this pipeline is compiled.
164    ///
165    /// This implements `Default`, and for most users can be set to `Default::default()`
166    pub compilation_options: PipelineCompilationOptions<'a>,
167}
168#[cfg(send_sync)]
169static_assertions::assert_impl_all!(TaskState<'_>: Send, Sync);
170
171/// Describes the mesh shader stage in a mesh shader pipeline.
172///
173/// For use in [`MeshPipelineDescriptor`]
174#[derive(Clone, Debug)]
175pub struct MeshState<'a> {
176    /// The compiled shader module for this stage.
177    pub module: &'a ShaderModule,
178    /// The name of the entry point in the compiled shader to use.
179    ///
180    /// If [`Some`], there must be a vertex-stage shader entry point with this name in `module`.
181    /// Otherwise, expect exactly one vertex-stage entry point in `module`, which will be
182    /// selected.
183    pub entry_point: Option<&'a str>,
184    /// Advanced options for when this pipeline is compiled
185    ///
186    /// This implements `Default`, and for most users can be set to `Default::default()`
187    pub compilation_options: PipelineCompilationOptions<'a>,
188}
189#[cfg(send_sync)]
190static_assertions::assert_impl_all!(MeshState<'_>: Send, Sync);
191
192/// Describes a render (graphics) pipeline.
193///
194/// For use with [`Device::create_render_pipeline`].
195///
196/// Corresponds to [WebGPU `GPURenderPipelineDescriptor`](
197/// https://gpuweb.github.io/gpuweb/#dictdef-gpurenderpipelinedescriptor).
198#[derive(Clone, Debug)]
199pub struct RenderPipelineDescriptor<'a> {
200    /// Debug label of the pipeline. This will show up in graphics debuggers for easy identification.
201    pub label: Label<'a>,
202    /// The layout of bind groups for this pipeline.
203    ///
204    /// If this is set, then [`Device::create_render_pipeline`] will raise a validation error if
205    /// the layout doesn't match what the shader module(s) expect.
206    ///
207    /// Using the same [`PipelineLayout`] for many [`RenderPipeline`] or [`ComputePipeline`]
208    /// pipelines guarantees that you don't have to rebind any resources when switching between
209    /// those pipelines.
210    ///
211    /// ## Default pipeline layout
212    ///
213    /// If `layout` is `None`, then the pipeline has a [default layout] created and used instead.
214    /// The default layout is deduced from the shader modules.
215    ///
216    /// You can use [`RenderPipeline::get_bind_group_layout`] to create bind groups for use with the
217    /// default layout. However, these bind groups cannot be used with any other pipelines. This is
218    /// convenient for simple pipelines, but using an explicit layout is recommended in most cases.
219    ///
220    /// [default layout]: https://www.w3.org/TR/webgpu/#default-pipeline-layout
221    pub layout: Option<&'a PipelineLayout>,
222    /// The compiled vertex stage, its entry point, and the input buffers layout.
223    pub vertex: VertexState<'a>,
224    /// The properties of the pipeline at the primitive assembly and rasterization level.
225    pub primitive: PrimitiveState,
226    /// The effect of draw calls on the depth and stencil aspects of the output target, if any.
227    pub depth_stencil: Option<DepthStencilState>,
228    /// The multi-sampling properties of the pipeline.
229    pub multisample: MultisampleState,
230    /// The compiled fragment stage, its entry point, and the color targets.
231    pub fragment: Option<FragmentState<'a>>,
232    /// If the pipeline will be used with a multiview render pass, this indicates what multiview
233    /// mask the render pass will be used with. The masks must match exactly.
234    ///
235    /// For example, if you wish to render to the first 2 layers, you would use 3=0b11. If you
236    /// wanted to render to only the 2nd layer, you would use 2=0b10. If you aren't using
237    /// multiview this should be `None`.
238    pub multiview_mask: Option<NonZeroU32>,
239    /// The pipeline cache to use when creating this pipeline.
240    pub cache: Option<&'a PipelineCache>,
241}
242#[cfg(send_sync)]
243static_assertions::assert_impl_all!(RenderPipelineDescriptor<'_>: Send, Sync);
244
245/// Describes a mesh shader (graphics) pipeline.
246///
247/// For use with [`Device::create_mesh_pipeline`]. A mesh pipeline is very much
248/// like a render pipeline, except that instead of [`RenderPass::draw`] it is
249/// invoked with [`RenderPass::draw_mesh_tasks`], and instead of a vertex shader
250/// and a fragment shader:
251///
252/// - [`task`] specifies an optional task shader entry point, which determines how
253///   many groups of mesh shaders to dispatch.
254///
255/// - [`mesh`] specifies a mesh shader entry point, which generates groups of
256///   primitives to draw
257///
258/// - [`fragment`] specifies as fragment shader for drawing those primitives,
259///   just like in an ordinary render pipeline.
260///
261/// The key difference is that, whereas a vertex shader is invoked on the
262/// elements of vertex buffers, the task shader gets to decide how many mesh
263/// shader workgroups to make, and then each mesh shader workgroup gets to
264/// decide which primitives it wants to generate, and what their vertex
265/// attributes are. Task and mesh shaders can use whatever they please as
266/// inputs, like a compute shader. However, they cannot use specialized vertex
267/// or index buffers.
268///
269/// A mesh pipeline is invoked by [`RenderPass::draw_mesh_tasks`], which looks
270/// like a compute shader dispatch with [`ComputePass::dispatch_workgroups`]:
271/// you pass `x`, `y`, and `z` values indicating the number of task shaders to
272/// invoke in parallel. The output value of the first thread in a task shader
273/// workgroup determines how many mesh workgroups should be dispatched from there.
274/// Those mesh workgroups also get a special payload passed from the task shader.
275///
276/// If the task shader is omitted, then the (`x`, `y`, `z`) parameters to
277/// `draw_mesh_tasks` are used to decide how many invocations of the mesh shader
278/// to invoke directly, without a task payload.
279///
280/// [vertex formats]: wgpu_types::VertexFormat
281/// [`task`]: Self::task
282/// [`mesh`]: Self::mesh
283/// [`fragment`]: Self::fragment
284#[derive(Clone, Debug)]
285pub struct MeshPipelineDescriptor<'a> {
286    /// Debug label of the pipeline. This will show up in graphics debuggers for easy identification.
287    pub label: Label<'a>,
288    /// The layout of bind groups for this pipeline.
289    ///
290    /// If this is set, then [`Device::create_render_pipeline`] will raise a validation error if
291    /// the layout doesn't match what the shader module(s) expect.
292    ///
293    /// Using the same [`PipelineLayout`] for many [`RenderPipeline`] or [`ComputePipeline`]
294    /// pipelines guarantees that you don't have to rebind any resources when switching between
295    /// those pipelines.
296    ///
297    /// ## Default pipeline layout
298    ///
299    /// If `layout` is `None`, then the pipeline has a [default layout] created and used instead.
300    /// The default layout is deduced from the shader modules.
301    ///
302    /// You can use [`RenderPipeline::get_bind_group_layout`] to create bind groups for use with the
303    /// default layout. However, these bind groups cannot be used with any other pipelines. This is
304    /// convenient for simple pipelines, but using an explicit layout is recommended in most cases.
305    ///
306    /// [default layout]: https://www.w3.org/TR/webgpu/#default-pipeline-layout
307    pub layout: Option<&'a PipelineLayout>,
308
309    /// The mesh pipeline's task shader.
310    ///
311    /// If this is `None`, the mesh pipeline has no task shader. Executing a
312    /// mesh drawing command simply dispatches a grid of mesh shaders directly.
313    ///
314    /// [`draw_mesh_tasks`]: RenderPass::draw_mesh_tasks
315    pub task: Option<TaskState<'a>>,
316
317    /// The compiled mesh stage and its entry point
318    pub mesh: MeshState<'a>,
319    /// The properties of the pipeline at the primitive assembly and rasterization level.
320    pub primitive: PrimitiveState,
321    /// The effect of draw calls on the depth and stencil aspects of the output target, if any.
322    pub depth_stencil: Option<DepthStencilState>,
323    /// The multi-sampling properties of the pipeline.
324    pub multisample: MultisampleState,
325    /// The compiled fragment stage, its entry point, and the color targets.
326    pub fragment: Option<FragmentState<'a>>,
327    /// If the pipeline will be used with a multiview render pass, this indicates how many array
328    /// layers the attachments will have.
329    pub multiview: Option<NonZeroU32>,
330    /// The pipeline cache to use when creating this pipeline.
331    pub cache: Option<&'a PipelineCache>,
332}
333#[cfg(send_sync)]
334static_assertions::assert_impl_all!(MeshPipelineDescriptor<'_>: Send, Sync);