Skip to main content

molgfx_gpu/descriptors/
binding.rs

1//! Bind-group layouts and bind groups.
2//!
3//! Bind groups are numbered by update frequency, a fixed convention every
4//! layout declaration documents: group 0 per-frame (camera, lights, time),
5//! group 1 per-pass, group 2 per-representation, group 3 per-material. This
6//! ordering minimizes rebinds.
7
8use crate::device::Device;
9
10bitflags::bitflags! {
11    /// Which stages see a binding.
12    #[derive(Clone, Copy, PartialEq, Eq, Debug)]
13    pub struct ShaderStages: u32 {
14        /// Vertex stage.
15        const VERTEX = 1;
16        /// Fragment stage.
17        const FRAGMENT = 1 << 1;
18        /// Compute stage.
19        const COMPUTE = 1 << 2;
20    }
21}
22
23/// What kind of resource a binding slot holds.
24#[derive(Clone, Copy, PartialEq, Eq, Debug)]
25pub enum BindingType {
26    /// A uniform buffer.
27    Uniform,
28    /// A storage buffer.
29    Storage {
30        /// Whether shaders only read it.
31        read_only: bool,
32    },
33    /// A sampled 2-D texture.
34    Texture {
35        /// Whether the texel type is filterable float (versus unsigned
36        /// integer, e.g. the entity-id channel).
37        filterable: bool,
38    },
39    /// A sampled 3-D floating-point texture.
40    Texture3dFloat {
41        /// Whether hardware linear filtering is required.
42        filterable: bool,
43    },
44    /// A sampled 3-D unsigned-integer texture.
45    Texture3dUint,
46    /// A write-only 3-D storage texture used by compute-generated fields.
47    StorageTexture3dWrite {
48        /// Portable storage format shared by the layout and texture.
49        format: crate::TextureFormat,
50    },
51    /// A depth texture read texel by texel, never compared or filtered.
52    ///
53    /// Shaders declare it as `texture_2d<f32>` and read the depth from the
54    /// first channel of a `textureLoad`.
55    DepthTexture,
56    /// A sampler.
57    Sampler {
58        /// Whether it is a comparison sampler.
59        comparison: bool,
60    },
61}
62
63/// One slot in a bind-group layout: index, visibility, kind. Every binding
64/// index is declared here with a name; shaders never invent one.
65#[derive(Clone, Copy, Debug)]
66pub struct BindGroupLayoutEntry {
67    /// Binding index within the group.
68    pub binding: u32,
69    /// Stages that access it.
70    pub visibility: ShaderStages,
71    /// The resource kind.
72    pub ty: BindingType,
73}
74
75/// Everything needed to create a bind-group layout.
76#[derive(Clone, Copy, Debug)]
77pub struct BindGroupLayoutDesc<'a> {
78    /// Debug label; by convention states the group's update frequency.
79    pub label: &'static str,
80    /// The slots, in binding order.
81    pub entries: &'a [BindGroupLayoutEntry],
82}
83
84/// A live resource bound into a slot.
85#[derive(Debug)]
86pub enum BindGroupEntry<'a, D: Device> {
87    /// A whole buffer.
88    Buffer {
89        /// Binding index.
90        binding: u32,
91        /// The buffer.
92        buffer: &'a D::Buffer,
93    },
94    /// A contiguous slice of a buffer.
95    ///
96    /// Binding a range rather than a whole buffer is what lets one packed
97    /// table be drawn as several groups: each group's shader sees its slice
98    /// starting at instance zero, so no draw needs a first-instance offset —
99    /// a capability the portable baseline does not guarantee.
100    BufferRange {
101        /// Binding index.
102        binding: u32,
103        /// The buffer holding every group.
104        buffer: &'a D::Buffer,
105        /// Byte offset of this group; a multiple of the device's storage
106        /// binding alignment.
107        offset: u64,
108        /// Length of this group in bytes.
109        size: u64,
110    },
111    /// A texture view.
112    Texture {
113        /// Binding index.
114        binding: u32,
115        /// The view.
116        view: &'a D::TextureView,
117    },
118    /// A sampler.
119    Sampler {
120        /// Binding index.
121        binding: u32,
122        /// The sampler.
123        sampler: &'a D::Sampler,
124    },
125}
126
127/// Everything needed to create a bind group over a layout.
128#[derive(Debug)]
129pub struct BindGroupDesc<'a, D: Device> {
130    /// Debug label.
131    pub label: &'static str,
132    /// The layout this group instantiates.
133    pub layout: &'a D::BindGroupLayout,
134    /// The bound resources.
135    pub entries: &'a [BindGroupEntry<'a, D>],
136}
137
138/// One TLAS resource bound into a ray-query bind group.
139#[derive(Clone, Copy, Debug)]
140pub struct AccelerationStructureBinding<'a, D: Device> {
141    /// Binding index within the group.
142    pub binding: u32,
143    /// Top-level acceleration structure.
144    pub tlas: &'a D::Tlas,
145}
146
147/// One acceleration-structure slot in a ray-query bind-group layout.
148#[derive(Clone, Copy, Debug)]
149pub struct AccelerationStructureLayoutEntry {
150    /// Binding index within the group.
151    pub binding: u32,
152    /// Shader stages that may issue ray queries.
153    pub visibility: ShaderStages,
154}
155
156/// Layout containing regular slots and acceleration-structure slots.
157#[derive(Debug)]
158pub struct RayQueryBindGroupLayoutDesc<'a> {
159    /// Diagnostic label.
160    pub label: &'static str,
161    /// Buffer, texture and sampler slots.
162    pub entries: &'a [BindGroupLayoutEntry],
163    /// TLAS slots.
164    pub acceleration_structures: &'a [AccelerationStructureLayoutEntry],
165}
166
167/// Bind group containing regular resources and TLAS resources.
168#[derive(Debug)]
169pub struct RayQueryBindGroupDesc<'a, D: Device> {
170    /// Diagnostic label.
171    pub label: &'static str,
172    /// Layout containing matching acceleration-structure entries.
173    pub layout: &'a D::BindGroupLayout,
174    /// Buffer, texture and sampler resources.
175    pub entries: &'a [BindGroupEntry<'a, D>],
176    /// TLAS resources.
177    pub acceleration_structures: &'a [AccelerationStructureBinding<'a, D>],
178}