wgpu/api/
render_pipeline.rs

1use std::{num::NonZeroU32, sync::Arc, thread};
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)]
12pub struct RenderPipeline {
13    pub(crate) context: Arc<C>,
14    pub(crate) data: Box<Data>,
15}
16#[cfg(send_sync)]
17static_assertions::assert_impl_all!(RenderPipeline: Send, Sync);
18
19super::impl_partialeq_eq_hash!(RenderPipeline);
20
21impl Drop for RenderPipeline {
22    fn drop(&mut self) {
23        if !thread::panicking() {
24            self.context.render_pipeline_drop(self.data.as_ref());
25        }
26    }
27}
28
29impl RenderPipeline {
30    /// Get an object representing the bind group layout at a given index.
31    ///
32    /// If this pipeline was created with a [default layout][RenderPipelineDescriptor::layout], then
33    /// bind groups created with the returned `BindGroupLayout` can only be used with this pipeline.
34    ///
35    /// This method will raise a validation error if there is no bind group layout at `index`.
36    pub fn get_bind_group_layout(&self, index: u32) -> BindGroupLayout {
37        let context = Arc::clone(&self.context);
38        let data = self
39            .context
40            .render_pipeline_get_bind_group_layout(self.data.as_ref(), index);
41        BindGroupLayout { context, data }
42    }
43}
44
45/// Describes how the vertex buffer is interpreted.
46///
47/// For use in [`VertexState`].
48///
49/// Corresponds to [WebGPU `GPUVertexBufferLayout`](
50/// https://gpuweb.github.io/gpuweb/#dictdef-gpuvertexbufferlayout).
51#[derive(Clone, Debug, Hash, Eq, PartialEq)]
52pub struct VertexBufferLayout<'a> {
53    /// The stride, in bytes, between elements of this buffer.
54    pub array_stride: BufferAddress,
55    /// How often this vertex buffer is "stepped" forward.
56    pub step_mode: VertexStepMode,
57    /// The list of attributes which comprise a single vertex.
58    pub attributes: &'a [VertexAttribute],
59}
60static_assertions::assert_impl_all!(VertexBufferLayout<'_>: Send, Sync);
61
62/// Describes the vertex processing in a render pipeline.
63///
64/// For use in [`RenderPipelineDescriptor`].
65///
66/// Corresponds to [WebGPU `GPUVertexState`](
67/// https://gpuweb.github.io/gpuweb/#dictdef-gpuvertexstate).
68#[derive(Clone, Debug)]
69pub struct VertexState<'a> {
70    /// The compiled shader module for this stage.
71    pub module: &'a ShaderModule,
72    /// The name of the entry point in the compiled shader to use.
73    ///
74    /// If [`Some`], there must be a vertex-stage shader entry point with this name in `module`.
75    /// Otherwise, expect exactly one vertex-stage entry point in `module`, which will be
76    /// selected.
77    // NOTE: keep phrasing in sync. with `ComputePipelineDescriptor::entry_point`
78    // NOTE: keep phrasing in sync. with `FragmentState::entry_point`
79    pub entry_point: Option<&'a str>,
80    /// Advanced options for when this pipeline is compiled
81    ///
82    /// This implements `Default`, and for most users can be set to `Default::default()`
83    pub compilation_options: PipelineCompilationOptions<'a>,
84    /// The format of any vertex buffers used with this pipeline.
85    pub buffers: &'a [VertexBufferLayout<'a>],
86}
87#[cfg(send_sync)]
88static_assertions::assert_impl_all!(VertexState<'_>: Send, Sync);
89
90/// Describes the fragment processing in a render pipeline.
91///
92/// For use in [`RenderPipelineDescriptor`].
93///
94/// Corresponds to [WebGPU `GPUFragmentState`](
95/// https://gpuweb.github.io/gpuweb/#dictdef-gpufragmentstate).
96#[derive(Clone, Debug)]
97pub struct FragmentState<'a> {
98    /// The compiled shader module for this stage.
99    pub module: &'a ShaderModule,
100    /// The name of the entry point in the compiled shader to use.
101    ///
102    /// If [`Some`], there must be a `@fragment` shader entry point with this name in `module`.
103    /// Otherwise, expect exactly one fragment-stage entry point in `module`, which will be
104    /// selected.
105    // NOTE: keep phrasing in sync. with `ComputePipelineDescriptor::entry_point`
106    // NOTE: keep phrasing in sync. with `VertexState::entry_point`
107    pub entry_point: Option<&'a str>,
108    /// Advanced options for when this pipeline is compiled
109    ///
110    /// This implements `Default`, and for most users can be set to `Default::default()`
111    pub compilation_options: PipelineCompilationOptions<'a>,
112    /// The color state of the render targets.
113    pub targets: &'a [Option<ColorTargetState>],
114}
115#[cfg(send_sync)]
116static_assertions::assert_impl_all!(FragmentState<'_>: Send, Sync);
117
118/// Describes a render (graphics) pipeline.
119///
120/// For use with [`Device::create_render_pipeline`].
121///
122/// Corresponds to [WebGPU `GPURenderPipelineDescriptor`](
123/// https://gpuweb.github.io/gpuweb/#dictdef-gpurenderpipelinedescriptor).
124#[derive(Clone, Debug)]
125pub struct RenderPipelineDescriptor<'a> {
126    /// Debug label of the pipeline. This will show up in graphics debuggers for easy identification.
127    pub label: Label<'a>,
128    /// The layout of bind groups for this pipeline.
129    ///
130    /// If this is set, then [`Device::create_render_pipeline`] will raise a validation error if
131    /// the layout doesn't match what the shader module(s) expect.
132    ///
133    /// Using the same [`PipelineLayout`] for many [`RenderPipeline`] or [`ComputePipeline`]
134    /// pipelines guarantees that you don't have to rebind any resources when switching between
135    /// those pipelines.
136    ///
137    /// ## Default pipeline layout
138    ///
139    /// If `layout` is `None`, then the pipeline has a [default layout] created and used instead.
140    /// The default layout is deduced from the shader modules.
141    ///
142    /// You can use [`RenderPipeline::get_bind_group_layout`] to create bind groups for use with the
143    /// default layout. However, these bind groups cannot be used with any other pipelines. This is
144    /// convenient for simple pipelines, but using an explicit layout is recommended in most cases.
145    ///
146    /// [default layout]: https://www.w3.org/TR/webgpu/#default-pipeline-layout
147    pub layout: Option<&'a PipelineLayout>,
148    /// The compiled vertex stage, its entry point, and the input buffers layout.
149    pub vertex: VertexState<'a>,
150    /// The properties of the pipeline at the primitive assembly and rasterization level.
151    pub primitive: PrimitiveState,
152    /// The effect of draw calls on the depth and stencil aspects of the output target, if any.
153    pub depth_stencil: Option<DepthStencilState>,
154    /// The multi-sampling properties of the pipeline.
155    pub multisample: MultisampleState,
156    /// The compiled fragment stage, its entry point, and the color targets.
157    pub fragment: Option<FragmentState<'a>>,
158    /// If the pipeline will be used with a multiview render pass, this indicates how many array
159    /// layers the attachments will have.
160    pub multiview: Option<NonZeroU32>,
161    /// The pipeline cache to use when creating this pipeline.
162    pub cache: Option<&'a PipelineCache>,
163}
164#[cfg(send_sync)]
165static_assertions::assert_impl_all!(RenderPipelineDescriptor<'_>: Send, Sync);