Skip to main content

euv_engine/renderer/status/
enum.rs

1use super::*;
2
3/// Defines how new pixels are composited with existing pixels on the canvas.
4///
5/// Maps directly to the CSS `globalCompositeOperation` property.
6#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
7pub enum BlendMode {
8    /// The source is drawn over the destination (default alpha blending).
9    #[default]
10    Normal,
11    /// The source color is multiplied with the destination, producing a darker result.
12    Multiply,
13    /// The source and destination are inverted, multiplied, then inverted again.
14    Screen,
15    /// The source and destination colors are added together, clamped to maximum brightness.
16    Lighter,
17    /// Combines `Multiply` and `Screen` based on the destination color.
18    Overlay,
19    /// Keeps the darker of the source and destination per channel.
20    Darken,
21    /// Keeps the lighter of the source and destination per channel.
22    Lighten,
23    /// Dodges the destination color brightening it based on the source.
24    ColorDodge,
25    /// Burns the destination color darkening it based on the source.
26    ColorBurn,
27    /// A harsher version of `Overlay` using the source color as the filter.
28    HardLight,
29    /// A softer version of `Overlay` using the source color as the filter.
30    SoftLight,
31    /// Subtracts the darker color from the lighter color per channel.
32    Difference,
33    /// Similar to `Difference` but with lower contrast.
34    Exclusion,
35    /// Uses the hue of the source with the saturation and luminosity of the destination.
36    Hue,
37    /// Uses the saturation of the source with the hue and luminosity of the destination.
38    Saturation,
39    /// Uses the hue and saturation of the source with the luminosity of the destination.
40    Color,
41    /// Uses the luminosity of the source with the hue and saturation of the destination.
42    Luminosity,
43}
44
45/// Rendering quality preset controlling anti-aliasing smoothing strategy.
46///
47/// Maps to the canvas `imageSmoothingQuality` value plus an explicit
48/// `imageSmoothingEnabled` toggle. Combined with a CSS `image-rendering:
49/// pixelated` rule on the consumer side, `Low` produces crisp pixel-art
50/// rendering while `High` produces smooth vector-style rendering.
51#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
52pub enum RenderQuality {
53    /// Fastest rendering, pixelated scaling.
54    ///
55    /// Disables `imageSmoothingEnabled` on the canvas context and sets
56    /// `imageSmoothingQuality = "low"`. Pair with CSS `image-rendering:
57    /// pixelated` for sharp nearest-neighbour scaling.
58    Low,
59    /// Balanced rendering with default smoothing quality.
60    ///
61    /// Sets `imageSmoothingQuality = "medium"`.
62    Medium,
63    /// Highest fidelity rendering with smooth edges and high-quality scaling.
64    ///
65    /// Sets `imageSmoothingQuality = "high"`. Best for vector-style content
66    /// on HiDPI displays. This is the default — when no explicit quality is
67    /// requested, the engine errs on the side of visual fidelity rather than
68    /// performance, since users typically notice aliasing artifacts before
69    /// they notice a few extra milliseconds of GPU time.
70    #[default]
71    High,
72}
73
74/// Whether a vertex buffer is consumed per-vertex or per-instance.
75#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
76pub enum VertexStepMode {
77    /// Advance the buffer one vertex at a time.
78    #[default]
79    Vertex,
80    /// Advance the buffer one entry at a time, for all vertices of an
81    /// instance.
82    Instance,
83}
84
85/// What a render pass attachment does with the contents it already holds
86/// before the pass draws anything.
87///
88/// Replaces the `"clear"` / `"load"` string literals that
89/// `GpuRenderPassColorAttachment.loadOp` and
90/// `GpuRenderPassDepthStencilAttachment.depthLoadOp` accept. A typo in a
91/// string literal is a silent runtime failure (the browser rejects the pass
92/// and the frame renders nothing); a typo in a variant is a compile error.
93#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
94pub enum LoadOp {
95    /// Overwrite the attachment with its clear value before drawing.
96    ///
97    /// The clear value is [`ColorAttachment::clear`] for color
98    /// attachments and [`DepthStencilAttachment::depth_clear`] for
99    /// depth-stencil attachments. WebGPU requires the clear value to be
100    /// present whenever this variant is used, which is why the clear
101    /// fields on those two structs are `Option` and paired with a
102    /// non-optional load op rather than with `Option<&'static str>`
103    /// defaults resolved by heuristic.
104    #[default]
105    Clear,
106    /// Keep the attachment's existing contents and draw over them.
107    ///
108    /// The clear value must be absent; any value present is ignored.
109    Load,
110}
111
112/// What a render pass attachment does with the contents it produced once the
113/// pass ends.
114///
115/// Replaces the `"store"` / `"discard"` string literals accepted by
116/// `storeOp` and `depthStoreOp`. `Discard` saves bandwidth for attachments
117/// the pass writes but nothing ever reads back — the depth buffer of a
118/// depth-test-only pass is the canonical case.
119#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
120pub enum StoreOp {
121    /// Keep the attachment's contents after the pass so later passes can
122    /// read or resolve them.
123    #[default]
124    Store,
125    /// Drop the attachment's contents after the pass.
126    Discard,
127}
128
129/// One legal use of a GPU buffer, as declared in `GpuBufferDescriptor.usage`.
130///
131/// The WebGPU buffer usage field is a bitmask, not an enum: a buffer may
132/// be used for several purposes at once. This enum names the individual
133/// bits so call sites never hand-write a magic number, and the renderer
134/// ORs the selected variants into the bitmask at the call site. Combine
135/// bits with `|`, e.g. `BufferUsage::Vertex | BufferUsage::CopyDestination`.
136#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
137pub enum BufferUsage {
138    /// The buffer may be mapped for reading from the CPU.
139    ///
140    /// Implies the buffer is host-visible, so it cannot be combined with
141    /// most other uses on conformant implementations.
142    MapRead,
143    /// The buffer may be mapped for writing from the CPU.
144    MapWrite,
145    /// The buffer may be the source of a `copyBufferToBuffer` / `copyTextureToBuffer` call.
146    CopySource,
147    /// The buffer may be the destination of a `copyBufferToBuffer` call or
148    /// of `queue.writeBuffer`.
149    CopyDestination,
150    /// The buffer holds an index list for `setIndexBuffer` and
151    /// `drawIndexed`.
152    Index,
153    /// The buffer holds per-vertex or per-instance attributes for `setVertexBuffer`.
154    Vertex,
155    /// The buffer is bound as a `var<uniform>` in WGSL.
156    Uniform,
157    /// The buffer is bound as a `var<storage>` in WGSL.
158    Storage,
159    /// The buffer holds the arguments of an indirect draw or dispatch.
160    Indirect,
161    /// The buffer is the destination of `commandEncoder.resolveQuerySet`.
162    QueryResolve,
163}
164
165/// One legal use of a GPU texture, as declared in `GpuTextureDescriptor.usage`.
166///
167/// Like [`BufferUsage`], the underlying WebGPU field is a bitmask and the
168/// renderer ORs the selected variants together at the call site. A render
169/// target needs `RenderAttachment`; a sampled texture needs
170/// `TextureBinding`; a write-once compute output needs `StorageBinding`.
171#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
172pub enum TextureUsage {
173    /// The texture may be the source of a texture-to-texture or
174    /// texture-to-buffer copy.
175    CopySource,
176    /// The texture may be the destination of `queue.writeTexture` or of a
177    /// texture-to-texture copy.
178    CopyDestination,
179    /// The texture is sampled through a `texture_2d<f32>` binding.
180    TextureBinding,
181    /// The texture is written through a `texture_storage_2d<...>` binding.
182    StorageBinding,
183    /// The texture is bound as a color, depth, or stencil attachment of a
184    /// render pass.
185    RenderAttachment,
186}
187
188/// How texels are interpolated when a sample is fetched.
189///
190/// Used for both the magnification filter (`magFilter`) and the
191/// minification filter (`minFilter`) of a sampler. The two filters are
192/// separate WebGPU fields because a magnified surface and a minified
193/// surface of the same texture want different behaviour — pixel art wants
194/// `Nearest` when magnified and `Linear` when minified — so a single
195/// [`SamplerDescriptor::filter`] covers both by letting the caller pick
196/// the same mode or override it per stage.
197#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
198pub enum FilterMode {
199    /// Sample the nearest texel. Keeps hard edges and is the correct
200    /// choice for pixel art and for integer data.
201    Nearest,
202    /// Blend the neighbouring texels. Smooths magnification and
203    /// minification alike.
204    #[default]
205    Linear,
206}
207
208/// How texels are blended between adjacent mip levels of a mipmapped
209/// texture.
210///
211/// This is the `mipmapFilter` field of a sampler, which is a separate
212/// decision from [`FilterMode`]: `FilterMode` decides how one mip level is
213/// sampled, this decides how the results of two levels are combined.
214#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
215pub enum MipmapFilter {
216    /// Pick one mip level. Avoids the extra texture fetches that
217    /// trilinear filtering costs, at the price of visible mip transitions.
218    Nearest,
219    /// Blend the two nearest mip levels. Smoother across the mip
220    /// transition, one extra texture fetch per sample.
221    #[default]
222    Linear,
223}
224
225/// What a sampler does with coordinates that fall outside `[0, 1]`.
226///
227/// One value per texture axis (`addressModeU`, `addressModeV`,
228/// `addressModeW` on the wire). The W axis is only meaningful for 3D
229/// textures; for 2D textures it is accepted and ignored.
230#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
231pub enum AddressMode {
232    /// Clamp to the edge texel, stretching it outwards. The right default
233    /// for anything that is not meant to tile.
234    #[default]
235    ClampToEdge,
236    /// Mirror the texture at each edge, so `0..1` then `1..0` then `0..1`.
237    MirrorRepeat,
238    /// Tile the texture, so `0..1` then `0..1` again.
239    Repeat,
240}
241
242/// The comparison performed between two values, used both for depth tests
243/// and for comparison samplers.
244///
245/// Replaces the bare `&'static str` that
246/// `GpuSamplerDescriptor.compare` could not express: a `bool` there forced
247/// the renderer to hardcode a single comparison, while
248/// [`SamplerDescriptor::compare`] carries the comparison itself as
249/// `Option<CompareFunction>` — `None` for a plain filtering sampler.
250#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
251pub enum CompareFunction {
252    /// Never passes: the test always fails.
253    Never,
254    /// Passes when the incoming value is strictly less than the reference.
255    #[default]
256    Less,
257    /// Passes when the two values are equal.
258    Equal,
259    /// Passes when the incoming value is less than or equal to the reference.
260    LessEqual,
261    /// Passes when the incoming value is strictly greater than the reference.
262    Greater,
263    /// Passes when the two values differ.
264    NotEqual,
265    /// Passes when the incoming value is greater than or equal to the reference.
266    GreaterEqual,
267    /// Always passes: the test never fails.
268    ///
269    /// Useful for an always-visible overlay drawn after the opaque pass,
270    /// where the depth buffer must be bound but must not reject anything.
271    Always,
272}
273
274/// One term of a blend equation: the factor the source or destination value
275/// is multiplied by.
276///
277/// A blend state pairs one of these as the source factor and one as the
278/// destination factor, then combines the two results with a
279/// [`BlendOperation`]. The conventional alpha-blend pairing is
280/// `SourceAlpha` as the source and `OneMinusSourceAlpha` as the
281/// destination, with `BlendOperation::Add`.
282#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
283pub enum BlendFactor {
284    /// `0` — the term contributes nothing.
285    Zero,
286    /// `1` — the term passes through unchanged.
287    One,
288    /// The source color, for a source factor; the destination color, for a
289    /// destination factor.
290    SourceColor,
291    /// `1` minus the source color, for a source factor.
292    OneMinusSourceColor,
293    /// The destination color, for a source factor; the source color, for a
294    /// destination factor.
295    DestinationColor,
296    /// `1` minus the destination color, for a source factor.
297    OneMinusDestinationColor,
298    /// The source alpha.
299    #[default]
300    SourceAlpha,
301    /// `1` minus the source alpha. The conventional destination factor for
302    /// alpha blending.
303    OneMinusSourceAlpha,
304    /// The destination alpha, for a destination factor.
305    DestinationAlpha,
306    /// `1` minus the destination alpha, for a source factor.
307    OneMinusDestinationAlpha,
308    /// The blend constant set via `setBlendConstant`.
309    ConstantColor,
310    /// `1` minus the blend constant.
311    OneMinusConstantColor,
312    /// The alpha of the blend constant.
313    ConstantAlpha,
314    /// `1` minus the alpha of the blend constant.
315    OneMinusConstantAlpha,
316    /// The smaller of the source alpha and `1 - destination alpha`, which is
317    /// what keeps repeated alpha-blended passes from accumulating
318    /// saturation.
319    SourceAlphaSaturated,
320}
321
322/// How the two blended terms are combined into the final value.
323#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
324pub enum BlendOperation {
325    /// `source + destination`. The default, and what alpha blending needs.
326    #[default]
327    Add,
328    /// `source - destination`.
329    Subtract,
330    /// `destination - source`.
331    ReverseSubtract,
332    /// `min(source, destination)`.
333    Min,
334    /// `max(source, destination)`.
335    Max,
336}
337
338/// How the vertex stage assembles the stream of vertices into primitives.
339#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
340pub enum PrimitiveTopology {
341    /// One independent point per vertex.
342    PointList,
343    /// One independent line segment per pair of vertices.
344    LineList,
345    /// One connected polyline through every vertex.
346    LineStrip,
347    /// One independent triangle per three vertices. The default, and the
348    /// only topology an indexed mesh needs.
349    #[default]
350    TriangleList,
351    /// One connected triangle strip through every vertex.
352    TriangleStrip,
353}
354
355/// The element width of the index buffer handed to `setIndexBuffer`.
356///
357/// The format must match the element type of the index data and the
358/// [`PrimitiveState::strip_index_format`] when a strip topology is used.
359#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
360pub enum IndexFormat {
361    /// 16-bit unsigned indices. Halves the index buffer, but a mesh with
362    /// more than 65536 vertices would silently wrap.
363    Uint16,
364    /// 32-bit unsigned indices.
365    #[default]
366    Uint32,
367}
368
369/// The shader stages a bind group layout entry is visible to.
370///
371/// The wire field is a bitmask, so entries are usually visible to more
372/// than one stage; the renderer ORs the selected variants together at the
373/// call site. This replaces the raw `visibility: u32` on
374/// [`BindGroupLayoutEntry`], where `0x1` / `0x2` / `0x4` were written by
375/// hand and a wrong bit silently produced a binding the shader cannot see.
376#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
377pub enum ShaderStage {
378    /// The vertex stage, mask value `0x1`.
379    Vertex,
380    /// The fragment stage, mask value `0x2`.
381    Fragment,
382    /// The compute stage, mask value `0x4`.
383    Compute,
384}
385
386/// Which winding order counts as the front face of a triangle.
387///
388/// The two sides are labelled only relative to this choice, so flipping
389/// it swaps what [`CullMode::Front`] and [`CullMode::Back`] discard.
390#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
391pub enum FrontFace {
392    /// Counter-clockwise triangles, in framebuffer coordinates, are front
393    /// facing.
394    #[default]
395    CounterClockwise,
396    /// Clockwise triangles, in framebuffer coordinates, are front facing.
397    Clockwise,
398}
399
400/// Which triangle faces are discarded before rasterization.
401#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
402pub enum CullMode {
403    /// Keep both faces. The default, and the right choice for 2D content
404    /// and for double-sided materials.
405    #[default]
406    None,
407    /// Discard front-facing triangles.
408    Front,
409    /// Discard back-facing triangles. The usual choice for closed solid
410    /// geometry, which roughly halves rasterization work.
411    Back,
412}
413
414/// The in-memory layout of one vertex attribute.
415///
416/// Maps to the `GPUVertexAttribute.format` field. A position of three
417/// `f32` is `Float32x3`; a packed 8-bit-per-channel color is `Unorm8x4`.
418#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
419pub enum VertexAttributeFormat {
420    /// One 32-bit float.
421    Float32,
422    /// Two 32-bit floats, laid out as an `x` / `y` pair.
423    #[default]
424    Float32x2,
425    /// Three 32-bit floats, laid out as an `x` / `y` / `z` triple.
426    Float32x3,
427    /// Four 32-bit floats, laid out as `x` / `y` / `z` / `w`.
428    Float32x4,
429    /// Four 8-bit unsigned-normalized channels in one 32-bit word.
430    Unorm8x4,
431    /// One 32-bit unsigned integer.
432    Uint32,
433    /// One 32-bit signed integer.
434    Sint32,
435}
436
437/// The texture formats the renderer supports, as a closed set.
438///
439/// Deliberately a subset of the WebGPU format list: every variant here is
440/// one the renderer's attachment, binding, and sampling paths are known
441/// to handle. Naming them as an enum turns a wrong format string into a
442/// compile error rather than a validation-layer rejection at creation time.
443#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
444pub enum GpuTextureFormat {
445    /// Four 8-bit channels, normalized to `0.0..=1.0`. The default, and
446    /// the format `gpu.getPreferredCanvasFormat()` usually resolves to
447    /// when the platform is not BGRA.
448    #[default]
449    Rgba8Unorm,
450    /// Four 8-bit channels in blue-green-red-alpha order. The swap-chain
451    /// format on most desktop GPUs.
452    Bgra8Unorm,
453    /// Four 16-bit floating-point channels. A render target for HDR passes,
454    /// which then tone-map on resolve.
455    Rgba16Float,
456    /// 24-bit depth, no stencil. The usual choice for a shadow map or any
457    /// other single-sample depth attachment.
458    Depth24Plus,
459    /// 24-bit depth plus an 8-bit stencil, in one 32-bit word.
460    Depth24PlusStencil8,
461    /// 32-bit floating-point depth. Needed for view-space z-buffers.
462    Depth32Float,
463    /// One 32-bit floating-point channel. A single-channel render target
464    /// and the usual format for a read-only storage binding.
465    R32Float,
466    /// Four 32-bit floating-point channels. The format for a compute
467    /// shader's read-write storage output.
468    Rgba32Float,
469}
470
471/// The class of error a WebGPU error scope collects.
472///
473/// Pushed onto `GpuDevice` via
474/// [`WebGpuRenderer::push_error_scope`]; every error of this class raised
475/// while the scope is open is captured instead of being reported to the
476/// console immediately. A typo in the filter string is a silent
477/// behaviour change - `pushErrorScope` accepts any string and simply
478/// never matches - so the filter is named as a variant.
479#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
480pub enum GpuErrorFilter {
481    /// Captures spec violations: shader compile errors, bind-group
482    /// mismatches, out-of-bounds draws, invalid descriptors. The filter
483    /// to reach for when wrapping a single `create_*` call.
484    #[default]
485    Validation,
486    /// Captures allocation failures. Distinct from `Validation` because a
487    /// driver may reject a large allocation that is perfectly legal.
488    OutOfMemory,
489    /// Captures failures originating inside the browser or driver rather
490    /// than in the submitted commands. Rare, and usually fatal for the
491    /// device.
492    Internal,
493}