euv_engine/renderer/descriptor/struct.rs
1use super::*;
2
3/// Describes a 2D viewport rectangle plus optional depth range, in the same
4/// pixel space as the destination render target.
5///
6/// Used by [`WebGpuRenderer::set_viewport`] (and any future caller that needs
7/// to push a `GpuViewport`-shaped JS object through `Reflect::set`). The
8/// depth-range fields are omitted from the `::new` constructor via
9/// `#[new(skip)]`; they default to zero-initialised `f32` and are typically
10/// overwritten by [`WebGpuRenderer::set_viewport`] to the WebGPU spec
11/// defaults of `0.0` / `1.0`.
12#[derive(Clone, Copy, Data, Debug, New, PartialEq)]
13pub struct ViewportDescriptor {
14 /// X coordinate of the viewport's top-left in pixels.
15 #[get(type(copy))]
16 #[get_mut(pub(crate))]
17 pub x: f32,
18 /// Y coordinate of the viewport's top-left in pixels.
19 #[get(type(copy))]
20 pub y: f32,
21 /// Viewport width in pixels.
22 #[get(type(copy))]
23 #[set(pub(crate))]
24 #[get_mut(pub(crate))]
25 pub width: f32,
26 /// Viewport height in pixels.
27 #[get(type(copy))]
28 #[set(pub(crate))]
29 #[get_mut(pub(crate))]
30 pub height: f32,
31 /// Minimum depth, clamped to `[0, 1]`. Set to `0.0` to disable.
32 #[new(skip)]
33 #[get(pub(crate), type(copy))]
34 pub min_depth: f32,
35 /// Maximum depth, clamped to `[0, 1]`. Set to `1.0` to disable.
36 #[new(skip)]
37 #[get(pub(crate), type(copy))]
38 #[get_mut(pub(crate))]
39 pub max_depth: f32,
40}
41
42/// A single vertex attribute within a vertex buffer layout.
43///
44/// Mirrors the fields of `GPUVertexAttribute` exactly. The shader location
45/// is the `@location(N)` qualifier in the WGSL source. The offset is in
46/// bytes from the start of the vertex, and `format` is one of the
47/// WGSL vertex format strings (e.g. `"float32x4"`, `"unorm8x4"`).
48#[derive(Clone, Copy, Debug, Eq, Getter, Hash, New, PartialEq)]
49pub struct VertexAttribute {
50 /// The shader location the attribute maps to.
51 #[get(pub(crate), type(copy))]
52 pub(crate) shader_location: u32,
53 /// The byte offset from the start of the vertex.
54 #[get(type(copy))]
55 pub offset: u64,
56 /// The in-memory layout of the attribute, as one of the
57 /// [`VertexAttributeFormat`] variants. Naming it turns a wrong
58 /// format string into a compile error rather than a pipeline
59 /// validation failure at creation time.
60 #[get(type(copy))]
61 pub format: VertexAttributeFormat,
62}
63
64/// The layout of a single vertex buffer, expressed as an array stride plus
65/// a list of attributes.
66///
67/// Mirrors `GPUVertexBufferLayout` from the WebGPU spec. The renderer
68/// passes the assembled descriptor straight to `createRenderPipeline` via
69/// `Reflect`.
70#[derive(Clone, Debug, Getter, New)]
71pub struct VertexBufferLayout {
72 /// The byte stride of one vertex in the buffer.
73 #[get(pub(crate), type(copy))]
74 pub(crate) array_stride: u64,
75 /// Whether the buffer should be advanced per-instance (`true`) or
76 /// per-vertex (`false`).
77 #[get(pub(crate), type(copy))]
78 pub(crate) step_mode: VertexStepMode,
79 /// The attributes that describe how to interpret the bytes of one
80 /// vertex.
81 #[get(pub(crate))]
82 pub(crate) attributes: Vec<VertexAttribute>,
83}
84
85/// A 2D texture descriptor for `create_texture_2d`.
86///
87/// Defaults produce a 1x1 RGBA8 texture with `TEXTURE_BINDING | COPY_DST
88/// | COPY_SRC` usage, which is the right baseline for a sampled color
89/// texture that is uploaded to via `queue.writeTexture`. Override fields
90/// after constructing to set `mip_level_count`, `sample_count`, or
91/// different `usage` flags.
92#[derive(Clone, Data, Debug, New)]
93pub struct Texture2DDescriptor {
94 /// The texture width in pixels. Must be > 0.
95 #[get(type(copy))]
96 #[set(pub(crate))]
97 #[get_mut(pub(crate))]
98 pub width: u32,
99 /// The texture height in pixels. Must be > 0.
100 #[get(type(copy))]
101 #[set(pub(crate))]
102 #[get_mut(pub(crate))]
103 pub height: u32,
104 /// The texel format, as one of the [`GpuTextureFormat`] variants.
105 #[get(type(copy))]
106 #[set(pub(crate))]
107 #[get_mut(pub(crate))]
108 pub format: GpuTextureFormat,
109 /// The number of mip levels. `0` is treated as `1`.
110 #[get(type(copy))]
111 #[new(skip)]
112 #[set(pub(crate))]
113 #[get_mut(pub(crate))]
114 pub mip_level_count: u32,
115 /// The number of samples per texel (`1` for non-MSAA, `4` for MSAA).
116 #[get(type(copy))]
117 #[new(skip)]
118 #[set(pub(crate))]
119 #[get_mut(pub(crate))]
120 pub sample_count: u32,
121}
122
123/// Descriptor for `GpuTexture.createView(descriptor)`.
124///
125/// Sub-selects a single cube face / mip / array slice / depth-aspect of a
126/// texture. When you need the full texture as a 2D view (the common case),
127/// just call `create_view` without a descriptor; the new method accepts an
128/// `Option<&TextureViewDescriptor>` for callers that need the full
129/// flexibility of the WebGPU spec.
130#[derive(Clone, Debug, Getter, New)]
131pub struct TextureViewDescriptor {
132 /// View format override, or `None` to use the texture's own format.
133 #[get(type(clone))]
134 #[new(value = "None")]
135 pub format: Option<&'static str>,
136 /// View dimension (`"2d"`, `"2d-array"`, `"cube"`, `"cube-array"`, ...).
137 /// `None` means the dimension is inferred from the texture.
138 #[get(type(clone))]
139 #[new(value = "None")]
140 pub dimension: Option<&'static str>,
141 /// Most significant mip level (inclusive). `None` → `0`.
142 #[get(type(copy))]
143 #[new(value = "0")]
144 pub base_mip_level: u32,
145 /// Number of mip levels in the view. `0` → all the way to the top.
146 #[get(type(copy))]
147 #[new(value = "0")]
148 pub mip_level_count: u32,
149 /// First array layer (inclusive). `None` → `0`. Only meaningful for
150 /// `2d-array` / `cube` / `cube-array` views.
151 #[get(type(copy))]
152 #[new(value = "0")]
153 pub base_array_layer: u32,
154 /// Number of array layers. `0` → all remaining layers.
155 #[get(type(copy))]
156 #[new(value = "0")]
157 pub array_layer_count: u32,
158 /// Which aspect of the texture to expose. One of:
159 /// `"all"`, `"depth-only"`, `"stencil-only"`. `None` → `"all"`.
160 #[get(type(clone))]
161 #[new(value = "None")]
162 pub aspect: Option<&'static str>,
163}
164
165/// Descriptor for `queue.writeTexture(destination, data, dataLayout, size)`.
166///
167/// WebGPU's `writeTexture` lets you upload CPU-side pixel data directly to a
168/// texture without staging through a buffer. Use it for: ImGui font atlases,
169/// procedural noise textures, sprite sheets, `ImageBitmap` pixels, etc.
170#[derive(Clone, Debug, Getter, New)]
171pub struct TextureWriteDescriptor {
172 /// The pixel data to upload. Bytes are laid out according to
173 /// `bytes_per_row` / `rows_per_image`.
174 #[get(type(clone))]
175 pub data: Vec<u8>,
176 /// Bytes per row of the source data. Must be a multiple of 256.
177 #[get(type(copy))]
178 pub bytes_per_row: u32,
179 /// Number of rows per image. `0` for 2D textures without mip chains.
180 #[get(type(copy))]
181 pub rows_per_image: u32,
182 /// Destination mip level to write into.
183 #[get(type(copy))]
184 pub mip_level: u32,
185 /// Destination texture to write into.
186 #[get(type(clone))]
187 pub texture: JsValue,
188 /// Origin within the destination texture. `None` → `(0, 0, 0)`.
189 #[get(type(clone))]
190 #[new(value = "None")]
191 pub origin: Option<JsValue>,
192 /// Whether to flip the source data vertically before writing.
193 /// `true` is essential when uploading from `<img>` / `<canvas>` whose
194 /// rows are top-to-bottom but WebGPU textures are bottom-to-top.
195 #[get(type(copy))]
196 #[new(value = "false")]
197 pub flip_y: bool,
198}
199
200/// A single entry inside a `GpuBindGroupLayoutDescriptor`.
201///
202/// Together these describe one slot of the bind group layout used by
203/// a render / compute pipeline. The `visibility` field names the
204/// shader stages that can read the binding as [`ShaderStage`] values
205/// combined with `|`; a hand-written `0x1` / `0x2` / `0x4` there
206/// silently produced a binding the shader could not see.
207#[derive(Clone, Debug)]
208pub struct BindGroupLayoutEntry {
209 /// The binding slot (matches `@binding(N)` in the shader).
210 pub binding: u32,
211 /// The shader stages that can read this binding. Combine several
212 /// with `|`, e.g. `ShaderStage::Vertex | ShaderStage::Fragment`.
213 pub visibility: ShaderStages,
214 /// The resource kind bound at this slot.
215 pub ty: BindGroupEntryType,
216}
217
218/// A strongly-typed sampler descriptor for `create_sampler`.
219///
220/// Replaces the historical `GpuSamplerDescriptor`, which spelled the
221/// filter and address modes as six independent `&'static str` fields plus
222/// a `compare: bool`. The new layout keeps the same information but as
223/// three orthogonal decisions — how to interpolate, how to blend mip
224/// levels, how to wrap — so the combinations the old fields allowed but
225/// the renderer could not express (a `Nearest` magnification filter with a
226/// `Linear` minification filter, a comparison other than the hardcoded
227/// one) are now expressible, and an invalid value is a compile error
228/// rather than a silently rejected `createSampler` call.
229#[derive(Clone, Copy, Data, Debug, New)]
230pub struct SamplerDescriptor {
231 /// How texels are interpolated within one mip level. Applied to both
232 /// the magnification and the minification filter.
233 #[get(type(copy))]
234 #[new(skip)]
235 #[get_mut(pub(crate))]
236 pub filter: FilterMode,
237 /// How results from adjacent mip levels are blended together.
238 #[get(type(copy))]
239 #[new(skip)]
240 #[get_mut(pub(crate))]
241 pub mipmap_filter: MipmapFilter,
242 /// What sampling does with U coordinates outside `[0, 1]`.
243 #[get(type(copy))]
244 #[new(skip)]
245 #[get_mut(pub(crate))]
246 pub address_mode_u: AddressMode,
247 /// What sampling does with V coordinates outside `[0, 1]`.
248 #[get(type(copy))]
249 #[new(skip)]
250 #[set(pub(crate))]
251 #[get_mut(pub(crate))]
252 pub address_mode_v: AddressMode,
253 /// What sampling does with W coordinates outside `[0, 1]`. Only
254 /// meaningful for 3D textures.
255 #[get(type(copy))]
256 #[new(skip)]
257 #[set(pub(crate))]
258 #[get_mut(pub(crate))]
259 pub address_mode_w: AddressMode,
260 /// The depth comparison to apply, or `None` for a plain filtering
261 /// sampler that performs no comparison. Strictly more expressive than
262 /// the old `compare: bool`, which could only mean "compare with the
263 /// single hardcoded comparison".
264 #[get(type(copy))]
265 #[new(skip)]
266 #[set(pub(crate))]
267 #[get_mut(pub(crate))]
268 pub compare: Option<CompareFunction>,
269}
270
271/// One color attachment of a render pass.
272///
273/// Replaces the historical `RenderPassColorAttachment`. The two `Option<&'static str>`
274/// load and store ops disappear: a [`LoadOp`] and a [`StoreOp`] say
275/// directly what the old optional strings inferred, and a clear color is
276/// the engine's own [`Color`] rather than a bare `(f64, f64, f64, f64)`
277/// tuple whose channel order had to be re-checked at every call site.
278#[derive(Clone, Debug, Getter)]
279pub struct ColorAttachment {
280 /// The texture view to draw into, or `None` to let the renderer use
281 /// the swap-chain view (or the MSAA intermediate view when
282 /// antialiasing is on).
283 pub view: Option<JsValue>,
284 /// The destination view that a multisampled attachment resolves into,
285 /// or `None` when multisampling is disabled. The renderer substitutes
286 /// the swap-chain view when this is `None` but the attachment is
287 /// multisampled.
288 pub resolve_target: Option<JsValue>,
289 /// The color to overwrite the attachment with when `load_op` is
290 /// [`LoadOp::Clear`]. `None` means no clear, so `load_op` must then be
291 /// [`LoadOp::Load`].
292 pub clear: Option<Color>,
293 /// What to do with the attachment's existing contents before drawing.
294 pub load_op: LoadOp,
295 /// What to do with the attachment's contents once the pass ends.
296 pub store_op: StoreOp,
297}
298
299/// The depth-stencil attachment of a render pass.
300///
301/// Replaces the historical `RenderPassDepthStencilAttachment`. As with
302/// [`ColorAttachment`], the optional load and store op strings are
303/// replaced by typed ops, and the clear depth is `None`-able so that
304/// "clear to 1.0" and "keep what is there" are distinguishable at the
305/// type level rather than by which fields happen to be set.
306#[derive(Clone, Debug, Getter)]
307pub struct DepthStencilAttachment {
308 /// The depth-stencil texture view to use, or `None` to let the
309 /// renderer use the default view into its own depth texture,
310 /// allocating that texture lazily if needed.
311 pub view: Option<JsValue>,
312 /// The depth to overwrite the attachment with when `depth_load_op` is
313 /// [`LoadOp::Clear`], in `0.0..=1.0`. `None` means no clear, so
314 /// `depth_load_op` must then be [`LoadOp::Load`].
315 pub depth_clear: Option<f64>,
316 /// What to do with the existing depth before drawing.
317 pub depth_load_op: LoadOp,
318 /// What to do with the depth once the pass ends.
319 pub depth_store_op: StoreOp,
320 /// Whether the pass reads depth without writing it. `true` lets the
321 /// driver skip the depth write entirely.
322 ///
323 /// `get_depth_read_only` is `type(copy)`: a `bool` getter must hand back
324 /// the value, not `&bool` (§17.8.1), so every call site uses it directly.
325 #[get(type(copy))]
326 pub depth_read_only: bool,
327}
328
329/// One channel group of a [`BlendState`]: an operation plus the factors
330/// applied to the incoming and the existing value.
331#[derive(Clone, Copy, Data, Debug, Default, New, PartialEq)]
332pub struct BlendComponent {
333 /// How the two scaled terms are combined.
334 #[get(type(copy))]
335 #[new(skip)]
336 #[set(pub(crate))]
337 #[get_mut(pub(crate))]
338 pub operation: BlendOperation,
339 /// The factor the incoming value is multiplied by.
340 #[get(type(copy))]
341 #[new(skip)]
342 #[set(pub(crate))]
343 #[get_mut(pub(crate))]
344 pub source: BlendFactor,
345 /// The factor the existing value is multiplied by.
346 #[get(type(copy))]
347 #[new(skip)]
348 #[set(pub(crate))]
349 #[get_mut(pub(crate))]
350 pub destination: BlendFactor,
351}
352
353/// The full blend state of a single color target.
354///
355/// Alpha blending is `BlendComponent { operation: Add, source:
356/// SourceAlpha, destination: OneMinusSourceAlpha }` on both the color and
357/// the alpha channel; replacing the source and keeping the destination is
358/// how a fade-to-black and other multiply blends are expressed.
359#[derive(Clone, Copy, Data, Debug, Default, New)]
360pub struct BlendState {
361 /// The blend applied to the RGB channels.
362 #[get(type(copy))]
363 #[new(skip)]
364 #[set(pub(crate))]
365 #[get_mut(pub(crate))]
366 pub color: BlendComponent,
367 /// The blend applied to the alpha channel, which is frequently not
368 /// the same as the color blend.
369 #[get(type(copy))]
370 #[new(skip)]
371 #[set(pub(crate))]
372 #[get_mut(pub(crate))]
373 pub alpha: BlendComponent,
374}
375
376/// One entry of a fragment stage's `targets` array: the format of that
377/// color attachment and how fragments write into it.
378#[derive(Clone, Copy, Data, Debug, Default, New)]
379pub struct ColorTargetState {
380 /// The format of the color attachment this target writes to. It must
381 /// match the attachment's own format.
382 #[get(type(copy))]
383 #[new(skip)]
384 #[set(pub(crate))]
385 #[get_mut(pub(crate))]
386 pub format: GpuTextureFormat,
387 /// The blend to apply, or `None` to overwrite the target with the
388 /// fragment's color.
389 #[get(type(copy))]
390 #[new(skip)]
391 #[set(pub(crate))]
392 #[get_mut(pub(crate))]
393 pub blend: Option<BlendState>,
394 /// Which channels the fragment stage may write, as a bitmask:
395 /// `0x1` red, `0x2` green, `0x4` blue, `0x8` alpha. All four channels
396 /// is `0xf`; `0xf` is the right value for almost every opaque
397 /// fragment.
398 #[get(type(copy))]
399 #[new(skip)]
400 #[set(pub(crate))]
401 #[get_mut(pub(crate))]
402 pub write_mask: u32,
403}
404
405/// The pipeline's depth-stencil state: whether depth is written, and the
406/// test fragments must pass.
407#[derive(Clone, Copy, Data, Debug, Default, New)]
408pub struct DepthStencilState {
409 /// The format of the pipeline's depth-stencil attachment. It must
410 /// match the attachment's own format.
411 #[get(type(copy))]
412 #[new(skip)]
413 #[set(pub(crate))]
414 #[get_mut(pub(crate))]
415 pub format: GpuTextureFormat,
416 /// Whether a fragment that passes the test updates the depth buffer.
417 /// `false` is correct for a pipeline that only reads depth, such as a
418 /// transparent overlay drawn after the opaque pass.
419 #[get(type(copy))]
420 #[new(skip)]
421 #[set(pub(crate))]
422 #[get_mut(pub(crate))]
423 pub depth_write_enabled: bool,
424 /// The comparison performed between the fragment's depth and the
425 /// stored depth.
426 #[get(type(copy))]
427 #[new(skip)]
428 #[set(pub(crate))]
429 #[get_mut(pub(crate))]
430 pub depth_compare: CompareFunction,
431}
432
433/// The pipeline's multisample state: how many samples each pixel holds and
434/// which of them are written.
435#[derive(Clone, Copy, Data, Debug, Default, New)]
436pub struct MultisampleState {
437 /// The samples per pixel: `1` disables multisampling, `4` enables 4x
438 /// MSAA. The value must match the sample count of every color
439 /// attachment the pipeline draws into.
440 #[get(type(copy))]
441 #[new(skip)]
442 #[set(pub(crate))]
443 #[get_mut(pub(crate))]
444 pub count: u32,
445 /// Which samples are written, as a bitmask. Leave at `0xf` to write
446 /// all four samples of a 4x pipeline.
447 #[get(type(copy))]
448 #[new(skip)]
449 #[set(pub(crate))]
450 #[get_mut(pub(crate))]
451 pub mask: u32,
452}
453
454/// The pipeline's primitive-assembly state: how vertices become
455/// triangles, and which of those triangles survive rasterization.
456#[derive(Clone, Copy, Data, Debug, Default, New)]
457pub struct PrimitiveState {
458 /// How vertices are assembled into primitives.
459 #[get(pub(crate), type(copy))]
460 #[new(skip)]
461 #[set(pub(crate))]
462 #[get_mut(pub(crate))]
463 pub(crate) topology: PrimitiveTopology,
464 /// Which winding order counts as front facing.
465 #[get(type(copy))]
466 #[new(skip)]
467 #[set(pub(crate))]
468 #[get_mut(pub(crate))]
469 pub front_face: FrontFace,
470 /// Which faces are discarded before rasterization.
471 #[get(pub(crate), type(copy))]
472 #[new(skip)]
473 #[set(pub(crate))]
474 #[get_mut(pub(crate))]
475 pub(crate) cull_mode: CullMode,
476 /// The index format for a strip topology, or `None` for a
477 /// non-stripped topology where the field does not apply.
478 #[get(pub(crate), type(copy))]
479 #[new(skip)]
480 #[set(pub(crate))]
481 #[get_mut(pub(crate))]
482 pub(crate) strip_index_format: Option<IndexFormat>,
483 /// Whether fragments outside the depth range of `0.0..=1.0` survive.
484 /// `false`, the default, discards them.
485 #[get(pub(crate), type(copy))]
486 #[new(skip)]
487 #[set(pub(crate))]
488 #[get_mut(pub(crate))]
489 pub(crate) unclipped_depth: bool,
490}
491
492/// The pipeline's vertex stage: which shader runs, and how the vertex
493/// buffers feed it.
494#[derive(Clone, Debug, Getter, New)]
495pub struct VertexState {
496 /// The `GpuShaderModule` compiled from WGSL source.
497 #[get(type(clone))]
498 pub module: JsValue,
499 /// The `@vertex` entry point's name inside that module.
500 #[get(type(clone))]
501 pub entry_point: String,
502 /// The layouts of the vertex buffers this stage reads. The i-th entry
503 /// matches the i-th `setVertexBuffer(i, ...)` call.
504 #[get(pub(crate))]
505 pub(crate) buffers: Vec<VertexBufferLayout>,
506}
507
508/// The pipeline's fragment stage: which shader runs, and how it writes to
509/// the color attachments.
510#[derive(Clone, Debug, Getter, New)]
511pub struct FragmentState {
512 /// The `GpuShaderModule` compiled from WGSL source.
513 #[get(type(clone))]
514 pub module: JsValue,
515 /// The `@fragment` entry point's name inside that module.
516 #[get(type(clone))]
517 pub entry_point: String,
518 /// One entry per color attachment, in attachment order.
519 #[get(pub(crate))]
520 pub(crate) targets: Vec<ColorTargetState>,
521}
522
523/// The single full-control render pipeline constructor.
524///
525/// This is the one type a caller needs for any render pipeline: the
526/// renderer assembles it into a `GpuRenderPipelineDescriptor` and hands
527/// that to `device.createRenderPipeline`. Every narrower renderer method
528/// is sugar over this struct — `create_render_pipeline` is a preset with
529/// auto layout, triangle-list topology, no culling, and a single
530/// `Rgba8Unorm` target, and `create_render_pipeline_full` is the same
531/// preset with vertex buffers and a depth-stencil state added. Reach for
532/// this type when either of those presets is too narrow, and for nothing
533/// else.
534#[derive(Clone, Debug, Getter, New)]
535pub struct RenderPipelineDescriptor {
536 /// The vertex stage, and the only stage a pipeline cannot do without.
537 #[get(pub(crate))]
538 pub(crate) vertex: VertexState,
539 /// How vertices are assembled and which faces are discarded.
540 #[get(pub(crate))]
541 pub(crate) primitive: PrimitiveState,
542 /// The depth-stencil state, or `None` for a pipeline that neither
543 /// reads nor writes depth.
544 #[get(pub(crate))]
545 pub(crate) depth_stencil: Option<DepthStencilState>,
546 /// The multisample state, which must match the attachments.
547 #[get(pub(crate))]
548 pub(crate) multisample: MultisampleState,
549 /// The fragment stage, or `None` for a pipeline that writes no color
550 /// — a depth-only prepass, for instance.
551 #[get(pub(crate))]
552 pub(crate) fragment: Option<FragmentState>,
553}
554
555/// A compute pipeline: one shader module and one entry point.
556///
557/// The compute counterpart of [`RenderPipelineDescriptor`], and much
558/// smaller because a compute pipeline has no vertex buffers, no
559/// attachments, and no rasterization state.
560#[derive(Clone, Debug, Getter, New)]
561pub struct ComputePipelineDescriptor {
562 /// The `GpuShaderModule` compiled from WGSL source.
563 #[get(type(clone))]
564 pub module: JsValue,
565 /// The `@compute` entry point's name inside that module.
566 #[get(type(clone))]
567 pub entry_point: String,
568}
569
570/// The general texture constructor, covering 2D, 2D-array, and 3D
571/// textures.
572///
573/// [`Texture2DDescriptor`] is the narrow preset: a single layer, a
574/// format string, and a usage string, with no label. The two fields
575/// [`TextureDescriptor`] adds on top of it are what keep it general —
576/// `dimension` selects between a 2D texture, a 2D array, and a 3D
577/// texture, and `label` names the resource in the browser's GPU debug
578/// tooling, which is the only way to tell two same-sized textures apart
579/// in a capture.
580#[derive(Clone, Data, Debug, New)]
581pub struct TextureDescriptor {
582 /// The width in texels. Must be greater than zero.
583 #[get(type(copy))]
584 #[set(pub(crate))]
585 #[get_mut(pub(crate))]
586 pub width: u32,
587 /// The height in texels. Must be greater than zero.
588 #[get(type(copy))]
589 #[set(pub(crate))]
590 #[get_mut(pub(crate))]
591 pub height: u32,
592 /// The number of array layers for a `2d-array` texture, or the depth
593 /// in texels for a `3d` texture. `1` for a plain 2D texture.
594 #[get(type(copy))]
595 #[new(skip)]
596 #[get_mut(pub(crate))]
597 pub depth_or_layers: u32,
598 /// The texture's dimensionality. Defaults to `"2d"`; a
599 /// `"2d-array"` or `"3d"` texture needs this set explicitly.
600 #[get(type(clone))]
601 #[set(pub(crate))]
602 #[get_mut(pub(crate))]
603 pub dimension: &'static str,
604 /// The texel format.
605 #[get(type(copy))]
606 #[set(pub(crate))]
607 #[get_mut(pub(crate))]
608 pub format: GpuTextureFormat,
609 /// The legal uses of this texture, as a `usage` bitmask. Combine
610 /// several [`TextureUsage`] values with `|`.
611 #[get(type(copy))]
612 #[set(pub(crate))]
613 #[get_mut(pub(crate))]
614 pub usage: u32,
615 /// The number of mip levels. Zero is treated as one.
616 #[get(type(copy))]
617 #[new(skip)]
618 #[set(pub(crate))]
619 #[get_mut(pub(crate))]
620 pub mip_level_count: u32,
621 /// The samples per texel: `1` for an ordinary texture, `4` for a
622 /// multisampled render target.
623 #[get(type(copy))]
624 #[new(skip)]
625 #[set(pub(crate))]
626 #[get_mut(pub(crate))]
627 pub sample_count: u32,
628 /// A debug label shown for this texture in the browser's GPU
629 /// tooling, or `None` to leave it unnamed.
630 #[get(type(clone))]
631 #[new(skip)]
632 #[set(pub(crate))]
633 #[get_mut(pub(crate))]
634 pub label: Option<String>,
635}
636
637/// A buffer constructor, naming both the size and the legal uses of a
638/// GPU buffer.
639///
640/// Replaces the raw `usage: u32` bitmask that `create_buffer` takes
641/// today, where a caller had to know the bit values and pass `64 | 8` by
642/// hand for a uniform-or-vertex buffer. Combine several uses with `|`.
643#[derive(Clone, Debug, Getter, New)]
644pub(crate) struct BufferDescriptor {
645 /// The size in bytes. Must be greater than zero.
646 #[get(pub(crate), type(copy))]
647 pub(crate) size: u64,
648 /// The legal uses of this buffer, as a `usage` bitmask. Combine
649 /// several [`BufferUsage`] values with `|`.
650 #[get(pub(crate), type(copy))]
651 pub(crate) usage: u32,
652 /// A debug label shown for this buffer in the browser's GPU tooling,
653 /// or `None` to leave it unnamed.
654 #[get(pub(crate), type(clone))]
655 #[new(skip)]
656 pub(crate) label: Option<String>,
657}
658
659/// One entry in the dynamic-offset list passed to
660/// `set_bind_group_with_dynamic_offsets`.
661///
662/// A uniform buffer that a shader declares with `hasDynamicOffset: true`
663/// can hold many independent records back to back, and the bind group
664/// picks one per draw by adding an offset. Grouping the pair into a struct
665/// keeps the two values together at the call site, where writing them as
666/// two separate positional arguments is easy to transpose.
667#[derive(Clone, Copy, Data, Debug, Default, New)]
668pub struct UniformSlice {
669 /// The byte offset of this record from the start of the bound range.
670 /// The spec requires this to be a multiple of the binding's minimum
671 /// uniform buffer offset alignment, typically 256.
672 #[get(type(copy))]
673 #[set(pub(crate))]
674 #[get_mut(pub(crate))]
675 pub offset: u64,
676 /// The size in bytes of this record. A size of zero means "from this
677 /// offset to the end of the bound range".
678 #[get(type(copy))]
679 #[set(pub(crate))]
680 #[get_mut(pub(crate))]
681 pub size: u64,
682}
683
684/// The five arguments of an indexed draw, as one value.
685///
686/// `drawIndexed` and `drawIndexedOffset` take these as five positional
687/// arguments today, with no named parameter in between to keep them in
688/// order and no way to leave a trailing one at its default. Grouping them
689/// makes the call self-documenting and lets a caller vary one of the five
690/// without restating the other four.
691#[derive(Clone, Copy, Data, Debug, New)]
692pub struct DrawIndexedArgs {
693 /// The number of indices to read from the bound index buffer.
694 #[get(type(copy))]
695 #[new(skip)]
696 #[get_mut(pub(crate))]
697 pub index_count: u32,
698 /// How many instances of the indexed geometry to draw. `1` draws a
699 /// single instance.
700 #[get(type(copy))]
701 #[new(skip)]
702 #[get_mut(pub(crate))]
703 pub instance_count: u32,
704 /// The index of the first index to read, for drawing a sub-range of
705 /// the index buffer.
706 #[get(type(copy))]
707 #[new(skip)]
708 #[get_mut(pub(crate))]
709 pub first_index: u32,
710 /// The value added to every index before it is used to fetch a vertex.
711 /// Lets several meshes share one vertex buffer.
712 #[get(type(copy))]
713 #[new(skip)]
714 #[get_mut(pub(crate))]
715 pub base_vertex: i32,
716 /// The first instance index, for reading per-instance attributes from
717 /// an offset.
718 #[get(type(copy))]
719 #[new(skip)]
720 #[get_mut(pub(crate))]
721 pub first_instance: u32,
722}
723
724/// The four arguments of a non-indexed draw, as one value.
725///
726/// The non-indexed counterpart of [`DrawIndexedArgs`], and the same
727/// argument in the same order as `draw(vertexCount, instanceCount,
728/// firstVertex, firstInstance)`.
729#[derive(Clone, Copy, Data, Debug, New)]
730pub struct DrawArgs {
731 /// The number of vertices to draw, taken from the bound vertex buffers
732 /// as a non-indexed stream.
733 #[get(type(copy))]
734 #[new(skip)]
735 #[get_mut(pub(crate))]
736 pub vertex_count: u32,
737 /// How many instances of the geometry to draw. `1` draws a single
738 /// instance.
739 #[get(type(copy))]
740 #[new(skip)]
741 #[get_mut(pub(crate))]
742 pub instance_count: u32,
743 /// The vertex to start from, for drawing a sub-range of the vertex
744 /// stream.
745 #[get(type(copy))]
746 #[new(skip)]
747 #[get_mut(pub(crate))]
748 pub first_vertex: u32,
749 /// The first instance index, for reading per-instance attributes from
750 /// an offset.
751 #[get(type(copy))]
752 #[new(skip)]
753 #[get_mut(pub(crate))]
754 pub first_instance: u32,
755}
756
757/// The three workgroup counts of a compute dispatch, as one value.
758///
759/// `dispatch(x, y, z)` today takes these as three positional numbers
760/// whose order is easy to transpose, since `x` is the fastest-varying
761/// axis and the natural reading order of a 3D problem is `z, y, x`.
762#[derive(Clone, Copy, Data, Debug, New)]
763pub struct DispatchArgs {
764 /// The workgroups dispatched along the x axis.
765 #[get(type(copy))]
766 #[new(skip)]
767 #[get_mut(pub(crate))]
768 pub x: u32,
769 /// The workgroups dispatched along the y axis.
770 #[get(type(copy))]
771 #[new(skip)]
772 #[get_mut(pub(crate))]
773 pub y: u32,
774 /// The workgroups dispatched along the z axis.
775 #[get(type(copy))]
776 #[new(skip)]
777 #[get_mut(pub(crate))]
778 pub z: u32,
779}