Skip to main content

bevy_material/
descriptor.rs

1use alloc::borrow::Cow;
2use bevy_asset::Handle;
3use bevy_derive::Deref;
4use bevy_mesh::VertexBufferLayout;
5use bevy_shader::{CachedPipelineId, Shader, ShaderDefVal};
6use core::iter;
7use thiserror::Error;
8use wgpu_types::{
9    BindGroupLayoutEntry, ColorTargetState, DepthStencilState, MultisampleState, PrimitiveState,
10};
11
12#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)]
13pub struct BindGroupLayoutDescriptor {
14    /// Debug label of the bind group layout descriptor. This will show up in graphics debuggers for easy identification.
15    pub label: Cow<'static, str>,
16    pub entries: Vec<BindGroupLayoutEntry>,
17}
18
19impl BindGroupLayoutDescriptor {
20    pub fn new(label: impl Into<Cow<'static, str>>, entries: &[BindGroupLayoutEntry]) -> Self {
21        Self {
22            label: label.into(),
23            entries: entries.into(),
24        }
25    }
26}
27
28/// Describes a render (graphics) pipeline.
29#[derive(Clone, Debug, PartialEq, Default)]
30pub struct RenderPipelineDescriptor {
31    /// Debug label of the pipeline. This will show up in graphics debuggers for easy identification.
32    pub label: Option<Cow<'static, str>>,
33    /// The layout of bind groups for this pipeline.
34    pub layout: Vec<BindGroupLayoutDescriptor>,
35    /// The immediate size for this pipeline.
36    /// Supply 0 if the pipeline doesn't use push constants/immediates.
37    pub immediate_size: u32,
38    /// The compiled vertex stage, its entry point, and the input buffers layout.
39    pub vertex: VertexState,
40    /// The properties of the pipeline at the primitive assembly and rasterization level.
41    pub primitive: PrimitiveState,
42    /// The effect of draw calls on the depth and stencil aspects of the output target, if any.
43    pub depth_stencil: Option<DepthStencilState>,
44    /// The multi-sampling properties of the pipeline.
45    pub multisample: MultisampleState,
46    /// The compiled fragment stage, its entry point, and the color targets.
47    pub fragment: Option<FragmentState>,
48    /// Whether to zero-initialize workgroup memory by default. If you're not sure, set this to true.
49    /// If this is false, reading from workgroup variables before writing to them will result in garbage values.
50    pub zero_initialize_workgroup_memory: bool,
51}
52
53#[derive(Copy, Clone, Debug, Error)]
54#[error("RenderPipelineDescriptor has no FragmentState configured")]
55pub struct NoFragmentStateError;
56
57impl RenderPipelineDescriptor {
58    pub fn fragment_mut(&mut self) -> Result<&mut FragmentState, NoFragmentStateError> {
59        self.fragment.as_mut().ok_or(NoFragmentStateError)
60    }
61
62    pub fn set_layout(&mut self, index: usize, layout: BindGroupLayoutDescriptor) {
63        filling_set_at(&mut self.layout, index, bevy_utils::default(), layout);
64    }
65}
66
67#[derive(Clone, Debug, PartialEq, Default)]
68pub struct VertexState {
69    /// The compiled shader module for this stage.
70    pub shader: Handle<Shader>,
71    pub shader_defs: Vec<ShaderDefVal>,
72    /// The name of the entry point in the compiled shader, or `None` if the default entry point
73    /// is used.
74    pub entry_point: Option<Cow<'static, str>>,
75    /// The format of any vertex buffers used with this pipeline.
76    pub buffers: Vec<VertexBufferLayout>,
77    /// Values for pipeline-overridable constants declared with `override` in this shader stage.
78    pub constants: Vec<(Cow<'static, str>, f64)>,
79}
80
81/// Describes the fragment process in a render pipeline.
82#[derive(Clone, Debug, PartialEq, Default)]
83pub struct FragmentState {
84    /// The compiled shader module for this stage.
85    pub shader: Handle<Shader>,
86    pub shader_defs: Vec<ShaderDefVal>,
87    /// The name of the entry point in the compiled shader, or `None` if the default entry point
88    /// is used.
89    pub entry_point: Option<Cow<'static, str>>,
90    /// The color state of the render targets.
91    pub targets: Vec<Option<ColorTargetState>>,
92    /// Values for pipeline-overridable constants declared with `override` in this shader stage.
93    pub constants: Vec<(Cow<'static, str>, f64)>,
94}
95
96impl FragmentState {
97    pub fn set_target(&mut self, index: usize, target: ColorTargetState) {
98        filling_set_at(&mut self.targets, index, None, Some(target));
99    }
100}
101
102/// Describes a compute pipeline.
103#[derive(Clone, Debug, PartialEq, Default)]
104pub struct ComputePipelineDescriptor {
105    pub label: Option<Cow<'static, str>>,
106    pub layout: Vec<BindGroupLayoutDescriptor>,
107    pub immediate_size: u32,
108    /// The compiled shader module for this stage.
109    pub shader: Handle<Shader>,
110    pub shader_defs: Vec<ShaderDefVal>,
111    /// The name of the entry point in the compiled shader, or `None` if the default entry point
112    /// is used.
113    pub entry_point: Option<Cow<'static, str>>,
114    /// Whether to zero-initialize workgroup memory by default. If you're not sure, set this to true.
115    /// If this is false, reading from workgroup variables before writing to them will result in garbage values.
116    pub zero_initialize_workgroup_memory: bool,
117    /// Values for pipeline-overridable constants declared with `override` in the shader.
118    pub constants: Vec<(Cow<'static, str>, f64)>,
119}
120
121// utility function to set a value at the specified index, extending with
122// a filler value if the index is out of bounds.
123fn filling_set_at<T: Clone>(vec: &mut Vec<T>, index: usize, filler: T, value: T) {
124    let num_to_fill = (index + 1).saturating_sub(vec.len());
125    vec.extend(iter::repeat_n(filler, num_to_fill));
126    vec[index] = value;
127}
128
129/// A descriptor for a [`Pipeline`](https://docs.rs/bevy/latest/bevy/render/render_resource/enum.Pipeline.html).
130///
131/// Used to store a heterogenous collection of render and compute pipeline descriptors together.
132#[derive(Debug)]
133pub enum PipelineDescriptor {
134    RenderPipelineDescriptor(Box<RenderPipelineDescriptor>),
135    ComputePipelineDescriptor(Box<ComputePipelineDescriptor>),
136    MeshPipelineDescriptor(Box<MeshPipelineDescriptor>),
137}
138
139/// Describes a Task and Mesh pipeline.
140#[derive(Clone, Debug, PartialEq, Default)]
141pub struct MeshPipelineDescriptor {
142    /// Debug label of the pipeline. This will show up in graphics debuggers for easy identification.
143    pub label: Option<Cow<'static, str>>,
144    /// The layout of bind groups for this pipeline.
145    pub layout: Vec<BindGroupLayoutDescriptor>,
146    /// The immediate size for this pipeline.
147    /// Supply 0 if the pipeline doesn't use push constants/immediates.
148    pub immediate_size: u32,
149    /// The compiled task stage, its entry point, and the input buffers layout.
150    pub task: Option<TaskState>,
151    /// The compiled mesh stage, its entry point, and the input buffers layout.
152    pub mesh: MeshState,
153    /// The properties of the pipeline at the primitive assembly and rasterization level.
154    pub primitive: PrimitiveState,
155    /// The effect of draw calls on the depth and stencil aspects of the output target, if any.
156    pub depth_stencil: Option<DepthStencilState>,
157    /// The multi-sampling properties of the pipeline.
158    pub multisample: MultisampleState,
159    /// The compiled fragment stage, its entry point, and the color targets.
160    pub fragment: Option<FragmentState>,
161    // Whether to zero-initialize workgroup memory by default. If you're not sure, set this to true.
162    // If this is false, reading from workgroup variables before writing to them will result in garbage values.
163    pub zero_initialize_workgroup_memory: bool,
164}
165
166#[derive(Clone, Debug, PartialEq, Default)]
167pub struct TaskState {
168    /// The compiled shader module for this stage.
169    pub shader: Handle<Shader>,
170    pub shader_defs: Vec<ShaderDefVal>,
171    /// The name of the entry point in the compiled shader, or `None` if the default entry point
172    /// is used.
173    pub entry_point: Option<Cow<'static, str>>,
174    /// Values for pipeline-overridable constants declared with `override` in this shader stage.
175    pub constants: Vec<(Cow<'static, str>, f64)>,
176}
177
178#[derive(Clone, Debug, PartialEq, Default)]
179pub struct MeshState {
180    /// The compiled shader module for this stage.
181    pub shader: Handle<Shader>,
182    pub shader_defs: Vec<ShaderDefVal>,
183    /// The name of the entry point in the compiled shader, or `None` if the default entry point
184    /// is used.
185    pub entry_point: Option<Cow<'static, str>>,
186    /// Values for pipeline-overridable constants declared with `override` in this shader stage.
187    pub constants: Vec<(Cow<'static, str>, f64)>,
188}
189
190/// Index of a cached render pipeline in a `PipelineCache`.
191#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord, Deref)]
192pub struct CachedRenderPipelineId(CachedPipelineId);
193
194impl CachedRenderPipelineId {
195    /// An invalid cached render pipeline index, often used to initialize a variable.
196    pub const INVALID: Self = CachedRenderPipelineId(usize::MAX);
197
198    #[inline]
199    pub fn new(id: usize) -> Self {
200        Self(id)
201    }
202
203    #[inline]
204    pub fn id(&self) -> usize {
205        self.0
206    }
207}
208
209/// Index of a cached compute pipeline in a `PipelineCache`.
210#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
211pub struct CachedComputePipelineId(CachedPipelineId);
212
213impl CachedComputePipelineId {
214    /// An invalid cached compute pipeline index, often used to initialize a variable.
215    pub const INVALID: Self = CachedComputePipelineId(usize::MAX);
216
217    #[inline]
218    pub fn new(id: usize) -> Self {
219        Self(id)
220    }
221
222    #[inline]
223    pub fn id(&self) -> usize {
224        self.0
225    }
226}