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}