Skip to main content

euv_engine/renderer/status/
impl.rs

1use super::*;
2
3/// Implements CSS composite operation string conversion for `BlendMode`.
4impl BlendMode {
5    /// Returns the CSS `globalCompositeOperation` string for this blend mode.
6    ///
7    /// # Returns
8    ///
9    /// - `&str` - The CSS composite operation string.
10    pub fn to_css(&self) -> &str {
11        match self {
12            BlendMode::Normal => BLEND_MODE_NORMAL,
13            BlendMode::Multiply => BLEND_MODE_MULTIPLY,
14            BlendMode::Screen => BLEND_MODE_SCREEN,
15            BlendMode::Lighter => BLEND_MODE_LIGHTER,
16            BlendMode::Overlay => BLEND_MODE_OVERLAY,
17            BlendMode::Darken => BLEND_MODE_DARKEN,
18            BlendMode::Lighten => BLEND_MODE_LIGHTEN,
19            BlendMode::ColorDodge => BLEND_MODE_COLOR_DODGE,
20            BlendMode::ColorBurn => BLEND_MODE_COLOR_BURN,
21            BlendMode::HardLight => BLEND_MODE_HARD_LIGHT,
22            BlendMode::SoftLight => BLEND_MODE_SOFT_LIGHT,
23            BlendMode::Difference => BLEND_MODE_DIFFERENCE,
24            BlendMode::Exclusion => BLEND_MODE_EXCLUSION,
25            BlendMode::Hue => BLEND_MODE_HUE,
26            BlendMode::Saturation => BLEND_MODE_SATURATION,
27            BlendMode::Color => BLEND_MODE_COLOR,
28            BlendMode::Luminosity => BLEND_MODE_LUMINOSITY,
29        }
30    }
31}
32
33/// Inherent implementation of [`VertexStepMode`].
34impl VertexStepMode {
35    /// Returns the WGSL / WebGPU string representation.
36    ///
37    /// # Returns
38    ///
39    /// - `&'static str` - A static `&str` representation.
40    pub fn as_str(&self) -> &'static str {
41        match self {
42            Self::Vertex => WEBGPU_VERTEX_STEP_MODE_VERTEX,
43            Self::Instance => WEBGPU_VERTEX_STEP_MODE_INSTANCE,
44        }
45    }
46}
47
48/// Combines two buffer uses into the bitmask a `GpuBufferDescriptor`
49/// expects.
50///
51/// A buffer may be used for several purposes at once, and the WebGPU
52/// `usage` field is a bitmask rather than an enum, so combining uses is
53/// the normal case rather than the exception. The `|` operator is the
54/// only way the engine combines them, which keeps every bit value in
55/// exactly one place.
56impl BitOr for BufferUsage {
57    /// The combined `usage` bitmask.
58    type Output = u32;
59
60    /// Combines two buffer uses into their `usage` bitmask.
61    ///
62    /// # Arguments
63    ///
64    /// - `Self` - The right-hand use.
65    ///
66    /// # Returns
67    ///
68    /// - `Self::Output` - The bitmask carrying both uses.
69    fn bitor(self, rhs: Self) -> Self::Output {
70        buffer_usage_bit(self) | buffer_usage_bit(rhs)
71    }
72}
73
74/// Combines two texture uses into the bitmask a `GpuTextureDescriptor`
75/// expects.
76///
77/// The texture counterpart of the `|` operator on [`BufferUsage`], with
78/// the same single-source-of-truth rationale.
79impl BitOr for TextureUsage {
80    /// The combined `usage` bitmask.
81    type Output = u32;
82
83    /// Combines two texture uses into their `usage` bitmask.
84    ///
85    /// # Arguments
86    ///
87    /// - `Self` - The right-hand use.
88    ///
89    /// # Returns
90    ///
91    /// - `Self::Output` - The bitmask carrying both uses.
92    fn bitor(self, rhs: Self) -> Self::Output {
93        texture_usage_bit(self) | texture_usage_bit(rhs)
94    }
95}
96
97/// Combines two shader stages into the visibility bitmask a bind group
98/// layout entry expects.
99///
100/// The third of the three bitmask-carrying WebGPU enums; see
101/// [`BufferUsage`] for why combining is expressed as an operator rather
102/// than a helper call.
103impl BitOr for ShaderStage {
104    /// The combined visibility bitmask.
105    type Output = ShaderStages;
106
107    /// Combines two shader stages into their visibility bitmask.
108    ///
109    /// # Arguments
110    ///
111    /// - `Self` - The right-hand stage.
112    ///
113    /// # Returns
114    ///
115    /// - `Self::Output` - The mask naming both stages.
116    fn bitor(self, rhs: Self) -> Self::Output {
117        ShaderStages(shader_stage_bit(self) | shader_stage_bit(rhs))
118    }
119}
120
121/// The mask arithmetic behind [`ShaderStages`], kept next to the
122/// [`BitOr`] impl for [`ShaderStage`] that produces one.
123impl ShaderStages {
124    /// The raw `GPUShaderStage` bitmask this mask stands for.
125    ///
126    /// # Returns
127    ///
128    /// - `u32` - The combined bits, ready for the wire.
129    pub fn bits(self) -> u32 {
130        self.0
131    }
132
133    /// Whether this mask names no stage at all.
134    ///
135    /// A bind group layout slot with an empty mask is visible to
136    /// nothing, which the driver reports as a validation error rather
137    /// than as a silently unreachable binding.
138    ///
139    /// # Returns
140    ///
141    /// - `bool` - `true` when no stage is named.
142    pub fn is_empty(self) -> bool {
143        self.0 == 0
144    }
145
146    /// Whether one stage is among the stages this mask names.
147    ///
148    /// # Arguments
149    ///
150    /// - `ShaderStage` - The stage to test for.
151    ///
152    /// # Returns
153    ///
154    /// - `bool` - `true` when the stage's bit is set.
155    pub fn contains(self, stage: ShaderStage) -> bool {
156        self.0 & shader_stage_bit(stage) == shader_stage_bit(stage)
157    }
158}
159
160/// Lets a lone stage stand in where a mask is expected, so every
161/// single-stage call site keeps reading as one.
162impl From<ShaderStage> for ShaderStages {
163    /// Widens one stage into a mask naming only that stage.
164    ///
165    /// # Arguments
166    ///
167    /// - `ShaderStage` - The stage the mask should name.
168    ///
169    /// # Returns
170    ///
171    /// - `ShaderStages` - A mask with that stage's single bit set.
172    fn from(value: ShaderStage) -> Self {
173        ShaderStages(shader_stage_bit(value))
174    }
175}
176
177/// Adding a stage to a mask that already names others.
178impl BitOr<ShaderStage> for ShaderStages {
179    /// The widened mask.
180    type Output = ShaderStages;
181
182    /// Sets one more stage's bit, leaving the existing bits alone.
183    ///
184    /// # Arguments
185    ///
186    /// - `ShaderStage` - The stage to add.
187    ///
188    /// # Returns
189    ///
190    /// - `Self::Output` - The mask naming both sides.
191    fn bitor(self, rhs: ShaderStage) -> Self::Output {
192        ShaderStages(self.0 | shader_stage_bit(rhs))
193    }
194}
195
196/// Combining two masks, which is what a caller reaches for when the two
197/// halves of a layout entry are built independently.
198impl BitOr for ShaderStages {
199    /// The union of the two masks.
200    type Output = ShaderStages;
201
202    /// Sets every bit either side names.
203    ///
204    /// # Arguments
205    ///
206    /// - `Self` - The right-hand mask.
207    ///
208    /// # Returns
209    ///
210    /// - `Self::Output` - The mask naming both sides.
211    fn bitor(self, rhs: Self) -> Self::Output {
212        ShaderStages(self.0 | rhs.0)
213    }
214}
215
216/// The `GPUBufferUsage` bit one use occupies.
217///
218/// The canonical WebGPU values, in one place: a buffer's legal uses
219/// are a `GPUTextureUsage`-style bitmask, and getting a bit wrong
220/// produces a buffer that validates in some draws and silently loses
221/// the access in others. Keeping the table on the enum itself means a
222/// call site cannot reference a stale duplicate constant.
223impl BufferUsage {
224    /// The `GPUBufferUsage` bit this use occupies.
225    ///
226    /// # Returns
227    ///
228    /// - `u32` - The bit this use occupies in a `GpuBufferDescriptor`
229    ///   `usage`; combine several with `|`.
230    pub fn usage_bit(self) -> u32 {
231        buffer_usage_bit(self)
232    }
233}
234
235/// The `GPUTextureUsage` bit one use occupies.
236///
237/// The texture-side counterpart of [`BufferUsage::usage_bit`]. Note
238/// that the buffer and texture families share their variant *names*
239/// but not their *values* - `CopySource` is `4` for a buffer and `1`
240/// for a texture - which is why the two tables are separate.
241impl TextureUsage {
242    /// The `GPUTextureUsage` bit this use occupies.
243    ///
244    /// # Returns
245    ///
246    /// - `u32` - The bit this use occupies in a `GpuTextureDescriptor`
247    ///   `usage`; combine several with `|`.
248    pub fn usage_bit(self) -> u32 {
249        texture_usage_bit(self)
250    }
251}
252
253/// The `GPUShaderStage` bit one pipeline stage occupies.
254impl ShaderStage {
255    /// The `GPUShaderStage` bit this pipeline stage occupies.
256    ///
257    /// # Returns
258    ///
259    /// - `u32` - The bit this stage occupies in a
260    ///   `BindGroupLayoutEntry` `visibility`; combine several with
261    ///   `|`.
262    pub fn stage_bit(self) -> u32 {
263        shader_stage_bit(self)
264    }
265}