1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
use std::{sync::Arc, thread};
use crate::*;
/// Handle to a binding group.
///
/// A `BindGroup` represents the set of resources bound to the bindings described by a
/// [`BindGroupLayout`]. It can be created with [`Device::create_bind_group`]. A `BindGroup` can
/// be bound to a particular [`RenderPass`] with [`RenderPass::set_bind_group`], or to a
/// [`ComputePass`] with [`ComputePass::set_bind_group`].
///
/// Corresponds to [WebGPU `GPUBindGroup`](https://gpuweb.github.io/gpuweb/#gpubindgroup).
#[derive(Debug)]
pub struct BindGroup {
pub(crate) context: Arc<C>,
pub(crate) data: Box<Data>,
}
#[cfg(send_sync)]
static_assertions::assert_impl_all!(BindGroup: Send, Sync);
super::impl_partialeq_eq_hash!(BindGroup);
impl Drop for BindGroup {
fn drop(&mut self) {
if !thread::panicking() {
self.context.bind_group_drop(self.data.as_ref());
}
}
}
/// Resource that can be bound to a pipeline.
///
/// Corresponds to [WebGPU `GPUBindingResource`](
/// https://gpuweb.github.io/gpuweb/#typedefdef-gpubindingresource).
#[non_exhaustive]
#[derive(Clone, Debug)]
pub enum BindingResource<'a> {
/// Binding is backed by a buffer.
///
/// Corresponds to [`wgt::BufferBindingType::Uniform`] and [`wgt::BufferBindingType::Storage`]
/// with [`BindGroupLayoutEntry::count`] set to None.
Buffer(BufferBinding<'a>),
/// Binding is backed by an array of buffers.
///
/// [`Features::BUFFER_BINDING_ARRAY`] must be supported to use this feature.
///
/// Corresponds to [`wgt::BufferBindingType::Uniform`] and [`wgt::BufferBindingType::Storage`]
/// with [`BindGroupLayoutEntry::count`] set to Some.
BufferArray(&'a [BufferBinding<'a>]),
/// Binding is a sampler.
///
/// Corresponds to [`wgt::BindingType::Sampler`] with [`BindGroupLayoutEntry::count`] set to None.
Sampler(&'a Sampler),
/// Binding is backed by an array of samplers.
///
/// [`Features::TEXTURE_BINDING_ARRAY`] must be supported to use this feature.
///
/// Corresponds to [`wgt::BindingType::Sampler`] with [`BindGroupLayoutEntry::count`] set
/// to Some.
SamplerArray(&'a [&'a Sampler]),
/// Binding is backed by a texture.
///
/// Corresponds to [`wgt::BindingType::Texture`] and [`wgt::BindingType::StorageTexture`] with
/// [`BindGroupLayoutEntry::count`] set to None.
TextureView(&'a TextureView),
/// Binding is backed by an array of textures.
///
/// [`Features::TEXTURE_BINDING_ARRAY`] must be supported to use this feature.
///
/// Corresponds to [`wgt::BindingType::Texture`] and [`wgt::BindingType::StorageTexture`] with
/// [`BindGroupLayoutEntry::count`] set to Some.
TextureViewArray(&'a [&'a TextureView]),
}
#[cfg(send_sync)]
static_assertions::assert_impl_all!(BindingResource<'_>: Send, Sync);
/// Describes the segment of a buffer to bind.
///
/// Corresponds to [WebGPU `GPUBufferBinding`](
/// https://gpuweb.github.io/gpuweb/#dictdef-gpubufferbinding).
#[derive(Clone, Debug)]
pub struct BufferBinding<'a> {
/// The buffer to bind.
pub buffer: &'a Buffer,
/// Base offset of the buffer, in bytes.
///
/// If the [`has_dynamic_offset`] field of this buffer's layout entry is
/// `true`, the offset here will be added to the dynamic offset passed to
/// [`RenderPass::set_bind_group`] or [`ComputePass::set_bind_group`].
///
/// If the buffer was created with [`BufferUsages::UNIFORM`], then this
/// offset must be a multiple of
/// [`Limits::min_uniform_buffer_offset_alignment`].
///
/// If the buffer was created with [`BufferUsages::STORAGE`], then this
/// offset must be a multiple of
/// [`Limits::min_storage_buffer_offset_alignment`].
///
/// [`has_dynamic_offset`]: BindingType::Buffer::has_dynamic_offset
pub offset: BufferAddress,
/// Size of the binding in bytes, or `None` for using the rest of the buffer.
pub size: Option<BufferSize>,
}
#[cfg(send_sync)]
static_assertions::assert_impl_all!(BufferBinding<'_>: Send, Sync);
/// An element of a [`BindGroupDescriptor`], consisting of a bindable resource
/// and the slot to bind it to.
///
/// Corresponds to [WebGPU `GPUBindGroupEntry`](
/// https://gpuweb.github.io/gpuweb/#dictdef-gpubindgroupentry).
#[derive(Clone, Debug)]
pub struct BindGroupEntry<'a> {
/// Slot for which binding provides resource. Corresponds to an entry of the same
/// binding index in the [`BindGroupLayoutDescriptor`].
pub binding: u32,
/// Resource to attach to the binding
pub resource: BindingResource<'a>,
}
#[cfg(send_sync)]
static_assertions::assert_impl_all!(BindGroupEntry<'_>: Send, Sync);
/// Describes a group of bindings and the resources to be bound.
///
/// For use with [`Device::create_bind_group`].
///
/// Corresponds to [WebGPU `GPUBindGroupDescriptor`](
/// https://gpuweb.github.io/gpuweb/#dictdef-gpubindgroupdescriptor).
#[derive(Clone, Debug)]
pub struct BindGroupDescriptor<'a> {
/// Debug label of the bind group. This will show up in graphics debuggers for easy identification.
pub label: Label<'a>,
/// The [`BindGroupLayout`] that corresponds to this bind group.
pub layout: &'a BindGroupLayout,
/// The resources to bind to this bind group.
pub entries: &'a [BindGroupEntry<'a>],
}
#[cfg(send_sync)]
static_assertions::assert_impl_all!(BindGroupDescriptor<'_>: Send, Sync);