bevy_render/render_resource/
pipeline.rs

1use super::ShaderDefVal;
2use crate::{
3    define_atomic_id,
4    render_resource::{resource_macros::render_resource_wrapper, BindGroupLayout, Shader},
5};
6use bevy_asset::Handle;
7use std::{borrow::Cow, ops::Deref};
8use wgpu::{
9    BufferAddress, ColorTargetState, DepthStencilState, MultisampleState, PrimitiveState,
10    PushConstantRange, VertexAttribute, VertexFormat, VertexStepMode,
11};
12
13define_atomic_id!(RenderPipelineId);
14render_resource_wrapper!(ErasedRenderPipeline, wgpu::RenderPipeline);
15
16/// A [`RenderPipeline`] represents a graphics pipeline and its stages (shaders), bindings and vertex buffers.
17///
18/// May be converted from and dereferences to a wgpu [`RenderPipeline`](wgpu::RenderPipeline).
19/// Can be created via [`RenderDevice::create_render_pipeline`](crate::renderer::RenderDevice::create_render_pipeline).
20#[derive(Clone, Debug)]
21pub struct RenderPipeline {
22    id: RenderPipelineId,
23    value: ErasedRenderPipeline,
24}
25
26impl RenderPipeline {
27    #[inline]
28    pub fn id(&self) -> RenderPipelineId {
29        self.id
30    }
31}
32
33impl From<wgpu::RenderPipeline> for RenderPipeline {
34    fn from(value: wgpu::RenderPipeline) -> Self {
35        RenderPipeline {
36            id: RenderPipelineId::new(),
37            value: ErasedRenderPipeline::new(value),
38        }
39    }
40}
41
42impl Deref for RenderPipeline {
43    type Target = wgpu::RenderPipeline;
44
45    #[inline]
46    fn deref(&self) -> &Self::Target {
47        &self.value
48    }
49}
50
51define_atomic_id!(ComputePipelineId);
52render_resource_wrapper!(ErasedComputePipeline, wgpu::ComputePipeline);
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)]
59pub struct ComputePipeline {
60    id: ComputePipelineId,
61    value: ErasedComputePipeline,
62}
63
64impl ComputePipeline {
65    /// Returns the [`ComputePipelineId`].
66    #[inline]
67    pub fn id(&self) -> ComputePipelineId {
68        self.id
69    }
70}
71
72impl From<wgpu::ComputePipeline> for ComputePipeline {
73    fn from(value: wgpu::ComputePipeline) -> Self {
74        ComputePipeline {
75            id: ComputePipelineId::new(),
76            value: ErasedComputePipeline::new(value),
77        }
78    }
79}
80
81impl 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)]
92pub 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}
111
112#[derive(Clone, Debug, Eq, PartialEq)]
113pub struct VertexState {
114    /// The compiled shader module for this stage.
115    pub shader: Handle<Shader>,
116    pub shader_defs: Vec<ShaderDefVal>,
117    /// The name of the entry point in the compiled shader. There must be a
118    /// function with this name in the shader.
119    pub entry_point: Cow<'static, str>,
120    /// The format of any vertex buffers used with this pipeline.
121    pub buffers: Vec<VertexBufferLayout>,
122}
123
124/// Describes how the vertex buffer is interpreted.
125#[derive(Default, Clone, Debug, Hash, Eq, PartialEq)]
126pub struct VertexBufferLayout {
127    /// The stride, in bytes, between elements of this buffer.
128    pub array_stride: BufferAddress,
129    /// How often this vertex buffer is "stepped" forward.
130    pub step_mode: VertexStepMode,
131    /// The list of attributes which comprise a single vertex.
132    pub attributes: Vec<VertexAttribute>,
133}
134
135impl VertexBufferLayout {
136    /// Creates a new densely packed [`VertexBufferLayout`] from an iterator of vertex formats.
137    /// Iteration order determines the `shader_location` and `offset` of the [`VertexAttributes`](VertexAttribute).
138    /// The first iterated item will have a `shader_location` and `offset` of zero.
139    /// The `array_stride` is the sum of the size of the iterated [`VertexFormats`](VertexFormat) (in bytes).
140    pub fn from_vertex_formats<T: IntoIterator<Item = VertexFormat>>(
141        step_mode: VertexStepMode,
142        vertex_formats: T,
143    ) -> Self {
144        let mut offset = 0;
145        let mut attributes = Vec::new();
146        for (shader_location, format) in vertex_formats.into_iter().enumerate() {
147            attributes.push(VertexAttribute {
148                format,
149                offset,
150                shader_location: shader_location as u32,
151            });
152            offset += format.size();
153        }
154
155        VertexBufferLayout {
156            array_stride: offset,
157            step_mode,
158            attributes,
159        }
160    }
161}
162
163/// Describes the fragment process in a render pipeline.
164#[derive(Clone, Debug, PartialEq, Eq)]
165pub struct FragmentState {
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. There must be a
170    /// function with this name in the shader.
171    pub entry_point: Cow<'static, str>,
172    /// The color state of the render targets.
173    pub targets: Vec<Option<ColorTargetState>>,
174}
175
176/// Describes a compute pipeline.
177#[derive(Clone, Debug)]
178pub struct ComputePipelineDescriptor {
179    pub label: Option<Cow<'static, str>>,
180    pub layout: Vec<BindGroupLayout>,
181    pub push_constant_ranges: Vec<PushConstantRange>,
182    /// The compiled shader module for this stage.
183    pub shader: Handle<Shader>,
184    pub shader_defs: Vec<ShaderDefVal>,
185    /// The name of the entry point in the compiled shader. There must be a
186    /// function with this name in the shader.
187    pub entry_point: Cow<'static, str>,
188}