Skip to main content

wgpu/api/
bind_group.rs

1use crate::*;
2
3/// Handle to a binding group.
4///
5/// A `BindGroup` represents the set of resources bound to the bindings described by a
6/// [`BindGroupLayout`]. It can be created with [`Device::create_bind_group`]. A `BindGroup` can
7/// be bound to a particular [`RenderPass`] with [`RenderPass::set_bind_group`], or to a
8/// [`ComputePass`] with [`ComputePass::set_bind_group`].
9///
10/// Corresponds to [WebGPU `GPUBindGroup`](https://gpuweb.github.io/gpuweb/#gpubindgroup).
11#[derive(Debug, Clone)]
12pub struct BindGroup {
13    pub(crate) inner: dispatch::DispatchBindGroup,
14}
15#[cfg(send_sync)]
16static_assertions::assert_impl_all!(BindGroup: Send, Sync);
17
18crate::cmp::impl_eq_ord_hash_proxy!(BindGroup => .inner);
19
20impl BindGroup {
21    #[cfg(custom)]
22    /// Returns custom implementation of BindGroup (if custom backend and is internally T)
23    pub fn as_custom<T: custom::BindGroupInterface>(&self) -> Option<&T> {
24        self.inner.as_custom()
25    }
26}
27
28#[cfg(wgpu_core)]
29impl BindGroup {
30    /// Create a new bind group of wgpu from a wgpu-core bind group.
31    ///
32    /// # Arguments
33    ///
34    /// - `core_bind_group` - wgpu-core bind group.
35    pub fn from_core(core_bind_group: alloc::sync::Arc<wgc::binding_model::BindGroup>) -> Self {
36        Self {
37            inner: crate::backend::wgpu_core::CoreBindGroup::from_core(core_bind_group).into(),
38        }
39    }
40
41    /// Returns the underlying wgpu-core bind group if this `BindGroup` is on the wgpu-core backend, otherwise `None`.
42    pub fn as_core(&self) -> Option<alloc::sync::Arc<wgc::binding_model::BindGroup>> {
43        self.inner.as_core_opt().map(|bg| bg.as_core())
44    }
45}
46
47/// Resource to be bound by a [`BindGroup`] for use with a pipeline.
48///
49/// The pipeline’s [`BindGroupLayout`] must contain a matching [`BindingType`].
50///
51/// Corresponds to [WebGPU `GPUBindingResource`](
52/// https://gpuweb.github.io/gpuweb/#typedefdef-gpubindingresource).
53#[non_exhaustive]
54#[derive(Clone, Debug)]
55pub enum BindingResource<'a> {
56    /// Binding is backed by a buffer.
57    ///
58    /// Corresponds to [`wgt::BufferBindingType::Uniform`] and [`wgt::BufferBindingType::Storage`]
59    /// with [`BindGroupLayoutEntry::count`] set to None.
60    Buffer(BufferBinding<'a>),
61    /// Binding is backed by an array of buffers.
62    ///
63    /// [`Features::BUFFER_BINDING_ARRAY`] must be supported to use this feature.
64    ///
65    /// Corresponds to [`wgt::BufferBindingType::Uniform`] and [`wgt::BufferBindingType::Storage`]
66    /// with [`BindGroupLayoutEntry::count`] set to Some.
67    BufferArray(&'a [BufferBinding<'a>]),
68    /// Binding is a sampler.
69    ///
70    /// Corresponds to [`wgt::BindingType::Sampler`] with [`BindGroupLayoutEntry::count`] set to None.
71    Sampler(&'a Sampler),
72    /// Binding is backed by an array of samplers.
73    ///
74    /// [`Features::TEXTURE_BINDING_ARRAY`] must be supported to use this feature.
75    ///
76    /// Corresponds to [`wgt::BindingType::Sampler`] with [`BindGroupLayoutEntry::count`] set
77    /// to Some.
78    SamplerArray(&'a [&'a Sampler]),
79    /// Binding is backed by a texture.
80    ///
81    /// Corresponds to [`wgt::BindingType::Texture`] and [`wgt::BindingType::StorageTexture`] with
82    /// [`BindGroupLayoutEntry::count`] set to None.
83    TextureView(&'a TextureView),
84    /// Binding is backed by an array of textures.
85    ///
86    /// [`Features::TEXTURE_BINDING_ARRAY`] must be supported to use this feature.
87    ///
88    /// Corresponds to [`wgt::BindingType::Texture`] and [`wgt::BindingType::StorageTexture`] with
89    /// [`BindGroupLayoutEntry::count`] set to Some.
90    TextureViewArray(&'a [&'a TextureView]),
91    /// Binding is backed by a top level acceleration structure
92    ///
93    /// Corresponds to [`wgt::BindingType::AccelerationStructure`] with [`BindGroupLayoutEntry::count`] set to None.
94    ///
95    /// # Validation
96    /// When using (e.g. with `set_bind_group`) a bind group that has been created with one or more of this binding
97    /// resource certain checks take place.
98    /// - TLAS must have been built, if not a validation error is generated
99    /// - All BLASes that were built into the TLAS must be built before the TLAS, if this was not satisfied and TLAS was
100    ///   built using `build_acceleration_structures` a validation error is generated otherwise this is a part of the
101    ///   safety section of `build_acceleration_structures_unsafe_tlas` and so undefined behavior occurs.
102    AccelerationStructure(&'a Tlas),
103    /// Binding is backed by an array of top level acceleration structures.
104    ///
105    /// Corresponds to [`wgt::BindingType::AccelerationStructure`] with [`BindGroupLayoutEntry::count`] set to Some.
106    ///
107    /// # Validation
108    /// The same validation rules apply as for [`BindingResource::AccelerationStructure`], for each element.
109    ///
110    /// Note: backend support may vary; this is primarily intended for native backends.
111    AccelerationStructureArray(&'a [&'a Tlas]),
112    /// Binding is backed by an external texture.
113    ///
114    /// [`Features::EXTERNAL_TEXTURE`] must be supported to use this feature.
115    ///
116    /// Corresponds to [`wgt::BindingType::ExternalTexture`].
117    ExternalTexture(&'a ExternalTexture),
118}
119#[cfg(send_sync)]
120static_assertions::assert_impl_all!(BindingResource<'_>: Send, Sync);
121
122/// Describes the segment of a buffer to bind.
123///
124/// Corresponds to [WebGPU `GPUBufferBinding`](
125/// https://gpuweb.github.io/gpuweb/#dictdef-gpubufferbinding).
126#[derive(Clone, Debug)]
127pub struct BufferBinding<'a> {
128    /// The buffer to bind.
129    pub buffer: &'a Buffer,
130
131    /// Base offset of the buffer, in bytes.
132    ///
133    /// If the [`has_dynamic_offset`] field of this buffer's layout entry is
134    /// `true`, the offset here will be added to the dynamic offset passed to
135    /// [`RenderPass::set_bind_group`] or [`ComputePass::set_bind_group`].
136    ///
137    /// If the buffer was created with [`BufferUsages::UNIFORM`], then this
138    /// offset must be a multiple of
139    /// [`Limits::min_uniform_buffer_offset_alignment`].
140    ///
141    /// If the buffer was created with [`BufferUsages::STORAGE`], then this
142    /// offset must be a multiple of
143    /// [`Limits::min_storage_buffer_offset_alignment`].
144    ///
145    /// [`has_dynamic_offset`]: BindingType::Buffer::has_dynamic_offset
146    pub offset: BufferAddress,
147
148    /// Size of the binding in bytes, or `None` for using the rest of the buffer.
149    pub size: Option<BufferSize>,
150}
151#[cfg(send_sync)]
152static_assertions::assert_impl_all!(BufferBinding<'_>: Send, Sync);
153
154/// An element of a [`BindGroupDescriptor`], consisting of a bindable resource
155/// and the slot to bind it to.
156///
157/// Corresponds to [WebGPU `GPUBindGroupEntry`](
158/// https://gpuweb.github.io/gpuweb/#dictdef-gpubindgroupentry).
159#[derive(Clone, Debug)]
160pub struct BindGroupEntry<'a> {
161    /// Slot for which binding provides resource. Corresponds to an entry of the same
162    /// binding index in the [`BindGroupLayoutDescriptor`].
163    pub binding: u32,
164    /// Resource to attach to the binding
165    pub resource: BindingResource<'a>,
166}
167#[cfg(send_sync)]
168static_assertions::assert_impl_all!(BindGroupEntry<'_>: Send, Sync);
169
170/// Describes a group of bindings and the resources to be bound.
171///
172/// For use with [`Device::create_bind_group`].
173///
174/// Corresponds to [WebGPU `GPUBindGroupDescriptor`](
175/// https://gpuweb.github.io/gpuweb/#dictdef-gpubindgroupdescriptor).
176#[derive(Clone, Debug)]
177pub struct BindGroupDescriptor<'a> {
178    /// Debug label of the bind group. This will show up in graphics debuggers for easy identification.
179    pub label: Label<'a>,
180    /// The [`BindGroupLayout`] that corresponds to this bind group.
181    pub layout: &'a BindGroupLayout,
182    /// The resources to bind to this bind group.
183    pub entries: &'a [BindGroupEntry<'a>],
184}
185#[cfg(send_sync)]
186static_assertions::assert_impl_all!(BindGroupDescriptor<'_>: Send, Sync);