Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_render/src/render_resource/pipeline.rs
6596 views
1
use super::empty_bind_group_layout;
2
use crate::renderer::WgpuWrapper;
3
use crate::{define_atomic_id, render_resource::BindGroupLayout};
4
use alloc::borrow::Cow;
5
use bevy_asset::Handle;
6
use bevy_mesh::VertexBufferLayout;
7
use bevy_shader::{Shader, ShaderDefVal};
8
use core::iter;
9
use core::ops::Deref;
10
use thiserror::Error;
11
use wgpu::{
12
ColorTargetState, DepthStencilState, MultisampleState, PrimitiveState, PushConstantRange,
13
};
14
15
define_atomic_id!(RenderPipelineId);
16
17
/// A [`RenderPipeline`] represents a graphics pipeline and its stages (shaders), bindings and vertex buffers.
18
///
19
/// May be converted from and dereferences to a wgpu [`RenderPipeline`](wgpu::RenderPipeline).
20
/// Can be created via [`RenderDevice::create_render_pipeline`](crate::renderer::RenderDevice::create_render_pipeline).
21
#[derive(Clone, Debug)]
22
pub struct RenderPipeline {
23
id: RenderPipelineId,
24
value: WgpuWrapper<wgpu::RenderPipeline>,
25
}
26
27
impl RenderPipeline {
28
#[inline]
29
pub fn id(&self) -> RenderPipelineId {
30
self.id
31
}
32
}
33
34
impl From<wgpu::RenderPipeline> for RenderPipeline {
35
fn from(value: wgpu::RenderPipeline) -> Self {
36
RenderPipeline {
37
id: RenderPipelineId::new(),
38
value: WgpuWrapper::new(value),
39
}
40
}
41
}
42
43
impl Deref for RenderPipeline {
44
type Target = wgpu::RenderPipeline;
45
46
#[inline]
47
fn deref(&self) -> &Self::Target {
48
&self.value
49
}
50
}
51
52
define_atomic_id!(ComputePipelineId);
53
54
/// A [`ComputePipeline`] represents a compute pipeline and its single shader stage.
55
///
56
/// May be converted from and dereferences to a wgpu [`ComputePipeline`](wgpu::ComputePipeline).
57
/// Can be created via [`RenderDevice::create_compute_pipeline`](crate::renderer::RenderDevice::create_compute_pipeline).
58
#[derive(Clone, Debug)]
59
pub struct ComputePipeline {
60
id: ComputePipelineId,
61
value: WgpuWrapper<wgpu::ComputePipeline>,
62
}
63
64
impl ComputePipeline {
65
/// Returns the [`ComputePipelineId`].
66
#[inline]
67
pub fn id(&self) -> ComputePipelineId {
68
self.id
69
}
70
}
71
72
impl From<wgpu::ComputePipeline> for ComputePipeline {
73
fn from(value: wgpu::ComputePipeline) -> Self {
74
ComputePipeline {
75
id: ComputePipelineId::new(),
76
value: WgpuWrapper::new(value),
77
}
78
}
79
}
80
81
impl Deref for ComputePipeline {
82
type Target = wgpu::ComputePipeline;
83
84
#[inline]
85
fn deref(&self) -> &Self::Target {
86
&self.value
87
}
88
}
89
90
/// Describes a render (graphics) pipeline.
91
#[derive(Clone, Debug, PartialEq, Default)]
92
pub struct RenderPipelineDescriptor {
93
/// Debug label of the pipeline. This will show up in graphics debuggers for easy identification.
94
pub label: Option<Cow<'static, str>>,
95
/// The layout of bind groups for this pipeline.
96
pub layout: Vec<BindGroupLayout>,
97
/// The push constant ranges for this pipeline.
98
/// Supply an empty vector if the pipeline doesn't use push constants.
99
pub push_constant_ranges: Vec<PushConstantRange>,
100
/// The compiled vertex stage, its entry point, and the input buffers layout.
101
pub vertex: VertexState,
102
/// The properties of the pipeline at the primitive assembly and rasterization level.
103
pub primitive: PrimitiveState,
104
/// The effect of draw calls on the depth and stencil aspects of the output target, if any.
105
pub depth_stencil: Option<DepthStencilState>,
106
/// The multi-sampling properties of the pipeline.
107
pub multisample: MultisampleState,
108
/// The compiled fragment stage, its entry point, and the color targets.
109
pub fragment: Option<FragmentState>,
110
/// Whether to zero-initialize workgroup memory by default. If you're not sure, set this to true.
111
/// If this is false, reading from workgroup variables before writing to them will result in garbage values.
112
pub zero_initialize_workgroup_memory: bool,
113
}
114
115
#[derive(Copy, Clone, Debug, Error)]
116
#[error("RenderPipelineDescriptor has no FragmentState configured")]
117
pub struct NoFragmentStateError;
118
119
impl RenderPipelineDescriptor {
120
pub fn fragment_mut(&mut self) -> Result<&mut FragmentState, NoFragmentStateError> {
121
self.fragment.as_mut().ok_or(NoFragmentStateError)
122
}
123
124
pub fn set_layout(&mut self, index: usize, layout: BindGroupLayout) {
125
filling_set_at(&mut self.layout, index, empty_bind_group_layout(), layout);
126
}
127
}
128
129
#[derive(Clone, Debug, Eq, PartialEq, Default)]
130
pub struct VertexState {
131
/// The compiled shader module for this stage.
132
pub shader: Handle<Shader>,
133
pub shader_defs: Vec<ShaderDefVal>,
134
/// The name of the entry point in the compiled shader, or `None` if the default entry point
135
/// is used.
136
pub entry_point: Option<Cow<'static, str>>,
137
/// The format of any vertex buffers used with this pipeline.
138
pub buffers: Vec<VertexBufferLayout>,
139
}
140
141
/// Describes the fragment process in a render pipeline.
142
#[derive(Clone, Debug, PartialEq, Eq, Default)]
143
pub struct FragmentState {
144
/// The compiled shader module for this stage.
145
pub shader: Handle<Shader>,
146
pub shader_defs: Vec<ShaderDefVal>,
147
/// The name of the entry point in the compiled shader, or `None` if the default entry point
148
/// is used.
149
pub entry_point: Option<Cow<'static, str>>,
150
/// The color state of the render targets.
151
pub targets: Vec<Option<ColorTargetState>>,
152
}
153
154
impl FragmentState {
155
pub fn set_target(&mut self, index: usize, target: ColorTargetState) {
156
filling_set_at(&mut self.targets, index, None, Some(target));
157
}
158
}
159
160
/// Describes a compute pipeline.
161
#[derive(Clone, Debug, PartialEq, Eq, Default)]
162
pub struct ComputePipelineDescriptor {
163
pub label: Option<Cow<'static, str>>,
164
pub layout: Vec<BindGroupLayout>,
165
pub push_constant_ranges: Vec<PushConstantRange>,
166
/// The compiled shader module for this stage.
167
pub shader: Handle<Shader>,
168
pub shader_defs: Vec<ShaderDefVal>,
169
/// The name of the entry point in the compiled shader, or `None` if the default entry point
170
/// is used.
171
pub entry_point: Option<Cow<'static, str>>,
172
/// Whether to zero-initialize workgroup memory by default. If you're not sure, set this to true.
173
/// If this is false, reading from workgroup variables before writing to them will result in garbage values.
174
pub zero_initialize_workgroup_memory: bool,
175
}
176
177
// utility function to set a value at the specified index, extending with
178
// a filler value if the index is out of bounds.
179
fn filling_set_at<T: Clone>(vec: &mut Vec<T>, index: usize, filler: T, value: T) {
180
let num_to_fill = (index + 1).saturating_sub(vec.len());
181
vec.extend(iter::repeat_n(filler, num_to_fill));
182
vec[index] = value;
183
}
184
185