From 27e7408f16bb18b2b082beeb516718cbc40a8c2d Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 9 Jul 2025 13:17:07 -0700 Subject: [PATCH 001/303] Restore the buffer size changes --- wgpu-core/src/binding_model.rs | 43 ++++++-- wgpu-core/src/command/bundle.rs | 85 ++++++++++----- wgpu-core/src/command/draw.rs | 5 +- wgpu-core/src/command/render.rs | 68 ++++++------ wgpu-core/src/command/render_command.rs | 28 ++++- wgpu-core/src/device/global.rs | 3 +- wgpu-core/src/device/resource.rs | 94 +++++++--------- wgpu-core/src/indirect_validation/dispatch.rs | 14 ++- wgpu-core/src/indirect_validation/draw.rs | 14 ++- wgpu-core/src/resource.rs | 77 ++++++++++++- wgpu-core/src/timestamp_normalization/mod.rs | 16 +-- wgpu-hal/examples/halmark/main.rs | 18 ++-- wgpu-hal/examples/ray-traced-triangle/main.rs | 11 +- wgpu-hal/src/dx12/command.rs | 4 +- wgpu-hal/src/dx12/device.rs | 2 +- wgpu-hal/src/dx12/mod.rs | 7 -- wgpu-hal/src/gles/device.rs | 10 +- wgpu-hal/src/gles/mod.rs | 1 - wgpu-hal/src/lib.rs | 102 ++++++++++++++---- wgpu-hal/src/metal/command.rs | 16 ++- wgpu-hal/src/metal/device.rs | 21 ++-- wgpu-hal/src/metal/mod.rs | 10 -- wgpu-hal/src/vulkan/device.rs | 6 +- wgpu-types/src/lib.rs | 6 ++ wgpu/src/api/device.rs | 1 + wgpu/src/backend/wgpu_core.rs | 6 ++ 26 files changed, 423 insertions(+), 245 deletions(-) diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index af8bea948a4..656cc208a5b 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -95,8 +95,39 @@ impl WebGpuError for CreateBindGroupLayoutError { } } -//TODO: refactor this to move out `enum BindingError`. +#[derive(Clone, Debug, Error)] +#[non_exhaustive] +pub enum BindingError { + #[error(transparent)] + DestroyedResource(#[from] DestroyedResourceError), + #[error("Buffer {buffer}: Binding with size {binding_size} at offset {offset} would overflow buffer size of {buffer_size}")] + BindingRangeTooLarge { + buffer: ResourceErrorIdent, + offset: wgt::BufferAddress, + binding_size: u64, + buffer_size: u64, + }, + #[error("Buffer {buffer}: Binding offset {offset} is greater than buffer size {buffer_size}")] + BindingOffsetTooLarge { + buffer: ResourceErrorIdent, + offset: wgt::BufferAddress, + buffer_size: u64, + }, +} +impl WebGpuError for BindingError { + fn webgpu_error_type(&self) -> ErrorType { + match self { + Self::DestroyedResource(e) => e.webgpu_error_type(), + Self::BindingRangeTooLarge { .. } | Self::BindingOffsetTooLarge { .. } => { + ErrorType::Validation + } + } + } +} + +// TODO: there may be additional variants here that can be extracted into +// `BindingError`. #[derive(Clone, Debug, Error)] #[non_exhaustive] pub enum CreateBindGroupError { @@ -104,6 +135,8 @@ pub enum CreateBindGroupError { Device(#[from] DeviceError), #[error(transparent)] DestroyedResource(#[from] DestroyedResourceError), + #[error(transparent)] + BindingError(#[from] BindingError), #[error( "Binding count declared with at most {expected} items, but {actual} items were provided" )] @@ -114,12 +147,6 @@ pub enum CreateBindGroupError { BindingArrayLengthMismatch { actual: usize, expected: usize }, #[error("Array binding provided zero elements")] BindingArrayZeroLength, - #[error("The bound range {range:?} of {buffer} overflows its size ({size})")] - BindingRangeTooLarge { - buffer: ResourceErrorIdent, - range: Range, - size: u64, - }, #[error("Binding size {actual} of {buffer} is less than minimum {min}")] BindingSizeTooSmall { buffer: ResourceErrorIdent, @@ -234,6 +261,7 @@ impl WebGpuError for CreateBindGroupError { let e: &dyn WebGpuError = match self { Self::Device(e) => e, Self::DestroyedResource(e) => e, + Self::BindingError(e) => e, Self::MissingBufferUsage(e) => e, Self::MissingTextureUsage(e) => e, Self::ResourceUsageCompatibility(e) => e, @@ -241,7 +269,6 @@ impl WebGpuError for CreateBindGroupError { Self::BindingArrayPartialLengthMismatch { .. } | Self::BindingArrayLengthMismatch { .. } | Self::BindingArrayZeroLength - | Self::BindingRangeTooLarge { .. } | Self::BindingSizeTooSmall { .. } | Self::BindingsNumMismatch { .. } | Self::BindingZeroSize(_) diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index 743865bb630..c476a0aaf99 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -93,6 +93,7 @@ use core::{ use arrayvec::ArrayVec; use thiserror::Error; +use wgpu_hal::ShouldBeNonZeroExt; use wgt::error::{ErrorType, WebGpuError}; use crate::{ @@ -504,7 +505,7 @@ impl RenderBundleEncoder { buffer_id, index_format, offset, - size, + size: size.map(NonZeroU64::get), }); } } @@ -602,13 +603,14 @@ fn set_pipeline( Ok(()) } +// This function is duplicative of `render::set_index_buffer`. fn set_index_buffer( state: &mut State, buffer_guard: &crate::storage::Storage>, buffer_id: id::Id, index_format: wgt::IndexFormat, offset: u64, - size: Option, + size: Option, ) -> Result<(), RenderBundleErrorInner> { let buffer = buffer_guard.get(buffer_id).get()?; @@ -620,28 +622,27 @@ fn set_index_buffer( buffer.same_device(&state.device)?; buffer.check_usage(wgt::BufferUsages::INDEX)?; - let end = match size { - Some(s) => offset + s.get(), - None => buffer.size, - }; + let end = buffer.resolve_binding_size(offset, size)?; + state .buffer_memory_init_actions .extend(buffer.initialization_status.read().create_action( &buffer, - offset..end, + offset..end.get(), MemoryInitKind::NeedsInitializedMemory, )); - state.set_index_buffer(buffer, index_format, offset..end); + state.set_index_buffer(buffer, index_format, offset..end.get()); Ok(()) } +// This function is duplicative of `render::set_vertex_buffer`. fn set_vertex_buffer( state: &mut State, buffer_guard: &crate::storage::Storage>, slot: u32, buffer_id: id::Id, offset: u64, - size: Option, + size: Option, ) -> Result<(), RenderBundleErrorInner> { let max_vertex_buffers = state.device.limits.max_vertex_buffers; if slot >= max_vertex_buffers { @@ -662,18 +663,16 @@ fn set_vertex_buffer( buffer.same_device(&state.device)?; buffer.check_usage(wgt::BufferUsages::VERTEX)?; - let end = match size { - Some(s) => offset + s.get(), - None => buffer.size, - }; + let end = buffer.resolve_binding_size(offset, size)?; + state .buffer_memory_init_actions .extend(buffer.initialization_status.read().create_action( &buffer, - offset..end, + offset..end.get(), MemoryInitKind::NeedsInitializedMemory, )); - state.vertex[slot as usize] = Some(VertexState::new(buffer, offset..end)); + state.vertex[slot as usize] = Some(VertexState::new(buffer, offset..end.get())); Ok(()) } @@ -965,10 +964,14 @@ impl RenderBundle { size, } => { let buffer = buffer.try_raw(snatch_guard)?; - let bb = hal::BufferBinding { - buffer, - offset: *offset, - size: *size, + let bb = unsafe { + // SAFETY: The binding size was checked against the buffer size + // in `set_index_buffer` and again in `IndexState::flush`. + hal::BufferBinding::new_unchecked( + buffer, + *offset, + size.expect("size was resolved in `RenderBundleEncoder::finish`"), + ) }; unsafe { raw.set_index_buffer(bb, *index_format) }; } @@ -979,10 +982,14 @@ impl RenderBundle { size, } => { let buffer = buffer.try_raw(snatch_guard)?; - let bb = hal::BufferBinding { - buffer, - offset: *offset, - size: *size, + let bb = unsafe { + // SAFETY: The binding size was checked against the buffer size + // in `set_vertex_buffer` and again in `VertexState::flush`. + hal::BufferBinding::new_unchecked( + buffer, + *offset, + size.expect("size was resolved in `RenderBundleEncoder::finish`"), + ) }; unsafe { raw.set_vertex_buffer(*slot, bb) }; } @@ -1131,6 +1138,9 @@ crate::impl_trackable!(RenderBundle); /// [`RenderBundleEncoder::finish`] records the currently set index buffer here, /// and calls [`State::flush_index`] before any indexed draw command to produce /// a `SetIndexBuffer` command if one is necessary. +/// +/// Binding ranges must be validated against the size of the buffer before +/// being stored in `IndexState`. #[derive(Debug)] struct IndexState { buffer: Arc, @@ -1152,13 +1162,21 @@ impl IndexState { /// Generate a `SetIndexBuffer` command to prepare for an indexed draw /// command, if needed. fn flush(&mut self) -> Option { + // This was all checked before, but let's check again just in case. + let binding_size = self + .range + .end + .checked_sub(self.range.start) + .filter(|_| self.range.end <= self.buffer.size) + .expect("index range must be contained in buffer"); + if self.is_dirty { self.is_dirty = false; Some(ArcRenderCommand::SetIndexBuffer { buffer: self.buffer.clone(), index_format: self.format, offset: self.range.start, - size: wgt::BufferSize::new(self.range.end - self.range.start), + size: Some(binding_size), }) } else { None @@ -1174,6 +1192,9 @@ impl IndexState { /// calls this type's [`flush`] method just before any draw command to /// produce a `SetVertexBuffer` commands if one is necessary. /// +/// Binding ranges must be validated against the size of the buffer before +/// being stored in `VertexState`. +/// /// [`flush`]: IndexState::flush #[derive(Debug)] struct VertexState { @@ -1183,6 +1204,9 @@ struct VertexState { } impl VertexState { + /// Create a new `VertexState`. + /// + /// The `range` must be contained within `buffer`. fn new(buffer: Arc, range: Range) -> Self { Self { buffer, @@ -1195,13 +1219,20 @@ impl VertexState { /// /// `slot` is the index of the vertex buffer slot that `self` tracks. fn flush(&mut self, slot: u32) -> Option { + let binding_size = self + .range + .end + .checked_sub(self.range.start) + .filter(|_| self.range.end <= self.buffer.size) + .expect("vertex range must be contained in buffer"); + if self.is_dirty { self.is_dirty = false; Some(ArcRenderCommand::SetVertexBuffer { slot, buffer: self.buffer.clone(), offset: self.range.start, - size: wgt::BufferSize::new(self.range.end - self.range.start), + size: Some(binding_size), }) } else { None @@ -1565,7 +1596,7 @@ where pub mod bundle_ffi { use super::{RenderBundleEncoder, RenderCommand}; use crate::{id, RawString}; - use core::{convert::TryInto, slice}; + use core::{convert::TryInto, num::NonZeroU64, slice}; use wgt::{BufferAddress, BufferSize, DynamicOffset, IndexFormat}; /// # Safety @@ -1624,7 +1655,7 @@ pub mod bundle_ffi { slot, buffer_id, offset, - size, + size: size.map(NonZeroU64::get), }); } diff --git a/wgpu-core/src/command/draw.rs b/wgpu-core/src/command/draw.rs index 53a3f204fcc..7dadc8bfa4e 100644 --- a/wgpu-core/src/command/draw.rs +++ b/wgpu-core/src/command/draw.rs @@ -7,7 +7,7 @@ use wgt::error::{ErrorType, WebGpuError}; use super::bind::BinderError; use crate::command::pass; use crate::{ - binding_model::{LateMinBufferBindingSizeMismatch, PushConstantUploadError}, + binding_model::{BindingError, LateMinBufferBindingSizeMismatch, PushConstantUploadError}, resource::{ DestroyedResourceError, MissingBufferUsageError, MissingTextureUsageError, ResourceErrorIdent, @@ -89,6 +89,8 @@ pub enum RenderCommandError { MissingTextureUsage(#[from] MissingTextureUsageError), #[error(transparent)] PushConstants(#[from] PushConstantUploadError), + #[error(transparent)] + BindingError(#[from] BindingError), #[error("Viewport size {{ w: {w}, h: {h} }} greater than device's requested `max_texture_dimension_2d` limit {max}, or less than zero")] InvalidViewportRectSize { w: f32, h: f32, max: u32 }, #[error("Viewport has invalid rect {rect:?} for device's requested `max_texture_dimension_2d` limit; Origin less than -2 * `max_texture_dimension_2d` ({min}), or rect extends past 2 * `max_texture_dimension_2d` - 1 ({max})")] @@ -110,6 +112,7 @@ impl WebGpuError for RenderCommandError { Self::MissingBufferUsage(e) => e, Self::MissingTextureUsage(e) => e, Self::PushConstants(e) => e, + Self::BindingError(e) => e, Self::BindGroupIndexOutOfRange { .. } | Self::VertexBufferIndexOutOfRange { .. } diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index f9cccbff359..58bda99c4b7 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1,12 +1,17 @@ use alloc::{borrow::Cow, sync::Arc, vec::Vec}; -use core::{fmt, num::NonZeroU32, ops::Range, str}; +use core::{ + fmt, + num::{NonZeroU32, NonZeroU64}, + str, +}; +use hal::ShouldBeNonZeroExt; use arrayvec::ArrayVec; use thiserror::Error; use wgt::{ error::{ErrorType, WebGpuError}, - BufferAddress, BufferSize, BufferUsages, Color, DynamicOffset, IndexFormat, ShaderStages, - TextureSelector, TextureUsages, TextureViewDimension, VertexStepMode, + BufferAddress, BufferSize, BufferSizeOrZero, BufferUsages, Color, DynamicOffset, IndexFormat, + ShaderStages, TextureSelector, TextureUsages, TextureViewDimension, VertexStepMode, }; use crate::command::{ @@ -357,13 +362,17 @@ struct IndexState { } impl IndexState { - fn update_buffer(&mut self, range: Range, format: IndexFormat) { + fn update_buffer( + &mut self, + binding: &hal::BufferBinding<'_, B>, + format: IndexFormat, + ) { self.buffer_format = Some(format); let shift = match format { IndexFormat::Uint16 => 1, IndexFormat::Uint32 => 2, }; - self.limit = (range.end - range.start) >> shift; + self.limit = binding.size.get() >> shift; } fn reset(&mut self) { @@ -2323,13 +2332,14 @@ fn set_pipeline( Ok(()) } +// This function is duplicative of `bundle::set_index_buffer`. fn set_index_buffer( state: &mut State, cmd_buf: &Arc, buffer: Arc, index_format: IndexFormat, offset: u64, - size: Option, + size: Option, ) -> Result<(), RenderPassErrorInner> { api_log!("RenderPass::set_index_buffer {}", buffer.error_ident()); @@ -2342,40 +2352,34 @@ fn set_index_buffer( buffer.same_device_as(cmd_buf.as_ref())?; buffer.check_usage(BufferUsages::INDEX)?; - let buf_raw = buffer.try_raw(state.general.snatch_guard)?; - let end = match size { - Some(s) => offset + s.get(), - None => buffer.size, - }; - state.index.update_buffer(offset..end, index_format); + let binding = buffer + .binding(offset, size, state.general.snatch_guard) + .map_err(RenderCommandError::from)?; + state.index.update_buffer(&binding, index_format); state.general.buffer_memory_init_actions.extend( buffer.initialization_status.read().create_action( &buffer, - offset..end, + offset..(offset + binding.size.get()), MemoryInitKind::NeedsInitializedMemory, ), ); - let bb = hal::BufferBinding { - buffer: buf_raw, - offset, - size, - }; unsafe { - hal::DynCommandEncoder::set_index_buffer(state.general.raw_encoder, bb, index_format); + hal::DynCommandEncoder::set_index_buffer(state.general.raw_encoder, binding, index_format); } Ok(()) } +// This function is duplicative of `render::set_vertex_buffer`. fn set_vertex_buffer( state: &mut State, cmd_buf: &Arc, slot: u32, buffer: Arc, offset: u64, - size: Option, + size: Option, ) -> Result<(), RenderPassErrorInner> { api_log!( "RenderPass::set_vertex_buffer {slot} {}", @@ -2400,30 +2404,22 @@ fn set_vertex_buffer( } buffer.check_usage(BufferUsages::VERTEX)?; - let buf_raw = buffer.try_raw(state.general.snatch_guard)?; - //TODO: where are we checking that the offset is in bound? - let buffer_size = match size { - Some(s) => s.get(), - None => buffer.size - offset, - }; - state.vertex.buffer_sizes[slot as usize] = Some(buffer_size); + let binding = buffer + .binding(offset, size, state.general.snatch_guard) + .map_err(RenderCommandError::from)?; + state.vertex.buffer_sizes[slot as usize] = Some(binding.size.get()); state.general.buffer_memory_init_actions.extend( buffer.initialization_status.read().create_action( &buffer, - offset..(offset + buffer_size), + offset..(offset + binding.size.get()), MemoryInitKind::NeedsInitializedMemory, ), ); - let bb = hal::BufferBinding { - buffer: buf_raw, - offset, - size, - }; unsafe { - hal::DynCommandEncoder::set_vertex_buffer(state.general.raw_encoder, slot, bb); + hal::DynCommandEncoder::set_vertex_buffer(state.general.raw_encoder, slot, binding); } if let Some(pipeline) = state.pipeline.as_ref() { state.vertex.update_limits(&pipeline.vertex_steps); @@ -3094,7 +3090,7 @@ impl Global { buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), index_format, offset, - size, + size: size.map(NonZeroU64::get), }); Ok(()) @@ -3115,7 +3111,7 @@ impl Global { slot, buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), offset, - size, + size: size.map(NonZeroU64::get), }); Ok(()) diff --git a/wgpu-core/src/command/render_command.rs b/wgpu-core/src/command/render_command.rs index 6fc4cbf5cf5..f57ec026e24 100644 --- a/wgpu-core/src/command/render_command.rs +++ b/wgpu-core/src/command/render_command.rs @@ -1,6 +1,6 @@ use alloc::sync::Arc; -use wgt::{BufferAddress, BufferSize, Color}; +use wgt::{BufferAddress, BufferSizeOrZero, Color}; use super::{Rect, RenderBundle}; use crate::{ @@ -24,13 +24,13 @@ pub enum RenderCommand { buffer_id: id::BufferId, index_format: wgt::IndexFormat, offset: BufferAddress, - size: Option, + size: Option, }, SetVertexBuffer { slot: u32, buffer_id: id::BufferId, offset: BufferAddress, - size: Option, + size: Option, }, SetBlendConstant(Color), SetStencilReference(u32), @@ -392,6 +392,17 @@ impl RenderCommand { } /// Equivalent to `RenderCommand` with the Ids resolved into resource Arcs. +/// +/// In a render pass, commands are stored in this format between when they are +/// added to the pass, and when the pass is `end()`ed and the commands are +/// replayed to the HAL encoder. Validation occurs when the pass is ended, which +/// means that parameters stored in an `ArcRenderCommand` for a pass operation +/// have generally not been validated. +/// +/// In a render bundle, commands are stored in this format between when the bundle +/// is `finish()`ed and when the bundle is executed. Validation occurs when the +/// bundle is finished, which means that parameters stored in an `ArcRenderCommand` +/// for a render bundle operation must have been validated. #[doc(hidden)] #[derive(Clone, Debug)] pub enum ArcRenderCommand { @@ -405,13 +416,20 @@ pub enum ArcRenderCommand { buffer: Arc, index_format: wgt::IndexFormat, offset: BufferAddress, - size: Option, + + // For a render pass, this reflects the argument passed by the + // application, which may be `None`. For a finished render bundle, this + // reflects the validated size of the binding, and will be populated + // even in the case that the application omitted the size. + size: Option, }, SetVertexBuffer { slot: u32, buffer: Arc, offset: BufferAddress, - size: Option, + + // See comment in `SetIndexBuffer`. + size: Option, }, SetBlendConstant(Color), SetStencilReference(u32), diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index 9ad56fb9bab..96842c7168d 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -385,6 +385,7 @@ impl Global { /// - `hal_buffer` must be created from `device_id` corresponding raw handle. /// - `hal_buffer` must be created respecting `desc` /// - `hal_buffer` must be initialized + /// - `hal_buffer` must not have zero size. pub unsafe fn create_buffer_from_hal( &self, hal_buffer: A::Buffer, @@ -406,7 +407,7 @@ impl Global { trace.add(trace::Action::CreateBuffer(fid.id(), desc.clone())); } - let (buffer, err) = device.create_buffer_from_hal(Box::new(hal_buffer), desc); + let (buffer, err) = unsafe { device.create_buffer_from_hal(Box::new(hal_buffer), desc) }; let id = fid.assign(buffer); api_log!("Device::create_buffer -> {id:?}"); diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index ce7187ef507..5afc4d6b3a1 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -8,9 +8,10 @@ use alloc::{ use core::{ fmt, mem::{self, ManuallyDrop}, - num::NonZeroU32, + num::{NonZeroU32, NonZeroU64}, sync::atomic::{AtomicBool, Ordering}, }; +use hal::ShouldBeNonZeroExt; use arrayvec::ArrayVec; use bitflags::Flags; @@ -702,7 +703,8 @@ impl Device { let buffer = unsafe { self.raw().create_buffer(&hal_desc) } .map_err(|e| self.handle_hal_error_with_nonfatal_oom(e))?; - let timestamp_normalization_bind_group = Snatchable::new( + let timestamp_normalization_bind_group = Snatchable::new(unsafe { + // SAFETY: The size passed here must not overflow the buffer. self.timestamp_normalizer .get() .unwrap() @@ -710,10 +712,10 @@ impl Device { self, &*buffer, desc.label.as_deref(), - desc.size, + wgt::BufferSize::new(hal_desc.size).unwrap(), desc.usage, - )?, - ); + ) + }?); let indirect_validation_bind_groups = self.create_indirect_validation_bind_groups(buffer.as_ref(), desc.size, desc.usage)?; @@ -809,28 +811,36 @@ impl Device { Ok(texture) } - pub(crate) fn create_buffer_from_hal( + /// # Safety + /// + /// - `hal_buffer` must have been created on this device. + /// - `hal_buffer` must have been created respecting `desc` (in particular, the size). + /// - `hal_buffer` must be initialized. + /// - `hal_buffer` must not have zero size. + pub(crate) unsafe fn create_buffer_from_hal( self: &Arc, hal_buffer: Box, desc: &resource::BufferDescriptor, ) -> (Fallible, Option) { - let timestamp_normalization_bind_group = match self - .timestamp_normalizer - .get() - .unwrap() - .create_normalization_bind_group( - self, - &*hal_buffer, - desc.label.as_deref(), - desc.size, - desc.usage, - ) { - Ok(bg) => Snatchable::new(bg), - Err(e) => { - return ( - Fallible::Invalid(Arc::new(desc.label.to_string())), - Some(e.into()), - ) + let timestamp_normalization_bind_group = unsafe { + match self + .timestamp_normalizer + .get() + .unwrap() + .create_normalization_bind_group( + self, + &*hal_buffer, + desc.label.as_deref(), + wgt::BufferSize::new(desc.size).unwrap(), + desc.usage, + ) { + Ok(bg) => Snatchable::new(bg), + Err(e) => { + return ( + Fallible::Invalid(Arc::new(desc.label.to_string())), + Some(e.into()), + ) + } } }; @@ -2187,31 +2197,9 @@ impl Device { buffer.same_device(self)?; buffer.check_usage(pub_usage)?; - let raw_buffer = buffer.try_raw(snatch_guard)?; - - let (bind_size, bind_end) = match bb.size { - Some(size) => { - let end = bb.offset + size.get(); - if end > buffer.size { - return Err(Error::BindingRangeTooLarge { - buffer: buffer.error_ident(), - range: bb.offset..end, - size: buffer.size, - }); - } - (size.get(), end) - } - None => { - if buffer.size < bb.offset { - return Err(Error::BindingRangeTooLarge { - buffer: buffer.error_ident(), - range: bb.offset..bb.offset, - size: buffer.size, - }); - } - (buffer.size - bb.offset, buffer.size) - } - }; + + let bb = buffer.binding(bb.offset, bb.size.map(NonZeroU64::get), snatch_guard)?; + let bind_size = bb.size.get(); if bind_size > range_limit as u64 { return Err(Error::BufferRangeTooLarge { @@ -2226,8 +2214,8 @@ impl Device { dynamic_binding_info.push(binding_model::BindGroupDynamicBindingData { binding_idx: binding, buffer_size: buffer.size, - binding_range: bb.offset..bind_end, - maximum_dynamic_offset: buffer.size - bind_end, + binding_range: bb.offset..bb.offset + bind_size, + maximum_dynamic_offset: buffer.size - bb.offset - bind_size, binding_type: binding_ty, }); } @@ -2265,11 +2253,7 @@ impl Device { MemoryInitKind::NeedsInitializedMemory, )); - Ok(hal::BufferBinding { - buffer: raw_buffer, - offset: bb.offset, - size: bb.size, - }) + Ok(bb) } fn create_sampler_binding<'a>( diff --git a/wgpu-core/src/indirect_validation/dispatch.rs b/wgpu-core/src/indirect_validation/dispatch.rs index 00e3798e9ba..e9fe4971bf7 100644 --- a/wgpu-core/src/indirect_validation/dispatch.rs +++ b/wgpu-core/src/indirect_validation/dispatch.rs @@ -232,10 +232,9 @@ impl Dispatch { resource_index: 0, count: 1, }], - buffers: &[hal::BufferBinding { - buffer: dst_buffer.as_ref(), - offset: 0, - size: Some(DST_BUFFER_SIZE), + buffers: &[unsafe { + // SAFETY: We just created the buffer with this size. + hal::BufferBinding::new_unchecked(dst_buffer.as_ref(), 0, DST_BUFFER_SIZE) }], samplers: &[], textures: &[], @@ -278,10 +277,9 @@ impl Dispatch { resource_index: 0, count: 1, }], - buffers: &[hal::BufferBinding { - buffer, - offset: 0, - size: Some(binding_size), + buffers: &[unsafe { + // SAFETY: We calculated the binding size to fit within the buffer. + hal::BufferBinding::new_unchecked(buffer, 0, binding_size) }], samplers: &[], textures: &[], diff --git a/wgpu-core/src/indirect_validation/draw.rs b/wgpu-core/src/indirect_validation/draw.rs index d88acb8d60d..af0e1a2c54c 100644 --- a/wgpu-core/src/indirect_validation/draw.rs +++ b/wgpu-core/src/indirect_validation/draw.rs @@ -135,10 +135,9 @@ impl Draw { resource_index: 0, count: 1, }], - buffers: &[hal::BufferBinding { - buffer, - offset: 0, - size: Some(binding_size), + buffers: &[unsafe { + // SAFETY: We calculated the binding size to fit within the buffer. + hal::BufferBinding::new_unchecked(buffer, 0, binding_size) }], samplers: &[], textures: &[], @@ -684,10 +683,9 @@ fn create_buffer_and_bind_group( resource_index: 0, count: 1, }], - buffers: &[hal::BufferBinding { - buffer: buffer.as_ref(), - offset: 0, - size: Some(BUFFER_SIZE), + buffers: &[unsafe { + // SAFETY: We just created the buffer with this size. + hal::BufferBinding::new_unchecked(buffer.as_ref(), 0, BUFFER_SIZE) }], samplers: &[], textures: &[], diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 9d4b90f1936..1bfde1db775 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -17,7 +17,7 @@ use wgt::{ #[cfg(feature = "trace")] use crate::device::trace; use crate::{ - binding_model::BindGroup, + binding_model::{BindGroup, BindingError}, device::{ queue, resource::DeferredDestroy, BufferMapPendingClosure, Device, DeviceError, DeviceMismatch, HostMap, MissingDownlevelFlags, MissingFeatures, @@ -494,6 +494,81 @@ impl Buffer { } } + /// Resolve the size of a binding for buffer with `offset` and `size`. + /// + /// If `size` is `None`, then the remainder of the buffer starting from + /// `offset` is used. + /// + /// If the binding would overflow the buffer, then an error is returned. + /// + /// Zero-size bindings are permitted here for historical reasons. Although + /// zero-size bindings are permitted by WebGPU, they are not permitted by + /// some backends. See [`Buffer::binding`] and + /// [#3170](https://github.com/gfx-rs/wgpu/issues/3170). + pub fn resolve_binding_size( + &self, + offset: wgt::BufferAddress, + binding_size: Option, + ) -> Result { + let buffer_size = self.size; + + match binding_size { + Some(binding_size) => match offset.checked_add(binding_size) { + Some(end) if end <= buffer_size => Ok(binding_size), + _ => Err(BindingError::BindingRangeTooLarge { + buffer: self.error_ident(), + offset, + binding_size, + buffer_size, + }), + }, + None => { + buffer_size + .checked_sub(offset) + .ok_or_else(|| BindingError::BindingOffsetTooLarge { + buffer: self.error_ident(), + offset, + buffer_size, + }) + } + } + } + + /// Create a new [`hal::BufferBinding`] for the buffer with `offset` and + /// `size`. + /// + /// If `size` is `None`, then the remainder of the buffer starting from + /// `offset` is used. + /// + /// If the binding would overflow the buffer, then an error is returned. + /// + /// Zero-size bindings are permitted here for historical reasons. Although + /// zero-size bindings are permitted by WebGPU, they are not permitted by + /// some backends. Previous documentation for `hal::BufferBinding` + /// disallowed zero-size bindings, but this restriction was not honored + /// elsewhere in the code. Zero-size bindings need to be quashed or remapped + /// to a non-zero size, either universally in wgpu-core, or in specific + /// backends that do not support them. See + /// [#3170](https://github.com/gfx-rs/wgpu/issues/3170). + pub fn binding<'a>( + &'a self, + offset: wgt::BufferAddress, + binding_size: Option, + snatch_guard: &'a SnatchGuard, + ) -> Result, BindingError> { + let buf_raw = self.try_raw(snatch_guard)?; + let resolved_size = self.resolve_binding_size(offset, binding_size)?; + unsafe { + // SAFETY: The offset and size passed to hal::BufferBinding::new_unchecked must + // define a binding contained within the buffer. + Ok(hal::BufferBinding::new_unchecked( + buf_raw, + offset, + resolved_size, + )) + } + } + /// Returns the mapping callback in case of error so that the callback can be fired outside /// of the locks that are held in this function. pub(crate) fn map_async( diff --git a/wgpu-core/src/timestamp_normalization/mod.rs b/wgpu-core/src/timestamp_normalization/mod.rs index dd4d466235c..e5a9ef9a8ad 100644 --- a/wgpu-core/src/timestamp_normalization/mod.rs +++ b/wgpu-core/src/timestamp_normalization/mod.rs @@ -242,12 +242,16 @@ impl TimestampNormalizer { } } - pub fn create_normalization_bind_group( + /// Create a bind group for normalizing timestamps in `buffer`. + /// + /// This function is unsafe because it does not know that `buffer_size` is + /// the true size of the buffer. + pub unsafe fn create_normalization_bind_group( &self, device: &Device, buffer: &dyn hal::DynBuffer, buffer_label: Option<&str>, - buffer_size: u64, + buffer_size: wgt::BufferSize, buffer_usages: wgt::BufferUsages, ) -> Result { unsafe { @@ -263,7 +267,7 @@ impl TimestampNormalizer { // at once to normalize the timestamps, we can't use it. We force the buffer to fail // to allocate. The lowest max binding size is 128MB, and query sets must be small // (no more than 4096), so this should never be hit in practice by sane programs. - if buffer_size > device.adapter.limits().max_storage_buffer_binding_size as u64 { + if buffer_size.get() > device.adapter.limits().max_storage_buffer_binding_size as u64 { return Err(DeviceError::OutOfMemory); } @@ -282,11 +286,7 @@ impl TimestampNormalizer { .create_bind_group(&hal::BindGroupDescriptor { label: Some(label), layout: &*state.temporary_bind_group_layout, - buffers: &[hal::BufferBinding { - buffer, - offset: 0, - size: None, - }], + buffers: &[hal::BufferBinding::new_unchecked(buffer, 0, buffer_size)], samplers: &[], textures: &[], acceleration_structures: &[], diff --git a/wgpu-hal/examples/halmark/main.rs b/wgpu-hal/examples/halmark/main.rs index 75f3bc2fb9a..60eb3d59b82 100644 --- a/wgpu-hal/examples/halmark/main.rs +++ b/wgpu-hal/examples/halmark/main.rs @@ -445,10 +445,9 @@ impl Example { let texture_view = unsafe { device.create_texture_view(&texture, &view_desc).unwrap() }; let global_group = { - let global_buffer_binding = hal::BufferBinding { - buffer: &global_buffer, - offset: 0, - size: None, + let global_buffer_binding = unsafe { + // SAFETY: This is the same size that was specified for buffer creation. + hal::BufferBinding::new_unchecked(&global_buffer, 0, global_buffer_desc.size) }; let texture_binding = hal::TextureBinding { view: &texture_view, @@ -483,10 +482,13 @@ impl Example { }; let local_group = { - let local_buffer_binding = hal::BufferBinding { - buffer: &local_buffer, - offset: 0, - size: wgpu_types::BufferSize::new(size_of::() as _), + let local_buffer_binding = unsafe { + // SAFETY: The size must fit within the buffer. + hal::BufferBinding::new_unchecked( + &local_buffer, + 0, + wgpu_types::BufferSize::new(size_of::() as _).unwrap(), + ) }; let local_group_desc = hal::BindGroupDescriptor { label: Some("local"), diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index a8d3a77b916..93e687ff1b5 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -603,10 +603,13 @@ impl Example { let texture_view = unsafe { device.create_texture_view(&texture, &view_desc).unwrap() }; let bind_group = { - let buffer_binding = hal::BufferBinding { - buffer: &uniform_buffer, - offset: 0, - size: None, + let buffer_binding = unsafe { + // SAFETY: The size matches the buffer allocation. + hal::BufferBinding::new_unchecked( + &uniform_buffer, + 0, + wgpu_types::BufferSize::new_unchecked(uniforms_size as u64), + ) }; let texture_binding = hal::TextureBinding { view: &texture_view, diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index f57e6b9238a..39e18af13b0 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -1136,7 +1136,7 @@ impl crate::CommandEncoder for super::CommandEncoder { ) { let ibv = Direct3D12::D3D12_INDEX_BUFFER_VIEW { BufferLocation: binding.resolve_address(), - SizeInBytes: binding.resolve_size() as u32, + SizeInBytes: binding.size.try_into().unwrap(), Format: auxil::dxgi::conv::map_index_format(format), }; @@ -1149,7 +1149,7 @@ impl crate::CommandEncoder for super::CommandEncoder { ) { let vb = &mut self.pass.vertex_buffers[index as usize]; vb.BufferLocation = binding.resolve_address(); - vb.SizeInBytes = binding.resolve_size() as u32; + vb.SizeInBytes = binding.size.try_into().unwrap(); self.pass.dirty_vertex_buffers |= 1 << index; } diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 24cd3826d4b..e4b8e449e54 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -1442,7 +1442,7 @@ impl crate::Device for super::Device { let end = start + entry.count as usize; for data in &desc.buffers[start..end] { let gpu_address = data.resolve_address(); - let mut size = data.resolve_size() as u32; + let mut size = data.size.try_into().unwrap(); if has_dynamic_offset { match ty { diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index c8e6c3e0cfb..cb5b1974f49 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -865,13 +865,6 @@ unsafe impl Sync for Buffer {} impl crate::DynBuffer for Buffer {} impl crate::BufferBinding<'_, Buffer> { - fn resolve_size(&self) -> wgt::BufferAddress { - match self.size { - Some(size) => size.get(), - None => self.buffer.size - self.offset, - } - } - // TODO: Return GPU handle directly? fn resolve_address(&self) -> wgt::BufferAddress { (unsafe { self.buffer.resource.GetGPUVirtualAddress() }) + self.offset diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index 0f36f734b8c..17a2fe72216 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -534,7 +534,6 @@ impl crate::Device for super::Device { return Ok(super::Buffer { raw: None, target, - size: desc.size, map_flags: 0, data: Some(Arc::new(MaybeMutex::new(vec![0; desc.size as usize]))), offset_of_current_mapping: Arc::new(MaybeMutex::new(0)), @@ -634,7 +633,6 @@ impl crate::Device for super::Device { Ok(super::Buffer { raw, target, - size: desc.size, map_flags, data, offset_of_current_mapping: Arc::new(MaybeMutex::new(0)), @@ -1263,13 +1261,11 @@ impl crate::Device for super::Device { let binding = match layout.ty { wgt::BindingType::Buffer { .. } => { let bb = &desc.buffers[entry.resource_index as usize]; + assert!(bb.size != 0, "zero-size bindings are not supported"); super::RawBinding::Buffer { raw: bb.buffer.raw.unwrap(), - offset: bb.offset as i32, - size: match bb.size { - Some(s) => s.get() as i32, - None => (bb.buffer.size - bb.offset) as i32, - }, + offset: bb.offset.try_into().unwrap(), + size: bb.size.try_into().unwrap(), } } wgt::BindingType::Sampler { .. } => { diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index a6073b4ec8f..c1b226f8cd6 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -342,7 +342,6 @@ impl Drop for Queue { pub struct Buffer { raw: Option, target: BindTarget, - size: wgt::BufferAddress, map_flags: u32, data: Option>>>, offset_of_current_mapping: Arc>, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 6f05edbb168..0ffdac35e7c 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -297,7 +297,7 @@ use core::{ borrow::Borrow, error::Error, fmt, - num::NonZeroU32, + num::{NonZeroU32, NonZeroU64}, ops::{Range, RangeInclusive}, ptr::NonNull, }; @@ -1968,11 +1968,18 @@ pub struct PipelineLayoutDescriptor<'a, B: DynBindGroupLayout + ?Sized> { /// /// [`BindGroup`]: Api::BindGroup /// +/// ## Construction +/// +/// The recommended way to construct a `BufferBinding` is using the `binding` +/// method on a wgpu-core `Buffer`, which will validate the binding size +/// against the buffer size. An unsafe `new_unchecked` constructor is also +/// provided for cases where direct construction is necessary. +/// /// ## Accessible region /// /// `wgpu_hal` guarantees that shaders compiled with /// [`ShaderModuleDescriptor::runtime_checks`] set to `true` cannot read or -/// write data via this binding outside the *accessible region* of [`buffer`]: +/// write data via this binding outside the *accessible region* of a buffer: /// /// - The accessible region starts at [`offset`]. /// @@ -1992,39 +1999,47 @@ pub struct PipelineLayoutDescriptor<'a, B: DynBindGroupLayout + ?Sized> { /// parts of which buffers shaders might observe. This optimization is only /// sound if shader access is bounds-checked. /// -/// [`buffer`]: BufferBinding::buffer +/// ## Zero-length bindings +/// +/// Some back ends cannot tolerate zero-length regions; for example, see +/// [VUID-VkDescriptorBufferInfo-offset-00340][340] and +/// [VUID-VkDescriptorBufferInfo-range-00341][341], or the +/// documentation for GLES's [glBindBufferRange][bbr]. This documentation +/// previously stated that a `BufferBinding` must have `offset` strictly less +/// than the size of the buffer, but this restriction was not honored elsewhere +/// in the code, so has been removed. However, it remains the case that +/// some backends do not support zero-length bindings, so additional +/// logic is needed somewhere to handle this properly. See +/// [#3170](https://github.com/gfx-rs/wgpu/issues/3170). +/// /// [`offset`]: BufferBinding::offset /// [`size`]: BufferBinding::size /// [`Storage`]: wgt::BufferBindingType::Storage /// [`Uniform`]: wgt::BufferBindingType::Uniform +/// [340]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkDescriptorBufferInfo-offset-00340 +/// [341]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkDescriptorBufferInfo-range-00341 +/// [bbr]: https://registry.khronos.org/OpenGL-Refpages/es3.0/html/glBindBufferRange.xhtml /// [woob]: https://gpuweb.github.io/gpuweb/wgsl/#out-of-bounds-access-sec #[derive(Debug)] pub struct BufferBinding<'a, B: DynBuffer + ?Sized> { /// The buffer being bound. - pub buffer: &'a B, + /// + /// This is not fully `pub` to prevent direct construction of + /// `BufferBinding`s, while still allowing public read access to the `offset` + /// and `size` properties. + pub(crate) buffer: &'a B, /// The offset at which the bound region starts. /// - /// This must be less than the size of the buffer. Some back ends - /// cannot tolerate zero-length regions; for example, see - /// [VUID-VkDescriptorBufferInfo-offset-00340][340] and - /// [VUID-VkDescriptorBufferInfo-range-00341][341], or the - /// documentation for GLES's [glBindBufferRange][bbr]. - /// - /// [340]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkDescriptorBufferInfo-offset-00340 - /// [341]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkDescriptorBufferInfo-range-00341 - /// [bbr]: https://registry.khronos.org/OpenGL-Refpages/es3.0/html/glBindBufferRange.xhtml + /// This must be less or equal to the size of the buffer. pub offset: wgt::BufferAddress, /// The size of the region bound, in bytes. - /// - /// If `None`, the region extends from `offset` to the end of the - /// buffer. Given the restrictions on `offset`, this means that - /// the size is always greater than zero. - pub size: Option, + pub size: wgt::BufferSizeOrZero, } -impl<'a, T: DynBuffer + ?Sized> Clone for BufferBinding<'a, T> { +// We must implement this manually because `B` is not necessarily `Clone`. +impl Clone for BufferBinding<'_, B> { fn clone(&self) -> Self { BufferBinding { buffer: self.buffer, @@ -2034,6 +2049,55 @@ impl<'a, T: DynBuffer + ?Sized> Clone for BufferBinding<'a, T> { } } +/// Temporary convenience trait to let us call `.get()` on `u64`s in code that +/// really wants to be using `NonZeroU64`. +/// TODO(): remove this +pub trait ShouldBeNonZeroExt { + fn get(&self) -> u64; +} + +impl ShouldBeNonZeroExt for NonZeroU64 { + fn get(&self) -> u64 { + NonZeroU64::get(*self) + } +} + +impl ShouldBeNonZeroExt for u64 { + fn get(&self) -> u64 { + *self + } +} + +impl<'a, B: DynBuffer + ?Sized> BufferBinding<'a, B> { + /// Construct a `BufferBinding` with the given contents. + /// + /// When possible, use the `binding` method on a wgpu-core `Buffer` instead + /// of this method. `Buffer::binding` validates the size of the binding + /// against the size of the buffer. + /// + /// It is more difficult to provide a validating constructor here, due to + /// not having direct access to the size of a `DynBuffer`. + /// + /// SAFETY: The caller is responsible for ensuring that a binding of `size` + /// bytes starting at `offset` is contained within the buffer. + /// + /// The `S` type parameter is a temporary convenience to allow callers to + /// pass either a `u64` or a `NonZeroU64`. When the zero-size binding issue + /// is resolved, the argument should just match the type of the member. + /// TODO(): remove the parameter + pub unsafe fn new_unchecked>( + buffer: &'a B, + offset: wgt::BufferAddress, + size: S, + ) -> Self { + Self { + buffer, + offset, + size: size.into(), + } + } +} + #[derive(Debug)] pub struct TextureBinding<'a, T: DynTextureView + ?Sized> { pub view: &'a T, diff --git a/wgpu-hal/src/metal/command.rs b/wgpu-hal/src/metal/command.rs index 72a799a0275..9f331fd4685 100644 --- a/wgpu-hal/src/metal/command.rs +++ b/wgpu-hal/src/metal/command.rs @@ -4,7 +4,7 @@ use alloc::{ borrow::{Cow, ToOwned as _}, vec::Vec, }; -use core::ops::Range; +use core::{num::NonZeroU64, ops::Range}; use metal::{ MTLIndexType, MTLLoadAction, MTLPrimitiveType, MTLScissorRect, MTLSize, MTLStoreAction, MTLViewport, MTLVisibilityResultMode, NSRange, @@ -977,15 +977,11 @@ impl crate::CommandEncoder for super::CommandEncoder { let encoder = self.state.render.as_ref().unwrap(); encoder.set_vertex_buffer(buffer_index, Some(&binding.buffer.raw), binding.offset); - let buffer_size = binding.resolve_size(); - if buffer_size > 0 { - self.state.vertex_buffer_size_map.insert( - buffer_index, - core::num::NonZeroU64::new(buffer_size).unwrap(), - ); - } else { - self.state.vertex_buffer_size_map.remove(&buffer_index); - } + // https://github.com/gfx-rs/wgpu/issues/3170 + let size = + NonZeroU64::new(binding.size).expect("zero-size vertex buffers are not supported"); + + self.state.vertex_buffer_size_map.insert(buffer_index, size); if let Some((index, sizes)) = self .state diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index ef8e7c83a52..ba40854dd43 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -1,5 +1,5 @@ use alloc::{borrow::ToOwned as _, sync::Arc, vec::Vec}; -use core::{ptr::NonNull, sync::atomic}; +use core::{num::NonZeroU64, ptr::NonNull, sync::atomic}; use std::{thread, time}; use parking_lot::Mutex; @@ -340,10 +340,6 @@ impl super::Device { } } - pub unsafe fn buffer_from_raw(raw: metal::Buffer, size: wgt::BufferAddress) -> super::Buffer { - super::Buffer { raw, size } - } - pub fn raw_device(&self) -> &Mutex { &self.shared.device } @@ -373,10 +369,7 @@ impl crate::Device for super::Device { raw.set_label(label); } self.counters.buffers.add(1); - Ok(super::Buffer { - raw, - size: desc.size, - }) + Ok(super::Buffer { raw }) }) } unsafe fn destroy_buffer(&self, _buffer: super::Buffer) { @@ -935,14 +928,12 @@ impl crate::Device for super::Device { let end = start + 1; bg.buffers .extend(desc.buffers[start..end].iter().map(|source| { - // Given the restrictions on `BufferBinding::offset`, - // this should never be `None`. - let remaining_size = wgt::BufferSize::new( - source.buffer.size - source.offset, - ); + // https://github.com/gfx-rs/wgpu/issues/3170 + let source_size = NonZeroU64::new(source.size) + .expect("zero-size bindings are not supported"); let binding_size = match ty { wgt::BufferBindingType::Storage { .. } => { - source.size.or(remaining_size) + Some(source_size) } _ => None, }; diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index b5ae1dd5d5d..30af14a33fa 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -502,7 +502,6 @@ impl crate::Queue for Queue { #[derive(Debug)] pub struct Buffer { raw: metal::Buffer, - size: wgt::BufferAddress, } unsafe impl Send for Buffer {} @@ -516,15 +515,6 @@ impl Buffer { } } -impl crate::BufferBinding<'_, Buffer> { - fn resolve_size(&self) -> wgt::BufferAddress { - match self.size { - Some(size) => size.get(), - None => self.buffer.size - self.offset, - } - } -} - #[derive(Debug)] pub struct Texture { raw: metal::Texture, diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index e760c49462b..5251d0e05d6 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -1804,12 +1804,12 @@ impl crate::Device for super::Device { (buffer_infos, local_buffer_infos) = buffer_infos.extend(desc.buffers[start as usize..end as usize].iter().map( |binding| { + // https://github.com/gfx-rs/wgpu/issues/3170 + assert!(binding.size != 0, "zero-size bindings are not supported"); vk::DescriptorBufferInfo::default() .buffer(binding.buffer.raw) .offset(binding.offset) - .range( - binding.size.map_or(vk::WHOLE_SIZE, wgt::BufferSize::get), - ) + .range(binding.size) }, )); write.buffer_info(local_buffer_infos) diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index ea821512eb5..0b676dd8cfc 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -61,6 +61,12 @@ pub type BufferAddress = u64; /// [`BufferSlice`]: ../wgpu/struct.BufferSlice.html pub type BufferSize = core::num::NonZeroU64; +/// Integral type used for buffer sizes that may be zero. +/// +/// Although the wgpu Rust API disallows zero-size `BufferSlice` and wgpu-hal +/// disallows zero-size bindings, WebGPU permits zero-size buffers and bindings. +pub type BufferSizeOrZero = u64; + /// Integral type used for binding locations in shaders. /// /// Used in [`VertexAttribute`]s and errors. diff --git a/wgpu/src/api/device.rs b/wgpu/src/api/device.rs index 8313e05dff3..6fe5cd0ea1e 100644 --- a/wgpu/src/api/device.rs +++ b/wgpu/src/api/device.rs @@ -324,6 +324,7 @@ impl Device { /// - `hal_buffer` must be created from this device internal handle /// - `hal_buffer` must be created respecting `desc` /// - `hal_buffer` must be initialized + /// - `hal_buffer` must not have zero size #[cfg(wgpu_core)] #[must_use] pub unsafe fn create_buffer_from_hal( diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index 7c9a23e39c2..f1509ac5648 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -166,6 +166,12 @@ impl ContextWgpuCore { } } + /// # Safety + /// + /// - `hal_buffer` must be created from `device`. + /// - `hal_buffer` must be created respecting `desc` + /// - `hal_buffer` must be initialized + /// - `hal_buffer` must not have zero size. pub unsafe fn create_buffer_from_hal( &self, hal_buffer: A::Buffer, From 2db1d71f1bdf4cb232085626aa1ea46b9c81f329 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 9 Jul 2025 16:28:51 -0700 Subject: [PATCH 002/303] [deno] Implement nullable vertex buffer layouts --- deno_webgpu/device.rs | 41 ++++++++++++++++++--------------------- wgpu-core/src/pipeline.rs | 11 +++++++++++ 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/deno_webgpu/device.rs b/deno_webgpu/device.rs index 5416f53798c..211cdc513d0 100644 --- a/deno_webgpu/device.rs +++ b/deno_webgpu/device.rs @@ -680,29 +680,26 @@ impl GPUDevice { .buffers .into_iter() .map(|b| { - let layout = b.into_option().ok_or_else(|| { - JsErrorBox::type_error( - "Nullable GPUVertexBufferLayouts are currently not supported", - ) - })?; - - Ok(wgpu_core::pipeline::VertexBufferLayout { - array_stride: layout.array_stride, - step_mode: layout.step_mode.into(), - attributes: Cow::Owned( - layout - .attributes - .into_iter() - .map(|attr| wgpu_types::VertexAttribute { - format: attr.format.into(), - offset: attr.offset, - shader_location: attr.shader_location, - }) - .collect(), - ), - }) + b.into_option().map_or_else( + wgpu_core::pipeline::VertexBufferLayout::default, + |layout| wgpu_core::pipeline::VertexBufferLayout { + array_stride: layout.array_stride, + step_mode: layout.step_mode.into(), + attributes: Cow::Owned( + layout + .attributes + .into_iter() + .map(|attr| wgpu_types::VertexAttribute { + format: attr.format.into(), + offset: attr.offset, + shader_location: attr.shader_location, + }) + .collect(), + ), + }, + ) }) - .collect::>()?, + .collect(), ), }; diff --git a/wgpu-core/src/pipeline.rs b/wgpu-core/src/pipeline.rs index 3c4b52cc757..3bc3f7f6d79 100644 --- a/wgpu-core/src/pipeline.rs +++ b/wgpu-core/src/pipeline.rs @@ -371,6 +371,17 @@ pub struct VertexBufferLayout<'a> { pub attributes: Cow<'a, [wgt::VertexAttribute]>, } +/// A null vertex buffer layout that may be placed in unused slots. +impl Default for VertexBufferLayout<'_> { + fn default() -> Self { + Self { + array_stride: Default::default(), + step_mode: Default::default(), + attributes: Cow::Borrowed(&[]), + } + } +} + /// Describes the vertex process in a render pipeline. #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] From 00406a75a4c95261587af125f3855c721fc39bcf Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 9 Jul 2025 13:55:37 -0700 Subject: [PATCH 003/303] Fix calculation error --- wgpu-core/src/command/bundle.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index c476a0aaf99..6a9a0b75bb0 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -622,7 +622,7 @@ fn set_index_buffer( buffer.same_device(&state.device)?; buffer.check_usage(wgt::BufferUsages::INDEX)?; - let end = buffer.resolve_binding_size(offset, size)?; + let end = offset + buffer.resolve_binding_size(offset, size)?; state .buffer_memory_init_actions @@ -663,7 +663,7 @@ fn set_vertex_buffer( buffer.same_device(&state.device)?; buffer.check_usage(wgt::BufferUsages::VERTEX)?; - let end = buffer.resolve_binding_size(offset, size)?; + let end = offset + buffer.resolve_binding_size(offset, size)?; state .buffer_memory_init_actions From 468632f20747079b242c46fae97e43bf67014ddd Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 9 Jul 2025 11:31:06 -0700 Subject: [PATCH 004/303] Restore plumbing of implicit remainder-of-buffer size to backends --- cts_runner/test.lst | 2 + wgpu-core/src/command/bundle.rs | 26 ++++-------- wgpu-core/src/command/render.rs | 40 ++++++++---------- wgpu-core/src/command/render_command.rs | 17 +++----- wgpu-core/src/device/resource.rs | 10 ++--- wgpu-core/src/indirect_validation/dispatch.rs | 2 +- wgpu-core/src/resource.rs | 41 ++++++++++--------- wgpu-hal/examples/halmark/main.rs | 12 ++++-- wgpu-hal/src/dx12/command.rs | 4 +- wgpu-hal/src/dx12/device.rs | 2 +- wgpu-hal/src/dx12/mod.rs | 7 ++++ wgpu-hal/src/gles/device.rs | 10 +++-- wgpu-hal/src/gles/mod.rs | 1 + wgpu-hal/src/lib.rs | 25 ++++++++--- wgpu-hal/src/metal/command.rs | 16 +++++--- wgpu-hal/src/metal/device.rs | 21 +++++++--- wgpu-hal/src/metal/mod.rs | 10 +++++ wgpu-hal/src/vulkan/device.rs | 6 +-- wgpu-types/src/lib.rs | 6 --- 19 files changed, 144 insertions(+), 114 deletions(-) diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 163944db9ad..6432ffdd387 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -27,6 +27,8 @@ webgpu:api,validation,encoding,cmds,copyTextureToTexture:sample_count:* //FAIL: webgpu:api,validation,encoding,cmds,copyTextureToTexture:copy_ranges_with_compressed_texture_formats:* webgpu:api,validation,encoding,cmds,index_access:* //FAIL: webgpu:api,validation,encoding,cmds,render,draw:* +webgpu:api,validation,encoding,cmds,render,draw:index_buffer_OOB:* +webgpu:api,validation,encoding,cmds,render,draw:unused_buffer_bound:* webgpu:api,validation,encoding,encoder_state:* webgpu:api,validation,encoding,encoder_open_state:non_pass_commands:* webgpu:api,validation,encoding,encoder_open_state:render_pass_commands:* diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index 6a9a0b75bb0..d883f37116d 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -505,7 +505,7 @@ impl RenderBundleEncoder { buffer_id, index_format, offset, - size: size.map(NonZeroU64::get), + size, }); } } @@ -610,7 +610,7 @@ fn set_index_buffer( buffer_id: id::Id, index_format: wgt::IndexFormat, offset: u64, - size: Option, + size: Option, ) -> Result<(), RenderBundleErrorInner> { let buffer = buffer_guard.get(buffer_id).get()?; @@ -642,7 +642,7 @@ fn set_vertex_buffer( slot: u32, buffer_id: id::Id, offset: u64, - size: Option, + size: Option, ) -> Result<(), RenderBundleErrorInner> { let max_vertex_buffers = state.device.limits.max_vertex_buffers; if slot >= max_vertex_buffers { @@ -967,11 +967,7 @@ impl RenderBundle { let bb = unsafe { // SAFETY: The binding size was checked against the buffer size // in `set_index_buffer` and again in `IndexState::flush`. - hal::BufferBinding::new_unchecked( - buffer, - *offset, - size.expect("size was resolved in `RenderBundleEncoder::finish`"), - ) + hal::BufferBinding::new_unchecked(buffer, *offset, *size) }; unsafe { raw.set_index_buffer(bb, *index_format) }; } @@ -985,11 +981,7 @@ impl RenderBundle { let bb = unsafe { // SAFETY: The binding size was checked against the buffer size // in `set_vertex_buffer` and again in `VertexState::flush`. - hal::BufferBinding::new_unchecked( - buffer, - *offset, - size.expect("size was resolved in `RenderBundleEncoder::finish`"), - ) + hal::BufferBinding::new_unchecked(buffer, *offset, *size) }; unsafe { raw.set_vertex_buffer(*slot, bb) }; } @@ -1176,7 +1168,7 @@ impl IndexState { buffer: self.buffer.clone(), index_format: self.format, offset: self.range.start, - size: Some(binding_size), + size: NonZeroU64::new(binding_size), }) } else { None @@ -1232,7 +1224,7 @@ impl VertexState { slot, buffer: self.buffer.clone(), offset: self.range.start, - size: Some(binding_size), + size: NonZeroU64::new(binding_size), }) } else { None @@ -1596,7 +1588,7 @@ where pub mod bundle_ffi { use super::{RenderBundleEncoder, RenderCommand}; use crate::{id, RawString}; - use core::{convert::TryInto, num::NonZeroU64, slice}; + use core::{convert::TryInto, slice}; use wgt::{BufferAddress, BufferSize, DynamicOffset, IndexFormat}; /// # Safety @@ -1655,7 +1647,7 @@ pub mod bundle_ffi { slot, buffer_id, offset, - size: size.map(NonZeroU64::get), + size, }); } diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 58bda99c4b7..96c09c3c1a2 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1,17 +1,12 @@ use alloc::{borrow::Cow, sync::Arc, vec::Vec}; -use core::{ - fmt, - num::{NonZeroU32, NonZeroU64}, - str, -}; -use hal::ShouldBeNonZeroExt; +use core::{fmt, num::NonZeroU32, ops::Range, str}; use arrayvec::ArrayVec; use thiserror::Error; use wgt::{ error::{ErrorType, WebGpuError}, - BufferAddress, BufferSize, BufferSizeOrZero, BufferUsages, Color, DynamicOffset, IndexFormat, - ShaderStages, TextureSelector, TextureUsages, TextureViewDimension, VertexStepMode, + BufferAddress, BufferSize, BufferUsages, Color, DynamicOffset, IndexFormat, ShaderStages, + TextureSelector, TextureUsages, TextureViewDimension, VertexStepMode, }; use crate::command::{ @@ -362,17 +357,13 @@ struct IndexState { } impl IndexState { - fn update_buffer( - &mut self, - binding: &hal::BufferBinding<'_, B>, - format: IndexFormat, - ) { + fn update_buffer(&mut self, range: Range, format: IndexFormat) { self.buffer_format = Some(format); let shift = match format { IndexFormat::Uint16 => 1, IndexFormat::Uint32 => 2, }; - self.limit = binding.size.get() >> shift; + self.limit = (range.end - range.start) >> shift; } fn reset(&mut self) { @@ -2339,7 +2330,7 @@ fn set_index_buffer( buffer: Arc, index_format: IndexFormat, offset: u64, - size: Option, + size: Option, ) -> Result<(), RenderPassErrorInner> { api_log!("RenderPass::set_index_buffer {}", buffer.error_ident()); @@ -2353,15 +2344,16 @@ fn set_index_buffer( buffer.check_usage(BufferUsages::INDEX)?; - let binding = buffer + let (binding, resolved_size) = buffer .binding(offset, size, state.general.snatch_guard) .map_err(RenderCommandError::from)?; - state.index.update_buffer(&binding, index_format); + let end = offset + resolved_size; + state.index.update_buffer(offset..end, index_format); state.general.buffer_memory_init_actions.extend( buffer.initialization_status.read().create_action( &buffer, - offset..(offset + binding.size.get()), + offset..end, MemoryInitKind::NeedsInitializedMemory, ), ); @@ -2379,7 +2371,7 @@ fn set_vertex_buffer( slot: u32, buffer: Arc, offset: u64, - size: Option, + size: Option, ) -> Result<(), RenderPassErrorInner> { api_log!( "RenderPass::set_vertex_buffer {slot} {}", @@ -2405,15 +2397,15 @@ fn set_vertex_buffer( buffer.check_usage(BufferUsages::VERTEX)?; - let binding = buffer + let (binding, buffer_size) = buffer .binding(offset, size, state.general.snatch_guard) .map_err(RenderCommandError::from)?; - state.vertex.buffer_sizes[slot as usize] = Some(binding.size.get()); + state.vertex.buffer_sizes[slot as usize] = Some(buffer_size); state.general.buffer_memory_init_actions.extend( buffer.initialization_status.read().create_action( &buffer, - offset..(offset + binding.size.get()), + offset..(offset + buffer_size), MemoryInitKind::NeedsInitializedMemory, ), ); @@ -3090,7 +3082,7 @@ impl Global { buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), index_format, offset, - size: size.map(NonZeroU64::get), + size, }); Ok(()) @@ -3111,7 +3103,7 @@ impl Global { slot, buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), offset, - size: size.map(NonZeroU64::get), + size, }); Ok(()) diff --git a/wgpu-core/src/command/render_command.rs b/wgpu-core/src/command/render_command.rs index f57ec026e24..6564238548f 100644 --- a/wgpu-core/src/command/render_command.rs +++ b/wgpu-core/src/command/render_command.rs @@ -1,6 +1,6 @@ use alloc::sync::Arc; -use wgt::{BufferAddress, BufferSizeOrZero, Color}; +use wgt::{BufferAddress, BufferSize, Color}; use super::{Rect, RenderBundle}; use crate::{ @@ -24,13 +24,13 @@ pub enum RenderCommand { buffer_id: id::BufferId, index_format: wgt::IndexFormat, offset: BufferAddress, - size: Option, + size: Option, }, SetVertexBuffer { slot: u32, buffer_id: id::BufferId, offset: BufferAddress, - size: Option, + size: Option, }, SetBlendConstant(Color), SetStencilReference(u32), @@ -416,20 +416,13 @@ pub enum ArcRenderCommand { buffer: Arc, index_format: wgt::IndexFormat, offset: BufferAddress, - - // For a render pass, this reflects the argument passed by the - // application, which may be `None`. For a finished render bundle, this - // reflects the validated size of the binding, and will be populated - // even in the case that the application omitted the size. - size: Option, + size: Option, }, SetVertexBuffer { slot: u32, buffer: Arc, offset: BufferAddress, - - // See comment in `SetIndexBuffer`. - size: Option, + size: Option, }, SetBlendConstant(Color), SetStencilReference(u32), diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 5afc4d6b3a1..302a74e341e 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -8,7 +8,7 @@ use alloc::{ use core::{ fmt, mem::{self, ManuallyDrop}, - num::{NonZeroU32, NonZeroU64}, + num::NonZeroU32, sync::atomic::{AtomicBool, Ordering}, }; use hal::ShouldBeNonZeroExt; @@ -2198,8 +2198,8 @@ impl Device { buffer.check_usage(pub_usage)?; - let bb = buffer.binding(bb.offset, bb.size.map(NonZeroU64::get), snatch_guard)?; - let bind_size = bb.size.get(); + let (bb, bind_size) = buffer.binding(bb.offset, bb.size, snatch_guard)?; + let bind_end = bb.offset + bind_size; if bind_size > range_limit as u64 { return Err(Error::BufferRangeTooLarge { @@ -2214,8 +2214,8 @@ impl Device { dynamic_binding_info.push(binding_model::BindGroupDynamicBindingData { binding_idx: binding, buffer_size: buffer.size, - binding_range: bb.offset..bb.offset + bind_size, - maximum_dynamic_offset: buffer.size - bb.offset - bind_size, + binding_range: bb.offset..bind_end, + maximum_dynamic_offset: buffer.size - bind_end, binding_type: binding_ty, }); } diff --git a/wgpu-core/src/indirect_validation/dispatch.rs b/wgpu-core/src/indirect_validation/dispatch.rs index e9fe4971bf7..aa89619b766 100644 --- a/wgpu-core/src/indirect_validation/dispatch.rs +++ b/wgpu-core/src/indirect_validation/dispatch.rs @@ -234,7 +234,7 @@ impl Dispatch { }], buffers: &[unsafe { // SAFETY: We just created the buffer with this size. - hal::BufferBinding::new_unchecked(dst_buffer.as_ref(), 0, DST_BUFFER_SIZE) + hal::BufferBinding::new_unchecked(dst_buffer.as_ref(), 0, Some(DST_BUFFER_SIZE)) }], samplers: &[], textures: &[], diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 1bfde1db775..eaf3a377802 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -508,17 +508,17 @@ impl Buffer { pub fn resolve_binding_size( &self, offset: wgt::BufferAddress, - binding_size: Option, - ) -> Result { + binding_size: Option, + ) -> Result { let buffer_size = self.size; match binding_size { - Some(binding_size) => match offset.checked_add(binding_size) { - Some(end) if end <= buffer_size => Ok(binding_size), + Some(binding_size) => match offset.checked_add(binding_size.get()) { + Some(end) if end <= buffer_size => Ok(binding_size.get()), _ => Err(BindingError::BindingRangeTooLarge { buffer: self.error_ident(), offset, - binding_size, + binding_size: binding_size.get(), buffer_size, }), }, @@ -535,35 +535,38 @@ impl Buffer { } /// Create a new [`hal::BufferBinding`] for the buffer with `offset` and - /// `size`. + /// `binding_size`. /// - /// If `size` is `None`, then the remainder of the buffer starting from - /// `offset` is used. + /// If `binding_size` is `None`, then the remainder of the buffer starting + /// from `offset` is used. /// /// If the binding would overflow the buffer, then an error is returned. /// - /// Zero-size bindings are permitted here for historical reasons. Although + /// A zero-size binding at the end of the buffer is permitted here for historical reasons. Although /// zero-size bindings are permitted by WebGPU, they are not permitted by - /// some backends. Previous documentation for `hal::BufferBinding` - /// disallowed zero-size bindings, but this restriction was not honored - /// elsewhere in the code. Zero-size bindings need to be quashed or remapped - /// to a non-zero size, either universally in wgpu-core, or in specific - /// backends that do not support them. See + /// some backends. The zero-size binding need to be quashed or remapped to a + /// non-zero size, either universally in wgpu-core, or in specific backends + /// that do not support them. See /// [#3170](https://github.com/gfx-rs/wgpu/issues/3170). + /// + /// Although it seems like it would be simpler and safer to use the resolved + /// size in the returned [`hal::BufferBinding`], doing this (and removing + /// redundant logic in backends to resolve the implicit size) was observed + /// to cause problems in certain CTS tests, so an implicit size + /// specification is preserved in the output. pub fn binding<'a>( &'a self, offset: wgt::BufferAddress, - binding_size: Option, + binding_size: Option, snatch_guard: &'a SnatchGuard, - ) -> Result, BindingError> { + ) -> Result<(hal::BufferBinding<'a, dyn hal::DynBuffer>, u64), BindingError> { let buf_raw = self.try_raw(snatch_guard)?; let resolved_size = self.resolve_binding_size(offset, binding_size)?; unsafe { // SAFETY: The offset and size passed to hal::BufferBinding::new_unchecked must // define a binding contained within the buffer. - Ok(hal::BufferBinding::new_unchecked( - buf_raw, - offset, + Ok(( + hal::BufferBinding::new_unchecked(buf_raw, offset, binding_size), resolved_size, )) } diff --git a/wgpu-hal/examples/halmark/main.rs b/wgpu-hal/examples/halmark/main.rs index 60eb3d59b82..0b1c3c28da6 100644 --- a/wgpu-hal/examples/halmark/main.rs +++ b/wgpu-hal/examples/halmark/main.rs @@ -14,7 +14,9 @@ use winit::{ use std::{ borrow::{Borrow, Cow}, - iter, ptr, + iter, + num::NonZeroU64, + ptr, time::Instant, }; @@ -447,7 +449,11 @@ impl Example { let global_group = { let global_buffer_binding = unsafe { // SAFETY: This is the same size that was specified for buffer creation. - hal::BufferBinding::new_unchecked(&global_buffer, 0, global_buffer_desc.size) + hal::BufferBinding::new_unchecked( + &global_buffer, + 0, + NonZeroU64::new(global_buffer_desc.size), + ) }; let texture_binding = hal::TextureBinding { view: &texture_view, @@ -487,7 +493,7 @@ impl Example { hal::BufferBinding::new_unchecked( &local_buffer, 0, - wgpu_types::BufferSize::new(size_of::() as _).unwrap(), + wgpu_types::BufferSize::new(size_of::() as _), ) }; let local_group_desc = hal::BindGroupDescriptor { diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index 39e18af13b0..32953455927 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -1136,7 +1136,7 @@ impl crate::CommandEncoder for super::CommandEncoder { ) { let ibv = Direct3D12::D3D12_INDEX_BUFFER_VIEW { BufferLocation: binding.resolve_address(), - SizeInBytes: binding.size.try_into().unwrap(), + SizeInBytes: binding.resolve_size().try_into().unwrap(), Format: auxil::dxgi::conv::map_index_format(format), }; @@ -1149,7 +1149,7 @@ impl crate::CommandEncoder for super::CommandEncoder { ) { let vb = &mut self.pass.vertex_buffers[index as usize]; vb.BufferLocation = binding.resolve_address(); - vb.SizeInBytes = binding.size.try_into().unwrap(); + vb.SizeInBytes = binding.resolve_size().try_into().unwrap(); self.pass.dirty_vertex_buffers |= 1 << index; } diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index e4b8e449e54..19e7743d6f7 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -1442,7 +1442,7 @@ impl crate::Device for super::Device { let end = start + entry.count as usize; for data in &desc.buffers[start..end] { let gpu_address = data.resolve_address(); - let mut size = data.size.try_into().unwrap(); + let mut size = data.resolve_size().try_into().unwrap(); if has_dynamic_offset { match ty { diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index cb5b1974f49..c8e6c3e0cfb 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -865,6 +865,13 @@ unsafe impl Sync for Buffer {} impl crate::DynBuffer for Buffer {} impl crate::BufferBinding<'_, Buffer> { + fn resolve_size(&self) -> wgt::BufferAddress { + match self.size { + Some(size) => size.get(), + None => self.buffer.size - self.offset, + } + } + // TODO: Return GPU handle directly? fn resolve_address(&self) -> wgt::BufferAddress { (unsafe { self.buffer.resource.GetGPUVirtualAddress() }) + self.offset diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index 17a2fe72216..0f36f734b8c 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -534,6 +534,7 @@ impl crate::Device for super::Device { return Ok(super::Buffer { raw: None, target, + size: desc.size, map_flags: 0, data: Some(Arc::new(MaybeMutex::new(vec![0; desc.size as usize]))), offset_of_current_mapping: Arc::new(MaybeMutex::new(0)), @@ -633,6 +634,7 @@ impl crate::Device for super::Device { Ok(super::Buffer { raw, target, + size: desc.size, map_flags, data, offset_of_current_mapping: Arc::new(MaybeMutex::new(0)), @@ -1261,11 +1263,13 @@ impl crate::Device for super::Device { let binding = match layout.ty { wgt::BindingType::Buffer { .. } => { let bb = &desc.buffers[entry.resource_index as usize]; - assert!(bb.size != 0, "zero-size bindings are not supported"); super::RawBinding::Buffer { raw: bb.buffer.raw.unwrap(), - offset: bb.offset.try_into().unwrap(), - size: bb.size.try_into().unwrap(), + offset: bb.offset as i32, + size: match bb.size { + Some(s) => s.get() as i32, + None => (bb.buffer.size - bb.offset) as i32, + }, } } wgt::BindingType::Sampler { .. } => { diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index c1b226f8cd6..a6073b4ec8f 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -342,6 +342,7 @@ impl Drop for Queue { pub struct Buffer { raw: Option, target: BindTarget, + size: wgt::BufferAddress, map_flags: u32, data: Option>>>, offset_of_current_mapping: Arc>, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 0ffdac35e7c..83f88690f70 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -1972,8 +1972,8 @@ pub struct PipelineLayoutDescriptor<'a, B: DynBindGroupLayout + ?Sized> { /// /// The recommended way to construct a `BufferBinding` is using the `binding` /// method on a wgpu-core `Buffer`, which will validate the binding size -/// against the buffer size. An unsafe `new_unchecked` constructor is also -/// provided for cases where direct construction is necessary. +/// against the buffer size. A `new_unchecked` constructor is also provided for +/// cases where direct construction is necessary. /// /// ## Accessible region /// @@ -2035,7 +2035,11 @@ pub struct BufferBinding<'a, B: DynBuffer + ?Sized> { pub offset: wgt::BufferAddress, /// The size of the region bound, in bytes. - pub size: wgt::BufferSizeOrZero, + /// + /// If `None`, the region extends from `offset` to the end of the + /// buffer. Given the restrictions on `offset`, this means that + /// the size is always greater than zero. + pub size: Option, } // We must implement this manually because `B` is not necessarily `Clone`. @@ -2068,6 +2072,15 @@ impl ShouldBeNonZeroExt for u64 { } } +impl ShouldBeNonZeroExt for Option { + fn get(&self) -> u64 { + match *self { + Some(non_zero) => non_zero.get(), + None => 0, + } + } +} + impl<'a, B: DynBuffer + ?Sized> BufferBinding<'a, B> { /// Construct a `BufferBinding` with the given contents. /// @@ -2082,10 +2095,10 @@ impl<'a, B: DynBuffer + ?Sized> BufferBinding<'a, B> { /// bytes starting at `offset` is contained within the buffer. /// /// The `S` type parameter is a temporary convenience to allow callers to - /// pass either a `u64` or a `NonZeroU64`. When the zero-size binding issue - /// is resolved, the argument should just match the type of the member. + /// pass a zero size. When the zero-size binding issue is resolved, the + /// argument should just match the type of the member. /// TODO(): remove the parameter - pub unsafe fn new_unchecked>( + pub unsafe fn new_unchecked>>( buffer: &'a B, offset: wgt::BufferAddress, size: S, diff --git a/wgpu-hal/src/metal/command.rs b/wgpu-hal/src/metal/command.rs index 9f331fd4685..72a799a0275 100644 --- a/wgpu-hal/src/metal/command.rs +++ b/wgpu-hal/src/metal/command.rs @@ -4,7 +4,7 @@ use alloc::{ borrow::{Cow, ToOwned as _}, vec::Vec, }; -use core::{num::NonZeroU64, ops::Range}; +use core::ops::Range; use metal::{ MTLIndexType, MTLLoadAction, MTLPrimitiveType, MTLScissorRect, MTLSize, MTLStoreAction, MTLViewport, MTLVisibilityResultMode, NSRange, @@ -977,11 +977,15 @@ impl crate::CommandEncoder for super::CommandEncoder { let encoder = self.state.render.as_ref().unwrap(); encoder.set_vertex_buffer(buffer_index, Some(&binding.buffer.raw), binding.offset); - // https://github.com/gfx-rs/wgpu/issues/3170 - let size = - NonZeroU64::new(binding.size).expect("zero-size vertex buffers are not supported"); - - self.state.vertex_buffer_size_map.insert(buffer_index, size); + let buffer_size = binding.resolve_size(); + if buffer_size > 0 { + self.state.vertex_buffer_size_map.insert( + buffer_index, + core::num::NonZeroU64::new(buffer_size).unwrap(), + ); + } else { + self.state.vertex_buffer_size_map.remove(&buffer_index); + } if let Some((index, sizes)) = self .state diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index ba40854dd43..ef8e7c83a52 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -1,5 +1,5 @@ use alloc::{borrow::ToOwned as _, sync::Arc, vec::Vec}; -use core::{num::NonZeroU64, ptr::NonNull, sync::atomic}; +use core::{ptr::NonNull, sync::atomic}; use std::{thread, time}; use parking_lot::Mutex; @@ -340,6 +340,10 @@ impl super::Device { } } + pub unsafe fn buffer_from_raw(raw: metal::Buffer, size: wgt::BufferAddress) -> super::Buffer { + super::Buffer { raw, size } + } + pub fn raw_device(&self) -> &Mutex { &self.shared.device } @@ -369,7 +373,10 @@ impl crate::Device for super::Device { raw.set_label(label); } self.counters.buffers.add(1); - Ok(super::Buffer { raw }) + Ok(super::Buffer { + raw, + size: desc.size, + }) }) } unsafe fn destroy_buffer(&self, _buffer: super::Buffer) { @@ -928,12 +935,14 @@ impl crate::Device for super::Device { let end = start + 1; bg.buffers .extend(desc.buffers[start..end].iter().map(|source| { - // https://github.com/gfx-rs/wgpu/issues/3170 - let source_size = NonZeroU64::new(source.size) - .expect("zero-size bindings are not supported"); + // Given the restrictions on `BufferBinding::offset`, + // this should never be `None`. + let remaining_size = wgt::BufferSize::new( + source.buffer.size - source.offset, + ); let binding_size = match ty { wgt::BufferBindingType::Storage { .. } => { - Some(source_size) + source.size.or(remaining_size) } _ => None, }; diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index 30af14a33fa..b5ae1dd5d5d 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -502,6 +502,7 @@ impl crate::Queue for Queue { #[derive(Debug)] pub struct Buffer { raw: metal::Buffer, + size: wgt::BufferAddress, } unsafe impl Send for Buffer {} @@ -515,6 +516,15 @@ impl Buffer { } } +impl crate::BufferBinding<'_, Buffer> { + fn resolve_size(&self) -> wgt::BufferAddress { + match self.size { + Some(size) => size.get(), + None => self.buffer.size - self.offset, + } + } +} + #[derive(Debug)] pub struct Texture { raw: metal::Texture, diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 5251d0e05d6..e760c49462b 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -1804,12 +1804,12 @@ impl crate::Device for super::Device { (buffer_infos, local_buffer_infos) = buffer_infos.extend(desc.buffers[start as usize..end as usize].iter().map( |binding| { - // https://github.com/gfx-rs/wgpu/issues/3170 - assert!(binding.size != 0, "zero-size bindings are not supported"); vk::DescriptorBufferInfo::default() .buffer(binding.buffer.raw) .offset(binding.offset) - .range(binding.size) + .range( + binding.size.map_or(vk::WHOLE_SIZE, wgt::BufferSize::get), + ) }, )); write.buffer_info(local_buffer_infos) diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 0b676dd8cfc..ea821512eb5 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -61,12 +61,6 @@ pub type BufferAddress = u64; /// [`BufferSlice`]: ../wgpu/struct.BufferSlice.html pub type BufferSize = core::num::NonZeroU64; -/// Integral type used for buffer sizes that may be zero. -/// -/// Although the wgpu Rust API disallows zero-size `BufferSlice` and wgpu-hal -/// disallows zero-size bindings, WebGPU permits zero-size buffers and bindings. -pub type BufferSizeOrZero = u64; - /// Integral type used for binding locations in shaders. /// /// Used in [`VertexAttribute`]s and errors. From 9b966bf8a39b07bfc495fb43e8bf7725c5df440c Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 9 Jul 2025 09:56:57 -0700 Subject: [PATCH 005/303] Fix for destroyed resource errors --- cts_runner/test.lst | 2 ++ wgpu-core/src/command/mod.rs | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 6432ffdd387..c509d87bbee 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -29,6 +29,8 @@ webgpu:api,validation,encoding,cmds,index_access:* //FAIL: webgpu:api,validation,encoding,cmds,render,draw:* webgpu:api,validation,encoding,cmds,render,draw:index_buffer_OOB:* webgpu:api,validation,encoding,cmds,render,draw:unused_buffer_bound:* +webgpu:api,validation,encoding,cmds,render,setIndexBuffer:index_buffer_state:* +webgpu:api,validation,encoding,cmds,render,setVertexBuffer:vertex_buffer_state:* webgpu:api,validation,encoding,encoder_state:* webgpu:api,validation,encoding,encoder_open_state:non_pass_commands:* webgpu:api,validation,encoding,encoder_open_state:render_pass_commands:* diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 80133c5b8ae..9587669c73d 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -31,6 +31,7 @@ pub use timestamp_writes::PassTimestampWrites; use self::memory_init::CommandBufferTextureMemoryActions; +use crate::binding_model::BindingError; use crate::command::transition_resources::TransitionResourcesError; use crate::device::queue::TempResource; use crate::device::{Device, DeviceError, MissingFeatures}; @@ -1060,6 +1061,18 @@ impl CommandEncoderError { inner: RenderPassErrorInner::DestroyedResource(_), .. }) + | Self::RenderPass(RenderPassError { + inner: RenderPassErrorInner::RenderCommand( + RenderCommandError::DestroyedResource(_) + ), + .. + }) + | Self::RenderPass(RenderPassError { + inner: RenderPassErrorInner::RenderCommand(RenderCommandError::BindingError( + BindingError::DestroyedResource(_) + )), + .. + }) ) } } From dc924bc715e64662deb7c7062789a843abc58c65 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 9 Jul 2025 16:56:49 -0700 Subject: [PATCH 006/303] Remove `unsafe` from `hal::BufferBinding::new_unchecked` --- wgpu-core/src/command/bundle.rs | 16 ++++------- wgpu-core/src/indirect_validation/dispatch.rs | 16 +++++------ wgpu-core/src/indirect_validation/draw.rs | 16 +++++------ wgpu-core/src/resource.rs | 14 ++++------ wgpu-hal/examples/halmark/main.rs | 28 ++++++++----------- wgpu-hal/src/lib.rs | 2 +- 6 files changed, 41 insertions(+), 51 deletions(-) diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index d883f37116d..8566706da8a 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -964,11 +964,9 @@ impl RenderBundle { size, } => { let buffer = buffer.try_raw(snatch_guard)?; - let bb = unsafe { - // SAFETY: The binding size was checked against the buffer size - // in `set_index_buffer` and again in `IndexState::flush`. - hal::BufferBinding::new_unchecked(buffer, *offset, *size) - }; + // SAFETY: The binding size was checked against the buffer size + // in `set_index_buffer` and again in `IndexState::flush`. + let bb = hal::BufferBinding::new_unchecked(buffer, *offset, *size); unsafe { raw.set_index_buffer(bb, *index_format) }; } Cmd::SetVertexBuffer { @@ -978,11 +976,9 @@ impl RenderBundle { size, } => { let buffer = buffer.try_raw(snatch_guard)?; - let bb = unsafe { - // SAFETY: The binding size was checked against the buffer size - // in `set_vertex_buffer` and again in `VertexState::flush`. - hal::BufferBinding::new_unchecked(buffer, *offset, *size) - }; + // SAFETY: The binding size was checked against the buffer size + // in `set_vertex_buffer` and again in `VertexState::flush`. + let bb = hal::BufferBinding::new_unchecked(buffer, *offset, *size); unsafe { raw.set_vertex_buffer(*slot, bb) }; } Cmd::SetPushConstant { diff --git a/wgpu-core/src/indirect_validation/dispatch.rs b/wgpu-core/src/indirect_validation/dispatch.rs index aa89619b766..a1c1627fd3a 100644 --- a/wgpu-core/src/indirect_validation/dispatch.rs +++ b/wgpu-core/src/indirect_validation/dispatch.rs @@ -232,10 +232,12 @@ impl Dispatch { resource_index: 0, count: 1, }], - buffers: &[unsafe { - // SAFETY: We just created the buffer with this size. - hal::BufferBinding::new_unchecked(dst_buffer.as_ref(), 0, Some(DST_BUFFER_SIZE)) - }], + // SAFETY: We just created the buffer with this size. + buffers: &[hal::BufferBinding::new_unchecked( + dst_buffer.as_ref(), + 0, + Some(DST_BUFFER_SIZE), + )], samplers: &[], textures: &[], acceleration_structures: &[], @@ -277,10 +279,8 @@ impl Dispatch { resource_index: 0, count: 1, }], - buffers: &[unsafe { - // SAFETY: We calculated the binding size to fit within the buffer. - hal::BufferBinding::new_unchecked(buffer, 0, binding_size) - }], + // SAFETY: We calculated the binding size to fit within the buffer. + buffers: &[hal::BufferBinding::new_unchecked(buffer, 0, binding_size)], samplers: &[], textures: &[], acceleration_structures: &[], diff --git a/wgpu-core/src/indirect_validation/draw.rs b/wgpu-core/src/indirect_validation/draw.rs index af0e1a2c54c..8e6943f3c34 100644 --- a/wgpu-core/src/indirect_validation/draw.rs +++ b/wgpu-core/src/indirect_validation/draw.rs @@ -135,10 +135,8 @@ impl Draw { resource_index: 0, count: 1, }], - buffers: &[unsafe { - // SAFETY: We calculated the binding size to fit within the buffer. - hal::BufferBinding::new_unchecked(buffer, 0, binding_size) - }], + // SAFETY: We calculated the binding size to fit within the buffer. + buffers: &[hal::BufferBinding::new_unchecked(buffer, 0, binding_size)], samplers: &[], textures: &[], acceleration_structures: &[], @@ -683,10 +681,12 @@ fn create_buffer_and_bind_group( resource_index: 0, count: 1, }], - buffers: &[unsafe { - // SAFETY: We just created the buffer with this size. - hal::BufferBinding::new_unchecked(buffer.as_ref(), 0, BUFFER_SIZE) - }], + // SAFETY: We just created the buffer with this size. + buffers: &[hal::BufferBinding::new_unchecked( + buffer.as_ref(), + 0, + BUFFER_SIZE, + )], samplers: &[], textures: &[], acceleration_structures: &[], diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index eaf3a377802..d8e80702f0d 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -562,14 +562,12 @@ impl Buffer { ) -> Result<(hal::BufferBinding<'a, dyn hal::DynBuffer>, u64), BindingError> { let buf_raw = self.try_raw(snatch_guard)?; let resolved_size = self.resolve_binding_size(offset, binding_size)?; - unsafe { - // SAFETY: The offset and size passed to hal::BufferBinding::new_unchecked must - // define a binding contained within the buffer. - Ok(( - hal::BufferBinding::new_unchecked(buf_raw, offset, binding_size), - resolved_size, - )) - } + // SAFETY: The offset and size passed to hal::BufferBinding::new_unchecked must + // define a binding contained within the buffer. + Ok(( + hal::BufferBinding::new_unchecked(buf_raw, offset, binding_size), + resolved_size, + )) } /// Returns the mapping callback in case of error so that the callback can be fired outside diff --git a/wgpu-hal/examples/halmark/main.rs b/wgpu-hal/examples/halmark/main.rs index 0b1c3c28da6..153bd49adb5 100644 --- a/wgpu-hal/examples/halmark/main.rs +++ b/wgpu-hal/examples/halmark/main.rs @@ -447,14 +447,12 @@ impl Example { let texture_view = unsafe { device.create_texture_view(&texture, &view_desc).unwrap() }; let global_group = { - let global_buffer_binding = unsafe { - // SAFETY: This is the same size that was specified for buffer creation. - hal::BufferBinding::new_unchecked( - &global_buffer, - 0, - NonZeroU64::new(global_buffer_desc.size), - ) - }; + // SAFETY: This is the same size that was specified for buffer creation. + let global_buffer_binding = hal::BufferBinding::new_unchecked( + &global_buffer, + 0, + NonZeroU64::new(global_buffer_desc.size), + ); let texture_binding = hal::TextureBinding { view: &texture_view, usage: wgpu_types::TextureUses::RESOURCE, @@ -488,14 +486,12 @@ impl Example { }; let local_group = { - let local_buffer_binding = unsafe { - // SAFETY: The size must fit within the buffer. - hal::BufferBinding::new_unchecked( - &local_buffer, - 0, - wgpu_types::BufferSize::new(size_of::() as _), - ) - }; + // SAFETY: The size must fit within the buffer. + let local_buffer_binding = hal::BufferBinding::new_unchecked( + &local_buffer, + 0, + wgpu_types::BufferSize::new(size_of::() as _), + ); let local_group_desc = hal::BindGroupDescriptor { label: Some("local"), layout: &local_group_layout, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 83f88690f70..75be3ee734b 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -2098,7 +2098,7 @@ impl<'a, B: DynBuffer + ?Sized> BufferBinding<'a, B> { /// pass a zero size. When the zero-size binding issue is resolved, the /// argument should just match the type of the member. /// TODO(): remove the parameter - pub unsafe fn new_unchecked>>( + pub fn new_unchecked>>( buffer: &'a B, offset: wgt::BufferAddress, size: S, From da6ccd551659632e5241d725e1e8d1900deef799 Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Thu, 10 Jul 2025 09:39:06 -0700 Subject: [PATCH 007/303] Fix undeclared `base` in profiling scopes. This would cause compilation to fail if profiling was enabled. --- CHANGELOG.md | 4 ++++ wgpu-core/src/command/compute.rs | 2 +- wgpu-core/src/command/render.rs | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82d6698c010..082dba39de8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,10 @@ Bottom level categories: ## Unreleased +### Bug Fixes + +- Fixed build error occurring when the `profiling` dependency is configured to have profiling active. By @kpreid in [#7916](https://github.com/gfx-rs/wgpu/pull/7916). + ## v26.0.0 (2025-07-09) ### Major Features diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index 361a5990f81..e6793a32d7b 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -492,7 +492,7 @@ impl Global { let pass_scope = PassErrorScope::Pass; profiling::scope!( "CommandEncoder::run_compute_pass {}", - base.label.as_deref().unwrap_or("") + pass.base.label.as_deref().unwrap_or("") ); let cmd_buf = pass.parent.take().ok_or(EncoderStateError::Ended)?; diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 96c09c3c1a2..06bba2c8f66 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1804,7 +1804,7 @@ impl Global { let pass_scope = PassErrorScope::Pass; profiling::scope!( "CommandEncoder::run_render_pass {}", - base.label.as_deref().unwrap_or("") + pass.base.label.as_deref().unwrap_or("") ); let cmd_buf = pass.parent.take().ok_or(EncoderStateError::Ended)?; From c0a8ba69b001488339d632f0d38f5774f7871d98 Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Thu, 10 Jul 2025 09:46:37 -0700 Subject: [PATCH 008/303] [ci] Check with profiling enabled. Minimum version of `profiling` increases from ^1.0.0 to ^1.0.1 because the `type-check` feature was added in 1.0.1. --- .github/workflows/ci.yml | 4 ++++ Cargo.toml | 2 +- tests/Cargo.toml | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eaea55ec01e..1dea4069e47 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -313,6 +313,10 @@ jobs: # Check with all features. cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} --tests --benches --all-features + # Check with all features and profiling macro code. + # If we don't check this then errors inside `profiling::scope!()` will not be caught. + cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} --tests --benches --all-features --features test-build-with-profiling + # build docs cargo doc --target ${{ matrix.target }} ${{ matrix.extra-flags }} --all-features --no-deps diff --git a/Cargo.toml b/Cargo.toml index bab8e735098..7083e33a12c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -162,7 +162,7 @@ pollster = "0.4" portable-atomic = "1.8" portable-atomic-util = "0.2.4" pp-rs = "0.2.1" -profiling = { version = "1", default-features = false } +profiling = { version = "1.0.1", default-features = false } quote = "1.0.38" raw-window-handle = { version = "0.6.2", default-features = false } rwh_05 = { version = "0.5.2", package = "raw-window-handle" } # temporary compatibility for glutin-winit diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 17c131a026c..d93f7338939 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -29,6 +29,9 @@ harness = true [features] webgl = ["wgpu/webgl"] +# This feature is not actually used by this package, but it being present somewhere in the workspace +# allows us to force the build to have profiling code enabled so we can test that configuration. +test-build-with-profiling = ["profiling/type-check"] [dependencies] wgpu = { workspace = true, features = ["noop"] } From b83c9cfd578837a6163d980130249c245a9c5f8a Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Thu, 10 Jul 2025 10:06:36 -0700 Subject: [PATCH 009/303] Fix `initialize_adapter_from_env` under no_std. Without this change, `desired_adapter_name` is an undeclared variable. --- wgpu/src/util/init.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/wgpu/src/util/init.rs b/wgpu/src/util/init.rs index 5e775e5aa6a..527274ebe84 100644 --- a/wgpu/src/util/init.rs +++ b/wgpu/src/util/init.rs @@ -5,20 +5,23 @@ use crate::Backends; /// Initialize the adapter obeying the `WGPU_ADAPTER_NAME` environment variable. #[cfg(wgpu_core)] +#[cfg_attr(not(std), expect(unused_variables, unreachable_code))] pub fn initialize_adapter_from_env( instance: &Instance, compatible_surface: Option<&Surface<'_>>, ) -> Result { - cfg_if::cfg_if! { - if #[cfg(std)] { - let desired_adapter_name = std::env::var("WGPU_ADAPTER_NAME") - .as_deref() - .map(str::to_lowercase) - .map_err(|_| wgt::RequestAdapterError::EnvNotSet)?; - } else { - return Err(wgt::RequestAdapterError::EnvNotSet); + let desired_adapter_name: alloc::string::String = { + cfg_if::cfg_if! { + if #[cfg(std)] { + std::env::var("WGPU_ADAPTER_NAME") + .as_deref() + .map(str::to_lowercase) + .map_err(|_| wgt::RequestAdapterError::EnvNotSet)? + } else { + return Err(wgt::RequestAdapterError::EnvNotSet) + } } - } + }; let adapters = instance.enumerate_adapters(crate::Backends::all()); From 166c2ea2aa86d26a40857b2388f5d8a47c03b4c6 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Thu, 10 Jul 2025 15:04:37 -0400 Subject: [PATCH 010/303] fix(core): check query set index before other validation (#7908) --- CHANGELOG.md | 3 +++ cts_runner/test.lst | 1 + wgpu-core/src/command/query.rs | 15 ++++++++------- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 082dba39de8..b534e3687ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,7 +42,10 @@ Bottom level categories: ### Bug Fixes +#### General + - Fixed build error occurring when the `profiling` dependency is configured to have profiling active. By @kpreid in [#7916](https://github.com/gfx-rs/wgpu/pull/7916). +- Emit a validation error instead of panicking when a query set index is OOB. By @ErichDonGubler in [#7908](https://github.com/gfx-rs/wgpu/pull/7908). ## v26.0.0 (2025-07-09) diff --git a/cts_runner/test.lst b/cts_runner/test.lst index c509d87bbee..5b1f604cd78 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -47,6 +47,7 @@ webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bind_grou webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bind_groups_and_pipeline_layout_mismatch:encoderType="render%20pass";* webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:buffer_binding,render_pipeline:* webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:sampler_binding,render_pipeline:* +webgpu:api,validation,encoding,queries,general:occlusion_query,query_index:* webgpu:api,validation,image_copy,layout_related:copy_end_overflows_u64:* webgpu:api,validation,image_copy,texture_related:format:dimension="1d";* webgpu:api,validation,queue,submit:command_buffer,device_mismatch:* diff --git a/wgpu-core/src/command/query.rs b/wgpu-core/src/command/query.rs index cd487e0dbff..fb59c8dd4dc 100644 --- a/wgpu-core/src/command/query.rs +++ b/wgpu-core/src/command/query.rs @@ -210,6 +210,14 @@ impl QuerySet { query_index: u32, reset_state: Option<&mut QueryResetMap>, ) -> Result<(), QueryUseError> { + // NOTE: Further code assumes the index is good, so do this first. + if query_index >= self.desc.count { + return Err(QueryUseError::OutOfBounds { + query_index, + query_set_size: self.desc.count, + }); + } + // We need to defer our resets because we are in a renderpass, // add the usage to the reset map. if let Some(reset) = reset_state { @@ -227,13 +235,6 @@ impl QuerySet { }); } - if query_index >= self.desc.count { - return Err(QueryUseError::OutOfBounds { - query_index, - query_set_size: self.desc.count, - }); - } - Ok(()) } From 4844fa6b5e12cda6b588c333be0f93e1752524d3 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Fri, 11 Jul 2025 07:53:32 +1200 Subject: [PATCH 011/303] Merge acceleration structure feature and ray query feature. (#7913) Co-authored-by: Connor Fitzgerald --- CHANGELOG.md | 13 ++++ docs/api-specs/ray_tracing.md | 5 +- examples/features/src/ray_cube_compute/mod.rs | 1 - .../features/src/ray_cube_fragment/mod.rs | 1 - examples/features/src/ray_cube_normals/mod.rs | 4 +- examples/features/src/ray_scene/mod.rs | 1 - examples/features/src/ray_shadows/mod.rs | 4 +- .../features/src/ray_traced_triangle/mod.rs | 3 +- tests/tests/wgpu-gpu/oom.rs | 8 +-- tests/tests/wgpu-gpu/ray_tracing/as_build.rs | 69 +++++-------------- tests/tests/wgpu-gpu/ray_tracing/as_create.rs | 4 +- .../wgpu-gpu/ray_tracing/as_use_after_free.rs | 7 +- tests/tests/wgpu-gpu/ray_tracing/limits.rs | 6 +- tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs | 10 +-- tests/tests/wgpu-gpu/ray_tracing/shader.rs | 5 +- wgpu-core/src/command/ray_tracing.rs | 5 +- wgpu-core/src/device/queue.rs | 4 +- wgpu-core/src/device/ray_tracing.rs | 4 +- wgpu-core/src/device/resource.rs | 2 +- wgpu-hal/src/dx12/adapter.rs | 39 ++++------- wgpu-hal/src/vulkan/adapter.rs | 34 ++++----- wgpu-types/src/features.rs | 58 +++++++--------- wgpu-types/src/lib.rs | 12 ++-- wgpu/src/api/command_encoder.rs | 6 +- wgpu/src/api/device.rs | 10 +-- 25 files changed, 121 insertions(+), 194 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b534e3687ea..183b75f1a9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,19 @@ Bottom level categories: ## Unreleased +### Major Changes + +#### `EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE` has been merged into `EXPERIMENTAL_RAY_QUERY` + +We have merged the acceleration structure feature into the `RayQuery` feature. This is to help work around an AMD driver bug and reduce the feature complexity of ray tracing. In the future when ray tracing pipelines are implemented, if either feature is enabled, acceleration structures will be available. + +```diff +- Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE ++ Features::EXPERIMENTAL_RAY_QUERY +``` + +By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). + ### Bug Fixes #### General diff --git a/docs/api-specs/ray_tracing.md b/docs/api-specs/ray_tracing.md index afb447b9eec..a4038547d46 100644 --- a/docs/api-specs/ray_tracing.md +++ b/docs/api-specs/ray_tracing.md @@ -3,7 +3,7 @@ 🧪Experimental🧪 `wgpu` supports an experimental version of ray tracing which is subject to change. The extensions allow for acceleration structures to be created and built (with -`Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE` enabled) and interacted with in shaders. Currently `naga` only supports ray queries +`Features::EXPERIMENTAL_RAY_QUERY` enabled) and interacted with in shaders. Currently `naga` only supports ray queries (accessible with `Features::EXPERIMENTAL_RAY_QUERY` enabled in wgpu). **Note**: The features documented here may have major bugs in them and are expected to be subject @@ -18,6 +18,9 @@ an [introduction](https://developer.nvidia.com/blog/introduction-nvidia-rtx-dire The documentation and specific details of the functions and structures provided can be found with their definitions. +Acceleration structures do not have a separate feature, instead they are enabled by `Features::EXPERIMENTAL_RAY_QUERY`, unlike vulkan. +When ray tracing pipelines are added, that feature will also enable acceleration structures. + A [`Blas`] can be created with [`Device::create_blas`]. A [`Tlas`] can be created with [`Device::create_tlas`]. diff --git a/examples/features/src/ray_cube_compute/mod.rs b/examples/features/src/ray_cube_compute/mod.rs index 1f049a34b9f..522a6e75c14 100644 --- a/examples/features/src/ray_cube_compute/mod.rs +++ b/examples/features/src/ray_cube_compute/mod.rs @@ -145,7 +145,6 @@ impl crate::framework::Example for Example { wgpu::Features::TEXTURE_BINDING_ARRAY | wgpu::Features::VERTEX_WRITABLE_STORAGE | wgpu::Features::EXPERIMENTAL_RAY_QUERY - | wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE } fn required_downlevel_capabilities() -> wgpu::DownlevelCapabilities { diff --git a/examples/features/src/ray_cube_fragment/mod.rs b/examples/features/src/ray_cube_fragment/mod.rs index 5c6b2d79e8e..1dd1ae90da8 100644 --- a/examples/features/src/ray_cube_fragment/mod.rs +++ b/examples/features/src/ray_cube_fragment/mod.rs @@ -108,7 +108,6 @@ struct Example { impl crate::framework::Example for Example { fn required_features() -> wgpu::Features { wgpu::Features::EXPERIMENTAL_RAY_QUERY - | wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE } fn required_downlevel_capabilities() -> wgpu::DownlevelCapabilities { diff --git a/examples/features/src/ray_cube_normals/mod.rs b/examples/features/src/ray_cube_normals/mod.rs index 72985c3b8b4..66a56d75bb2 100644 --- a/examples/features/src/ray_cube_normals/mod.rs +++ b/examples/features/src/ray_cube_normals/mod.rs @@ -133,9 +133,7 @@ impl crate::framework::Example for Example { // Don't want srgb, so normals show up better. const SRGB: bool = false; fn required_features() -> wgpu::Features { - wgpu::Features::EXPERIMENTAL_RAY_QUERY - | wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE - | wgpu::Features::EXPERIMENTAL_RAY_HIT_VERTEX_RETURN + wgpu::Features::EXPERIMENTAL_RAY_QUERY | wgpu::Features::EXPERIMENTAL_RAY_HIT_VERTEX_RETURN } fn required_downlevel_capabilities() -> wgpu::DownlevelCapabilities { diff --git a/examples/features/src/ray_scene/mod.rs b/examples/features/src/ray_scene/mod.rs index 6db996e129a..765705cb853 100644 --- a/examples/features/src/ray_scene/mod.rs +++ b/examples/features/src/ray_scene/mod.rs @@ -318,7 +318,6 @@ struct Example { impl crate::framework::Example for Example { fn required_features() -> wgpu::Features { wgpu::Features::EXPERIMENTAL_RAY_QUERY - | wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE } fn required_downlevel_capabilities() -> wgpu::DownlevelCapabilities { diff --git a/examples/features/src/ray_shadows/mod.rs b/examples/features/src/ray_shadows/mod.rs index 271db01f966..8ba14c399ce 100644 --- a/examples/features/src/ray_shadows/mod.rs +++ b/examples/features/src/ray_shadows/mod.rs @@ -104,9 +104,7 @@ fn create_matrix(config: &wgpu::SurfaceConfiguration) -> Uniforms { impl crate::framework::Example for Example { fn required_features() -> wgpu::Features { - wgpu::Features::EXPERIMENTAL_RAY_QUERY - | wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE - | wgpu::Features::PUSH_CONSTANTS + wgpu::Features::EXPERIMENTAL_RAY_QUERY | wgpu::Features::PUSH_CONSTANTS } fn required_downlevel_capabilities() -> wgpu::DownlevelCapabilities { diff --git a/examples/features/src/ray_traced_triangle/mod.rs b/examples/features/src/ray_traced_triangle/mod.rs index cd0df2c8e5c..9d3d0cb3794 100644 --- a/examples/features/src/ray_traced_triangle/mod.rs +++ b/examples/features/src/ray_traced_triangle/mod.rs @@ -29,8 +29,7 @@ struct Uniforms { impl crate::framework::Example for Example { fn required_features() -> wgpu::Features { - wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE - | wgpu::Features::EXPERIMENTAL_RAY_QUERY + wgpu::Features::EXPERIMENTAL_RAY_QUERY } fn required_limits() -> wgpu::Limits { diff --git a/tests/tests/wgpu-gpu/oom.rs b/tests/tests/wgpu-gpu/oom.rs index f2378b22599..d1889f71a60 100644 --- a/tests/tests/wgpu-gpu/oom.rs +++ b/tests/tests/wgpu-gpu/oom.rs @@ -159,10 +159,8 @@ static QUERY_SET_OOM_TEST: GpuTestConfiguration = GpuTestConfiguration::new() static BLAS_OOM_TEST: GpuTestConfiguration = GpuTestConfiguration::new() .parameters( TestParameters::default() - .features(Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) + .features(Features::EXPERIMENTAL_RAY_QUERY) .skip(FailureCase::backend(!OOM_DETECTION_IMPL)) - // https://github.com/gfx-rs/wgpu/issues/6727 - .skip(FailureCase::backend_adapter(Backends::VULKAN, "AMD")) // see comment at the top of the file .skip(FailureCase::backend_adapter(Backends::VULKAN, "llvmpipe")), ) @@ -203,10 +201,8 @@ static BLAS_OOM_TEST: GpuTestConfiguration = GpuTestConfiguration::new() static TLAS_OOM_TEST: GpuTestConfiguration = GpuTestConfiguration::new() .parameters( TestParameters::default() - .features(Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) + .features(Features::EXPERIMENTAL_RAY_QUERY) .skip(FailureCase::backend(!OOM_DETECTION_IMPL)) - // https://github.com/gfx-rs/wgpu/issues/6727 - .skip(FailureCase::backend_adapter(Backends::VULKAN, "AMD")) // see comment at the top of the file .skip(FailureCase::backend_adapter(Backends::VULKAN, "llvmpipe")), ) diff --git a/tests/tests/wgpu-gpu/ray_tracing/as_build.rs b/tests/tests/wgpu-gpu/ray_tracing/as_build.rs index 3ef6e7be28a..2ba80294c92 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/as_build.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/as_build.rs @@ -3,9 +3,7 @@ use std::iter; use crate::ray_tracing::{acceleration_structure_limits, AsBuildContext}; use wgpu::util::{BufferInitDescriptor, DeviceExt}; use wgpu::*; -use wgpu_test::{ - fail, fail_if, gpu_test, FailureCase, GpuTestConfiguration, TestParameters, TestingContext, -}; +use wgpu_test::{fail, fail_if, gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; #[gpu_test] static UNBUILT_BLAS: GpuTestConfiguration = GpuTestConfiguration::new() @@ -13,9 +11,7 @@ static UNBUILT_BLAS: GpuTestConfiguration = GpuTestConfiguration::new() TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) - // https://github.com/gfx-rs/wgpu/issues/6727 - .skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), ) .run_sync(unbuilt_blas); @@ -48,9 +44,7 @@ static UNBUILT_BLAS_COMPACTION: GpuTestConfiguration = GpuTestConfiguration::new TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) - // https://github.com/gfx-rs/wgpu/issues/6727 - .skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), ) .run_sync(unbuilt_blas_compaction); @@ -77,9 +71,7 @@ static BLAS_COMPACTION_WITHOUT_FLAGS: GpuTestConfiguration = GpuTestConfiguratio TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) - // https://github.com/gfx-rs/wgpu/issues/6727 - .skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), ) .run_sync(blas_compaction_without_flags); @@ -114,9 +106,7 @@ static UNPREPARED_BLAS_COMPACTION: GpuTestConfiguration = GpuTestConfiguration:: TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) - // https://github.com/gfx-rs/wgpu/issues/6727 - .skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), ) .run_sync(unprepared_blas_compaction); @@ -144,9 +134,7 @@ static BLAS_COMPACTION: GpuTestConfiguration = GpuTestConfiguration::new() TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) - // https://github.com/gfx-rs/wgpu/issues/6727 - .skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), ) .run_sync(blas_compaction); @@ -203,9 +191,7 @@ static OUT_OF_ORDER_AS_BUILD: GpuTestConfiguration = GpuTestConfiguration::new() TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) - // https://github.com/gfx-rs/wgpu/issues/6727 - .skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), ) .run_sync(out_of_order_as_build); @@ -287,12 +273,7 @@ static OUT_OF_ORDER_AS_BUILD_USE: GpuTestConfiguration = GpuTestConfiguration::n TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features( - wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE - | wgpu::Features::EXPERIMENTAL_RAY_QUERY, - ) - // https://github.com/gfx-rs/wgpu/issues/6727 - .skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), ) .run_sync(out_of_order_as_build_use); @@ -474,7 +455,7 @@ static EMPTY_BUILD: GpuTestConfiguration = GpuTestConfiguration::new() TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), ) .run_sync(empty_build); fn empty_build(ctx: TestingContext) { @@ -495,9 +476,7 @@ static BUILD_WITH_TRANSFORM: GpuTestConfiguration = GpuTestConfiguration::new() TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) - // https://github.com/gfx-rs/wgpu/issues/6727 - .skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), ) .run_sync(build_with_transform); @@ -583,12 +562,9 @@ static ONLY_BLAS_VERTEX_RETURN: GpuTestConfiguration = GpuTestConfiguration::new .test_features_limits() .limits(acceleration_structure_limits()) .features( - wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE - | wgpu::Features::EXPERIMENTAL_RAY_QUERY + wgpu::Features::EXPERIMENTAL_RAY_QUERY | wgpu::Features::EXPERIMENTAL_RAY_HIT_VERTEX_RETURN, - ) - // https://github.com/gfx-rs/wgpu/issues/6727 - .skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")), + ), ) .run_sync(only_blas_vertex_return); @@ -710,12 +686,9 @@ static ONLY_TLAS_VERTEX_RETURN: GpuTestConfiguration = GpuTestConfiguration::new .test_features_limits() .limits(acceleration_structure_limits()) .features( - wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE - | wgpu::Features::EXPERIMENTAL_RAY_QUERY + wgpu::Features::EXPERIMENTAL_RAY_QUERY | wgpu::Features::EXPERIMENTAL_RAY_HIT_VERTEX_RETURN, - ) - // https://github.com/gfx-rs/wgpu/issues/6727 - .skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")), + ), ) .run_sync(only_tlas_vertex_return); @@ -752,11 +725,9 @@ static EXTRA_FORMAT_BUILD: GpuTestConfiguration = GpuTestConfiguration::new() .test_features_limits() .limits(acceleration_structure_limits()) .features( - wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE + wgpu::Features::EXPERIMENTAL_RAY_QUERY | wgpu::Features::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS, - ) - // https://github.com/gfx-rs/wgpu/issues/6727 - .skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")), + ), ) .run_sync(|ctx| test_as_build_format_stride(ctx, VertexFormat::Snorm16x4, 6, false)); @@ -766,9 +737,7 @@ static MISALIGNED_BUILD: GpuTestConfiguration = GpuTestConfiguration::new() TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) - // https://github.com/gfx-rs/wgpu/issues/6727 - .skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), ) // Larger than the minimum size, but not aligned as required .run_sync(|ctx| test_as_build_format_stride(ctx, VertexFormat::Float32x3, 13, true)); @@ -779,9 +748,7 @@ static TOO_SMALL_STRIDE_BUILD: GpuTestConfiguration = GpuTestConfiguration::new( TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) - // https://github.com/gfx-rs/wgpu/issues/6727 - .skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), ) // Aligned as required, but smaller than minimum size .run_sync(|ctx| test_as_build_format_stride(ctx, VertexFormat::Float32x3, 8, true)); diff --git a/tests/tests/wgpu-gpu/ray_tracing/as_create.rs b/tests/tests/wgpu-gpu/ray_tracing/as_create.rs index f6f2e57c352..703e6e5f689 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/as_create.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/as_create.rs @@ -14,7 +14,7 @@ static BLAS_INVALID_VERTEX_FORMAT: GpuTestConfiguration = GpuTestConfiguration:: TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), ) .run_sync(invalid_vertex_format_blas_create); @@ -55,7 +55,7 @@ static BLAS_MISMATCHED_INDEX: GpuTestConfiguration = GpuTestConfiguration::new() TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), ) .run_sync(mismatched_index_blas_create); diff --git a/tests/tests/wgpu-gpu/ray_tracing/as_use_after_free.rs b/tests/tests/wgpu-gpu/ray_tracing/as_use_after_free.rs index 3e9c5a45e23..8a090b47063 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/as_use_after_free.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/as_use_after_free.rs @@ -11,11 +11,10 @@ use wgpu::{ PollType, TlasInstance, VertexFormat, }; use wgpu_macros::gpu_test; -use wgpu_test::{FailureCase, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{GpuTestConfiguration, TestParameters, TestingContext}; fn required_features() -> wgpu::Features { wgpu::Features::EXPERIMENTAL_RAY_QUERY - | wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE } /// This test creates a blas, puts a reference to it in a tlas instance inside a tlas package, @@ -147,8 +146,6 @@ static ACCELERATION_STRUCTURE_USE_AFTER_FREE: GpuTestConfiguration = GpuTestConf TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(required_features()) - // https://github.com/gfx-rs/wgpu/issues/6727 - .skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")), + .features(required_features()), ) .run_sync(acceleration_structure_use_after_free); diff --git a/tests/tests/wgpu-gpu/ray_tracing/limits.rs b/tests/tests/wgpu-gpu/ray_tracing/limits.rs index a31f5d050f5..172c5818af1 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/limits.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/limits.rs @@ -8,7 +8,7 @@ use wgpu::{ ShaderStages, VertexFormat, }; use wgpu_macros::gpu_test; -use wgpu_test::{fail, FailureCase, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{fail, GpuTestConfiguration, TestParameters, TestingContext}; #[gpu_test] static LIMITS_HIT: GpuTestConfiguration = GpuTestConfiguration::new() @@ -22,9 +22,7 @@ static LIMITS_HIT: GpuTestConfiguration = GpuTestConfiguration::new() max_acceleration_structures_per_shader_stage: 1, ..Limits::default() }) - .features(wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) - // https://github.com/gfx-rs/wgpu/issues/6727 - .skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), ) .run_sync(hit_limits); diff --git a/tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs b/tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs index 11be74bdf45..e258a828103 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs @@ -1,6 +1,6 @@ use std::{iter, mem}; -use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; use wgpu::util::DeviceExt; @@ -103,9 +103,7 @@ static ACCELERATION_STRUCTURE_BUILD_NO_INDEX: GpuTestConfiguration = GpuTestConf TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) - // https://github.com/gfx-rs/wgpu/issues/6727 - .skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), ) .run_sync(|ctx| { acceleration_structure_build(&ctx, false); @@ -117,9 +115,7 @@ static ACCELERATION_STRUCTURE_BUILD_WITH_INDEX: GpuTestConfiguration = GpuTestCo TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) - // https://github.com/gfx-rs/wgpu/issues/6727 - .skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), ) .run_sync(|ctx| { acceleration_structure_build(&ctx, true); diff --git a/tests/tests/wgpu-gpu/ray_tracing/shader.rs b/tests/tests/wgpu-gpu/ray_tracing/shader.rs index 1ed167e4f15..d7fb7b0158a 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/shader.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/shader.rs @@ -15,10 +15,7 @@ static ACCESS_ALL_STRUCT_MEMBERS: GpuTestConfiguration = GpuTestConfiguration::n TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features( - wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE - | wgpu::Features::EXPERIMENTAL_RAY_QUERY, - ), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), ) .run_sync(access_all_struct_members); diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 5f5557ee051..6ae01d57204 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -76,8 +76,7 @@ impl Global { |cmd_buf_data| -> Result<(), BuildAccelerationStructureError> { let device = &cmd_buf.device; device.check_is_valid()?; - device - .require_features(Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE)?; + device.require_features(Features::EXPERIMENTAL_RAY_QUERY)?; let mut build_command = AsBuild::default(); @@ -214,7 +213,7 @@ impl Global { let device = &cmd_buf.device; device.check_is_valid()?; - device.require_features(Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE)?; + device.require_features(Features::EXPERIMENTAL_RAY_QUERY)?; let mut buf_storage = Vec::new(); iter_blas( diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index f6d57924ade..10df7aaf1a9 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -1691,9 +1691,7 @@ impl Global { // TODO: Tracing let error = 'error: { - match device.require_features( - wgpu_types::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE, - ) { + match device.require_features(wgpu_types::Features::EXPERIMENTAL_RAY_QUERY) { Ok(_) => {} Err(err) => break 'error err.into(), } diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index 09f6867da50..1daecf61907 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -30,7 +30,7 @@ impl Device { sizes: wgt::BlasGeometrySizeDescriptors, ) -> Result, CreateBlasError> { self.check_is_valid()?; - self.require_features(Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE)?; + self.require_features(Features::EXPERIMENTAL_RAY_QUERY)?; if blas_desc .flags @@ -176,7 +176,7 @@ impl Device { desc: &resource::TlasDescriptor, ) -> Result, CreateTlasError> { self.check_is_valid()?; - self.require_features(Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE)?; + self.require_features(Features::EXPERIMENTAL_RAY_QUERY)?; if desc.max_instances > self.limits.max_tlas_instance_count { return Err(CreateTlasError::TooManyInstances( diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 302a74e341e..7af8faac82a 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -237,7 +237,7 @@ impl Device { let rt_uses = if desc .required_features - .contains(wgt::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) + .intersects(wgt::Features::EXPERIMENTAL_RAY_QUERY) { wgt::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT } else { diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index ae3478b0949..42a8e671103 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -468,17 +468,15 @@ impl super::Adapter { } .is_ok(); - // Since all features for raytracing pipeline (geometry index) and ray queries both come - // from here, there is no point in adding an extra call here given that there will be no - // feature using EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE if all these are not met. // Once ray tracing pipelines are supported they also will go here + let supports_ray_tracing = features5.RaytracingTier + == Direct3D12::D3D12_RAYTRACING_TIER_1_1 + && shader_model >= naga::back::hlsl::ShaderModel::V6_5 + && has_features5; features.set( wgt::Features::EXPERIMENTAL_RAY_QUERY - | wgt::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE | wgt::Features::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS, - features5.RaytracingTier == Direct3D12::D3D12_RAYTRACING_TIER_1_1 - && shader_model >= naga::back::hlsl::ShaderModel::V6_5 - && has_features5, + supports_ray_tracing, ); let atomic_int64_on_typed_resource_supported = { @@ -519,12 +517,11 @@ impl super::Adapter { // If we also support acceleration structures these are shared so we must halve it. // It's unlikely that this affects anything because most devices that support ray tracing // probably have a higher binding tier than one. - let max_sampled_textures_per_shader_stage = - if !features.contains(wgt::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) { - max_srv_count - } else { - max_srv_count / 2 - }; + let max_sampled_textures_per_shader_stage = if !supports_ray_tracing { + max_srv_count + } else { + max_srv_count / 2 + }; Some(crate::ExposedAdapter { adapter: super::Adapter { @@ -616,30 +613,22 @@ impl super::Adapter { // store buffer sizes using 32 bit ints (a situation we have already encountered with vulkan). max_buffer_size: i32::MAX as u64, max_non_sampler_bindings: 1_000_000, - max_blas_primitive_count: if features - .contains(wgt::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) - { + max_blas_primitive_count: if supports_ray_tracing { 1 << 29 // 2^29 } else { 0 }, - max_blas_geometry_count: if features - .contains(wgt::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) - { + max_blas_geometry_count: if supports_ray_tracing { 1 << 24 // 2^24 } else { 0 }, - max_tlas_instance_count: if features - .contains(wgt::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) - { + max_tlas_instance_count: if supports_ray_tracing { 1 << 24 // 2^24 } else { 0 }, - max_acceleration_structures_per_shader_stage: if features - .contains(wgt::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) - { + max_acceleration_structures_per_shader_stage: if supports_ray_tracing { max_srv_count / 2 } else { 0 diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index b429f2314dc..67428309541 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -75,17 +75,17 @@ pub struct PhysicalDeviceFeatures { /// Features provided by `VK_KHR_buffer_device_address`, promoted to Vulkan 1.2. /// /// We only use this feature for - /// [`Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE`], which requires + /// [`Features::EXPERIMENTAL_RAY_QUERY`], which requires /// `VK_KHR_acceleration_structure`, which depends on /// `VK_KHR_buffer_device_address`, so [`Instance::expose_adapter`] only /// bothers to check if `VK_KHR_acceleration_structure` is available, /// leaving this `None`. /// /// However, we do populate this when creating a device if - /// [`Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE`] is requested. + /// [`Features::EXPERIMENTAL_RAY_QUERY`] is requested. /// /// [`Instance::expose_adapter`]: super::Instance::expose_adapter - /// [`Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE`]: wgt::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE + /// [`Features::EXPERIMENTAL_RAY_QUERY`]: wgt::Features::EXPERIMENTAL_RAY_QUERY buffer_device_address: Option>, /// Features provided by `VK_KHR_ray_query`, @@ -799,17 +799,17 @@ impl PhysicalDeviceFeatures { features.set(F::DEPTH32FLOAT_STENCIL8, texture_d32_s8); - features.set( - F::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE - | F::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS, - caps.supports_extension(khr::deferred_host_operations::NAME) - && caps.supports_extension(khr::acceleration_structure::NAME) - && caps.supports_extension(khr::buffer_device_address::NAME), - ); + let supports_acceleration_structures = caps + .supports_extension(khr::deferred_host_operations::NAME) + && caps.supports_extension(khr::acceleration_structure::NAME) + && caps.supports_extension(khr::buffer_device_address::NAME); features.set( - F::EXPERIMENTAL_RAY_QUERY, - caps.supports_extension(khr::ray_query::NAME), + F::EXPERIMENTAL_RAY_QUERY + // Although this doesn't really require ray queries, it does not make sense to be enabled if acceleration structures + // aren't enabled. + | F::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS, + supports_acceleration_structures && caps.supports_extension(khr::ray_query::NAME), ); let rg11b10ufloat_renderable = supports_format( @@ -1098,17 +1098,11 @@ impl PhysicalDeviceProperties { extensions.push(khr::draw_indirect_count::NAME); } - // Require `VK_KHR_deferred_host_operations`, `VK_KHR_acceleration_structure` and `VK_KHR_buffer_device_address` if the feature `RAY_TRACING` was requested - if requested_features - .contains(wgt::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) - { + // Require `VK_KHR_deferred_host_operations`, `VK_KHR_acceleration_structure` `VK_KHR_buffer_device_address` (for acceleration structures) and`VK_KHR_ray_query` if `EXPERIMENTAL_RAY_QUERY` was requested + if requested_features.contains(wgt::Features::EXPERIMENTAL_RAY_QUERY) { extensions.push(khr::deferred_host_operations::NAME); extensions.push(khr::acceleration_structure::NAME); extensions.push(khr::buffer_device_address::NAME); - } - - // Require `VK_KHR_ray_query` if the associated feature was requested - if requested_features.contains(wgt::Features::EXPERIMENTAL_RAY_QUERY) { extensions.push(khr::ray_query::NAME); } diff --git a/wgpu-types/src/features.rs b/wgpu-types/src/features.rs index e01885fc412..53c2037c56d 100644 --- a/wgpu-types/src/features.rs +++ b/wgpu-types/src/features.rs @@ -984,18 +984,6 @@ bitflags_array! { /// /// [`TextureFormat::NV12`]: super::TextureFormat::NV12 const TEXTURE_FORMAT_NV12 = 1 << 29; - /// ***THIS IS EXPERIMENTAL:*** Features enabled by this may have - /// major bugs in them and are expected to be subject to breaking changes, suggestions - /// for the API exposed by this should be posted on [the ray-tracing issue](https://github.com/gfx-rs/wgpu/issues/1040) - /// - /// Allows for the creation of ray-tracing acceleration structures. Currently, - /// ray-tracing acceleration structures are only useful when used with [Features::EXPERIMENTAL_RAY_QUERY] - /// - /// Supported platforms: - /// - Vulkan - /// - /// This is a native-only feature. - const EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE = 1 << 30; /// Allows for the creation and usage of `ExternalTexture`s, and bind /// group layouts containing external texture `BindingType`s. @@ -1010,7 +998,7 @@ bitflags_array! { /// /// Supported platforms: /// - None - const EXTERNAL_TEXTURE = 1 << 31; + const EXTERNAL_TEXTURE = 1 << 30; // Shader: @@ -1024,7 +1012,7 @@ bitflags_array! { /// - Vulkan /// /// This is a native-only feature. - const EXPERIMENTAL_RAY_QUERY = 1 << 32; + const EXPERIMENTAL_RAY_QUERY = 1 << 31; /// Enables 64-bit floating point types in SPIR-V shaders. /// /// Note: even when supported by GPU hardware, 64-bit floating point operations are @@ -1034,14 +1022,14 @@ bitflags_array! { /// - Vulkan /// /// This is a native only feature. - const SHADER_F64 = 1 << 33; + const SHADER_F64 = 1 << 32; /// Allows shaders to use i16. Not currently supported in `naga`, only available through `spirv-passthrough`. /// /// Supported platforms: /// - Vulkan /// /// This is a native only feature. - const SHADER_I16 = 1 << 34; + const SHADER_I16 = 1 << 33; /// Enables `builtin(primitive_index)` in fragment shaders. /// /// Note: enables geometry processing for pipelines using the builtin. @@ -1055,7 +1043,7 @@ bitflags_array! { /// - OpenGL (some) /// /// This is a native only feature. - const SHADER_PRIMITIVE_INDEX = 1 << 35; + const SHADER_PRIMITIVE_INDEX = 1 << 34; /// Allows shaders to use the `early_depth_test` attribute. /// /// The attribute is applied to the fragment shader entry point. It can be used in two @@ -1083,7 +1071,7 @@ bitflags_array! { /// This is a native only feature. /// /// [`EarlyDepthTest`]: https://docs.rs/naga/latest/naga/ir/enum.EarlyDepthTest.html - const SHADER_EARLY_DEPTH_TEST = 1 << 36; + const SHADER_EARLY_DEPTH_TEST = 1 << 35; /// Allows shaders to use i64 and u64. /// /// Supported platforms: @@ -1092,7 +1080,7 @@ bitflags_array! { /// - Metal (with MSL 2.3+) /// /// This is a native only feature. - const SHADER_INT64 = 1 << 37; + const SHADER_INT64 = 1 << 36; /// Allows compute and fragment shaders to use the subgroup operation built-ins /// /// Supported Platforms: @@ -1101,14 +1089,14 @@ bitflags_array! { /// - Metal /// /// This is a native only feature. - const SUBGROUP = 1 << 38; + const SUBGROUP = 1 << 37; /// Allows vertex shaders to use the subgroup operation built-ins /// /// Supported Platforms: /// - Vulkan /// /// This is a native only feature. - const SUBGROUP_VERTEX = 1 << 39; + const SUBGROUP_VERTEX = 1 << 38; /// Allows shaders to use the subgroup barrier /// /// Supported Platforms: @@ -1116,7 +1104,7 @@ bitflags_array! { /// - Metal /// /// This is a native only feature. - const SUBGROUP_BARRIER = 1 << 40; + const SUBGROUP_BARRIER = 1 << 39; /// Allows the use of pipeline cache objects /// /// Supported platforms: @@ -1125,7 +1113,7 @@ bitflags_array! { /// Unimplemented Platforms: /// - DX12 /// - Metal - const PIPELINE_CACHE = 1 << 41; + const PIPELINE_CACHE = 1 << 40; /// Allows shaders to use i64 and u64 atomic min and max. /// /// Supported platforms: @@ -1134,7 +1122,7 @@ bitflags_array! { /// - Metal (with MSL 2.4+) /// /// This is a native only feature. - const SHADER_INT64_ATOMIC_MIN_MAX = 1 << 42; + const SHADER_INT64_ATOMIC_MIN_MAX = 1 << 41; /// Allows shaders to use all i64 and u64 atomic operations. /// /// Supported platforms: @@ -1142,7 +1130,7 @@ bitflags_array! { /// - DX12 (with SM 6.6+) /// /// This is a native only feature. - const SHADER_INT64_ATOMIC_ALL_OPS = 1 << 43; + const SHADER_INT64_ATOMIC_ALL_OPS = 1 << 42; /// Allows using the [VK_GOOGLE_display_timing] Vulkan extension. /// /// This is used for frame pacing to reduce latency, and is generally only available on Android. @@ -1158,7 +1146,7 @@ bitflags_array! { /// /// [VK_GOOGLE_display_timing]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_GOOGLE_display_timing.html /// [`Surface::as_hal()`]: https://docs.rs/wgpu/latest/wgpu/struct.Surface.html#method.as_hal - const VULKAN_GOOGLE_DISPLAY_TIMING = 1 << 44; + const VULKAN_GOOGLE_DISPLAY_TIMING = 1 << 43; /// Allows using the [VK_KHR_external_memory_win32] Vulkan extension. /// @@ -1168,7 +1156,7 @@ bitflags_array! { /// This is a native only feature. /// /// [VK_KHR_external_memory_win32]: https://registry.khronos.org/vulkan/specs/latest/man/html/VK_KHR_external_memory_win32.html - const VULKAN_EXTERNAL_MEMORY_WIN32 = 1 << 45; + const VULKAN_EXTERNAL_MEMORY_WIN32 = 1 << 44; /// Enables R64Uint image atomic min and max. /// @@ -1178,7 +1166,7 @@ bitflags_array! { /// - Metal (with MSL 3.1+) /// /// This is a native only feature. - const TEXTURE_INT64_ATOMIC = 1 << 46; + const TEXTURE_INT64_ATOMIC = 1 << 45; /// Allows uniform buffers to be bound as binding arrays. /// @@ -1195,7 +1183,7 @@ bitflags_array! { /// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s `shaderUniformBufferArrayNonUniformIndexing` feature) /// /// This is a native only feature. - const UNIFORM_BUFFER_BINDING_ARRAYS = 1 << 47; + const UNIFORM_BUFFER_BINDING_ARRAYS = 1 << 46; /// Enables mesh shaders and task shaders in mesh shader pipelines. /// @@ -1207,7 +1195,7 @@ bitflags_array! { /// - Metal /// /// This is a native only feature. - const EXPERIMENTAL_MESH_SHADER = 1 << 48; + const EXPERIMENTAL_MESH_SHADER = 1 << 47; /// ***THIS IS EXPERIMENTAL:*** Features enabled by this may have /// major bugs in them and are expected to be subject to breaking changes, suggestions @@ -1222,7 +1210,7 @@ bitflags_array! { /// This is a native only feature /// /// [`AccelerationStructureFlags::ALLOW_RAY_HIT_VERTEX_RETURN`]: super::AccelerationStructureFlags::ALLOW_RAY_HIT_VERTEX_RETURN - const EXPERIMENTAL_RAY_HIT_VERTEX_RETURN = 1 << 49; + const EXPERIMENTAL_RAY_HIT_VERTEX_RETURN = 1 << 48; /// Enables multiview in mesh shader pipelines /// @@ -1234,7 +1222,7 @@ bitflags_array! { /// - Metal /// /// This is a native only feature. - const EXPERIMENTAL_MESH_SHADER_MULTIVIEW = 1 << 50; + const EXPERIMENTAL_MESH_SHADER_MULTIVIEW = 1 << 49; /// Allows usage of additional vertex formats in [BlasTriangleGeometrySizeDescriptor::vertex_format] /// @@ -1243,7 +1231,7 @@ bitflags_array! { /// - DX12 /// /// [BlasTriangleGeometrySizeDescriptor::vertex_format]: super::BlasTriangleGeometrySizeDescriptor - const EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS = 1 << 51; + const EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS = 1 << 50; /// Enables creating shader modules from DirectX HLSL or DXIL shaders (unsafe) /// @@ -1253,7 +1241,7 @@ bitflags_array! { /// - DX12 /// /// This is a native only feature. - const HLSL_DXIL_SHADER_PASSTHROUGH = 1 << 53; + const HLSL_DXIL_SHADER_PASSTHROUGH = 1 << 51; } /// Features that are not guaranteed to be supported. @@ -1529,7 +1517,7 @@ impl Features { #[must_use] pub fn allowed_vertex_formats_for_blas(&self) -> Vec { let mut formats = Vec::new(); - if self.contains(Self::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) { + if self.intersects(Self::EXPERIMENTAL_RAY_QUERY) { formats.push(VertexFormat::Float32x3); } if self.contains(Self::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS) { diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index ea821512eb5..e3c6c89a6cb 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -608,19 +608,19 @@ pub struct Limits { /// to create many bind groups at the cost of a large up-front allocation at device creation. pub max_non_sampler_bindings: u32, /// The maximum number of primitive (ex: triangles, aabbs) a BLAS is allowed to have. Requesting - /// more than 0 during device creation only makes sense if [`Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE`] + /// more than 0 during device creation only makes sense if [`Features::EXPERIMENTAL_RAY_QUERY`] /// is enabled. pub max_blas_primitive_count: u32, /// The maximum number of geometry descriptors a BLAS is allowed to have. Requesting - /// more than 0 during device creation only makes sense if [`Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE`] + /// more than 0 during device creation only makes sense if [`Features::EXPERIMENTAL_RAY_QUERY`] /// is enabled. pub max_blas_geometry_count: u32, /// The maximum number of instances a TLAS is allowed to have. Requesting more than 0 during - /// device creation only makes sense if [`Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE`] + /// device creation only makes sense if [`Features::EXPERIMENTAL_RAY_QUERY`] /// is enabled. pub max_tlas_instance_count: u32, /// The maximum number of acceleration structures allowed to be used in a shader stage. - /// Requesting more than 0 during device creation only makes sense if [`Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE`] + /// Requesting more than 0 during device creation only makes sense if [`Features::EXPERIMENTAL_RAY_QUERY`] /// is enabled. pub max_acceleration_structures_per_shader_stage: u32, } @@ -895,7 +895,7 @@ impl Limits { } } - /// The minimum guaranteed limits for acceleration structures if you enable [`Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE`] + /// The minimum guaranteed limits for acceleration structures if you enable [`Features::EXPERIMENTAL_RAY_QUERY`] #[must_use] pub const fn using_minimum_supported_acceleration_structure_values(self) -> Self { Self { @@ -7506,7 +7506,7 @@ impl Default for ShaderRuntimeChecks { /// Descriptor for all size defining attributes of a single triangle geometry inside a bottom level acceleration structure. pub struct BlasTriangleGeometrySizeDescriptor { /// Format of a vertex position, must be [`VertexFormat::Float32x3`] - /// with just [`Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE`] + /// with just [`Features::EXPERIMENTAL_RAY_QUERY`] /// but [`Features::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS`] adds more. pub vertex_format: VertexFormat, /// Number of vertices. diff --git a/wgpu/src/api/command_encoder.rs b/wgpu/src/api/command_encoder.rs index 3e6f73195b8..4a5fafb00a1 100644 --- a/wgpu/src/api/command_encoder.rs +++ b/wgpu/src/api/command_encoder.rs @@ -286,7 +286,7 @@ impl CommandEncoder { } } -/// [`Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE`] must be enabled on the device in order to call these functions. +/// [`Features::EXPERIMENTAL_RAY_QUERY`] must be enabled on the device in order to call these functions. impl CommandEncoder { /// Mark acceleration structures as being built. ***Should only*** be used with wgpu-hal /// functions, all wgpu functions already mark acceleration structures as built. @@ -323,7 +323,7 @@ impl CommandEncoder { /// - Each BLAS in each TLAS instance must have been being built in the current call or in a previous call to `build_acceleration_structures` or `build_acceleration_structures_unsafe_tlas` /// - The number of TLAS instances must be less than or equal to the max number of tlas instances when creating (if creating a package with `TlasPackage::new()` this is already satisfied) /// - /// If the device the command encoder is created from does not have [Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE] enabled then a validation error is generated + /// If the device the command encoder is created from does not have [Features::EXPERIMENTAL_RAY_QUERY] enabled then a validation error is generated /// /// A bottom level acceleration structure may be build and used as a reference in a top level acceleration structure in the same invocation of this function. /// @@ -334,7 +334,7 @@ impl CommandEncoder { /// - All the bottom level acceleration structures referenced by the top level acceleration structure are valid and have been built prior, /// or at same time as the containing top level acceleration structure. /// - /// [Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE]: wgt::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE + /// [Features::EXPERIMENTAL_RAY_QUERY]: wgt::Features::EXPERIMENTAL_RAY_QUERY pub fn build_acceleration_structures<'a>( &mut self, blas: impl IntoIterator>, diff --git a/wgpu/src/api/device.rs b/wgpu/src/api/device.rs index 6fe5cd0ea1e..48c719f9a16 100644 --- a/wgpu/src/api/device.rs +++ b/wgpu/src/api/device.rs @@ -555,7 +555,7 @@ impl Device { } } -/// [`Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE`] must be enabled on the device in order to call these functions. +/// [`Features::EXPERIMENTAL_RAY_QUERY`] must be enabled on the device in order to call these functions. impl Device { /// Create a bottom level acceleration structure, used inside a top level acceleration structure for ray tracing. /// - `desc`: The descriptor of the acceleration structure. @@ -564,14 +564,14 @@ impl Device { /// # Validation /// If any of the following is not satisfied a validation error is generated /// - /// The device ***must*** have [`Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE`] enabled. + /// The device ***must*** have [`Features::EXPERIMENTAL_RAY_QUERY`] enabled. /// if `sizes` is [`BlasGeometrySizeDescriptors::Triangles`] then the following must be satisfied /// - For every geometry descriptor (for the purposes this is called `geo_desc`) of `sizes.descriptors` the following must be satisfied: /// - `geo_desc.vertex_format` must be within allowed formats (allowed formats for a given feature set /// may be queried with [`Features::allowed_vertex_formats_for_blas`]). /// - Both or neither of `geo_desc.index_format` and `geo_desc.index_count` must be provided. /// - /// [`Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE`]: wgt::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE + /// [`Features::EXPERIMENTAL_RAY_QUERY`]: wgt::Features::EXPERIMENTAL_RAY_QUERY /// [`Features::allowed_vertex_formats_for_blas`]: wgt::Features::allowed_vertex_formats_for_blas #[must_use] pub fn create_blas( @@ -593,9 +593,9 @@ impl Device { /// # Validation /// If any of the following is not satisfied a validation error is generated /// - /// The device ***must*** have [`Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE`] enabled. + /// The device ***must*** have [`Features::EXPERIMENTAL_RAY_QUERY`] enabled. /// - /// [`Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE`]: wgt::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE + /// [`Features::EXPERIMENTAL_RAY_QUERY`]: wgt::Features::EXPERIMENTAL_RAY_QUERY #[must_use] pub fn create_tlas(&self, desc: &CreateTlasDescriptor<'_>) -> Tlas { let tlas = self.inner.create_tlas(desc); From 085eaa60e8a49017e07ea6f8fe89fb4c45bee264 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 10 Jul 2025 18:42:49 -0400 Subject: [PATCH 012/303] Forward port v26.0.1 changelog (#7921) --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 183b75f1a9a..c27699365fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,10 +53,11 @@ We have merged the acceleration structure feature into the `RayQuery` feature. T By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). -### Bug Fixes +## v26.0.1 (2025-07-10) -#### General +### Bug Fixes +- Fixed build error inside `wgpu::util::initialize_adapter_from_env` when `std` feature is not enabled. By @kpreid in [#7918](https://github.com/gfx-rs/wgpu/pull/7918). - Fixed build error occurring when the `profiling` dependency is configured to have profiling active. By @kpreid in [#7916](https://github.com/gfx-rs/wgpu/pull/7916). - Emit a validation error instead of panicking when a query set index is OOB. By @ErichDonGubler in [#7908](https://github.com/gfx-rs/wgpu/pull/7908). From 5b2c8406bf787f8b8f86ece1f0b0ba67e72874d2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 10 Jul 2025 18:57:33 -0400 Subject: [PATCH 013/303] chore(deps): update cts digest to 18fcd81 (#7923) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- cts_runner/revision.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cts_runner/revision.txt b/cts_runner/revision.txt index 495758ec245..0cf30d50a8a 100644 --- a/cts_runner/revision.txt +++ b/cts_runner/revision.txt @@ -1 +1 @@ -223e1bfb039319ced939020379f7f489640a87cb +18fcd81fcd695192e7ec128125a2bc267a472153 From ae946dbb8cf173eb77fdc0a7e80d42d840afac20 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Fri, 11 Jul 2025 13:20:13 -0700 Subject: [PATCH 014/303] Use backwards-compatible options to `git config` (#7934) --- xtask/src/cts.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/xtask/src/cts.rs b/xtask/src/cts.rs index 8af0953e7bf..9128181d614 100644 --- a/xtask/src/cts.rs +++ b/xtask/src/cts.rs @@ -80,7 +80,7 @@ pub fn run_cts(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { // clones may not have it. Eventually this can be removed. if shell .cmd("git") - .args(["config", "get", "remote.origin.fetch"]) + .args(["config", "--get", "remote.origin.fetch"]) .quiet() .ignore_stdout() .ignore_stderr() @@ -91,7 +91,6 @@ pub fn run_cts(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { .cmd("git") .args([ "config", - "set", "remote.origin.fetch", "+refs/heads/gh-pages:refs/remotes/origin/gh-pages", ]) From c868142709d0894a1787beb6b9c1d13965a72a8d Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Fri, 11 Jul 2025 14:43:03 -0700 Subject: [PATCH 015/303] Validate vertex and index buffer alignment (#7929) --- cts_runner/test.lst | 4 ++-- wgpu-core/src/command/bundle.rs | 10 ++++++++++ wgpu-core/src/command/draw.rs | 8 ++++++++ wgpu-core/src/command/render.rs | 10 ++++++++++ wgpu-core/src/device/resource.rs | 2 +- wgpu-core/src/pipeline.rs | 2 +- wgpu-types/src/lib.rs | 8 ++++++++ wgpu/src/api/render_pipeline.rs | 2 +- wgpu/src/lib.rs | 6 +++++- 9 files changed, 46 insertions(+), 6 deletions(-) diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 5b1f604cd78..78aae871386 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -29,8 +29,8 @@ webgpu:api,validation,encoding,cmds,index_access:* //FAIL: webgpu:api,validation,encoding,cmds,render,draw:* webgpu:api,validation,encoding,cmds,render,draw:index_buffer_OOB:* webgpu:api,validation,encoding,cmds,render,draw:unused_buffer_bound:* -webgpu:api,validation,encoding,cmds,render,setIndexBuffer:index_buffer_state:* -webgpu:api,validation,encoding,cmds,render,setVertexBuffer:vertex_buffer_state:* +webgpu:api,validation,encoding,cmds,render,setIndexBuffer:* +webgpu:api,validation,encoding,cmds,render,setVertexBuffer:* webgpu:api,validation,encoding,encoder_state:* webgpu:api,validation,encoding,encoder_open_state:non_pass_commands:* webgpu:api,validation,encoding,encoder_open_state:render_pass_commands:* diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index 8566706da8a..5044928b7b4 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -622,6 +622,13 @@ fn set_index_buffer( buffer.same_device(&state.device)?; buffer.check_usage(wgt::BufferUsages::INDEX)?; + if offset % u64::try_from(index_format.byte_size()).unwrap() != 0 { + return Err(RenderCommandError::UnalignedIndexBuffer { + offset, + alignment: index_format.byte_size(), + } + .into()); + } let end = offset + buffer.resolve_binding_size(offset, size)?; state @@ -663,6 +670,9 @@ fn set_vertex_buffer( buffer.same_device(&state.device)?; buffer.check_usage(wgt::BufferUsages::VERTEX)?; + if offset % wgt::VERTEX_ALIGNMENT != 0 { + return Err(RenderCommandError::UnalignedVertexBuffer { slot, offset }.into()); + } let end = offset + buffer.resolve_binding_size(offset, size)?; state diff --git a/wgpu-core/src/command/draw.rs b/wgpu-core/src/command/draw.rs index 7dadc8bfa4e..adb83643d98 100644 --- a/wgpu-core/src/command/draw.rs +++ b/wgpu-core/src/command/draw.rs @@ -73,6 +73,12 @@ pub enum RenderCommandError { BindGroupIndexOutOfRange(#[from] pass::BindGroupIndexOutOfRange), #[error("Vertex buffer index {index} is greater than the device's requested `max_vertex_buffers` limit {max}")] VertexBufferIndexOutOfRange { index: u32, max: u32 }, + #[error( + "Offset {offset} for vertex buffer in slot {slot} is not a multiple of `VERTEX_ALIGNMENT`" + )] + UnalignedVertexBuffer { slot: u32, offset: u64 }, + #[error("Offset {offset} for index buffer is not a multiple of {alignment}")] + UnalignedIndexBuffer { offset: u64, alignment: usize }, #[error("Render pipeline targets are incompatible with render pass")] IncompatiblePipelineTargets(#[from] crate::device::RenderPassCompatibilityError), #[error("{0} writes to depth, while the pass has read-only depth access")] @@ -116,6 +122,8 @@ impl WebGpuError for RenderCommandError { Self::BindGroupIndexOutOfRange { .. } | Self::VertexBufferIndexOutOfRange { .. } + | Self::UnalignedIndexBuffer { .. } + | Self::UnalignedVertexBuffer { .. } | Self::IncompatibleDepthAccess(..) | Self::IncompatibleStencilAccess(..) | Self::InvalidViewportRectSize { .. } diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 06bba2c8f66..b6cef5627c2 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -2344,6 +2344,13 @@ fn set_index_buffer( buffer.check_usage(BufferUsages::INDEX)?; + if offset % u64::try_from(index_format.byte_size()).unwrap() != 0 { + return Err(RenderCommandError::UnalignedIndexBuffer { + offset, + alignment: index_format.byte_size(), + } + .into()); + } let (binding, resolved_size) = buffer .binding(offset, size, state.general.snatch_guard) .map_err(RenderCommandError::from)?; @@ -2397,6 +2404,9 @@ fn set_vertex_buffer( buffer.check_usage(BufferUsages::VERTEX)?; + if offset % wgt::VERTEX_ALIGNMENT != 0 { + return Err(RenderCommandError::UnalignedVertexBuffer { slot, offset }.into()); + } let (binding, buffer_size) = buffer .binding(offset, size, state.general.snatch_guard) .map_err(RenderCommandError::from)?; diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 7af8faac82a..4b41ff8b8b2 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -3159,7 +3159,7 @@ impl Device { limit: self.limits.max_vertex_buffer_array_stride, }); } - if vb_state.array_stride % wgt::VERTEX_STRIDE_ALIGNMENT != 0 { + if vb_state.array_stride % wgt::VERTEX_ALIGNMENT != 0 { return Err(pipeline::CreateRenderPipelineError::UnalignedVertexStride { index: i as u32, stride: vb_state.array_stride, diff --git a/wgpu-core/src/pipeline.rs b/wgpu-core/src/pipeline.rs index 3bc3f7f6d79..cdc88f9f3a2 100644 --- a/wgpu-core/src/pipeline.rs +++ b/wgpu-core/src/pipeline.rs @@ -512,7 +512,7 @@ pub enum CreateRenderPipelineError { given: u32, limit: u32, }, - #[error("Vertex buffer {index} stride {stride} does not respect `VERTEX_STRIDE_ALIGNMENT`")] + #[error("Vertex buffer {index} stride {stride} does not respect `VERTEX_ALIGNMENT`")] UnalignedVertexStride { index: u32, stride: wgt::BufferAddress, diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index e3c6c89a6cb..aff93296605 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -97,10 +97,18 @@ pub const COPY_BUFFER_ALIGNMENT: BufferAddress = 4; /// [`get_mapped_range()`]: ../wgpu/struct.Buffer.html#method.get_mapped_range pub const MAP_ALIGNMENT: BufferAddress = 8; +/// [Vertex buffer offsets] and [strides] have to be a multiple of this number. +/// +/// [Vertex buffer offsets]: ../wgpu/util/trait.RenderEncoder.html#tymethod.set_vertex_buffer +/// [strides]: ../wgpu/struct.VertexBufferLayout.html#structfield.array_stride +pub const VERTEX_ALIGNMENT: BufferAddress = 4; + /// [Vertex buffer strides] have to be a multiple of this number. /// /// [Vertex buffer strides]: ../wgpu/struct.VertexBufferLayout.html#structfield.array_stride +#[deprecated(note = "Use `VERTEX_ALIGNMENT` instead", since = "27.0.0")] pub const VERTEX_STRIDE_ALIGNMENT: BufferAddress = 4; + /// Ranges of [writes to push constant storage] must be at least this aligned. /// /// [writes to push constant storage]: ../wgpu/struct.RenderPass.html#method.set_push_constants diff --git a/wgpu/src/api/render_pipeline.rs b/wgpu/src/api/render_pipeline.rs index 13b4f9b5f7b..27f96bce734 100644 --- a/wgpu/src/api/render_pipeline.rs +++ b/wgpu/src/api/render_pipeline.rs @@ -76,7 +76,7 @@ impl RenderPipeline { pub struct VertexBufferLayout<'a> { /// The stride, in bytes, between elements of this buffer (between vertices). /// - /// This must be a multiple of [`VERTEX_STRIDE_ALIGNMENT`]. + /// This must be a multiple of [`VERTEX_ALIGNMENT`]. pub array_stride: BufferAddress, /// How often this vertex buffer is "stepped" forward. pub step_mode: VertexStepMode, diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index c72eba64832..29243255890 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -90,8 +90,12 @@ pub use wgt::{ TextureTransition, TextureUsages, TextureUses, TextureViewDimension, Trace, VertexAttribute, VertexFormat, VertexStepMode, WasmNotSend, WasmNotSendSync, WasmNotSync, COPY_BUFFER_ALIGNMENT, COPY_BYTES_PER_ROW_ALIGNMENT, MAP_ALIGNMENT, PUSH_CONSTANT_ALIGNMENT, - QUERY_RESOLVE_BUFFER_ALIGNMENT, QUERY_SET_MAX_QUERIES, QUERY_SIZE, VERTEX_STRIDE_ALIGNMENT, + QUERY_RESOLVE_BUFFER_ALIGNMENT, QUERY_SET_MAX_QUERIES, QUERY_SIZE, VERTEX_ALIGNMENT, }; + +#[expect(deprecated)] +pub use wgt::VERTEX_STRIDE_ALIGNMENT; + // wasm-only types, we try to keep as many types non-platform // specific, but these need to depend on web-sys. #[cfg(web)] From bfa7ee8de5fa4063c2d048ff500bcb676b7563e0 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Sat, 22 Mar 2025 13:01:11 -0700 Subject: [PATCH 016/303] [naga hlsl-out] Handle additional cases of Cx2 matrices Fixes #4423 --- naga/src/back/hlsl/mod.rs | 23 +- naga/src/back/hlsl/storage.rs | 144 ++++++-- naga/src/back/hlsl/writer.rs | 71 +++- naga/tests/in/wgsl/access.wgsl | 3 + naga/tests/in/wgsl/hlsl_mat_cx2.toml | 1 + naga/tests/in/wgsl/hlsl_mat_cx2.wgsl | 177 ++++++++++ naga/tests/in/wgsl/hlsl_mat_cx3.toml | 1 + naga/tests/in/wgsl/hlsl_mat_cx3.wgsl | 173 +++++++++ naga/tests/out/hlsl/wgsl-hlsl_mat_cx2.hlsl | 372 ++++++++++++++++++++ naga/tests/out/hlsl/wgsl-hlsl_mat_cx2.ron | 12 + naga/tests/out/hlsl/wgsl-hlsl_mat_cx3.hlsl | 350 +++++++++++++++++++ naga/tests/out/hlsl/wgsl-hlsl_mat_cx3.ron | 12 + naga/tests/out/spv/wgsl-access.spvasm | 385 +++++++++++---------- 13 files changed, 1489 insertions(+), 235 deletions(-) create mode 100644 naga/tests/in/wgsl/hlsl_mat_cx2.toml create mode 100644 naga/tests/in/wgsl/hlsl_mat_cx2.wgsl create mode 100644 naga/tests/in/wgsl/hlsl_mat_cx3.toml create mode 100644 naga/tests/in/wgsl/hlsl_mat_cx3.wgsl create mode 100644 naga/tests/out/hlsl/wgsl-hlsl_mat_cx2.hlsl create mode 100644 naga/tests/out/hlsl/wgsl-hlsl_mat_cx2.ron create mode 100644 naga/tests/out/hlsl/wgsl-hlsl_mat_cx3.hlsl create mode 100644 naga/tests/out/hlsl/wgsl-hlsl_mat_cx3.ron diff --git a/naga/src/back/hlsl/mod.rs b/naga/src/back/hlsl/mod.rs index dd9a5bf6e58..7f553980402 100644 --- a/naga/src/back/hlsl/mod.rs +++ b/naga/src/back/hlsl/mod.rs @@ -13,11 +13,17 @@ type should be stored in `uniform` and `storage` buffers. The HLSL we generate must access values in that form, even when it is not what HLSL would use normally. -The rules described here only apply to WGSL `uniform` variables. WGSL -`storage` buffers are translated as HLSL `ByteAddressBuffers`, for -which we generate `Load` and `Store` method calls with explicit byte -offsets. WGSL pipeline inputs must be scalars or vectors; they cannot -be matrices, which is where the interesting problems arise. +Matching the WGSL memory layout is a concern only for `uniform` +variables. WGSL `storage` buffers are translated as HLSL +`ByteAddressBuffers`, for which we generate `Load` and `Store` method +calls with explicit byte offsets. WGSL pipeline inputs must be scalars +or vectors; they cannot be matrices, which is where the interesting +problems arise. However, when an affected type appears in a struct +definition, the transformations described here are applied without +consideration of where the struct is used. + +Access to storage buffers is implemented in `storage.rs`. Access to +uniform buffers is implemented where applicable in `writer.rs`. ## Row- and column-major ordering for matrices @@ -57,10 +63,9 @@ that the columns of a `matKx2` need only be [aligned as required for `vec2`][ilov], which is [eight-byte alignment][8bb]. To compensate for this, any time a `matKx2` appears in a WGSL -`uniform` variable, whether directly as the variable's type or as part -of a struct/array, we actually emit `K` separate `float2` members, and -assemble/disassemble the matrix from its columns (in WGSL; rows in -HLSL) upon load and store. +`uniform` value or as part of a struct/array, we actually emit `K` +separate `float2` members, and assemble/disassemble the matrix from its +columns (in WGSL; rows in HLSL) upon load and store. For example, the following WGSL struct type: diff --git a/naga/src/back/hlsl/storage.rs b/naga/src/back/hlsl/storage.rs index 9f92d866398..5d66af00087 100644 --- a/naga/src/back/hlsl/storage.rs +++ b/naga/src/back/hlsl/storage.rs @@ -108,6 +108,13 @@ pub(super) enum StoreValue { base: Handle, member_index: u32, }, + // Access to a single column of a Cx2 matrix within a struct + TempColumnAccess { + depth: usize, + base: Handle, + member_index: u32, + column: u32, + }, } impl super::Writer<'_, W> { @@ -290,6 +297,15 @@ impl super::Writer<'_, W> { let name = &self.names[&NameKey::StructMember(base, member_index)]; write!(self.out, "{STORE_TEMP_NAME}{depth}.{name}")? } + StoreValue::TempColumnAccess { + depth, + base, + member_index, + column, + } => { + let name = &self.names[&NameKey::StructMember(base, member_index)]; + write!(self.out, "{STORE_TEMP_NAME}{depth}.{name}_{column}")? + } } Ok(()) } @@ -302,6 +318,7 @@ impl super::Writer<'_, W> { value: StoreValue, func_ctx: &FunctionCtx, level: crate::back::Level, + within_struct: Option>, ) -> BackendResult { let temp_resolution; let ty_resolution = match value { @@ -325,6 +342,9 @@ impl super::Writer<'_, W> { temp_resolution = TypeResolution::Handle(ty_handle); &temp_resolution } + StoreValue::TempColumnAccess { .. } => { + unreachable!("attempting write_storage_store for TempColumnAccess"); + } }; match *ty_resolution.inner_with(&module.types) { crate::TypeInner::Scalar(scalar) => { @@ -372,37 +392,92 @@ impl super::Writer<'_, W> { rows, scalar, } => { - // first, assign the value to a temporary - writeln!(self.out, "{level}{{")?; - let depth = level.0 + 1; - write!( - self.out, - "{}{}{}x{} {}{} = ", - level.next(), - scalar.to_hlsl_str()?, - columns as u8, - rows as u8, - STORE_TEMP_NAME, - depth, - )?; - self.write_store_value(module, &value, func_ctx)?; - writeln!(self.out, ";")?; - // Note: Matrices containing vec3s, due to padding, act like they contain vec4s. let row_stride = Alignment::from(rows) * scalar.width as u32; - // then iterate the stores - for i in 0..columns as u32 { - self.temp_access_chain - .push(SubAccess::Offset(i * row_stride)); - let ty_inner = crate::TypeInner::Vector { size: rows, scalar }; - let sv = StoreValue::TempIndex { - depth, - index: i, - ty: TypeResolution::Value(ty_inner), - }; - self.write_storage_store(module, var_handle, sv, func_ctx, level.next())?; - self.temp_access_chain.pop(); + writeln!(self.out, "{level}{{")?; + + match within_struct { + Some(containing_struct) if rows == crate::VectorSize::Bi => { + // If we are within a struct, then the struct was already assigned to + // a temporary, we don't need to make another. + let mut chain = mem::take(&mut self.temp_access_chain); + for i in 0..columns as u32 { + chain.push(SubAccess::Offset(i * row_stride)); + // working around the borrow checker in `self.write_expr` + let var_name = &self.names[&NameKey::GlobalVariable(var_handle)]; + let StoreValue::TempAccess { member_index, .. } = value else { + unreachable!( + "write_storage_store within_struct but not TempAccess" + ); + }; + let column_value = StoreValue::TempColumnAccess { + depth: level.0, // note not incrementing, b/c no temp + base: containing_struct, + member_index, + column: i, + }; + // See note about DXC and Load/Store in the module's documentation. + if scalar.width == 4 { + write!( + self.out, + "{}{}.Store{}(", + level.next(), + var_name, + rows as u8 + )?; + self.write_storage_address(module, &chain, func_ctx)?; + write!(self.out, ", asuint(")?; + self.write_store_value(module, &column_value, func_ctx)?; + writeln!(self.out, "));")?; + } else { + write!(self.out, "{}{var_name}.Store(", level.next())?; + self.write_storage_address(module, &chain, func_ctx)?; + write!(self.out, ", ")?; + self.write_store_value(module, &column_value, func_ctx)?; + writeln!(self.out, ");")?; + } + chain.pop(); + } + self.temp_access_chain = chain; + } + _ => { + // first, assign the value to a temporary + let depth = level.0 + 1; + write!( + self.out, + "{}{}{}x{} {}{} = ", + level.next(), + scalar.to_hlsl_str()?, + columns as u8, + rows as u8, + STORE_TEMP_NAME, + depth, + )?; + self.write_store_value(module, &value, func_ctx)?; + writeln!(self.out, ";")?; + + // then iterate the stores + for i in 0..columns as u32 { + self.temp_access_chain + .push(SubAccess::Offset(i * row_stride)); + let ty_inner = crate::TypeInner::Vector { size: rows, scalar }; + let sv = StoreValue::TempIndex { + depth, + index: i, + ty: TypeResolution::Value(ty_inner), + }; + self.write_storage_store( + module, + var_handle, + sv, + func_ctx, + level.next(), + None, + )?; + self.temp_access_chain.pop(); + } + } } // done writeln!(self.out, "{level}}}")?; @@ -415,7 +490,7 @@ impl super::Writer<'_, W> { // first, assign the value to a temporary writeln!(self.out, "{level}{{")?; write!(self.out, "{}", level.next())?; - self.write_value_type(module, &module.types[base].inner)?; + self.write_type(module, base)?; let depth = level.next().0; write!(self.out, " {STORE_TEMP_NAME}{depth}")?; self.write_array_size(module, base, crate::ArraySize::Constant(size))?; @@ -430,7 +505,7 @@ impl super::Writer<'_, W> { index: i, ty: TypeResolution::Handle(base), }; - self.write_storage_store(module, var_handle, sv, func_ctx, level.next())?; + self.write_storage_store(module, var_handle, sv, func_ctx, level.next(), None)?; self.temp_access_chain.pop(); } // done @@ -461,7 +536,14 @@ impl super::Writer<'_, W> { base: struct_ty, member_index: i as u32, }; - self.write_storage_store(module, var_handle, sv, func_ctx, level.next())?; + self.write_storage_store( + module, + var_handle, + sv, + func_ctx, + level.next(), + Some(struct_ty), + )?; self.temp_access_chain.pop(); } // done diff --git a/naga/src/back/hlsl/writer.rs b/naga/src/back/hlsl/writer.rs index 2096aff0f97..b06fa534edb 100644 --- a/naga/src/back/hlsl/writer.rs +++ b/naga/src/back/hlsl/writer.rs @@ -1945,6 +1945,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { StoreValue::Expression(value), func_ctx, level, + None, )?; } else { // We treat matrices of the form `matCx2` as a sequence of C `vec2`s. @@ -2963,6 +2964,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { rows: crate::VectorSize::Bi, width: 4, }) = get_inner_matrix_of_struct_array_member(module, base, func_ctx, true) + .or_else(|| get_global_uniform_matrix(module, base, func_ctx)) { write!(self.out, "__get_col_of_mat{}x2(", columns as u8)?; self.write_expr(module, base, func_ctx)?; @@ -3075,13 +3077,15 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { { // do nothing, the chain is written on `Load`/`Store` } else { - // We write the matrix column access in a special way since - // the type of `base` is our special __matCx2 struct. + // See if we need to write the matrix column access in a + // special way since the type of `base` is our special + // __matCx2 struct. if let Some(MatrixType { rows: crate::VectorSize::Bi, width: 4, .. }) = get_inner_matrix_of_struct_array_member(module, base, func_ctx, true) + .or_else(|| get_global_uniform_matrix(module, base, func_ctx)) { self.write_expr(module, base, func_ctx)?; write!(self.out, "._{index}")?; @@ -3381,8 +3385,11 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { .or_else(|| get_inner_matrix_of_global_uniform(module, pointer, func_ctx)) { let mut resolved = func_ctx.resolve_type(pointer, &module.types); - if let TypeInner::Pointer { base, .. } = *resolved { - resolved = &module.types[base].inner; + let ptr_tr = resolved.pointer_base_type(); + if let Some(ptr_ty) = + ptr_tr.as_ref().map(|tr| tr.inner_with(&module.types)) + { + resolved = ptr_ty; } write!(self.out, "((")?; @@ -4416,6 +4423,32 @@ pub(super) fn get_inner_matrix_data( } } +fn find_matrix_in_access_chain( + module: &Module, + base: Handle, + func_ctx: &back::FunctionCtx<'_>, +) -> Option> { + let mut current_base = base; + loop { + let resolved_tr = func_ctx + .resolve_type(current_base, &module.types) + .pointer_base_type(); + let resolved = resolved_tr.as_ref()?.inner_with(&module.types); + + match *resolved { + TypeInner::Scalar(_) | TypeInner::Vector { .. } => {} + TypeInner::Matrix { .. } => return Some(current_base), + _ => return None, + } + + current_base = match func_ctx.expressions[current_base] { + crate::Expression::Access { base, .. } => base, + crate::Expression::AccessIndex { base, .. } => base, + _ => return None, + } + } +} + /// Returns the matrix data if the access chain starting at `base`: /// - starts with an expression with resolved type of [`TypeInner::Matrix`] if `direct = true` /// - contains one or more expressions with resolved type of [`TypeInner::Array`] of [`TypeInner::Matrix`] @@ -4474,6 +4507,36 @@ pub(super) fn get_inner_matrix_of_struct_array_member( None } +/// Simpler version of get_inner_matrix_of_global_uniform that only looks at the +/// immediate expression, rather than traversing an access chain. +fn get_global_uniform_matrix( + module: &Module, + base: Handle, + func_ctx: &back::FunctionCtx<'_>, +) -> Option { + let base_tr = func_ctx + .resolve_type(base, &module.types) + .pointer_base_type(); + let base_ty = base_tr.as_ref().map(|tr| tr.inner_with(&module.types)); + match (&func_ctx.expressions[base], base_ty) { + ( + &crate::Expression::GlobalVariable(handle), + Some(&TypeInner::Matrix { + columns, + rows, + scalar, + }), + ) if module.global_variables[handle].space == crate::AddressSpace::Uniform => { + Some(MatrixType { + columns, + rows, + width: scalar.width, + }) + } + _ => None, + } +} + /// Returns the matrix data if the access chain starting at `base`: /// - starts with an expression with resolved type of [`TypeInner::Matrix`] /// - contains zero or more expressions with resolved type of [`TypeInner::Array`] of [`TypeInner::Matrix`] diff --git a/naga/tests/in/wgsl/access.wgsl b/naga/tests/in/wgsl/access.wgsl index d93f2b30a10..0e89bcfb0eb 100644 --- a/naga/tests/in/wgsl/access.wgsl +++ b/naga/tests/in/wgsl/access.wgsl @@ -35,6 +35,9 @@ var baz: Baz; var qux: vec2; fn test_matrix_within_struct_accesses() { + // Test HLSL accesses to Cx2 matrices. There are additional tests + // in `hlsl_mat_cx2.wgsl`. + var idx = 1; idx--; diff --git a/naga/tests/in/wgsl/hlsl_mat_cx2.toml b/naga/tests/in/wgsl/hlsl_mat_cx2.toml new file mode 100644 index 00000000000..3ca0b52f4e5 --- /dev/null +++ b/naga/tests/in/wgsl/hlsl_mat_cx2.toml @@ -0,0 +1 @@ +targets = "HLSL" diff --git a/naga/tests/in/wgsl/hlsl_mat_cx2.wgsl b/naga/tests/in/wgsl/hlsl_mat_cx2.wgsl new file mode 100644 index 00000000000..50bc188794a --- /dev/null +++ b/naga/tests/in/wgsl/hlsl_mat_cx2.wgsl @@ -0,0 +1,177 @@ +// Test HLSL handling of N-by-2 matrices. +// See the doc comment on `naga::back::hlsl` for details. +// +// There are additional tests in `access.wgsl`. +// +// Tests that we don't apply this handling to other sizes are in hlsl_mat_cx3.wgsl. + +// Access type (3rd item in variable names) +// S = Struct +// M = Matrix +// C = Column +// E = Element + +// Index type (4th item in variable names) +// C = Constant +// V = Variable + +alias Mat = mat2x2; + +@group(0) @binding(0) +var s_m: Mat; + +@group(0) @binding(1) +var u_m: Mat; + +fn access_m() { + var idx = 1; + idx--; + + // loads from storage + let l_s_m = s_m; + let l_s_c_c = s_m[0]; + let l_s_c_v = s_m[idx]; + let l_s_e_cc = s_m[0][0]; + let l_s_e_cv = s_m[0][idx]; + let l_s_e_vc = s_m[idx][0]; + let l_s_e_vv = s_m[idx][idx]; + + // loads from uniform + let l_u_m = u_m; + let l_u_c_c = u_m[0]; + let l_u_c_v = u_m[idx]; + let l_u_e_cc = u_m[0][0]; + let l_u_e_cv = u_m[0][idx]; + let l_u_e_vc = u_m[idx][0]; + let l_u_e_vv = u_m[idx][idx]; + + // stores to storage + s_m = l_u_m; + s_m[0] = l_u_c_c; + s_m[idx] = l_u_c_v; + s_m[0][0] = l_u_e_cc; + s_m[0][idx] = l_u_e_cv; + s_m[idx][0] = l_u_e_vc; + s_m[idx][idx] = l_u_e_vv; +} + +struct StructWithMat { + m: Mat, +} + +@group(1) @binding(0) +var s_sm: StructWithMat; + +@group(1) @binding(1) +var u_sm: StructWithMat; + +fn access_sm() { + var idx = 1; + idx--; + + // loads from storage + let l_s_s = s_sm; + let l_s_m = s_sm.m; + let l_s_c_c = s_sm.m[0]; + let l_s_c_v = s_sm.m[idx]; + let l_s_e_cc = s_sm.m[0][0]; + let l_s_e_cv = s_sm.m[0][idx]; + let l_s_e_vc = s_sm.m[idx][0]; + let l_s_e_vv = s_sm.m[idx][idx]; + + // loads from uniform + let l_u_s = u_sm; + let l_u_m = u_sm.m; + let l_u_c_c = u_sm.m[0]; + let l_u_c_v = u_sm.m[idx]; + let l_u_e_cc = u_sm.m[0][0]; + let l_u_e_cv = u_sm.m[0][idx]; + let l_u_e_vc = u_sm.m[idx][0]; + let l_u_e_vv = u_sm.m[idx][idx]; + + // stores to storage + s_sm = l_u_s; + s_sm.m = l_u_m; + s_sm.m[0] = l_u_c_c; + s_sm.m[idx] = l_u_c_v; + s_sm.m[0][0] = l_u_e_cc; + s_sm.m[0][idx] = l_u_e_cv; + s_sm.m[idx][0] = l_u_e_vc; + s_sm.m[idx][idx] = l_u_e_vv; +} + +struct StructWithArrayOfStructOfMat { + a: array, +} + +@group(2) @binding(0) +var s_sasm: StructWithArrayOfStructOfMat; + +@group(2) @binding(1) +var u_sasm: StructWithArrayOfStructOfMat; + +fn access_sasm() { + var idx = 1; + idx--; + + // loads from storage + let l_s_s = s_sasm; + let l_s_a = s_sasm.a; + let l_s_m_c = s_sasm.a[0].m; + let l_s_m_v = s_sasm.a[idx].m; + let l_s_c_cc = s_sasm.a[0].m[0]; + let l_s_c_cv = s_sasm.a[0].m[idx]; + let l_s_c_vc = s_sasm.a[idx].m[0]; + let l_s_c_vv = s_sasm.a[idx].m[idx]; + let l_s_e_ccc = s_sasm.a[0].m[0][0]; + let l_s_e_ccv = s_sasm.a[0].m[0][idx]; + let l_s_e_cvc = s_sasm.a[0].m[idx][0]; + let l_s_e_cvv = s_sasm.a[0].m[idx][idx]; + let l_s_e_vcc = s_sasm.a[idx].m[0][0]; + let l_s_e_vcv = s_sasm.a[idx].m[0][idx]; + let l_s_e_vvc = s_sasm.a[idx].m[idx][0]; + let l_s_e_vvv = s_sasm.a[idx].m[idx][idx]; + + // loads from uniform + let l_u_s = u_sasm; + let l_u_a = u_sasm.a; + let l_u_m_c = u_sasm.a[0].m; + let l_u_m_v = u_sasm.a[idx].m; + let l_u_c_cc = u_sasm.a[0].m[0]; + let l_u_c_cv = u_sasm.a[0].m[idx]; + let l_u_c_vc = u_sasm.a[idx].m[0]; + let l_u_c_vv = u_sasm.a[idx].m[idx]; + let l_u_e_ccc = u_sasm.a[0].m[0][0]; + let l_u_e_ccv = u_sasm.a[0].m[0][idx]; + let l_u_e_cvc = u_sasm.a[0].m[idx][0]; + let l_u_e_cvv = u_sasm.a[0].m[idx][idx]; + let l_u_e_vcc = u_sasm.a[idx].m[0][0]; + let l_u_e_vcv = u_sasm.a[idx].m[0][idx]; + let l_u_e_vvc = u_sasm.a[idx].m[idx][0]; + let l_u_e_vvv = u_sasm.a[idx].m[idx][idx]; + + // stores to storage + s_sasm = l_u_s; + s_sasm.a = l_u_a; + s_sasm.a[0].m = l_u_m_c; + s_sasm.a[idx].m = l_u_m_v; + s_sasm.a[0].m[0] = l_u_c_cc; + s_sasm.a[0].m[idx] = l_u_c_cv; + s_sasm.a[idx].m[0] = l_u_c_vc; + s_sasm.a[idx].m[idx] = l_u_c_vv; + s_sasm.a[0].m[0][0] = l_u_e_ccc; + s_sasm.a[0].m[0][idx] = l_u_e_ccv; + s_sasm.a[0].m[idx][0] = l_u_e_cvc; + s_sasm.a[0].m[idx][idx] = l_u_e_cvv; + s_sasm.a[idx].m[0][0] = l_u_e_vcc; + s_sasm.a[idx].m[0][idx] = l_u_e_vcv; + s_sasm.a[idx].m[idx][0] = l_u_e_vvc; + s_sasm.a[idx].m[idx][idx] = l_u_e_vvv; +} + +@compute @workgroup_size(1) +fn main() { + access_m(); + access_sm(); + access_sasm(); +} diff --git a/naga/tests/in/wgsl/hlsl_mat_cx3.toml b/naga/tests/in/wgsl/hlsl_mat_cx3.toml new file mode 100644 index 00000000000..3ca0b52f4e5 --- /dev/null +++ b/naga/tests/in/wgsl/hlsl_mat_cx3.toml @@ -0,0 +1 @@ +targets = "HLSL" diff --git a/naga/tests/in/wgsl/hlsl_mat_cx3.wgsl b/naga/tests/in/wgsl/hlsl_mat_cx3.wgsl new file mode 100644 index 00000000000..e33f10fc9c5 --- /dev/null +++ b/naga/tests/in/wgsl/hlsl_mat_cx3.wgsl @@ -0,0 +1,173 @@ +// Test HLSL handling of N-by-3 matrices. These should not receive the special +// treatment that N-by-2 matrices receive (which is tested in hlsl_mat_cx2). + +// Access type (3rd item in variable names) +// S = Struct +// M = Matrix +// C = Column +// E = Element + +// Index type (4th item in variable names) +// C = Constant +// V = Variable + +alias Mat = mat3x3; + +@group(0) @binding(0) +var s_m: Mat; + +@group(0) @binding(1) +var u_m: Mat; + +fn access_m() { + var idx = 1; + idx--; + + // loads from storage + let l_s_m = s_m; + let l_s_c_c = s_m[0]; + let l_s_c_v = s_m[idx]; + let l_s_e_cc = s_m[0][0]; + let l_s_e_cv = s_m[0][idx]; + let l_s_e_vc = s_m[idx][0]; + let l_s_e_vv = s_m[idx][idx]; + + // loads from uniform + let l_u_m = u_m; + let l_u_c_c = u_m[0]; + let l_u_c_v = u_m[idx]; + let l_u_e_cc = u_m[0][0]; + let l_u_e_cv = u_m[0][idx]; + let l_u_e_vc = u_m[idx][0]; + let l_u_e_vv = u_m[idx][idx]; + + // stores to storage + s_m = l_u_m; + s_m[0] = l_u_c_c; + s_m[idx] = l_u_c_v; + s_m[0][0] = l_u_e_cc; + s_m[0][idx] = l_u_e_cv; + s_m[idx][0] = l_u_e_vc; + s_m[idx][idx] = l_u_e_vv; +} + +struct StructWithMat { + m: Mat, +} + +@group(1) @binding(0) +var s_sm: StructWithMat; + +@group(1) @binding(1) +var u_sm: StructWithMat; + +fn access_sm() { + var idx = 1; + idx--; + + // loads from storage + let l_s_s = s_sm; + let l_s_m = s_sm.m; + let l_s_c_c = s_sm.m[0]; + let l_s_c_v = s_sm.m[idx]; + let l_s_e_cc = s_sm.m[0][0]; + let l_s_e_cv = s_sm.m[0][idx]; + let l_s_e_vc = s_sm.m[idx][0]; + let l_s_e_vv = s_sm.m[idx][idx]; + + // loads from uniform + let l_u_s = u_sm; + let l_u_m = u_sm.m; + let l_u_c_c = u_sm.m[0]; + let l_u_c_v = u_sm.m[idx]; + let l_u_e_cc = u_sm.m[0][0]; + let l_u_e_cv = u_sm.m[0][idx]; + let l_u_e_vc = u_sm.m[idx][0]; + let l_u_e_vv = u_sm.m[idx][idx]; + + // stores to storage + s_sm = l_u_s; + s_sm.m = l_u_m; + s_sm.m[0] = l_u_c_c; + s_sm.m[idx] = l_u_c_v; + s_sm.m[0][0] = l_u_e_cc; + s_sm.m[0][idx] = l_u_e_cv; + s_sm.m[idx][0] = l_u_e_vc; + s_sm.m[idx][idx] = l_u_e_vv; +} + +struct StructWithArrayOfStructOfMat { + a: array, +} + +@group(2) @binding(0) +var s_sasm: StructWithArrayOfStructOfMat; + +@group(2) @binding(1) +var u_sasm: StructWithArrayOfStructOfMat; + +fn access_sasm() { + var idx = 1; + idx--; + + // loads from storage + let l_s_s = s_sasm; + let l_s_a = s_sasm.a; + let l_s_m_c = s_sasm.a[0].m; + let l_s_m_v = s_sasm.a[idx].m; + let l_s_c_cc = s_sasm.a[0].m[0]; + let l_s_c_cv = s_sasm.a[0].m[idx]; + let l_s_c_vc = s_sasm.a[idx].m[0]; + let l_s_c_vv = s_sasm.a[idx].m[idx]; + let l_s_e_ccc = s_sasm.a[0].m[0][0]; + let l_s_e_ccv = s_sasm.a[0].m[0][idx]; + let l_s_e_cvc = s_sasm.a[0].m[idx][0]; + let l_s_e_cvv = s_sasm.a[0].m[idx][idx]; + let l_s_e_vcc = s_sasm.a[idx].m[0][0]; + let l_s_e_vcv = s_sasm.a[idx].m[0][idx]; + let l_s_e_vvc = s_sasm.a[idx].m[idx][0]; + let l_s_e_vvv = s_sasm.a[idx].m[idx][idx]; + + // loads from uniform + let l_u_s = u_sasm; + let l_u_a = u_sasm.a; + let l_u_m_c = u_sasm.a[0].m; + let l_u_m_v = u_sasm.a[idx].m; + let l_u_c_cc = u_sasm.a[0].m[0]; + let l_u_c_cv = u_sasm.a[0].m[idx]; + let l_u_c_vc = u_sasm.a[idx].m[0]; + let l_u_c_vv = u_sasm.a[idx].m[idx]; + let l_u_e_ccc = u_sasm.a[0].m[0][0]; + let l_u_e_ccv = u_sasm.a[0].m[0][idx]; + let l_u_e_cvc = u_sasm.a[0].m[idx][0]; + let l_u_e_cvv = u_sasm.a[0].m[idx][idx]; + let l_u_e_vcc = u_sasm.a[idx].m[0][0]; + let l_u_e_vcv = u_sasm.a[idx].m[0][idx]; + let l_u_e_vvc = u_sasm.a[idx].m[idx][0]; + let l_u_e_vvv = u_sasm.a[idx].m[idx][idx]; + + // stores to storage + s_sasm = l_u_s; + s_sasm.a = l_u_a; + s_sasm.a[0].m = l_u_m_c; + s_sasm.a[idx].m = l_u_m_v; + s_sasm.a[0].m[0] = l_u_c_cc; + s_sasm.a[0].m[idx] = l_u_c_cv; + s_sasm.a[idx].m[0] = l_u_c_vc; + s_sasm.a[idx].m[idx] = l_u_c_vv; + s_sasm.a[0].m[0][0] = l_u_e_ccc; + s_sasm.a[0].m[0][idx] = l_u_e_ccv; + s_sasm.a[0].m[idx][0] = l_u_e_cvc; + s_sasm.a[0].m[idx][idx] = l_u_e_cvv; + s_sasm.a[idx].m[0][0] = l_u_e_vcc; + s_sasm.a[idx].m[0][idx] = l_u_e_vcv; + s_sasm.a[idx].m[idx][0] = l_u_e_vvc; + s_sasm.a[idx].m[idx][idx] = l_u_e_vvv; +} + +@compute @workgroup_size(1) +fn main() { + access_m(); + access_sm(); + access_sasm(); +} diff --git a/naga/tests/out/hlsl/wgsl-hlsl_mat_cx2.hlsl b/naga/tests/out/hlsl/wgsl-hlsl_mat_cx2.hlsl new file mode 100644 index 00000000000..1de9e069cdc --- /dev/null +++ b/naga/tests/out/hlsl/wgsl-hlsl_mat_cx2.hlsl @@ -0,0 +1,372 @@ +typedef struct { float2 _0; float2 _1; } __mat2x2; +float2 __get_col_of_mat2x2(__mat2x2 mat, uint idx) { + switch(idx) { + case 0: { return mat._0; } + case 1: { return mat._1; } + default: { return (float2)0; } + } +} +void __set_col_of_mat2x2(__mat2x2 mat, uint idx, float2 value) { + switch(idx) { + case 0: { mat._0 = value; break; } + case 1: { mat._1 = value; break; } + } +} +void __set_el_of_mat2x2(__mat2x2 mat, uint idx, uint vec_idx, float value) { + switch(idx) { + case 0: { mat._0[vec_idx] = value; break; } + case 1: { mat._1[vec_idx] = value; break; } + } +} + +struct StructWithMat { + float2 m_0; float2 m_1; +}; + +struct StructWithArrayOfStructOfMat { + StructWithMat a[4]; +}; + +RWByteAddressBuffer s_m : register(u0); +cbuffer u_m : register(b1) { __mat2x2 u_m; } +RWByteAddressBuffer s_sm : register(u0, space1); +cbuffer u_sm : register(b1, space1) { StructWithMat u_sm; } +RWByteAddressBuffer s_sasm : register(u0, space2); +cbuffer u_sasm : register(b1, space2) { StructWithArrayOfStructOfMat u_sasm; } + +void access_m() +{ + int idx = int(1); + + int _e3 = idx; + idx = asint(asuint(_e3) - asuint(int(1))); + float2x2 l_s_m = float2x2(asfloat(s_m.Load2(0)), asfloat(s_m.Load2(8))); + float2 l_s_c_c = asfloat(s_m.Load2(0)); + int _e11 = idx; + float2 l_s_c_v = asfloat(s_m.Load2(_e11*8)); + float l_s_e_cc = asfloat(s_m.Load(0+0)); + int _e20 = idx; + float l_s_e_cv = asfloat(s_m.Load(_e20*4+0)); + int _e24 = idx; + float l_s_e_vc = asfloat(s_m.Load(0+_e24*8)); + int _e29 = idx; + int _e31 = idx; + float l_s_e_vv = asfloat(s_m.Load(_e31*4+_e29*8)); + float2x2 l_u_m = ((float2x2)u_m); + float2 l_u_c_c = u_m._0; + int _e40 = idx; + float2 l_u_c_v = __get_col_of_mat2x2(u_m, _e40); + float l_u_e_cc = u_m._0.x; + int _e49 = idx; + float l_u_e_cv = u_m._0[_e49]; + int _e53 = idx; + float l_u_e_vc = __get_col_of_mat2x2(u_m, _e53).x; + int _e58 = idx; + int _e60 = idx; + float l_u_e_vv = __get_col_of_mat2x2(u_m, _e58)[_e60]; + { + float2x2 _value2 = l_u_m; + s_m.Store2(0, asuint(_value2[0])); + s_m.Store2(8, asuint(_value2[1])); + } + s_m.Store2(0, asuint(l_u_c_c)); + int _e67 = idx; + s_m.Store2(_e67*8, asuint(l_u_c_v)); + s_m.Store(0+0, asuint(l_u_e_cc)); + int _e74 = idx; + s_m.Store(_e74*4+0, asuint(l_u_e_cv)); + int _e77 = idx; + s_m.Store(0+_e77*8, asuint(l_u_e_vc)); + int _e81 = idx; + int _e83 = idx; + s_m.Store(_e83*4+_e81*8, asuint(l_u_e_vv)); + return; +} + +StructWithMat ConstructStructWithMat(float2x2 arg0) { + StructWithMat ret = (StructWithMat)0; + ret.m_0 = arg0[0]; + ret.m_1 = arg0[1]; + return ret; +} + +float2x2 GetMatmOnStructWithMat(StructWithMat obj) { + return float2x2(obj.m_0, obj.m_1); +} + +void SetMatmOnStructWithMat(StructWithMat obj, float2x2 mat) { + obj.m_0 = mat[0]; + obj.m_1 = mat[1]; +} + +void SetMatVecmOnStructWithMat(StructWithMat obj, float2 vec, uint mat_idx) { + switch(mat_idx) { + case 0: { obj.m_0 = vec; break; } + case 1: { obj.m_1 = vec; break; } + } +} + +void SetMatScalarmOnStructWithMat(StructWithMat obj, float scalar, uint mat_idx, uint vec_idx) { + switch(mat_idx) { + case 0: { obj.m_0[vec_idx] = scalar; break; } + case 1: { obj.m_1[vec_idx] = scalar; break; } + } +} + +void access_sm() +{ + int idx_1 = int(1); + + int _e3 = idx_1; + idx_1 = asint(asuint(_e3) - asuint(int(1))); + StructWithMat l_s_s = ConstructStructWithMat(float2x2(asfloat(s_sm.Load2(0+0)), asfloat(s_sm.Load2(0+8)))); + float2x2 l_s_m_1 = float2x2(asfloat(s_sm.Load2(0+0)), asfloat(s_sm.Load2(0+8))); + float2 l_s_c_c_1 = asfloat(s_sm.Load2(0+0)); + int _e16 = idx_1; + float2 l_s_c_v_1 = asfloat(s_sm.Load2(_e16*8+0)); + float l_s_e_cc_1 = asfloat(s_sm.Load(0+0+0)); + int _e27 = idx_1; + float l_s_e_cv_1 = asfloat(s_sm.Load(_e27*4+0+0)); + int _e32 = idx_1; + float l_s_e_vc_1 = asfloat(s_sm.Load(0+_e32*8+0)); + int _e38 = idx_1; + int _e40 = idx_1; + float l_s_e_vv_1 = asfloat(s_sm.Load(_e40*4+_e38*8+0)); + StructWithMat l_u_s = u_sm; + float2x2 l_u_m_1 = GetMatmOnStructWithMat(u_sm); + float2 l_u_c_c_1 = GetMatmOnStructWithMat(u_sm)[0]; + int _e54 = idx_1; + float2 l_u_c_v_1 = GetMatmOnStructWithMat(u_sm)[_e54]; + float l_u_e_cc_1 = GetMatmOnStructWithMat(u_sm)[0].x; + int _e65 = idx_1; + float l_u_e_cv_1 = GetMatmOnStructWithMat(u_sm)[0][_e65]; + int _e70 = idx_1; + float l_u_e_vc_1 = GetMatmOnStructWithMat(u_sm)[_e70].x; + int _e76 = idx_1; + int _e78 = idx_1; + float l_u_e_vv_1 = GetMatmOnStructWithMat(u_sm)[_e76][_e78]; + { + StructWithMat _value2 = l_u_s; + { + s_sm.Store2(0+0, asuint(_value2.m_0)); + s_sm.Store2(0+8, asuint(_value2.m_1)); + } + } + { + float2x2 _value2 = l_u_m_1; + s_sm.Store2(0+0, asuint(_value2[0])); + s_sm.Store2(0+8, asuint(_value2[1])); + } + s_sm.Store2(0+0, asuint(l_u_c_c_1)); + int _e89 = idx_1; + s_sm.Store2(_e89*8+0, asuint(l_u_c_v_1)); + s_sm.Store(0+0+0, asuint(l_u_e_cc_1)); + int _e98 = idx_1; + s_sm.Store(_e98*4+0+0, asuint(l_u_e_cv_1)); + int _e102 = idx_1; + s_sm.Store(0+_e102*8+0, asuint(l_u_e_vc_1)); + int _e107 = idx_1; + int _e109 = idx_1; + s_sm.Store(_e109*4+_e107*8+0, asuint(l_u_e_vv_1)); + return; +} + +typedef StructWithMat ret_Constructarray4_StructWithMat_[4]; +ret_Constructarray4_StructWithMat_ Constructarray4_StructWithMat_(StructWithMat arg0, StructWithMat arg1, StructWithMat arg2, StructWithMat arg3) { + StructWithMat ret[4] = { arg0, arg1, arg2, arg3 }; + return ret; +} + +StructWithArrayOfStructOfMat ConstructStructWithArrayOfStructOfMat(StructWithMat arg0[4]) { + StructWithArrayOfStructOfMat ret = (StructWithArrayOfStructOfMat)0; + ret.a = arg0; + return ret; +} + +void access_sasm() +{ + int idx_2 = int(1); + + int _e3 = idx_2; + idx_2 = asint(asuint(_e3) - asuint(int(1))); + StructWithArrayOfStructOfMat l_s_s_1 = ConstructStructWithArrayOfStructOfMat(Constructarray4_StructWithMat_(ConstructStructWithMat(float2x2(asfloat(s_sasm.Load2(0+0+0+0)), asfloat(s_sasm.Load2(0+0+0+8)))), ConstructStructWithMat(float2x2(asfloat(s_sasm.Load2(0+16+0+0)), asfloat(s_sasm.Load2(0+16+0+8)))), ConstructStructWithMat(float2x2(asfloat(s_sasm.Load2(0+32+0+0)), asfloat(s_sasm.Load2(0+32+0+8)))), ConstructStructWithMat(float2x2(asfloat(s_sasm.Load2(0+48+0+0)), asfloat(s_sasm.Load2(0+48+0+8)))))); + StructWithMat l_s_a[4] = Constructarray4_StructWithMat_(ConstructStructWithMat(float2x2(asfloat(s_sasm.Load2(0+0+0+0)), asfloat(s_sasm.Load2(0+0+0+8)))), ConstructStructWithMat(float2x2(asfloat(s_sasm.Load2(0+16+0+0)), asfloat(s_sasm.Load2(0+16+0+8)))), ConstructStructWithMat(float2x2(asfloat(s_sasm.Load2(0+32+0+0)), asfloat(s_sasm.Load2(0+32+0+8)))), ConstructStructWithMat(float2x2(asfloat(s_sasm.Load2(0+48+0+0)), asfloat(s_sasm.Load2(0+48+0+8))))); + float2x2 l_s_m_c = float2x2(asfloat(s_sasm.Load2(0+0+0+0)), asfloat(s_sasm.Load2(0+0+0+8))); + int _e17 = idx_2; + float2x2 l_s_m_v = float2x2(asfloat(s_sasm.Load2(0+_e17*16+0+0)), asfloat(s_sasm.Load2(0+_e17*16+0+8))); + float2 l_s_c_cc = asfloat(s_sasm.Load2(0+0+0+0)); + int _e31 = idx_2; + float2 l_s_c_cv = asfloat(s_sasm.Load2(_e31*8+0+0+0)); + int _e36 = idx_2; + float2 l_s_c_vc = asfloat(s_sasm.Load2(0+0+_e36*16+0)); + int _e43 = idx_2; + int _e46 = idx_2; + float2 l_s_c_vv = asfloat(s_sasm.Load2(_e46*8+0+_e43*16+0)); + float l_s_e_ccc = asfloat(s_sasm.Load(0+0+0+0+0)); + int _e61 = idx_2; + float l_s_e_ccv = asfloat(s_sasm.Load(_e61*4+0+0+0+0)); + int _e68 = idx_2; + float l_s_e_cvc = asfloat(s_sasm.Load(0+_e68*8+0+0+0)); + int _e76 = idx_2; + int _e78 = idx_2; + float l_s_e_cvv = asfloat(s_sasm.Load(_e78*4+_e76*8+0+0+0)); + int _e83 = idx_2; + float l_s_e_vcc = asfloat(s_sasm.Load(0+0+0+_e83*16+0)); + int _e91 = idx_2; + int _e95 = idx_2; + float l_s_e_vcv = asfloat(s_sasm.Load(_e95*4+0+0+_e91*16+0)); + int _e100 = idx_2; + int _e103 = idx_2; + float l_s_e_vvc = asfloat(s_sasm.Load(0+_e103*8+0+_e100*16+0)); + int _e109 = idx_2; + int _e112 = idx_2; + int _e114 = idx_2; + float l_s_e_vvv = asfloat(s_sasm.Load(_e114*4+_e112*8+0+_e109*16+0)); + StructWithArrayOfStructOfMat l_u_s_1 = u_sasm; + StructWithMat l_u_a[4] = u_sasm.a; + float2x2 l_u_m_c = GetMatmOnStructWithMat(u_sasm.a[0]); + int _e129 = idx_2; + float2x2 l_u_m_v = GetMatmOnStructWithMat(u_sasm.a[_e129]); + float2 l_u_c_cc = GetMatmOnStructWithMat(u_sasm.a[0])[0]; + int _e143 = idx_2; + float2 l_u_c_cv = GetMatmOnStructWithMat(u_sasm.a[0])[_e143]; + int _e148 = idx_2; + float2 l_u_c_vc = GetMatmOnStructWithMat(u_sasm.a[_e148])[0]; + int _e155 = idx_2; + int _e158 = idx_2; + float2 l_u_c_vv = GetMatmOnStructWithMat(u_sasm.a[_e155])[_e158]; + float l_u_e_ccc = GetMatmOnStructWithMat(u_sasm.a[0])[0].x; + int _e173 = idx_2; + float l_u_e_ccv = GetMatmOnStructWithMat(u_sasm.a[0])[0][_e173]; + int _e180 = idx_2; + float l_u_e_cvc = GetMatmOnStructWithMat(u_sasm.a[0])[_e180].x; + int _e188 = idx_2; + int _e190 = idx_2; + float l_u_e_cvv = GetMatmOnStructWithMat(u_sasm.a[0])[_e188][_e190]; + int _e195 = idx_2; + float l_u_e_vcc = GetMatmOnStructWithMat(u_sasm.a[_e195])[0].x; + int _e203 = idx_2; + int _e207 = idx_2; + float l_u_e_vcv = GetMatmOnStructWithMat(u_sasm.a[_e203])[0][_e207]; + int _e212 = idx_2; + int _e215 = idx_2; + float l_u_e_vvc = GetMatmOnStructWithMat(u_sasm.a[_e212])[_e215].x; + int _e221 = idx_2; + int _e224 = idx_2; + int _e226 = idx_2; + float l_u_e_vvv = GetMatmOnStructWithMat(u_sasm.a[_e221])[_e224][_e226]; + { + StructWithArrayOfStructOfMat _value2 = l_u_s_1; + { + StructWithMat _value3[4] = _value2.a; + { + StructWithMat _value4 = _value3[0]; + { + s_sasm.Store2(0+0+0+0, asuint(_value4.m_0)); + s_sasm.Store2(0+0+0+8, asuint(_value4.m_1)); + } + } + { + StructWithMat _value4 = _value3[1]; + { + s_sasm.Store2(0+16+0+0, asuint(_value4.m_0)); + s_sasm.Store2(0+16+0+8, asuint(_value4.m_1)); + } + } + { + StructWithMat _value4 = _value3[2]; + { + s_sasm.Store2(0+32+0+0, asuint(_value4.m_0)); + s_sasm.Store2(0+32+0+8, asuint(_value4.m_1)); + } + } + { + StructWithMat _value4 = _value3[3]; + { + s_sasm.Store2(0+48+0+0, asuint(_value4.m_0)); + s_sasm.Store2(0+48+0+8, asuint(_value4.m_1)); + } + } + } + } + { + StructWithMat _value2[4] = l_u_a; + { + StructWithMat _value3 = _value2[0]; + { + s_sasm.Store2(0+0+0+0, asuint(_value3.m_0)); + s_sasm.Store2(0+0+0+8, asuint(_value3.m_1)); + } + } + { + StructWithMat _value3 = _value2[1]; + { + s_sasm.Store2(0+16+0+0, asuint(_value3.m_0)); + s_sasm.Store2(0+16+0+8, asuint(_value3.m_1)); + } + } + { + StructWithMat _value3 = _value2[2]; + { + s_sasm.Store2(0+32+0+0, asuint(_value3.m_0)); + s_sasm.Store2(0+32+0+8, asuint(_value3.m_1)); + } + } + { + StructWithMat _value3 = _value2[3]; + { + s_sasm.Store2(0+48+0+0, asuint(_value3.m_0)); + s_sasm.Store2(0+48+0+8, asuint(_value3.m_1)); + } + } + } + { + float2x2 _value2 = l_u_m_c; + s_sasm.Store2(0+0+0+0, asuint(_value2[0])); + s_sasm.Store2(0+0+0+8, asuint(_value2[1])); + } + int _e238 = idx_2; + { + float2x2 _value2 = l_u_m_v; + s_sasm.Store2(0+_e238*16+0+0, asuint(_value2[0])); + s_sasm.Store2(0+_e238*16+0+8, asuint(_value2[1])); + } + s_sasm.Store2(0+0+0+0, asuint(l_u_c_cc)); + int _e250 = idx_2; + s_sasm.Store2(_e250*8+0+0+0, asuint(l_u_c_cv)); + int _e254 = idx_2; + s_sasm.Store2(0+0+_e254*16+0, asuint(l_u_c_vc)); + int _e260 = idx_2; + int _e263 = idx_2; + s_sasm.Store2(_e263*8+0+_e260*16+0, asuint(l_u_c_vv)); + s_sasm.Store(0+0+0+0+0, asuint(l_u_e_ccc)); + int _e276 = idx_2; + s_sasm.Store(_e276*4+0+0+0+0, asuint(l_u_e_ccv)); + int _e282 = idx_2; + s_sasm.Store(0+_e282*8+0+0+0, asuint(l_u_e_cvc)); + int _e289 = idx_2; + int _e291 = idx_2; + s_sasm.Store(_e291*4+_e289*8+0+0+0, asuint(l_u_e_cvv)); + int _e295 = idx_2; + s_sasm.Store(0+0+0+_e295*16+0, asuint(l_u_e_vcc)); + int _e302 = idx_2; + int _e306 = idx_2; + s_sasm.Store(_e306*4+0+0+_e302*16+0, asuint(l_u_e_vcv)); + int _e310 = idx_2; + int _e313 = idx_2; + s_sasm.Store(0+_e313*8+0+_e310*16+0, asuint(l_u_e_vvc)); + int _e318 = idx_2; + int _e321 = idx_2; + int _e323 = idx_2; + s_sasm.Store(_e323*4+_e321*8+0+_e318*16+0, asuint(l_u_e_vvv)); + return; +} + +[numthreads(1, 1, 1)] +void main() +{ + access_m(); + access_sm(); + access_sasm(); + return; +} diff --git a/naga/tests/out/hlsl/wgsl-hlsl_mat_cx2.ron b/naga/tests/out/hlsl/wgsl-hlsl_mat_cx2.ron new file mode 100644 index 00000000000..a07b03300b1 --- /dev/null +++ b/naga/tests/out/hlsl/wgsl-hlsl_mat_cx2.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ], + compute:[ + ( + entry_point:"main", + target_profile:"cs_5_1", + ), + ], +) diff --git a/naga/tests/out/hlsl/wgsl-hlsl_mat_cx3.hlsl b/naga/tests/out/hlsl/wgsl-hlsl_mat_cx3.hlsl new file mode 100644 index 00000000000..f90cdff6e1a --- /dev/null +++ b/naga/tests/out/hlsl/wgsl-hlsl_mat_cx3.hlsl @@ -0,0 +1,350 @@ +struct StructWithMat { + row_major float3x3 m; + int _end_pad_0; +}; + +struct StructWithArrayOfStructOfMat { + StructWithMat a[4]; +}; + +RWByteAddressBuffer s_m : register(u0); +cbuffer u_m : register(b1) { row_major float3x3 u_m; } +RWByteAddressBuffer s_sm : register(u0, space1); +cbuffer u_sm : register(b1, space1) { StructWithMat u_sm; } +RWByteAddressBuffer s_sasm : register(u0, space2); +cbuffer u_sasm : register(b1, space2) { StructWithArrayOfStructOfMat u_sasm; } + +void access_m() +{ + int idx = int(1); + + int _e3 = idx; + idx = asint(asuint(_e3) - asuint(int(1))); + float3x3 l_s_m = float3x3(asfloat(s_m.Load3(0)), asfloat(s_m.Load3(16)), asfloat(s_m.Load3(32))); + float3 l_s_c_c = asfloat(s_m.Load3(0)); + int _e11 = idx; + float3 l_s_c_v = asfloat(s_m.Load3(_e11*16)); + float l_s_e_cc = asfloat(s_m.Load(0+0)); + int _e20 = idx; + float l_s_e_cv = asfloat(s_m.Load(_e20*4+0)); + int _e24 = idx; + float l_s_e_vc = asfloat(s_m.Load(0+_e24*16)); + int _e29 = idx; + int _e31 = idx; + float l_s_e_vv = asfloat(s_m.Load(_e31*4+_e29*16)); + float3x3 l_u_m = u_m; + float3 l_u_c_c = u_m[0]; + int _e40 = idx; + float3 l_u_c_v = u_m[_e40]; + float l_u_e_cc = u_m[0].x; + int _e49 = idx; + float l_u_e_cv = u_m[0][_e49]; + int _e53 = idx; + float l_u_e_vc = u_m[_e53].x; + int _e58 = idx; + int _e60 = idx; + float l_u_e_vv = u_m[_e58][_e60]; + { + float3x3 _value2 = l_u_m; + s_m.Store3(0, asuint(_value2[0])); + s_m.Store3(16, asuint(_value2[1])); + s_m.Store3(32, asuint(_value2[2])); + } + s_m.Store3(0, asuint(l_u_c_c)); + int _e67 = idx; + s_m.Store3(_e67*16, asuint(l_u_c_v)); + s_m.Store(0+0, asuint(l_u_e_cc)); + int _e74 = idx; + s_m.Store(_e74*4+0, asuint(l_u_e_cv)); + int _e77 = idx; + s_m.Store(0+_e77*16, asuint(l_u_e_vc)); + int _e81 = idx; + int _e83 = idx; + s_m.Store(_e83*4+_e81*16, asuint(l_u_e_vv)); + return; +} + +StructWithMat ConstructStructWithMat(float3x3 arg0) { + StructWithMat ret = (StructWithMat)0; + ret.m = arg0; + return ret; +} + +void access_sm() +{ + int idx_1 = int(1); + + int _e3 = idx_1; + idx_1 = asint(asuint(_e3) - asuint(int(1))); + StructWithMat l_s_s = ConstructStructWithMat(float3x3(asfloat(s_sm.Load3(0+0)), asfloat(s_sm.Load3(0+16)), asfloat(s_sm.Load3(0+32)))); + float3x3 l_s_m_1 = float3x3(asfloat(s_sm.Load3(0+0)), asfloat(s_sm.Load3(0+16)), asfloat(s_sm.Load3(0+32))); + float3 l_s_c_c_1 = asfloat(s_sm.Load3(0+0)); + int _e16 = idx_1; + float3 l_s_c_v_1 = asfloat(s_sm.Load3(_e16*16+0)); + float l_s_e_cc_1 = asfloat(s_sm.Load(0+0+0)); + int _e27 = idx_1; + float l_s_e_cv_1 = asfloat(s_sm.Load(_e27*4+0+0)); + int _e32 = idx_1; + float l_s_e_vc_1 = asfloat(s_sm.Load(0+_e32*16+0)); + int _e38 = idx_1; + int _e40 = idx_1; + float l_s_e_vv_1 = asfloat(s_sm.Load(_e40*4+_e38*16+0)); + StructWithMat l_u_s = u_sm; + float3x3 l_u_m_1 = u_sm.m; + float3 l_u_c_c_1 = u_sm.m[0]; + int _e54 = idx_1; + float3 l_u_c_v_1 = u_sm.m[_e54]; + float l_u_e_cc_1 = u_sm.m[0].x; + int _e65 = idx_1; + float l_u_e_cv_1 = u_sm.m[0][_e65]; + int _e70 = idx_1; + float l_u_e_vc_1 = u_sm.m[_e70].x; + int _e76 = idx_1; + int _e78 = idx_1; + float l_u_e_vv_1 = u_sm.m[_e76][_e78]; + { + StructWithMat _value2 = l_u_s; + { + float3x3 _value3 = _value2.m; + s_sm.Store3(0+0, asuint(_value3[0])); + s_sm.Store3(0+16, asuint(_value3[1])); + s_sm.Store3(0+32, asuint(_value3[2])); + } + } + { + float3x3 _value2 = l_u_m_1; + s_sm.Store3(0+0, asuint(_value2[0])); + s_sm.Store3(0+16, asuint(_value2[1])); + s_sm.Store3(0+32, asuint(_value2[2])); + } + s_sm.Store3(0+0, asuint(l_u_c_c_1)); + int _e89 = idx_1; + s_sm.Store3(_e89*16+0, asuint(l_u_c_v_1)); + s_sm.Store(0+0+0, asuint(l_u_e_cc_1)); + int _e98 = idx_1; + s_sm.Store(_e98*4+0+0, asuint(l_u_e_cv_1)); + int _e102 = idx_1; + s_sm.Store(0+_e102*16+0, asuint(l_u_e_vc_1)); + int _e107 = idx_1; + int _e109 = idx_1; + s_sm.Store(_e109*4+_e107*16+0, asuint(l_u_e_vv_1)); + return; +} + +typedef StructWithMat ret_Constructarray4_StructWithMat_[4]; +ret_Constructarray4_StructWithMat_ Constructarray4_StructWithMat_(StructWithMat arg0, StructWithMat arg1, StructWithMat arg2, StructWithMat arg3) { + StructWithMat ret[4] = { arg0, arg1, arg2, arg3 }; + return ret; +} + +StructWithArrayOfStructOfMat ConstructStructWithArrayOfStructOfMat(StructWithMat arg0[4]) { + StructWithArrayOfStructOfMat ret = (StructWithArrayOfStructOfMat)0; + ret.a = arg0; + return ret; +} + +void access_sasm() +{ + int idx_2 = int(1); + + int _e3 = idx_2; + idx_2 = asint(asuint(_e3) - asuint(int(1))); + StructWithArrayOfStructOfMat l_s_s_1 = ConstructStructWithArrayOfStructOfMat(Constructarray4_StructWithMat_(ConstructStructWithMat(float3x3(asfloat(s_sasm.Load3(0+0+0+0)), asfloat(s_sasm.Load3(0+0+0+16)), asfloat(s_sasm.Load3(0+0+0+32)))), ConstructStructWithMat(float3x3(asfloat(s_sasm.Load3(0+48+0+0)), asfloat(s_sasm.Load3(0+48+0+16)), asfloat(s_sasm.Load3(0+48+0+32)))), ConstructStructWithMat(float3x3(asfloat(s_sasm.Load3(0+96+0+0)), asfloat(s_sasm.Load3(0+96+0+16)), asfloat(s_sasm.Load3(0+96+0+32)))), ConstructStructWithMat(float3x3(asfloat(s_sasm.Load3(0+144+0+0)), asfloat(s_sasm.Load3(0+144+0+16)), asfloat(s_sasm.Load3(0+144+0+32)))))); + StructWithMat l_s_a[4] = Constructarray4_StructWithMat_(ConstructStructWithMat(float3x3(asfloat(s_sasm.Load3(0+0+0+0)), asfloat(s_sasm.Load3(0+0+0+16)), asfloat(s_sasm.Load3(0+0+0+32)))), ConstructStructWithMat(float3x3(asfloat(s_sasm.Load3(0+48+0+0)), asfloat(s_sasm.Load3(0+48+0+16)), asfloat(s_sasm.Load3(0+48+0+32)))), ConstructStructWithMat(float3x3(asfloat(s_sasm.Load3(0+96+0+0)), asfloat(s_sasm.Load3(0+96+0+16)), asfloat(s_sasm.Load3(0+96+0+32)))), ConstructStructWithMat(float3x3(asfloat(s_sasm.Load3(0+144+0+0)), asfloat(s_sasm.Load3(0+144+0+16)), asfloat(s_sasm.Load3(0+144+0+32))))); + float3x3 l_s_m_c = float3x3(asfloat(s_sasm.Load3(0+0+0+0)), asfloat(s_sasm.Load3(0+0+0+16)), asfloat(s_sasm.Load3(0+0+0+32))); + int _e17 = idx_2; + float3x3 l_s_m_v = float3x3(asfloat(s_sasm.Load3(0+_e17*48+0+0)), asfloat(s_sasm.Load3(0+_e17*48+0+16)), asfloat(s_sasm.Load3(0+_e17*48+0+32))); + float3 l_s_c_cc = asfloat(s_sasm.Load3(0+0+0+0)); + int _e31 = idx_2; + float3 l_s_c_cv = asfloat(s_sasm.Load3(_e31*16+0+0+0)); + int _e36 = idx_2; + float3 l_s_c_vc = asfloat(s_sasm.Load3(0+0+_e36*48+0)); + int _e43 = idx_2; + int _e46 = idx_2; + float3 l_s_c_vv = asfloat(s_sasm.Load3(_e46*16+0+_e43*48+0)); + float l_s_e_ccc = asfloat(s_sasm.Load(0+0+0+0+0)); + int _e61 = idx_2; + float l_s_e_ccv = asfloat(s_sasm.Load(_e61*4+0+0+0+0)); + int _e68 = idx_2; + float l_s_e_cvc = asfloat(s_sasm.Load(0+_e68*16+0+0+0)); + int _e76 = idx_2; + int _e78 = idx_2; + float l_s_e_cvv = asfloat(s_sasm.Load(_e78*4+_e76*16+0+0+0)); + int _e83 = idx_2; + float l_s_e_vcc = asfloat(s_sasm.Load(0+0+0+_e83*48+0)); + int _e91 = idx_2; + int _e95 = idx_2; + float l_s_e_vcv = asfloat(s_sasm.Load(_e95*4+0+0+_e91*48+0)); + int _e100 = idx_2; + int _e103 = idx_2; + float l_s_e_vvc = asfloat(s_sasm.Load(0+_e103*16+0+_e100*48+0)); + int _e109 = idx_2; + int _e112 = idx_2; + int _e114 = idx_2; + float l_s_e_vvv = asfloat(s_sasm.Load(_e114*4+_e112*16+0+_e109*48+0)); + StructWithArrayOfStructOfMat l_u_s_1 = u_sasm; + StructWithMat l_u_a[4] = u_sasm.a; + float3x3 l_u_m_c = u_sasm.a[0].m; + int _e129 = idx_2; + float3x3 l_u_m_v = u_sasm.a[_e129].m; + float3 l_u_c_cc = u_sasm.a[0].m[0]; + int _e143 = idx_2; + float3 l_u_c_cv = u_sasm.a[0].m[_e143]; + int _e148 = idx_2; + float3 l_u_c_vc = u_sasm.a[_e148].m[0]; + int _e155 = idx_2; + int _e158 = idx_2; + float3 l_u_c_vv = u_sasm.a[_e155].m[_e158]; + float l_u_e_ccc = u_sasm.a[0].m[0].x; + int _e173 = idx_2; + float l_u_e_ccv = u_sasm.a[0].m[0][_e173]; + int _e180 = idx_2; + float l_u_e_cvc = u_sasm.a[0].m[_e180].x; + int _e188 = idx_2; + int _e190 = idx_2; + float l_u_e_cvv = u_sasm.a[0].m[_e188][_e190]; + int _e195 = idx_2; + float l_u_e_vcc = u_sasm.a[_e195].m[0].x; + int _e203 = idx_2; + int _e207 = idx_2; + float l_u_e_vcv = u_sasm.a[_e203].m[0][_e207]; + int _e212 = idx_2; + int _e215 = idx_2; + float l_u_e_vvc = u_sasm.a[_e212].m[_e215].x; + int _e221 = idx_2; + int _e224 = idx_2; + int _e226 = idx_2; + float l_u_e_vvv = u_sasm.a[_e221].m[_e224][_e226]; + { + StructWithArrayOfStructOfMat _value2 = l_u_s_1; + { + StructWithMat _value3[4] = _value2.a; + { + StructWithMat _value4 = _value3[0]; + { + float3x3 _value5 = _value4.m; + s_sasm.Store3(0+0+0+0, asuint(_value5[0])); + s_sasm.Store3(0+0+0+16, asuint(_value5[1])); + s_sasm.Store3(0+0+0+32, asuint(_value5[2])); + } + } + { + StructWithMat _value4 = _value3[1]; + { + float3x3 _value5 = _value4.m; + s_sasm.Store3(0+48+0+0, asuint(_value5[0])); + s_sasm.Store3(0+48+0+16, asuint(_value5[1])); + s_sasm.Store3(0+48+0+32, asuint(_value5[2])); + } + } + { + StructWithMat _value4 = _value3[2]; + { + float3x3 _value5 = _value4.m; + s_sasm.Store3(0+96+0+0, asuint(_value5[0])); + s_sasm.Store3(0+96+0+16, asuint(_value5[1])); + s_sasm.Store3(0+96+0+32, asuint(_value5[2])); + } + } + { + StructWithMat _value4 = _value3[3]; + { + float3x3 _value5 = _value4.m; + s_sasm.Store3(0+144+0+0, asuint(_value5[0])); + s_sasm.Store3(0+144+0+16, asuint(_value5[1])); + s_sasm.Store3(0+144+0+32, asuint(_value5[2])); + } + } + } + } + { + StructWithMat _value2[4] = l_u_a; + { + StructWithMat _value3 = _value2[0]; + { + float3x3 _value4 = _value3.m; + s_sasm.Store3(0+0+0+0, asuint(_value4[0])); + s_sasm.Store3(0+0+0+16, asuint(_value4[1])); + s_sasm.Store3(0+0+0+32, asuint(_value4[2])); + } + } + { + StructWithMat _value3 = _value2[1]; + { + float3x3 _value4 = _value3.m; + s_sasm.Store3(0+48+0+0, asuint(_value4[0])); + s_sasm.Store3(0+48+0+16, asuint(_value4[1])); + s_sasm.Store3(0+48+0+32, asuint(_value4[2])); + } + } + { + StructWithMat _value3 = _value2[2]; + { + float3x3 _value4 = _value3.m; + s_sasm.Store3(0+96+0+0, asuint(_value4[0])); + s_sasm.Store3(0+96+0+16, asuint(_value4[1])); + s_sasm.Store3(0+96+0+32, asuint(_value4[2])); + } + } + { + StructWithMat _value3 = _value2[3]; + { + float3x3 _value4 = _value3.m; + s_sasm.Store3(0+144+0+0, asuint(_value4[0])); + s_sasm.Store3(0+144+0+16, asuint(_value4[1])); + s_sasm.Store3(0+144+0+32, asuint(_value4[2])); + } + } + } + { + float3x3 _value2 = l_u_m_c; + s_sasm.Store3(0+0+0+0, asuint(_value2[0])); + s_sasm.Store3(0+0+0+16, asuint(_value2[1])); + s_sasm.Store3(0+0+0+32, asuint(_value2[2])); + } + int _e238 = idx_2; + { + float3x3 _value2 = l_u_m_v; + s_sasm.Store3(0+_e238*48+0+0, asuint(_value2[0])); + s_sasm.Store3(0+_e238*48+0+16, asuint(_value2[1])); + s_sasm.Store3(0+_e238*48+0+32, asuint(_value2[2])); + } + s_sasm.Store3(0+0+0+0, asuint(l_u_c_cc)); + int _e250 = idx_2; + s_sasm.Store3(_e250*16+0+0+0, asuint(l_u_c_cv)); + int _e254 = idx_2; + s_sasm.Store3(0+0+_e254*48+0, asuint(l_u_c_vc)); + int _e260 = idx_2; + int _e263 = idx_2; + s_sasm.Store3(_e263*16+0+_e260*48+0, asuint(l_u_c_vv)); + s_sasm.Store(0+0+0+0+0, asuint(l_u_e_ccc)); + int _e276 = idx_2; + s_sasm.Store(_e276*4+0+0+0+0, asuint(l_u_e_ccv)); + int _e282 = idx_2; + s_sasm.Store(0+_e282*16+0+0+0, asuint(l_u_e_cvc)); + int _e289 = idx_2; + int _e291 = idx_2; + s_sasm.Store(_e291*4+_e289*16+0+0+0, asuint(l_u_e_cvv)); + int _e295 = idx_2; + s_sasm.Store(0+0+0+_e295*48+0, asuint(l_u_e_vcc)); + int _e302 = idx_2; + int _e306 = idx_2; + s_sasm.Store(_e306*4+0+0+_e302*48+0, asuint(l_u_e_vcv)); + int _e310 = idx_2; + int _e313 = idx_2; + s_sasm.Store(0+_e313*16+0+_e310*48+0, asuint(l_u_e_vvc)); + int _e318 = idx_2; + int _e321 = idx_2; + int _e323 = idx_2; + s_sasm.Store(_e323*4+_e321*16+0+_e318*48+0, asuint(l_u_e_vvv)); + return; +} + +[numthreads(1, 1, 1)] +void main() +{ + access_m(); + access_sm(); + access_sasm(); + return; +} diff --git a/naga/tests/out/hlsl/wgsl-hlsl_mat_cx3.ron b/naga/tests/out/hlsl/wgsl-hlsl_mat_cx3.ron new file mode 100644 index 00000000000..a07b03300b1 --- /dev/null +++ b/naga/tests/out/hlsl/wgsl-hlsl_mat_cx3.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ], + compute:[ + ( + entry_point:"main", + target_profile:"cs_5_1", + ), + ], +) diff --git a/naga/tests/out/spv/wgsl-access.spvasm b/naga/tests/out/spv/wgsl-access.spvasm index 8bbfd03edba..ae6a1d1c5f2 100644 --- a/naga/tests/out/spv/wgsl-access.spvasm +++ b/naga/tests/out/spv/wgsl-access.spvasm @@ -49,6 +49,9 @@ var baz: Baz; var qux: vec2; fn test_matrix_within_struct_accesses() { + // Test HLSL accesses to Cx2 matrices. There are additional tests + // in `hlsl_mat_cx2.wgsl`. + var idx = 1; idx--; @@ -576,91 +579,91 @@ OpDecorate %388 Location 0 %69 = OpAccessChain %68 %56 %48 OpBranch %98 %98 = OpLabel -OpLine %3 40 5 +OpLine %3 43 5 %99 = OpLoad %6 %94 %100 = OpISub %6 %99 %70 -OpLine %3 40 5 +OpLine %3 43 5 OpStore %94 %100 -OpLine %3 43 14 +OpLine %3 46 14 %102 = OpAccessChain %101 %69 %48 %103 = OpLoad %22 %102 -OpLine %3 44 14 -OpLine %3 44 14 +OpLine %3 47 14 +OpLine %3 47 14 %105 = OpAccessChain %104 %69 %48 %48 %106 = OpLoad %13 %105 -OpLine %3 45 14 +OpLine %3 48 14 %107 = OpLoad %6 %94 %108 = OpAccessChain %104 %69 %48 %107 %109 = OpLoad %13 %108 -OpLine %3 46 14 -OpLine %3 46 14 -OpLine %3 46 14 +OpLine %3 49 14 +OpLine %3 49 14 +OpLine %3 49 14 %111 = OpAccessChain %110 %69 %48 %48 %44 %112 = OpLoad %9 %111 -OpLine %3 47 14 -OpLine %3 47 14 +OpLine %3 50 14 +OpLine %3 50 14 %113 = OpLoad %6 %94 %114 = OpAccessChain %110 %69 %48 %48 %113 %115 = OpLoad %9 %114 -OpLine %3 48 14 +OpLine %3 51 14 %116 = OpLoad %6 %94 -OpLine %3 48 14 +OpLine %3 51 14 %117 = OpAccessChain %110 %69 %48 %116 %44 %118 = OpLoad %9 %117 -OpLine %3 49 14 +OpLine %3 52 14 %119 = OpLoad %6 %94 %120 = OpLoad %6 %94 %121 = OpAccessChain %110 %69 %48 %119 %120 %122 = OpLoad %9 %121 -OpLine %3 51 29 -OpLine %3 51 45 -OpLine %3 51 13 -OpLine %3 53 5 +OpLine %3 54 29 +OpLine %3 54 45 +OpLine %3 54 13 +OpLine %3 56 5 %123 = OpLoad %6 %94 %124 = OpIAdd %6 %123 %70 -OpLine %3 53 5 -OpStore %94 %124 -OpLine %3 56 5 -OpLine %3 56 23 -OpLine %3 56 39 -OpLine %3 56 11 OpLine %3 56 5 +OpStore %94 %124 +OpLine %3 59 5 +OpLine %3 59 23 +OpLine %3 59 39 +OpLine %3 59 11 +OpLine %3 59 5 %126 = OpAccessChain %125 %96 %48 OpStore %126 %85 -OpLine %3 57 5 -OpLine %3 57 5 -OpLine %3 57 14 -OpLine %3 57 5 +OpLine %3 60 5 +OpLine %3 60 5 +OpLine %3 60 14 +OpLine %3 60 5 %128 = OpAccessChain %127 %96 %48 %48 OpStore %128 %87 -OpLine %3 58 5 +OpLine %3 61 5 %129 = OpLoad %6 %94 -OpLine %3 58 16 -OpLine %3 58 5 +OpLine %3 61 16 +OpLine %3 61 5 %130 = OpAccessChain %127 %96 %48 %129 OpStore %130 %89 -OpLine %3 59 5 -OpLine %3 59 5 -OpLine %3 59 5 -OpLine %3 59 5 +OpLine %3 62 5 +OpLine %3 62 5 +OpLine %3 62 5 +OpLine %3 62 5 %131 = OpAccessChain %28 %96 %48 %48 %44 OpStore %131 %90 -OpLine %3 60 5 -OpLine %3 60 5 +OpLine %3 63 5 +OpLine %3 63 5 %132 = OpLoad %6 %94 -OpLine %3 60 5 +OpLine %3 63 5 %133 = OpAccessChain %28 %96 %48 %48 %132 OpStore %133 %91 -OpLine %3 61 5 +OpLine %3 64 5 %134 = OpLoad %6 %94 -OpLine %3 61 5 -OpLine %3 61 5 +OpLine %3 64 5 +OpLine %3 64 5 %135 = OpAccessChain %28 %96 %48 %134 %44 OpStore %135 %92 -OpLine %3 62 5 +OpLine %3 65 5 %136 = OpLoad %6 %94 %137 = OpLoad %6 %94 -OpLine %3 62 5 +OpLine %3 65 5 %138 = OpAccessChain %28 %96 %48 %136 %137 OpStore %138 %93 OpReturn @@ -672,111 +675,111 @@ OpFunctionEnd %142 = OpAccessChain %141 %62 %48 OpBranch %153 %153 = OpLabel -OpLine %3 75 5 +OpLine %3 78 5 %154 = OpLoad %6 %150 %155 = OpISub %6 %154 %70 -OpLine %3 75 5 +OpLine %3 78 5 OpStore %150 %155 -OpLine %3 78 14 +OpLine %3 81 14 %157 = OpAccessChain %156 %142 %48 %158 = OpLoad %26 %157 -OpLine %3 79 14 -OpLine %3 79 14 +OpLine %3 82 14 +OpLine %3 82 14 %160 = OpAccessChain %159 %142 %48 %48 %161 = OpLoad %25 %160 -OpLine %3 80 14 -OpLine %3 80 14 -OpLine %3 80 14 +OpLine %3 83 14 +OpLine %3 83 14 +OpLine %3 83 14 %162 = OpAccessChain %104 %142 %48 %48 %48 %163 = OpLoad %13 %162 -OpLine %3 81 14 -OpLine %3 81 14 +OpLine %3 84 14 +OpLine %3 84 14 %164 = OpLoad %6 %150 %165 = OpAccessChain %104 %142 %48 %48 %164 %166 = OpLoad %13 %165 -OpLine %3 82 14 -OpLine %3 82 14 -OpLine %3 82 14 -OpLine %3 82 14 +OpLine %3 85 14 +OpLine %3 85 14 +OpLine %3 85 14 +OpLine %3 85 14 %167 = OpAccessChain %110 %142 %48 %48 %48 %44 %168 = OpLoad %9 %167 -OpLine %3 83 14 -OpLine %3 83 14 -OpLine %3 83 14 +OpLine %3 86 14 +OpLine %3 86 14 +OpLine %3 86 14 %169 = OpLoad %6 %150 %170 = OpAccessChain %110 %142 %48 %48 %48 %169 %171 = OpLoad %9 %170 -OpLine %3 84 14 -OpLine %3 84 14 +OpLine %3 87 14 +OpLine %3 87 14 %172 = OpLoad %6 %150 -OpLine %3 84 14 +OpLine %3 87 14 %173 = OpAccessChain %110 %142 %48 %48 %172 %44 %174 = OpLoad %9 %173 -OpLine %3 85 14 -OpLine %3 85 14 +OpLine %3 88 14 +OpLine %3 88 14 %175 = OpLoad %6 %150 %176 = OpLoad %6 %150 %177 = OpAccessChain %110 %142 %48 %48 %175 %176 %178 = OpLoad %9 %177 -OpLine %3 87 13 -OpLine %3 89 5 +OpLine %3 90 13 +OpLine %3 92 5 %179 = OpLoad %6 %150 %180 = OpIAdd %6 %179 %70 -OpLine %3 89 5 -OpStore %150 %180 -OpLine %3 92 5 OpLine %3 92 5 +OpStore %150 %180 +OpLine %3 95 5 +OpLine %3 95 5 %182 = OpAccessChain %181 %151 %48 OpStore %182 %143 -OpLine %3 93 5 -OpLine %3 93 5 -OpLine %3 93 27 -OpLine %3 93 43 -OpLine %3 93 59 -OpLine %3 93 15 -OpLine %3 93 5 +OpLine %3 96 5 +OpLine %3 96 5 +OpLine %3 96 27 +OpLine %3 96 43 +OpLine %3 96 59 +OpLine %3 96 15 +OpLine %3 96 5 %184 = OpAccessChain %183 %151 %48 %48 OpStore %184 %149 -OpLine %3 94 5 -OpLine %3 94 5 -OpLine %3 94 5 -OpLine %3 94 18 -OpLine %3 94 5 +OpLine %3 97 5 +OpLine %3 97 5 +OpLine %3 97 5 +OpLine %3 97 18 +OpLine %3 97 5 %185 = OpAccessChain %127 %151 %48 %48 %48 OpStore %185 %87 -OpLine %3 95 5 -OpLine %3 95 5 +OpLine %3 98 5 +OpLine %3 98 5 %186 = OpLoad %6 %150 -OpLine %3 95 20 -OpLine %3 95 5 +OpLine %3 98 20 +OpLine %3 98 5 %187 = OpAccessChain %127 %151 %48 %48 %186 OpStore %187 %89 -OpLine %3 96 5 -OpLine %3 96 5 -OpLine %3 96 5 -OpLine %3 96 5 -OpLine %3 96 5 +OpLine %3 99 5 +OpLine %3 99 5 +OpLine %3 99 5 +OpLine %3 99 5 +OpLine %3 99 5 %188 = OpAccessChain %28 %151 %48 %48 %48 %44 OpStore %188 %90 -OpLine %3 97 5 -OpLine %3 97 5 -OpLine %3 97 5 +OpLine %3 100 5 +OpLine %3 100 5 +OpLine %3 100 5 %189 = OpLoad %6 %150 -OpLine %3 97 5 +OpLine %3 100 5 %190 = OpAccessChain %28 %151 %48 %48 %48 %189 OpStore %190 %91 -OpLine %3 98 5 -OpLine %3 98 5 +OpLine %3 101 5 +OpLine %3 101 5 %191 = OpLoad %6 %150 -OpLine %3 98 5 -OpLine %3 98 5 +OpLine %3 101 5 +OpLine %3 101 5 %192 = OpAccessChain %28 %151 %48 %48 %191 %44 OpStore %192 %92 -OpLine %3 99 5 -OpLine %3 99 5 +OpLine %3 102 5 +OpLine %3 102 5 %193 = OpLoad %6 %150 %194 = OpLoad %6 %150 -OpLine %3 99 5 +OpLine %3 102 5 %195 = OpAccessChain %28 %151 %48 %48 %193 %194 OpStore %195 %93 OpReturn @@ -786,7 +789,7 @@ OpFunctionEnd %196 = OpLabel OpBranch %200 %200 = OpLabel -OpLine %3 102 22 +OpLine %3 105 22 %201 = OpLoad %9 %197 OpReturnValue %201 OpFunctionEnd @@ -795,9 +798,9 @@ OpFunctionEnd %202 = OpLabel OpBranch %206 %206 = OpLabel -OpLine %3 107 12 +OpLine %3 110 12 %207 = OpCompositeExtract %29 %203 4 -OpLine %3 107 12 +OpLine %3 110 12 %208 = OpCompositeExtract %9 %207 9 OpReturnValue %208 OpFunctionEnd @@ -806,7 +809,7 @@ OpFunctionEnd %209 = OpLabel OpBranch %214 %214 = OpLabel -OpLine %3 156 5 +OpLine %3 159 5 OpStore %210 %213 OpReturn OpFunctionEnd @@ -815,11 +818,11 @@ OpFunctionEnd %215 = OpLabel OpBranch %222 %222 = OpLabel -OpLine %3 160 32 -OpLine %3 160 43 -OpLine %3 160 32 -OpLine %3 160 12 -OpLine %3 160 5 +OpLine %3 163 32 +OpLine %3 163 43 +OpLine %3 163 32 +OpLine %3 163 12 +OpLine %3 163 5 OpStore %216 %221 OpReturn OpFunctionEnd @@ -829,13 +832,13 @@ OpFunctionEnd %230 = OpVariable %36 Function %228 OpBranch %231 %231 = OpLabel -OpLine %3 165 5 -%232 = OpFunctionCall %2 %211 %229 -OpLine %3 167 35 -OpLine %3 167 46 -OpLine %3 167 35 -OpLine %3 167 15 OpLine %3 168 5 +%232 = OpFunctionCall %2 %211 %229 +OpLine %3 170 35 +OpLine %3 170 46 +OpLine %3 170 35 +OpLine %3 170 15 +OpLine %3 171 5 %233 = OpFunctionCall %2 %217 %230 OpReturn OpFunctionEnd @@ -844,7 +847,7 @@ OpFunctionEnd %234 = OpLabel OpBranch %238 %238 = OpLabel -OpLine %3 176 10 +OpLine %3 179 10 %239 = OpAccessChain %34 %235 %48 %240 = OpLoad %4 %239 OpReturnValue %240 @@ -854,8 +857,8 @@ OpFunctionEnd %241 = OpLabel OpBranch %245 %245 = OpLabel -OpLine %3 180 3 -OpLine %3 180 3 +OpLine %3 183 3 +OpLine %3 183 3 %246 = OpAccessChain %34 %242 %48 OpStore %246 %17 OpReturn @@ -865,7 +868,7 @@ OpFunctionEnd %247 = OpLabel OpBranch %251 %251 = OpLabel -OpLine %3 184 10 +OpLine %3 187 10 %252 = OpAccessChain %34 %248 %44 %253 = OpLoad %4 %252 OpReturnValue %253 @@ -875,8 +878,8 @@ OpFunctionEnd %254 = OpLabel OpBranch %258 %258 = OpLabel -OpLine %3 188 3 -OpLine %3 188 3 +OpLine %3 191 3 +OpLine %3 191 3 %259 = OpAccessChain %34 %255 %44 OpStore %259 %17 OpReturn @@ -887,13 +890,13 @@ OpFunctionEnd %264 = OpVariable %41 Function %265 OpBranch %266 %266 = OpLabel -OpLine %3 193 4 +OpLine %3 196 4 %267 = OpFunctionCall %2 %243 %262 -OpLine %3 194 4 -%268 = OpFunctionCall %4 %236 %262 OpLine %3 197 4 +%268 = OpFunctionCall %4 %236 %262 +OpLine %3 200 4 %269 = OpFunctionCall %2 %256 %264 -OpLine %3 198 4 +OpLine %3 201 4 %270 = OpFunctionCall %4 %249 %264 OpReturn OpFunctionEnd @@ -903,11 +906,11 @@ OpFunctionEnd %275 = OpVariable %276 Function %277 OpBranch %278 %278 = OpLabel -OpLine %3 202 13 +OpLine %3 205 13 %279 = OpCompositeConstruct %43 %272 -OpLine %3 202 5 +OpLine %3 205 5 OpStore %275 %279 -OpLine %3 204 12 +OpLine %3 207 12 %281 = OpAccessChain %280 %275 %48 %282 = OpLoad %42 %281 OpReturnValue %282 @@ -917,8 +920,8 @@ OpFunctionEnd %288 = OpVariable %289 Function %287 OpBranch %290 %290 = OpLabel -OpLine %3 210 16 -OpLine %3 212 12 +OpLine %3 213 16 +OpLine %3 215 12 %291 = OpAccessChain %95 %288 %48 %292 = OpLoad %6 %291 OpReturnValue %292 @@ -927,19 +930,19 @@ OpFunctionEnd %293 = OpLabel OpBranch %296 %296 = OpLabel -OpLine %3 222 17 +OpLine %3 225 17 %297 = OpCompositeExtract %46 %295 0 -OpLine %3 223 20 +OpLine %3 226 20 %298 = OpCompositeExtract %6 %297 0 -OpLine %3 225 9 +OpLine %3 228 9 %299 = OpCompositeExtract %4 %295 1 %300 = OpBitcast %4 %298 %301 = OpINotEqual %42 %299 %300 -OpLine %3 225 5 +OpLine %3 228 5 OpSelectionMerge %302 None OpBranchConditional %301 %302 %302 %302 = OpLabel -OpLine %3 229 12 +OpLine %3 232 12 %303 = OpCompositeExtract %46 %295 0 %304 = OpCompositeExtract %6 %303 0 OpReturnValue %304 @@ -951,27 +954,27 @@ OpFunctionEnd %312 = OpVariable %95 Function %313 OpBranch %314 %314 = OpLabel -OpLine %3 235 17 +OpLine %3 238 17 %315 = OpAccessChain %310 %307 %48 %316 = OpLoad %46 %315 -OpLine %3 235 5 +OpLine %3 238 5 OpStore %309 %316 -OpLine %3 236 20 +OpLine %3 239 20 %317 = OpAccessChain %95 %309 %48 %318 = OpLoad %6 %317 -OpLine %3 236 5 +OpLine %3 239 5 OpStore %312 %318 -OpLine %3 238 9 +OpLine %3 241 9 %319 = OpAccessChain %34 %307 %44 %320 = OpLoad %4 %319 %321 = OpLoad %6 %312 %322 = OpBitcast %4 %321 %323 = OpINotEqual %42 %320 %322 -OpLine %3 238 5 +OpLine %3 241 5 OpSelectionMerge %324 None OpBranchConditional %323 %324 %324 %324 = OpLabel -OpLine %3 242 12 +OpLine %3 245 12 %325 = OpAccessChain %95 %307 %48 %48 %326 = OpLoad %6 %325 OpReturnValue %326 @@ -988,58 +991,58 @@ OpBranch %348 %348 = OpLabel OpLine %3 1 1 %349 = OpLoad %9 %344 -OpLine %3 115 5 +OpLine %3 118 5 OpStore %344 %71 -OpLine %3 117 9 +OpLine %3 120 9 %350 = OpLoad %7 %52 -OpLine %3 118 5 +OpLine %3 121 5 %351 = OpFunctionCall %2 %66 -OpLine %3 119 5 +OpLine %3 122 5 %352 = OpFunctionCall %2 %140 -OpLine %3 122 19 +OpLine %3 125 19 %354 = OpAccessChain %353 %54 %48 %355 = OpLoad %10 %354 -OpLine %3 123 15 +OpLine %3 126 15 %357 = OpAccessChain %356 %54 %40 %358 = OpLoad %19 %357 -OpLine %3 125 13 +OpLine %3 128 13 %361 = OpAccessChain %360 %54 %48 %339 %48 %362 = OpLoad %9 %361 -OpLine %3 126 13 -OpLine %3 126 22 +OpLine %3 129 13 +OpLine %3 129 22 %364 = OpArrayLength %4 %54 5 -OpLine %3 126 13 +OpLine %3 129 13 %365 = OpISub %4 %364 %15 %368 = OpAccessChain %367 %54 %31 %365 %48 %369 = OpLoad %6 %368 -OpLine %3 127 13 +OpLine %3 130 13 %370 = OpLoad %24 %336 -OpLine %3 130 56 -OpLine %3 130 56 -OpLine %3 131 21 +OpLine %3 133 56 +OpLine %3 133 56 +OpLine %3 134 21 %371 = OpFunctionCall %9 %198 %344 -OpLine %3 134 31 +OpLine %3 137 31 %374 = OpExtInst %9 %1 FClamp %362 %372 %373 %375 = OpConvertFToS %6 %374 -OpLine %3 134 14 +OpLine %3 137 14 %376 = OpCompositeConstruct %33 %369 %375 %340 %341 %342 -OpLine %3 134 5 +OpLine %3 137 5 OpStore %345 %376 -OpLine %3 135 5 +OpLine %3 138 5 %377 = OpIAdd %4 %330 %44 -OpLine %3 135 5 +OpLine %3 138 5 %378 = OpAccessChain %95 %345 %377 OpStore %378 %286 -OpLine %3 136 17 +OpLine %3 139 17 %379 = OpAccessChain %95 %345 %330 %380 = OpLoad %6 %379 -OpLine %3 138 5 +OpLine %3 141 5 %381 = OpFunctionCall %9 %204 %343 -OpLine %3 140 22 +OpLine %3 143 22 %383 = OpCompositeConstruct %382 %380 %380 %380 %380 %384 = OpConvertSToF %32 %383 %385 = OpMatrixTimesVector %11 %355 %384 -OpLine %3 140 12 +OpLine %3 143 12 %386 = OpCompositeConstruct %32 %385 %73 OpStore %331 %386 OpReturn @@ -1049,33 +1052,33 @@ OpFunctionEnd %390 = OpAccessChain %335 %59 %48 OpBranch %401 %401 = OpLabel -OpLine %3 146 5 -OpLine %3 146 5 -OpLine %3 146 5 +OpLine %3 149 5 +OpLine %3 149 5 +OpLine %3 149 5 %402 = OpAccessChain %360 %54 %48 %44 %15 OpStore %402 %71 -OpLine %3 147 5 -OpLine %3 147 31 -OpLine %3 147 47 -OpLine %3 147 63 -OpLine %3 147 19 -OpLine %3 147 5 +OpLine %3 150 5 +OpLine %3 150 31 +OpLine %3 150 47 +OpLine %3 150 63 +OpLine %3 150 19 +OpLine %3 150 5 %403 = OpAccessChain %353 %54 %48 OpStore %403 %395 -OpLine %3 148 5 -OpLine %3 148 35 -OpLine %3 148 15 -OpLine %3 148 5 +OpLine %3 151 5 +OpLine %3 151 35 +OpLine %3 151 15 +OpLine %3 151 5 %404 = OpAccessChain %356 %54 %40 OpStore %404 %398 -OpLine %3 149 5 -OpLine %3 149 5 -OpLine %3 149 5 +OpLine %3 152 5 +OpLine %3 152 5 +OpLine %3 152 5 %405 = OpAccessChain %367 %54 %31 %44 %48 OpStore %405 %70 -OpLine %3 150 5 +OpLine %3 153 5 OpStore %390 %399 -OpLine %3 152 12 +OpLine %3 155 12 OpStore %388 %400 OpReturn OpFunctionEnd @@ -1083,17 +1086,17 @@ OpFunctionEnd %406 = OpLabel OpBranch %409 %409 = OpLabel -OpLine %3 247 5 +OpLine %3 250 5 %410 = OpFunctionCall %2 %224 -OpLine %3 248 5 +OpLine %3 251 5 %411 = OpFunctionCall %2 %261 -OpLine %3 249 5 +OpLine %3 252 5 %412 = OpFunctionCall %42 %273 %408 -OpLine %3 250 5 +OpLine %3 253 5 %413 = OpFunctionCall %6 %284 -OpLine %3 251 5 +OpLine %3 254 5 %414 = OpFunctionCall %6 %294 -OpLine %3 252 5 +OpLine %3 255 5 %415 = OpFunctionCall %6 %306 OpReturn OpFunctionEnd \ No newline at end of file From 1b4eca97cf19649cb055cb6dd9582da5d872f7e5 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Tue, 25 Mar 2025 19:09:43 -0700 Subject: [PATCH 017/303] [naga hlsl-out] Factor out some repetitive code --- naga/src/back/hlsl/writer.rs | 358 +++++++++++++++-------------------- 1 file changed, 151 insertions(+), 207 deletions(-) diff --git a/naga/src/back/hlsl/writer.rs b/naga/src/back/hlsl/writer.rs index b06fa534edb..75e890d2724 100644 --- a/naga/src/back/hlsl/writer.rs +++ b/naga/src/back/hlsl/writer.rs @@ -45,6 +45,11 @@ pub(crate) const F2U64_FUNCTION: &str = "naga_f2u64"; pub(crate) const IMAGE_SAMPLE_BASE_CLAMP_TO_EDGE_FUNCTION: &str = "nagaTextureSampleBaseClampToEdge"; +enum Index { + Expression(Handle), + Static(u32), +} + struct EpStructMember { name: String, ty: Handle, @@ -1797,6 +1802,23 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { Ok(()) } + fn write_index( + &mut self, + module: &Module, + index: Index, + func_ctx: &back::FunctionCtx<'_>, + ) -> BackendResult { + match index { + Index::Static(index) => { + write!(self.out, "{index}")?; + } + Index::Expression(index) => { + self.write_expr(module, index, func_ctx)?; + } + } + Ok(()) + } + /// Helper method used to write statements /// /// # Notes @@ -1953,13 +1975,15 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { // // We handle matrix Stores here directly (including sub accesses for Vectors and Scalars). // Loads are handled by `Expression::AccessIndex` (since sub accesses work fine for Loads). - struct MatrixAccess { - base: Handle, - index: u32, - } - enum Index { - Expression(Handle), - Static(u32), + enum MatrixAccess { + Direct { + base: Handle, + index: u32, + }, + Struct { + columns: crate::VectorSize, + base: Handle, + }, } let get_members = |expr: Handle| { @@ -1973,187 +1997,28 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { } }; - let mut matrix = None; - let mut vector = None; - let mut scalar = None; - - let mut current_expr = pointer; - for _ in 0..3 { - let resolved = func_ctx.resolve_type(current_expr, &module.types); - - match (resolved, &func_ctx.expressions[current_expr]) { - ( - &TypeInner::Pointer { base: ty, .. }, - &crate::Expression::AccessIndex { base, index }, - ) if matches!( - module.types[ty].inner, - TypeInner::Matrix { - rows: crate::VectorSize::Bi, - .. - } - ) && get_members(base) - .map(|members| members[index as usize].binding.is_none()) - == Some(true) => - { - matrix = Some(MatrixAccess { base, index }); - break; - } - ( - &TypeInner::ValuePointer { - size: Some(crate::VectorSize::Bi), - .. - }, - &crate::Expression::Access { base, index }, - ) => { - vector = Some(Index::Expression(index)); - current_expr = base; - } - ( - &TypeInner::ValuePointer { - size: Some(crate::VectorSize::Bi), - .. - }, - &crate::Expression::AccessIndex { base, index }, - ) => { - vector = Some(Index::Static(index)); - current_expr = base; - } - ( - &TypeInner::ValuePointer { size: None, .. }, - &crate::Expression::Access { base, index }, - ) => { - scalar = Some(Index::Expression(index)); - current_expr = base; - } - ( - &TypeInner::ValuePointer { size: None, .. }, - &crate::Expression::AccessIndex { base, index }, - ) => { - scalar = Some(Index::Static(index)); - current_expr = base; - } - _ => break, - } - } - write!(self.out, "{level}")?; - if let Some(MatrixAccess { index, base }) = matrix { - let base_ty_res = &func_ctx.info[base].ty; - let resolved = base_ty_res.inner_with(&module.types); - let ty = match *resolved { - TypeInner::Pointer { base, .. } => base, - _ => base_ty_res.handle().unwrap(), - }; - - if let Some(Index::Static(vec_index)) = vector { - self.write_expr(module, base, func_ctx)?; - write!( - self.out, - ".{}_{}", - &self.names[&NameKey::StructMember(ty, index)], - vec_index - )?; - - if let Some(scalar_index) = scalar { - write!(self.out, "[")?; - match scalar_index { - Index::Static(index) => { - write!(self.out, "{index}")?; - } - Index::Expression(index) => { - self.write_expr(module, index, func_ctx)?; - } - } - write!(self.out, "]")?; - } - - write!(self.out, " = ")?; - self.write_expr(module, value, func_ctx)?; - writeln!(self.out, ";")?; - } else { - let access = WrappedStructMatrixAccess { ty, index }; - match (&vector, &scalar) { - (&Some(_), &Some(_)) => { - self.write_wrapped_struct_matrix_set_scalar_function_name( - access, - )?; - } - (&Some(_), &None) => { - self.write_wrapped_struct_matrix_set_vec_function_name(access)?; - } - (&None, _) => { - self.write_wrapped_struct_matrix_set_function_name(access)?; - } - } - - write!(self.out, "(")?; - self.write_expr(module, base, func_ctx)?; - write!(self.out, ", ")?; - self.write_expr(module, value, func_ctx)?; - - if let Some(Index::Expression(vec_index)) = vector { - write!(self.out, ", ")?; - self.write_expr(module, vec_index, func_ctx)?; - - if let Some(scalar_index) = scalar { - write!(self.out, ", ")?; - match scalar_index { - Index::Static(index) => { - write!(self.out, "{index}")?; - } - Index::Expression(index) => { - self.write_expr(module, index, func_ctx)?; - } - } - } - } - writeln!(self.out, ");")?; - } - } else { - // We handle `Store`s to __matCx2 column vectors and scalar elements via - // the previously injected functions __set_col_of_matCx2 / __set_el_of_matCx2. - struct MatrixData { - columns: crate::VectorSize, - base: Handle, - } - - enum Index { - Expression(Handle), - Static(u32), - } - - let mut matrix = None; - let mut vector = None; - let mut scalar = None; - - let mut current_expr = pointer; - for _ in 0..3 { - let resolved = func_ctx.resolve_type(current_expr, &module.types); - match (resolved, &func_ctx.expressions[current_expr]) { - ( - &TypeInner::ValuePointer { - size: Some(crate::VectorSize::Bi), - .. - }, - &crate::Expression::Access { base, index }, - ) => { - vector = Some(index); - current_expr = base; - } - ( - &TypeInner::ValuePointer { size: None, .. }, - &crate::Expression::Access { base, index }, - ) => { - scalar = Some(Index::Expression(index)); - current_expr = base; - } + let matrix_access_on_lhs = + find_matrix_in_access_chain(module, pointer, func_ctx).and_then( + |(matrix_expr, vector, scalar)| match ( + func_ctx.resolve_type(matrix_expr, &module.types), + &func_ctx.expressions[matrix_expr], + ) { ( - &TypeInner::ValuePointer { size: None, .. }, + &TypeInner::Pointer { base: ty, .. }, &crate::Expression::AccessIndex { base, index }, - ) => { - scalar = Some(Index::Static(index)); - current_expr = base; + ) if matches!( + module.types[ty].inner, + TypeInner::Matrix { + rows: crate::VectorSize::Bi, + .. + } + ) && get_members(base) + .map(|members| members[index as usize].binding.is_none()) + == Some(true) => + { + Some((MatrixAccess::Direct { base, index }, vector, scalar)) } _ => { if let Some(MatrixType { @@ -2162,24 +2027,95 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { width: 4, }) = get_inner_matrix_of_struct_array_member( module, - current_expr, + matrix_expr, func_ctx, true, ) { - matrix = Some(MatrixData { - columns, - base: current_expr, - }); + Some(( + MatrixAccess::Struct { + columns, + base: matrix_expr, + }, + vector, + scalar, + )) + } else { + None + } + } + }, + ); + + match matrix_access_on_lhs { + Some((MatrixAccess::Direct { index, base }, vector, scalar)) => { + let base_ty_res = &func_ctx.info[base].ty; + let resolved = base_ty_res.inner_with(&module.types); + let ty = match *resolved { + TypeInner::Pointer { base, .. } => base, + _ => base_ty_res.handle().unwrap(), + }; + + if let Some(Index::Static(vec_index)) = vector { + self.write_expr(module, base, func_ctx)?; + write!( + self.out, + ".{}_{}", + &self.names[&NameKey::StructMember(ty, index)], + vec_index + )?; + + if let Some(scalar_index) = scalar { + write!(self.out, "[")?; + self.write_index(module, scalar_index, func_ctx)?; + write!(self.out, "]")?; + } + + write!(self.out, " = ")?; + self.write_expr(module, value, func_ctx)?; + writeln!(self.out, ";")?; + } else { + let access = WrappedStructMatrixAccess { ty, index }; + match (&vector, &scalar) { + (&Some(_), &Some(_)) => { + self.write_wrapped_struct_matrix_set_scalar_function_name( + access, + )?; + } + (&Some(_), &None) => { + self.write_wrapped_struct_matrix_set_vec_function_name( + access, + )?; + } + (&None, _) => { + self.write_wrapped_struct_matrix_set_function_name(access)?; } + } + + write!(self.out, "(")?; + self.write_expr(module, base, func_ctx)?; + write!(self.out, ", ")?; + self.write_expr(module, value, func_ctx)?; + + if let Some(Index::Expression(vec_index)) = vector { + write!(self.out, ", ")?; + self.write_expr(module, vec_index, func_ctx)?; - break; + if let Some(scalar_index) = scalar { + write!(self.out, ", ")?; + self.write_index(module, scalar_index, func_ctx)?; + } } + writeln!(self.out, ");")?; } } + Some(( + MatrixAccess::Struct { columns, base }, + Some(Index::Expression(vec_index)), + scalar, + )) => { + // We handle `Store`s to __matCx2 column vectors and scalar elements via + // the previously injected functions __set_col_of_matCx2 / __set_el_of_matCx2. - if let (Some(MatrixData { columns, base }), Some(vec_index)) = - (matrix, vector) - { if scalar.is_some() { write!(self.out, "__set_el_of_mat{}x2", columns as u8)?; } else { @@ -2192,21 +2128,17 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { if let Some(scalar_index) = scalar { write!(self.out, ", ")?; - match scalar_index { - Index::Static(index) => { - write!(self.out, "{index}")?; - } - Index::Expression(index) => { - self.write_expr(module, index, func_ctx)?; - } - } + self.write_index(module, scalar_index, func_ctx)?; } write!(self.out, ", ")?; self.write_expr(module, value, func_ctx)?; writeln!(self.out, ");")?; - } else { + } + Some((MatrixAccess::Struct { .. }, Some(Index::Static(_)), _)) + | Some((MatrixAccess::Struct { .. }, None, _)) + | None => { self.write_expr(module, pointer, func_ctx)?; write!(self.out, " = ")?; @@ -4423,12 +4355,17 @@ pub(super) fn get_inner_matrix_data( } } +/// If `base` is an access chain of the form `mat`, `mat[col]`, or `mat[col][row]`, +/// returns a tuple of the matrix, the column (vector) index (if present), and +/// the row (scalar) index (if present). fn find_matrix_in_access_chain( module: &Module, base: Handle, func_ctx: &back::FunctionCtx<'_>, -) -> Option> { +) -> Option<(Handle, Option, Option)> { let mut current_base = base; + let mut vector = None; + let mut scalar = None; loop { let resolved_tr = func_ctx .resolve_type(current_base, &module.types) @@ -4436,15 +4373,22 @@ fn find_matrix_in_access_chain( let resolved = resolved_tr.as_ref()?.inner_with(&module.types); match *resolved { + TypeInner::Matrix { .. } => return Some((current_base, vector, scalar)), TypeInner::Scalar(_) | TypeInner::Vector { .. } => {} - TypeInner::Matrix { .. } => return Some(current_base), _ => return None, } - current_base = match func_ctx.expressions[current_base] { - crate::Expression::Access { base, .. } => base, - crate::Expression::AccessIndex { base, .. } => base, + let index; + (current_base, index) = match func_ctx.expressions[current_base] { + crate::Expression::Access { base, index } => (base, Index::Expression(index)), + crate::Expression::AccessIndex { base, index } => (base, Index::Static(index)), _ => return None, + }; + + match *resolved { + TypeInner::Scalar(_) => scalar = Some(index), + TypeInner::Vector { .. } => vector = Some(index), + _ => unreachable!(), } } } From c51fe577dc29fed7d785daee8f4a2fca427012ff Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Sat, 12 Jul 2025 22:04:19 -0700 Subject: [PATCH 018/303] Improve docs for `wgpu_types::InstanceFlags::VALIDATION`. (#7939) --- wgpu-types/src/instance.rs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/wgpu-types/src/instance.rs b/wgpu-types/src/instance.rs index 59426912396..4bafabb5fba 100644 --- a/wgpu-types/src/instance.rs +++ b/wgpu-types/src/instance.rs @@ -70,9 +70,29 @@ bitflags::bitflags! { /// /// When `Self::from_env()` is used takes value from `WGPU_DEBUG` environment variable. const DEBUG = 1 << 0; - /// Enable validation, if possible. + /// Enable validation in the backend API, if possible: /// - /// When `Self::from_env()` is used takes value from `WGPU_VALIDATION` environment variable. + /// - On the Direct3D `dx12` backend, this calls [`ID3D12Debug::EnableDebugLayer`][dx12]. + /// + /// - On the Vulkan backend, this enables the [Vulkan Validation Layer][vvl]. + /// + /// - On the `gles` backend driving Windows OpenGL, this enables [debug + /// output][gl:do], effectively calling `glEnable(GL_DEBUG_OUTPUT)`. + /// + /// - On non-Windows `gles` backends, this calls + /// [`eglDebugMessageControlKHR`][gl:dm] to enable all debugging messages. + /// If the GLES implementation is ANGLE running on Vulkan, this also + /// enables the Vulkan validation layers by setting + /// [`EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED`][gl:av]. + /// + /// When `Self::from_env()` is used, this bit is set if the `WGPU_VALIDATION` + /// environment variable has any value but "0". + /// + /// [dx12]: https://learn.microsoft.com/en-us/windows/win32/api/d3d12sdklayers/nf-d3d12sdklayers-id3d12debug-enabledebuglayer + /// [vvl]: https://github.com/KhronosGroup/Vulkan-ValidationLayers + /// [gl:dm]: https://registry.khronos.org/EGL/extensions/KHR/EGL_KHR_debug.txt + /// [gl:do]: https://www.khronos.org/opengl/wiki/Debug_Output + /// [gl:av]: https://chromium.googlesource.com/angle/angle/+/HEAD/extensions/EGL_ANGLE_platform_angle.txt const VALIDATION = 1 << 1; /// Don't pass labels to wgpu-hal. /// From 9872df55d7ec86c4f87e29116197ce9ed0388b14 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 14 Jul 2025 02:50:23 -0400 Subject: [PATCH 019/303] Update cts digest to 6e9d87b (#7941) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- cts_runner/revision.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cts_runner/revision.txt b/cts_runner/revision.txt index 0cf30d50a8a..c89d0b9012a 100644 --- a/cts_runner/revision.txt +++ b/cts_runner/revision.txt @@ -1 +1 @@ -18fcd81fcd695192e7ec128125a2bc267a472153 +6e9d87b9465e74a1d52e954d396a3109100e19a9 From 4572e05bfad91c279752d8ba43604b9e6ab032c1 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Mon, 14 Jul 2025 12:48:49 -0400 Subject: [PATCH 020/303] ci: add coverage for cts (#7942) --- .github/workflows/cts.yml | 29 +++++++++++++++++++++++++---- xtask/src/cts.rs | 9 ++++++++- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cts.yml b/.github/workflows/cts.yml index 418a46c986b..2bc0680cb29 100644 --- a/.github/workflows/cts.yml +++ b/.github/workflows/cts.yml @@ -43,10 +43,15 @@ jobs: - name: Install Repo MSRV toolchain run: | - rustup toolchain install ${{ env.MSRV }} --no-self-update --profile=minimal --target ${{ matrix.target }} + rustup toolchain install ${{ env.MSRV }} --no-self-update --profile=minimal --target ${{ matrix.target }} --component llvm-tools rustup override set ${{ env.MSRV }} cargo -V + - name: Install `cargo-llvm-cov` + uses: taiki-e/install-action@v2 + with: + tool: cargo-llvm-cov + - name: caching uses: Swatinem/rust-cache@v2 with: @@ -60,7 +65,7 @@ jobs: mkdir -p .cargo cat <> .cargo/config.toml [profile.dev] - debug = 1 + debug = "line-tables-only" EOF - name: (Windows) Install DXC @@ -71,7 +76,7 @@ jobs: if: matrix.os == 'windows-2022' uses: ./.github/actions/install-warp with: - target-dirs: "target/debug" + target-dirs: "target/llvm-cov-target/debug" - name: (Linux) Install Mesa if: matrix.os == 'ubuntu-24.04' @@ -79,4 +84,20 @@ jobs: - name: run CTS shell: bash - run: cargo xtask cts + run: cargo xtask cts --llvm-cov + + - name: Generate coverage report + id: coverage + shell: bash + continue-on-error: true + run: | + set -e + + cargo llvm-cov report --lcov --output-path lcov.info + + - name: Upload coverage report to Codecov + uses: codecov/codecov-action@v5 + if: steps.coverage.outcome == 'success' + with: + files: lcov.info + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/xtask/src/cts.rs b/xtask/src/cts.rs index 9128181d614..ff3a6cbe8f1 100644 --- a/xtask/src/cts.rs +++ b/xtask/src/cts.rs @@ -17,6 +17,7 @@ const CTS_DEFAULT_TEST_LIST: &str = "cts_runner/test.lst"; pub fn run_cts(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { let skip_checkout = args.contains("--skip-checkout"); + let llvm_cov = args.contains("--llvm-cov"); let mut list_files = Vec::::new(); while let Some(file) = args.opt_value_from_str("-f")? { @@ -133,12 +134,18 @@ pub fn run_cts(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { log::info!("Skipping CTS checkout because --skip-checkout was specified"); } + let run_flags = if llvm_cov { + &["llvm-cov", "--no-cfg-coverage", "--no-report", "run"][..] + } else { + &["run"][..] + }; + log::info!("Running CTS"); for test in &tests { log::info!("Running {}", test.to_string_lossy()); shell .cmd("cargo") - .args(["run"]) + .args(run_flags) .args(["--manifest-path".as_ref(), wgpu_cargo_toml.as_os_str()]) .args(["-p", "cts_runner"]) .args(["--bin", "cts_runner"]) From dd50e56c59879d83d7721b2f4c5fde427aaa503a Mon Sep 17 00:00:00 2001 From: SupaMaggie70Incorporated <85136135+SupaMaggie70Incorporated@users.noreply.github.com> Date: Mon, 14 Jul 2025 21:51:31 -0700 Subject: [PATCH 021/303] Update rspirv version (#7945) --- Cargo.lock | 17 ++---- Cargo.toml | 2 +- .../spv/wgsl-6438-conflicting-idents.spvasm | 4 +- .../spv/wgsl-7048-multiple-dynamic-1.spvasm | 2 +- .../spv/wgsl-7048-multiple-dynamic-2.spvasm | 2 +- .../spv/wgsl-7048-multiple-dynamic-3.spvasm | 2 +- .../spv/wgsl-abstract-types-builtins.spvasm | 2 +- .../out/spv/wgsl-abstract-types-const.spvasm | 18 +++---- .../wgsl-abstract-types-function-calls.spvasm | 2 +- .../out/spv/wgsl-abstract-types-let.spvasm | 18 +++---- .../spv/wgsl-abstract-types-operators.spvasm | 14 ++--- .../out/spv/wgsl-abstract-types-return.spvasm | 2 +- .../out/spv/wgsl-abstract-types-var.spvasm | 18 +++---- naga/tests/out/spv/wgsl-access.spvasm | 34 ++++++------ .../out/spv/wgsl-aliased-ray-query.spvasm | 10 ++-- .../wgsl-array-in-function-return-type.spvasm | 6 +-- .../out/spv/wgsl-atomicCompareExchange.spvasm | 2 +- naga/tests/out/spv/wgsl-binding-arrays.spvasm | 2 +- naga/tests/out/spv/wgsl-bitcast.spvasm | 2 +- naga/tests/out/spv/wgsl-bits.spvasm | 2 +- naga/tests/out/spv/wgsl-boids.spvasm | 6 +-- ...l-bounds-check-image-restrict-depth.spvasm | 2 +- .../wgsl-bounds-check-image-restrict.spvasm | 2 +- .../wgsl-bounds-check-image-rzsw-depth.spvasm | 2 +- .../spv/wgsl-bounds-check-image-rzsw.spvasm | 2 +- .../out/spv/wgsl-bounds-check-restrict.spvasm | 16 +++--- .../out/spv/wgsl-bounds-check-zero.spvasm | 16 +++--- naga/tests/out/spv/wgsl-const-exprs.spvasm | 10 ++-- naga/tests/out/spv/wgsl-constructors.spvasm | 8 +-- .../spv/wgsl-conversion-float-to-int.spvasm | 54 +++++++++---------- naga/tests/out/spv/wgsl-conversions.spvasm | 2 +- naga/tests/out/spv/wgsl-cross.spvasm | 4 +- .../spv/wgsl-debug-symbol-large-source.spvasm | 28 +++++----- .../out/spv/wgsl-debug-symbol-simple.spvasm | 2 +- .../out/spv/wgsl-debug-symbol-terrain.spvasm | 28 +++++----- naga/tests/out/spv/wgsl-extra.spvasm | 2 +- naga/tests/out/spv/wgsl-f16.spvasm | 14 ++--- naga/tests/out/spv/wgsl-f64.spvasm | 14 ++--- .../tests/out/spv/wgsl-fragment-output.spvasm | 2 +- ...l-functions-optimized-by-capability.spvasm | 12 ++--- ...wgsl-functions-optimized-by-version.spvasm | 12 ++--- naga/tests/out/spv/wgsl-functions.spvasm | 14 ++--- naga/tests/out/spv/wgsl-globals.spvasm | 8 +-- naga/tests/out/spv/wgsl-image.spvasm | 8 +-- naga/tests/out/spv/wgsl-index-by-value.spvasm | 8 +-- naga/tests/out/spv/wgsl-int64.spvasm | 8 +-- .../out/spv/wgsl-interface.fragment.spvasm | 4 +- .../out/spv/wgsl-interface.vertex.spvasm | 2 +- .../wgsl-interface.vertex_two_structs.spvasm | 4 +- naga/tests/out/spv/wgsl-interpolate.spvasm | 42 +++++++-------- .../out/spv/wgsl-interpolate_compat.spvasm | 42 +++++++-------- naga/tests/out/spv/wgsl-math-functions.spvasm | 8 +-- naga/tests/out/spv/wgsl-operators.spvasm | 12 ++--- .../spv/wgsl-overrides-ray-query.main.spvasm | 16 +++--- naga/tests/out/spv/wgsl-overrides.main.spvasm | 10 ++-- naga/tests/out/spv/wgsl-padding.spvasm | 2 +- naga/tests/out/spv/wgsl-pointers.spvasm | 2 +- naga/tests/out/spv/wgsl-policy-mix.spvasm | 4 +- naga/tests/out/spv/wgsl-quad.spvasm | 4 +- naga/tests/out/spv/wgsl-ray-query.spvasm | 10 ++-- naga/tests/out/spv/wgsl-select.spvasm | 4 +- ...wgsl-separate-entry-points.fragment.spvasm | 2 +- naga/tests/out/spv/wgsl-shadow.spvasm | 4 +- naga/tests/out/spv/wgsl-skybox.spvasm | 6 +-- .../out/spv/wgsl-storage-textures.spvasm | 2 +- naga/tests/out/spv/wgsl-struct-layout.spvasm | 2 +- naga/tests/out/spv/wgsl-texture-arg.spvasm | 2 +- naga/tests/out/spv/wgsl-type-inference.spvasm | 4 +- 68 files changed, 313 insertions(+), 320 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7681964afa8..64c090b97ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2505,7 +2505,7 @@ dependencies = [ "rspirv", "rustc-hash", "serde", - "spirv 0.3.0+sdk-1.3.268.0", + "spirv", "strum 0.27.1", "thiserror 2.0.12", "toml", @@ -3549,11 +3549,12 @@ dependencies = [ [[package]] name = "rspirv" -version = "0.11.0+sdk-1.2.198" -source = "git+https://github.com/gfx-rs/rspirv?rev=b969f175d5663258b4891e44b76c1544da9661ab#b969f175d5663258b4891e44b76c1544da9661ab" +version = "0.12.0+sdk-1.3.268.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cf3a93856b6e5946537278df0d3075596371b1950ccff012f02b0f7eafec8d" dependencies = [ "rustc-hash", - "spirv 0.2.0+sdk-1.2.198", + "spirv", ] [[package]] @@ -3932,14 +3933,6 @@ dependencies = [ "lock_api", ] -[[package]] -name = "spirv" -version = "0.2.0+sdk-1.2.198" -source = "git+https://github.com/gfx-rs/rspirv?rev=b969f175d5663258b4891e44b76c1544da9661ab#b969f175d5663258b4891e44b76c1544da9661ab" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "spirv" version = "0.3.0+sdk-1.3.268.0" diff --git a/Cargo.toml b/Cargo.toml index 7083e33a12c..ca7f4121e2c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -169,7 +169,7 @@ rwh_05 = { version = "0.5.2", package = "raw-window-handle" } # temporary compat rayon = "1.3" regex-lite = "0.1" renderdoc-sys = "1" -rspirv = { version = "0.11", git = "https://github.com/gfx-rs/rspirv", rev = "b969f175d5663258b4891e44b76c1544da9661ab" } +rspirv = "0.12" ron = "0.10" # NOTE: rustc-hash v2 is a completely different hasher with different performance characteristics # see discussion here (including with some other alternatives): https://github.com/gfx-rs/wgpu/issues/6999 diff --git a/naga/tests/out/spv/wgsl-6438-conflicting-idents.spvasm b/naga/tests/out/spv/wgsl-6438-conflicting-idents.spvasm index 589eeb34624..be4ca450115 100644 --- a/naga/tests/out/spv/wgsl-6438-conflicting-idents.spvasm +++ b/naga/tests/out/spv/wgsl-6438-conflicting-idents.spvasm @@ -26,8 +26,8 @@ OpDecorate %32 Location 0 %14 = OpTypePointer Output %5 %13 = OpVariable %14 Output %16 = OpTypeFunction %2 -%17 = OpConstant %4 0.0 -%18 = OpConstant %4 1.0 +%17 = OpConstant %4 0 +%18 = OpConstant %4 1 %20 = OpTypePointer Function %6 %21 = OpConstantNull %6 %23 = OpTypePointer Function %3 diff --git a/naga/tests/out/spv/wgsl-7048-multiple-dynamic-1.spvasm b/naga/tests/out/spv/wgsl-7048-multiple-dynamic-1.spvasm index ad042682297..dd87117cfc4 100644 --- a/naga/tests/out/spv/wgsl-7048-multiple-dynamic-1.spvasm +++ b/naga/tests/out/spv/wgsl-7048-multiple-dynamic-1.spvasm @@ -18,7 +18,7 @@ OpDecorate %5 ArrayStride 16 %9 = OpTypeInt 32 1 %12 = OpTypeFunction %2 %13 = OpConstantNull %5 -%14 = OpConstant %4 0.0 +%14 = OpConstant %4 0 %15 = OpConstantComposite %8 %14 %14 %14 %14 %16 = OpConstant %9 0 %18 = OpTypePointer Function %8 diff --git a/naga/tests/out/spv/wgsl-7048-multiple-dynamic-2.spvasm b/naga/tests/out/spv/wgsl-7048-multiple-dynamic-2.spvasm index 504bd8f4eb3..1eba8a12a5e 100644 --- a/naga/tests/out/spv/wgsl-7048-multiple-dynamic-2.spvasm +++ b/naga/tests/out/spv/wgsl-7048-multiple-dynamic-2.spvasm @@ -20,7 +20,7 @@ OpDecorate %11 Location 0 %12 = OpTypePointer Output %3 %11 = OpVariable %12 Output %14 = OpTypeFunction %2 -%15 = OpConstant %4 0.0 +%15 = OpConstant %4 0 %16 = OpConstantComposite %5 %15 %15 %17 = OpConstantComposite %6 %16 %16 %18 = OpConstant %9 0 diff --git a/naga/tests/out/spv/wgsl-7048-multiple-dynamic-3.spvasm b/naga/tests/out/spv/wgsl-7048-multiple-dynamic-3.spvasm index d11c182d519..2e4ab1e1aef 100644 --- a/naga/tests/out/spv/wgsl-7048-multiple-dynamic-3.spvasm +++ b/naga/tests/out/spv/wgsl-7048-multiple-dynamic-3.spvasm @@ -20,7 +20,7 @@ OpDecorate %6 ArrayStride 16 %13 = OpTypeFunction %5 %6 %8 %14 = OpConstant %8 0 %15 = OpConstant %8 1 -%16 = OpConstant %3 0.0 +%16 = OpConstant %3 0 %17 = OpConstantComposite %4 %16 %16 %16 %18 = OpConstantComposite %5 %16 %17 %20 = OpTypePointer Function %8 diff --git a/naga/tests/out/spv/wgsl-abstract-types-builtins.spvasm b/naga/tests/out/spv/wgsl-abstract-types-builtins.spvasm index 83ef259cba5..0601a126b1b 100644 --- a/naga/tests/out/spv/wgsl-abstract-types-builtins.spvasm +++ b/naga/tests/out/spv/wgsl-abstract-types-builtins.spvasm @@ -12,7 +12,7 @@ OpExecutionMode %6 LocalSize 1 1 1 %4 = OpTypeFloat 32 %7 = OpTypeFunction %2 %8 = OpConstant %3 1 -%9 = OpConstant %4 1.0 +%9 = OpConstant %4 1 %11 = OpTypePointer Function %3 %13 = OpTypePointer Function %4 %6 = OpFunction %2 None %7 diff --git a/naga/tests/out/spv/wgsl-abstract-types-const.spvasm b/naga/tests/out/spv/wgsl-abstract-types-const.spvasm index b1da55273f5..b1dd0dc374e 100644 --- a/naga/tests/out/spv/wgsl-abstract-types-const.spvasm +++ b/naga/tests/out/spv/wgsl-abstract-types-const.spvasm @@ -32,11 +32,11 @@ OpMemberDecorate %14 2 Offset 8 %19 = OpConstant %5 44 %20 = OpConstant %5 45 %21 = OpConstantComposite %6 %19 %20 -%22 = OpConstant %7 46.0 -%23 = OpConstant %7 47.0 +%22 = OpConstant %7 46 +%23 = OpConstant %7 47 %24 = OpConstantComposite %8 %22 %23 -%25 = OpConstant %7 48.0 -%26 = OpConstant %7 49.0 +%25 = OpConstant %7 48 +%26 = OpConstant %7 49 %27 = OpConstantComposite %8 %25 %26 %28 = OpConstant %5 42 %29 = OpConstant %5 43 @@ -45,14 +45,14 @@ OpMemberDecorate %14 2 Offset 8 %32 = OpConstantComposite %4 %31 %31 %33 = OpConstant %5 0 %34 = OpConstantComposite %6 %33 %33 -%35 = OpConstant %7 0.0 +%35 = OpConstant %7 0 %36 = OpConstantComposite %8 %35 %35 %37 = OpConstantComposite %9 %36 %36 -%38 = OpConstant %7 1.0 -%39 = OpConstant %7 2.0 +%38 = OpConstant %7 1 +%39 = OpConstant %7 2 %40 = OpConstantComposite %8 %38 %39 -%41 = OpConstant %7 3.0 -%42 = OpConstant %7 4.0 +%41 = OpConstant %7 3 +%42 = OpConstant %7 4 %43 = OpConstantComposite %8 %41 %42 %44 = OpConstantComposite %9 %40 %43 %45 = OpConstant %3 1 diff --git a/naga/tests/out/spv/wgsl-abstract-types-function-calls.spvasm b/naga/tests/out/spv/wgsl-abstract-types-function-calls.spvasm index 81b0a5e44c5..40931665253 100644 --- a/naga/tests/out/spv/wgsl-abstract-types-function-calls.spvasm +++ b/naga/tests/out/spv/wgsl-abstract-types-function-calls.spvasm @@ -34,7 +34,7 @@ OpDecorate %13 ArrayStride 4 %62 = OpTypeFunction %2 %13 %68 = OpTypeFunction %2 %3 %4 %72 = OpTypeFunction %2 -%73 = OpConstant %3 0.0 +%73 = OpConstant %3 0 %74 = OpConstant %4 0 %75 = OpConstant %5 0 %76 = OpConstantComposite %6 %73 %73 diff --git a/naga/tests/out/spv/wgsl-abstract-types-let.spvasm b/naga/tests/out/spv/wgsl-abstract-types-let.spvasm index f0b7ea3c4f3..c9394ebaf4c 100644 --- a/naga/tests/out/spv/wgsl-abstract-types-let.spvasm +++ b/naga/tests/out/spv/wgsl-abstract-types-let.spvasm @@ -34,11 +34,11 @@ OpDecorate %17 ArrayStride 16 %24 = OpConstant %5 44 %25 = OpConstant %5 45 %26 = OpConstantComposite %6 %24 %25 -%27 = OpConstant %7 46.0 -%28 = OpConstant %7 47.0 +%27 = OpConstant %7 46 +%28 = OpConstant %7 47 %29 = OpConstantComposite %8 %27 %28 -%30 = OpConstant %7 48.0 -%31 = OpConstant %7 49.0 +%30 = OpConstant %7 48 +%31 = OpConstant %7 49 %32 = OpConstantComposite %8 %30 %31 %33 = OpConstant %5 42 %34 = OpConstant %5 43 @@ -47,14 +47,14 @@ OpDecorate %17 ArrayStride 16 %37 = OpConstantComposite %4 %36 %36 %38 = OpConstant %5 0 %39 = OpConstantComposite %6 %38 %38 -%40 = OpConstant %7 0.0 +%40 = OpConstant %7 0 %41 = OpConstantComposite %8 %40 %40 %42 = OpConstantComposite %9 %41 %41 -%43 = OpConstant %7 1.0 -%44 = OpConstant %7 2.0 +%43 = OpConstant %7 1 +%44 = OpConstant %7 2 %45 = OpConstantComposite %8 %43 %44 -%46 = OpConstant %7 3.0 -%47 = OpConstant %7 4.0 +%46 = OpConstant %7 3 +%47 = OpConstant %7 4 %48 = OpConstantComposite %8 %46 %47 %49 = OpConstantComposite %9 %45 %48 %50 = OpConstant %3 1 diff --git a/naga/tests/out/spv/wgsl-abstract-types-operators.spvasm b/naga/tests/out/spv/wgsl-abstract-types-operators.spvasm index c37f96d92bf..4ce80049d24 100644 --- a/naga/tests/out/spv/wgsl-abstract-types-operators.spvasm +++ b/naga/tests/out/spv/wgsl-abstract-types-operators.spvasm @@ -15,23 +15,23 @@ OpDecorate %116 BuiltIn LocalInvocationId %5 = OpTypeInt 32 0 %7 = OpConstant %5 64 %6 = OpTypeArray %5 %7 -%8 = OpConstant %3 3.0 +%8 = OpConstant %3 3 %9 = OpConstant %4 3 %10 = OpConstant %5 3 %11 = OpConstant %5 0 %12 = OpConstant %4 -2147483648 -%13 = OpConstant %3 -3.4028235e38 +%13 = OpConstant %3 -340282350000000000000000000000000000000 %14 = OpConstant %4 4 %15 = OpConstant %5 4 %16 = OpConstant %4 0 %18 = OpTypePointer Workgroup %6 %17 = OpVariable %18 Workgroup %21 = OpTypeFunction %2 -%22 = OpConstant %3 42.0 +%22 = OpConstant %3 42 %23 = OpConstant %4 43 %24 = OpConstant %5 44 -%25 = OpConstant %3 1.0 -%26 = OpConstant %3 2.0 +%25 = OpConstant %3 1 +%26 = OpConstant %3 2 %27 = OpConstant %4 1 %28 = OpConstant %4 2 %29 = OpConstant %5 1 @@ -52,8 +52,8 @@ OpDecorate %116 BuiltIn LocalInvocationId %64 = OpConstantNull %5 %66 = OpConstantNull %4 %68 = OpConstantNull %4 -%101 = OpConstant %3 5.0 -%102 = OpConstant %3 7.0 +%101 = OpConstant %3 5 +%102 = OpConstant %3 7 %108 = OpTypePointer Workgroup %5 %114 = OpConstantNull %6 %115 = OpTypeVector %5 3 diff --git a/naga/tests/out/spv/wgsl-abstract-types-return.spvasm b/naga/tests/out/spv/wgsl-abstract-types-return.spvasm index 48c1b155668..d2dc2cfed43 100644 --- a/naga/tests/out/spv/wgsl-abstract-types-return.spvasm +++ b/naga/tests/out/spv/wgsl-abstract-types-return.spvasm @@ -20,7 +20,7 @@ OpDecorate %7 ArrayStride 4 %16 = OpTypeFunction %4 %17 = OpConstant %4 1 %21 = OpTypeFunction %5 -%22 = OpConstant %5 1.0 +%22 = OpConstant %5 1 %29 = OpTypeFunction %6 %30 = OpConstantComposite %6 %22 %22 %34 = OpTypeFunction %7 diff --git a/naga/tests/out/spv/wgsl-abstract-types-var.spvasm b/naga/tests/out/spv/wgsl-abstract-types-var.spvasm index de7b74dae48..8dc36f0fb5f 100644 --- a/naga/tests/out/spv/wgsl-abstract-types-var.spvasm +++ b/naga/tests/out/spv/wgsl-abstract-types-var.spvasm @@ -35,11 +35,11 @@ OpDecorate %18 ArrayStride 16 %22 = OpConstant %5 44 %23 = OpConstant %5 45 %24 = OpConstantComposite %6 %22 %23 -%25 = OpConstant %7 46.0 -%26 = OpConstant %7 47.0 +%25 = OpConstant %7 46 +%26 = OpConstant %7 47 %27 = OpConstantComposite %8 %25 %26 -%28 = OpConstant %7 48.0 -%29 = OpConstant %7 49.0 +%28 = OpConstant %7 48 +%29 = OpConstant %7 49 %30 = OpConstantComposite %8 %28 %29 %31 = OpConstant %5 42 %32 = OpConstant %5 43 @@ -48,14 +48,14 @@ OpDecorate %18 ArrayStride 16 %35 = OpConstantComposite %4 %34 %34 %36 = OpConstant %5 0 %37 = OpConstantComposite %6 %36 %36 -%38 = OpConstant %7 0.0 +%38 = OpConstant %7 0 %39 = OpConstantComposite %8 %38 %38 %40 = OpConstantComposite %9 %39 %39 -%41 = OpConstant %7 1.0 -%42 = OpConstant %7 2.0 +%41 = OpConstant %7 1 +%42 = OpConstant %7 2 %43 = OpConstantComposite %8 %41 %42 -%44 = OpConstant %7 3.0 -%45 = OpConstant %7 4.0 +%44 = OpConstant %7 3 +%45 = OpConstant %7 4 %46 = OpConstantComposite %8 %44 %45 %47 = OpConstantComposite %9 %43 %46 %48 = OpConstant %3 1 diff --git a/naga/tests/out/spv/wgsl-access.spvasm b/naga/tests/out/spv/wgsl-access.spvasm index ae6a1d1c5f2..78d263d5fc6 100644 --- a/naga/tests/out/spv/wgsl-access.spvasm +++ b/naga/tests/out/spv/wgsl-access.spvasm @@ -463,29 +463,29 @@ OpDecorate %388 Location 0 %67 = OpTypeFunction %2 %68 = OpTypePointer Uniform %23 %70 = OpConstant %6 1 -%71 = OpConstant %9 1.0 +%71 = OpConstant %9 1 %72 = OpConstantComposite %13 %71 %71 -%73 = OpConstant %9 2.0 +%73 = OpConstant %9 2 %74 = OpConstantComposite %13 %73 %73 -%75 = OpConstant %9 3.0 +%75 = OpConstant %9 3 %76 = OpConstantComposite %13 %75 %75 %77 = OpConstantComposite %22 %72 %74 %76 %78 = OpConstantComposite %23 %77 -%79 = OpConstant %9 6.0 +%79 = OpConstant %9 6 %80 = OpConstantComposite %13 %79 %79 -%81 = OpConstant %9 5.0 +%81 = OpConstant %9 5 %82 = OpConstantComposite %13 %81 %81 -%83 = OpConstant %9 4.0 +%83 = OpConstant %9 4 %84 = OpConstantComposite %13 %83 %83 %85 = OpConstantComposite %22 %80 %82 %84 -%86 = OpConstant %9 9.0 +%86 = OpConstant %9 9 %87 = OpConstantComposite %13 %86 %86 -%88 = OpConstant %9 90.0 +%88 = OpConstant %9 90 %89 = OpConstantComposite %13 %88 %88 -%90 = OpConstant %9 10.0 -%91 = OpConstant %9 20.0 -%92 = OpConstant %9 30.0 -%93 = OpConstant %9 40.0 +%90 = OpConstant %9 10 +%91 = OpConstant %9 20 +%92 = OpConstant %9 30 +%93 = OpConstant %9 40 %95 = OpTypePointer Function %6 %97 = OpTypePointer Function %23 %101 = OpTypePointer Uniform %22 @@ -496,9 +496,9 @@ OpDecorate %388 Location 0 %141 = OpTypePointer Uniform %27 %143 = OpConstantNull %26 %144 = OpConstantComposite %27 %143 -%145 = OpConstant %9 8.0 +%145 = OpConstant %9 8 %146 = OpConstantComposite %13 %145 %145 -%147 = OpConstant %9 7.0 +%147 = OpConstant %9 7 %148 = OpConstantComposite %13 %147 %147 %149 = OpConstantComposite %25 %146 %148 %80 %82 %152 = OpTypePointer Function %27 @@ -542,7 +542,7 @@ OpDecorate %388 Location 0 %332 = OpTypePointer Output %32 %331 = OpVariable %332 Output %335 = OpTypePointer StorageBuffer %24 -%338 = OpConstant %9 0.0 +%338 = OpConstant %9 0 %339 = OpConstant %4 3 %340 = OpConstant %6 3 %341 = OpConstant %6 4 @@ -557,8 +557,8 @@ OpDecorate %388 Location 0 %363 = OpTypePointer StorageBuffer %20 %366 = OpTypePointer StorageBuffer %8 %367 = OpTypePointer StorageBuffer %6 -%372 = OpConstant %9 -2147483600.0 -%373 = OpConstant %9 2147483500.0 +%372 = OpConstant %9 -2147483600 +%373 = OpConstant %9 2147483500 %382 = OpTypeVector %6 4 %388 = OpVariable %332 Output %391 = OpConstantComposite %11 %338 %338 %338 diff --git a/naga/tests/out/spv/wgsl-aliased-ray-query.spvasm b/naga/tests/out/spv/wgsl-aliased-ray-query.spvasm index 2dc19683634..b095e8b8e83 100644 --- a/naga/tests/out/spv/wgsl-aliased-ray-query.spvasm +++ b/naga/tests/out/spv/wgsl-aliased-ray-query.spvasm @@ -34,7 +34,7 @@ OpDecorate %13 DescriptorSet 0 OpDecorate %13 Binding 0 %2 = OpTypeVoid %3 = OpTypeRayQueryKHR -%4 = OpTypeAccelerationStructureNV +%4 = OpTypeAccelerationStructureKHR %5 = OpTypeFloat 32 %6 = OpTypeVector %5 3 %7 = OpTypeInt 32 0 @@ -46,17 +46,17 @@ OpDecorate %13 Binding 0 %14 = OpTypePointer UniformConstant %4 %13 = OpVariable %14 UniformConstant %17 = OpTypeFunction %2 -%19 = OpConstant %5 0.0 +%19 = OpConstant %5 0 %20 = OpConstantComposite %6 %19 %19 %19 -%21 = OpConstant %5 1.0 +%21 = OpConstant %5 1 %22 = OpConstantComposite %6 %19 %21 %19 %23 = OpConstant %7 4 %24 = OpConstant %7 255 %25 = OpConstant %5 0.1 -%26 = OpConstant %5 100.0 +%26 = OpConstant %5 100 %27 = OpConstantComposite %8 %23 %24 %25 %26 %20 %22 %28 = OpConstant %7 3 -%29 = OpConstant %5 10.0 +%29 = OpConstant %5 10 %30 = OpConstant %7 1 %32 = OpTypePointer Function %3 %40 = OpTypePointer Function %12 diff --git a/naga/tests/out/spv/wgsl-array-in-function-return-type.spvasm b/naga/tests/out/spv/wgsl-array-in-function-return-type.spvasm index 146e032f354..9e2b2220f25 100644 --- a/naga/tests/out/spv/wgsl-array-in-function-return-type.spvasm +++ b/naga/tests/out/spv/wgsl-array-in-function-return-type.spvasm @@ -19,14 +19,14 @@ OpDecorate %26 Location 0 %7 = OpTypeArray %4 %8 %9 = OpTypeVector %3 4 %12 = OpTypeFunction %4 -%13 = OpConstant %3 1.0 -%14 = OpConstant %3 2.0 +%13 = OpConstant %3 1 +%14 = OpConstant %3 2 %15 = OpConstantComposite %4 %13 %14 %19 = OpTypeFunction %7 %27 = OpTypePointer Output %9 %26 = OpVariable %27 Output %29 = OpTypeFunction %2 -%30 = OpConstant %3 0.0 +%30 = OpConstant %3 0 %11 = OpFunction %4 None %12 %10 = OpLabel OpBranch %16 diff --git a/naga/tests/out/spv/wgsl-atomicCompareExchange.spvasm b/naga/tests/out/spv/wgsl-atomicCompareExchange.spvasm index 8b7e4ded087..e0e32c85d82 100644 --- a/naga/tests/out/spv/wgsl-atomicCompareExchange.spvasm +++ b/naga/tests/out/spv/wgsl-atomicCompareExchange.spvasm @@ -44,7 +44,7 @@ OpMemberDecorate %15 0 Offset 0 %21 = OpConstant %3 0 %23 = OpConstantFalse %8 %24 = OpTypeFloat 32 -%25 = OpConstant %24 1.0 +%25 = OpConstant %24 1 %26 = OpConstant %3 1 %28 = OpTypePointer Function %3 %30 = OpTypePointer Function %4 diff --git a/naga/tests/out/spv/wgsl-binding-arrays.spvasm b/naga/tests/out/spv/wgsl-binding-arrays.spvasm index 074aff8f9bc..c95bef4c567 100644 --- a/naga/tests/out/spv/wgsl-binding-arrays.spvasm +++ b/naga/tests/out/spv/wgsl-binding-arrays.spvasm @@ -130,7 +130,7 @@ OpDecorate %395 NonUniform %54 = OpTypePointer Uniform %4 %55 = OpConstant %3 0 %57 = OpConstantComposite %23 %55 %55 -%58 = OpConstant %6 0.0 +%58 = OpConstant %6 0 %59 = OpConstantComposite %22 %58 %58 %58 %58 %60 = OpTypeVector %6 2 %61 = OpConstantComposite %60 %58 %58 diff --git a/naga/tests/out/spv/wgsl-bitcast.spvasm b/naga/tests/out/spv/wgsl-bitcast.spvasm index 43dfa8df339..28b8fe56954 100644 --- a/naga/tests/out/spv/wgsl-bitcast.spvasm +++ b/naga/tests/out/spv/wgsl-bitcast.spvasm @@ -29,7 +29,7 @@ OpExecutionMode %16 LocalSize 1 1 1 %23 = OpConstantComposite %7 %22 %22 %24 = OpConstantComposite %9 %22 %22 %22 %25 = OpConstantComposite %10 %22 %22 %22 %22 -%26 = OpConstant %12 0.0 +%26 = OpConstant %12 0 %27 = OpConstantComposite %11 %26 %26 %28 = OpConstantComposite %13 %26 %26 %26 %29 = OpConstantComposite %14 %26 %26 %26 %26 diff --git a/naga/tests/out/spv/wgsl-bits.spvasm b/naga/tests/out/spv/wgsl-bits.spvasm index dec26768b3a..90786720f1a 100644 --- a/naga/tests/out/spv/wgsl-bits.spvasm +++ b/naga/tests/out/spv/wgsl-bits.spvasm @@ -29,7 +29,7 @@ OpExecutionMode %15 LocalSize 1 1 1 %22 = OpConstantComposite %8 %21 %21 %23 = OpConstantComposite %9 %21 %21 %21 %24 = OpConstantComposite %10 %21 %21 %21 %21 -%25 = OpConstant %12 0.0 +%25 = OpConstant %12 0 %26 = OpConstantComposite %11 %25 %25 %27 = OpConstantComposite %13 %25 %25 %25 %25 %28 = OpConstant %7 5 diff --git a/naga/tests/out/spv/wgsl-boids.spvasm b/naga/tests/out/spv/wgsl-boids.spvasm index 35bda2793b4..837d9326cd4 100644 --- a/naga/tests/out/spv/wgsl-boids.spvasm +++ b/naga/tests/out/spv/wgsl-boids.spvasm @@ -191,14 +191,14 @@ OpDecorate %21 BuiltIn GlobalInvocationId %25 = OpTypeFunction %2 %26 = OpTypePointer Uniform %8 %27 = OpConstant %4 0 -%29 = OpConstant %5 0.0 +%29 = OpConstant %5 0 %30 = OpConstantComposite %6 %29 %29 %31 = OpConstant %12 0 %32 = OpConstant %12 1 %33 = OpConstant %4 1 %34 = OpConstant %5 0.1 -%35 = OpConstant %5 -1.0 -%36 = OpConstant %5 1.0 +%35 = OpConstant %5 -1 +%36 = OpConstant %5 1 %38 = OpTypePointer Function %6 %39 = OpConstantNull %6 %41 = OpConstantNull %6 diff --git a/naga/tests/out/spv/wgsl-bounds-check-image-restrict-depth.spvasm b/naga/tests/out/spv/wgsl-bounds-check-image-restrict-depth.spvasm index b8a36ed3dfc..2f7efbe55df 100644 --- a/naga/tests/out/spv/wgsl-bounds-check-image-restrict-depth.spvasm +++ b/naga/tests/out/spv/wgsl-bounds-check-image-restrict-depth.spvasm @@ -101,7 +101,7 @@ OpDecorate %89 Location 0 %96 = OpConstantNull %7 %97 = OpConstant %6 0 %98 = OpConstant %9 0 -%99 = OpConstant %5 0.0 +%99 = OpConstant %5 0 %100 = OpConstantComposite %11 %99 %99 %99 %99 %21 = OpFunction %5 None %22 %19 = OpFunctionParameter %7 diff --git a/naga/tests/out/spv/wgsl-bounds-check-image-restrict.spvasm b/naga/tests/out/spv/wgsl-bounds-check-image-restrict.spvasm index aa311f557e6..4a7b1240e14 100644 --- a/naga/tests/out/spv/wgsl-bounds-check-image-restrict.spvasm +++ b/naga/tests/out/spv/wgsl-bounds-check-image-restrict.spvasm @@ -229,7 +229,7 @@ OpDecorate %172 Location 0 %187 = OpConstant %11 0 %188 = OpConstantNull %13 %189 = OpConstantNull %7 -%190 = OpConstant %5 0.0 +%190 = OpConstant %5 0 %191 = OpConstantComposite %7 %190 %190 %190 %190 %40 = OpFunction %7 None %41 %38 = OpFunctionParameter %6 diff --git a/naga/tests/out/spv/wgsl-bounds-check-image-rzsw-depth.spvasm b/naga/tests/out/spv/wgsl-bounds-check-image-rzsw-depth.spvasm index 0db821d3bf3..4ecca6c2f38 100644 --- a/naga/tests/out/spv/wgsl-bounds-check-image-rzsw-depth.spvasm +++ b/naga/tests/out/spv/wgsl-bounds-check-image-rzsw-depth.spvasm @@ -100,7 +100,7 @@ OpDecorate %100 Location 0 %107 = OpConstantNull %7 %108 = OpConstant %6 0 %109 = OpConstant %9 0 -%110 = OpConstant %5 0.0 +%110 = OpConstant %5 0 %111 = OpConstantComposite %11 %110 %110 %110 %110 %21 = OpFunction %5 None %22 %19 = OpFunctionParameter %7 diff --git a/naga/tests/out/spv/wgsl-bounds-check-image-rzsw.spvasm b/naga/tests/out/spv/wgsl-bounds-check-image-rzsw.spvasm index 7eb0c8b6121..814d2aa24df 100644 --- a/naga/tests/out/spv/wgsl-bounds-check-image-rzsw.spvasm +++ b/naga/tests/out/spv/wgsl-bounds-check-image-rzsw.spvasm @@ -226,7 +226,7 @@ OpDecorate %187 Location 0 %201 = OpConstantNull %9 %202 = OpConstant %11 0 %203 = OpConstantNull %13 -%204 = OpConstant %5 0.0 +%204 = OpConstant %5 0 %205 = OpConstantComposite %7 %204 %204 %204 %204 %40 = OpFunction %7 None %41 %38 = OpFunctionParameter %6 diff --git a/naga/tests/out/spv/wgsl-bounds-check-restrict.spvasm b/naga/tests/out/spv/wgsl-bounds-check-restrict.spvasm index 9885a0bde73..86a0a0547c6 100644 --- a/naga/tests/out/spv/wgsl-bounds-check-restrict.spvasm +++ b/naga/tests/out/spv/wgsl-bounds-check-restrict.spvasm @@ -45,9 +45,9 @@ OpDecorate %12 Binding 0 %59 = OpTypePointer StorageBuffer %8 %60 = OpConstant %6 2 %68 = OpTypeFunction %3 %11 %11 -%77 = OpConstant %3 100.0 -%83 = OpConstant %3 -2147483600.0 -%84 = OpConstant %3 2147483500.0 +%77 = OpConstant %3 100 +%83 = OpConstant %3 -2147483600 +%84 = OpConstant %3 2147483500 %92 = OpTypeFunction %3 %106 = OpTypeFunction %2 %11 %3 %130 = OpTypeFunction %2 %11 %7 @@ -56,14 +56,14 @@ OpDecorate %12 Binding 0 %170 = OpConstant %6 1000 %184 = OpTypeFunction %2 %185 = OpConstant %11 1 -%186 = OpConstant %3 2.0 -%187 = OpConstant %3 3.0 -%188 = OpConstant %3 4.0 -%189 = OpConstant %3 5.0 +%186 = OpConstant %3 2 +%187 = OpConstant %3 3 +%188 = OpConstant %3 4 +%189 = OpConstant %3 5 %190 = OpConstantComposite %7 %186 %187 %188 %189 %191 = OpConstant %11 6 %192 = OpConstant %11 2 -%193 = OpConstant %3 1.0 +%193 = OpConstant %3 1 %16 = OpFunction %3 None %17 %15 = OpFunctionParameter %11 %14 = OpLabel diff --git a/naga/tests/out/spv/wgsl-bounds-check-zero.spvasm b/naga/tests/out/spv/wgsl-bounds-check-zero.spvasm index c31e9e1ab73..f8cd0080678 100644 --- a/naga/tests/out/spv/wgsl-bounds-check-zero.spvasm +++ b/naga/tests/out/spv/wgsl-bounds-check-zero.spvasm @@ -48,9 +48,9 @@ OpDecorate %12 Binding 0 %74 = OpConstant %6 2 %76 = OpConstantNull %7 %85 = OpTypeFunction %3 %11 %11 -%98 = OpConstant %3 100.0 -%104 = OpConstant %3 -2147483600.0 -%105 = OpConstant %3 2147483500.0 +%98 = OpConstant %3 100 +%104 = OpConstant %3 -2147483600 +%105 = OpConstant %3 2147483500 %116 = OpTypeFunction %3 %118 = OpConstant %6 9 %131 = OpTypeFunction %2 %11 %3 @@ -60,14 +60,14 @@ OpDecorate %12 Binding 0 %206 = OpConstant %6 1000 %224 = OpTypeFunction %2 %225 = OpConstant %11 1 -%226 = OpConstant %3 2.0 -%227 = OpConstant %3 3.0 -%228 = OpConstant %3 4.0 -%229 = OpConstant %3 5.0 +%226 = OpConstant %3 2 +%227 = OpConstant %3 3 +%228 = OpConstant %3 4 +%229 = OpConstant %3 5 %230 = OpConstantComposite %7 %226 %227 %228 %229 %231 = OpConstant %11 6 %232 = OpConstant %11 2 -%233 = OpConstant %3 1.0 +%233 = OpConstant %3 1 %16 = OpFunction %3 None %17 %15 = OpFunctionParameter %11 %14 = OpLabel diff --git a/naga/tests/out/spv/wgsl-const-exprs.spvasm b/naga/tests/out/spv/wgsl-const-exprs.spvasm index c4413460f1e..84701b9e163 100644 --- a/naga/tests/out/spv/wgsl-const-exprs.spvasm +++ b/naga/tests/out/spv/wgsl-const-exprs.spvasm @@ -34,10 +34,10 @@ OpDecorate %13 ArrayStride 4 %24 = OpConstant %7 3.141 %25 = OpConstant %7 6.282 %26 = OpConstant %7 0.44444445 -%27 = OpConstant %7 0.0 +%27 = OpConstant %7 0 %28 = OpConstantComposite %8 %26 %27 %27 %27 -%29 = OpConstant %7 4.0 -%30 = OpConstant %7 5.0 +%29 = OpConstant %7 4 +%30 = OpConstant %7 5 %31 = OpConstantComposite %15 %29 %30 %32 = OpConstantComposite %12 %17 %18 %35 = OpTypeFunction %2 @@ -58,8 +58,8 @@ OpDecorate %13 ArrayStride 4 %86 = OpConstant %3 30 %87 = OpConstant %3 0 %94 = OpConstantNull %3 -%97 = OpConstant %7 1.0 -%98 = OpConstant %7 2.0 +%97 = OpConstant %7 1 +%98 = OpConstant %7 2 %99 = OpConstantComposite %8 %98 %97 %97 %97 %101 = OpTypePointer Function %8 %106 = OpTypePointer Function %9 diff --git a/naga/tests/out/spv/wgsl-constructors.spvasm b/naga/tests/out/spv/wgsl-constructors.spvasm index 233cb2735ea..0192183dc84 100644 --- a/naga/tests/out/spv/wgsl-constructors.spvasm +++ b/naga/tests/out/spv/wgsl-constructors.spvasm @@ -31,11 +31,11 @@ OpDecorate %18 ArrayStride 4 %19 = OpConstant %12 4 %18 = OpTypeArray %5 %19 %20 = OpTypeMatrix %7 2 -%21 = OpConstant %3 0.0 +%21 = OpConstant %3 0 %22 = OpConstantComposite %7 %21 %21 %21 -%23 = OpConstant %3 1.0 -%24 = OpConstant %3 2.0 -%25 = OpConstant %3 3.0 +%23 = OpConstant %3 1 +%24 = OpConstant %3 2 +%25 = OpConstant %3 3 %26 = OpConstantComposite %9 %21 %23 %27 = OpConstantComposite %9 %24 %25 %28 = OpConstantComposite %8 %26 %27 diff --git a/naga/tests/out/spv/wgsl-conversion-float-to-int.spvasm b/naga/tests/out/spv/wgsl-conversion-float-to-int.spvasm index 10cbbe3b8c4..8d8168bfc00 100644 --- a/naga/tests/out/spv/wgsl-conversion-float-to-int.spvasm +++ b/naga/tests/out/spv/wgsl-conversion-float-to-int.spvasm @@ -29,12 +29,12 @@ OpExecutionMode %278 LocalSize 1 1 1 %14 = OpTypeVector %9 2 %15 = OpTypeVector %4 2 %16 = OpTypeVector %5 2 -%17 = OpConstant %3 9.0399e-41 -%18 = OpConstant %3 4.4481e-41 -%19 = OpConstant %4 -3.4028235e38 -%20 = OpConstant %4 3.4028235e38 -%21 = OpConstant %5 -1.7976931348623157e308 -%22 = OpConstant %5 1.7976931348623157e308 +%17 = OpConstant %3 0.000000000000000000000000000000000000000090399 +%18 = OpConstant %3 0.000000000000000000000000000000000000000044481 +%19 = OpConstant %4 -340282350000000000000000000000000000000 +%20 = OpConstant %4 340282350000000000000000000000000000000 +%21 = OpConstant %5 -179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +%22 = OpConstant %5 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 %25 = OpTypeFunction %2 %26 = OpConstant %6 -65504 %27 = OpConstant %6 65504 @@ -60,31 +60,31 @@ OpExecutionMode %278 LocalSize 1 1 1 %54 = OpTypePointer Function %9 %80 = OpTypeFunction %6 %3 %87 = OpTypeFunction %7 %3 -%89 = OpConstant %3 0.0 +%89 = OpConstant %3 0 %95 = OpTypeFunction %8 %3 %102 = OpTypeFunction %9 %3 %109 = OpTypeFunction %6 %4 -%111 = OpConstant %4 -2147483600.0 -%112 = OpConstant %4 2147483500.0 +%111 = OpConstant %4 -2147483600 +%112 = OpConstant %4 2147483500 %118 = OpTypeFunction %7 %4 -%120 = OpConstant %4 0.0 -%121 = OpConstant %4 4294967000.0 +%120 = OpConstant %4 0 +%121 = OpConstant %4 4294967000 %127 = OpTypeFunction %8 %4 -%129 = OpConstant %4 -9.223372e18 -%130 = OpConstant %4 9.2233715e18 +%129 = OpConstant %4 -9223372000000000000 +%130 = OpConstant %4 9223371500000000000 %136 = OpTypeFunction %9 %4 -%138 = OpConstant %4 1.8446743e19 +%138 = OpConstant %4 18446743000000000000 %144 = OpTypeFunction %6 %5 -%146 = OpConstant %5 -2147483648.0 -%147 = OpConstant %5 2147483647.0 +%146 = OpConstant %5 -2147483648 +%147 = OpConstant %5 2147483647 %153 = OpTypeFunction %7 %5 -%155 = OpConstant %5 0.0 -%156 = OpConstant %5 4294967295.0 +%155 = OpConstant %5 0 +%156 = OpConstant %5 4294967295 %162 = OpTypeFunction %8 %5 -%164 = OpConstant %5 -9.223372036854776e18 -%165 = OpConstant %5 9.223372036854775e18 +%164 = OpConstant %5 -9223372036854776000 +%165 = OpConstant %5 9223372036854775000 %171 = OpTypeFunction %9 %5 -%173 = OpConstant %5 1.844674407370955e19 +%173 = OpConstant %5 18446744073709550000 %179 = OpTypeFunction %11 %10 %181 = OpConstantComposite %10 %17 %17 %182 = OpConstantComposite %10 %18 %18 @@ -114,14 +114,14 @@ OpExecutionMode %278 LocalSize 1 1 1 %266 = OpConstantComposite %16 %165 %165 %272 = OpTypeFunction %14 %16 %274 = OpConstantComposite %16 %173 %173 -%279 = OpConstant %3 2.1524e-41 -%280 = OpConstant %4 1.0 -%281 = OpConstant %5 1.0 -%282 = OpConstant %3 2.2959e-41 +%279 = OpConstant %3 0.000000000000000000000000000000000000000021524 +%280 = OpConstant %4 1 +%281 = OpConstant %5 1 +%282 = OpConstant %3 0.000000000000000000000000000000000000000022959 %283 = OpConstantComposite %10 %279 %282 -%284 = OpConstant %4 2.0 +%284 = OpConstant %4 2 %285 = OpConstantComposite %15 %280 %284 -%286 = OpConstant %5 2.0 +%286 = OpConstant %5 2 %287 = OpConstantComposite %16 %281 %286 %24 = OpFunction %2 None %25 %23 = OpLabel diff --git a/naga/tests/out/spv/wgsl-conversions.spvasm b/naga/tests/out/spv/wgsl-conversions.spvasm index 5dae778e115..112979819ce 100644 --- a/naga/tests/out/spv/wgsl-conversions.spvasm +++ b/naga/tests/out/spv/wgsl-conversions.spvasm @@ -10,7 +10,7 @@ OpExecutionMode %8 LocalSize 1 1 1 %2 = OpTypeVoid %4 = OpTypeFloat 32 %3 = OpTypeVector %4 2 -%5 = OpConstant %4 2.0 +%5 = OpConstant %4 2 %6 = OpConstantComposite %3 %5 %5 %9 = OpTypeFunction %2 %11 = OpTypePointer Function %3 diff --git a/naga/tests/out/spv/wgsl-cross.spvasm b/naga/tests/out/spv/wgsl-cross.spvasm index fd13684894b..849b26ef778 100644 --- a/naga/tests/out/spv/wgsl-cross.spvasm +++ b/naga/tests/out/spv/wgsl-cross.spvasm @@ -11,8 +11,8 @@ OpExecutionMode %6 LocalSize 1 1 1 %4 = OpTypeFloat 32 %3 = OpTypeVector %4 3 %7 = OpTypeFunction %2 -%8 = OpConstant %4 0.0 -%9 = OpConstant %4 1.0 +%8 = OpConstant %4 0 +%9 = OpConstant %4 1 %10 = OpConstantComposite %3 %8 %8 %9 %6 = OpFunction %2 None %7 %5 = OpLabel diff --git a/naga/tests/out/spv/wgsl-debug-symbol-large-source.spvasm b/naga/tests/out/spv/wgsl-debug-symbol-large-source.spvasm index f1db8e611ed..ef1d8bc534f 100644 --- a/naga/tests/out/spv/wgsl-debug-symbol-large-source.spvasm +++ b/naga/tests/out/spv/wgsl-debug-symbol-large-source.spvasm @@ -7716,10 +7716,10 @@ OpDecorate %614 Location 0 %49 = OpVariable %46 UniformConstant %50 = OpVariable %48 UniformConstant %54 = OpTypeFunction %5 %5 -%55 = OpConstant %4 34.0 -%56 = OpConstant %4 1.0 +%55 = OpConstant %4 34 +%56 = OpConstant %4 1 %57 = OpConstantComposite %5 %56 %56 %56 -%58 = OpConstant %4 289.0 +%58 = OpConstant %4 289 %59 = OpConstantComposite %5 %58 %58 %58 %68 = OpTypeFunction %4 %6 %69 = OpConstant %4 0.21132487 @@ -7727,18 +7727,18 @@ OpDecorate %614 Location 0 %71 = OpConstant %4 -0.57735026 %72 = OpConstant %4 0.024390243 %73 = OpConstantComposite %7 %69 %70 %71 %72 -%74 = OpConstant %4 0.0 +%74 = OpConstant %4 0 %75 = OpConstantComposite %6 %56 %74 %76 = OpConstantComposite %6 %74 %56 %77 = OpConstantComposite %6 %58 %58 %78 = OpConstant %4 0.5 %79 = OpConstantComposite %5 %78 %78 %78 %80 = OpConstantComposite %5 %74 %74 %74 -%81 = OpConstant %4 2.0 +%81 = OpConstant %4 2 %82 = OpConstant %4 0.85373473 %83 = OpConstant %4 1.7928429 %84 = OpConstantComposite %5 %83 %83 %83 -%85 = OpConstant %4 130.0 +%85 = OpConstant %4 130 %87 = OpTypePointer Function %6 %88 = OpConstantNull %6 %90 = OpConstantNull %6 @@ -7753,7 +7753,7 @@ OpDecorate %614 Location 0 %135 = OpConstant %8 0 %205 = OpConstant %8 5 %206 = OpConstant %4 0.01 -%207 = OpConstant %4 100.0 +%207 = OpConstant %4 100 %208 = OpConstantComposite %6 %207 %207 %209 = OpConstant %4 0.87758255 %210 = OpConstant %4 0.47942555 @@ -7775,11 +7775,11 @@ OpDecorate %614 Location 0 %314 = OpTypeFunction %8 %8 %8 %326 = OpTypeFunction %6 %8 %10 %11 %343 = OpTypeFunction %5 %6 -%344 = OpConstant %4 23.0 -%345 = OpConstant %4 32.0 +%344 = OpConstant %4 23 +%345 = OpConstant %4 32 %346 = OpConstantComposite %6 %344 %345 -%347 = OpConstant %4 -43.0 -%348 = OpConstant %4 3.0 +%347 = OpConstant %4 -43 +%348 = OpConstant %4 3 %349 = OpConstantComposite %6 %347 %348 %365 = OpTypePointer Input %19 %364 = OpVariable %365 Input @@ -7806,9 +7806,9 @@ OpDecorate %614 Location 0 %443 = OpTypePointer Output %6 %442 = OpVariable %443 Output %445 = OpTypePointer Uniform %20 -%447 = OpConstant %4 -1.0 +%447 = OpConstant %4 -1 %448 = OpConstantComposite %6 %447 %447 -%473 = OpConstant %4 4294967000.0 +%473 = OpConstant %4 4294967000 %485 = OpVariable %436 Input %488 = OpTypePointer Input %7 %487 = OpVariable %488 Input @@ -7816,7 +7816,7 @@ OpDecorate %614 Location 0 %490 = OpVariable %491 Input %493 = OpVariable %439 Output %494 = OpVariable %439 Output -%497 = OpConstant %4 6.0 +%497 = OpConstant %4 6 %582 = OpTypePointer Input %5 %581 = OpVariable %582 Input %584 = OpVariable %582 Input diff --git a/naga/tests/out/spv/wgsl-debug-symbol-simple.spvasm b/naga/tests/out/spv/wgsl-debug-symbol-simple.spvasm index bde02c231de..4adb3411b35 100644 --- a/naga/tests/out/spv/wgsl-debug-symbol-simple.spvasm +++ b/naga/tests/out/spv/wgsl-debug-symbol-simple.spvasm @@ -87,7 +87,7 @@ OpDecorate %48 Location 0 %20 = OpTypePointer Output %5 %19 = OpVariable %20 Output %22 = OpTypeFunction %2 -%23 = OpConstant %4 1.0 +%23 = OpConstant %4 1 %25 = OpTypePointer Function %8 %26 = OpConstantNull %8 %28 = OpTypePointer Function %5 diff --git a/naga/tests/out/spv/wgsl-debug-symbol-terrain.spvasm b/naga/tests/out/spv/wgsl-debug-symbol-terrain.spvasm index 69f08bcdb62..47009186afb 100644 --- a/naga/tests/out/spv/wgsl-debug-symbol-terrain.spvasm +++ b/naga/tests/out/spv/wgsl-debug-symbol-terrain.spvasm @@ -551,10 +551,10 @@ OpDecorate %614 Location 0 %49 = OpVariable %46 UniformConstant %50 = OpVariable %48 UniformConstant %54 = OpTypeFunction %5 %5 -%55 = OpConstant %4 34.0 -%56 = OpConstant %4 1.0 +%55 = OpConstant %4 34 +%56 = OpConstant %4 1 %57 = OpConstantComposite %5 %56 %56 %56 -%58 = OpConstant %4 289.0 +%58 = OpConstant %4 289 %59 = OpConstantComposite %5 %58 %58 %58 %68 = OpTypeFunction %4 %6 %69 = OpConstant %4 0.21132487 @@ -562,18 +562,18 @@ OpDecorate %614 Location 0 %71 = OpConstant %4 -0.57735026 %72 = OpConstant %4 0.024390243 %73 = OpConstantComposite %7 %69 %70 %71 %72 -%74 = OpConstant %4 0.0 +%74 = OpConstant %4 0 %75 = OpConstantComposite %6 %56 %74 %76 = OpConstantComposite %6 %74 %56 %77 = OpConstantComposite %6 %58 %58 %78 = OpConstant %4 0.5 %79 = OpConstantComposite %5 %78 %78 %78 %80 = OpConstantComposite %5 %74 %74 %74 -%81 = OpConstant %4 2.0 +%81 = OpConstant %4 2 %82 = OpConstant %4 0.85373473 %83 = OpConstant %4 1.7928429 %84 = OpConstantComposite %5 %83 %83 %83 -%85 = OpConstant %4 130.0 +%85 = OpConstant %4 130 %87 = OpTypePointer Function %6 %88 = OpConstantNull %6 %90 = OpConstantNull %6 @@ -588,7 +588,7 @@ OpDecorate %614 Location 0 %135 = OpConstant %8 0 %205 = OpConstant %8 5 %206 = OpConstant %4 0.01 -%207 = OpConstant %4 100.0 +%207 = OpConstant %4 100 %208 = OpConstantComposite %6 %207 %207 %209 = OpConstant %4 0.87758255 %210 = OpConstant %4 0.47942555 @@ -610,11 +610,11 @@ OpDecorate %614 Location 0 %314 = OpTypeFunction %8 %8 %8 %326 = OpTypeFunction %6 %8 %10 %11 %343 = OpTypeFunction %5 %6 -%344 = OpConstant %4 23.0 -%345 = OpConstant %4 32.0 +%344 = OpConstant %4 23 +%345 = OpConstant %4 32 %346 = OpConstantComposite %6 %344 %345 -%347 = OpConstant %4 -43.0 -%348 = OpConstant %4 3.0 +%347 = OpConstant %4 -43 +%348 = OpConstant %4 3 %349 = OpConstantComposite %6 %347 %348 %365 = OpTypePointer Input %19 %364 = OpVariable %365 Input @@ -641,9 +641,9 @@ OpDecorate %614 Location 0 %443 = OpTypePointer Output %6 %442 = OpVariable %443 Output %445 = OpTypePointer Uniform %20 -%447 = OpConstant %4 -1.0 +%447 = OpConstant %4 -1 %448 = OpConstantComposite %6 %447 %447 -%473 = OpConstant %4 4294967000.0 +%473 = OpConstant %4 4294967000 %485 = OpVariable %436 Input %488 = OpTypePointer Input %7 %487 = OpVariable %488 Input @@ -651,7 +651,7 @@ OpDecorate %614 Location 0 %490 = OpVariable %491 Input %493 = OpVariable %439 Output %494 = OpVariable %439 Output -%497 = OpConstant %4 6.0 +%497 = OpConstant %4 6 %582 = OpTypePointer Input %5 %581 = OpVariable %582 Input %584 = OpVariable %582 Input diff --git a/naga/tests/out/spv/wgsl-extra.spvasm b/naga/tests/out/spv/wgsl-extra.spvasm index 0e84427bad4..0d091ae1fe2 100644 --- a/naga/tests/out/spv/wgsl-extra.spvasm +++ b/naga/tests/out/spv/wgsl-extra.spvasm @@ -37,7 +37,7 @@ OpDecorate %20 Location 0 %23 = OpTypeFunction %2 %24 = OpTypePointer PushConstant %6 %25 = OpConstant %3 0 -%27 = OpConstant %5 1.0 +%27 = OpConstant %5 1 %28 = OpTypeVector %5 3 %29 = OpConstantComposite %28 %27 %27 %27 %32 = OpTypePointer PushConstant %3 diff --git a/naga/tests/out/spv/wgsl-f16.spvasm b/naga/tests/out/spv/wgsl-f16.spvasm index d6aed42b4eb..4fc6963ce87 100644 --- a/naga/tests/out/spv/wgsl-f16.spvasm +++ b/naga/tests/out/spv/wgsl-f16.spvasm @@ -100,8 +100,8 @@ OpMemberDecorate %41 0 Offset 0 %20 = OpTypeArray %3 %21 %22 = OpTypeStruct %20 %23 = OpTypeStruct %3 %3 %8 %3 %3 %4 -%24 = OpConstant %3 2.1524e-41 -%25 = OpConstant %3 2.7121e-41 +%24 = OpConstant %3 0.000000000000000000000000000000000000000021524 +%25 = OpConstant %3 0.000000000000000000000000000000000000000027121 %27 = OpTypePointer Private %3 %26 = OpVariable %27 Private %24 %29 = OpTypeStruct %19 @@ -124,13 +124,13 @@ OpMemberDecorate %41 0 Offset 0 %48 = OpConstant %4 0 %50 = OpTypePointer StorageBuffer %19 %52 = OpTypePointer StorageBuffer %22 -%56 = OpConstant %3 8.8991e-41 -%57 = OpConstant %3 2.4753e-41 +%56 = OpConstant %3 0.000000000000000000000000000000000000000088991 +%57 = OpConstant %3 0.000000000000000000000000000000000000000024753 %58 = OpConstant %5 65504 %59 = OpConstant %5 -65504 %60 = OpConstant %4 65504 -%61 = OpConstant %6 65504.0 -%62 = OpConstant %6 -65504.0 +%61 = OpConstant %6 65504 +%62 = OpConstant %6 -65504 %64 = OpTypePointer Function %23 %65 = OpConstantNull %23 %67 = OpTypePointer Function %3 @@ -192,7 +192,7 @@ OpMemberDecorate %41 0 Offset 0 %474 = OpTypeMatrix %344 4 %496 = OpTypeMatrix %350 4 %519 = OpTypeFunction %2 -%525 = OpConstant %3 2.2959e-41 +%525 = OpConstant %3 0.000000000000000000000000000000000000000022959 %528 = OpConstant %4 7 %45 = OpFunction %3 None %46 %44 = OpFunctionParameter %3 diff --git a/naga/tests/out/spv/wgsl-f64.spvasm b/naga/tests/out/spv/wgsl-f64.spvasm index d51bc3c8535..fd0fa038e1c 100644 --- a/naga/tests/out/spv/wgsl-f64.spvasm +++ b/naga/tests/out/spv/wgsl-f64.spvasm @@ -10,19 +10,19 @@ OpEntryPoint GLCompute %28 "main" OpExecutionMode %28 LocalSize 1 1 1 %2 = OpTypeVoid %3 = OpTypeFloat 64 -%4 = OpConstant %3 1.0 -%5 = OpConstant %3 2.0 +%4 = OpConstant %3 1 +%5 = OpConstant %3 2 %7 = OpTypePointer Private %3 %6 = OpVariable %7 Private %4 %11 = OpTypeFunction %3 %3 -%12 = OpConstant %3 30.0 -%13 = OpConstant %3 400.0 -%14 = OpConstant %3 5.0 -%15 = OpConstant %3 -1.0 +%12 = OpConstant %3 30 +%13 = OpConstant %3 400 +%14 = OpConstant %3 5 +%15 = OpConstant %3 -1 %17 = OpTypePointer Function %3 %18 = OpConstantNull %3 %29 = OpTypeFunction %2 -%30 = OpConstant %3 6.0 +%30 = OpConstant %3 6 %10 = OpFunction %3 None %11 %9 = OpFunctionParameter %3 %8 = OpLabel diff --git a/naga/tests/out/spv/wgsl-fragment-output.spvasm b/naga/tests/out/spv/wgsl-fragment-output.spvasm index 414c646c73c..cad9ebf7b24 100644 --- a/naga/tests/out/spv/wgsl-fragment-output.spvasm +++ b/naga/tests/out/spv/wgsl-fragment-output.spvasm @@ -61,7 +61,7 @@ OpDecorate %80 Location 5 %29 = OpTypePointer Output %11 %28 = OpVariable %29 Output %31 = OpTypeFunction %2 -%32 = OpConstant %3 0.0 +%32 = OpConstant %3 0 %33 = OpConstantComposite %4 %32 %32 %32 %32 %34 = OpConstant %5 0 %35 = OpConstantComposite %6 %34 %34 %34 %34 diff --git a/naga/tests/out/spv/wgsl-functions-optimized-by-capability.spvasm b/naga/tests/out/spv/wgsl-functions-optimized-by-capability.spvasm index 00fc02f9f8b..011a5e39e34 100644 --- a/naga/tests/out/spv/wgsl-functions-optimized-by-capability.spvasm +++ b/naga/tests/out/spv/wgsl-functions-optimized-by-capability.spvasm @@ -3,8 +3,8 @@ ; Generator: rspirv ; Bound: 30 OpCapability Shader -OpCapability DotProductKHR -OpCapability DotProductInput4x8BitPackedKHR +OpCapability DotProduct +OpCapability DotProductInput4x8BitPacked OpExtension "SPV_KHR_integer_dot_product" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 @@ -27,14 +27,14 @@ OpExecutionMode %26 LocalSize 1 1 1 %4 = OpLabel OpBranch %15 %15 = OpLabel -%17 = OpSDotKHR %16 %7 %8 PackedVectorFormat4x8BitKHR -%18 = OpUDotKHR %3 %9 %10 PackedVectorFormat4x8BitKHR +%17 = OpSDot %16 %7 %8 PackedVectorFormat4x8Bit +%18 = OpUDot %3 %9 %10 PackedVectorFormat4x8Bit %19 = OpIAdd %3 %11 %18 %20 = OpIAdd %3 %12 %18 -%21 = OpSDotKHR %16 %19 %20 PackedVectorFormat4x8BitKHR +%21 = OpSDot %16 %19 %20 PackedVectorFormat4x8Bit %22 = OpIAdd %3 %13 %18 %23 = OpIAdd %3 %14 %18 -%24 = OpUDotKHR %3 %22 %23 PackedVectorFormat4x8BitKHR +%24 = OpUDot %3 %22 %23 PackedVectorFormat4x8Bit OpReturnValue %24 OpFunctionEnd %26 = OpFunction %2 None %27 diff --git a/naga/tests/out/spv/wgsl-functions-optimized-by-version.spvasm b/naga/tests/out/spv/wgsl-functions-optimized-by-version.spvasm index 0c77fbda039..46aa7520ca1 100644 --- a/naga/tests/out/spv/wgsl-functions-optimized-by-version.spvasm +++ b/naga/tests/out/spv/wgsl-functions-optimized-by-version.spvasm @@ -3,8 +3,8 @@ ; Generator: rspirv ; Bound: 30 OpCapability Shader -OpCapability DotProductKHR -OpCapability DotProductInput4x8BitPackedKHR +OpCapability DotProduct +OpCapability DotProductInput4x8BitPacked %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %26 "main" @@ -26,14 +26,14 @@ OpExecutionMode %26 LocalSize 1 1 1 %4 = OpLabel OpBranch %15 %15 = OpLabel -%17 = OpSDotKHR %16 %7 %8 PackedVectorFormat4x8BitKHR -%18 = OpUDotKHR %3 %9 %10 PackedVectorFormat4x8BitKHR +%17 = OpSDot %16 %7 %8 PackedVectorFormat4x8Bit +%18 = OpUDot %3 %9 %10 PackedVectorFormat4x8Bit %19 = OpIAdd %3 %11 %18 %20 = OpIAdd %3 %12 %18 -%21 = OpSDotKHR %16 %19 %20 PackedVectorFormat4x8BitKHR +%21 = OpSDot %16 %19 %20 PackedVectorFormat4x8Bit %22 = OpIAdd %3 %13 %18 %23 = OpIAdd %3 %14 %18 -%24 = OpUDotKHR %3 %22 %23 PackedVectorFormat4x8BitKHR +%24 = OpUDot %3 %22 %23 PackedVectorFormat4x8Bit OpReturnValue %24 OpFunctionEnd %26 = OpFunction %2 None %27 diff --git a/naga/tests/out/spv/wgsl-functions.spvasm b/naga/tests/out/spv/wgsl-functions.spvasm index 35585e2a6c6..a84e322ae74 100644 --- a/naga/tests/out/spv/wgsl-functions.spvasm +++ b/naga/tests/out/spv/wgsl-functions.spvasm @@ -3,8 +3,8 @@ ; Generator: rspirv ; Bound: 95 OpCapability Shader -OpCapability DotProductKHR -OpCapability DotProductInput4x8BitPackedKHR +OpCapability DotProduct +OpCapability DotProductInput4x8BitPacked OpExtension "SPV_KHR_integer_dot_product" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 @@ -16,7 +16,7 @@ OpExecutionMode %89 LocalSize 1 1 1 %5 = OpTypeInt 32 1 %6 = OpTypeInt 32 0 %9 = OpTypeFunction %3 -%10 = OpConstant %4 2.0 +%10 = OpConstant %4 2 %11 = OpConstantComposite %3 %10 %10 %12 = OpConstant %4 0.5 %13 = OpConstantComposite %3 %12 %12 @@ -96,14 +96,14 @@ OpFunctionEnd %69 = OpLabel OpBranch %79 %79 = OpLabel -%80 = OpSDotKHR %5 %22 %72 PackedVectorFormat4x8BitKHR -%81 = OpUDotKHR %6 %73 %74 PackedVectorFormat4x8BitKHR +%80 = OpSDot %5 %22 %72 PackedVectorFormat4x8Bit +%81 = OpUDot %6 %73 %74 PackedVectorFormat4x8Bit %82 = OpIAdd %6 %75 %81 %83 = OpIAdd %6 %76 %81 -%84 = OpSDotKHR %5 %82 %83 PackedVectorFormat4x8BitKHR +%84 = OpSDot %5 %82 %83 PackedVectorFormat4x8Bit %85 = OpIAdd %6 %77 %81 %86 = OpIAdd %6 %78 %81 -%87 = OpUDotKHR %6 %85 %86 PackedVectorFormat4x8BitKHR +%87 = OpUDot %6 %85 %86 PackedVectorFormat4x8Bit OpReturnValue %87 OpFunctionEnd %89 = OpFunction %2 None %90 diff --git a/naga/tests/out/spv/wgsl-globals.spvasm b/naga/tests/out/spv/wgsl-globals.spvasm index 5cf31f80766..8feae9610ce 100644 --- a/naga/tests/out/spv/wgsl-globals.spvasm +++ b/naga/tests/out/spv/wgsl-globals.spvasm @@ -106,11 +106,11 @@ OpDecorate %116 BuiltIn LocalInvocationId %58 = OpTypeFunction %2 %59 = OpTypePointer StorageBuffer %9 %60 = OpConstant %7 0 -%62 = OpConstant %4 1.0 +%62 = OpConstant %4 1 %63 = OpConstantComposite %8 %62 %62 %62 %64 = OpConstant %23 1 -%65 = OpConstant %4 2.0 -%66 = OpConstant %4 3.0 +%65 = OpConstant %4 2 +%66 = OpConstant %4 3 %67 = OpConstantNull %24 %69 = OpTypePointer Function %23 %71 = OpTypePointer StorageBuffer %8 @@ -121,7 +121,7 @@ OpDecorate %116 BuiltIn LocalInvocationId %101 = OpTypePointer Uniform %15 %103 = OpTypePointer Uniform %19 %105 = OpTypePointer Uniform %22 -%107 = OpConstant %4 4.0 +%107 = OpConstant %4 4 %109 = OpTypePointer Function %4 %111 = OpTypePointer Function %3 %113 = OpConstantNull %5 diff --git a/naga/tests/out/spv/wgsl-image.spvasm b/naga/tests/out/spv/wgsl-image.spvasm index 25681afe888..541fb1f5e64 100644 --- a/naga/tests/out/spv/wgsl-image.spvasm +++ b/naga/tests/out/spv/wgsl-image.spvasm @@ -405,8 +405,8 @@ OpDecorate %549 Location 0 %117 = OpTypeVector %5 4 %132 = OpTypeVector %15 3 %195 = OpVariable %94 Input -%212 = OpConstant %8 0.0 -%213 = OpConstant %8 4294967000.0 +%212 = OpConstant %8 0 +%213 = OpConstant %8 4294967000 %219 = OpTypePointer Output %24 %218 = OpVariable %219 Output %229 = OpConstant %5 0 @@ -420,12 +420,12 @@ OpDecorate %549 Location 0 %314 = OpConstant %15 3 %315 = OpConstantComposite %14 %314 %88 %316 = OpConstant %8 2.3 -%317 = OpConstant %8 2.0 +%317 = OpConstant %8 2 %319 = OpTypePointer Function %24 %320 = OpConstantNull %24 %322 = OpTypeSampledImage %16 %327 = OpTypeSampledImage %17 -%351 = OpConstant %8 1.0 +%351 = OpConstant %8 1 %352 = OpConstantComposite %310 %351 %351 %359 = OpTypeSampledImage %19 %420 = OpTypeSampledImage %21 diff --git a/naga/tests/out/spv/wgsl-index-by-value.spvasm b/naga/tests/out/spv/wgsl-index-by-value.spvasm index 09fedc4d676..e9ed297e2bf 100644 --- a/naga/tests/out/spv/wgsl-index-by-value.spvasm +++ b/naga/tests/out/spv/wgsl-index-by-value.spvasm @@ -36,10 +36,10 @@ OpDecorate %77 BuiltIn Position %36 = OpConstantComposite %9 %32 %35 %38 = OpTypePointer Function %9 %46 = OpTypeFunction %10 %3 %3 -%47 = OpConstant %10 1.0 -%48 = OpConstant %10 2.0 -%49 = OpConstant %10 3.0 -%50 = OpConstant %10 4.0 +%47 = OpConstant %10 1 +%48 = OpConstant %10 2 +%49 = OpConstant %10 3 +%50 = OpConstant %10 4 %51 = OpConstantComposite %12 %47 %48 %52 = OpConstantComposite %12 %49 %50 %53 = OpConstantComposite %11 %51 %52 diff --git a/naga/tests/out/spv/wgsl-int64.spvasm b/naga/tests/out/spv/wgsl-int64.spvasm index 141a95be586..c35098f7bd2 100644 --- a/naga/tests/out/spv/wgsl-int64.spvasm +++ b/naga/tests/out/spv/wgsl-int64.spvasm @@ -99,8 +99,8 @@ OpMemberDecorate %36 0 Offset 0 %78 = OpTypePointer Uniform %6 %79 = OpConstant %5 1 %88 = OpTypePointer Uniform %7 -%94 = OpConstant %7 -9.223372e18 -%95 = OpConstant %7 9.2233715e18 +%94 = OpConstant %7 -9223372000000000000 +%95 = OpConstant %7 9223371500000000000 %100 = OpTypePointer Uniform %3 %101 = OpConstant %5 7 %108 = OpTypePointer Uniform %4 @@ -128,8 +128,8 @@ OpMemberDecorate %36 0 Offset 0 %230 = OpConstant %4 18446744073709551615 %231 = OpConstant %4 5 %233 = OpTypePointer Function %4 -%264 = OpConstant %7 0.0 -%265 = OpConstant %7 1.8446743e19 +%264 = OpConstant %7 0 +%265 = OpConstant %7 18446743000000000000 %299 = OpTypePointer StorageBuffer %4 %306 = OpTypePointer StorageBuffer %8 %313 = OpTypePointer StorageBuffer %9 diff --git a/naga/tests/out/spv/wgsl-interface.fragment.spvasm b/naga/tests/out/spv/wgsl-interface.fragment.spvasm index 891b10d863d..e78d69121f3 100644 --- a/naga/tests/out/spv/wgsl-interface.fragment.spvasm +++ b/naga/tests/out/spv/wgsl-interface.fragment.spvasm @@ -56,8 +56,8 @@ OpDecorate %34 Location 0 %32 = OpVariable %33 Output %34 = OpVariable %31 Output %36 = OpTypeFunction %2 -%37 = OpConstant %3 0.0 -%38 = OpConstant %3 1.0 +%37 = OpConstant %3 0 +%38 = OpConstant %3 1 %35 = OpFunction %2 None %36 %14 = OpLabel %18 = OpLoad %4 %16 diff --git a/naga/tests/out/spv/wgsl-interface.vertex.spvasm b/naga/tests/out/spv/wgsl-interface.vertex.spvasm index 63ca57fa7d6..fa11c5b89f7 100644 --- a/naga/tests/out/spv/wgsl-interface.vertex.spvasm +++ b/naga/tests/out/spv/wgsl-interface.vertex.spvasm @@ -42,7 +42,7 @@ OpDecorate %26 BuiltIn PointSize %25 = OpTypePointer Output %3 %24 = OpVariable %25 Output %26 = OpVariable %25 Output -%27 = OpConstant %3 1.0 +%27 = OpConstant %3 1 %29 = OpTypeFunction %2 %30 = OpConstantComposite %4 %27 %27 %27 %27 %28 = OpFunction %2 None %29 diff --git a/naga/tests/out/spv/wgsl-interface.vertex_two_structs.spvasm b/naga/tests/out/spv/wgsl-interface.vertex_two_structs.spvasm index cad89cc551a..f83a5a624b3 100644 --- a/naga/tests/out/spv/wgsl-interface.vertex_two_structs.spvasm +++ b/naga/tests/out/spv/wgsl-interface.vertex_two_structs.spvasm @@ -38,10 +38,10 @@ OpDecorate %24 BuiltIn PointSize %22 = OpVariable %23 Output %25 = OpTypePointer Output %3 %24 = OpVariable %25 Output -%26 = OpConstant %3 1.0 +%26 = OpConstant %3 1 %28 = OpTypeFunction %2 %29 = OpConstant %6 2 -%30 = OpConstant %3 0.0 +%30 = OpConstant %3 0 %32 = OpTypePointer Function %6 %27 = OpFunction %2 None %28 %14 = OpLabel diff --git a/naga/tests/out/spv/wgsl-interpolate.spvasm b/naga/tests/out/spv/wgsl-interpolate.spvasm index ce0a9211522..91af2f3fe2c 100644 --- a/naga/tests/out/spv/wgsl-interpolate.spvasm +++ b/naga/tests/out/spv/wgsl-interpolate.spvasm @@ -176,36 +176,36 @@ OpDecorate %135 Location 11 %26 = OpVariable %18 Output %27 = OpVariable %18 Output %28 = OpVariable %18 Output -%29 = OpConstant %4 1.0 +%29 = OpConstant %4 1 %31 = OpTypeFunction %2 -%32 = OpConstant %4 2.0 -%33 = OpConstant %4 4.0 -%34 = OpConstant %4 5.0 -%35 = OpConstant %4 6.0 +%32 = OpConstant %4 2 +%33 = OpConstant %4 4 +%34 = OpConstant %4 5 +%35 = OpConstant %4 6 %36 = OpConstantComposite %5 %32 %33 %34 %35 %37 = OpConstant %6 8 %38 = OpConstant %6 9 %39 = OpConstant %6 10 -%40 = OpConstant %4 27.0 -%41 = OpConstant %4 64.0 -%42 = OpConstant %4 125.0 +%40 = OpConstant %4 27 +%41 = OpConstant %4 64 +%42 = OpConstant %4 125 %43 = OpConstantComposite %7 %41 %42 -%44 = OpConstant %4 216.0 -%45 = OpConstant %4 343.0 -%46 = OpConstant %4 512.0 +%44 = OpConstant %4 216 +%45 = OpConstant %4 343 +%46 = OpConstant %4 512 %47 = OpConstantComposite %8 %44 %45 %46 -%48 = OpConstant %4 255.0 -%49 = OpConstant %4 511.0 -%50 = OpConstant %4 1024.0 +%48 = OpConstant %4 255 +%49 = OpConstant %4 511 +%50 = OpConstant %4 1024 %51 = OpConstantComposite %8 %48 %49 %50 -%52 = OpConstant %4 729.0 -%53 = OpConstant %4 1000.0 -%54 = OpConstant %4 1331.0 -%55 = OpConstant %4 1728.0 +%52 = OpConstant %4 729 +%53 = OpConstant %4 1000 +%54 = OpConstant %4 1331 +%55 = OpConstant %4 1728 %56 = OpConstantComposite %5 %52 %53 %54 %55 -%57 = OpConstant %4 2197.0 -%58 = OpConstant %4 2744.0 -%59 = OpConstant %4 2812.0 +%57 = OpConstant %4 2197 +%58 = OpConstant %4 2744 +%59 = OpConstant %4 2812 %61 = OpTypePointer Function %9 %62 = OpConstantNull %9 %64 = OpTypePointer Function %5 diff --git a/naga/tests/out/spv/wgsl-interpolate_compat.spvasm b/naga/tests/out/spv/wgsl-interpolate_compat.spvasm index f6c72a053ef..f09a39d5a52 100644 --- a/naga/tests/out/spv/wgsl-interpolate_compat.spvasm +++ b/naga/tests/out/spv/wgsl-interpolate_compat.spvasm @@ -169,35 +169,35 @@ OpDecorate %129 Location 11 %25 = OpVariable %17 Output %26 = OpVariable %17 Output %27 = OpVariable %17 Output -%28 = OpConstant %4 1.0 +%28 = OpConstant %4 1 %30 = OpTypeFunction %2 -%31 = OpConstant %4 2.0 -%32 = OpConstant %4 4.0 -%33 = OpConstant %4 5.0 -%34 = OpConstant %4 6.0 +%31 = OpConstant %4 2 +%32 = OpConstant %4 4 +%33 = OpConstant %4 5 +%34 = OpConstant %4 6 %35 = OpConstantComposite %5 %31 %32 %33 %34 %36 = OpConstant %6 8 %37 = OpConstant %6 10 -%38 = OpConstant %4 27.0 -%39 = OpConstant %4 64.0 -%40 = OpConstant %4 125.0 +%38 = OpConstant %4 27 +%39 = OpConstant %4 64 +%40 = OpConstant %4 125 %41 = OpConstantComposite %7 %39 %40 -%42 = OpConstant %4 216.0 -%43 = OpConstant %4 343.0 -%44 = OpConstant %4 512.0 +%42 = OpConstant %4 216 +%43 = OpConstant %4 343 +%44 = OpConstant %4 512 %45 = OpConstantComposite %8 %42 %43 %44 -%46 = OpConstant %4 255.0 -%47 = OpConstant %4 511.0 -%48 = OpConstant %4 1024.0 +%46 = OpConstant %4 255 +%47 = OpConstant %4 511 +%48 = OpConstant %4 1024 %49 = OpConstantComposite %8 %46 %47 %48 -%50 = OpConstant %4 729.0 -%51 = OpConstant %4 1000.0 -%52 = OpConstant %4 1331.0 -%53 = OpConstant %4 1728.0 +%50 = OpConstant %4 729 +%51 = OpConstant %4 1000 +%52 = OpConstant %4 1331 +%53 = OpConstant %4 1728 %54 = OpConstantComposite %5 %50 %51 %52 %53 -%55 = OpConstant %4 2197.0 -%56 = OpConstant %4 2744.0 -%57 = OpConstant %4 2812.0 +%55 = OpConstant %4 2197 +%56 = OpConstant %4 2744 +%57 = OpConstant %4 2812 %59 = OpTypePointer Function %9 %60 = OpConstantNull %9 %62 = OpTypePointer Function %5 diff --git a/naga/tests/out/spv/wgsl-math-functions.spvasm b/naga/tests/out/spv/wgsl-math-functions.spvasm index a85644d4548..9aba53bc248 100644 --- a/naga/tests/out/spv/wgsl-math-functions.spvasm +++ b/naga/tests/out/spv/wgsl-math-functions.spvasm @@ -33,12 +33,12 @@ OpMemberDecorate %15 1 Offset 16 %15 = OpTypeStruct %4 %6 %16 = OpTypeVector %3 3 %19 = OpTypeFunction %2 -%20 = OpConstant %3 1.0 -%21 = OpConstant %3 0.0 +%20 = OpConstant %3 1 +%21 = OpConstant %3 0 %22 = OpConstantComposite %4 %21 %21 %21 %21 %23 = OpConstant %5 -1 %24 = OpConstantComposite %6 %23 %23 %23 %23 -%25 = OpConstant %3 -1.0 +%25 = OpConstant %3 -1 %26 = OpConstantComposite %4 %25 %25 %25 %25 %27 = OpConstantNull %7 %28 = OpConstant %9 4294967295 @@ -54,7 +54,7 @@ OpMemberDecorate %15 1 Offset 16 %38 = OpConstant %9 31 %39 = OpConstantComposite %8 %38 %38 %40 = OpConstant %5 2 -%41 = OpConstant %3 2.0 +%41 = OpConstant %3 2 %42 = OpConstantComposite %10 %20 %41 %43 = OpConstant %5 3 %44 = OpConstant %5 4 diff --git a/naga/tests/out/spv/wgsl-operators.spvasm b/naga/tests/out/spv/wgsl-operators.spvasm index cf24cc8102f..9ffe1ae1ea2 100644 --- a/naga/tests/out/spv/wgsl-operators.spvasm +++ b/naga/tests/out/spv/wgsl-operators.spvasm @@ -21,9 +21,9 @@ OpDecorate %513 BuiltIn WorkgroupId %12 = OpTypeMatrix %8 4 %13 = OpTypeMatrix %4 3 %14 = OpTypeVector %5 3 -%15 = OpConstant %3 1.0 +%15 = OpConstant %3 1 %16 = OpConstantComposite %4 %15 %15 %15 %15 -%17 = OpConstant %3 0.0 +%17 = OpConstant %3 0 %18 = OpConstantComposite %4 %17 %17 %17 %17 %19 = OpConstant %3 0.5 %20 = OpConstantComposite %4 %19 %19 %19 %19 @@ -44,17 +44,17 @@ OpDecorate %513 BuiltIn WorkgroupId %60 = OpConstantComposite %6 %58 %58 %58 %58 %65 = OpConstantComposite %6 %21 %21 %21 %21 %72 = OpTypeFunction %4 %3 %5 -%73 = OpConstant %3 2.0 +%73 = OpConstant %3 2 %74 = OpConstantComposite %7 %73 %73 -%75 = OpConstant %3 4.0 +%75 = OpConstant %3 4 %76 = OpConstantComposite %7 %75 %75 -%77 = OpConstant %3 8.0 +%77 = OpConstant %3 8 %78 = OpConstantComposite %7 %77 %77 %79 = OpConstant %5 2 %80 = OpConstantComposite %6 %79 %79 %79 %79 %93 = OpTypeFunction %7 %94 = OpConstantComposite %7 %15 %15 -%95 = OpConstant %3 3.0 +%95 = OpConstant %3 3 %96 = OpConstantComposite %7 %95 %95 %98 = OpTypePointer Function %7 %110 = OpTypeFunction %8 %8 diff --git a/naga/tests/out/spv/wgsl-overrides-ray-query.main.spvasm b/naga/tests/out/spv/wgsl-overrides-ray-query.main.spvasm index 4ceae75e596..34a8df87711 100644 --- a/naga/tests/out/spv/wgsl-overrides-ray-query.main.spvasm +++ b/naga/tests/out/spv/wgsl-overrides-ray-query.main.spvasm @@ -19,24 +19,24 @@ OpDecorate %10 DescriptorSet 0 OpDecorate %10 Binding 0 %2 = OpTypeVoid %3 = OpTypeFloat 32 -%4 = OpTypeAccelerationStructureNV +%4 = OpTypeAccelerationStructureKHR %5 = OpTypeRayQueryKHR %6 = OpTypeInt 32 0 %7 = OpTypeVector %3 3 %8 = OpTypeStruct %6 %6 %3 %3 %7 %7 -%9 = OpConstant %3 2.0 +%9 = OpConstant %3 2 %11 = OpTypePointer UniformConstant %4 %10 = OpVariable %11 UniformConstant %14 = OpTypeFunction %2 %16 = OpConstant %6 4 %17 = OpConstant %6 255 -%18 = OpConstant %3 34.0 -%19 = OpConstant %3 38.0 -%20 = OpConstant %3 46.0 +%18 = OpConstant %3 34 +%19 = OpConstant %3 38 +%20 = OpConstant %3 46 %21 = OpConstantComposite %7 %20 %20 %20 -%22 = OpConstant %3 58.0 -%23 = OpConstant %3 62.0 -%24 = OpConstant %3 74.0 +%22 = OpConstant %3 58 +%23 = OpConstant %3 62 +%24 = OpConstant %3 74 %25 = OpConstantComposite %7 %22 %23 %24 %26 = OpConstantComposite %8 %16 %17 %18 %19 %21 %25 %28 = OpTypePointer Function %5 diff --git a/naga/tests/out/spv/wgsl-overrides.main.spvasm b/naga/tests/out/spv/wgsl-overrides.main.spvasm index a685272479e..3b9eaca2497 100644 --- a/naga/tests/out/spv/wgsl-overrides.main.spvasm +++ b/naga/tests/out/spv/wgsl-overrides.main.spvasm @@ -13,21 +13,21 @@ OpExecutionMode %22 LocalSize 1 1 1 %5 = OpTypeInt 32 0 %6 = OpConstantTrue %3 %7 = OpConstant %4 2.3 -%8 = OpConstant %4 0.0 +%8 = OpConstant %4 0 %9 = OpConstantFalse %3 %10 = OpConstant %4 1.1 -%11 = OpConstant %4 2.0 +%11 = OpConstant %4 2 %12 = OpConstant %4 4.6 %13 = OpConstant %4 2.718 %14 = OpConstant %5 0 -%15 = OpConstant %4 10.0 -%16 = OpConstant %4 11.0 +%15 = OpConstant %4 10 +%16 = OpConstant %4 11 %18 = OpTypePointer Private %4 %17 = OpVariable %18 Private %16 %20 = OpConstantNull %4 %19 = OpVariable %18 Private %20 %23 = OpTypeFunction %2 -%24 = OpConstant %4 23.0 +%24 = OpConstant %4 23 %26 = OpTypePointer Function %4 %28 = OpTypePointer Function %3 %29 = OpConstantNull %3 diff --git a/naga/tests/out/spv/wgsl-padding.spvasm b/naga/tests/out/spv/wgsl-padding.spvasm index 2df29c96d4b..615965cc3e4 100644 --- a/naga/tests/out/spv/wgsl-padding.spvasm +++ b/naga/tests/out/spv/wgsl-padding.spvasm @@ -107,7 +107,7 @@ OpDecorate %25 BuiltIn Position %30 = OpConstant %10 0 %32 = OpTypePointer Uniform %11 %34 = OpTypePointer Uniform %13 -%36 = OpConstant %4 1.0 +%36 = OpConstant %4 1 %37 = OpConstantComposite %14 %36 %36 %36 %36 %39 = OpTypePointer Uniform %4 %40 = OpConstant %10 1 diff --git a/naga/tests/out/spv/wgsl-pointers.spvasm b/naga/tests/out/spv/wgsl-pointers.spvasm index 779b01b8af9..08867c95384 100644 --- a/naga/tests/out/spv/wgsl-pointers.spvasm +++ b/naga/tests/out/spv/wgsl-pointers.spvasm @@ -71,7 +71,7 @@ OpDecorate %11 Binding 0 %12 = OpTypePointer StorageBuffer %9 %11 = OpVariable %12 StorageBuffer %15 = OpTypeFunction %2 -%16 = OpConstant %6 10.0 +%16 = OpConstant %6 10 %17 = OpConstantComposite %5 %16 %16 %19 = OpTypePointer Function %4 %20 = OpConstantNull %4 diff --git a/naga/tests/out/spv/wgsl-policy-mix.spvasm b/naga/tests/out/spv/wgsl-policy-mix.spvasm index 28e8d92226f..8d9209d7b35 100644 --- a/naga/tests/out/spv/wgsl-policy-mix.spvasm +++ b/naga/tests/out/spv/wgsl-policy-mix.spvasm @@ -120,8 +120,8 @@ OpDecorate %115 BuiltIn LocalInvocationId %42 = OpConstant %8 0 %44 = OpTypePointer Uniform %12 %47 = OpConstant %4 0.707 -%48 = OpConstant %4 0.0 -%49 = OpConstant %4 1.0 +%48 = OpConstant %4 0 +%49 = OpConstant %4 1 %50 = OpConstantComposite %5 %47 %48 %48 %49 %51 = OpConstantComposite %5 %48 %47 %48 %49 %52 = OpConstantComposite %20 %50 %51 diff --git a/naga/tests/out/spv/wgsl-quad.spvasm b/naga/tests/out/spv/wgsl-quad.spvasm index a3532fb16e0..307fa304926 100644 --- a/naga/tests/out/spv/wgsl-quad.spvasm +++ b/naga/tests/out/spv/wgsl-quad.spvasm @@ -97,8 +97,8 @@ OpDecorate %60 Location 0 %24 = OpTypePointer Output %6 %23 = OpVariable %24 Output %26 = OpTypeFunction %2 -%27 = OpConstant %4 0.0 -%28 = OpConstant %4 1.0 +%27 = OpConstant %4 0 +%28 = OpConstant %4 1 %35 = OpTypePointer Output %4 %37 = OpTypeInt 32 0 %36 = OpConstant %37 1 diff --git a/naga/tests/out/spv/wgsl-ray-query.spvasm b/naga/tests/out/spv/wgsl-ray-query.spvasm index 138efe2c352..d49ae40b2f8 100644 --- a/naga/tests/out/spv/wgsl-ray-query.spvasm +++ b/naga/tests/out/spv/wgsl-ray-query.spvasm @@ -43,7 +43,7 @@ OpMemberDecorate %18 0 Offset 0 %2 = OpTypeVoid %3 = OpTypeFloat 32 %4 = OpTypeVector %3 3 -%5 = OpTypeAccelerationStructureNV +%5 = OpTypeAccelerationStructureKHR %6 = OpTypeInt 32 0 %7 = OpTypeVector %3 2 %8 = OpTypeBool @@ -62,7 +62,7 @@ OpMemberDecorate %18 0 Offset 0 %27 = OpConstant %6 4 %28 = OpConstant %6 255 %29 = OpConstant %3 0.1 -%30 = OpConstant %3 100.0 +%30 = OpConstant %3 100 %32 = OpTypePointer Function %11 %45 = OpTypeVector %6 2 %46 = OpTypePointer Function %45 @@ -89,9 +89,9 @@ OpMemberDecorate %18 0 Offset 0 %113 = OpConstant %6 7 %115 = OpConstant %6 8 %123 = OpTypeFunction %4 %4 %10 -%124 = OpConstant %3 1.0 +%124 = OpConstant %3 1 %125 = OpConstant %3 2.4 -%126 = OpConstant %3 0.0 +%126 = OpConstant %3 0 %141 = OpTypeFunction %2 %143 = OpTypePointer StorageBuffer %13 %145 = OpConstantComposite %4 %126 %126 %126 @@ -99,7 +99,7 @@ OpMemberDecorate %18 0 Offset 0 %149 = OpTypePointer StorageBuffer %6 %154 = OpTypePointer StorageBuffer %4 %162 = OpConstantComposite %12 %27 %28 %29 %30 %145 %146 -%163 = OpConstant %3 10.0 +%163 = OpConstant %3 10 %76 = OpFunction %10 None %75 %78 = OpFunctionParameter %32 %79 = OpLabel diff --git a/naga/tests/out/spv/wgsl-select.spvasm b/naga/tests/out/spv/wgsl-select.spvasm index d0011c464f8..9725ab38beb 100644 --- a/naga/tests/out/spv/wgsl-select.spvasm +++ b/naga/tests/out/spv/wgsl-select.spvasm @@ -13,11 +13,11 @@ OpExecutionMode %8 LocalSize 1 1 1 %6 = OpTypeInt 32 1 %5 = OpTypeVector %6 2 %9 = OpTypeFunction %2 -%10 = OpConstant %4 1.0 +%10 = OpConstant %4 1 %11 = OpConstant %6 1 %12 = OpConstant %6 2 %13 = OpConstantComposite %5 %11 %12 -%14 = OpConstant %4 0.0 +%14 = OpConstant %4 0 %15 = OpConstantComposite %3 %10 %14 %16 = OpConstantComposite %3 %14 %10 %18 = OpTypePointer Function %5 diff --git a/naga/tests/out/spv/wgsl-separate-entry-points.fragment.spvasm b/naga/tests/out/spv/wgsl-separate-entry-points.fragment.spvasm index e29ce8f15db..ae58bae874f 100644 --- a/naga/tests/out/spv/wgsl-separate-entry-points.fragment.spvasm +++ b/naga/tests/out/spv/wgsl-separate-entry-points.fragment.spvasm @@ -12,7 +12,7 @@ OpDecorate %14 Location 0 %4 = OpTypeFloat 32 %3 = OpTypeVector %4 4 %7 = OpTypeFunction %2 -%8 = OpConstant %4 0.0 +%8 = OpConstant %4 0 %15 = OpTypePointer Output %3 %14 = OpVariable %15 Output %17 = OpConstantNull %3 diff --git a/naga/tests/out/spv/wgsl-shadow.spvasm b/naga/tests/out/spv/wgsl-shadow.spvasm index ea131ae6d03..1360528131a 100644 --- a/naga/tests/out/spv/wgsl-shadow.spvasm +++ b/naga/tests/out/spv/wgsl-shadow.spvasm @@ -267,8 +267,8 @@ OpDecorate %227 Location 0 %40 = OpTypePointer UniformConstant %21 %39 = OpVariable %40 UniformConstant %45 = OpTypeFunction %4 %7 %6 -%48 = OpConstant %4 0.0 -%49 = OpConstant %4 1.0 +%48 = OpConstant %4 0 +%49 = OpConstant %4 1 %50 = OpConstant %4 0.5 %51 = OpConstant %4 -0.5 %52 = OpConstantComposite %22 %50 %51 diff --git a/naga/tests/out/spv/wgsl-skybox.spvasm b/naga/tests/out/spv/wgsl-skybox.spvasm index 7bc7b30f6da..f3e4be2cc22 100644 --- a/naga/tests/out/spv/wgsl-skybox.spvasm +++ b/naga/tests/out/spv/wgsl-skybox.spvasm @@ -65,9 +65,9 @@ OpDecorate %105 Location 0 %48 = OpTypePointer Uniform %8 %49 = OpConstant %9 0 %51 = OpConstant %10 2 -%52 = OpConstant %4 4.0 -%53 = OpConstant %4 1.0 -%54 = OpConstant %4 0.0 +%52 = OpConstant %4 4 +%53 = OpConstant %4 1 +%54 = OpConstant %4 0 %56 = OpTypePointer Function %10 %57 = OpConstantNull %10 %59 = OpConstantNull %10 diff --git a/naga/tests/out/spv/wgsl-storage-textures.spvasm b/naga/tests/out/spv/wgsl-storage-textures.spvasm index c043c2b94e2..167d5f49299 100644 --- a/naga/tests/out/spv/wgsl-storage-textures.spvasm +++ b/naga/tests/out/spv/wgsl-storage-textures.spvasm @@ -48,7 +48,7 @@ OpDecorate %15 Binding 2 %24 = OpTypeVector %22 2 %25 = OpConstantComposite %24 %23 %23 %27 = OpTypeVector %4 4 -%36 = OpConstant %4 0.0 +%36 = OpConstant %4 0 %37 = OpConstantComposite %27 %36 %36 %36 %36 %17 = OpFunction %2 None %18 %16 = OpLabel diff --git a/naga/tests/out/spv/wgsl-struct-layout.spvasm b/naga/tests/out/spv/wgsl-struct-layout.spvasm index 42899de9b58..31611dad6a9 100644 --- a/naga/tests/out/spv/wgsl-struct-layout.spvasm +++ b/naga/tests/out/spv/wgsl-struct-layout.spvasm @@ -76,7 +76,7 @@ OpDecorate %77 BuiltIn Position %29 = OpTypePointer Output %6 %28 = OpVariable %29 Output %31 = OpTypeFunction %2 -%32 = OpConstant %3 0.0 +%32 = OpConstant %3 0 %33 = OpConstantComposite %6 %32 %32 %32 %32 %37 = OpVariable %23 Input %39 = OpVariable %26 Input diff --git a/naga/tests/out/spv/wgsl-texture-arg.spvasm b/naga/tests/out/spv/wgsl-texture-arg.spvasm index ebb110e8fd8..23bd0ce2977 100644 --- a/naga/tests/out/spv/wgsl-texture-arg.spvasm +++ b/naga/tests/out/spv/wgsl-texture-arg.spvasm @@ -44,7 +44,7 @@ OpDecorate %27 Location 0 %12 = OpTypePointer UniformConstant %6 %11 = OpVariable %12 UniformConstant %19 = OpTypeFunction %7 %10 %12 -%20 = OpConstant %5 0.0 +%20 = OpConstant %5 0 %21 = OpConstantComposite %8 %20 %20 %23 = OpTypeSampledImage %4 %28 = OpTypePointer Output %7 diff --git a/naga/tests/out/spv/wgsl-type-inference.spvasm b/naga/tests/out/spv/wgsl-type-inference.spvasm index adcaa8094e6..d56e1fdac6b 100644 --- a/naga/tests/out/spv/wgsl-type-inference.spvasm +++ b/naga/tests/out/spv/wgsl-type-inference.spvasm @@ -15,11 +15,11 @@ OpExecutionMode %18 LocalSize 1 1 1 %8 = OpTypeVector %4 2 %7 = OpTypeMatrix %8 2 %9 = OpConstant %3 1 -%10 = OpConstant %4 1.0 +%10 = OpConstant %4 1 %11 = OpConstantNull %6 %12 = OpConstant %5 1 %13 = OpConstantComposite %6 %12 %12 %12 %12 -%14 = OpConstant %4 0.0 +%14 = OpConstant %4 0 %15 = OpConstantComposite %8 %14 %14 %16 = OpConstantComposite %7 %15 %15 %19 = OpTypeFunction %2 From 1da2177547ef22d70eaf13dbb6a52bca00f72093 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Tue, 15 Jul 2025 10:06:11 -0700 Subject: [PATCH 022/303] Add skip conditions to CTS runner (#7949) --- .github/workflows/cts.yml | 5 ++- xtask/src/cts.rs | 87 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 86 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cts.yml b/.github/workflows/cts.yml index 2bc0680cb29..d5e98950491 100644 --- a/.github/workflows/cts.yml +++ b/.github/workflows/cts.yml @@ -23,16 +23,19 @@ jobs: - name: Windows x86_64 os: windows-2022 target: x86_64-pc-windows-msvc + backend: dx12 # Mac - name: Mac aarch64 os: macos-14 target: x86_64-apple-darwin + backend: metal # Linux - name: Linux x86_64 os: ubuntu-24.04 target: x86_64-unknown-linux-gnu + backend: vulkan name: CTS ${{ matrix.name }} runs-on: ${{ matrix.os }} @@ -84,7 +87,7 @@ jobs: - name: run CTS shell: bash - run: cargo xtask cts --llvm-cov + run: cargo xtask cts --llvm-cov --backend ${{ matrix.backend }} - name: Generate coverage report id: coverage diff --git a/xtask/src/cts.rs b/xtask/src/cts.rs index ff3a6cbe8f1..31f3fad3493 100644 --- a/xtask/src/cts.rs +++ b/xtask/src/cts.rs @@ -1,6 +1,39 @@ +//! Interface for running the WebGPU CTS (Conformance Test Suite) against wgpu. +//! +//! To run the default set of tests from `cts_runner/test.lst`: +//! +//! ```sh +//! cargo xtask cts +//! ``` +//! +//! To run a specific test selector: +//! +//! ```sh +//! cargo xtask cts 'webgpu:api,operation,command_buffer,basic:*' +//! ``` +//! +//! You can also supply your own test list in a file: +//! +//! ```sh +//! cargo xtask cts -f your_tests.lst +//! ``` +//! +//! Each line in a test list file is a test selector that will be passed to the +//! CTS's own command line runner. Note that wildcards may only be used to specify +//! running all tests in a file, or all subtests in a test. +//! +//! A test line may optionally contain a `fails-if(backend)` clause. This +//! indicates that the test should be skipped on that backend, however, the +//! runner will only do so if the `--backend` flag is passed to tell it where +//! it is running. +//! +//! Lines starting with `//` or `#` in the test list are treated as comments and +//! ignored. + use anyhow::{bail, Context}; use pico_args::Arguments; -use std::ffi::OsString; +use regex_lite::{Regex, RegexBuilder}; +use std::{ffi::OsString, sync::LazyLock}; use xshell::Shell; /// Path within the repository where the CTS will be checked out. @@ -15,16 +48,42 @@ const CTS_GIT_URL: &str = "https://github.com/gpuweb/cts.git"; /// Path to default CTS test list. const CTS_DEFAULT_TEST_LIST: &str = "cts_runner/test.lst"; +static TEST_LINE_REGEX: LazyLock = LazyLock::new(|| { + RegexBuilder::new(r#"(?:fails-if\s*\(\s*(?\w+)\s*\)\s+)?(?.*)"#) + .build() + .unwrap() +}); + +#[derive(Default)] +struct TestLine { + pub selector: OsString, + pub fails_if: Option, +} + pub fn run_cts(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { let skip_checkout = args.contains("--skip-checkout"); let llvm_cov = args.contains("--llvm-cov"); + let running_on_backend = args.opt_value_from_str::<_, String>("--backend")?; + + if running_on_backend.is_none() { + log::warn!( + "fails-if conditions are only evaluated if a backend is specified with --backend" + ); + } let mut list_files = Vec::::new(); while let Some(file) = args.opt_value_from_str("-f")? { list_files.push(file); } - let mut tests = args.finish(); + let mut tests = args + .finish() + .into_iter() + .map(|selector| TestLine { + selector, + ..Default::default() + }) + .collect::>(); if tests.is_empty() && list_files.is_empty() { log::info!("Reading default test list from {CTS_DEFAULT_TEST_LIST}"); @@ -35,7 +94,13 @@ pub fn run_cts(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { tests.extend(shell.read_file(file)?.lines().filter_map(|line| { let trimmed = line.trim(); let is_comment = trimmed.starts_with("//") || trimmed.starts_with("#"); - (!trimmed.is_empty() && !is_comment).then(|| OsString::from(trimmed)) + let captures = TEST_LINE_REGEX + .captures(trimmed) + .expect("Invalid test line: {trimmed}"); + (!trimmed.is_empty() && !is_comment).then(|| TestLine { + selector: OsString::from(&captures["selector"]), + fails_if: captures.name("fails_if").map(|m| m.as_str().to_string()), + }) })) } @@ -142,7 +207,19 @@ pub fn run_cts(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { log::info!("Running CTS"); for test in &tests { - log::info!("Running {}", test.to_string_lossy()); + match (&test.fails_if, &running_on_backend) { + (Some(backend), Some(running_on_backend)) if backend == running_on_backend => { + log::info!( + "Skipping {} on {} backend", + test.selector.to_string_lossy(), + running_on_backend, + ); + continue; + } + _ => {} + } + + log::info!("Running {}", test.selector.to_string_lossy()); shell .cmd("cargo") .args(run_flags) @@ -150,7 +227,7 @@ pub fn run_cts(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { .args(["-p", "cts_runner"]) .args(["--bin", "cts_runner"]) .args(["--", "./tools/run_deno", "--verbose"]) - .args([test]) + .args([&test.selector]) .run() .context("CTS failed")?; } From 13d0cd4d585e28d263baf2cdfefd79b46a3ee634 Mon Sep 17 00:00:00 2001 From: Lucas Abel <22837557+uael@users.noreply.github.com> Date: Wed, 16 Jul 2025 18:49:03 +0200 Subject: [PATCH 023/303] [core] fix invalid read in `Queue::write_texture` (#7893) --- wgpu-core/src/device/queue.rs | 3 +-- wgpu-core/src/resource.rs | 7 +++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 10df7aaf1a9..22261c13e46 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -860,7 +860,6 @@ impl Queue { wgt::BufferSize::new(stage_bytes_per_row as u64 * block_rows_in_copy as u64) .unwrap(); let mut staging_buffer = StagingBuffer::new(&self.device, stage_size)?; - let copy_bytes_per_row = stage_bytes_per_row.min(bytes_per_row) as usize; for layer in 0..size.depth_or_array_layers { let rows_offset = layer * rows_per_image; for row in rows_offset..rows_offset + height_in_blocks { @@ -871,7 +870,7 @@ impl Queue { data, src_offset as isize, dst_offset as isize, - copy_bytes_per_row, + bytes_in_last_row as usize, ) } } diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index d8e80702f0d..afdf73e3f0c 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -1076,6 +1076,13 @@ impl StagingBuffer { size: usize, ) { unsafe { + debug_assert!( + (src_offset + size as isize) as usize <= data.len(), + "src_offset + size must be in-bounds: src_offset = {}, size = {}, data.len() = {}", + src_offset, + size, + data.len() + ); core::ptr::copy_nonoverlapping( data.as_ptr().offset(src_offset), self.ptr.as_ptr().offset(dst_offset), From 15f7c7e561d5fd7dd2057fcea74c3242052103d1 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 10 Jul 2025 21:48:50 -0400 Subject: [PATCH 024/303] Remove unneeded comment --- wgpu/src/lib.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 29243255890..c8bc687d52d 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -52,12 +52,6 @@ mod dispatch; mod macros; pub mod util; -// -// -// Private re-exports -// -// - // // // Public re-exports From f83af61f74ac043ec1602c3a179d2d49a4c03f7f Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 10 Jul 2025 21:59:35 -0400 Subject: [PATCH 025/303] Clarify `naga` psuedo-feature in wgpu --- wgpu/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index c8bc687d52d..44791dea2bb 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -11,7 +11,7 @@ //! complicated cases. //! //! - **`wgpu_core`** --- Enabled when there is any non-webgpu backend enabled on the platform. -//! - **`naga`** ---- Enabled when any non-wgsl shader input is enabled. +//! - **`naga`** --- Enabled when target `glsl` or `spirv`` input is enabled, or when `wgpu_core` is enabled. //! #![no_std] From f7b672f28bb2109d1da85ef2a8842d344cc0ac12 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 10 Jul 2025 22:14:36 -0400 Subject: [PATCH 026/303] Update release checklist --- docs/release-checklist.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-checklist.md b/docs/release-checklist.md index a314e6c70da..f533255ccaa 100644 --- a/docs/release-checklist.md +++ b/docs/release-checklist.md @@ -50,6 +50,7 @@ Day of Release: - Create a new tag called `vX.Y.Z` and push it to the repo. - Create a new release on the `wgpu` repo with the changelog from this version, targeting that tag - Create a branch with the with the new version `vX` and push it to the repo. + - On this branch, remove the [!NOTE] at the top of [wgpu/examples/README.md]. - Complete the release's milestone on GitHub. - Create a new milestone for the next release, in 12 weeks time. - Update the release checklist with any needed changes. From e5b10e07e89b2ff3fea6038c64fcf25ac1a6f2a0 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 10 Jul 2025 22:14:36 -0400 Subject: [PATCH 027/303] Adjust InstanceDescriptor docs --- wgpu-types/src/instance.rs | 23 +++++++++++++++++++++-- wgpu/src/api/instance.rs | 38 +++++++++++--------------------------- wgpu/src/lib.rs | 21 +++++++++++++++++++-- 3 files changed, 51 insertions(+), 31 deletions(-) diff --git a/wgpu-types/src/instance.rs b/wgpu-types/src/instance.rs index 4bafabb5fba..a427b1b1c3e 100644 --- a/wgpu-types/src/instance.rs +++ b/wgpu-types/src/instance.rs @@ -8,15 +8,34 @@ use crate::Backends; use crate::{Backend, DownlevelFlags}; /// Options for creating an instance. +/// +/// If you want to allow control of instance settings via environment variables, call either +/// [`InstanceDescriptor::from_env_or_default()`] or [`InstanceDescriptor::with_env()`]. Each type +/// within this descriptor has its own equivalent methods, so you can select which options you want +/// to expose to influence from the environment. #[derive(Clone, Debug)] pub struct InstanceDescriptor { - /// Which `Backends` to enable. + /// Which [`Backends`] to enable. + /// + /// [`Backends::BROWSER_WEBGPU`] has an additional effect: + /// If it is set and a [`navigator.gpu`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/gpu) + /// object is present, this instance will *only* be able to create WebGPU adapters. + /// + /// ⚠️ On some browsers this check is insufficient to determine whether WebGPU is supported, + /// as the browser may define the `navigator.gpu` object, but be unable to create any WebGPU adapters. + /// For targeting _both_ WebGPU & WebGL, it is recommended to use [`crate::util::new_instance_with_webgpu_detection`](../wgpu/util/fn.new_instance_with_webgpu_detection.html). + /// + /// If you instead want to force use of WebGL, either disable the `webgpu` compile-time feature + /// or don't include the [`Backends::BROWSER_WEBGPU`] flag in this field. + /// If it is set and WebGPU support is *not* detected, the instance will use `wgpu-core` + /// to create adapters, meaning that if the `webgl` feature is enabled, it is able to create + /// a WebGL adapter. pub backends: Backends, /// Flags to tune the behavior of the instance. pub flags: InstanceFlags, /// Memory budget thresholds used by some backends. pub memory_budget_thresholds: MemoryBudgetThresholds, - /// Options the control the behavior of various backends. + /// Options the control the behavior of specific backends. pub backend_options: BackendOptions, } diff --git a/wgpu/src/api/instance.rs b/wgpu/src/api/instance.rs index 26703a48eff..7d7e6eaf0fb 100644 --- a/wgpu/src/api/instance.rs +++ b/wgpu/src/api/instance.rs @@ -21,7 +21,7 @@ bitflags::bitflags! { } } -/// Context for all other wgpu objects. Instance of wgpu. +/// Contains the various entry points to start interacting with the system's GPUs. /// /// This is the first thing you create when using wgpu. /// Its primary use is to create [`Adapter`]s and [`Surface`]s. @@ -84,33 +84,14 @@ impl Instance { backends } - /// Create an new instance of wgpu. - /// - /// # Arguments - /// - /// - `instance_desc` - Has fields for which [backends][Backends] wgpu will choose - /// during instantiation, and which [DX12 shader compiler][Dx12Compiler] wgpu will use. - /// - /// [`Backends::BROWSER_WEBGPU`] takes a special role: - /// If it is set and a [`navigator.gpu`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/gpu) - /// object is present, this instance will *only* be able to create WebGPU adapters. - /// - /// ⚠️ On some browsers this check is insufficient to determine whether WebGPU is supported, - /// as the browser may define the `navigator.gpu` object, but be unable to create any WebGPU adapters. - /// For targeting _both_ WebGPU & WebGL is recommended to use [`crate::util::new_instance_with_webgpu_detection`]. - /// - /// If you instead want to force use of WebGL, either disable the `webgpu` compile-time feature - /// or don't add the [`Backends::BROWSER_WEBGPU`] flag to the the `instance_desc`'s `backends` field. - /// If it is set and WebGPU support is *not* detected, the instance will use wgpu-core - /// to create adapters. Meaning that if the `webgl` feature is enabled, it is able to create - /// a WebGL adapter. + /// Create an new instance of wgpu using the given options and enabled backends. /// /// # Panics /// - /// If no backend feature for the active target platform is enabled, - /// this method will panic, see [`Instance::enabled_backend_features()`]. + /// - If no backend feature for the active target platform is enabled, + /// this method will panic; see [`Instance::enabled_backend_features()`]. #[allow(clippy::allow_attributes, unreachable_code)] - pub fn new(_instance_desc: &InstanceDescriptor) -> Self { + pub fn new(desc: &InstanceDescriptor) -> Self { if Self::enabled_backend_features().is_empty() { panic!( "No wgpu backend feature that is implemented for the target platform was enabled. \ @@ -121,14 +102,14 @@ impl Instance { #[cfg(webgpu)] { let is_only_available_backend = !cfg!(wgpu_core); - let requested_webgpu = _instance_desc.backends.contains(Backends::BROWSER_WEBGPU); + let requested_webgpu = desc.backends.contains(Backends::BROWSER_WEBGPU); let support_webgpu = crate::backend::get_browser_gpu_property() .map(|maybe_gpu| maybe_gpu.is_some()) .unwrap_or(false); if is_only_available_backend || (requested_webgpu && support_webgpu) { return Self { - inner: crate::backend::ContextWebGpu::new(_instance_desc).into(), + inner: crate::backend::ContextWebGpu::new(desc).into(), }; } } @@ -136,10 +117,13 @@ impl Instance { #[cfg(wgpu_core)] { return Self { - inner: crate::backend::ContextWgpuCore::new(_instance_desc).into(), + inner: crate::backend::ContextWgpuCore::new(desc).into(), }; } + // Silence unused variable warnings without adding _ to the parameter name (which shows up in docs). + let _ = desc; + unreachable!( "Earlier check of `enabled_backend_features` should have prevented getting here!" ); diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 44791dea2bb..0a3ded75f73 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -1,6 +1,23 @@ -//! A cross-platform graphics and compute library based on [WebGPU](https://gpuweb.github.io/gpuweb/). +//! `wgpu` is a cross-platform, safe, pure-Rust graphics API. It runs natively on +//! Vulkan, Metal, D3D12, and OpenGL; and on top of WebGL2 and WebGPU on wasm. //! -//! To start using the API, create an [`Instance`]. +//! The API is based on the [WebGPU standard][webgpu]. It serves as the core of the +//! WebGPU integration in Firefox, Servo, and Deno. +//! +//! [webgpu]: https://gpuweb.github.io/gpuweb/ +//! +//! ## Getting Started +//! +//! The main entry point to the API is the [`Instance`] type, from which you can create [`Adapter`], [`Device`], and [`Surface`]. +//! +//! If you are new to `wgpu` and graphics programming, we recommend reading +//! and . The latter is a WebGPU +//! tutorial, but the concepts are nearly identical to `wgpu`. +//! +//! There are examples for this version [available on GitHub](https://github.com/gfx-rs/wgpu/tree/v26/examples#readme).. +//! +//! The API is refcounted, so all handles are cloneable, and if you create a resource which references another, +//! it will automatically keep dependent resources alive. //! //! ## Feature flags #![doc = document_features::document_features!()] From 81b3e7ce140022a9382e8be73eaecd3cb2bb5bca Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 10 Jul 2025 22:33:46 -0400 Subject: [PATCH 028/303] Rearrange methods on Instance --- wgpu/src/api/instance.rs | 259 ++++++++++++++++++++------------------- 1 file changed, 133 insertions(+), 126 deletions(-) diff --git a/wgpu/src/api/instance.rs b/wgpu/src/api/instance.rs index 7d7e6eaf0fb..c830f8203df 100644 --- a/wgpu/src/api/instance.rs +++ b/wgpu/src/api/instance.rs @@ -53,37 +53,6 @@ impl Default for Instance { } impl Instance { - /// Returns which backends can be picked for the current build configuration. - /// - /// The returned set depends on a combination of target platform and enabled features. - /// This does *not* do any runtime checks and is exclusively based on compile time information. - /// - /// `InstanceDescriptor::backends` does not need to be a subset of this, - /// but any backend that is not in this set, will not be picked. - pub const fn enabled_backend_features() -> Backends { - let mut backends = Backends::empty(); - // `.set` and `|=` don't work in a `const` context. - if cfg!(noop) { - backends = backends.union(Backends::NOOP); - } - if cfg!(vulkan) { - backends = backends.union(Backends::VULKAN); - } - if cfg!(any(gles, webgl)) { - backends = backends.union(Backends::GL); - } - if cfg!(metal) { - backends = backends.union(Backends::METAL); - } - if cfg!(dx12) { - backends = backends.union(Backends::DX12); - } - if cfg!(webgpu) { - backends = backends.union(Backends::BROWSER_WEBGPU); - } - backends - } - /// Create an new instance of wgpu using the given options and enabled backends. /// /// # Panics @@ -129,83 +98,43 @@ impl Instance { ); } - /// Create an new instance of wgpu from a wgpu-hal instance. - /// - /// # Arguments - /// - /// - `hal_instance` - wgpu-hal instance. + /// Returns which backends can be picked for the current build configuration. /// - /// # Safety + /// The returned set depends on a combination of target platform and enabled features. + /// This does *not* do any runtime checks and is exclusively based on compile time information. /// - /// Refer to the creation of wgpu-hal Instance for every backend. - #[cfg(wgpu_core)] - pub unsafe fn from_hal(hal_instance: A::Instance) -> Self { - Self { - inner: unsafe { - crate::backend::ContextWgpuCore::from_hal_instance::(hal_instance).into() - }, + /// `InstanceDescriptor::backends` does not need to be a subset of this, + /// but any backend that is not in this set, will not be picked. + pub const fn enabled_backend_features() -> Backends { + let mut backends = Backends::empty(); + // `.set` and `|=` don't work in a `const` context. + if cfg!(noop) { + backends = backends.union(Backends::NOOP); } - } - - /// Get the [`wgpu_hal`] instance from this `Instance`. - /// - /// Find the Api struct corresponding to the active backend in [`wgpu_hal::api`], - /// and pass that struct to the to the `A` type parameter. - /// - /// Returns a guard that dereferences to the type of the hal backend - /// which implements [`A::Instance`]. - /// - /// # Errors - /// - /// This method will return None if: - /// - The instance is not from the backend specified by `A`. - /// - The instance is from the `webgpu` or `custom` backend. - /// - /// # Safety - /// - /// - The returned resource must not be destroyed unless the guard - /// is the last reference to it and it is not in use by the GPU. - /// The guard and handle may be dropped at any time however. - /// - All the safety requirements of wgpu-hal must be upheld. - /// - /// [`A::Instance`]: hal::Api::Instance - #[cfg(wgpu_core)] - pub unsafe fn as_hal(&self) -> Option<&A::Instance> { - self.inner - .as_core_opt() - .and_then(|ctx| unsafe { ctx.instance_as_hal::() }) - } - - /// Create an new instance of wgpu from a wgpu-core instance. - /// - /// # Arguments - /// - /// - `core_instance` - wgpu-core instance. - /// - /// # Safety - /// - /// Refer to the creation of wgpu-core Instance. - #[cfg(wgpu_core)] - pub unsafe fn from_core(core_instance: wgc::instance::Instance) -> Self { - Self { - inner: unsafe { - crate::backend::ContextWgpuCore::from_core_instance(core_instance).into() - }, + if cfg!(vulkan) { + backends = backends.union(Backends::VULKAN); } - } - - #[cfg(custom)] - /// Creates instance from custom context implementation - pub fn from_custom(instance: T) -> Self { - Self { - inner: dispatch::DispatchInstance::Custom(backend::custom::DynContext::new(instance)), + if cfg!(any(gles, webgl)) { + backends = backends.union(Backends::GL); } + if cfg!(metal) { + backends = backends.union(Backends::METAL); + } + if cfg!(dx12) { + backends = backends.union(Backends::DX12); + } + if cfg!(webgpu) { + backends = backends.union(Backends::BROWSER_WEBGPU); + } + backends } - #[cfg(custom)] - /// Returns custom implementation of Instance (if custom backend and is internally T) - pub fn as_custom(&self) -> Option<&T> { - self.inner.as_custom() + /// Returns the set of [WGSL language extensions] supported by this instance. + /// + /// [WGSL language extensions]: https://www.w3.org/TR/webgpu/#gpuwgsllanguagefeatures + #[cfg(feature = "wgsl")] + pub fn wgsl_language_features(&self) -> WgslLanguageFeatures { + self.inner.wgsl_language_features() } /// Retrieves all available [`Adapter`]s that match the given [`Backends`]. @@ -248,26 +177,6 @@ impl Instance { async move { future.await.map(|adapter| Adapter { inner: adapter }) } } - /// Converts a wgpu-hal `ExposedAdapter` to a wgpu [`Adapter`]. - /// - /// # Safety - /// - /// `hal_adapter` must be created from this instance internal handle. - #[cfg(wgpu_core)] - pub unsafe fn create_adapter_from_hal( - &self, - hal_adapter: hal::ExposedAdapter, - ) -> Adapter { - let core_instance = self.inner.as_core(); - let adapter = unsafe { core_instance.create_adapter_from_hal(hal_adapter) }; - let core = backend::wgpu_core::CoreAdapter { - context: core_instance.clone(), - id: adapter, - }; - - Adapter { inner: core.into() } - } - /// Creates a new surface targeting a given window/canvas/surface/etc.. /// /// Internally, this creates surfaces for all backends that are enabled for this instance. @@ -393,12 +302,110 @@ impl Instance { pub fn generate_report(&self) -> Option { self.inner.as_core_opt().map(|ctx| ctx.generate_report()) } +} - /// Returns set of supported WGSL language extensions supported by this instance. +/// Interop with wgpu-hal. +#[cfg(wgpu_core)] +impl Instance { + /// Create an new instance of wgpu from a wgpu-hal instance. /// - /// - #[cfg(feature = "wgsl")] - pub fn wgsl_language_features(&self) -> WgslLanguageFeatures { - self.inner.wgsl_language_features() + /// # Arguments + /// + /// - `hal_instance` - wgpu-hal instance. + /// + /// # Safety + /// + /// Refer to the creation of wgpu-hal Instance for every backend. + pub unsafe fn from_hal(hal_instance: A::Instance) -> Self { + Self { + inner: unsafe { + crate::backend::ContextWgpuCore::from_hal_instance::(hal_instance).into() + }, + } + } + + /// Get the [`wgpu_hal`] instance from this `Instance`. + /// + /// Find the Api struct corresponding to the active backend in [`wgpu_hal::api`], + /// and pass that struct to the to the `A` type parameter. + /// + /// Returns a guard that dereferences to the type of the hal backend + /// which implements [`A::Instance`]. + /// + /// # Errors + /// + /// This method will return None if: + /// - The instance is not from the backend specified by `A`. + /// - The instance is from the `webgpu` or `custom` backend. + /// + /// # Safety + /// + /// - The returned resource must not be destroyed unless the guard + /// is the last reference to it and it is not in use by the GPU. + /// The guard and handle may be dropped at any time however. + /// - All the safety requirements of wgpu-hal must be upheld. + /// + /// [`A::Instance`]: hal::Api::Instance + pub unsafe fn as_hal(&self) -> Option<&A::Instance> { + self.inner + .as_core_opt() + .and_then(|ctx| unsafe { ctx.instance_as_hal::() }) + } + + /// Converts a wgpu-hal `ExposedAdapter` to a wgpu [`Adapter`]. + /// + /// # Safety + /// + /// `hal_adapter` must be created from this instance internal handle. + pub unsafe fn create_adapter_from_hal( + &self, + hal_adapter: hal::ExposedAdapter, + ) -> Adapter { + let core_instance = self.inner.as_core(); + let adapter = unsafe { core_instance.create_adapter_from_hal(hal_adapter) }; + let core = backend::wgpu_core::CoreAdapter { + context: core_instance.clone(), + id: adapter, + }; + + Adapter { inner: core.into() } + } +} + +/// Interop with wgpu-core. +#[cfg(wgpu_core)] +impl Instance { + /// Create an new instance of wgpu from a wgpu-core instance. + /// + /// # Arguments + /// + /// - `core_instance` - wgpu-core instance. + /// + /// # Safety + /// + /// Refer to the creation of wgpu-core Instance. + pub unsafe fn from_core(core_instance: wgc::instance::Instance) -> Self { + Self { + inner: unsafe { + crate::backend::ContextWgpuCore::from_core_instance(core_instance).into() + }, + } + } +} + +/// Interop with custom backends. +#[cfg(custom)] +impl Instance { + /// Creates instance from custom context implementation + pub fn from_custom(instance: T) -> Self { + Self { + inner: dispatch::DispatchInstance::Custom(backend::custom::DynContext::new(instance)), + } + } + + #[cfg(custom)] + /// Returns custom implementation of Instance (if custom backend and is internally T) + pub fn as_custom(&self) -> Option<&T> { + self.inner.as_custom() } } From 0dbe5fb28e6cc6f0d8c3563ac6e920b484eaf4cd Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 10 Jul 2025 23:56:07 -0400 Subject: [PATCH 029/303] Add annotations for the types hal types return --- wgpu-hal/src/gles/mod.rs | 6 +-- wgpu/src/api/adapter.rs | 13 +++++- wgpu/src/api/blas.rs | 9 ++++ wgpu/src/api/buffer.rs | 9 ++++ wgpu/src/api/command_encoder.rs | 25 ++++++++-- wgpu/src/api/device.rs | 27 +++++++++++ wgpu/src/api/instance.rs | 35 ++++++++++++-- wgpu/src/api/queue.rs | 9 ++++ wgpu/src/api/surface.rs | 9 ++++ wgpu/src/api/texture.rs | 9 ++++ wgpu/src/api/texture_view.rs | 9 ++++ wgpu/src/api/tlas.rs | 9 ++++ wgpu/src/macros.rs | 82 +++++++++++++++++++++++++++++++++ 13 files changed, 237 insertions(+), 14 deletions(-) diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index a6073b4ec8f..30a9d925db1 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -101,17 +101,17 @@ pub use fence::Fence; #[cfg(not(any(windows, webgl)))] pub use self::egl::{AdapterContext, AdapterContextLock}; #[cfg(not(any(windows, webgl)))] -use self::egl::{Instance, Surface}; +pub use self::egl::{Instance, Surface}; #[cfg(webgl)] pub use self::web::AdapterContext; #[cfg(webgl)] -use self::web::{Instance, Surface}; +pub use self::web::{Instance, Surface}; #[cfg(windows)] use self::wgl::AdapterContext; #[cfg(windows)] -use self::wgl::{Instance, Surface}; +pub use self::wgl::{Instance, Surface}; use alloc::{boxed::Box, string::String, string::ToString as _, sync::Arc, vec::Vec}; use core::{ diff --git a/wgpu/src/api/adapter.rs b/wgpu/src/api/adapter.rs index 659216fe77e..529b8421d2b 100644 --- a/wgpu/src/api/adapter.rs +++ b/wgpu/src/api/adapter.rs @@ -66,12 +66,12 @@ impl Adapter { } } - /// Create a wgpu [`Device`] and [`Queue`] from a wgpu-hal `OpenDevice` + /// Create a wgpu [`Device`] and [`Queue`] from a wgpu-hal [`hal::OpenDevice`]. /// /// # Safety /// /// - `hal_device` must be created from this adapter internal handle. - /// - `desc.features` must be a subset of `hal_device` features. + /// - `desc.features` must be a subset of `hal_device`'s supported features. #[cfg(wgpu_core)] pub unsafe fn create_device_from_hal( &self, @@ -103,6 +103,15 @@ impl Adapter { /// Returns a guard that dereferences to the type of the hal backend /// which implements [`A::Adapter`]. /// + /// # Types + /// + /// The returned type depends on the backend: + /// + #[doc = crate::hal_type_vulkan!("Adapter")] + #[doc = crate::hal_type_metal!("Adapter")] + #[doc = crate::hal_type_dx12!("Adapter")] + #[doc = crate::hal_type_gles!("Adapter")] + /// /// # Errors /// /// This method will return None if: diff --git a/wgpu/src/api/blas.rs b/wgpu/src/api/blas.rs index c6069e1b0ce..4252fa4baac 100644 --- a/wgpu/src/api/blas.rs +++ b/wgpu/src/api/blas.rs @@ -162,6 +162,15 @@ impl Blas { /// Returns a guard that dereferences to the type of the hal backend /// which implements [`A::AccelerationStructure`]. /// + /// # Types + /// + /// The returned type depends on the backend: + /// + #[doc = crate::hal_type_vulkan!("AccelerationStructure")] + #[doc = crate::hal_type_metal!("AccelerationStructure")] + #[doc = crate::hal_type_dx12!("AccelerationStructure")] + #[doc = crate::hal_type_gles!("AccelerationStructure")] + /// /// # Deadlocks /// /// - The returned guard holds a read-lock on a device-local "destruction" diff --git a/wgpu/src/api/buffer.rs b/wgpu/src/api/buffer.rs index 277a3031a70..2f66b541c65 100644 --- a/wgpu/src/api/buffer.rs +++ b/wgpu/src/api/buffer.rs @@ -208,6 +208,15 @@ impl Buffer { /// Returns a guard that dereferences to the type of the hal backend /// which implements [`A::Buffer`]. /// + /// # Types + /// + /// The returned type depends on the backend: + /// + #[doc = crate::hal_type_vulkan!("Buffer")] + #[doc = crate::hal_type_metal!("Buffer")] + #[doc = crate::hal_type_dx12!("Buffer")] + #[doc = crate::hal_type_gles!("Buffer")] + /// /// # Deadlocks /// /// - The returned guard holds a read-lock on a device-local "destruction" diff --git a/wgpu/src/api/command_encoder.rs b/wgpu/src/api/command_encoder.rs index 4a5fafb00a1..56e0ae19983 100644 --- a/wgpu/src/api/command_encoder.rs +++ b/wgpu/src/api/command_encoder.rs @@ -232,14 +232,31 @@ impl CommandEncoder { ); } - /// Returns the inner hal CommandEncoder using a callback. The hal command encoder will be `None` if the - /// backend type argument does not match with this wgpu CommandEncoder + /// Get the [`wgpu_hal`] command encoder from this `CommandEncoder`. /// - /// This method will start the wgpu_core level command recording. + /// The returned command encoder will be ready to record onto. + /// + /// # Errors + /// + /// This method will pass in [`None`] if: + /// - The encoder is not from the backend specified by `A`. + /// - The encoder is from the `webgpu` or `custom` backend. + /// + /// # Types + /// + /// The callback argument depends on the backend: + /// + #[doc = crate::hal_type_vulkan!("CommandEncoder")] + #[doc = crate::hal_type_metal!("CommandEncoder")] + #[doc = crate::hal_type_dx12!("CommandEncoder")] + #[doc = crate::hal_type_gles!("CommandEncoder")] /// /// # Safety /// - /// - The raw handle obtained from the hal CommandEncoder must not be manually destroyed + /// - The raw handle obtained from the `A::CommandEncoder` must not be manually destroyed. + /// - You must not end the command buffer; wgpu will do it when you call finish. + /// - The wgpu command encoder must not be interacted with in any way while recording is + /// happening to the wgpu_hal or backend command encoder. #[cfg(wgpu_core)] pub unsafe fn as_hal_mut< A: wgc::hal_api::HalApi, diff --git a/wgpu/src/api/device.rs b/wgpu/src/api/device.rs index 48c719f9a16..00a03c921c2 100644 --- a/wgpu/src/api/device.rs +++ b/wgpu/src/api/device.rs @@ -289,6 +289,15 @@ impl Device { /// Creates a [`Texture`] from a wgpu-hal Texture. /// + /// # Types + /// + /// The type of `A::Texture` depends on the backend: + /// + #[doc = crate::hal_type_vulkan!("Texture")] + #[doc = crate::hal_type_metal!("Texture")] + #[doc = crate::hal_type_dx12!("Texture")] + #[doc = crate::hal_type_gles!("Texture")] + /// /// # Safety /// /// - `hal_texture` must be created from this device internal handle @@ -319,6 +328,15 @@ impl Device { /// Creates a [`Buffer`] from a wgpu-hal Buffer. /// + /// # Types + /// + /// The type of `A::Buffer` depends on the backend: + /// + #[doc = crate::hal_type_vulkan!("Buffer")] + #[doc = crate::hal_type_metal!("Buffer")] + #[doc = crate::hal_type_dx12!("Buffer")] + #[doc = crate::hal_type_gles!("Buffer")] + /// /// # Safety /// /// - `hal_buffer` must be created from this device internal handle @@ -473,6 +491,15 @@ impl Device { /// Returns a guard that dereferences to the type of the hal backend /// which implements [`A::Device`]. /// + /// # Types + /// + /// The returned type depends on the backend: + /// + #[doc = crate::hal_type_vulkan!("Device")] + #[doc = crate::hal_type_metal!("Device")] + #[doc = crate::hal_type_dx12!("Device")] + #[doc = crate::hal_type_gles!("Device")] + /// /// # Errors /// /// This method will return None if: diff --git a/wgpu/src/api/instance.rs b/wgpu/src/api/instance.rs index c830f8203df..70cbabfcaa5 100644 --- a/wgpu/src/api/instance.rs +++ b/wgpu/src/api/instance.rs @@ -307,15 +307,24 @@ impl Instance { /// Interop with wgpu-hal. #[cfg(wgpu_core)] impl Instance { - /// Create an new instance of wgpu from a wgpu-hal instance. + /// Create an new instance of wgpu from a wgpu-hal instance. This is often useful + /// when you need to do backend specific logic, or interop with an existing backend + /// instance. /// - /// # Arguments + /// # Types + /// + /// The type of `A::Instance` depends on the backend: /// - /// - `hal_instance` - wgpu-hal instance. + #[doc = crate::hal_type_vulkan!("Instance")] + #[doc = crate::hal_type_metal!("Instance")] + #[doc = crate::hal_type_dx12!("Instance")] + #[doc = crate::hal_type_gles!("Instance")] /// /// # Safety /// - /// Refer to the creation of wgpu-hal Instance for every backend. + /// - The `hal_instance` must be a valid and usable instance of the backend specified by `A`. + /// - wgpu will act like it has complete ownership of this instance, and will destroy it + /// when the last reference to the instance, internal or external, is dropped. pub unsafe fn from_hal(hal_instance: A::Instance) -> Self { Self { inner: unsafe { @@ -332,6 +341,13 @@ impl Instance { /// Returns a guard that dereferences to the type of the hal backend /// which implements [`A::Instance`]. /// + /// # Types + /// + #[doc = crate::hal_type_vulkan!("Instance")] + #[doc = crate::hal_type_metal!("Instance")] + #[doc = crate::hal_type_dx12!("Instance")] + #[doc = crate::hal_type_gles!("Instance")] + /// /// # Errors /// /// This method will return None if: @@ -352,7 +368,16 @@ impl Instance { .and_then(|ctx| unsafe { ctx.instance_as_hal::() }) } - /// Converts a wgpu-hal `ExposedAdapter` to a wgpu [`Adapter`]. + /// Converts a wgpu-hal [`hal::ExposedAdapter`] to a wgpu [`Adapter`]. + /// + /// # Types + /// + /// The type of `hal_adapter.adapter` depends on the backend: + /// + #[doc = crate::hal_type_vulkan!("Adapter")] + #[doc = crate::hal_type_metal!("Adapter")] + #[doc = crate::hal_type_dx12!("Adapter")] + #[doc = crate::hal_type_gles!("Adapter")] /// /// # Safety /// diff --git a/wgpu/src/api/queue.rs b/wgpu/src/api/queue.rs index ad6cc65e415..27d2006fad1 100644 --- a/wgpu/src/api/queue.rs +++ b/wgpu/src/api/queue.rs @@ -288,6 +288,15 @@ impl Queue { /// Returns a guard that dereferences to the type of the hal backend /// which implements [`A::Queue`]. /// + /// # Types + /// + /// The returned type depends on the backend: + /// + #[doc = crate::hal_type_vulkan!("Queue")] + #[doc = crate::hal_type_metal!("Queue")] + #[doc = crate::hal_type_dx12!("Queue")] + #[doc = crate::hal_type_gles!("Queue")] + /// /// # Errors /// /// This method will return None if: diff --git a/wgpu/src/api/surface.rs b/wgpu/src/api/surface.rs index 20e020fc5c3..ced7a47b294 100644 --- a/wgpu/src/api/surface.rs +++ b/wgpu/src/api/surface.rs @@ -158,6 +158,15 @@ impl Surface<'_> { /// Returns a guard that dereferences to the type of the hal backend /// which implements [`A::Surface`]. /// + /// # Types + /// + /// The returned type depends on the backend: + /// + #[doc = crate::hal_type_vulkan!("Surface")] + #[doc = crate::hal_type_metal!("Surface")] + #[doc = crate::hal_type_dx12!("Surface")] + #[doc = crate::hal_type_gles!("Surface")] + /// /// # Errors /// /// This method will return None if: diff --git a/wgpu/src/api/texture.rs b/wgpu/src/api/texture.rs index d398137f19e..2e2764e812f 100644 --- a/wgpu/src/api/texture.rs +++ b/wgpu/src/api/texture.rs @@ -27,6 +27,15 @@ impl Texture { /// Returns a guard that dereferences to the type of the hal backend /// which implements [`A::Texture`]. /// + /// # Types + /// + /// The returned type depends on the backend: + /// + #[doc = crate::hal_type_vulkan!("Texture")] + #[doc = crate::hal_type_metal!("Texture")] + #[doc = crate::hal_type_dx12!("Texture")] + #[doc = crate::hal_type_gles!("Texture")] + /// /// # Deadlocks /// /// - The returned guard holds a read-lock on a device-local "destruction" diff --git a/wgpu/src/api/texture_view.rs b/wgpu/src/api/texture_view.rs index cff3f959685..faa300d1cff 100644 --- a/wgpu/src/api/texture_view.rs +++ b/wgpu/src/api/texture_view.rs @@ -39,6 +39,15 @@ impl TextureView { /// Returns a guard that dereferences to the type of the hal backend /// which implements [`A::TextureView`]. /// + /// # Types + /// + /// The returned type depends on the backend: + /// + #[doc = crate::hal_type_vulkan!("TextureView")] + #[doc = crate::hal_type_metal!("TextureView")] + #[doc = crate::hal_type_dx12!("TextureView")] + #[doc = crate::hal_type_gles!("TextureView")] + /// /// # Deadlocks /// /// - The returned guard holds a read-lock on a device-local "destruction" diff --git a/wgpu/src/api/tlas.rs b/wgpu/src/api/tlas.rs index adfe82912e8..07d6d0da42e 100644 --- a/wgpu/src/api/tlas.rs +++ b/wgpu/src/api/tlas.rs @@ -38,6 +38,15 @@ impl Tlas { /// Returns a guard that dereferences to the type of the hal backend /// which implements [`A::AccelerationStructure`]. /// + /// # Types + /// + /// The returned type depends on the backend: + /// + #[doc = crate::hal_type_vulkan!("AccelerationStructure")] + #[doc = crate::hal_type_metal!("AccelerationStructure")] + #[doc = crate::hal_type_dx12!("AccelerationStructure")] + #[doc = crate::hal_type_gles!("AccelerationStructure")] + /// /// # Deadlocks /// /// - The returned guard holds a read-lock on a device-local "destruction" diff --git a/wgpu/src/macros.rs b/wgpu/src/macros.rs index 87eb6f2d898..c766dfb2178 100644 --- a/wgpu/src/macros.rs +++ b/wgpu/src/macros.rs @@ -139,6 +139,88 @@ macro_rules! include_wgsl { }; } +// Macros which help us generate the documentation of which hal types correspond to which backend. +// +// Because all backends are not compiled into the program, we cannot link to them in all situations, +// we need to only link to the types if the backend is compiled in. These are used in #[doc] attributes +// so cannot have more than one line, so cannot use internal cfgs. + +/// Helper macro to generate the documentation for dx12 hal methods, referencing the hal type. +#[macro_export] +#[doc(hidden)] +#[cfg(dx12)] +macro_rules! hal_type_dx12 { + ($ty: literal) => { + concat!("- [`hal::api::Dx12`] uses [`hal::dx12::", $ty, "`]") + }; +} +/// Helper macro to generate the documentation for dx12 hal methods, referencing the hal type. +#[macro_export] +#[doc(hidden)] +#[cfg(not(dx12))] +macro_rules! hal_type_dx12 { + ($ty: literal) => { + concat!("- `hal::api::Dx12` uses `hal::dx12::", $ty, "`") + }; +} + +/// Helper macro to generate the documentation for metal hal methods, referencing the hal type. +#[macro_export] +#[doc(hidden)] +#[cfg(metal)] +macro_rules! hal_type_metal { + ($ty: literal) => { + concat!("- [`hal::api::Metal`] uses [`hal::metal::", $ty, "`]") + }; +} +/// Helper macro to generate the documentation for metal hal methods, referencing the hal type. +#[macro_export] +#[doc(hidden)] +#[cfg(not(metal))] +macro_rules! hal_type_metal { + ($ty: literal) => { + concat!("- `hal::api::Metal` uses `hal::metal::", $ty, "`") + }; +} + +/// Helper macro to generate the documentation for vulkan hal methods, referencing the hal type. +#[macro_export] +#[doc(hidden)] +#[cfg(vulkan)] +macro_rules! hal_type_vulkan { + ($ty: literal) => { + concat!("- [`hal::api::Vulkan`] uses [`hal::vulkan::", $ty, "`]") + }; +} +/// Helper macro to generate the documentation for vulkan hal methods, referencing the hal type. +#[macro_export] +#[doc(hidden)] +#[cfg(not(vulkan))] +macro_rules! hal_type_vulkan { + ($ty: literal) => { + concat!("- `hal::api::Vulkan` uses `hal::vulkan::", $ty, "`") + }; +} + +/// Helper macro to generate the documentation for gles hal methods, referencing the hal type. +#[macro_export] +#[doc(hidden)] +#[cfg(gles)] +macro_rules! hal_type_gles { + ($ty: literal) => { + concat!("- [`hal::api::Gles`] uses [`hal::gles::", $ty, "`]") + }; +} +/// Helper macro to generate the documentation for gles hal methods, referencing the hal type. +#[macro_export] +#[doc(hidden)] +#[cfg(not(gles))] +macro_rules! hal_type_gles { + ($ty: literal) => { + concat!("- `hal::api::Gles` uses `hal::gles::", $ty, "`") + }; +} + #[doc(hidden)] pub mod helpers { pub use alloc::borrow::Cow; From 1ed61877b51e88f8792129b4a7a5c013f22c4813 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Fri, 11 Jul 2025 00:26:02 -0400 Subject: [PATCH 030/303] Remove wgpu_core::hal_api::HalApi --- wgpu-core/src/as_hal.rs | 23 +++++++++++------------ wgpu-core/src/device/global.rs | 3 +-- wgpu-core/src/global.rs | 5 ++--- wgpu-core/src/hal_api.rs | 29 ----------------------------- wgpu-core/src/instance.rs | 7 +++---- wgpu-core/src/lib.rs | 1 - wgpu-hal/src/dx12/mod.rs | 2 ++ wgpu-hal/src/gles/mod.rs | 2 ++ wgpu-hal/src/lib.rs | 4 +++- wgpu-hal/src/metal/mod.rs | 2 ++ wgpu-hal/src/noop/mod.rs | 2 ++ wgpu-hal/src/vulkan/mod.rs | 2 ++ wgpu/src/api/adapter.rs | 4 ++-- wgpu/src/api/blas.rs | 2 +- wgpu/src/api/buffer.rs | 2 +- wgpu/src/api/command_encoder.rs | 6 +----- wgpu/src/api/device.rs | 6 +++--- wgpu/src/api/instance.rs | 6 +++--- wgpu/src/api/queue.rs | 2 +- wgpu/src/api/surface.rs | 2 +- wgpu/src/api/texture.rs | 4 +--- wgpu/src/api/texture_view.rs | 4 +--- wgpu/src/api/tlas.rs | 2 +- wgpu/src/backend/wgpu_core.rs | 32 ++++++++++++++++---------------- 24 files changed, 62 insertions(+), 92 deletions(-) delete mode 100644 wgpu-core/src/hal_api.rs diff --git a/wgpu-core/src/as_hal.rs b/wgpu-core/src/as_hal.rs index 1191bcbbd62..8ad9cf3ea2f 100644 --- a/wgpu-core/src/as_hal.rs +++ b/wgpu-core/src/as_hal.rs @@ -6,7 +6,6 @@ use hal::DynResource; use crate::{ device::Device, global::Global, - hal_api::HalApi, id::{ AdapterId, BlasId, BufferId, CommandEncoderId, DeviceId, QueueId, SurfaceId, TextureId, TextureViewId, TlasId, @@ -226,7 +225,7 @@ impl Global { /// # Safety /// /// - The raw buffer handle must not be manually destroyed - pub unsafe fn buffer_as_hal( + pub unsafe fn buffer_as_hal( &self, id: BufferId, ) -> Option> { @@ -242,7 +241,7 @@ impl Global { /// # Safety /// /// - The raw texture handle must not be manually destroyed - pub unsafe fn texture_as_hal( + pub unsafe fn texture_as_hal( &self, id: TextureId, ) -> Option> { @@ -258,7 +257,7 @@ impl Global { /// # Safety /// /// - The raw texture view handle must not be manually destroyed - pub unsafe fn texture_view_as_hal( + pub unsafe fn texture_view_as_hal( &self, id: TextureViewId, ) -> Option> { @@ -274,7 +273,7 @@ impl Global { /// # Safety /// /// - The raw adapter handle must not be manually destroyed - pub unsafe fn adapter_as_hal( + pub unsafe fn adapter_as_hal( &self, id: AdapterId, ) -> Option> { @@ -291,7 +290,7 @@ impl Global { /// # Safety /// /// - The raw device handle must not be manually destroyed - pub unsafe fn device_as_hal( + pub unsafe fn device_as_hal( &self, id: DeviceId, ) -> Option> { @@ -305,7 +304,7 @@ impl Global { /// # Safety /// /// - The raw fence handle must not be manually destroyed - pub unsafe fn device_fence_as_hal( + pub unsafe fn device_fence_as_hal( &self, id: DeviceId, ) -> Option> { @@ -318,7 +317,7 @@ impl Global { /// # Safety /// - The raw surface handle must not be manually destroyed - pub unsafe fn surface_as_hal( + pub unsafe fn surface_as_hal( &self, id: SurfaceId, ) -> Option> { @@ -335,7 +334,7 @@ impl Global { /// /// - The raw command encoder handle must not be manually destroyed pub unsafe fn command_encoder_as_hal_mut< - A: HalApi, + A: hal::Api, F: FnOnce(Option<&mut A::CommandEncoder>) -> R, R, >( @@ -363,7 +362,7 @@ impl Global { /// # Safety /// /// - The raw queue handle must not be manually destroyed - pub unsafe fn queue_as_hal( + pub unsafe fn queue_as_hal( &self, id: QueueId, ) -> Option> { @@ -377,7 +376,7 @@ impl Global { /// # Safety /// /// - The raw blas handle must not be manually destroyed - pub unsafe fn blas_as_hal( + pub unsafe fn blas_as_hal( &self, id: BlasId, ) -> Option> { @@ -393,7 +392,7 @@ impl Global { /// # Safety /// /// - The raw tlas handle must not be manually destroyed - pub unsafe fn tlas_as_hal( + pub unsafe fn tlas_as_hal( &self, id: TlasId, ) -> Option> { diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index 96842c7168d..cf2412536d8 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -13,7 +13,6 @@ use crate::{ conv, device::{bgl, life::WaitIdleError, DeviceError, DeviceLostClosure}, global::Global, - hal_api::HalApi, id::{self, AdapterId, DeviceId, QueueId, SurfaceId}, instance::{self, Adapter, Surface}, pipeline::{ @@ -386,7 +385,7 @@ impl Global { /// - `hal_buffer` must be created respecting `desc` /// - `hal_buffer` must be initialized /// - `hal_buffer` must not have zero size. - pub unsafe fn create_buffer_from_hal( + pub unsafe fn create_buffer_from_hal( &self, hal_buffer: A::Buffer, device_id: DeviceId, diff --git a/wgpu-core/src/global.rs b/wgpu-core/src/global.rs index 357cb2d42a5..150191d24f1 100644 --- a/wgpu-core/src/global.rs +++ b/wgpu-core/src/global.rs @@ -2,7 +2,6 @@ use alloc::{borrow::ToOwned as _, sync::Arc}; use core::fmt; use crate::{ - hal_api::HalApi, hub::{Hub, HubReport}, instance::{Instance, Surface}, registry::{Registry, RegistryReport}, @@ -44,7 +43,7 @@ impl Global { /// # Safety /// /// Refer to the creation of wgpu-hal Instance for every backend. - pub unsafe fn from_hal_instance(name: &str, hal_instance: A::Instance) -> Self { + pub unsafe fn from_hal_instance(name: &str, hal_instance: A::Instance) -> Self { profiling::scope!("Global::new"); Self { @@ -57,7 +56,7 @@ impl Global { /// # Safety /// /// - The raw instance handle returned must not be manually destroyed. - pub unsafe fn instance_as_hal(&self) -> Option<&A::Instance> { + pub unsafe fn instance_as_hal(&self) -> Option<&A::Instance> { unsafe { self.instance.as_hal::() } } diff --git a/wgpu-core/src/hal_api.rs b/wgpu-core/src/hal_api.rs deleted file mode 100644 index e8d40d8eb2f..00000000000 --- a/wgpu-core/src/hal_api.rs +++ /dev/null @@ -1,29 +0,0 @@ -use wgt::{Backend, WasmNotSendSync}; - -pub trait HalApi: hal::Api + 'static + WasmNotSendSync { - const VARIANT: Backend; -} - -impl HalApi for hal::api::Noop { - const VARIANT: Backend = Backend::Noop; -} - -#[cfg(vulkan)] -impl HalApi for hal::api::Vulkan { - const VARIANT: Backend = Backend::Vulkan; -} - -#[cfg(metal)] -impl HalApi for hal::api::Metal { - const VARIANT: Backend = Backend::Metal; -} - -#[cfg(dx12)] -impl HalApi for hal::api::Dx12 { - const VARIANT: Backend = Backend::Dx12; -} - -#[cfg(gles)] -impl HalApi for hal::api::Gles { - const VARIANT: Backend = Backend::Gl; -} diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 962596a0040..4f36b0a85bf 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -15,7 +15,6 @@ use crate::{ api_log, api_log_debug, device::{queue::Queue, resource::Device, DeviceDescriptor, DeviceError}, global::Global, - hal_api::HalApi, id::{markers, AdapterId, DeviceId, QueueId, SurfaceId}, lock::{rank, Mutex}, present::Presentation, @@ -117,7 +116,7 @@ impl Instance { } /// Helper for `Instance::new()`; attempts to add a single `wgpu-hal` backend to this instance. - fn try_add_hal(&mut self, _: A, instance_desc: &wgt::InstanceDescriptor) { + fn try_add_hal(&mut self, _: A, instance_desc: &wgt::InstanceDescriptor) { // Whether or not the backend was requested, and whether or not it succeeds, // note that we *could* try it. self.supported_backends |= A::VARIANT.into(); @@ -151,7 +150,7 @@ impl Instance { } } - pub(crate) fn from_hal_instance( + pub(crate) fn from_hal_instance( name: String, hal_instance: ::Instance, ) -> Self { @@ -175,7 +174,7 @@ impl Instance { /// # Safety /// /// - The raw instance handle returned must not be manually destroyed. - pub unsafe fn as_hal(&self) -> Option<&A::Instance> { + pub unsafe fn as_hal(&self) -> Option<&A::Instance> { self.raw(A::VARIANT).map(|instance| { instance .as_any() diff --git a/wgpu-core/src/lib.rs b/wgpu-core/src/lib.rs index 4f85de994eb..54c9f1cdc64 100644 --- a/wgpu-core/src/lib.rs +++ b/wgpu-core/src/lib.rs @@ -72,7 +72,6 @@ mod conv; pub mod device; pub mod error; pub mod global; -pub mod hal_api; mod hash_utils; pub mod hub; pub mod id; diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index c8e6c3e0cfb..a41796331db 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -397,6 +397,8 @@ impl D3DBlob { pub struct Api; impl crate::Api for Api { + const VARIANT: wgt::Backend = wgt::Backend::Dx12; + type Instance = Instance; type Surface = Surface; type Adapter = Adapter; diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 30a9d925db1..3500eb98cbf 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -141,6 +141,8 @@ const MAX_PUSH_CONSTANTS: usize = 64; const MAX_PUSH_CONSTANT_COMMANDS: usize = MAX_PUSH_CONSTANTS * crate::MAX_CONCURRENT_SHADER_STAGES; impl crate::Api for Api { + const VARIANT: wgt::Backend = wgt::Backend::Gl; + type Instance = Instance; type Surface = Surface; type Adapter = Adapter; diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 75be3ee734b..d4308b2a03e 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -472,7 +472,9 @@ impl InstanceError { } } -pub trait Api: Clone + fmt::Debug + Sized { +pub trait Api: Clone + fmt::Debug + Sized + WasmNotSendSync + 'static { + const VARIANT: wgt::Backend; + type Instance: DynInstance + Instance; type Surface: DynSurface + Surface; type Adapter: DynAdapter + Adapter; diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index b5ae1dd5d5d..e1bd7ff0fda 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -47,6 +47,8 @@ pub struct Api; type ResourceIndex = u32; impl crate::Api for Api { + const VARIANT: wgt::Backend = wgt::Backend::Metal; + type Instance = Instance; type Surface = Surface; type Adapter = Adapter; diff --git a/wgpu-hal/src/noop/mod.rs b/wgpu-hal/src/noop/mod.rs index 6ae4adcf2d4..ef2d51294da 100644 --- a/wgpu-hal/src/noop/mod.rs +++ b/wgpu-hal/src/noop/mod.rs @@ -31,6 +31,8 @@ pub struct Fence { type DeviceResult = Result; impl crate::Api for Api { + const VARIANT: wgt::Backend = wgt::Backend::Noop; + type Instance = Context; type Surface = Context; type Adapter = Context; diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 55bd148519b..507af4c2596 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -56,6 +56,8 @@ const MAX_TOTAL_ATTACHMENTS: usize = crate::MAX_COLOR_ATTACHMENTS * 2 + 1; pub struct Api; impl crate::Api for Api { + const VARIANT: wgt::Backend = wgt::Backend::Vulkan; + type Instance = Instance; type Surface = Surface; type Adapter = Adapter; diff --git a/wgpu/src/api/adapter.rs b/wgpu/src/api/adapter.rs index 529b8421d2b..16abaacf15b 100644 --- a/wgpu/src/api/adapter.rs +++ b/wgpu/src/api/adapter.rs @@ -73,7 +73,7 @@ impl Adapter { /// - `hal_device` must be created from this adapter internal handle. /// - `desc.features` must be a subset of `hal_device`'s supported features. #[cfg(wgpu_core)] - pub unsafe fn create_device_from_hal( + pub unsafe fn create_device_from_hal( &self, hal_device: hal::OpenDevice, desc: &DeviceDescriptor<'_>, @@ -127,7 +127,7 @@ impl Adapter { /// /// [`A::Adapter`]: hal::Api::Adapter #[cfg(wgpu_core)] - pub unsafe fn as_hal( + pub unsafe fn as_hal( &self, ) -> Option + WasmNotSendSync> { let adapter = self.inner.as_core_opt()?; diff --git a/wgpu/src/api/blas.rs b/wgpu/src/api/blas.rs index 4252fa4baac..54013882fda 100644 --- a/wgpu/src/api/blas.rs +++ b/wgpu/src/api/blas.rs @@ -192,7 +192,7 @@ impl Blas { /// /// [`A::AccelerationStructure`]: hal::Api::AccelerationStructure #[cfg(wgpu_core)] - pub unsafe fn as_hal( + pub unsafe fn as_hal( &mut self, ) -> Option + WasmNotSendSync> { let blas = self.inner.as_core_opt()?; diff --git a/wgpu/src/api/buffer.rs b/wgpu/src/api/buffer.rs index 2f66b541c65..da7e4aca873 100644 --- a/wgpu/src/api/buffer.rs +++ b/wgpu/src/api/buffer.rs @@ -239,7 +239,7 @@ impl Buffer { /// /// [`A::Buffer`]: hal::Api::Buffer #[cfg(wgpu_core)] - pub unsafe fn as_hal( + pub unsafe fn as_hal( &self, ) -> Option + WasmNotSendSync> { let buffer = self.inner.as_core_opt()?; diff --git a/wgpu/src/api/command_encoder.rs b/wgpu/src/api/command_encoder.rs index 56e0ae19983..77cb4d1a29e 100644 --- a/wgpu/src/api/command_encoder.rs +++ b/wgpu/src/api/command_encoder.rs @@ -258,11 +258,7 @@ impl CommandEncoder { /// - The wgpu command encoder must not be interacted with in any way while recording is /// happening to the wgpu_hal or backend command encoder. #[cfg(wgpu_core)] - pub unsafe fn as_hal_mut< - A: wgc::hal_api::HalApi, - F: FnOnce(Option<&mut A::CommandEncoder>) -> R, - R, - >( + pub unsafe fn as_hal_mut) -> R, R>( &mut self, hal_command_encoder_callback: F, ) -> R { diff --git a/wgpu/src/api/device.rs b/wgpu/src/api/device.rs index 00a03c921c2..b5544b69afa 100644 --- a/wgpu/src/api/device.rs +++ b/wgpu/src/api/device.rs @@ -305,7 +305,7 @@ impl Device { /// - `hal_texture` must be initialized #[cfg(wgpu_core)] #[must_use] - pub unsafe fn create_texture_from_hal( + pub unsafe fn create_texture_from_hal( &self, hal_texture: A::Texture, desc: &TextureDescriptor<'_>, @@ -345,7 +345,7 @@ impl Device { /// - `hal_buffer` must not have zero size #[cfg(wgpu_core)] #[must_use] - pub unsafe fn create_buffer_from_hal( + pub unsafe fn create_buffer_from_hal( &self, hal_buffer: A::Buffer, desc: &BufferDescriptor<'_>, @@ -515,7 +515,7 @@ impl Device { /// /// [`A::Device`]: hal::Api::Device #[cfg(wgpu_core)] - pub unsafe fn as_hal( + pub unsafe fn as_hal( &self, ) -> Option + WasmNotSendSync> { let device = self.inner.as_core_opt()?; diff --git a/wgpu/src/api/instance.rs b/wgpu/src/api/instance.rs index 70cbabfcaa5..b9decd59603 100644 --- a/wgpu/src/api/instance.rs +++ b/wgpu/src/api/instance.rs @@ -325,7 +325,7 @@ impl Instance { /// - The `hal_instance` must be a valid and usable instance of the backend specified by `A`. /// - wgpu will act like it has complete ownership of this instance, and will destroy it /// when the last reference to the instance, internal or external, is dropped. - pub unsafe fn from_hal(hal_instance: A::Instance) -> Self { + pub unsafe fn from_hal(hal_instance: A::Instance) -> Self { Self { inner: unsafe { crate::backend::ContextWgpuCore::from_hal_instance::(hal_instance).into() @@ -362,7 +362,7 @@ impl Instance { /// - All the safety requirements of wgpu-hal must be upheld. /// /// [`A::Instance`]: hal::Api::Instance - pub unsafe fn as_hal(&self) -> Option<&A::Instance> { + pub unsafe fn as_hal(&self) -> Option<&A::Instance> { self.inner .as_core_opt() .and_then(|ctx| unsafe { ctx.instance_as_hal::() }) @@ -382,7 +382,7 @@ impl Instance { /// # Safety /// /// `hal_adapter` must be created from this instance internal handle. - pub unsafe fn create_adapter_from_hal( + pub unsafe fn create_adapter_from_hal( &self, hal_adapter: hal::ExposedAdapter, ) -> Adapter { diff --git a/wgpu/src/api/queue.rs b/wgpu/src/api/queue.rs index 27d2006fad1..d7c2749b056 100644 --- a/wgpu/src/api/queue.rs +++ b/wgpu/src/api/queue.rs @@ -312,7 +312,7 @@ impl Queue { /// /// [`A::Queue`]: hal::Api::Queue #[cfg(wgpu_core)] - pub unsafe fn as_hal( + pub unsafe fn as_hal( &self, ) -> Option + WasmNotSendSync> { let queue = self.inner.as_core_opt()?; diff --git a/wgpu/src/api/surface.rs b/wgpu/src/api/surface.rs index ced7a47b294..113f46639e6 100644 --- a/wgpu/src/api/surface.rs +++ b/wgpu/src/api/surface.rs @@ -182,7 +182,7 @@ impl Surface<'_> { /// /// [`A::Surface`]: hal::Api::Surface #[cfg(wgpu_core)] - pub unsafe fn as_hal( + pub unsafe fn as_hal( &self, ) -> Option + WasmNotSendSync> { let core_surface = self.inner.as_core_opt()?; diff --git a/wgpu/src/api/texture.rs b/wgpu/src/api/texture.rs index 2e2764e812f..98136ece4cc 100644 --- a/wgpu/src/api/texture.rs +++ b/wgpu/src/api/texture.rs @@ -58,9 +58,7 @@ impl Texture { /// /// [`A::Texture`]: hal::Api::Texture #[cfg(wgpu_core)] - pub unsafe fn as_hal( - &self, - ) -> Option> { + pub unsafe fn as_hal(&self) -> Option> { let texture = self.inner.as_core_opt()?; unsafe { texture.context.texture_as_hal::(texture) } } diff --git a/wgpu/src/api/texture_view.rs b/wgpu/src/api/texture_view.rs index faa300d1cff..7d578a25feb 100644 --- a/wgpu/src/api/texture_view.rs +++ b/wgpu/src/api/texture_view.rs @@ -70,9 +70,7 @@ impl TextureView { /// /// [`A::TextureView`]: hal::Api::TextureView #[cfg(wgpu_core)] - pub unsafe fn as_hal( - &self, - ) -> Option> { + pub unsafe fn as_hal(&self) -> Option> { let view = self.inner.as_core_opt()?; unsafe { view.context.texture_view_as_hal::(view) } } diff --git a/wgpu/src/api/tlas.rs b/wgpu/src/api/tlas.rs index 07d6d0da42e..4b1c34ad4d7 100644 --- a/wgpu/src/api/tlas.rs +++ b/wgpu/src/api/tlas.rs @@ -68,7 +68,7 @@ impl Tlas { /// /// [`A::AccelerationStructure`]: hal::Api::AccelerationStructure #[cfg(wgpu_core)] - pub unsafe fn as_hal( + pub unsafe fn as_hal( &mut self, ) -> Option> { let tlas = self.inner.as_core_opt()?; diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index f1509ac5648..8fed4d9f88a 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -55,7 +55,7 @@ impl fmt::Debug for ContextWgpuCore { } impl ContextWgpuCore { - pub unsafe fn from_hal_instance(hal_instance: A::Instance) -> Self { + pub unsafe fn from_hal_instance(hal_instance: A::Instance) -> Self { Self(unsafe { Arc::new(wgc::global::Global::from_hal_instance::( "wgpu", @@ -67,7 +67,7 @@ impl ContextWgpuCore { /// # Safety /// /// - The raw instance handle returned must not be manually destroyed. - pub unsafe fn instance_as_hal(&self) -> Option<&A::Instance> { + pub unsafe fn instance_as_hal(&self) -> Option<&A::Instance> { unsafe { self.0.instance_as_hal::() } } @@ -80,28 +80,28 @@ impl ContextWgpuCore { self.0.enumerate_adapters(backends) } - pub unsafe fn create_adapter_from_hal( + pub unsafe fn create_adapter_from_hal( &self, hal_adapter: hal::ExposedAdapter, ) -> wgc::id::AdapterId { unsafe { self.0.create_adapter_from_hal(hal_adapter.into(), None) } } - pub unsafe fn adapter_as_hal( + pub unsafe fn adapter_as_hal( &self, adapter: &CoreAdapter, ) -> Option + WasmNotSendSync> { unsafe { self.0.adapter_as_hal::(adapter.id) } } - pub unsafe fn buffer_as_hal( + pub unsafe fn buffer_as_hal( &self, buffer: &CoreBuffer, ) -> Option> { unsafe { self.0.buffer_as_hal::(buffer.id) } } - pub unsafe fn create_device_from_hal( + pub unsafe fn create_device_from_hal( &self, adapter: &CoreAdapter, hal_device: hal::OpenDevice, @@ -140,7 +140,7 @@ impl ContextWgpuCore { Ok((device, queue)) } - pub unsafe fn create_texture_from_hal( + pub unsafe fn create_texture_from_hal( &self, hal_texture: A::Texture, device: &CoreDevice, @@ -172,7 +172,7 @@ impl ContextWgpuCore { /// - `hal_buffer` must be created respecting `desc` /// - `hal_buffer` must be initialized /// - `hal_buffer` must not have zero size. - pub unsafe fn create_buffer_from_hal( + pub unsafe fn create_buffer_from_hal( &self, hal_buffer: A::Buffer, device: &CoreDevice, @@ -201,28 +201,28 @@ impl ContextWgpuCore { } } - pub unsafe fn device_as_hal( + pub unsafe fn device_as_hal( &self, device: &CoreDevice, ) -> Option> { unsafe { self.0.device_as_hal::(device.id) } } - pub unsafe fn surface_as_hal( + pub unsafe fn surface_as_hal( &self, surface: &CoreSurface, ) -> Option> { unsafe { self.0.surface_as_hal::(surface.id) } } - pub unsafe fn texture_as_hal( + pub unsafe fn texture_as_hal( &self, texture: &CoreTexture, ) -> Option> { unsafe { self.0.texture_as_hal::(texture.id) } } - pub unsafe fn texture_view_as_hal( + pub unsafe fn texture_view_as_hal( &self, texture_view: &CoreTextureView, ) -> Option> { @@ -231,7 +231,7 @@ impl ContextWgpuCore { /// This method will start the wgpu_core level command recording. pub unsafe fn command_encoder_as_hal_mut< - A: wgc::hal_api::HalApi, + A: hal::Api, F: FnOnce(Option<&mut A::CommandEncoder>) -> R, R, >( @@ -247,14 +247,14 @@ impl ContextWgpuCore { } } - pub unsafe fn blas_as_hal( + pub unsafe fn blas_as_hal( &self, blas: &CoreBlas, ) -> Option> { unsafe { self.0.blas_as_hal::(blas.id) } } - pub unsafe fn tlas_as_hal( + pub unsafe fn tlas_as_hal( &self, tlas: &CoreTlas, ) -> Option> { @@ -369,7 +369,7 @@ impl ContextWgpuCore { format!("Validation Error\n\nCaused by:\n{output}") } - pub unsafe fn queue_as_hal( + pub unsafe fn queue_as_hal( &self, queue: &CoreQueue, ) -> Option + WasmNotSendSync> { From 49b773fde25595f99fd634ccaab91a7e5958963b Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Fri, 11 Jul 2025 00:48:44 -0400 Subject: [PATCH 031/303] Add some documentation to wgpu-hal types --- wgpu-hal/src/lib.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index d4308b2a03e..b9ab0c3c9b7 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -472,6 +472,13 @@ impl InstanceError { } } +/// All the types and methods that make up a implementation on top of a backend. +/// +/// Only the types that have non-dyn trait bounds have methods on them. Most methods +/// are either on [`CommandEncoder`] or [`Device`]. +/// +/// The api can either be used through generics (through use of this trait and associated +/// types) or dynamically through using the `Dyn*` traits. pub trait Api: Clone + fmt::Debug + Sized + WasmNotSendSync + 'static { const VARIANT: wgt::Backend; @@ -1806,6 +1813,10 @@ pub struct Capabilities { pub downlevel: wgt::DownlevelCapabilities, } +/// An adapter with all the information needed to reason about its capabilities. +/// +/// These are either made by [`Instance::enumerate_adapters`] or by backend specific +/// methods on the backend [`Instance`] or [`Adapter`]. #[derive(Debug)] pub struct ExposedAdapter { pub adapter: A::Adapter, @@ -1860,6 +1871,10 @@ pub struct AcquiredSurfaceTexture { pub suboptimal: bool, } +/// An open connection to a device and a queue. +/// +/// This can be created from [`Adapter::open`] or backend +/// specific methods on the backend's [`Instance`] or [`Adapter`]. #[derive(Debug)] pub struct OpenDevice { pub device: A::Device, From 76dba55e8dd3356c58682636c6dee01d56b12659 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Wed, 16 Jul 2025 17:16:29 -0400 Subject: [PATCH 032/303] style(vulkan): no trailing space after raytrace cap. negotiation (#7954) --- wgpu-hal/src/vulkan/adapter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 67428309541..399c9d81ab4 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -807,7 +807,7 @@ impl PhysicalDeviceFeatures { features.set( F::EXPERIMENTAL_RAY_QUERY // Although this doesn't really require ray queries, it does not make sense to be enabled if acceleration structures - // aren't enabled. + // aren't enabled. | F::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS, supports_acceleration_structures && caps.supports_extension(khr::ray_query::NAME), ); From 33b9f86cc4ca4103fc321291cb92ab38fd9f4c51 Mon Sep 17 00:00:00 2001 From: Teodor Tanasoaia <28601907+teoxoy@users.noreply.github.com> Date: Thu, 17 Jul 2025 18:47:59 +0200 Subject: [PATCH 033/303] Fix detection of `local_invocation_id` for zero initialization of workgroup memory (#7962) --- naga/src/back/spv/writer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/naga/src/back/spv/writer.rs b/naga/src/back/spv/writer.rs index b61747c8326..ff6a9c1813c 100644 --- a/naga/src/back/spv/writer.rs +++ b/naga/src/back/spv/writer.rs @@ -760,7 +760,7 @@ impl Writer { .push(Instruction::load(type_id, id, varying_id, None)); constituent_ids.push(id); - if binding == &crate::Binding::BuiltIn(crate::BuiltIn::GlobalInvocationId) { + if binding == &crate::Binding::BuiltIn(crate::BuiltIn::LocalInvocationId) { local_invocation_id = Some(id); } } From ff0de91ad7684d9e44dbc3d9bfa9a4f91736c843 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 17 Jul 2025 13:00:40 -0400 Subject: [PATCH 034/303] Bump REPO_MSRV to 1.88 (#7960) --- .github/workflows/ci.yml | 2 +- .github/workflows/cts.yml | 2 +- .github/workflows/docs.yml | 2 +- .github/workflows/generate.yml | 2 +- Cargo.toml | 4 +- README.md | 4 +- benches/benches/wgpu-benchmark/bind_groups.rs | 2 +- clippy.toml | 2 - cts_runner/test.lst | 2 +- .../features/src/big_compute_buffers/mod.rs | 4 +- examples/features/src/framework.rs | 2 +- .../features/src/hello_synchronization/mod.rs | 4 +- examples/features/src/msaa_line/mod.rs | 2 +- examples/features/src/ray_cube_compute/mod.rs | 2 +- .../features/src/ray_cube_fragment/mod.rs | 2 +- examples/features/src/ray_cube_normals/mod.rs | 2 +- examples/features/src/ray_scene/mod.rs | 4 +- examples/features/src/ray_shadows/mod.rs | 2 +- examples/features/src/skybox/mod.rs | 6 +-- examples/features/src/utils.rs | 10 ++--- .../standalone/01_hello_compute/Cargo.toml | 2 +- .../standalone/01_hello_compute/src/main.rs | 2 +- .../standalone/02_hello_window/Cargo.toml | 2 +- examples/standalone/custom_backend/Cargo.toml | 2 +- naga/src/back/dot/mod.rs | 2 +- naga/src/back/glsl/mod.rs | 8 ++-- naga/src/back/hlsl/writer.rs | 6 +-- naga/src/back/msl/writer.rs | 8 ++-- naga/src/back/spv/block.rs | 4 +- naga/src/back/spv/helpers.rs | 3 ++ naga/src/back/spv/image.rs | 2 +- naga/src/back/spv/index.rs | 2 +- naga/src/common/wgsl/types.rs | 6 +-- naga/src/compact/expressions.rs | 2 +- naga/src/compact/handle_set_map.rs | 2 +- naga/src/compact/mod.rs | 6 +-- naga/src/error.rs | 2 +- naga/src/front/glsl/context.rs | 19 +++------ naga/src/front/glsl/functions.rs | 10 ++--- naga/src/front/mod.rs | 2 +- naga/src/front/spv/function.rs | 8 ++-- naga/src/front/spv/image.rs | 17 ++++---- naga/src/front/spv/mod.rs | 37 +++++++++-------- naga/src/front/wgsl/error.rs | 11 ++--- naga/src/front/wgsl/lower/mod.rs | 8 ++-- naga/src/lib.rs | 3 +- naga/src/proc/constant_evaluator.rs | 8 ++-- naga/src/proc/index.rs | 4 +- naga/src/proc/overloads/regular.rs | 2 +- naga/src/proc/typifier.rs | 20 +++++----- naga/src/valid/compose.rs | 13 +++--- naga/src/valid/expression.rs | 40 +++++++++---------- naga/src/valid/function.rs | 16 ++++---- naga/src/valid/interface.rs | 12 ++---- naga/tests/naga/snapshots.rs | 2 +- naga/tests/naga/validation.rs | 5 +++ naga/tests/naga/wgsl_errors.rs | 4 ++ naga/xtask/Cargo.toml | 2 +- naga/xtask/src/validate.rs | 2 +- player/src/bin/play.rs | 14 +++---- player/src/lib.rs | 4 +- rust-toolchain.toml | 2 +- tests/src/isolation.rs | 2 +- tests/tests/wgpu-gpu/buffer_usages.rs | 2 +- tests/tests/wgpu-gpu/clear_texture.rs | 7 +--- tests/tests/wgpu-gpu/samplers.rs | 4 +- .../wgpu-gpu/timestamp_normalization/utils.rs | 3 +- wgpu-core/src/device/global.rs | 4 +- wgpu-core/src/device/life.rs | 1 - wgpu-core/src/device/resource.rs | 8 ++-- wgpu-core/src/device/trace.rs | 6 +-- wgpu-core/src/id.rs | 2 +- wgpu-core/src/identity.rs | 1 - wgpu-core/src/indirect_validation/dispatch.rs | 2 +- wgpu-core/src/indirect_validation/draw.rs | 2 +- wgpu-core/src/instance.rs | 16 +++----- wgpu-core/src/lib.rs | 4 +- wgpu-core/src/lock/observing.rs | 11 ++--- wgpu-core/src/present.rs | 4 +- wgpu-core/src/timestamp_normalization/mod.rs | 5 +-- wgpu-core/src/validation.rs | 2 +- wgpu-hal/examples/halmark/main.rs | 2 +- wgpu-hal/examples/ray-traced-triangle/main.rs | 2 +- wgpu-hal/src/auxil/dxgi/exception.rs | 2 +- wgpu-hal/src/auxil/dxgi/factory.rs | 2 +- wgpu-hal/src/auxil/dxgi/result.rs | 2 +- wgpu-hal/src/auxil/renderdoc.rs | 10 ++--- wgpu-hal/src/dx12/adapter.rs | 2 +- wgpu-hal/src/dx12/command.rs | 2 +- wgpu-hal/src/dx12/descriptor.rs | 2 +- wgpu-hal/src/dx12/device.rs | 17 +++----- wgpu-hal/src/dx12/mod.rs | 4 +- wgpu-hal/src/dx12/sampler.rs | 3 +- wgpu-hal/src/dx12/suballocation.rs | 11 ++--- wgpu-hal/src/gles/adapter.rs | 12 +++--- wgpu-hal/src/gles/device.rs | 20 ++++------ wgpu-hal/src/gles/egl.rs | 26 +++++------- wgpu-hal/src/gles/mod.rs | 6 +-- wgpu-hal/src/lib.rs | 2 + wgpu-hal/src/metal/device.rs | 27 ++++++------- wgpu-hal/src/metal/mod.rs | 2 +- wgpu-hal/src/metal/surface.rs | 2 +- wgpu-hal/src/vulkan/adapter.rs | 14 +++---- wgpu-hal/src/vulkan/conv.rs | 2 +- wgpu-hal/src/vulkan/drm.rs | 2 +- wgpu-hal/src/vulkan/instance.rs | 6 +-- wgpu-types/src/features.rs | 4 +- wgpu-types/src/instance.rs | 13 +----- wgpu-types/src/lib.rs | 4 +- wgpu/src/backend/webgpu.rs | 16 ++------ wgpu/src/backend/wgpu_core.rs | 2 +- wgpu/src/lib.rs | 4 ++ xtask/Cargo.toml | 2 +- xtask/src/util.rs | 2 +- xtask/src/vendor_web_sys.rs | 8 ++-- 115 files changed, 314 insertions(+), 397 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1dea4069e47..51a86219c48 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ env: MESA_VERSION: "24.3.4" # This is the MSRV used by `wgpu` itself and all surrounding infrastructure. - REPO_MSRV: "1.84" + REPO_MSRV: "1.88" # This is the MSRV used by the `wgpu-core`, `wgpu-hal`, and `wgpu-types` crates, # to ensure that they can be used with firefox. CORE_MSRV: "1.82.0" diff --git a/.github/workflows/cts.yml b/.github/workflows/cts.yml index d5e98950491..aeedd3df9f9 100644 --- a/.github/workflows/cts.yml +++ b/.github/workflows/cts.yml @@ -11,7 +11,7 @@ env: CARGO_INCREMENTAL: false CARGO_TERM_COLOR: always RUST_BACKTRACE: full - MSRV: "1.84" + MSRV: "1.88" jobs: cts: diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d96ed087096..ac97b771025 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -10,7 +10,7 @@ on: env: # This is the MSRV used by `wgpu` itself and all surrounding infrastructure. - REPO_MSRV: "1.84" + REPO_MSRV: "1.88" CARGO_INCREMENTAL: false CARGO_TERM_COLOR: always diff --git a/.github/workflows/generate.yml b/.github/workflows/generate.yml index 0f758d4a839..a3f0fb18f0a 100644 --- a/.github/workflows/generate.yml +++ b/.github/workflows/generate.yml @@ -13,7 +13,7 @@ env: # # This is the MSRV used by `wgpu` itself and all surrounding infrastructure. - REPO_MSRV: "1.84" + REPO_MSRV: "1.88" RUSTFLAGS: -D warnings jobs: diff --git a/Cargo.toml b/Cargo.toml index ca7f4121e2c..444bb9aa72d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,7 +54,7 @@ ref_as_ptr = "warn" [workspace.package] edition = "2021" -rust-version = "1.84" +rust-version = "1.88" keywords = ["graphics"] license = "MIT OR Apache-2.0" homepage = "https://wgpu.rs/" @@ -178,7 +178,7 @@ rustc-hash = { version = "1.1", default-features = false } serde_json = "1.0.118" serde = { version = "1.0.219", default-features = false } shell-words = "1" -smallvec = "1.9" +smallvec = "1.13.1" spirv = "0.3" static_assertions = "1.1" strum = { version = "0.27", default-features = false, features = ["derive"] } diff --git a/README.md b/README.md index ac984583e2e..51142739424 100644 --- a/README.md +++ b/README.md @@ -149,8 +149,8 @@ On Linux, you can point to them using `LD_LIBRARY_PATH` environment. Due to complex dependants, we have two MSRV policies: -- `naga`, `wgpu-core`, `wgpu-hal`, and `wgpu-types`'s MSRV is **1.76**. -- The rest of the workspace has an MSRV of **1.84**. +- `naga`, `wgpu-core`, `wgpu-hal`, and `wgpu-types`'s MSRV is **1.82**. +- The rest of the workspace has an MSRV of **1.88**. It is enforced on CI (in "/.github/workflows/ci.yml") with the `CORE_MSRV` and `REPO_MSRV` variables. This version can only be upgraded in breaking releases, though we release a breaking version every three months. diff --git a/benches/benches/wgpu-benchmark/bind_groups.rs b/benches/benches/wgpu-benchmark/bind_groups.rs index 6fb23d0a24d..50245d441bd 100644 --- a/benches/benches/wgpu-benchmark/bind_groups.rs +++ b/benches/benches/wgpu-benchmark/bind_groups.rs @@ -87,7 +87,7 @@ fn run_bench(ctx: &mut Criterion) { for &count in count_list { group.throughput(Throughput::Elements(count as u64)); group.bench_with_input( - format!("{} Element Bind Group", count), + format!("{count} Element Bind Group"), &count, |b, &count| { b.iter_custom(|iters| { diff --git a/clippy.toml b/clippy.toml index 35f212da623..1910b9fcb28 100644 --- a/clippy.toml +++ b/clippy.toml @@ -3,6 +3,4 @@ disallowed-types = [ { path = "std::collections::HashMap", reason = "use hashbrown::HashMap instead" }, { path = "std::collections::HashSet", reason = "use hashbrown::HashSet instead" }, - { path = "rustc_hash::FxHashMap", reason = "use hashbrown::HashMap instead" }, - { path = "rustc_hash::FxHashSet", reason = "use hashbrown::HashSet instead" }, ] diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 78aae871386..a34aa4b3797 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -68,7 +68,7 @@ webgpu:api,operation,rendering,color_target_state:blend_constant,setting:* webgpu:api,operation,rendering,depth:* webgpu:api,operation,rendering,draw:* webgpu:api,operation,shader_module,compilation_info:* -webgpu:api,operation,uncapturederror:iff_uncaptured:* +fails-if(metal) webgpu:api,operation,uncapturederror:iff_uncaptured:* //FAIL: webgpu:shader,execution,expression,call,builtin,select:* // - Fails with `const`/abstract int cases on all platforms because of . // - Fails with `vec3` & `f16` cases on macOS because of . diff --git a/examples/features/src/big_compute_buffers/mod.rs b/examples/features/src/big_compute_buffers/mod.rs index 90561271851..579ab8a79f3 100644 --- a/examples/features/src/big_compute_buffers/mod.rs +++ b/examples/features/src/big_compute_buffers/mod.rs @@ -193,7 +193,7 @@ fn create_storage_buffers(device: &wgpu::Device, numbers: &[f32]) -> Vec Vec wgpu::RenderBundle { - log::info!("sample_count: {}", sample_count); + log::info!("sample_count: {sample_count}"); let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: None, layout: Some(pipeline_layout), diff --git a/examples/features/src/ray_cube_compute/mod.rs b/examples/features/src/ray_cube_compute/mod.rs index 522a6e75c14..9492822ad77 100644 --- a/examples/features/src/ray_cube_compute/mod.rs +++ b/examples/features/src/ray_cube_compute/mod.rs @@ -114,7 +114,7 @@ impl>> Future for ErrorFuture { let inner = unsafe { self.map_unchecked_mut(|me| &mut me.inner) }; inner.poll(cx).map(|error| { if let Some(e) = error { - panic!("Rendering {}", e); + panic!("Rendering {e}"); } }) } diff --git a/examples/features/src/ray_cube_fragment/mod.rs b/examples/features/src/ray_cube_fragment/mod.rs index 1dd1ae90da8..94db6b59f52 100644 --- a/examples/features/src/ray_cube_fragment/mod.rs +++ b/examples/features/src/ray_cube_fragment/mod.rs @@ -89,7 +89,7 @@ impl>> Future for ErrorFuture { let inner = unsafe { self.map_unchecked_mut(|me| &mut me.inner) }; inner.poll(cx).map(|error| { if let Some(e) = error { - panic!("Rendering {}", e); + panic!("Rendering {e}"); } }) } diff --git a/examples/features/src/ray_cube_normals/mod.rs b/examples/features/src/ray_cube_normals/mod.rs index 66a56d75bb2..e21974eabfb 100644 --- a/examples/features/src/ray_cube_normals/mod.rs +++ b/examples/features/src/ray_cube_normals/mod.rs @@ -113,7 +113,7 @@ impl>> Future for ErrorFuture { let inner = unsafe { self.map_unchecked_mut(|me| &mut me.inner) }; inner.poll(cx).map(|error| { if let Some(e) = error { - panic!("Rendering {}", e); + panic!("Rendering {e}"); } }) } diff --git a/examples/features/src/ray_scene/mod.rs b/examples/features/src/ray_scene/mod.rs index 765705cb853..66717c5a87c 100644 --- a/examples/features/src/ray_scene/mod.rs +++ b/examples/features/src/ray_scene/mod.rs @@ -41,7 +41,7 @@ impl>> Future for ErrorFuture { let inner = unsafe { self.map_unchecked_mut(|me| &mut me.inner) }; inner.poll(cx).map(|error| { if let Some(e) = error { - panic!("Rendering {}", e); + panic!("Rendering {e}"); } }) } @@ -93,7 +93,7 @@ struct Material { fn load_model(scene: &mut RawSceneComponents, path: &str) { let path = env!("CARGO_MANIFEST_DIR").to_string() + "/src" + path; - println!("{}", path); + println!("{path}"); let mut object = obj::Obj::load(path).unwrap(); object.load_mtls().unwrap(); diff --git a/examples/features/src/ray_shadows/mod.rs b/examples/features/src/ray_shadows/mod.rs index 8ba14c399ce..8b93fb275a2 100644 --- a/examples/features/src/ray_shadows/mod.rs +++ b/examples/features/src/ray_shadows/mod.rs @@ -68,7 +68,7 @@ impl>> Future for ErrorFuture { let inner = unsafe { self.map_unchecked_mut(|me| &mut me.inner) }; inner.poll(cx).map(|error| { if let Some(e) = error { - panic!("Rendering {}", e); + panic!("Rendering {e}"); } }) } diff --git a/examples/features/src/skybox/mod.rs b/examples/features/src/skybox/mod.rs index 38b0e19066c..2484e6f25d3 100644 --- a/examples/features/src/skybox/mod.rs +++ b/examples/features/src/skybox/mod.rs @@ -299,11 +299,7 @@ impl crate::framework::Example for Example { let max_mips = layer_size.max_mips(wgpu::TextureDimension::D2); log::debug!( - "Copying {:?} skybox images of size {}, {}, 6 with {} mips to gpu", - skybox_format, - IMAGE_SIZE, - IMAGE_SIZE, - max_mips, + "Copying {skybox_format:?} skybox images of size {IMAGE_SIZE}, {IMAGE_SIZE}, 6 with {max_mips} mips to gpu", ); let bytes = match skybox_format { diff --git a/examples/features/src/utils.rs b/examples/features/src/utils.rs index e0c4b4f236a..5d2913c185a 100644 --- a/examples/features/src/utils.rs +++ b/examples/features/src/utils.rs @@ -37,7 +37,7 @@ pub fn output_image_native(image_data: Vec, texture_dims: (usize, usize), pa let mut file = std::fs::File::create(&path).unwrap(); file.write_all(&png_data[..]).unwrap(); - log::info!("PNG file written to disc as \"{}\".", path); + log::info!("PNG file written to disc as \"{path}\"."); } /// Effectively a version of `output_image_native` but meant for web browser contexts. @@ -58,9 +58,8 @@ pub fn output_image_wasm(image_data: Vec, texture_dims: (usize, usize)) { Err(e) => { log::error!( "In searching for a staging canvas for outputting an image \ - (element with id \"staging-canvas\"), found non-canvas element: {:?}. - Replacing with standard staging canvas.", - e + (element with id \"staging-canvas\"), found non-canvas element: {e:?}. + Replacing with standard staging canvas." ); e.remove(); create_staging_canvas(&document) @@ -101,9 +100,8 @@ pub fn output_image_wasm(image_data: Vec, texture_dims: (usize, usize)) { Ok(e) => e, Err(e) => { log::error!( - "Found an element with the id \"output-image-target\" but it was not an image: {:?}. + "Found an element with the id \"output-image-target\" but it was not an image: {e:?}. Replacing with default image output element.", - e ); e.remove(); create_output_image_element(&document) diff --git a/examples/standalone/01_hello_compute/Cargo.toml b/examples/standalone/01_hello_compute/Cargo.toml index 35c61745e6f..448c6c59e4b 100644 --- a/examples/standalone/01_hello_compute/Cargo.toml +++ b/examples/standalone/01_hello_compute/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "wgpu-example-01-hello-compute" edition = "2021" -rust-version = "1.84" +rust-version = "1.88" publish = false [dependencies] diff --git a/examples/standalone/01_hello_compute/src/main.rs b/examples/standalone/01_hello_compute/src/main.rs index 19d95620c2e..4a1f0346554 100644 --- a/examples/standalone/01_hello_compute/src/main.rs +++ b/examples/standalone/01_hello_compute/src/main.rs @@ -249,5 +249,5 @@ fn main() { let result: &[f32] = bytemuck::cast_slice(&data); // Print out the result. - println!("Result: {:?}", result); + println!("Result: {result:?}"); } diff --git a/examples/standalone/02_hello_window/Cargo.toml b/examples/standalone/02_hello_window/Cargo.toml index 35385e6e221..8640c143f37 100644 --- a/examples/standalone/02_hello_window/Cargo.toml +++ b/examples/standalone/02_hello_window/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "wgpu-example-02-hello-window" edition = "2021" -rust-version = "1.84" +rust-version = "1.88" publish = false [dependencies] diff --git a/examples/standalone/custom_backend/Cargo.toml b/examples/standalone/custom_backend/Cargo.toml index eb0142a1f81..47e52290ec7 100644 --- a/examples/standalone/custom_backend/Cargo.toml +++ b/examples/standalone/custom_backend/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "wgpu-example-custom-backend" edition = "2021" -rust-version = "1.84" +rust-version = "1.88" publish = false [features] diff --git a/naga/src/back/dot/mod.rs b/naga/src/back/dot/mod.rs index c9fc49fe1fc..826dad1c219 100644 --- a/naga/src/back/dot/mod.rs +++ b/naga/src/back/dot/mod.rs @@ -740,7 +740,7 @@ fn write_function_expressions( E::RayQueryVertexPositions { query, committed } => { edges.insert("", query); let ty = if committed { "Committed" } else { "Candidate" }; - (format!("get{}HitVertexPositions", ty).into(), 4) + (format!("get{ty}HitVertexPositions").into(), 4) } }; diff --git a/naga/src/back/glsl/mod.rs b/naga/src/back/glsl/mod.rs index ee0daa89c6c..75917fb76f5 100644 --- a/naga/src/back/glsl/mod.rs +++ b/naga/src/back/glsl/mod.rs @@ -1238,7 +1238,7 @@ impl<'a, W: Write> Writer<'a, W> { write!(self.out, "layout(")?; if let Some(layout) = layout { - write!(self.out, "{}, ", layout)?; + write!(self.out, "{layout}, ")?; } write!(self.out, "binding = {binding}) ")?; @@ -1255,7 +1255,7 @@ impl<'a, W: Write> Writer<'a, W> { // Either no explicit bindings are supported or we didn't have any. // Write just the memory layout. if let Some(layout) = layout { - write!(self.out, "layout({}) ", layout)?; + write!(self.out, "layout({layout}) ")?; } Ok(()) @@ -3698,11 +3698,11 @@ impl<'a, W: Write> Writer<'a, W> { // `Dot4U8Packed`, the code below only introduces parenthesis around // each factor, which aren't strictly needed because both operands are // baked, but which don't hurt either. - write!(self.out, "bitfieldExtract({}(", conversion)?; + write!(self.out, "bitfieldExtract({conversion}(")?; self.write_expr(arg, ctx)?; write!(self.out, "), {}, 8)", i * 8)?; - write!(self.out, " * bitfieldExtract({}(", conversion)?; + write!(self.out, " * bitfieldExtract({conversion}(")?; self.write_expr(arg1, ctx)?; write!(self.out, "), {}, 8)", i * 8)?; diff --git a/naga/src/back/hlsl/writer.rs b/naga/src/back/hlsl/writer.rs index 75e890d2724..2f98b1fbfe5 100644 --- a/naga/src/back/hlsl/writer.rs +++ b/naga/src/back/hlsl/writer.rs @@ -317,7 +317,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { } for (group, bt) in self.options.dynamic_storage_buffer_offsets_targets.iter() { - writeln!(self.out, "struct __dynamic_buffer_offsetsTy{} {{", group)?; + writeln!(self.out, "struct __dynamic_buffer_offsetsTy{group} {{")?; for i in 0..bt.size { writeln!(self.out, "{}uint _{};", back::INDENT, i)?; } @@ -706,7 +706,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { let members = match module.types[result.ty].inner { TypeInner::Struct { ref members, .. } => members, ref other => { - log::error!("Unexpected {:?} output type without a binding", other); + log::error!("Unexpected {other:?} output type without a binding"); &empty[..] } }; @@ -1433,7 +1433,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { let array_return_type = self.namer.call(&format!("ret_{name}")); write!(self.out, "typedef ")?; self.write_type(module, result.ty)?; - write!(self.out, " {}", array_return_type)?; + write!(self.out, " {array_return_type}")?; self.write_array_size(module, base, size)?; writeln!(self.out, ";")?; Some(array_return_type) diff --git a/naga/src/back/msl/writer.rs b/naga/src/back/msl/writer.rs index 3cb1ab2c39b..ce83b08dc4e 100644 --- a/naga/src/back/msl/writer.rs +++ b/naga/src/back/msl/writer.rs @@ -1150,7 +1150,7 @@ impl Writer { //TODO: do we support Zero on `Sampled` image classes? } _ if !has_levels => { - log::warn!("1D image can't be sampled with level {:?}", level); + log::warn!("1D image can't be sampled with level {level:?}"); } crate::SampleLevel::Exact(h) => { write!(self.out, ", {NAMESPACE}::level(")?; @@ -1397,7 +1397,7 @@ impl Writer { } else { fun.to_msl() }; - write!(self.out, ".atomic_{}(", op)?; + write!(self.out, ".atomic_{op}(")?; // coordinates in IR are int, but Metal expects uint self.put_cast_to_uint_scalar_or_vector(address.coordinate, &context.expression)?; write!(self.out, ", ")?; @@ -2352,7 +2352,7 @@ impl Writer { arg1.unwrap(), 4, |writer, arg, index| { - write!(writer.out, "({}(", conversion)?; + write!(writer.out, "({conversion}(")?; writer.put_expression(arg, context, true)?; if index == 3 { write!(writer.out, ") >> 24)")?; @@ -3420,7 +3420,7 @@ impl Writer { put_numeric_type(&mut self.out, scalar, &[rows, columns])?; } TypeResolution::Value(ref other) => { - log::warn!("Type {:?} isn't a known local", other); //TEMP! + log::warn!("Type {other:?} isn't a known local"); //TEMP! return Err(Error::FeatureNotImplemented("weird local type".to_string())); } } diff --git a/naga/src/back/spv/block.rs b/naga/src/back/spv/block.rs index 7ec659e1d90..71487c69758 100644 --- a/naga/src/back/spv/block.rs +++ b/naga/src/back/spv/block.rs @@ -675,7 +675,7 @@ impl BlockContext<'_> { load_id } ref other => { - log::error!("Unable to access index of {:?}", other); + log::error!("Unable to access index of {other:?}"); return Err(Error::FeatureNotImplemented("access index for type")); } } @@ -1893,7 +1893,7 @@ impl BlockContext<'_> { crate::TypeInner::Scalar(scalar) => (scalar, None), crate::TypeInner::Vector { scalar, size } => (scalar, Some(size)), ref other => { - log::error!("As source {:?}", other); + log::error!("As source {other:?}"); return Err(Error::Validation("Unexpected Expression::As source")); } }; diff --git a/naga/src/back/spv/helpers.rs b/naga/src/back/spv/helpers.rs index 7938791bae0..84e130efaa3 100644 --- a/naga/src/back/spv/helpers.rs +++ b/naga/src/back/spv/helpers.rs @@ -35,6 +35,9 @@ pub(super) fn string_to_byte_chunks(input: &str, limit: usize) -> Vec<&[u8]> { let mut words = vec![]; while offset < input.len() { offset = input.floor_char_boundary(offset + limit); + // Clippy wants us to call as_bytes() first to avoid the UTF-8 check, + // but we want to assert the output is valid UTF-8. + #[allow(clippy::sliced_string_as_bytes)] words.push(input[start..offset].as_bytes()); start = offset; } diff --git a/naga/src/back/spv/image.rs b/naga/src/back/spv/image.rs index f485014530e..faac982872b 100644 --- a/naga/src/back/spv/image.rs +++ b/naga/src/back/spv/image.rs @@ -303,7 +303,7 @@ impl BlockContext<'_> { return Err(Error::Validation("extending vec4 coordinate")); } ref other => { - log::error!("wrong coordinate type {:?}", other); + log::error!("wrong coordinate type {other:?}"); return Err(Error::Validation("coordinate type")); } }; diff --git a/naga/src/back/spv/index.rs b/naga/src/back/spv/index.rs index 45d628e0f71..3a15ee88060 100644 --- a/naga/src/back/spv/index.rs +++ b/naga/src/back/spv/index.rs @@ -277,7 +277,7 @@ impl BlockContext<'_> { Ok(MaybeKnown::Computed(length_id)) } Err(err) => { - log::error!("Sequence length for {:?} failed: {}", sequence, err); + log::error!("Sequence length for {sequence:?} failed: {err}"); Err(Error::Validation("indexable length")) } } diff --git a/naga/src/common/wgsl/types.rs b/naga/src/common/wgsl/types.rs index c118feeace7..1c20d967249 100644 --- a/naga/src/common/wgsl/types.rs +++ b/naga/src/common/wgsl/types.rs @@ -337,7 +337,7 @@ where } => { let (address, maybe_access) = address_space_str(space); if let Some(space) = address { - write!(out, "ptr<{}, ", space)?; + write!(out, "ptr<{space}, ")?; ctx.write_scalar(scalar, out)?; if let Some(access) = maybe_access { write!(out, ", {access}")?; @@ -368,14 +368,14 @@ where } TypeInner::AccelerationStructure { vertex_return } => { let caps = if vertex_return { "" } else { "" }; - write!(out, "acceleration_structure{}", caps)? + write!(out, "acceleration_structure{caps}")? } TypeInner::Struct { .. } => { ctx.write_unnamed_struct(inner, out)?; } TypeInner::RayQuery { vertex_return } => { let caps = if vertex_return { "" } else { "" }; - write!(out, "ray_query{}", caps)? + write!(out, "ray_query{caps}")? } } diff --git a/naga/src/compact/expressions.rs b/naga/src/compact/expressions.rs index 24562bdd4af..f36d747a935 100644 --- a/naga/src/compact/expressions.rs +++ b/naga/src/compact/expressions.rs @@ -68,7 +68,7 @@ impl ExpressionTracer<'_> { continue; } - log::trace!("tracing new expression {:?}", expr); + log::trace!("tracing new expression {expr:?}"); self.trace_expression(expr); } } diff --git a/naga/src/compact/handle_set_map.rs b/naga/src/compact/handle_set_map.rs index 7a174cd9171..b3cbb909eed 100644 --- a/naga/src/compact/handle_set_map.rs +++ b/naga/src/compact/handle_set_map.rs @@ -37,7 +37,7 @@ impl HandleMap { if self.new_index.len() <= handle.index() { self.new_index.resize_with(handle.index() + 1, || None); } - core::mem::replace(&mut self.new_index[handle.index()], Some(value)) + self.new_index[handle.index()].replace(value) } } diff --git a/naga/src/compact/mod.rs b/naga/src/compact/mod.rs index c7b7bfb46d8..48972dc648f 100644 --- a/naga/src/compact/mod.rs +++ b/naga/src/compact/mod.rs @@ -164,7 +164,7 @@ pub fn compact(module: &mut crate::Module, keep_unused: KeepUnused) { } while let Some(handle) = module_tracer.functions_pending.pop() { let function = &module.functions[handle]; - log::trace!("tracing function {:?}", function); + log::trace!("tracing function {function:?}"); let mut function_tracer = module_tracer.as_function(function); function_tracer.trace(); function_maps.insert(handle, FunctionMap::from(function_tracer)); @@ -680,7 +680,7 @@ fn type_expression_interdependence() { }; let mut type_name_counter = 0; let mut type_needed = |module: &mut crate::Module, handle| { - let name = Some(format!("type{}", type_name_counter)); + let name = Some(format!("type{type_name_counter}")); type_name_counter += 1; module.types.insert( crate::Type { @@ -696,7 +696,7 @@ fn type_expression_interdependence() { }; let mut override_name_counter = 0; let mut expression_needed = |module: &mut crate::Module, handle| { - let name = Some(format!("override{}", override_name_counter)); + let name = Some(format!("override{override_name_counter}")); override_name_counter += 1; module.overrides.append( crate::Override { diff --git a/naga/src/error.rs b/naga/src/error.rs index 597aad99202..3c2f476c9b1 100644 --- a/naga/src/error.rs +++ b/naga/src/error.rs @@ -56,7 +56,7 @@ impl fmt::Display for ShaderError writer.into_string() }; - write!(f, "\nShader validation {}", writer) + write!(f, "\nShader validation {writer}") } } diff --git a/naga/src/front/glsl/context.rs b/naga/src/front/glsl/context.rs index e6c5546fb95..d650044992e 100644 --- a/naga/src/front/glsl/context.rs +++ b/naga/src/front/glsl/context.rs @@ -541,7 +541,7 @@ impl<'a> Context<'a> { ) -> Result<(Option>, Span)> { let HirExpr { ref kind, meta } = stmt.hir_exprs[expr]; - log::debug!("Lowering {:?} (kind {:?}, pos {:?})", expr, kind, pos); + log::debug!("Lowering {expr:?} (kind {kind:?}, pos {pos:?})"); let handle = match *kind { HirExprKind::Access { base, index } => { @@ -636,8 +636,7 @@ impl<'a> Context<'a> { frontend.errors.push(Error { kind: ErrorKind::SemanticError( format!( - "Cannot apply operation to {:?} and {:?}", - left_inner, right_inner + "Cannot apply operation to {left_inner:?} and {right_inner:?}" ) .into(), ), @@ -835,8 +834,7 @@ impl<'a> Context<'a> { frontend.errors.push(Error { kind: ErrorKind::SemanticError( format!( - "Cannot apply operation to {:?} and {:?}", - left_inner, right_inner + "Cannot apply operation to {left_inner:?} and {right_inner:?}" ) .into(), ), @@ -916,8 +914,7 @@ impl<'a> Context<'a> { frontend.errors.push(Error { kind: ErrorKind::SemanticError( format!( - "Cannot apply operation to {:?} and {:?}", - left_inner, right_inner + "Cannot apply operation to {left_inner:?} and {right_inner:?}" ) .into(), ), @@ -1339,13 +1336,7 @@ impl<'a> Context<'a> { } }; - log::trace!( - "Lowered {:?}\n\tKind = {:?}\n\tPos = {:?}\n\tResult = {:?}", - expr, - kind, - pos, - handle - ); + log::trace!("Lowered {expr:?}\n\tKind = {kind:?}\n\tPos = {pos:?}\n\tResult = {handle:?}"); Ok((Some(handle), meta)) } diff --git a/naga/src/front/glsl/functions.rs b/naga/src/front/glsl/functions.rs index e0a0535a04e..7de7364cd40 100644 --- a/naga/src/front/glsl/functions.rs +++ b/naga/src/front/glsl/functions.rs @@ -560,7 +560,7 @@ impl Frontend { continue; } - log::trace!("Testing overload {}", overload_idx); + log::trace!("Testing overload {overload_idx}"); // Stores whether the current overload matches exactly the function call let mut exact = true; @@ -592,10 +592,7 @@ impl Frontend { let call_arg_ty = ctx.get_type(call_argument.0); log::trace!( - "Testing parameter {}\n\tOverload = {:?}\n\tCall = {:?}", - i, - overload_param_ty, - call_arg_ty + "Testing parameter {i}\n\tOverload = {overload_param_ty:?}\n\tCall = {call_arg_ty:?}" ); // Storage images cannot be directly compared since while the access is part of the @@ -641,8 +638,7 @@ impl Frontend { self.errors.push(Error { kind: ErrorKind::SemanticError( format!( - "'{}': image needs {:?} access but only {:?} was provided", - name, overload_access, call_access + "'{name}': image needs {overload_access:?} access but only {call_access:?} was provided" ) .into(), ), diff --git a/naga/src/front/mod.rs b/naga/src/front/mod.rs index 4f363d8973d..826100e878d 100644 --- a/naga/src/front/mod.rs +++ b/naga/src/front/mod.rs @@ -114,7 +114,7 @@ impl Typifier { for (eh, expr) in expressions.iter().skip(self.resolutions.len()) { //Note: the closure can't `Err` by construction let resolution = ctx.resolve(expr, |h| Ok(&self.resolutions[h]))?; - log::debug!("Resolving {:?} = {:?} : {:?}", eh, expr, resolution); + log::debug!("Resolving {eh:?} = {expr:?} : {resolution:?}"); self.resolutions.insert(eh, resolution); } } diff --git a/naga/src/front/spv/function.rs b/naga/src/front/spv/function.rs index 13163f6bd41..1e581368e27 100644 --- a/naga/src/front/spv/function.rs +++ b/naga/src/front/spv/function.rs @@ -167,7 +167,7 @@ impl> super::Frontend { if let Some(ref prefix) = self.options.block_ctx_dump_prefix { let dump_suffix = match self.lookup_entry_point.get(&fun_id) { Some(ep) => format!("block_ctx.{:?}-{}.txt", ep.stage, ep.name), - None => format!("block_ctx.Fun-{}.txt", function_index), + None => format!("block_ctx.Fun-{function_index}.txt"), }; cfg_if::cfg_if! { @@ -176,10 +176,10 @@ impl> super::Frontend { let dest = prefix.join(dump_suffix); let dump = format!("{block_ctx:#?}"); if let Err(e) = std::fs::write(&dest, dump) { - log::error!("Unable to dump the block context into {:?}: {}", dest, e); + log::error!("Unable to dump the block context into {dest:?}: {e}"); } } else { - log::error!("Unable to dump the block context into {:?}/{}: file system integration was not enabled with the `fs` feature", prefix, dump_suffix); + log::error!("Unable to dump the block context into {prefix:?}/{dump_suffix}: file system integration was not enabled with the `fs` feature"); } } } @@ -191,7 +191,7 @@ impl> super::Frontend { // to get the spill. for phi in block_ctx.phis.iter() { // Get a pointer to the local variable for the phi's value. - let phi_pointer = block_ctx.expressions.append( + let phi_pointer: Handle = block_ctx.expressions.append( crate::Expression::LocalVariable(phi.local), crate::Span::default(), ); diff --git a/naga/src/front/spv/image.rs b/naga/src/front/spv/image.rs index 15dafa5af04..ee94fe6efc9 100644 --- a/naga/src/front/spv/image.rs +++ b/naga/src/front/spv/image.rs @@ -202,7 +202,7 @@ pub(super) fn patch_comparison_type( return false; } - log::debug!("Flipping comparison for {:?}", var); + log::debug!("Flipping comparison for {var:?}"); let original_ty = &arena[var.ty]; let original_ty_span = arena.get_span(var.ty); let ty_inner = match original_ty.inner { @@ -279,7 +279,7 @@ impl> super::Frontend { if image_ops != 0 { let other = spirv::ImageOperands::from_bits_truncate(image_ops); - log::warn!("Unknown image write ops {:?}", other); + log::warn!("Unknown image write ops {other:?}"); for _ in 1..words_left { self.next()?; } @@ -403,7 +403,7 @@ impl> super::Frontend { words_left -= 1; } other => { - log::warn!("Unknown image load op {:?}", other); + log::warn!("Unknown image load op {other:?}"); for _ in 0..words_left { self.next()?; } @@ -546,12 +546,11 @@ impl> super::Frontend { }; level = if options.compare { - log::debug!("Assuming {:?} is zero", lod_handle); + log::debug!("Assuming {lod_handle:?} is zero"); crate::SampleLevel::Zero } else if is_depth_image { log::debug!( - "Assuming level {:?} converts losslessly to an integer", - lod_handle + "Assuming level {lod_handle:?} converts losslessly to an integer" ); let expr = crate::Expression::As { expr: lod_handle, @@ -588,9 +587,7 @@ impl> super::Frontend { ); level = if options.compare { log::debug!( - "Assuming gradients {:?} and {:?} are not greater than 1", - grad_x_handle, - grad_y_handle + "Assuming gradients {grad_x_handle:?} and {grad_y_handle:?} are not greater than 1" ); crate::SampleLevel::Zero } else { @@ -616,7 +613,7 @@ impl> super::Frontend { words_left -= 1; } other => { - log::warn!("Unknown image sample operand {:?}", other); + log::warn!("Unknown image sample operand {other:?}"); for _ in 0..words_left { self.next()?; } diff --git a/naga/src/front/spv/mod.rs b/naga/src/front/spv/mod.rs index 2375e61c531..960437ece58 100644 --- a/naga/src/front/spv/mod.rs +++ b/naga/src/front/spv/mod.rs @@ -515,7 +515,6 @@ enum MergeBlockInformation { /// [`blocks`]: BlockContext::blocks /// [`bodies`]: BlockContext::bodies /// [`phis`]: BlockContext::phis -/// [`lower`]: function::lower #[derive(Debug)] struct BlockContext<'function> { /// Phi nodes encountered when parsing the function, used to generate spills @@ -796,7 +795,7 @@ impl> Frontend { dec.specialization_constant_id = Some(self.next()?); } other => { - log::warn!("Unknown decoration {:?}", other); + log::warn!("Unknown decoration {other:?}"); for _ in base_words + 1..inst.wc { let _var = self.next()?; } @@ -1387,7 +1386,7 @@ impl> Frontend { block: &mut crate::Block, body_idx: usize, ) -> Result<(Handle, Handle), Error> { - log::trace!("\t\t\tlooking up pointer expr {:?}", pointer_id); + log::trace!("\t\t\tlooking up pointer expr {pointer_id:?}"); let p_lexp_handle; let p_lexp_ty_id; { @@ -1600,7 +1599,7 @@ impl> Frontend { .remove(&result_id) .and_then(|decor| decor.name); if let Some(ref name) = name { - log::debug!("\t\t\tid={} name={}", result_id, name); + log::debug!("\t\t\tid={result_id} name={name}"); } let lookup_ty = self.lookup_type.lookup(result_type_id)?; let var_handle = ctx.local_arena.append( @@ -1686,7 +1685,7 @@ impl> Frontend { let result_type_id = self.next()?; let result_id = self.next()?; let base_id = self.next()?; - log::trace!("\t\t\tlooking up expr {:?}", base_id); + log::trace!("\t\t\tlooking up expr {base_id:?}"); let mut acex = { let lexp = self.lookup_expression.lookup(base_id)?; @@ -1721,7 +1720,7 @@ impl> Frontend { for _ in 4..inst.wc { let access_id = self.next()?; - log::trace!("\t\t\tlooking up index expr {:?}", access_id); + log::trace!("\t\t\tlooking up index expr {access_id:?}"); let index_expr = self.lookup_expression.lookup(access_id)?.clone(); let index_expr_handle = get_expr_handle!(access_id, &index_expr); let index_expr_data = &ctx.expressions[index_expr.handle]; @@ -2064,7 +2063,7 @@ impl> Frontend { let result_type_id = self.next()?; let result_id = self.next()?; let base_id = self.next()?; - log::trace!("\t\t\tlooking up expr {:?}", base_id); + log::trace!("\t\t\tlooking up expr {base_id:?}"); let mut lexp = self.lookup_expression.lookup(base_id)?.clone(); lexp.handle = get_expr_handle!(base_id, &lexp); for _ in 4..inst.wc { @@ -2084,7 +2083,7 @@ impl> Frontend { .base_id .ok_or(Error::InvalidAccessType(lexp.type_id))?, ref other => { - log::warn!("composite type {:?}", other); + log::warn!("composite type {other:?}"); return Err(Error::UnsupportedType(type_lookup.handle)); } }; @@ -2153,7 +2152,7 @@ impl> Frontend { let mut components = Vec::with_capacity(inst.wc as usize - 2); for _ in 3..inst.wc { let comp_id = self.next()?; - log::trace!("\t\t\tlooking up expr {:?}", comp_id); + log::trace!("\t\t\tlooking up expr {comp_id:?}"); let lexp = self.lookup_expression.lookup(comp_id)?; let handle = get_expr_handle!(comp_id, lexp); components.push(handle); @@ -3872,7 +3871,7 @@ impl> Frontend { ); block.push(crate::Statement::ControlBarrier(flags), span); } else { - log::warn!("Unsupported barrier execution scope: {}", exec_scope); + log::warn!("Unsupported barrier execution scope: {exec_scope}"); } } Op::MemoryBarrier => { @@ -4244,7 +4243,7 @@ impl> Frontend { let _memory_semantics_id = self.next()?; let span = self.span_from_with_op(start); - log::trace!("\t\t\tlooking up expr {:?}", pointer_id); + log::trace!("\t\t\tlooking up expr {pointer_id:?}"); let p_lexp_handle = get_expr_handle!(pointer_id, self.lookup_expression.lookup(pointer_id)?); @@ -4274,11 +4273,11 @@ impl> Frontend { let value_id = self.next()?; let span = self.span_from_with_op(start); - log::trace!("\t\t\tlooking up pointer expr {:?}", pointer_id); + log::trace!("\t\t\tlooking up pointer expr {pointer_id:?}"); let p_lexp_handle = get_expr_handle!(pointer_id, self.lookup_expression.lookup(pointer_id)?); - log::trace!("\t\t\tlooking up value expr {:?}", pointer_id); + log::trace!("\t\t\tlooking up value expr {pointer_id:?}"); let v_lexp_handle = get_expr_handle!(value_id, self.lookup_expression.lookup(value_id)?); @@ -4380,11 +4379,11 @@ impl> Frontend { body_idx, )?; - log::trace!("\t\t\tlooking up value expr {:?}", value_id); + log::trace!("\t\t\tlooking up value expr {value_id:?}"); let v_lexp_handle = get_expr_handle!(value_id, self.lookup_expression.lookup(value_id)?); - log::trace!("\t\t\tlooking up comparator expr {:?}", value_id); + log::trace!("\t\t\tlooking up comparator expr {value_id:?}"); let c_lexp_handle = get_expr_handle!( comparator_id, self.lookup_expression.lookup(comparator_id)? @@ -4699,7 +4698,7 @@ impl> Frontend { let generator = self.next()?; let _bound = self.next()?; let _schema = self.next()?; - log::info!("Generated by {} version {:x}", generator, version_raw); + log::info!("Generated by {generator} version {version_raw:x}"); crate::Module::default() }; @@ -4840,7 +4839,7 @@ impl> Frontend { if self.options.strict_capabilities { return Err(Error::UnsupportedCapability(cap)); } else { - log::warn!("Unknown capability {:?}", cap); + log::warn!("Unknown capability {cap:?}"); } } Ok(()) @@ -6030,7 +6029,7 @@ impl> Frontend { ) { Ok(handle) => Some(handle), Err(e) => { - log::warn!("Failed to initialize output built-in: {}", e); + log::warn!("Failed to initialize output built-in: {e}"); None } } @@ -6077,7 +6076,7 @@ impl> Frontend { let handle = module.global_variables.append(var, span); if module.types[ty].inner.can_comparison_sample(module) { - log::debug!("\t\ttracking {:?} for sampling properties", handle); + log::debug!("\t\ttracking {handle:?} for sampling properties"); self.handle_sampling .insert(handle, image::SamplingFlags::empty()); diff --git a/naga/src/front/wgsl/error.rs b/naga/src/front/wgsl/error.rs index 1123caff6a3..7f2c8181257 100644 --- a/naga/src/front/wgsl/error.rs +++ b/naga/src/front/wgsl/error.rs @@ -690,7 +690,7 @@ impl<'a> Error<'a> { notes: vec![], }, Error::UnknownEnableExtension(span, word) => ParseError { - message: format!("unknown enable-extension `{}`", word), + message: format!("unknown enable-extension `{word}`"), labels: vec![(span, "".into())], notes: vec![ "See available extensions at ." @@ -1078,8 +1078,7 @@ impl<'a> Error<'a> { } = **error; ParseError { message: format!( - "automatic conversions cannot convert `{}` to `{}`", - source_type, dest_type + "automatic conversions cannot convert `{source_type}` to `{dest_type}`" ), labels: vec![ ( @@ -1103,15 +1102,13 @@ impl<'a> Error<'a> { } = **error; ParseError { message: format!( - "automatic conversions cannot convert elements of `{}` to `{}`", - source_type, dest_scalar + "automatic conversions cannot convert elements of `{source_type}` to `{dest_scalar}`" ), labels: vec![ ( dest_span, format!( - "a value with elements of type {} is required here", - dest_scalar + "a value with elements of type {dest_scalar} is required here" ) .into(), ), diff --git a/naga/src/front/wgsl/lower/mod.rs b/naga/src/front/wgsl/lower/mod.rs index 1f994d753f0..e60ae41a787 100644 --- a/naga/src/front/wgsl/lower/mod.rs +++ b/naga/src/front/wgsl/lower/mod.rs @@ -3400,12 +3400,12 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { ir::TypeInner::Pointer { base, .. } => match ctx.module.types[base].inner { ir::TypeInner::Atomic(scalar) => Ok((pointer, scalar)), ref other => { - log::error!("Pointer type to {:?} passed to atomic op", other); + log::error!("Pointer type to {other:?} passed to atomic op"); Err(Box::new(Error::InvalidAtomicPointer(span))) } }, ref other => { - log::error!("Type {:?} passed to atomic op", other); + log::error!("Type {other:?} passed to atomic op"); Err(Box::new(Error::InvalidAtomicPointer(span))) } } @@ -4034,12 +4034,12 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { ir::TypeInner::Pointer { base, .. } => match ctx.module.types[base].inner { ir::TypeInner::RayQuery { .. } => Ok(pointer), ref other => { - log::error!("Pointer type to {:?} passed to ray query op", other); + log::error!("Pointer type to {other:?} passed to ray query op"); Err(Box::new(Error::InvalidRayQueryPointer(span))) } }, ref other => { - log::error!("Type {:?} passed to ray query op", other); + log::error!("Type {other:?} passed to ray query op"); Err(Box::new(Error::InvalidRayQueryPointer(span))) } } diff --git a/naga/src/lib.rs b/naga/src/lib.rs index bdd5345c312..19b406588b3 100644 --- a/naga/src/lib.rs +++ b/naga/src/lib.rs @@ -75,7 +75,8 @@ void main() { clippy::derive_partial_eq_without_eq, clippy::needless_borrowed_reference, clippy::single_match, - clippy::enum_variant_names + clippy::enum_variant_names, + clippy::result_large_err )] #![warn( trivial_casts, diff --git a/naga/src/proc/constant_evaluator.rs b/naga/src/proc/constant_evaluator.rs index 4dba552f007..ac496f8562c 100644 --- a/naga/src/proc/constant_evaluator.rs +++ b/naga/src/proc/constant_evaluator.rs @@ -844,7 +844,7 @@ impl<'a> ConstantEvaluator<'a> { expr: &Expression, span: Span, ) -> Result, ConstantEvaluatorError> { - log::trace!("try_eval_and_append: {:?}", expr); + log::trace!("try_eval_and_append: {expr:?}"); match *expr { Expression::Constant(c) if self.is_global_arena() => { // "See through" the constant and use its initializer. @@ -2816,11 +2816,11 @@ fn first_leading_bit_smoke() { trait TryFromAbstract: Sized { /// Convert an abstract literal `value` to `Self`. /// - /// Since Naga's `AbstractInt` and `AbstractFloat` exist to support + /// Since Naga's [`AbstractInt`] and [`AbstractFloat`] exist to support /// WGSL, we follow WGSL's conversion rules here: /// /// - WGSL §6.1.2. Conversion Rank says that automatic conversions - /// from `AbstractInt` to an integer type are either lossless or an + /// from [`AbstractInt`] to an integer type are either lossless or an /// error. /// /// - WGSL §15.7.6 Floating Point Conversion says that conversions @@ -2834,7 +2834,7 @@ trait TryFromAbstract: Sized { /// conversion from AbstractFloat to integer types. /// /// [`AbstractInt`]: crate::Literal::AbstractInt - /// [`Float`]: crate::Literal::Float + /// [`AbstractFloat`]: crate::Literal::AbstractFloat fn try_from_abstract(value: T) -> Result; } diff --git a/naga/src/proc/index.rs b/naga/src/proc/index.rs index cf6a127aced..87eaac7775c 100644 --- a/naga/src/proc/index.rs +++ b/naga/src/proc/index.rs @@ -99,8 +99,8 @@ pub struct BoundsCheckPolicies { /// /// [`GlobalVariable`]: crate::GlobalVariable /// [`space`]: crate::GlobalVariable::space - /// [`Restrict`]: crate::back::BoundsCheckPolicy::Restrict - /// [`ReadZeroSkipWrite`]: crate::back::BoundsCheckPolicy::ReadZeroSkipWrite + /// [`Restrict`]: crate::proc::BoundsCheckPolicy::Restrict + /// [`ReadZeroSkipWrite`]: crate::proc::BoundsCheckPolicy::ReadZeroSkipWrite /// [`Access`]: crate::Expression::Access /// [`AccessIndex`]: crate::Expression::AccessIndex /// [`Storage`]: crate::AddressSpace::Storage diff --git a/naga/src/proc/overloads/regular.rs b/naga/src/proc/overloads/regular.rs index 3975592faed..0b180aa0e79 100644 --- a/naga/src/proc/overloads/regular.rs +++ b/naga/src/proc/overloads/regular.rs @@ -195,7 +195,7 @@ fn make_rule( let inner = size.to_inner(scalar); let arg = TypeResolution::Value(inner.clone()); Rule { - arguments: core::iter::repeat(arg.clone()).take(arity).collect(), + arguments: core::iter::repeat_n(arg.clone(), arity).collect(), conclusion: conclusion_rule.conclude(size, scalar), } } diff --git a/naga/src/proc/typifier.rs b/naga/src/proc/typifier.rs index f7d1ea48390..d675a898d97 100644 --- a/naga/src/proc/typifier.rs +++ b/naga/src/proc/typifier.rs @@ -296,7 +296,7 @@ impl<'a> ResolveContext<'a> { }, Ti::BindingArray { base, .. } => Ti::Pointer { base, space }, ref other => { - log::error!("Access sub-type {:?}", other); + log::error!("Access sub-type {other:?}"); return Err(ResolveError::InvalidSubAccess { ty: base, indexed: false, @@ -306,7 +306,7 @@ impl<'a> ResolveContext<'a> { } Ti::BindingArray { base, .. } => TypeResolution::Handle(base), ref other => { - log::error!("Access type {:?}", other); + log::error!("Access type {other:?}"); return Err(ResolveError::InvalidAccess { expr: base, indexed: false, @@ -392,7 +392,7 @@ impl<'a> ResolveContext<'a> { } Ti::BindingArray { base, .. } => Ti::Pointer { base, space }, ref other => { - log::error!("Access index sub-type {:?}", other); + log::error!("Access index sub-type {other:?}"); return Err(ResolveError::InvalidSubAccess { ty: ty_base, indexed: true, @@ -401,7 +401,7 @@ impl<'a> ResolveContext<'a> { }), Ti::BindingArray { base, .. } => TypeResolution::Handle(base), ref other => { - log::error!("Access index type {:?}", other); + log::error!("Access index type {other:?}"); return Err(ResolveError::InvalidAccess { expr: base, indexed: true, @@ -412,7 +412,7 @@ impl<'a> ResolveContext<'a> { crate::Expression::Splat { size, value } => match *past(value)?.inner_with(types) { Ti::Scalar(scalar) => TypeResolution::Value(Ti::Vector { size, scalar }), ref other => { - log::error!("Scalar type {:?}", other); + log::error!("Scalar type {other:?}"); return Err(ResolveError::InvalidScalar(value)); } }, @@ -425,7 +425,7 @@ impl<'a> ResolveContext<'a> { TypeResolution::Value(Ti::Vector { size, scalar }) } ref other => { - log::error!("Vector type {:?}", other); + log::error!("Vector type {other:?}"); return Err(ResolveError::InvalidVector(vector)); } }, @@ -476,7 +476,7 @@ impl<'a> ResolveContext<'a> { None => Ti::Scalar(scalar), }), ref other => { - log::error!("Pointer type {:?}", other); + log::error!("Pointer type {other:?}"); return Err(ResolveError::InvalidPointer(pointer)); } }, @@ -496,7 +496,7 @@ impl<'a> ResolveContext<'a> { size: crate::VectorSize::Quad, }), ref other => { - log::error!("Image type {:?}", other); + log::error!("Image type {other:?}"); return Err(ResolveError::InvalidImage(image)); } }, @@ -514,7 +514,7 @@ impl<'a> ResolveContext<'a> { }, }), ref other => { - log::error!("Image type {:?}", other); + log::error!("Image type {other:?}"); return Err(ResolveError::InvalidImage(image)); } }, @@ -532,7 +532,7 @@ impl<'a> ResolveContext<'a> { }, }, ref other => { - log::error!("Image type {:?}", other); + log::error!("Image type {other:?}"); return Err(ResolveError::InvalidImage(image)); } }, diff --git a/naga/src/valid/compose.rs b/naga/src/valid/compose.rs index 20df99cbf39..802ddb63956 100644 --- a/naga/src/valid/compose.rs +++ b/naga/src/valid/compose.rs @@ -32,10 +32,7 @@ pub fn validate_compose( } if comp_scalar == scalar => comp_size as u32, ref other => { log::error!( - "Vector component[{}] type {:?}, building {:?}", - index, - other, - scalar + "Vector component[{index}] type {other:?}, building {scalar:?}" ); return Err(ComposeError::ComponentType { index: index as u32, @@ -65,7 +62,7 @@ pub fn validate_compose( } for (index, comp_res) in component_resolutions.enumerate() { if comp_res.inner_with(gctx.types) != &inner { - log::error!("Matrix component[{}] type {:?}", index, comp_res); + log::error!("Matrix component[{index}] type {comp_res:?}"); return Err(ComposeError::ComponentType { index: index as u32, }); @@ -85,7 +82,7 @@ pub fn validate_compose( } for (index, comp_res) in component_resolutions.enumerate() { if !gctx.compare_types(&TypeResolution::Handle(base), &comp_res) { - log::error!("Array component[{}] type {:?}", index, comp_res); + log::error!("Array component[{index}] type {comp_res:?}"); return Err(ComposeError::ComponentType { index: index as u32, }); @@ -102,7 +99,7 @@ pub fn validate_compose( for (index, (member, comp_res)) in members.iter().zip(component_resolutions).enumerate() { if !gctx.compare_types(&TypeResolution::Handle(member.ty), &comp_res) { - log::error!("Struct component[{}] type {:?}", index, comp_res); + log::error!("Struct component[{index}] type {comp_res:?}"); return Err(ComposeError::ComponentType { index: index as u32, }); @@ -110,7 +107,7 @@ pub fn validate_compose( } } ref other => { - log::error!("Composing of {:?}", other); + log::error!("Composing of {other:?}"); return Err(ComposeError::Type(self_ty_handle)); } } diff --git a/naga/src/valid/expression.rs b/naga/src/valid/expression.rs index 8b73486b1fe..a2675d8c71d 100644 --- a/naga/src/valid/expression.rs +++ b/naga/src/valid/expression.rs @@ -266,7 +266,7 @@ impl super::Validator { | Ti::ValuePointer { size: Some(_), .. } | Ti::BindingArray { .. } => {} ref other => { - log::error!("Indexing of {:?}", other); + log::error!("Indexing of {other:?}"); return Err(ExpressionError::InvalidBaseType(base)); } }; @@ -277,7 +277,7 @@ impl super::Validator { .. }) => {} ref other => { - log::error!("Indexing by {:?}", other); + log::error!("Indexing by {other:?}"); return Err(ExpressionError::InvalidIndexType(index)); } } @@ -332,7 +332,7 @@ impl super::Validator { } Ti::Struct { ref members, .. } => members.len() as u32, ref other => { - log::error!("Indexing of {:?}", other); + log::error!("Indexing of {other:?}"); return Err(ExpressionError::InvalidBaseType(top)); } }; @@ -348,7 +348,7 @@ impl super::Validator { E::Splat { size: _, value } => match resolver[value] { Ti::Scalar { .. } => ShaderStages::all(), ref other => { - log::error!("Splat scalar type {:?}", other); + log::error!("Splat scalar type {other:?}"); return Err(ExpressionError::InvalidSplatType(value)); } }, @@ -360,7 +360,7 @@ impl super::Validator { let vec_size = match resolver[vector] { Ti::Vector { size: vec_size, .. } => vec_size, ref other => { - log::error!("Swizzle vector type {:?}", other); + log::error!("Swizzle vector type {other:?}"); return Err(ExpressionError::InvalidVectorType(vector)); } }; @@ -400,7 +400,7 @@ impl super::Validator { .contains(TypeFlags::SIZED | TypeFlags::DATA) => {} Ti::ValuePointer { .. } => {} ref other => { - log::error!("Loading {:?}", other); + log::error!("Loading {other:?}"); return Err(ExpressionError::InvalidPointerType(pointer)); } } @@ -766,7 +766,7 @@ impl super::Validator { | (Uo::LogicalNot, Some(Sk::Bool)) | (Uo::BitwiseNot, Some(Sk::Sint | Sk::Uint)) => {} other => { - log::error!("Op {:?} kind {:?}", op, other); + log::error!("Op {op:?} kind {other:?}"); return Err(ExpressionError::InvalidUnaryOperandType(op, expr)); } } @@ -875,7 +875,7 @@ impl super::Validator { Sk::Bool | Sk::AbstractInt | Sk::AbstractFloat => false, }, ref other => { - log::error!("Op {:?} left type {:?}", op, other); + log::error!("Op {op:?} left type {other:?}"); false } } @@ -887,7 +887,7 @@ impl super::Validator { .. } => left_inner == right_inner, ref other => { - log::error!("Op {:?} left type {:?}", op, other); + log::error!("Op {op:?} left type {other:?}"); false } }, @@ -897,7 +897,7 @@ impl super::Validator { Sk::Float | Sk::AbstractInt | Sk::AbstractFloat => false, }, ref other => { - log::error!("Op {:?} left type {:?}", op, other); + log::error!("Op {op:?} left type {other:?}"); false } }, @@ -907,7 +907,7 @@ impl super::Validator { Sk::Bool | Sk::Float | Sk::AbstractInt | Sk::AbstractFloat => false, }, ref other => { - log::error!("Op {:?} left type {:?}", op, other); + log::error!("Op {op:?} left type {other:?}"); false } }, @@ -916,7 +916,7 @@ impl super::Validator { Ti::Scalar(scalar) => (Ok(None), scalar), Ti::Vector { size, scalar } => (Ok(Some(size)), scalar), ref other => { - log::error!("Op {:?} base type {:?}", op, other); + log::error!("Op {op:?} base type {other:?}"); (Err(()), Sc::BOOL) } }; @@ -927,7 +927,7 @@ impl super::Validator { scalar: Sc { kind: Sk::Uint, .. }, } => Ok(Some(size)), ref other => { - log::error!("Op {:?} shift type {:?}", op, other); + log::error!("Op {op:?} shift type {other:?}"); Err(()) } }; @@ -1032,7 +1032,7 @@ impl super::Validator { .. } => {} ref other => { - log::error!("All/Any of type {:?}", other); + log::error!("All/Any of type {other:?}"); return Err(ExpressionError::InvalidBooleanVector(argument)); } }, @@ -1040,7 +1040,7 @@ impl super::Validator { Ti::Scalar(scalar) | Ti::Vector { scalar, .. } if scalar.kind == Sk::Float => {} ref other => { - log::error!("Float test of type {:?}", other); + log::error!("Float test of type {other:?}"); return Err(ExpressionError::InvalidFloatArgument(argument)); } }, @@ -1164,7 +1164,7 @@ impl super::Validator { } } ref other => { - log::error!("Array length of {:?}", other); + log::error!("Array length of {other:?}"); return Err(ExpressionError::InvalidArrayType(expr)); } }, @@ -1179,12 +1179,12 @@ impl super::Validator { } => match resolver.types[base].inner { Ti::RayQuery { .. } => ShaderStages::all(), ref other => { - log::error!("Intersection result of a pointer to {:?}", other); + log::error!("Intersection result of a pointer to {other:?}"); return Err(ExpressionError::InvalidRayQueryType(query)); } }, ref other => { - log::error!("Intersection result of {:?}", other); + log::error!("Intersection result of {other:?}"); return Err(ExpressionError::InvalidRayQueryType(query)); } }, @@ -1200,12 +1200,12 @@ impl super::Validator { vertex_return: true, } => ShaderStages::all(), ref other => { - log::error!("Intersection result of a pointer to {:?}", other); + log::error!("Intersection result of a pointer to {other:?}"); return Err(ExpressionError::InvalidRayQueryType(query)); } }, ref other => { - log::error!("Intersection result of {:?}", other); + log::error!("Intersection result of {other:?}"); return Err(ExpressionError::InvalidRayQueryType(query)); } }, diff --git a/naga/src/valid/function.rs b/naga/src/valid/function.rs index fb88f3934f5..dc19e191764 100644 --- a/naga/src/valid/function.rs +++ b/naga/src/valid/function.rs @@ -509,7 +509,7 @@ impl super::Validator { | crate::AtomicFunction::Subtract | crate::AtomicFunction::Exchange { compare: None } ) { - log::error!("Float32 atomic operation {:?} is not supported", fun); + log::error!("Float32 atomic operation {fun:?} is not supported"); return Err(AtomicError::InvalidOperator(*fun) .with_span_handle(value, context.expressions) .into_other()); @@ -639,7 +639,7 @@ impl super::Validator { crate::TypeInner::Scalar(scalar) => (true, scalar), crate::TypeInner::Vector { scalar, .. } => (false, scalar), _ => { - log::error!("Subgroup operand type {:?}", argument_inner); + log::error!("Subgroup operand type {argument_inner:?}"); return Err(SubgroupError::InvalidOperand(argument) .with_span_handle(argument, context.expressions) .into_other()); @@ -654,7 +654,7 @@ impl super::Validator { (sk::Sint | sk::Uint, sg::And | sg::Or | sg::Xor) => {} (_, _) => { - log::error!("Subgroup operand type {:?}", argument_inner); + log::error!("Subgroup operand type {argument_inner:?}"); return Err(SubgroupError::InvalidOperand(argument) .with_span_handle(argument, context.expressions) .into_other()); @@ -714,8 +714,7 @@ impl super::Validator { crate::TypeInner::Scalar(crate::Scalar::U32) => {} _ => { log::error!( - "Subgroup gather index type {:?}, expected unsigned int", - index_ty + "Subgroup gather index type {index_ty:?}, expected unsigned int" ); return Err(SubgroupError::InvalidOperand(argument) .with_span_handle(index, context.expressions) @@ -740,7 +739,7 @@ impl super::Validator { crate::TypeInner::Scalar ( scalar, .. ) | crate::TypeInner::Vector { scalar, .. } if matches!(scalar.kind, crate::ScalarKind::Uint | crate::ScalarKind::Sint | crate::ScalarKind::Float) ) { - log::error!("Subgroup gather operand type {:?}", argument_inner); + log::error!("Subgroup gather operand type {argument_inner:?}"); return Err(SubgroupError::InvalidOperand(argument) .with_span_handle(argument, context.expressions) .into_other()); @@ -1567,8 +1566,7 @@ impl super::Validator { crate::TypeInner::Scalar(crate::Scalar::BOOL,) ) { log::error!( - "Subgroup ballot predicate type {:?} expected bool", - predicate_inner + "Subgroup ballot predicate type {predicate_inner:?} expected bool" ); return Err(SubgroupError::InvalidOperand(predicate) .with_span_handle(predicate, context.expressions) @@ -1645,7 +1643,7 @@ impl super::Validator { fun_info: &FunctionInfo, local_expr_kind: &crate::proc::ExpressionKindTracker, ) -> Result<(), LocalVariableError> { - log::debug!("var {:?}", var); + log::debug!("var {var:?}"); let type_info = self .types .get(var.ty.index()) diff --git a/naga/src/valid/interface.rs b/naga/src/valid/interface.rs index 14cfa42e8a4..7c8cc903139 100644 --- a/naga/src/valid/interface.rs +++ b/naga/src/valid/interface.rs @@ -309,7 +309,7 @@ impl VaryingContext<'_> { return Err(VaryingError::InvalidBuiltInStage(built_in)); } if !type_good { - log::warn!("Wrong builtin type: {:?}", ty_inner); + log::warn!("Wrong builtin type: {ty_inner:?}"); return Err(VaryingError::InvalidBuiltInType(built_in)); } } @@ -501,7 +501,7 @@ impl super::Validator { ) -> Result<(), GlobalVariableError> { use super::TypeFlags; - log::debug!("var {:?}", var); + log::debug!("var {var:?}"); let inner_ty = match gctx.types[var.ty].inner { // A binding array is (mostly) supposed to behave the same as a // series of individually bound resources, so we can (mostly) @@ -795,12 +795,8 @@ impl super::Validator { crate::AddressSpace::PushConstant => GlobalUse::READ, }; if !allowed_usage.contains(usage) { - log::warn!("\tUsage error for: {:?}", var); - log::warn!( - "\tAllowed usage: {:?}, requested: {:?}", - allowed_usage, - usage - ); + log::warn!("\tUsage error for: {var:?}"); + log::warn!("\tAllowed usage: {allowed_usage:?}, requested: {usage:?}"); return Err(EntryPointError::InvalidGlobalUsage(var_handle, usage) .with_span_handle(var_handle, &module.global_variables)); } diff --git a/naga/tests/naga/snapshots.rs b/naga/tests/naga/snapshots.rs index 32e2f5e0285..e6e848deb7a 100644 --- a/naga/tests/naga/snapshots.rs +++ b/naga/tests/naga/snapshots.rs @@ -357,7 +357,7 @@ impl Input { "spvasm" => params.targets = Some(Targets::non_wgsl_default()), "vert" | "frag" | "comp" => params.targets = Some(Targets::non_wgsl_default()), e => { - panic!("Unknown extension: {}", e); + panic!("Unknown extension: {e}"); } } } diff --git a/naga/tests/naga/validation.rs b/naga/tests/naga/validation.rs index b7ba70ee028..9da549f8f14 100644 --- a/naga/tests/naga/validation.rs +++ b/naga/tests/naga/validation.rs @@ -1,3 +1,8 @@ +#![allow( + // We need to investiagate these. + clippy::result_large_err +)] + use naga::{ ir, valid::{self, ModuleInfo}, diff --git a/naga/tests/naga/wgsl_errors.rs b/naga/tests/naga/wgsl_errors.rs index 962c8f46a2c..5784192efdb 100644 --- a/naga/tests/naga/wgsl_errors.rs +++ b/naga/tests/naga/wgsl_errors.rs @@ -2,6 +2,10 @@ Tests for the WGSL front end. */ #![cfg(feature = "wgsl-in")] +#![allow( + // We need to investiagate these. + clippy::result_large_err +)] use naga::{compact::KeepUnused, valid::Capabilities}; diff --git a/naga/xtask/Cargo.toml b/naga/xtask/Cargo.toml index a56a07515df..8b921bc3124 100644 --- a/naga/xtask/Cargo.toml +++ b/naga/xtask/Cargo.toml @@ -3,7 +3,7 @@ name = "naga-xtask" version = "0.1.0" edition = "2021" publish = false -rust-version = "1.84" +rust-version.workspace = true [target.'cfg(not(target_arch = "wasm32"))'.dependencies] anyhow.workspace = true diff --git a/naga/xtask/src/validate.rs b/naga/xtask/src/validate.rs index d1d75783ea8..66144006754 100644 --- a/naga/xtask/src/validate.rs +++ b/naga/xtask/src/validate.rs @@ -46,7 +46,7 @@ pub(crate) fn validate(cmd: ValidateSubcommand) -> anyhow::Result<()> { if let Err(error) = result { all_good = false; progress_bar.suspend(|| { - log::error!("{:#}", error); + log::error!("{error:#}"); }); } progress_bar.inc(1); diff --git a/player/src/bin/play.rs b/player/src/bin/play.rs index 719a5c09621..5d908a3a060 100644 --- a/player/src/bin/play.rs +++ b/player/src/bin/play.rs @@ -33,7 +33,7 @@ fn main() { _ => panic!("Provide the dir path as the parameter"), }; - log::info!("Loading trace '{:?}'", dir); + log::info!("Loading trace '{dir:?}'"); let file = fs::File::open(dir.join(trace::FILE_NAME)).unwrap(); let mut actions: Vec = ron::de::from_reader(file).unwrap(); actions.reverse(); // allows us to pop from the top @@ -66,7 +66,7 @@ fn main() { let (device, queue) = match actions.pop() { Some(trace::Action::Init { desc, backend }) => { - log::info!("Initializing the device for backend: {:?}", backend); + log::info!("Initializing the device for backend: {backend:?}"); let adapter = global .request_adapter( &wgc::instance::RequestAdapterOptions { @@ -143,18 +143,18 @@ fn main() { let error = global.surface_configure(surface, device, &config); if let Some(e) = error { - panic!("{:?}", e); + panic!("{e:?}"); } } } Some(trace::Action::Present(id)) => { frame_count += 1; - log::debug!("Presenting frame {}", frame_count); + log::debug!("Presenting frame {frame_count}"); global.surface_present(id).unwrap(); target.exit(); } Some(trace::Action::DiscardSurfaceTexture(id)) => { - log::debug!("Discarding frame {}", frame_count); + log::debug!("Discarding frame {frame_count}"); global.surface_texture_discard(id).unwrap(); target.exit(); } @@ -169,7 +169,7 @@ fn main() { } None => { if !done { - println!("Finished the end at frame {}", frame_count); + println!("Finished the end at frame {frame_count}"); done = true; } target.exit(); @@ -180,7 +180,7 @@ fn main() { if let Some(config) = resize_config.take() { let error = global.surface_configure(surface, device, &config); if let Some(e) = error { - panic!("{:?}", e); + panic!("{e:?}"); } } } diff --git a/player/src/lib.rs b/player/src/lib.rs index 16e31947149..90f3fd8823c 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -189,7 +189,7 @@ impl GlobalPlay for wgc::global::Global { comb_manager: &mut wgc::identity::IdentityManager, ) { use wgc::device::trace::Action; - log::debug!("action {:?}", action); + log::debug!("action {action:?}"); //TODO: find a way to force ID perishing without excessive `maintain()` calls. match action { Action::Init { .. } => { @@ -280,7 +280,7 @@ impl GlobalPlay for wgc::global::Global { self.bind_group_drop(id); } Action::CreateShaderModule { id, desc, data } => { - log::debug!("Creating shader from {}", data); + log::debug!("Creating shader from {data}"); let code = fs::read_to_string(dir.join(&data)).unwrap(); let source = if data.ends_with(".wgsl") { wgc::pipeline::ShaderModuleSource::Wgsl(Cow::Owned(code.clone())) diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 1ed8cd0e604..607c42c968f 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.84" +channel = "1.88" components = ["rustfmt", "clippy"] targets = ["wasm32-unknown-unknown"] diff --git a/tests/src/isolation.rs b/tests/src/isolation.rs index d99f4250882..75d98c115d3 100644 --- a/tests/src/isolation.rs +++ b/tests/src/isolation.rs @@ -31,7 +31,7 @@ impl OneTestPerProcessGuard { // We never abort if we're on wasm. Wasm tests are inherently single threaded, and panics cannot // unwind the stack and trigger all the guards, so we don't actually need to check. if other_tests_in_flight && !cfg!(target_arch = "wasm32") { - log::error!("{}", OTHER_TEST_IN_PROGRESS_ERROR); + log::error!("{OTHER_TEST_IN_PROGRESS_ERROR}"); // Hard exit to call attention to the error std::process::abort(); } diff --git a/tests/tests/wgpu-gpu/buffer_usages.rs b/tests/tests/wgpu-gpu/buffer_usages.rs index efb7636f65e..4c5312e12b9 100644 --- a/tests/tests/wgpu-gpu/buffer_usages.rs +++ b/tests/tests/wgpu-gpu/buffer_usages.rs @@ -83,7 +83,7 @@ async fn map_test( after_unmap: bool, after_destroy: bool, ) { - log::info!("map_test usage_type:{usage_type} map_mode_type:{:?} before_unmap:{before_unmap} before_destroy:{before_destroy} after_unmap:{after_unmap} after_destroy:{after_destroy}", map_mode_type); + log::info!("map_test usage_type:{usage_type} map_mode_type:{map_mode_type:?} before_unmap:{before_unmap} before_destroy:{before_destroy} after_unmap:{after_unmap} after_destroy:{after_destroy}"); let size = 8; let usage = match usage_type { diff --git a/tests/tests/wgpu-gpu/clear_texture.rs b/tests/tests/wgpu-gpu/clear_texture.rs index 0789eedb1cc..23883b2418c 100644 --- a/tests/tests/wgpu-gpu/clear_texture.rs +++ b/tests/tests/wgpu-gpu/clear_texture.rs @@ -209,12 +209,7 @@ async fn single_texture_clear_test( size: wgpu::Extent3d, dimension: wgpu::TextureDimension, ) { - log::info!( - "clearing texture with {:?}, dimension {:?}, size {:?}", - format, - dimension, - size - ); + log::info!("clearing texture with {format:?}, dimension {dimension:?}, size {size:?}"); let extra_usages = match format { wgpu::TextureFormat::Depth24Plus | wgpu::TextureFormat::Depth24PlusStencil8 => { diff --git a/tests/tests/wgpu-gpu/samplers.rs b/tests/tests/wgpu-gpu/samplers.rs index 97e57a55f7a..adb49d067eb 100644 --- a/tests/tests/wgpu-gpu/samplers.rs +++ b/tests/tests/wgpu-gpu/samplers.rs @@ -114,7 +114,7 @@ fn sampler_creation_failure(ctx: TestingContext) { for i in 0..failed_count { valid(&ctx.device, || { - eprintln!("Trying to create sampler {}", i); + eprintln!("Trying to create sampler {i}"); let sampler = ctx.device.create_sampler(&wgpu::SamplerDescriptor { lod_min_clamp: i as f32 * 0.01, // Change the max clamp to ensure the sampler is using different cache slots from @@ -188,7 +188,7 @@ fn sampler_bind_group(ctx: TestingContext, group_type: GroupType) { GroupType::Multi => MULTI_GROUP_BINDINGS, }; - let full_shader = format!("{}\n{}", bindings, SAMPLER_CODE); + let full_shader = format!("{bindings}\n{SAMPLER_CODE}"); let module = ctx .device diff --git a/tests/tests/wgpu-gpu/timestamp_normalization/utils.rs b/tests/tests/wgpu-gpu/timestamp_normalization/utils.rs index aaf0548fa68..b68e2e0f6fd 100644 --- a/tests/tests/wgpu-gpu/timestamp_normalization/utils.rs +++ b/tests/tests/wgpu-gpu/timestamp_normalization/utils.rs @@ -51,8 +51,7 @@ fn assert_u64_mul_u32(left: u64, right: u32, computed: Uint96) { assert_eq!( computed, real, - "{left} * {right} should be {real} but is {}", - computed + "{left} * {right} should be {real} but is {computed}" ); } diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index cf2412536d8..92d0ea54bb5 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -1833,7 +1833,7 @@ impl Global { Ok(()) } - log::debug!("configuring surface with {:?}", config); + log::debug!("configuring surface with {config:?}"); let error = 'error: { // User callbacks must not be called while we are holding locks. @@ -1968,7 +1968,7 @@ impl Global { E::Device(device.handle_hal_error(error)) } hal::SurfaceError::Other(message) => { - log::error!("surface configuration failed: {}", message); + log::error!("surface configuration failed: {message}"); E::InvalidSurface } } diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index 67bb8a3c6d5..ed8b3862af7 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -22,7 +22,6 @@ use crate::{ /// resources it uses must remain alive until it has finished executing. /// /// [`wgpu_hal`]: hal -/// [`ResourceInfo::submission_index`]: crate::resource::ResourceInfo struct ActiveSubmission { /// The index of the submission we track. /// diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 4b41ff8b8b2..3e38726b8b4 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -553,9 +553,7 @@ impl Device { // This is defensive, as this should never be hit. assert!( current_finished_submission >= wait_submission_index, - "If the queue is empty, the current submission index ({}) should be at least the wait submission index ({})", - current_finished_submission, - wait_submission_index + "If the queue is empty, the current submission index ({current_finished_submission}) should be at least the wait submission index ({wait_submission_index})" ); } @@ -1772,7 +1770,7 @@ impl Device { pipeline::CreateShaderModuleError::Device(self.handle_hal_error(error)) } hal::ShaderError::Compilation(ref msg) => { - log::error!("Shader error: {}", msg); + log::error!("Shader error: {msg}"); pipeline::CreateShaderModuleError::Generation } }) @@ -1841,7 +1839,7 @@ impl Device { pipeline::CreateShaderModuleError::Device(self.handle_hal_error(error)) } hal::ShaderError::Compilation(ref msg) => { - log::error!("Shader error: {}", msg); + log::error!("Shader error: {msg}"); pipeline::CreateShaderModuleError::Generation } }) diff --git a/wgpu-core/src/device/trace.rs b/wgpu-core/src/device/trace.rs index 9d031bef8a6..33025818f4b 100644 --- a/wgpu-core/src/device/trace.rs +++ b/wgpu-core/src/device/trace.rs @@ -220,7 +220,7 @@ pub struct Trace { #[cfg(feature = "trace")] impl Trace { pub fn new(path: std::path::PathBuf) -> Result { - log::info!("Tracing into '{:?}'", path); + log::info!("Tracing into '{path:?}'"); let mut file = std::fs::File::create(path.join(FILE_NAME))?; file.write_all(b"[\n")?; Ok(Self { @@ -241,10 +241,10 @@ impl Trace { pub(crate) fn add(&mut self, action: Action) { match ron::ser::to_string_pretty(&action, self.config.clone()) { Ok(string) => { - let _ = writeln!(self.file, "{},", string); + let _ = writeln!(self.file, "{string},"); } Err(e) => { - log::warn!("RON serialization failure: {:?}", e); + log::warn!("RON serialization failure: {e:?}"); } } } diff --git a/wgpu-core/src/id.rs b/wgpu-core/src/id.rs index 8858e1f8966..cac9c134811 100644 --- a/wgpu-core/src/id.rs +++ b/wgpu-core/src/id.rs @@ -75,7 +75,7 @@ impl RawId { /// [`Hub`]: crate::hub::Hub /// [`Hub`]: crate::hub::Hub /// [`Texture`]: crate::resource::Texture -/// [`Registry`]: crate::hub::Registry +/// [`Registry`]: crate::registry::Registry /// [`Noop`]: hal::api::Noop #[repr(transparent)] #[cfg_attr(any(feature = "serde", feature = "trace"), derive(serde::Serialize))] diff --git a/wgpu-core/src/identity.rs b/wgpu-core/src/identity.rs index 0870b905e83..b34282207d7 100644 --- a/wgpu-core/src/identity.rs +++ b/wgpu-core/src/identity.rs @@ -33,7 +33,6 @@ enum IdSource { /// ids with new index values. Freed vector entries get reused. /// /// [`Id`]: crate::id::Id -/// [`Backend`]: wgt::Backend; /// [`alloc`]: IdentityValues::alloc /// [`release`]: IdentityValues::release #[derive(Debug)] diff --git a/wgpu-core/src/indirect_validation/dispatch.rs b/wgpu-core/src/indirect_validation/dispatch.rs index a1c1627fd3a..04a283eb4bc 100644 --- a/wgpu-core/src/indirect_validation/dispatch.rs +++ b/wgpu-core/src/indirect_validation/dispatch.rs @@ -124,7 +124,7 @@ impl Dispatch { CreateShaderModuleError::Device(DeviceError::from_hal(error)) } hal::ShaderError::Compilation(ref msg) => { - log::error!("Shader error: {}", msg); + log::error!("Shader error: {msg}"); CreateShaderModuleError::Generation } } diff --git a/wgpu-core/src/indirect_validation/draw.rs b/wgpu-core/src/indirect_validation/draw.rs index 8e6943f3c34..bc26eb717fc 100644 --- a/wgpu-core/src/indirect_validation/draw.rs +++ b/wgpu-core/src/indirect_validation/draw.rs @@ -509,7 +509,7 @@ fn create_validation_module( CreateShaderModuleError::Device(DeviceError::from_hal(error)) } hal::ShaderError::Compilation(ref msg) => { - log::error!("Shader error: {}", msg); + log::error!("Shader error: {msg}"); CreateShaderModuleError::Generation } }, diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 4f36b0a85bf..cf7629e40fa 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -220,9 +220,7 @@ impl Instance { } Err(err) => { log::debug!( - "Instance::create_surface: failed to create surface for {:?}: {:?}", - backend, - err + "Instance::create_surface: failed to create surface for {backend:?}: {err:?}" ); errors.insert(*backend, err); } @@ -415,7 +413,7 @@ impl Instance { { // NOTE: We might be using `profiling` without any features. The empty backend of this // macro emits no code, so unused code linting changes depending on the backend. - profiling::scope!("enumerating", &*alloc::format!("{:?}", _backend)); + profiling::scope!("enumerating", &*alloc::format!("{_backend:?}")); let hal_adapters = unsafe { instance.enumerate_adapters(None) }; for raw in hal_adapters { @@ -452,7 +450,7 @@ impl Instance { let mut backend_adapters = unsafe { instance.enumerate_adapters(compatible_hal_surface) }; if backend_adapters.is_empty() { - log::debug!("enabled backend `{:?}` has no adapters", backend); + log::debug!("enabled backend `{backend:?}` has no adapters"); no_adapter_backends |= Backends::from(backend); // by continuing, we avoid setting the further error bits below continue; @@ -468,7 +466,7 @@ impl Instance { keep }); if backend_adapters.is_empty() { - log::debug!("* Backend `{:?}` has no fallback adapters", backend); + log::debug!("* Backend `{backend:?}` has no fallback adapters"); no_fallback_backends |= Backends::from(backend); continue; } @@ -804,11 +802,7 @@ impl Adapter { && !caps.downlevel.is_webgpu_compliant() { let missing_flags = wgt::DownlevelFlags::compliant() - caps.downlevel.flags; - log::warn!( - "Missing downlevel flags: {:?}\n{}", - missing_flags, - DOWNLEVEL_WARNING_MESSAGE - ); + log::warn!("Missing downlevel flags: {missing_flags:?}\n{DOWNLEVEL_WARNING_MESSAGE}"); log::warn!("{:#?}", caps.downlevel); } diff --git a/wgpu-core/src/lib.rs b/wgpu-core/src/lib.rs index 54c9f1cdc64..a22e218d4d3 100644 --- a/wgpu-core/src/lib.rs +++ b/wgpu-core/src/lib.rs @@ -36,7 +36,9 @@ // It gets in the way a lot and does not prevent bugs in practice. clippy::pattern_type_mismatch, // `wgpu-core` isn't entirely user-facing, so it's useful to document internal items. - rustdoc::private_intra_doc_links + rustdoc::private_intra_doc_links, + // We should investigate these. + clippy::result_large_err )] #![warn( clippy::alloc_instead_of_core, diff --git a/wgpu-core/src/lock/observing.rs b/wgpu-core/src/lock/observing.rs index 16ae51be43b..f3f61455d51 100644 --- a/wgpu-core/src/lock/observing.rs +++ b/wgpu-core/src/lock/observing.rs @@ -294,13 +294,10 @@ fn acquire(new_rank: LockRank, location: &'static Location<'static>) -> Option Status::Outdated, hal::SurfaceError::Other(msg) => { - log::error!("acquire error: {}", msg); + log::error!("acquire error: {msg}"); Status::Lost } }, @@ -309,7 +309,7 @@ impl Surface { } hal::SurfaceError::Outdated => Ok(Status::Outdated), hal::SurfaceError::Other(msg) => { - log::error!("acquire error: {}", msg); + log::error!("acquire error: {msg}"); Err(SurfaceError::Invalid) } }, diff --git a/wgpu-core/src/timestamp_normalization/mod.rs b/wgpu-core/src/timestamp_normalization/mod.rs index e5a9ef9a8ad..651773c389c 100644 --- a/wgpu-core/src/timestamp_normalization/mod.rs +++ b/wgpu-core/src/timestamp_normalization/mod.rs @@ -177,7 +177,7 @@ impl TimestampNormalizer { CreateShaderModuleError::Device(device.handle_hal_error(error)) } hal::ShaderError::Compilation(ref msg) => { - log::error!("Shader error: {}", msg); + log::error!("Shader error: {msg}"); CreateShaderModuleError::Generation } })?; @@ -274,8 +274,7 @@ impl TimestampNormalizer { let bg_label_alloc; let label = match buffer_label { Some(label) => { - bg_label_alloc = - alloc::format!("Timestamp normalization bind group ({})", label); + bg_label_alloc = alloc::format!("Timestamp normalization bind group ({label})"); &*bg_label_alloc } None => "Timestamp normalization bind group", diff --git a/wgpu-core/src/validation.rs b/wgpu-core/src/validation.rs index fe303ace73b..f720ef68b49 100644 --- a/wgpu-core/src/validation.rs +++ b/wgpu-core/src/validation.rs @@ -937,7 +937,7 @@ impl Interface { // the reality is - every shader coming from `glslc` outputs an array // of clip distances and hits this path :( // So we lower it to `log::warn` to be less annoying. - log::warn!("Unexpected varying type: {:?}", other); + log::warn!("Unexpected varying type: {other:?}"); return; } }; diff --git a/wgpu-hal/examples/halmark/main.rs b/wgpu-hal/examples/halmark/main.rs index 153bd49adb5..8f93cc58602 100644 --- a/wgpu-hal/examples/halmark/main.rs +++ b/wgpu-hal/examples/halmark/main.rs @@ -123,7 +123,7 @@ impl Example { let surface_caps = unsafe { adapter.surface_capabilities(&surface) } .ok_or("failed to get surface capabilities")?; - log::info!("Surface caps: {:#?}", surface_caps); + log::info!("Surface caps: {surface_caps:#?}"); let hal::OpenDevice { device, queue } = unsafe { adapter diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index 93e687ff1b5..4fcb6691393 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -269,7 +269,7 @@ impl Example { }; let surface_caps = unsafe { adapter.surface_capabilities(&surface) } .expect("Surface doesn't support presentation"); - log::info!("Surface caps: {:#?}", surface_caps); + log::info!("Surface caps: {surface_caps:#?}"); let hal::OpenDevice { device, queue } = unsafe { adapter diff --git a/wgpu-hal/src/auxil/dxgi/exception.rs b/wgpu-hal/src/auxil/dxgi/exception.rs index b938da31ffa..e520ab18505 100644 --- a/wgpu-hal/src/auxil/dxgi/exception.rs +++ b/wgpu-hal/src/auxil/dxgi/exception.rs @@ -80,7 +80,7 @@ unsafe extern "system" fn output_debug_string_handler( } let _ = std::panic::catch_unwind(|| { - log::log!(level, "{}", message); + log::log!(level, "{message}"); }); #[cfg(feature = "validation_canary")] diff --git a/wgpu-hal/src/auxil/dxgi/factory.rs b/wgpu-hal/src/auxil/dxgi/factory.rs index dd7305c1bc5..ac050bcd332 100644 --- a/wgpu-hal/src/auxil/dxgi/factory.rs +++ b/wgpu-hal/src/auxil/dxgi/factory.rs @@ -89,7 +89,7 @@ pub fn enumerate_adapters(factory: DxgiFactory) -> Vec { Ok(a) => a, Err(e) if e.code() == Dxgi::DXGI_ERROR_NOT_FOUND => break, Err(e) => { - log::error!("Failed enumerating adapters: {}", e); + log::error!("Failed enumerating adapters: {e}"); break; } }; diff --git a/wgpu-hal/src/auxil/dxgi/result.rs b/wgpu-hal/src/auxil/dxgi/result.rs index 23e1e0bea3b..256e0827879 100644 --- a/wgpu-hal/src/auxil/dxgi/result.rs +++ b/wgpu-hal/src/auxil/dxgi/result.rs @@ -8,7 +8,7 @@ impl HResult for windows::core::Result { #![allow(unreachable_code)] self.map_err(|err| { - log::error!("{} failed: {}", description, err); + log::error!("{description} failed: {err}"); match err.code() { Foundation::E_OUTOFMEMORY => crate::DeviceError::OutOfMemory, diff --git a/wgpu-hal/src/auxil/renderdoc.rs b/wgpu-hal/src/auxil/renderdoc.rs index 2770869be58..52fa2b0bd67 100644 --- a/wgpu-hal/src/auxil/renderdoc.rs +++ b/wgpu-hal/src/auxil/renderdoc.rs @@ -77,8 +77,7 @@ impl RenderDoc { Err(e) => { return RenderDoc::NotAvailable { reason: format!( - "Unable to get RENDERDOC_GetAPI from renderdoc library '{}': {e:?}", - renderdoc_filename + "Unable to get RENDERDOC_GetAPI from renderdoc library '{renderdoc_filename}': {e:?}" ), } } @@ -93,8 +92,7 @@ impl RenderDoc { }, return_value => RenderDoc::NotAvailable { reason: format!( - "Unable to get API from renderdoc library '{}': {}", - renderdoc_filename, return_value + "Unable to get API from renderdoc library '{renderdoc_filename}': {return_value}" ), }, } @@ -123,7 +121,7 @@ impl RenderDoc { true } Self::NotAvailable { ref reason } => { - log::warn!("Could not start RenderDoc frame capture: {}", reason); + log::warn!("Could not start RenderDoc frame capture: {reason}"); false } } @@ -136,7 +134,7 @@ impl RenderDoc { unsafe { entry.api.EndFrameCapture.unwrap()(device_handle, window_handle) }; } Self::NotAvailable { ref reason } => { - log::warn!("Could not end RenderDoc frame capture: {}", reason) + log::warn!("Could not end RenderDoc frame capture: {reason}") } }; } diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index 42a8e671103..5c0bee01732 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -328,7 +328,7 @@ impl super::Adapter { tier3_practical_descriptor_limit, ), other => { - log::warn!("Unknown resource binding tier {:?}", other); + log::warn!("Unknown resource binding tier {other:?}"); ( Direct3D12::D3D12_MAX_SHADER_VISIBLE_DESCRIPTOR_HEAP_SIZE_TIER_1, 8, diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index 32953455927..edfea952ed2 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -198,7 +198,7 @@ impl super::CommandEncoder { self.pass.dirty_root_elements ^= 1 << index; match self.pass.root_elements[index as usize] { - super::RootElement::Empty => log::error!("Root index {} is not bound", index), + super::RootElement::Empty => log::error!("Root index {index} is not bound"), super::RootElement::Constant => { let info = self.pass.layout.root_constant_info.as_ref().unwrap(); diff --git a/wgpu-hal/src/dx12/descriptor.rs b/wgpu-hal/src/dx12/descriptor.rs index 54cf6fa8ba7..f57ba46e1e2 100644 --- a/wgpu-hal/src/dx12/descriptor.rs +++ b/wgpu-hal/src/dx12/descriptor.rs @@ -96,7 +96,7 @@ impl GeneralHeap { pub(super) fn allocate_slice(&self, count: u64) -> Result { let range = self.ranges.lock().allocate_range(count).map_err(|err| { - log::error!("Unable to allocate descriptors: {:?}", err); + log::error!("Unable to allocate descriptors: {err:?}"); crate::DeviceError::OutOfMemory })?; Ok(range.start) diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 19e7743d6f7..7d245e8ce31 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -342,10 +342,7 @@ impl super::Device { (source, entry_point) }; log::info!( - "Naga generated shader for {:?} at {:?}:\n{}", - entry_point, - naga_stage, - source + "Naga generated shader for {entry_point:?} at {naga_stage:?}:\n{source}" ); ShaderCacheKey { @@ -1584,7 +1581,7 @@ impl crate::Device for super::Device { let buffer_size = (sampler_indexes.len() * size_of::()) as u64; let label = if let Some(label) = desc.label { - Cow::Owned(format!("{} (Internal Sampler Index Buffer)", label)) + Cow::Owned(format!("{label} (Internal Sampler Index Buffer)")) } else { Cow::Borrowed("Internal Sampler Index Buffer") }; @@ -2123,11 +2120,7 @@ impl crate::Device for super::Device { } }; - log::trace!( - "Waiting for fence value {} for {:?}", - value, - remaining_wait_duration - ); + log::trace!("Waiting for fence value {value} for {remaining_wait_duration:?}"); match unsafe { Threading::WaitForSingleObject( @@ -2145,13 +2138,13 @@ impl crate::Device for super::Device { break Ok(false); } other => { - log::error!("Unexpected wait status: 0x{:?}", other); + log::error!("Unexpected wait status: 0x{other:?}"); break Err(crate::DeviceError::Lost); } }; fence_value = unsafe { fence.raw.GetCompletedValue() }; - log::trace!("Wait complete! Fence actual value: {}", fence_value); + log::trace!("Wait complete! Fence actual value: {fence_value}"); if fence_value >= value { break Ok(true); diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index a41796331db..a102006acb0 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -1195,7 +1195,7 @@ impl SwapChain { Foundation::WAIT_OBJECT_0 => Ok(true), Foundation::WAIT_TIMEOUT => Ok(false), other => { - log::error!("Unexpected wait status: 0x{:x?}", other); + log::error!("Unexpected wait status: 0x{other:x?}"); Err(crate::SurfaceError::Lost) } } @@ -1316,7 +1316,7 @@ impl crate::Surface for Surface { }; let swap_chain1 = swap_chain1.map_err(|err| { - log::error!("SwapChain creation error: {}", err); + log::error!("SwapChain creation error: {err}"); crate::SurfaceError::Other("swapchain creation") })?; diff --git a/wgpu-hal/src/dx12/sampler.rs b/wgpu-hal/src/dx12/sampler.rs index 9a069475e31..4b58a0b4232 100644 --- a/wgpu-hal/src/dx12/sampler.rs +++ b/wgpu-hal/src/dx12/sampler.rs @@ -226,8 +226,7 @@ impl SamplerHeap { let Entry::Occupied(mut hash_map_entry) = state.mapping.entry(HashableSamplerDesc(desc)) else { log::error!( - "Tried to destroy a sampler that doesn't exist. Sampler description: {:#?}", - desc + "Tried to destroy a sampler that doesn't exist. Sampler description: {desc:#?}" ); return; }; diff --git a/wgpu-hal/src/dx12/suballocation.rs b/wgpu-hal/src/dx12/suballocation.rs index 8547f130088..8cee4102303 100644 --- a/wgpu-hal/src/dx12/suballocation.rs +++ b/wgpu-hal/src/dx12/suballocation.rs @@ -106,7 +106,7 @@ impl Allocator { }; let allocator = gpu_allocator::d3d12::Allocator::new(&allocator_desc).inspect_err(|e| { - log::error!("Failed to create d3d12 allocator, error: {}", e); + log::error!("Failed to create d3d12 allocator, error: {e}"); })?; Ok(Self { @@ -627,7 +627,7 @@ impl From for crate::DeviceError { match result { gpu_allocator::AllocationError::OutOfMemory => Self::OutOfMemory, gpu_allocator::AllocationError::FailedToMap(e) => { - log::error!("DX12 gpu-allocator: Failed to map: {}", e); + log::error!("DX12 gpu-allocator: Failed to map: {e}"); Self::Lost } gpu_allocator::AllocationError::NoCompatibleMemoryTypeFound => { @@ -639,15 +639,12 @@ impl From for crate::DeviceError { Self::Lost } gpu_allocator::AllocationError::InvalidAllocatorCreateDesc(e) => { - log::error!( - "DX12 gpu-allocator: Invalid Allocator Creation Description: {}", - e - ); + log::error!("DX12 gpu-allocator: Invalid Allocator Creation Description: {e}"); Self::Lost } gpu_allocator::AllocationError::Internal(e) => { - log::error!("DX12 gpu-allocator: Internal Error: {}", e); + log::error!("DX12 gpu-allocator: Internal Error: {e}"); Self::Lost } gpu_allocator::AllocationError::BarrierLayoutNeedsDevice10 diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index 952ff0c917e..d9d2812ccdd 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -220,9 +220,9 @@ impl super::Adapter { let vendor = unsafe { gl.get_parameter_string(vendor_const) }; let renderer = unsafe { gl.get_parameter_string(renderer_const) }; let version = unsafe { gl.get_parameter_string(glow::VERSION) }; - log::debug!("Vendor: {}", vendor); - log::debug!("Renderer: {}", renderer); - log::debug!("Version: {}", version); + log::debug!("Vendor: {vendor}"); + log::debug!("Renderer: {renderer}"); + log::debug!("Version: {version}"); let full_ver = Self::parse_full_version(&version).ok(); let es_ver = full_ver.map_or_else(|| Self::parse_version(&version).ok(), |_| None); @@ -293,7 +293,7 @@ impl super::Adapter { } }; - log::debug!("Supported GL Extensions: {:#?}", extensions); + log::debug!("Supported GL Extensions: {extensions:#?}"); let supported = |(req_es_major, req_es_minor), (req_full_major, req_full_minor)| { let es_supported = es_ver @@ -909,7 +909,7 @@ impl super::Adapter { if !unsafe { gl.get_shader_compile_status(shader) } { let msg = unsafe { gl.get_shader_info_log(shader) }; if !msg.is_empty() { - log::error!("\tShader compile error: {}", msg); + log::error!("\tShader compile error: {msg}"); } unsafe { gl.delete_shader(shader) }; None @@ -946,7 +946,7 @@ impl super::Adapter { let linked_ok = unsafe { gl.get_program_link_status(program) }; let msg = unsafe { gl.get_program_info_log(program) }; if !msg.is_empty() { - log::warn!("Shader link error: {}", msg); + log::warn!("Shader link error: {msg}"); } if !linked_ok { return None; diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index 0f36f734b8c..be9cc03fbe5 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -188,17 +188,17 @@ impl super::Device { unsafe { gl.shader_source(raw, shader) }; unsafe { gl.compile_shader(raw) }; - log::debug!("\tCompiled shader {:?}", raw); + log::debug!("\tCompiled shader {raw:?}"); let compiled_ok = unsafe { gl.get_shader_compile_status(raw) }; let msg = unsafe { gl.get_shader_info_log(raw) }; if compiled_ok { if !msg.is_empty() { - log::warn!("\tCompile: {}", msg); + log::warn!("\tCompile: {msg}"); } Ok(raw) } else { - log::error!("\tShader compilation failed: {}", msg); + log::error!("\tShader compilation failed: {msg}"); unsafe { gl.delete_shader(raw) }; Err(crate::PipelineError::Linkage( map_naga_stage(naga_stage), @@ -286,7 +286,7 @@ impl super::Device { crate::PipelineError::Linkage(map_naga_stage(naga_stage), msg) })?; - log::debug!("Naga generated shader:\n{}", output); + log::debug!("Naga generated shader:\n{output}"); context.consume_reflection( gl, @@ -422,7 +422,7 @@ impl super::Device { unsafe { gl.delete_shader(shader) }; } - log::debug!("\tLinked program {:?}", program); + log::debug!("\tLinked program {program:?}"); let linked_ok = unsafe { gl.get_program_link_status(program) }; let msg = unsafe { gl.get_program_info_log(program) }; @@ -430,7 +430,7 @@ impl super::Device { return Err(crate::PipelineError::Linkage(has_stages, msg)); } if !msg.is_empty() { - log::warn!("\tLink: {}", msg); + log::warn!("\tLink: {msg}"); } if !private_caps.contains(PrivateCapabilities::SHADER_BINDING_LAYOUT) { @@ -438,7 +438,7 @@ impl super::Device { // in the shader. We can't remap storage buffers this way. unsafe { gl.use_program(Some(program)) }; for (ref name, (register, slot)) in name_binding_map { - log::trace!("Get binding {:?} from program {:?}", name, program); + log::trace!("Get binding {name:?} from program {program:?}"); match register { super::BindingRegister::UniformBuffers => { let index = unsafe { gl.get_uniform_block_index(program, name) }.unwrap(); @@ -448,11 +448,7 @@ impl super::Device { super::BindingRegister::StorageBuffers => { let index = unsafe { gl.get_shader_storage_block_index(program, name) }.unwrap(); - log::error!( - "Unable to re-map shader storage block {} to {}", - name, - index - ); + log::error!("Unable to re-map shader storage block {name} to {index}"); return Err(crate::DeviceError::Lost.into()); } super::BindingRegister::Textures | super::BindingRegister::Images => { diff --git a/wgpu-hal/src/gles/egl.rs b/wgpu-hal/src/gles/egl.rs index 65844ec78f8..ce1dd1299cf 100644 --- a/wgpu-hal/src/gles/egl.rs +++ b/wgpu-hal/src/gles/egl.rs @@ -98,13 +98,7 @@ unsafe extern "system" fn egl_debug_proc( unsafe { ffi::CStr::from_ptr(message_raw) }.to_string_lossy() }; - log::log!( - log_severity, - "EGL '{}' code 0x{:x}: {}", - command, - error, - message, - ); + log::log!(log_severity, "EGL '{command}' code 0x{error:x}: {message}",); } /// A simple wrapper around an X11 or Wayland display handle. @@ -239,7 +233,7 @@ fn choose_config( let mut attributes = Vec::with_capacity(9); for tier_max in (0..tiers.len()).rev() { let name = tiers[tier_max].0; - log::debug!("\tTrying {}", name); + log::debug!("\tTrying {name}"); attributes.clear(); for &(_, tier_attr) in tiers[..=tier_max].iter() { @@ -275,7 +269,7 @@ fn choose_config( log::warn!("No config found!"); } Err(e) => { - log::error!("error in choose_first_config: {:?}", e); + log::error!("error in choose_first_config: {e:?}"); } } } @@ -527,7 +521,7 @@ impl Inner { .query_string(Some(display), khronos_egl::EXTENSIONS) .unwrap() .to_string_lossy(); - log::debug!("Display vendor {:?}, version {:?}", vendor, version,); + log::debug!("Display vendor {vendor:?}, version {version:?}",); log::debug!( "Display extensions: {:#?}", display_extensions.split_whitespace().collect::>() @@ -717,11 +711,11 @@ impl Drop for Inner { .instance .destroy_context(self.egl.display, self.egl.raw) { - log::warn!("Error in destroy_context: {:?}", e); + log::warn!("Error in destroy_context: {e:?}"); } if let Err(e) = terminate_display(&self.egl.instance, self.egl.display) { - log::warn!("Error in terminate: {:?}", e); + log::warn!("Error in terminate: {e:?}"); } } } @@ -1200,7 +1194,7 @@ impl Surface { Some(self.egl.raw), ) .map_err(|e| { - log::error!("make_current(surface) failed: {}", e); + log::error!("make_current(surface) failed: {e}"); crate::SurfaceError::Lost })?; @@ -1244,7 +1238,7 @@ impl Surface { .instance .swap_buffers(self.egl.display, sc.surface) .map_err(|e| { - log::error!("swap_buffers failed: {}", e); + log::error!("swap_buffers failed: {e}"); crate::SurfaceError::Lost // TODO: should we unset the current context here? })?; @@ -1252,7 +1246,7 @@ impl Surface { .instance .make_current(self.egl.display, None, None, None) .map_err(|e| { - log::error!("make_current(null) failed: {}", e); + log::error!("make_current(null) failed: {e}"); crate::SurfaceError::Lost })?; @@ -1419,7 +1413,7 @@ impl crate::Surface for Surface { match raw_result { Ok(raw) => (raw, wl_window), Err(e) => { - log::warn!("Error in create_window_surface: {:?}", e); + log::warn!("Error in create_window_surface: {e:?}"); return Err(crate::SurfaceError::Lost); } } diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 3500eb98cbf..94416086d2e 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -1100,11 +1100,7 @@ fn gl_debug_message_callback(source: u32, gltype: u32, id: u32, severity: u32, m let _ = std::panic::catch_unwind(|| { log::log!( log_severity, - "GLES: [{}/{}] ID {} : {}", - source_str, - type_str, - id, - message + "GLES: [{source_str}/{type_str}] ID {id} : {message}" ); }); diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index b9ab0c3c9b7..db5269ad4ad 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -225,6 +225,8 @@ clippy::missing_safety_doc, // It gets in the way a lot and does not prevent bugs in practice. clippy::pattern_type_mismatch, + // We should investigate these. + clippy::large_enum_variant )] #![warn( clippy::alloc_instead_of_core, diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index ef8e7c83a52..f4a79de640c 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -140,7 +140,7 @@ impl super::Device { Some((naga_stage, stage.entry_point)), stage.constants, ) - .map_err(|e| crate::PipelineError::PipelineConstants(stage_bit, format!("MSL: {:?}", e)))?; + .map_err(|e| crate::PipelineError::PipelineConstants(stage_bit, format!("MSL: {e:?}")))?; let ep_resources = &layout.per_stage_map[naga_stage]; @@ -193,7 +193,7 @@ impl super::Device { let (source, info) = naga::back::msl::write_string(&module, &module_info, &options, &pipeline_options) - .map_err(|e| crate::PipelineError::Linkage(stage_bit, format!("MSL: {:?}", e)))?; + .map_err(|e| crate::PipelineError::Linkage(stage_bit, format!("MSL: {e:?}")))?; log::debug!( "Naga generated shader for entry point '{}' and stage {:?}\n{}", @@ -215,8 +215,8 @@ impl super::Device { .lock() .new_library_with_source(source.as_ref(), &options) .map_err(|err| { - log::warn!("Naga generated shader:\n{}", source); - crate::PipelineError::Linkage(stage_bit, format!("Metal: {}", err)) + log::warn!("Naga generated shader:\n{source}"); + crate::PipelineError::Linkage(stage_bit, format!("Metal: {err}")) })?; let ep_index = module @@ -227,7 +227,7 @@ impl super::Device { let ep = &module.entry_points[ep_index]; let translated_ep_name = info.entry_point_names[0] .as_ref() - .map_err(|e| crate::PipelineError::Linkage(stage_bit, format!("{}", e)))?; + .map_err(|e| crate::PipelineError::Linkage(stage_bit, format!("{e}")))?; let wg_size = MTLSize { width: ep.workgroup_size[0] as _, @@ -238,7 +238,7 @@ impl super::Device { let function = library .get_function(translated_ep_name, None) .map_err(|e| { - log::error!("get_function: {:?}", e); + log::error!("get_function: {e:?}"); crate::PipelineError::EntryPoint(naga_stage) })?; @@ -777,7 +777,7 @@ impl crate::Device for super::Device { || info.counters.textures > self.shared.private_caps.max_textures_per_stage || info.counters.samplers > self.shared.private_caps.max_samplers_per_stage { - log::error!("Resource limit exceeded: {:?}", info); + log::error!("Resource limit exceeded: {info:?}"); return Err(crate::DeviceError::OutOfMemory); } } @@ -1018,11 +1018,10 @@ impl crate::Device for super::Device { let device = self.shared.device.lock(); let library = device .new_library_with_source(&source, &options) - .map_err(|e| crate::ShaderError::Compilation(format!("MSL: {:?}", e)))?; + .map_err(|e| crate::ShaderError::Compilation(format!("MSL: {e:?}")))?; let function = library.get_function(&entry_point, None).map_err(|_| { crate::ShaderError::Compilation(format!( - "Entry point '{}' not found", - entry_point + "Entry point '{entry_point}' not found" )) })?; @@ -1289,7 +1288,7 @@ impl crate::Device for super::Device { .map_err(|e| { crate::PipelineError::Linkage( wgt::ShaderStages::VERTEX | wgt::ShaderStages::FRAGMENT, - format!("new_render_pipeline_state: {:?}", e), + format!("new_render_pipeline_state: {e:?}"), ) })?; @@ -1397,7 +1396,7 @@ impl crate::Device for super::Device { .map_err(|e| { crate::PipelineError::Linkage( wgt::ShaderStages::COMPUTE, - format!("new_compute_pipeline_state: {:?}", e), + format!("new_compute_pipeline_state: {e:?}"), ) })?; @@ -1472,7 +1471,7 @@ impl crate::Device for super::Device { match device.new_counter_sample_buffer_with_descriptor(&csb_desc) { Ok(buffer) => buffer, Err(err) => { - log::error!("Failed to create counter sample buffer: {:?}", err); + log::error!("Failed to create counter sample buffer: {err:?}"); return Err(crate::DeviceError::Unexpected); } }; @@ -1540,7 +1539,7 @@ impl crate::Device for super::Device { { Some((_, cmd_buf)) => cmd_buf, None => { - log::error!("No active command buffers for fence value {}", wait_value); + log::error!("No active command buffers for fence value {wait_value}"); return Err(crate::DeviceError::Lost); } }; diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index e1bd7ff0fda..00223b2f778 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -338,7 +338,7 @@ unsafe impl Sync for AdapterShared {} impl AdapterShared { fn new(device: metal::Device) -> Self { let private_caps = PrivateCapabilities::new(&device); - log::debug!("{:#?}", private_caps); + log::debug!("{private_caps:#?}"); Self { disabilities: PrivateDisabilities::new(&device), diff --git a/wgpu-hal/src/metal/surface.rs b/wgpu-hal/src/metal/surface.rs index 444193d6164..2a705cd7901 100644 --- a/wgpu-hal/src/metal/surface.rs +++ b/wgpu-hal/src/metal/surface.rs @@ -139,7 +139,7 @@ impl crate::Surface for super::Surface { device: &super::Device, config: &crate::SurfaceConfiguration, ) -> Result<(), crate::SurfaceError> { - log::debug!("build swapchain {:?}", config); + log::debug!("build swapchain {config:?}"); let caps = &device.shared.private_caps; *self.swapchain_format.write() = Some(config.format); diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 399c9d81ab4..24f0bfa9199 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -1694,7 +1694,7 @@ impl super::Instance { }; let queue_flags = queue_families.first()?.queue_flags; if !queue_flags.contains(vk::QueueFlags::GRAPHICS) { - log::warn!("The first queue only exposes {:?}", queue_flags); + log::warn!("The first queue only exposes {queue_flags:?}"); return None; } @@ -1822,10 +1822,10 @@ impl super::Adapter { }); if !unsupported_extensions.is_empty() { - log::warn!("Missing extensions: {:?}", unsupported_extensions); + log::warn!("Missing extensions: {unsupported_extensions:?}"); } - log::debug!("Supported extensions: {:?}", supported_extensions); + log::debug!("Supported extensions: {supported_extensions:?}"); supported_extensions } @@ -2510,7 +2510,7 @@ impl crate::Adapter for super::Adapter { Ok(true) => (), Ok(false) => return None, Err(e) => { - log::error!("get_physical_device_surface_support: {}", e); + log::error!("get_physical_device_surface_support: {e}"); return None; } } @@ -2525,7 +2525,7 @@ impl crate::Adapter for super::Adapter { } { Ok(caps) => caps, Err(e) => { - log::error!("get_physical_device_surface_capabilities: {}", e); + log::error!("get_physical_device_surface_capabilities: {e}"); return None; } } @@ -2559,7 +2559,7 @@ impl crate::Adapter for super::Adapter { } { Ok(present_modes) => present_modes, Err(e) => { - log::error!("get_physical_device_surface_present_modes: {}", e); + log::error!("get_physical_device_surface_present_modes: {e}"); // Per definition of `SurfaceCapabilities`, there must be at least one present mode. return None; } @@ -2575,7 +2575,7 @@ impl crate::Adapter for super::Adapter { } { Ok(formats) => formats, Err(e) => { - log::error!("get_physical_device_surface_formats: {}", e); + log::error!("get_physical_device_surface_formats: {e}"); // Per definition of `SurfaceCapabilities`, there must be at least one present format. return None; } diff --git a/wgpu-hal/src/vulkan/conv.rs b/wgpu-hal/src/vulkan/conv.rs index 405c8184470..5177896ac5b 100644 --- a/wgpu-hal/src/vulkan/conv.rs +++ b/wgpu-hal/src/vulkan/conv.rs @@ -484,7 +484,7 @@ pub fn map_vk_present_mode(mode: vk::PresentModeKHR) -> Option FIFO_LATEST_READY => None, _ => { - log::debug!("Unrecognized present mode {:?}", mode); + log::debug!("Unrecognized present mode {mode:?}"); None } } diff --git a/wgpu-hal/src/vulkan/drm.rs b/wgpu-hal/src/vulkan/drm.rs index a51268ebd3b..807260e33a5 100644 --- a/wgpu-hal/src/vulkan/drm.rs +++ b/wgpu-hal/src/vulkan/drm.rs @@ -54,7 +54,7 @@ impl super::Instance { let raw_devices = match unsafe { self.shared.raw.enumerate_physical_devices() } { Ok(devices) => devices, Err(err) => { - log::error!("enumerate_adapters: {}", err); + log::error!("enumerate_adapters: {err}"); Vec::new() } }; diff --git a/wgpu-hal/src/vulkan/instance.rs b/wgpu-hal/src/vulkan/instance.rs index 18b39017711..ddccc5c3b30 100644 --- a/wgpu-hal/src/vulkan/instance.rs +++ b/wgpu-hal/src/vulkan/instance.rs @@ -360,7 +360,7 @@ impl super::Instance { has_nv_optimus: bool, drop_callback: Option, ) -> Result { - log::debug!("Instance version: 0x{:x}", instance_api_version); + log::debug!("Instance version: 0x{instance_api_version:x}"); let debug_utils = if let Some(debug_utils_create_info) = debug_utils_create_info { if extensions.contains(&ext::debug_utils::NAME) { @@ -664,7 +664,7 @@ impl super::Instance { unsafe { entry.enumerate_instance_layer_properties() } }; let instance_layers = instance_layers.map_err(|e| { - log::debug!("enumerate_instance_layer_properties: {:?}", e); + log::debug!("enumerate_instance_layer_properties: {e:?}"); crate::InstanceError::with_source( String::from("enumerate_instance_layer_properties() failed"), e, @@ -962,7 +962,7 @@ impl crate::Instance for super::Instance { let raw_devices = match unsafe { self.shared.raw.enumerate_physical_devices() } { Ok(devices) => devices, Err(err) => { - log::error!("enumerate_adapters: {}", err); + log::error!("enumerate_adapters: {err}"); Vec::new() } }; diff --git a/wgpu-types/src/features.rs b/wgpu-types/src/features.rs index 53c2037c56d..5880c6ff351 100644 --- a/wgpu-types/src/features.rs +++ b/wgpu-types/src/features.rs @@ -1575,10 +1575,10 @@ mod tests { use alloc::format; let feature = Features::CLEAR_TEXTURE; - assert_eq!(format!("{}", feature), "CLEAR_TEXTURE"); + assert_eq!(format!("{feature}"), "CLEAR_TEXTURE"); let feature = Features::CLEAR_TEXTURE | Features::BGRA8UNORM_STORAGE; - assert_eq!(format!("{}", feature), "CLEAR_TEXTURE | BGRA8UNORM_STORAGE"); + assert_eq!(format!("{feature}"), "CLEAR_TEXTURE | BGRA8UNORM_STORAGE"); } #[test] diff --git a/wgpu-types/src/instance.rs b/wgpu-types/src/instance.rs index a427b1b1c3e..79e3f7b2526 100644 --- a/wgpu-types/src/instance.rs +++ b/wgpu-types/src/instance.rs @@ -13,7 +13,7 @@ use crate::{Backend, DownlevelFlags}; /// [`InstanceDescriptor::from_env_or_default()`] or [`InstanceDescriptor::with_env()`]. Each type /// within this descriptor has its own equivalent methods, so you can select which options you want /// to expose to influence from the environment. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct InstanceDescriptor { /// Which [`Backends`] to enable. /// @@ -39,17 +39,6 @@ pub struct InstanceDescriptor { pub backend_options: BackendOptions, } -impl Default for InstanceDescriptor { - fn default() -> Self { - Self { - backends: Backends::all(), - flags: InstanceFlags::default(), - memory_budget_thresholds: MemoryBudgetThresholds::default(), - backend_options: BackendOptions::default(), - } - } -} - impl InstanceDescriptor { /// Choose instance options entirely from environment variables. /// diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index aff93296605..e05822736ad 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -332,7 +332,7 @@ impl Backends { "webgpu" => Self::BROWSER_WEBGPU, "noop" => Self::NOOP, b => { - log::warn!("unknown backend string '{}'", b); + log::warn!("unknown backend string '{b}'"); continue; } } @@ -3668,7 +3668,7 @@ impl TextureFormat { // Two chroma bytes per block, one luma byte per block Self::NV12 => 3, f => { - log::warn!("Memory footprint for format {:?} is not implemented", f); + log::warn!("Memory footprint for format {f:?} is not implemented"); 0 } }, diff --git a/wgpu/src/backend/webgpu.rs b/wgpu/src/backend/webgpu.rs index 1cc99ee470a..deaea79e789 100644 --- a/wgpu/src/backend/webgpu.rs +++ b/wgpu/src/backend/webgpu.rs @@ -116,11 +116,7 @@ fn map_utf16_to_utf8_offset(utf16_offset: u32, text: &str) -> u32 { if utf16_i >= utf16_offset { text.len() as u32 } else { - log::error!( - "UTF16 offset {} is out of bounds for string {}", - utf16_offset, - text - ); + log::error!("UTF16 offset {utf16_offset} is out of bounds for string {text}"); u32::MAX } } @@ -2493,16 +2489,12 @@ impl dispatch::QueueInterface for WebQueue { } let write_size = u64::from(size); if write_size % wgt::COPY_BUFFER_ALIGNMENT != 0 { - log::error!( - "Copy size {} does not respect `COPY_BUFFER_ALIGNMENT`", - size - ); + log::error!("Copy size {size} does not respect `COPY_BUFFER_ALIGNMENT`"); return None; } if offset % wgt::COPY_BUFFER_ALIGNMENT != 0 { log::error!( - "Buffer offset {} is not aligned to block size or `COPY_BUFFER_ALIGNMENT`", - offset + "Buffer offset {offset} is not aligned to block size or `COPY_BUFFER_ALIGNMENT`" ); return None; } @@ -2600,7 +2592,7 @@ impl dispatch::QueueInterface for WebQueue { match wasm_bindgen_futures::JsFuture::from(promise).await { Ok(_) => callback(), Err(error) => { - log::error!("on_submitted_work_done promise failed: {:?}", error); + log::error!("on_submitted_work_done promise failed: {error:?}"); callback(); } } diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index 8fed4d9f88a..15fb57a45a0 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -1327,7 +1327,7 @@ impl dispatch::DeviceInterface for CoreDevice { .device_create_render_pipeline(self.id, &descriptor, None, None); if let Some(cause) = error { if let wgc::pipeline::CreateRenderPipelineError::Internal { stage, ref error } = cause { - log::error!("Shader translation error for stage {:?}: {}", stage, error); + log::error!("Shader translation error for stage {stage:?}: {error}"); log::error!("Please report it to https://github.com/gfx-rs/wgpu"); } self.context.handle_error( diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 0a3ded75f73..8a0a64b145a 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -43,6 +43,10 @@ rust_2018_idioms, unsafe_op_in_unsafe_fn )] +#![allow( + // We need to investiagate these. + clippy::large_enum_variant +)] // NOTE: Keep this in sync with `wgpu-core`. #![cfg_attr(not(send_sync), allow(clippy::arc_with_non_send_sync))] #![cfg_attr(not(any(wgpu_core, webgpu)), allow(unused))] diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 61fed29c9c4..330949337f2 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -2,7 +2,7 @@ name = "wgpu-xtask" version = "0.1.0" edition = "2021" -rust-version = "1.84" +rust-version.workspace = true publish = false [lints.rust] diff --git a/xtask/src/util.rs b/xtask/src/util.rs index 186426971fb..e38afde60d0 100644 --- a/xtask/src/util.rs +++ b/xtask/src/util.rs @@ -25,7 +25,7 @@ pub(crate) fn check_all_programs(programs: &[Program]) -> anyhow::Result<()> { } Err(e) => { log::error!("Checking for {binary_name} in PATH: ❌"); - panic!("Unknown IO error: {:?}", e); + panic!("Unknown IO error: {e:?}"); } } } diff --git a/xtask/src/vendor_web_sys.rs b/xtask/src/vendor_web_sys.rs index eaf30027cab..f519ae78662 100644 --- a/xtask/src/vendor_web_sys.rs +++ b/xtask/src/vendor_web_sys.rs @@ -180,7 +180,7 @@ pub(crate) fn run_vendor_web_sys(shell: Shell, mut args: Arguments) -> anyhow::R let git_url: Option = args.opt_value_from_str("--git-url")?; if let Some(url) = &git_url { - write!(&mut argument_description, " --git-url {}", url)?; + write!(&mut argument_description, " --git-url {url}")?; } let unknown_args = args.finish(); @@ -295,11 +295,11 @@ pub(crate) fn run_vendor_web_sys(shell: Shell, mut args: Arguments) -> anyhow::R module_file_contents.push_str("use web_sys::{Event, EventTarget};\n"); for &feature in WEB_SYS_FEATURES_NEEDED { - module_file_contents.push_str(&format!("mod gen_{};\n", feature)); - module_file_contents.push_str(&format!("pub use gen_{}::*;\n", feature)); + module_file_contents.push_str(&format!("mod gen_{feature};\n")); + module_file_contents.push_str(&format!("pub use gen_{feature}::*;\n")); } - shell.write_file(format!("{}/mod.rs", WEBGPU_SYS_PATH), module_file_contents)?; + shell.write_file(format!("{WEBGPU_SYS_PATH}/mod.rs"), module_file_contents)?; eprintln!("# Formatting files"); From 9a596fa1dc99658e2356993647b0636bb2ef0f79 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Thu, 17 Jul 2025 13:08:06 -0700 Subject: [PATCH 035/303] Fix warnings from the nightly Rust compiler (#7964) --- examples/features/src/framework.rs | 2 +- naga/src/arena/unique_arena.rs | 2 +- naga/src/compact/functions.rs | 2 +- naga/src/compact/mod.rs | 4 ++-- naga/src/front/spv/function.rs | 2 +- naga/src/front/wgsl/lower/mod.rs | 8 ++++---- naga/src/front/wgsl/parse/directive/enable_extension.rs | 2 +- naga/src/proc/constant_evaluator.rs | 2 +- naga/src/proc/namer.rs | 2 +- wgpu-core/src/command/memory_init.rs | 2 +- wgpu-core/src/init_tracker/mod.rs | 4 ++-- wgpu-core/src/lock/ranked.rs | 6 +++--- wgpu-core/src/lock/vanilla.rs | 6 +++--- wgpu-core/src/registry.rs | 2 +- wgpu-core/src/snatch.rs | 4 ++-- 15 files changed, 25 insertions(+), 25 deletions(-) diff --git a/examples/features/src/framework.rs b/examples/features/src/framework.rs index 50ad19194a3..7a3017848fa 100644 --- a/examples/features/src/framework.rs +++ b/examples/features/src/framework.rs @@ -247,7 +247,7 @@ impl SurfaceWrapper { } } - fn get(&self) -> Option<&Surface> { + fn get(&self) -> Option<&'_ Surface<'static>> { self.surface.as_ref() } diff --git a/naga/src/arena/unique_arena.rs b/naga/src/arena/unique_arena.rs index 49d481b2c0e..5b9f5297696 100644 --- a/naga/src/arena/unique_arena.rs +++ b/naga/src/arena/unique_arena.rs @@ -72,7 +72,7 @@ impl UniqueArena { .unwrap_or(&Span::default()) } - pub(crate) fn drain_all(&mut self) -> UniqueArenaDrain { + pub(crate) fn drain_all(&mut self) -> UniqueArenaDrain<'_, T> { UniqueArenaDrain { inner_elts: self.set.drain(..), inner_spans: self.span_info.drain(..), diff --git a/naga/src/compact/functions.rs b/naga/src/compact/functions.rs index eb829aec80e..dc91cade341 100644 --- a/naga/src/compact/functions.rs +++ b/naga/src/compact/functions.rs @@ -56,7 +56,7 @@ impl FunctionTracer<'_> { self.as_expression().trace_expressions(); } - fn as_expression(&mut self) -> super::expressions::ExpressionTracer { + fn as_expression(&mut self) -> super::expressions::ExpressionTracer<'_> { super::expressions::ExpressionTracer { constants: self.constants, overrides: self.overrides, diff --git a/naga/src/compact/mod.rs b/naga/src/compact/mod.rs index 48972dc648f..fe4296be844 100644 --- a/naga/src/compact/mod.rs +++ b/naga/src/compact/mod.rs @@ -460,7 +460,7 @@ impl<'module> ModuleTracer<'module> { } } - fn as_type(&mut self) -> types::TypeTracer { + fn as_type(&mut self) -> types::TypeTracer<'_> { types::TypeTracer { overrides: &self.module.overrides, types_used: &mut self.types_used, @@ -469,7 +469,7 @@ impl<'module> ModuleTracer<'module> { } } - fn as_const_expression(&mut self) -> expressions::ExpressionTracer { + fn as_const_expression(&mut self) -> expressions::ExpressionTracer<'_> { expressions::ExpressionTracer { constants: &self.module.constants, overrides: &self.module.overrides, diff --git a/naga/src/front/spv/function.rs b/naga/src/front/spv/function.rs index 1e581368e27..67cbf05f04f 100644 --- a/naga/src/front/spv/function.rs +++ b/naga/src/front/spv/function.rs @@ -603,7 +603,7 @@ impl> super::Frontend { } impl BlockContext<'_> { - pub(super) fn gctx(&self) -> crate::proc::GlobalCtx { + pub(super) fn gctx(&self) -> crate::proc::GlobalCtx<'_> { crate::proc::GlobalCtx { types: &self.module.types, constants: &self.module.constants, diff --git a/naga/src/front/wgsl/lower/mod.rs b/naga/src/front/wgsl/lower/mod.rs index e60ae41a787..7f702b82b93 100644 --- a/naga/src/front/wgsl/lower/mod.rs +++ b/naga/src/front/wgsl/lower/mod.rs @@ -466,7 +466,7 @@ impl<'source, 'temp, 'out> ExpressionContext<'source, 'temp, 'out> { } } - fn as_const_evaluator(&mut self) -> proc::ConstantEvaluator { + fn as_const_evaluator(&mut self) -> proc::ConstantEvaluator<'_> { match self.expr_type { ExpressionContextType::Runtime(ref mut rctx) => { proc::ConstantEvaluator::for_wgsl_function( @@ -513,7 +513,7 @@ impl<'source, 'temp, 'out> ExpressionContext<'source, 'temp, 'out> { fn as_diagnostic_display( &self, value: T, - ) -> crate::common::DiagnosticDisplay<(T, proc::GlobalCtx)> { + ) -> crate::common::DiagnosticDisplay<(T, proc::GlobalCtx<'_>)> { let ctx = self.module.to_ctx(); crate::common::DiagnosticDisplay((value, ctx)) } @@ -982,7 +982,7 @@ impl Components { } } - fn single_component(name: &str, name_span: Span) -> Result { + fn single_component(name: &str, name_span: Span) -> Result<'_, u32> { let ch = name.chars().next().ok_or(Error::BadAccessor(name_span))?; match Self::letter_component(ch) { Some(sc) => Ok(sc as u32), @@ -993,7 +993,7 @@ impl Components { /// Construct a `Components` value from a 'member' name, like `"wzy"` or `"x"`. /// /// Use `name_span` for reporting errors in parsing the component string. - fn new(name: &str, name_span: Span) -> Result { + fn new(name: &str, name_span: Span) -> Result<'_, Self> { let size = match name.len() { 1 => return Ok(Components::Single(Self::single_component(name, name_span)?)), 2 => ir::VectorSize::Bi, diff --git a/naga/src/front/wgsl/parse/directive/enable_extension.rs b/naga/src/front/wgsl/parse/directive/enable_extension.rs index 7064e40fb43..e614d19b6fe 100644 --- a/naga/src/front/wgsl/parse/directive/enable_extension.rs +++ b/naga/src/front/wgsl/parse/directive/enable_extension.rs @@ -73,7 +73,7 @@ impl EnableExtension { const SUBGROUPS: &'static str = "subgroups"; /// Convert from a sentinel word in WGSL into its associated [`EnableExtension`], if possible. - pub(crate) fn from_ident(word: &str, span: Span) -> Result { + pub(crate) fn from_ident(word: &str, span: Span) -> Result<'_, Self> { Ok(match word { Self::F16 => Self::Implemented(ImplementedEnableExtension::F16), Self::CLIP_DISTANCES => Self::Implemented(ImplementedEnableExtension::ClipDistances), diff --git a/naga/src/proc/constant_evaluator.rs b/naga/src/proc/constant_evaluator.rs index ac496f8562c..5aa9baaa961 100644 --- a/naga/src/proc/constant_evaluator.rs +++ b/naga/src/proc/constant_evaluator.rs @@ -703,7 +703,7 @@ impl<'a> ConstantEvaluator<'a> { } } - pub fn to_ctx(&self) -> crate::proc::GlobalCtx { + pub fn to_ctx(&self) -> crate::proc::GlobalCtx<'_> { crate::proc::GlobalCtx { types: self.types, constants: self.constants, diff --git a/naga/src/proc/namer.rs b/naga/src/proc/namer.rs index 74d28c4880e..504617dd1d3 100644 --- a/naga/src/proc/namer.rs +++ b/naga/src/proc/namer.rs @@ -201,7 +201,7 @@ impl Namer { self.keywords_case_insensitive.extend( reserved_keywords_case_insensitive .iter() - .map(|string| (AsciiUniCase(*string))), + .map(|string| AsciiUniCase(*string)), ); // Choose fallback names for anonymous entry point return types. diff --git a/wgpu-core/src/command/memory_init.rs b/wgpu-core/src/command/memory_init.rs index bec16272374..5ad9c7624b6 100644 --- a/wgpu-core/src/command/memory_init.rs +++ b/wgpu-core/src/command/memory_init.rs @@ -40,7 +40,7 @@ pub(crate) struct CommandBufferTextureMemoryActions { } impl CommandBufferTextureMemoryActions { - pub(crate) fn drain_init_actions(&mut self) -> Drain { + pub(crate) fn drain_init_actions(&mut self) -> Drain<'_, TextureInitTrackerAction> { self.init_actions.drain(..) } diff --git a/wgpu-core/src/init_tracker/mod.rs b/wgpu-core/src/init_tracker/mod.rs index c77eecd8648..abaf8b733d8 100644 --- a/wgpu-core/src/init_tracker/mod.rs +++ b/wgpu-core/src/init_tracker/mod.rs @@ -221,7 +221,7 @@ where } // Returns an iterator over the uninitialized ranges in a query range. - pub(crate) fn uninitialized(&mut self, drain_range: Range) -> UninitializedIter { + pub(crate) fn uninitialized(&mut self, drain_range: Range) -> UninitializedIter<'_, Idx> { let index = self .uninitialized_ranges .partition_point(|r| r.end <= drain_range.start); @@ -233,7 +233,7 @@ where } // Drains uninitialized ranges in a query range. - pub(crate) fn drain(&mut self, drain_range: Range) -> InitTrackerDrain { + pub(crate) fn drain(&mut self, drain_range: Range) -> InitTrackerDrain<'_, Idx> { let index = self .uninitialized_ranges .partition_point(|r| r.end <= drain_range.start); diff --git a/wgpu-core/src/lock/ranked.rs b/wgpu-core/src/lock/ranked.rs index 608126269f7..b633872ac0d 100644 --- a/wgpu-core/src/lock/ranked.rs +++ b/wgpu-core/src/lock/ranked.rs @@ -185,7 +185,7 @@ impl Mutex { } #[track_caller] - pub fn lock(&self) -> MutexGuard { + pub fn lock(&self) -> MutexGuard<'_, T> { let saved = acquire(self.rank, Location::caller()); MutexGuard { inner: self.inner.lock(), @@ -256,7 +256,7 @@ impl RwLock { } #[track_caller] - pub fn read(&self) -> RwLockReadGuard { + pub fn read(&self) -> RwLockReadGuard<'_, T> { let saved = acquire(self.rank, Location::caller()); RwLockReadGuard { inner: self.inner.read(), @@ -265,7 +265,7 @@ impl RwLock { } #[track_caller] - pub fn write(&self) -> RwLockWriteGuard { + pub fn write(&self) -> RwLockWriteGuard<'_, T> { let saved = acquire(self.rank, Location::caller()); RwLockWriteGuard { inner: self.inner.write(), diff --git a/wgpu-core/src/lock/vanilla.rs b/wgpu-core/src/lock/vanilla.rs index 9b9cf272b57..4ed38c38011 100644 --- a/wgpu-core/src/lock/vanilla.rs +++ b/wgpu-core/src/lock/vanilla.rs @@ -31,7 +31,7 @@ impl Mutex { Mutex(parking_lot::Mutex::new(value)) } - pub fn lock(&self) -> MutexGuard { + pub fn lock(&self) -> MutexGuard<'_, T> { MutexGuard(self.0.lock()) } @@ -87,11 +87,11 @@ impl RwLock { RwLock(parking_lot::RwLock::new(value)) } - pub fn read(&self) -> RwLockReadGuard { + pub fn read(&self) -> RwLockReadGuard<'_, T> { RwLockReadGuard(self.0.read()) } - pub fn write(&self) -> RwLockWriteGuard { + pub fn write(&self) -> RwLockWriteGuard<'_, T> { RwLockWriteGuard(self.0.write()) } diff --git a/wgpu-core/src/registry.rs b/wgpu-core/src/registry.rs index e015eb93af3..81b0b54ab77 100644 --- a/wgpu-core/src/registry.rs +++ b/wgpu-core/src/registry.rs @@ -70,7 +70,7 @@ impl FutureId<'_, T> { } impl Registry { - pub(crate) fn prepare(&self, id_in: Option>) -> FutureId { + pub(crate) fn prepare(&self, id_in: Option>) -> FutureId<'_, T> { FutureId { id: match id_in { Some(id_in) => { diff --git a/wgpu-core/src/snatch.rs b/wgpu-core/src/snatch.rs index f9b8e9f6080..a79cbcef331 100644 --- a/wgpu-core/src/snatch.rs +++ b/wgpu-core/src/snatch.rs @@ -143,7 +143,7 @@ impl SnatchLock { /// Request read access to snatchable resources. #[track_caller] - pub fn read(&self) -> SnatchGuard { + pub fn read(&self) -> SnatchGuard<'_> { LockTrace::enter("read"); SnatchGuard(self.lock.read()) } @@ -154,7 +154,7 @@ impl SnatchLock { /// a high risk of causing lock contention if called concurrently with other /// wgpu work. #[track_caller] - pub fn write(&self) -> ExclusiveSnatchGuard { + pub fn write(&self) -> ExclusiveSnatchGuard<'_> { LockTrace::enter("write"); ExclusiveSnatchGuard(self.lock.write()) } From 5d14f332593dbb0f759a5c80aa3fc697319aeec2 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Thu, 17 Jul 2025 15:52:51 -0700 Subject: [PATCH 036/303] Test for use of staging buffer in writeTexture (#7963) --- tests/tests/wgpu-gpu/write_texture.rs | 107 ++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/tests/tests/wgpu-gpu/write_texture.rs b/tests/tests/wgpu-gpu/write_texture.rs index 12349945a88..c02042c78bb 100644 --- a/tests/tests/wgpu-gpu/write_texture.rs +++ b/tests/tests/wgpu-gpu/write_texture.rs @@ -1,5 +1,6 @@ //! Tests for texture copy +use wgpu::*; use wgpu_test::{gpu_test, GpuTestConfiguration}; #[gpu_test] @@ -228,3 +229,109 @@ static WRITE_TEXTURE_NO_OOB: GpuTestConfiguration = }, ); }); + +// Test a writeTexture operation that will use the staging buffer. +// If run with the address sanitizer, this serves as a regression +// test for https://github.com/gfx-rs/wgpu/pull/7893. +#[gpu_test] +static WRITE_TEXTURE_VIA_STAGING_BUFFER: GpuTestConfiguration = GpuTestConfiguration::new() + .run_async(|ctx| async move { + let width = 89; + let height = 17; + + let tex = ctx.device.create_texture(&TextureDescriptor { + label: None, + dimension: TextureDimension::D2, + size: Extent3d { + width, + height, + depth_or_array_layers: 1, + }, + format: TextureFormat::R8Uint, + usage: TextureUsages::COPY_DST + | TextureUsages::COPY_SRC + | TextureUsages::TEXTURE_BINDING, + mip_level_count: 1, + sample_count: 1, + view_formats: &[], + }); + + let write_width: u32 = 31; + let write_height: u32 = 5; + let write_bytes_per_row: u32 = 113; + let write_data = (0..(write_height - 1) * write_bytes_per_row + write_width) + .map(|b| (b % 256) as u8) + .collect::>(); + + ctx.queue.write_texture( + TexelCopyTextureInfo { + texture: &tex, + mip_level: 0, + origin: Origin3d::ZERO, + aspect: TextureAspect::All, + }, + &write_data, + TexelCopyBufferLayout { + offset: 0, + bytes_per_row: Some(write_bytes_per_row), + rows_per_image: Some(19), + }, + Extent3d { + width: write_width, + height: write_height, + depth_or_array_layers: 1, + }, + ); + + ctx.queue.submit(None); + + let read_bytes_per_row = wgt::COPY_BYTES_PER_ROW_ALIGNMENT; + let read_buffer = ctx.device.create_buffer(&BufferDescriptor { + label: None, + size: (height * read_bytes_per_row) as u64, + usage: BufferUsages::MAP_READ | wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false, + }); + + let mut encoder = ctx + .device + .create_command_encoder(&CommandEncoderDescriptor { label: None }); + + encoder.copy_texture_to_buffer( + TexelCopyTextureInfo { + texture: &tex, + mip_level: 0, + origin: Origin3d::ZERO, + aspect: TextureAspect::All, + }, + TexelCopyBufferInfo { + buffer: &read_buffer, + layout: TexelCopyBufferLayout { + offset: 0, + bytes_per_row: Some(read_bytes_per_row), + rows_per_image: Some(height), + }, + }, + Extent3d { + width, + height, + depth_or_array_layers: 1, + }, + ); + + ctx.queue.submit(Some(encoder.finish())); + + let slice = read_buffer.slice(..); + slice.map_async(MapMode::Read, |_| ()); + ctx.async_poll(PollType::wait()).await.unwrap(); + let read_data: Vec = slice.get_mapped_range().to_vec(); + + for x in 0..write_width { + for y in 0..write_height { + assert_eq!( + read_data[(y * read_bytes_per_row + x) as usize], + write_data[(y * write_bytes_per_row + x) as usize] + ); + } + } + }); From 232d46509b1ec6cadf458d6ef9d47d230f4f337a Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 17 Jul 2025 21:12:30 -0400 Subject: [PATCH 037/303] ci: only allow one set of jobs per PR (#7958) --- .github/workflows/ci.yml | 7 +++ .github/workflows/cts.yml | 7 +++ .github/workflows/docs.yml | 7 +++ .github/workflows/generate.yml | 7 +++ .github/workflows/lazy.yml | 105 ++++++++++++++++++--------------- .github/workflows/publish.yml | 9 ++- .github/workflows/shaders.yml | 7 +++ 7 files changed, 99 insertions(+), 50 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 51a86219c48..87ec20dbc4c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,6 +46,13 @@ env: CACHE_SUFFIX: d # cache busting WGPU_CI: true +# Every time a PR is pushed to, cancel any previous jobs. This +# makes us behave nicer to github and get faster turnaround times +# on PRs that are pushed to multiple times in rapid succession. +concurrency: + group: ${{github.workflow}}-${{github.ref}} + cancel-in-progress: ${{github.event_name == 'pull_request'}} + # We distinguish the following kinds of builds: # - native: build for the same target as we compile on # - web: build for the Web diff --git a/.github/workflows/cts.yml b/.github/workflows/cts.yml index aeedd3df9f9..f7a2e1bf288 100644 --- a/.github/workflows/cts.yml +++ b/.github/workflows/cts.yml @@ -13,6 +13,13 @@ env: RUST_BACKTRACE: full MSRV: "1.88" +# Every time a PR is pushed to, cancel any previous jobs. This +# makes us behave nicer to github and get faster turnaround times +# on PRs that are pushed to multiple times in rapid succession. +concurrency: + group: ${{github.workflow}}-${{github.ref}} + cancel-in-progress: ${{github.event_name == 'pull_request'}} + jobs: cts: strategy: diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index ac97b771025..a8634bccd88 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -16,6 +16,13 @@ env: CARGO_TERM_COLOR: always RUST_BACKTRACE: full +# Every time a PR is pushed to, cancel any previous jobs. This +# makes us behave nicer to github and get faster turnaround times +# on PRs that are pushed to multiple times in rapid succession. +concurrency: + group: ${{github.workflow}}-${{github.ref}} + cancel-in-progress: ${{github.event_name == 'pull_request'}} + jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/generate.yml b/.github/workflows/generate.yml index a3f0fb18f0a..8feff230e5d 100644 --- a/.github/workflows/generate.yml +++ b/.github/workflows/generate.yml @@ -16,6 +16,13 @@ env: REPO_MSRV: "1.88" RUSTFLAGS: -D warnings +# Every time a PR is pushed to, cancel any previous jobs. This +# makes us behave nicer to github and get faster turnaround times +# on PRs that are pushed to multiple times in rapid succession. +concurrency: + group: ${{github.workflow}}-${{github.ref}} + cancel-in-progress: ${{github.event_name == 'pull_request'}} + jobs: cargo-generate: timeout-minutes: 5 diff --git a/.github/workflows/lazy.yml b/.github/workflows/lazy.yml index d33f4042368..46f666136c7 100644 --- a/.github/workflows/lazy.yml +++ b/.github/workflows/lazy.yml @@ -3,7 +3,7 @@ name: Lazy on: pull_request: paths: - - '.github/workflows/lazy.yml' + - ".github/workflows/lazy.yml" push: branches: [trunk] @@ -12,6 +12,13 @@ env: CARGO_TERM_COLOR: always RUST_BACKTRACE: full +# Every time a PR is pushed to, cancel any previous jobs. This +# makes us behave nicer to github and get faster turnaround times +# on PRs that are pushed to multiple times in rapid succession. +concurrency: + group: ${{github.workflow}}-${{github.ref}} + cancel-in-progress: ${{github.event_name == 'pull_request'}} + jobs: parse-dota2: name: "Validate Shaders: Dota2" @@ -98,58 +105,58 @@ jobs: - name: Compile `spv` from `spvasm` run: | - cd naga/spirv-samples - mkdir -p spv + cd naga/spirv-samples + mkdir -p spv - find "./spvasm" -name '*.spvasm' | while read fname; - do - echo "Convert to spv with spirv-as: $fname" - ../install/bin/spirv-as --target-env spv1.3 $(realpath ${fname}) -o ./spv/$(basename ${fname}).spv - done; + find "./spvasm" -name '*.spvasm' | while read fname; + do + echo "Convert to spv with spirv-as: $fname" + ../install/bin/spirv-as --target-env spv1.3 $(realpath ${fname}) -o ./spv/$(basename ${fname}).spv + done; - name: Validate `spv` and generate `wgsl` run: | - set +e - cd naga/spirv-samples - SUCCESS_RESULT_COUNT=0 - FILE_COUNT=0 - mkdir -p spv - mkdir -p wgsl - - echo "==== Validate spv and generate wgsl ====" - rm -f counter - touch counter - - find "./spv" -name '*.spv' | while read fname; - do - echo "Convert: $fname" - FILE_COUNT=$((FILE_COUNT+1)) - ../../target/release/naga --validate 27 $(realpath ${fname}) ./wgsl/$(basename ${fname}).wgsl - if [[ $? -eq 0 ]]; then - SUCCESS_RESULT_COUNT=$((SUCCESS_RESULT_COUNT + 1)) - fi - echo "Result: $(expr $FILE_COUNT - $SUCCESS_RESULT_COUNT) / $FILE_COUNT" > counter - done - cat counter + set +e + cd naga/spirv-samples + SUCCESS_RESULT_COUNT=0 + FILE_COUNT=0 + mkdir -p spv + mkdir -p wgsl + + echo "==== Validate spv and generate wgsl ====" + rm -f counter + touch counter + + find "./spv" -name '*.spv' | while read fname; + do + echo "Convert: $fname" + FILE_COUNT=$((FILE_COUNT+1)) + ../../target/release/naga --validate 27 $(realpath ${fname}) ./wgsl/$(basename ${fname}).wgsl + if [[ $? -eq 0 ]]; then + SUCCESS_RESULT_COUNT=$((SUCCESS_RESULT_COUNT + 1)) + fi + echo "Result: $(expr $FILE_COUNT - $SUCCESS_RESULT_COUNT) / $FILE_COUNT" > counter + done + cat counter - name: Validate output `wgsl` run: | - set +e - cd naga/spirv-samples - SUCCESS_RESULT_COUNT=0 - FILE_COUNT=0 - - rm -f counter - touch counter - - find "./wgsl" -name '*.wgsl' | while read fname; - do - echo "Validate: $fname" - FILE_COUNT=$((FILE_COUNT+1)) - ../../target/release/naga --validate 27 $(realpath ${fname}) - if [[ $? -eq 0 ]]; then - SUCCESS_RESULT_COUNT=$((SUCCESS_RESULT_COUNT + 1)) - fi - echo "Result: $(expr $FILE_COUNT - $SUCCESS_RESULT_COUNT) / $FILE_COUNT" > counter - done - cat counter + set +e + cd naga/spirv-samples + SUCCESS_RESULT_COUNT=0 + FILE_COUNT=0 + + rm -f counter + touch counter + + find "./wgsl" -name '*.wgsl' | while read fname; + do + echo "Validate: $fname" + FILE_COUNT=$((FILE_COUNT+1)) + ../../target/release/naga --validate 27 $(realpath ${fname}) + if [[ $? -eq 0 ]]; then + SUCCESS_RESULT_COUNT=$((SUCCESS_RESULT_COUNT + 1)) + fi + echo "Result: $(expr $FILE_COUNT - $SUCCESS_RESULT_COUNT) / $FILE_COUNT" > counter + done + cat counter diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 44326879b16..5967d20e863 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -3,7 +3,7 @@ name: Publish on: pull_request: paths: - - '.github/workflows/publish.yml' + - ".github/workflows/publish.yml" push: branches: - trunk @@ -13,6 +13,13 @@ env: CARGO_TERM_COLOR: always RUST_BACKTRACE: full +# Every time a PR is pushed to, cancel any previous jobs. This +# makes us behave nicer to github and get faster turnaround times +# on PRs that are pushed to multiple times in rapid succession. +concurrency: + group: ${{github.workflow}}-${{github.ref}} + cancel-in-progress: ${{github.event_name == 'pull_request'}} + jobs: publish: runs-on: ubuntu-latest diff --git a/.github/workflows/shaders.yml b/.github/workflows/shaders.yml index 8bcd6451506..b912c9d5dc4 100644 --- a/.github/workflows/shaders.yml +++ b/.github/workflows/shaders.yml @@ -18,6 +18,13 @@ env: # We don't include the 4th version number, as it's not used in any URL. VULKAN_SDK_VERSION: "1.4.313" +# Every time a PR is pushed to, cancel any previous jobs. This +# makes us behave nicer to github and get faster turnaround times +# on PRs that are pushed to multiple times in rapid succession. +concurrency: + group: ${{github.workflow}}-${{github.ref}} + cancel-in-progress: ${{github.event_name == 'pull_request'}} + jobs: naga-validate-windows: name: "Validate: HLSL" From cf4a74c6b909dc7062ba38a9a27a5421d983e6a7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 10 Jul 2025 22:24:26 +0000 Subject: [PATCH 038/303] chore(deps): update deps and deny file --- .deny.toml | 6 +- Cargo.lock | 156 +++++++++++++++++------ Cargo.toml | 8 +- benches/Cargo.toml | 2 +- benches/benches/wgpu-benchmark/shader.rs | 14 +- naga-cli/Cargo.toml | 2 +- naga-cli/src/bin/naga.rs | 6 +- 7 files changed, 143 insertions(+), 51 deletions(-) diff --git a/.deny.toml b/.deny.toml index 4e690a0cecb..80fc40130f1 100644 --- a/.deny.toml +++ b/.deny.toml @@ -29,7 +29,8 @@ skip = [ { name = "windows-result", version = "0.3.4" }, { name = "windows-strings", version = "0.4.2" }, - # cargo-metadata uses an old version of ordered-float. Only used for testing. + # cargo-metadata uses old version. Only used for infrastructure. + { name = "toml", version = "0.8.23" }, { name = "ordered-float", version = "2.10.1" }, # criterion uses an old version { name = "itertools", version = "0.10.5" }, @@ -41,6 +42,7 @@ skip = [ # Strum uses an old version { name = "heck", version = "0.4.0" }, # Deno uses an old version + { name = "bincode", version = "1.3.3" }, { name = "strum", version = "0.25.0" }, ] wildcards = "deny" @@ -70,7 +72,7 @@ private = { ignore = true } [sources] allow-git = [ - # Waiting on releases; used in examples only + # Waiting on releases; used in examples/tests only ] unknown-registry = "deny" unknown-git = "deny" diff --git a/Cargo.lock b/Cargo.lock index 64c090b97ad..c712af7b1de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -344,6 +344,26 @@ dependencies = [ "serde", ] +[[package]] +name = "bincode" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740" +dependencies = [ + "bincode_derive", + "serde", + "unty", +] + +[[package]] +name = "bincode_derive" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf95709a440f45e986983918d0e8a1f30a9b1df04918fc828670606804ac3c09" +dependencies = [ + "virtue", +] + [[package]] name = "bindgen" version = "0.70.1" @@ -595,25 +615,25 @@ dependencies = [ [[package]] name = "cargo-util-schemas" -version = "0.2.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e63d2780ac94487eb9f1fea7b0d56300abc9eb488800854ca217f102f5caccca" +checksum = "7dc1a6f7b5651af85774ae5a34b4e8be397d9cf4bc063b7e6dbd99a841837830" dependencies = [ "semver 1.0.26", "serde", "serde-untagged", "serde-value", - "thiserror 1.0.69", - "toml", + "thiserror 2.0.12", + "toml 0.8.23", "unicode-xid", "url", ] [[package]] name = "cargo_metadata" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f7835cfc6135093070e95eb2b53e5d9b5c403dc3a6be6040ee026270aa82502" +checksum = "5cfca2aaa699835ba88faf58a06342a314a950d2b9686165e038286c30316868" dependencies = [ "camino", "cargo-platform", @@ -723,9 +743,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.40" +version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" +checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9" dependencies = [ "clap_builder", "clap_derive", @@ -733,9 +753,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.40" +version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" +checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d" dependencies = [ "anstream", "anstyle", @@ -745,9 +765,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.40" +version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" +checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -905,9 +925,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] @@ -1046,7 +1066,7 @@ checksum = "113f3f08bd5daf99f1a7876c0f99cd8c3c609439fa0b808311ec856a253e95f0" dependencies = [ "anyhow", "az", - "bincode", + "bincode 1.3.3", "bit-set 0.5.3", "bit-vec 0.6.3", "bytes", @@ -2399,9 +2419,9 @@ checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "memmap2" -version = "0.9.5" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" +checksum = "483758ad303d734cec05e5c12b41d7e93e6a6390c5e9dae6bdeb7c1259012d28" dependencies = [ "libc", ] @@ -2508,7 +2528,7 @@ dependencies = [ "spirv", "strum 0.27.1", "thiserror 2.0.12", - "toml", + "toml 0.9.2", "unicode-ident", "walkdir", ] @@ -2519,7 +2539,7 @@ version = "26.0.0" dependencies = [ "anyhow", "argh", - "bincode", + "bincode 2.0.1", "codespan-reporting", "env_logger", "log", @@ -3238,7 +3258,7 @@ dependencies = [ "concurrent-queue", "hermit-abi", "pin-project-lite", - "rustix 1.0.7", + "rustix 1.0.8", "tracing", "windows-sys 0.59.0", ] @@ -3599,15 +3619,15 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" dependencies = [ "bitflags 2.9.1", "errno", "libc", "linux-raw-sys 0.9.4", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -3756,6 +3776,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83" +dependencies = [ + "serde", +] + [[package]] name = "serde_v8" version = "0.247.0" @@ -4041,9 +4070,9 @@ dependencies = [ [[package]] name = "sys_traits" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4707edf3196e8037ee45018d1bb1bfb233b0e4fc440fa3d3f25bc69bfdaf26" +checksum = "4f74a2c95f72e36fa6bd04a40d15623a9904bab1cc2fa6c6135b09d774a65088" dependencies = [ "sys_traits_macros", ] @@ -4222,11 +4251,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", - "serde_spanned", - "toml_datetime", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", "toml_edit", ] +[[package]] +name = "toml" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed0aee96c12fa71097902e0bb061a5e1ebd766a6636bb605ba401c45c1650eac" +dependencies = [ + "indexmap", + "serde", + "serde_spanned 1.0.0", + "toml_datetime 0.7.0", + "toml_parser", + "toml_writer", + "winnow", +] + [[package]] name = "toml_datetime" version = "0.6.11" @@ -4236,6 +4280,15 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3" +dependencies = [ + "serde", +] + [[package]] name = "toml_edit" version = "0.22.27" @@ -4244,18 +4297,33 @@ checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap", "serde", - "serde_spanned", - "toml_datetime", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", "toml_write", "winnow", ] +[[package]] +name = "toml_parser" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97200572db069e74c512a14117b296ba0a80a30123fbbb5aa1f4a348f639ca30" +dependencies = [ + "winnow", +] + [[package]] name = "toml_write" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +[[package]] +name = "toml_writer" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64" + [[package]] name = "tracing" version = "0.1.41" @@ -4328,9 +4396,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c9bf9513a2f4aeef5fdac8677d7d349c79fdbcc03b9c86da6e9d254f1e43be2" +checksum = "65af40ad689f2527aebbd37a0a816aea88ff5f774ceabe99de5be02f2f91dae2" dependencies = [ "glob", "serde", @@ -4338,7 +4406,7 @@ dependencies = [ "serde_json", "target-triple", "termcolor", - "toml", + "toml 0.9.2", ] [[package]] @@ -4430,6 +4498,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "323402cff2dd658f39ca17c789b502021b3f18707c91cdf22e3838e1b4023817" +[[package]] +name = "unty" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" + [[package]] name = "url" version = "2.5.4" @@ -4507,6 +4581,12 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "virtue" +version = "0.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1" + [[package]] name = "vsimd" version = "0.8.0" @@ -4852,7 +4932,7 @@ dependencies = [ name = "wgpu-benchmark" version = "26.0.0" dependencies = [ - "bincode", + "bincode 2.0.1", "bytemuck", "criterion", "naga", @@ -5147,7 +5227,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fabb953106c3c8eea8306e4393700d7657561cb43122571b172bbfb7c7ba1d" dependencies = [ "env_home", - "rustix 1.0.7", + "rustix 1.0.8", "winsafe", ] @@ -5747,9 +5827,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" +checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" dependencies = [ "memchr", ] @@ -5843,9 +5923,9 @@ checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" [[package]] name = "xml-rs" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62ce76d9b56901b19a74f19431b0d8b3bc7ca4ad685a746dfd78ca8f4fc6bda" +checksum = "6fd8403733700263c6eb89f192880191f1b83e332f7a20371ddcf421c4a337c7" [[package]] name = "xshell" diff --git a/Cargo.toml b/Cargo.toml index 444bb9aa72d..e8af139f6fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -95,7 +95,7 @@ approx = "0.5" arbitrary = "1.4" argh = "0.1.13" arrayvec = { version = "0.7.1", default-features = false } -bincode = "1" +bincode = "2" bit-set = { version = "0.8", default-features = false } bit-vec = { version = "0.8", default-features = false } bitflags = "2.9" @@ -103,7 +103,7 @@ bytemuck = { version = "1.22", features = [ "extern_crate_alloc", "min_const_generics", ] } -cargo_metadata = "0.20" +cargo_metadata = "0.21" cfg_aliases = "0.2.1" cfg-if = "1" criterion = "0.6" @@ -183,10 +183,10 @@ spirv = "0.3" static_assertions = "1.1" strum = { version = "0.27", default-features = false, features = ["derive"] } syn = "2.0.98" -toml = "0.8.9" +toml = "0.9.0" trybuild = "1" tracy-client = "0.18" -thiserror = { version = "2.0.3", default-features = false } +thiserror = { version = "2.0.11", default-features = false } unicode-ident = "1.0.5" walkdir = "2.3" winit = { version = "0.29", features = ["android-native-activity"] } diff --git a/benches/Cargo.toml b/benches/Cargo.toml index f0b70229adf..9af4cf4ae7d 100644 --- a/benches/Cargo.toml +++ b/benches/Cargo.toml @@ -26,7 +26,7 @@ unexpected_cfgs = { level = "warn", check-cfg = [ ] } [dependencies] -bincode.workspace = true +bincode = { workspace = true, features = ["serde"] } bytemuck.workspace = true criterion.workspace = true naga = { workspace = true, features = [ diff --git a/benches/benches/wgpu-benchmark/shader.rs b/benches/benches/wgpu-benchmark/shader.rs index d54c566faf5..b98cef01ae5 100644 --- a/benches/benches/wgpu-benchmark/shader.rs +++ b/benches/benches/wgpu-benchmark/shader.rs @@ -152,12 +152,22 @@ fn frontends(c: &mut Criterion) { let inputs_bin = inputs_wgsl .inner .iter() - .map(|input| bincode::serialize(&input.module.as_ref().unwrap()).unwrap()) + .map(|input| { + bincode::serde::encode_to_vec( + input.module.as_ref().unwrap(), + bincode::config::standard(), + ) + .unwrap() + }) .collect::>(); b.iter(move || { for input in inputs_bin.iter() { - bincode::deserialize::(input).unwrap(); + bincode::serde::decode_from_slice::( + input, + bincode::config::standard(), + ) + .unwrap(); } }); }); diff --git a/naga-cli/Cargo.toml b/naga-cli/Cargo.toml index 16e78631f0b..e1e708ddfad 100644 --- a/naga-cli/Cargo.toml +++ b/naga-cli/Cargo.toml @@ -41,7 +41,7 @@ naga = { workspace = true, features = [ "fs", ] } -bincode.workspace = true +bincode = { workspace = true, features = ["serde"] } codespan-reporting = { workspace = true, default-features = false, features = [ "std", "termcolor", diff --git a/naga-cli/src/bin/naga.rs b/naga-cli/src/bin/naga.rs index c32d52a8397..591ea0d9d7b 100644 --- a/naga-cli/src/bin/naga.rs +++ b/naga-cli/src/bin/naga.rs @@ -643,7 +643,7 @@ fn parse_input(input_path: &Path, input: Vec, params: &Parameters) -> anyhow Ok(match input_kind { InputKind::Bincode => Parsed { - module: bincode::deserialize(&input)?, + module: bincode::serde::decode_from_slice(&input, bincode::config::standard())?.0, input_text: None, language: naga::back::spv::SourceLanguage::Unknown, }, @@ -747,8 +747,8 @@ fn write_output( } } "bin" => { - let file = fs::File::create(output_path)?; - bincode::serialize_into(file, module)?; + let mut file = fs::File::create(output_path)?; + bincode::serde::encode_into_std_write(module, &mut file, bincode::config::standard())?; } "metal" => { use naga::back::msl; From 4ef4f5dfbe35c8693847f57f7e1873f1b79308f3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 10 Jul 2025 22:24:39 +0000 Subject: [PATCH 039/303] chore(deps): update dependency ubuntu to v24 --- .github/workflows/ci.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 87ec20dbc4c..8c3a0881cfb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -122,60 +122,60 @@ jobs: # Linux - name: Linux x86_64 - os: ubuntu-22.04 + os: ubuntu-24.04 target: x86_64-unknown-linux-gnu tier: 1 kind: native - name: Linux aarch64 - os: ubuntu-22.04 + os: ubuntu-24.04 target: aarch64-unknown-linux-gnu tier: 1 kind: native # Android - name: Android aarch64 - os: ubuntu-22.04 + os: ubuntu-24.04 target: aarch64-linux-android tier: 2 kind: native # Android - name: Android ARMv7 - os: ubuntu-22.04 + os: ubuntu-24.04 target: armv7-linux-androideabi tier: 2 kind: wgpu-only # Android - name: Android x86_64 - os: ubuntu-22.04 + os: ubuntu-24.04 target: x86_64-linux-android tier: 2 kind: wgpu-only # OpenHarmony - name: OpenHarmony aarch64 - os: ubuntu-22.04 + os: ubuntu-24.04 target: aarch64-unknown-linux-ohos tier: 2 kind: native # WebGPU/WebGL - name: WebAssembly - os: ubuntu-22.04 + os: ubuntu-24.04 target: wasm32-unknown-unknown tier: 2 kind: web - name: Emscripten - os: ubuntu-22.04 + os: ubuntu-24.04 target: wasm32-unknown-emscripten tier: 2 kind: wgpu-only - name: WebAssembly Core 1.0 - os: ubuntu-22.04 + os: ubuntu-24.04 target: wasm32v1-none tier: 2 kind: no_std @@ -183,7 +183,7 @@ jobs: # 32-bit PowerPC Linux # Included to test support for `portable-atomic` - name: Linux ppc32 - os: ubuntu-22.04 + os: ubuntu-24.04 target: powerpc-unknown-linux-gnu tier: 2 kind: wgpu-only @@ -364,7 +364,7 @@ jobs: # Linux - name: Linux x86_64 - os: ubuntu-22.04 + os: ubuntu-24.04 target: x86_64-unknown-linux-gnu name: MSRV Check ${{ matrix.name }} @@ -419,7 +419,7 @@ jobs: timeout-minutes: 10 name: MSRV Minimal Versions - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 env: # Override flags to NOT include `-D warnings`, because warnings may be due to harmless problems in deps. # Also, allow unexpected_cfgs because it is very common and spammy when using old deps. From d2f8c44ac669324f4324adabfda186b2a6192ac3 Mon Sep 17 00:00:00 2001 From: Teodor Tanasoaia <28601907+teoxoy@users.noreply.github.com> Date: Fri, 18 Jul 2025 19:04:46 +0200 Subject: [PATCH 040/303] [wgpu-core] remove implicit PL & BGL IDs from pipeline creation (#7967) --- deno_webgpu/device.rs | 4 +- player/src/lib.rs | 32 ++------- wgpu-core/src/device/global.rs | 114 +-------------------------------- wgpu-core/src/device/mod.rs | 27 -------- wgpu-core/src/device/trace.rs | 4 -- wgpu-core/src/pipeline.rs | 8 +-- wgpu-core/src/registry.rs | 7 +- wgpu/src/backend/wgpu_core.rs | 16 ++--- 8 files changed, 18 insertions(+), 194 deletions(-) diff --git a/deno_webgpu/device.rs b/deno_webgpu/device.rs index 211cdc513d0..7a124824617 100644 --- a/deno_webgpu/device.rs +++ b/deno_webgpu/device.rs @@ -651,7 +651,7 @@ impl GPUDevice { let (id, err) = self.instance - .device_create_compute_pipeline(self.id, &wgpu_descriptor, None, None); + .device_create_compute_pipeline(self.id, &wgpu_descriptor, None); self.error_handler.push_error(err); @@ -818,7 +818,7 @@ impl GPUDevice { let (id, err) = self.instance - .device_create_render_pipeline(self.id, &wgpu_descriptor, None, None); + .device_create_render_pipeline(self.id, &wgpu_descriptor, None); self.error_handler.push_error(err); diff --git a/player/src/lib.rs b/player/src/lib.rs index 90f3fd8823c..4b805e9d478 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -298,20 +298,8 @@ impl GlobalPlay for wgc::global::Global { Action::DestroyShaderModule(id) => { self.shader_module_drop(id); } - Action::CreateComputePipeline { - id, - desc, - implicit_context, - } => { - let implicit_ids = - implicit_context - .as_ref() - .map(|ic| wgc::device::ImplicitPipelineIds { - root_id: ic.root_id, - group_ids: &ic.group_ids, - }); - let (_, error) = - self.device_create_compute_pipeline(device, &desc, Some(id), implicit_ids); + Action::CreateComputePipeline { id, desc } => { + let (_, error) = self.device_create_compute_pipeline(device, &desc, Some(id)); if let Some(e) = error { panic!("{e}"); } @@ -319,20 +307,8 @@ impl GlobalPlay for wgc::global::Global { Action::DestroyComputePipeline(id) => { self.compute_pipeline_drop(id); } - Action::CreateRenderPipeline { - id, - desc, - implicit_context, - } => { - let implicit_ids = - implicit_context - .as_ref() - .map(|ic| wgc::device::ImplicitPipelineIds { - root_id: ic.root_id, - group_ids: &ic.group_ids, - }); - let (_, error) = - self.device_create_render_pipeline(device, &desc, Some(id), implicit_ids); + Action::CreateRenderPipeline { id, desc } => { + let (_, error) = self.device_create_render_pipeline(device, &desc, Some(id)); if let Some(e) = error { panic!("{e}"); } diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index 92d0ea54bb5..0fc9da4aa0e 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -30,7 +30,7 @@ use crate::{ use wgt::{BufferAddress, TextureFormat}; -use super::{ImplicitPipelineIds, UserClosures}; +use super::UserClosures; impl Global { pub fn adapter_is_surface_supported( @@ -1228,7 +1228,6 @@ impl Global { device_id: DeviceId, desc: &pipeline::RenderPipelineDescriptor, id_in: Option, - implicit_pipeline_ids: Option>, ) -> ( id::RenderPipelineId, Option, @@ -1237,18 +1236,9 @@ impl Global { let hub = &self.hub; - let missing_implicit_pipeline_ids = - desc.layout.is_none() && id_in.is_some() && implicit_pipeline_ids.is_none(); - let fid = hub.render_pipelines.prepare(id_in); - let implicit_context = implicit_pipeline_ids.map(|ipi| ipi.prepare(hub)); let error = 'error: { - if missing_implicit_pipeline_ids { - // TODO: categorize this error as API misuse - break 'error pipeline::ImplicitLayoutError::MissingImplicitPipelineIds.into(); - } - let device = self.hub.devices.get(device_id); #[cfg(feature = "trace")] @@ -1256,7 +1246,6 @@ impl Global { trace.add(trace::Action::CreateRenderPipeline { id: fid.id(), desc: desc.clone(), - implicit_context: implicit_context.clone(), }); } @@ -1357,40 +1346,6 @@ impl Global { Err(e) => break 'error e, }; - if let Some(ids) = implicit_context.as_ref() { - let group_count = pipeline.layout.bind_group_layouts.len(); - if ids.group_ids.len() < group_count { - log::error!( - "Not enough bind group IDs ({}) specified for the implicit layout ({})", - ids.group_ids.len(), - group_count - ); - // TODO: categorize this error as API misuse - break 'error pipeline::ImplicitLayoutError::MissingIds(group_count as _) - .into(); - } - - let mut pipeline_layout_guard = hub.pipeline_layouts.write(); - let mut bgl_guard = hub.bind_group_layouts.write(); - pipeline_layout_guard.insert(ids.root_id, Fallible::Valid(pipeline.layout.clone())); - let mut group_ids = ids.group_ids.iter(); - // NOTE: If the first iterator is longer than the second, the `.zip()` impl will still advance the - // the first iterator before realizing that the second iterator has finished. - // The `pipeline.layout.bind_group_layouts` iterator will always be shorter than `ids.group_ids`, - // so using it as the first iterator for `.zip()` will work properly. - for (bgl, bgl_id) in pipeline - .layout - .bind_group_layouts - .iter() - .zip(&mut group_ids) - { - bgl_guard.insert(*bgl_id, Fallible::Valid(bgl.clone())); - } - for bgl_id in group_ids { - bgl_guard.insert(*bgl_id, Fallible::Invalid(Arc::new(String::new()))); - } - } - let id = fid.assign(Fallible::Valid(pipeline)); api_log!("Device::create_render_pipeline -> {id:?}"); @@ -1399,17 +1354,6 @@ impl Global { let id = fid.assign(Fallible::Invalid(Arc::new(desc.label.to_string()))); - // We also need to assign errors to the implicit pipeline layout and the - // implicit bind group layouts. - if let Some(ids) = implicit_context { - let mut pipeline_layout_guard = hub.pipeline_layouts.write(); - let mut bgl_guard = hub.bind_group_layouts.write(); - pipeline_layout_guard.insert(ids.root_id, Fallible::Invalid(Arc::new(String::new()))); - for bgl_id in ids.group_ids { - bgl_guard.insert(bgl_id, Fallible::Invalid(Arc::new(String::new()))); - } - } - (id, Some(error)) } @@ -1467,7 +1411,6 @@ impl Global { device_id: DeviceId, desc: &pipeline::ComputePipelineDescriptor, id_in: Option, - implicit_pipeline_ids: Option>, ) -> ( id::ComputePipelineId, Option, @@ -1476,18 +1419,9 @@ impl Global { let hub = &self.hub; - let missing_implicit_pipeline_ids = - desc.layout.is_none() && id_in.is_some() && implicit_pipeline_ids.is_none(); - let fid = hub.compute_pipelines.prepare(id_in); - let implicit_context = implicit_pipeline_ids.map(|ipi| ipi.prepare(hub)); let error = 'error: { - if missing_implicit_pipeline_ids { - // TODO: categorize this error as API misuse - break 'error pipeline::ImplicitLayoutError::MissingImplicitPipelineIds.into(); - } - let device = self.hub.devices.get(device_id); #[cfg(feature = "trace")] @@ -1495,7 +1429,6 @@ impl Global { trace.add(trace::Action::CreateComputePipeline { id: fid.id(), desc: desc.clone(), - implicit_context: implicit_context.clone(), }); } @@ -1545,40 +1478,6 @@ impl Global { Err(e) => break 'error e, }; - if let Some(ids) = implicit_context.as_ref() { - let group_count = pipeline.layout.bind_group_layouts.len(); - if ids.group_ids.len() < group_count { - log::error!( - "Not enough bind group IDs ({}) specified for the implicit layout ({})", - ids.group_ids.len(), - group_count - ); - // TODO: categorize this error as API misuse - break 'error pipeline::ImplicitLayoutError::MissingIds(group_count as _) - .into(); - } - - let mut pipeline_layout_guard = hub.pipeline_layouts.write(); - let mut bgl_guard = hub.bind_group_layouts.write(); - pipeline_layout_guard.insert(ids.root_id, Fallible::Valid(pipeline.layout.clone())); - let mut group_ids = ids.group_ids.iter(); - // NOTE: If the first iterator is longer than the second, the `.zip()` impl will still advance the - // the first iterator before realizing that the second iterator has finished. - // The `pipeline.layout.bind_group_layouts` iterator will always be shorter than `ids.group_ids`, - // so using it as the first iterator for `.zip()` will work properly. - for (bgl, bgl_id) in pipeline - .layout - .bind_group_layouts - .iter() - .zip(&mut group_ids) - { - bgl_guard.insert(*bgl_id, Fallible::Valid(bgl.clone())); - } - for bgl_id in group_ids { - bgl_guard.insert(*bgl_id, Fallible::Invalid(Arc::new(String::new()))); - } - } - let id = fid.assign(Fallible::Valid(pipeline)); api_log!("Device::create_compute_pipeline -> {id:?}"); @@ -1587,17 +1486,6 @@ impl Global { let id = fid.assign(Fallible::Invalid(Arc::new(desc.label.to_string()))); - // We also need to assign errors to the implicit pipeline layout and the - // implicit bind group layouts. - if let Some(ids) = implicit_context { - let mut pipeline_layout_guard = hub.pipeline_layouts.write(); - let mut bgl_guard = hub.bind_group_layouts.write(); - pipeline_layout_guard.insert(ids.root_id, Fallible::Invalid(Arc::new(String::new()))); - for bgl_id in ids.group_ids { - bgl_guard.insert(bgl_id, Fallible::Invalid(Arc::new(String::new()))); - } - } - (id, Some(error)) } diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 2a1c7febd5f..ad60e106d62 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -3,8 +3,6 @@ use core::{fmt, num::NonZeroU32}; use crate::{ binding_model, - hub::Hub, - id::{BindGroupLayoutId, PipelineLayoutId}, ray_tracing::BlasCompactReadyPendingClosure, resource::{ Buffer, BufferAccessError, BufferAccessResult, BufferMapOperation, Labeled, @@ -385,31 +383,6 @@ impl WebGpuError for MissingDownlevelFlags { } } -#[derive(Clone, Debug)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct ImplicitPipelineContext { - pub root_id: PipelineLayoutId, - pub group_ids: ArrayVec, -} - -pub struct ImplicitPipelineIds<'a> { - pub root_id: PipelineLayoutId, - pub group_ids: &'a [BindGroupLayoutId], -} - -impl ImplicitPipelineIds<'_> { - fn prepare(self, hub: &Hub) -> ImplicitPipelineContext { - ImplicitPipelineContext { - root_id: hub.pipeline_layouts.prepare(Some(self.root_id)).id(), - group_ids: self - .group_ids - .iter() - .map(|id_in| hub.bind_group_layouts.prepare(Some(*id_in)).id()) - .collect(), - } - } -} - /// Create a validator with the given validation flags. pub fn create_validator( features: wgt::Features, diff --git a/wgpu-core/src/device/trace.rs b/wgpu-core/src/device/trace.rs index 33025818f4b..220a2406df5 100644 --- a/wgpu-core/src/device/trace.rs +++ b/wgpu-core/src/device/trace.rs @@ -90,15 +90,11 @@ pub enum Action<'a> { CreateComputePipeline { id: id::ComputePipelineId, desc: crate::pipeline::ComputePipelineDescriptor<'a>, - #[cfg_attr(feature = "replay", serde(default))] - implicit_context: Option, }, DestroyComputePipeline(id::ComputePipelineId), CreateRenderPipeline { id: id::RenderPipelineId, desc: crate::pipeline::RenderPipelineDescriptor<'a>, - #[cfg_attr(feature = "replay", serde(default))] - implicit_context: Option, }, DestroyRenderPipeline(id::RenderPipelineId), CreatePipelineCache { diff --git a/wgpu-core/src/pipeline.rs b/wgpu-core/src/pipeline.rs index cdc88f9f3a2..7d055b7052b 100644 --- a/wgpu-core/src/pipeline.rs +++ b/wgpu-core/src/pipeline.rs @@ -190,10 +190,6 @@ pub type ImplicitBindGroupCount = u8; #[derive(Clone, Debug, Error)] #[non_exhaustive] pub enum ImplicitLayoutError { - #[error("The implicit_pipeline_ids arg is required")] - MissingImplicitPipelineIds, - #[error("Missing IDs for deriving {0} bind groups")] - MissingIds(ImplicitBindGroupCount), #[error("Unable to reflect the shader {0:?} interface")] ReflectionError(wgt::ShaderStages), #[error(transparent)] @@ -205,9 +201,7 @@ pub enum ImplicitLayoutError { impl WebGpuError for ImplicitLayoutError { fn webgpu_error_type(&self) -> ErrorType { let e: &dyn WebGpuError = match self { - Self::MissingImplicitPipelineIds | Self::MissingIds(_) | Self::ReflectionError(_) => { - return ErrorType::Validation - } + Self::ReflectionError(_) => return ErrorType::Validation, Self::BindGroup(e) => e, Self::Pipeline(e) => e, }; diff --git a/wgpu-core/src/registry.rs b/wgpu-core/src/registry.rs index 81b0b54ab77..3ff81dc73e5 100644 --- a/wgpu-core/src/registry.rs +++ b/wgpu-core/src/registry.rs @@ -3,7 +3,7 @@ use alloc::sync::Arc; use crate::{ id::Id, identity::IdentityManager, - lock::{rank, RwLock, RwLockReadGuard, RwLockWriteGuard}, + lock::{rank, RwLock, RwLockReadGuard}, storage::{Element, Storage, StorageItem}, }; @@ -55,6 +55,7 @@ pub(crate) struct FutureId<'a, T: StorageItem> { } impl FutureId<'_, T> { + #[cfg(feature = "trace")] pub fn id(&self) -> Id { self.id } @@ -87,10 +88,6 @@ impl Registry { pub(crate) fn read<'a>(&'a self) -> RwLockReadGuard<'a, Storage> { self.storage.read() } - #[track_caller] - pub(crate) fn write<'a>(&'a self) -> RwLockWriteGuard<'a, Storage> { - self.storage.write() - } pub(crate) fn remove(&self, id: Id) -> T { let value = self.storage.write().remove(id); // This needs to happen *after* removing it from the storage, to maintain the diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index 15fb57a45a0..85c904af1a8 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -1321,10 +1321,10 @@ impl dispatch::DeviceInterface for CoreDevice { cache: desc.cache.map(|cache| cache.inner.as_core().id), }; - let (id, error) = - self.context - .0 - .device_create_render_pipeline(self.id, &descriptor, None, None); + let (id, error) = self + .context + .0 + .device_create_render_pipeline(self.id, &descriptor, None); if let Some(cause) = error { if let wgc::pipeline::CreateRenderPipelineError::Internal { stage, ref error } = cause { log::error!("Shader translation error for stage {stage:?}: {error}"); @@ -1372,10 +1372,10 @@ impl dispatch::DeviceInterface for CoreDevice { cache: desc.cache.map(|cache| cache.inner.as_core().id), }; - let (id, error) = - self.context - .0 - .device_create_compute_pipeline(self.id, &descriptor, None, None); + let (id, error) = self + .context + .0 + .device_create_compute_pipeline(self.id, &descriptor, None); if let Some(cause) = error { if let wgc::pipeline::CreateComputePipelineError::Internal(ref error) = cause { log::error!( From 96ef5ecaa449ee11af51c9469ec40f98452834a1 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Fri, 18 Jul 2025 16:21:15 -0400 Subject: [PATCH 041/303] ci: reduce log spam on wasm (#7966) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c3a0881cfb..ac088cd6008 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,7 @@ env: CARGO_INCREMENTAL: false CARGO_TERM_COLOR: always WGPU_DX12_COMPILER: dxc - RUST_LOG: debug + RUST_LOG: debug,wasm_bindgen_wasm_interpreter=warn,wasm_bindgen_cli_support=warn,walrus=warn RUST_BACKTRACE: full PKG_CONFIG_ALLOW_CROSS: 1 # allow android to work RUSTFLAGS: -D warnings From 712ab8dec2b1c8c6caa2224c561867097bd132f4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 20 Jul 2025 22:48:01 -0400 Subject: [PATCH 042/303] chore(deps): update cts digest to 7bdef02 (#7975) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- cts_runner/revision.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cts_runner/revision.txt b/cts_runner/revision.txt index c89d0b9012a..a80cc61d951 100644 --- a/cts_runner/revision.txt +++ b/cts_runner/revision.txt @@ -1 +1 @@ -6e9d87b9465e74a1d52e954d396a3109100e19a9 +7bdef028de174c1d236d8531f574194a12a4f1f6 From c95b7feea8f0705a38c7f202b59e9ef91968ae42 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 21 Jul 2025 02:50:42 +0000 Subject: [PATCH 043/303] chore(deps): update cargo.lock --- Cargo.lock | 58 ++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c712af7b1de..8a67c3562eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ab_glyph" -version = "0.2.30" +version = "0.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0f4f6fbdc5ee39f2ede9f5f3ec79477271a6d6a2baff22310d51736bda6cea" +checksum = "e074464580a518d16a7126262fffaaa47af89d4099d4cb403f8ed938ba12ee7d" dependencies = [ "ab_glyph_rasterizer", "owned_ttf_parser", @@ -493,9 +493,9 @@ dependencies = [ [[package]] name = "bytemuck_derive" -version = "1.9.3" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1" +checksum = "441473f2b4b0459a68628c744bc61d23e730fb00128b841d30fa4bb3972257e4" dependencies = [ "proc-macro2", "quote", @@ -652,9 +652,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.29" +version = "1.2.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362" +checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7" dependencies = [ "jobserver", "libc", @@ -852,9 +852,9 @@ dependencies = [ [[package]] name = "const_panic" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2459fc9262a1aa204eb4b5764ad4f189caec88aea9634389c0a25f8be7f6265e" +checksum = "b98d1483e98c9d67f341ab4b3915cfdc54740bd6f5cccc9226ee0535d86aa8fb" [[package]] name = "cooked-waker" @@ -2304,13 +2304,13 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638" +checksum = "4488594b9328dee448adb906d8b126d9b7deb7cf5c22161ee591610bb1be83c0" dependencies = [ "bitflags 2.9.1", "libc", - "redox_syscall 0.5.13", + "redox_syscall 0.5.14", ] [[package]] @@ -2526,7 +2526,7 @@ dependencies = [ "rustc-hash", "serde", "spirv", - "strum 0.27.1", + "strum 0.27.2", "thiserror 2.0.12", "toml 0.9.2", "unicode-ident", @@ -3110,7 +3110,7 @@ dependencies = [ "cfg-if", "libc", "petgraph 0.6.5", - "redox_syscall 0.5.13", + "redox_syscall 0.5.14", "smallvec", "thread-id", "windows-targets 0.52.6", @@ -3250,17 +3250,16 @@ dependencies = [ [[package]] name = "polling" -version = "3.8.0" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b53a684391ad002dd6a596ceb6c74fd004fdce75f4be2e3f615068abbea5fd50" +checksum = "8ee9b2fa7a4517d2c91ff5bc6c297a427a96749d15f98fcdbb22c05571a4d4b7" dependencies = [ "cfg-if", "concurrent-queue", "hermit-abi", "pin-project-lite", "rustix 1.0.8", - "tracing", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -3491,9 +3490,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" +checksum = "de3a5d9f0aba1dbcec1cc47f0ff94a4b778fe55bca98a6dfa92e4e094e57b1c4" dependencies = [ "bitflags 2.9.1", ] @@ -3756,9 +3755,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.140" +version = "1.0.141" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3" dependencies = [ "indexmap", "itoa", @@ -4013,11 +4012,11 @@ dependencies = [ [[package]] name = "strum" -version = "0.27.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" dependencies = [ - "strum_macros 0.27.1", + "strum_macros 0.27.2", ] [[package]] @@ -4035,14 +4034,13 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.27.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "rustversion", "syn", ] @@ -4386,9 +4384,9 @@ dependencies = [ [[package]] name = "tracy-client-sys" -version = "0.26.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9612d9503675b07b244922ea6f6f3cdd88c43add1b3498084613fc88cdf69d" +checksum = "319c70195101a93f56db4c74733e272d720768e13471f400c78406a326b172b0" dependencies = [ "cc", "windows-targets 0.52.6", @@ -5171,7 +5169,7 @@ dependencies = [ "profiling", "serde", "serde_json", - "strum 0.27.1", + "strum 0.27.2", "trybuild", "wasm-bindgen", "wasm-bindgen-futures", From 979487024e7ba3df64fc7071fbe57eb4f38e4712 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Mon, 21 Jul 2025 07:48:37 -0400 Subject: [PATCH 044/303] hal/vulkan: generate separate hash identity for Texture/TextureViews (#7972) --- wgpu-hal/src/vulkan/adapter.rs | 3 + wgpu-hal/src/vulkan/command.rs | 25 +++++--- wgpu-hal/src/vulkan/device.rs | 14 +++++ wgpu-hal/src/vulkan/instance.rs | 3 + wgpu-hal/src/vulkan/mod.rs | 106 +++++++++++++++++++++++++++++++- 5 files changed, 139 insertions(+), 12 deletions(-) diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 24f0bfa9199..a06616c6133 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -2162,6 +2162,9 @@ impl super::Adapter { self.private_caps.maximum_samplers, )), memory_allocations_counter: Default::default(), + + texture_identity_factory: super::ResourceIdentityFactory::new(), + texture_view_identity_factory: super::ResourceIdentityFactory::new(), }); let relay_semaphores = super::RelaySemaphores::new(&shared)?; diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index c31192b23b6..65ee0daa994 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -61,7 +61,8 @@ impl super::CommandEncoder { Entry::Vacant(e) => { let super::FramebufferKey { raw_pass, - ref attachments, + ref attachment_views, + attachment_identities: _, extent, } = *e.key(); @@ -70,7 +71,7 @@ impl super::CommandEncoder { .width(extent.width) .height(extent.height) .layers(extent.depth_or_array_layers) - .attachments(attachments); + .attachments(attachment_views); let raw = unsafe { self.device.raw.create_framebuffer(&vk_info, None).unwrap() }; *e.insert(raw) @@ -81,12 +82,13 @@ impl super::CommandEncoder { fn make_temp_texture_view( &mut self, key: super::TempTextureViewKey, - ) -> Result { + ) -> Result { Ok(match self.temp_texture_views.entry(key) { Entry::Occupied(e) => *e.get(), Entry::Vacant(e) => { let super::TempTextureViewKey { texture, + texture_identity: _, format, mip_level, depth_slice, @@ -105,7 +107,10 @@ impl super::CommandEncoder { }); let raw = unsafe { self.device.raw.create_image_view(&vk_info, None) } .map_err(super::map_host_device_oom_and_ioca_err)?; - *e.insert(raw) + + let identity = self.device.texture_view_identity_factory.next(); + + *e.insert(super::IdentifiedTextureView { raw, identity }) } }) } @@ -779,7 +784,8 @@ impl crate::CommandEncoder for super::CommandEncoder { }; let mut fb_key = super::FramebufferKey { raw_pass: vk::RenderPass::null(), - attachments: ArrayVec::default(), + attachment_views: ArrayVec::default(), + attachment_identities: ArrayVec::default(), extent: desc.extent, }; @@ -788,13 +794,14 @@ impl crate::CommandEncoder for super::CommandEncoder { let color_view = if cat.target.view.dimension == wgt::TextureViewDimension::D3 { let key = super::TempTextureViewKey { texture: cat.target.view.raw_texture, + texture_identity: cat.target.view.texture_identity, format: cat.target.view.raw_format, mip_level: cat.target.view.base_mip_level, depth_slice: cat.depth_slice.unwrap(), }; self.make_temp_texture_view(key)? } else { - cat.target.view.raw + cat.target.view.identified_raw_view() }; vk_clear_values.push(vk::ClearValue { @@ -809,10 +816,10 @@ impl crate::CommandEncoder for super::CommandEncoder { }; rp_key.colors.push(Some(color)); - fb_key.attachments.push(color_view); + fb_key.push_view(color_view); if let Some(ref at) = cat.resolve_target { vk_clear_values.push(unsafe { mem::zeroed() }); - fb_key.attachments.push(at.view.raw); + fb_key.push_view(at.view.identified_raw_view()); } // Assert this attachment is valid for the detected multiview, as a sanity check @@ -838,7 +845,7 @@ impl crate::CommandEncoder for super::CommandEncoder { base: ds.target.make_attachment_key(ds.depth_ops), stencil_ops: ds.stencil_ops, }); - fb_key.attachments.push(ds.target.view.raw); + fb_key.push_view(ds.target.view.identified_raw_view()); // Assert this attachment is valid for the detected multiview, as a sanity check // The driver crash for this is really bad on AMD, so the check is worth it diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index e760c49462b..b1cbfd84102 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -603,6 +603,7 @@ impl super::Device { /// `drop_callback` is [`Some`], `vk_image` must be valid until the callback is called. /// - If the `ImageCreateFlags` does not contain `MUTABLE_FORMAT`, the `view_formats` of `desc` must be empty. pub unsafe fn texture_from_raw( + &self, vk_image: vk::Image, desc: &crate::TextureDescriptor, drop_callback: Option, @@ -624,6 +625,8 @@ impl super::Device { raw_flags |= vk::ImageCreateFlags::MUTABLE_FORMAT; } + let identity = self.shared.texture_identity_factory.next(); + let drop_guard = crate::DropGuard::from_option(drop_callback); super::Texture { @@ -633,6 +636,7 @@ impl super::Device { block: None, format: desc.format, copy_size: desc.copy_extent(), + identity, } } @@ -796,6 +800,8 @@ impl super::Device { unsafe { self.shared.set_object_name(image.raw, label) }; } + let identity = self.shared.texture_identity_factory.next(); + self.counters.textures.add(1); Ok(super::Texture { @@ -805,6 +811,7 @@ impl super::Device { block: None, format: desc.format, copy_size: image.copy_size, + identity, }) } @@ -1274,6 +1281,8 @@ impl crate::Device for super::Device { unsafe { self.shared.set_object_name(image.raw, label) }; } + let identity = self.shared.texture_identity_factory.next(); + self.counters.textures.add(1); Ok(super::Texture { @@ -1283,6 +1292,7 @@ impl crate::Device for super::Device { block: Some(block), format: desc.format, copy_size: image.copy_size, + identity, }) } unsafe fn destroy_texture(&self, texture: super::Texture) { @@ -1335,6 +1345,8 @@ impl crate::Device for super::Device { unsafe { self.shared.set_object_name(raw, label) }; } + let identity = self.shared.texture_view_identity_factory.next(); + self.counters.texture_views.add(1); Ok(super::TextureView { @@ -1345,6 +1357,8 @@ impl crate::Device for super::Device { raw_format, base_mip_level: desc.range.base_mip_level, dimension: desc.dimension, + texture_identity: texture.identity, + view_identity: identity, }) } unsafe fn destroy_texture_view(&self, view: super::TextureView) { diff --git a/wgpu-hal/src/vulkan/instance.rs b/wgpu-hal/src/vulkan/instance.rs index ddccc5c3b30..d7d7183330d 100644 --- a/wgpu-hal/src/vulkan/instance.rs +++ b/wgpu-hal/src/vulkan/instance.rs @@ -1139,6 +1139,8 @@ impl crate::Surface for super::Surface { return Err(crate::SurfaceError::Outdated); } + let identity = swapchain.device.texture_identity_factory.next(); + let texture = super::SurfaceTexture { index, texture: super::Texture { @@ -1152,6 +1154,7 @@ impl crate::Surface for super::Surface { height: swapchain.config.extent.height, depth: 1, }, + identity, }, surface_semaphores: swapchain_semaphores_arc, }; diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 507af4c2596..a6bdff90d19 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -651,6 +651,14 @@ struct DeviceShared { render_passes: Mutex>, sampler_cache: Mutex, memory_allocations_counter: InternalCounter, + + /// Because we have cached framebuffers which are not deleted from until + /// the device is destroyed, if the implementation of vulkan re-uses handles + /// we need some way to differentiate between the old handle and the new handle. + /// This factory allows us to have a dedicated identity value for each texture. + texture_identity_factory: ResourceIdentityFactory, + /// As above, for texture views. + texture_view_identity_factory: ResourceIdentityFactory, } impl Drop for DeviceShared { @@ -864,6 +872,7 @@ pub struct Texture { block: Option>, format: wgt::TextureFormat, copy_size: crate::CopyExtent, + identity: ResourceIdentity, } impl crate::DynTexture for Texture {} @@ -886,6 +895,8 @@ pub struct TextureView { raw_format: vk::Format, base_mip_level: u32, dimension: wgt::TextureViewDimension, + texture_identity: ResourceIdentity, + view_identity: ResourceIdentity, } impl crate::DynTextureView for TextureView {} @@ -897,6 +908,14 @@ impl TextureView { pub unsafe fn raw_handle(&self) -> vk::ImageView { self.raw } + + /// Returns the raw texture view, along with its identity. + fn identified_raw_view(&self) -> IdentifiedTextureView { + IdentifiedTextureView { + raw: self.raw, + identity: self.view_identity, + } + } } #[derive(Debug)] @@ -956,16 +975,97 @@ impl Temp { } } +/// Generates unique IDs for each resource of type `T`. +/// +/// Because vk handles are not permanently unique, this +/// provides a way to generate unique IDs for each resource. +struct ResourceIdentityFactory { + #[cfg(not(target_has_atomic = "64"))] + next_id: Mutex, + #[cfg(target_has_atomic = "64")] + next_id: core::sync::atomic::AtomicU64, + _phantom: PhantomData, +} + +impl ResourceIdentityFactory { + fn new() -> Self { + Self { + #[cfg(not(target_has_atomic = "64"))] + next_id: Mutex::new(0), + #[cfg(target_has_atomic = "64")] + next_id: core::sync::atomic::AtomicU64::new(0), + _phantom: PhantomData, + } + } + + /// Returns a new unique ID for a resource of type `T`. + fn next(&self) -> ResourceIdentity { + #[cfg(not(target_has_atomic = "64"))] + { + let mut next_id = self.next_id.lock(); + let id = *next_id; + *next_id += 1; + ResourceIdentity { + id, + _phantom: PhantomData, + } + } + + #[cfg(target_has_atomic = "64")] + ResourceIdentity { + id: self + .next_id + .fetch_add(1, core::sync::atomic::Ordering::Relaxed), + _phantom: PhantomData, + } + } +} + +/// A unique identifier for a resource of type `T`. +/// +/// This is used as a hashable key for resources, which +/// is permanently unique through the lifetime of the program. +#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)] +struct ResourceIdentity { + id: u64, + _phantom: PhantomData, +} + #[derive(Clone, Eq, Hash, PartialEq)] struct FramebufferKey { raw_pass: vk::RenderPass, - attachments: ArrayVec, + /// Because this is used as a key in a hash map, we need to include the identity + /// so that this hashes differently, even if the ImageView handles are the same + /// between different views. + attachment_identities: ArrayVec, { MAX_TOTAL_ATTACHMENTS }>, + /// While this is redundant for calculating the hash, we need access to an array + /// of all the raw ImageViews when we are creating the actual framebuffer, + /// so we store this here. + attachment_views: ArrayVec, extent: wgt::Extent3d, } +impl FramebufferKey { + fn push_view(&mut self, view: IdentifiedTextureView) { + self.attachment_identities.push(view.identity); + self.attachment_views.push(view.raw); + } +} + +/// A texture view paired with its identity. +#[derive(Copy, Clone)] +struct IdentifiedTextureView { + raw: vk::ImageView, + identity: ResourceIdentity, +} + #[derive(Clone, Eq, Hash, PartialEq)] struct TempTextureViewKey { texture: vk::Image, + /// As this is used in a hashmap, we need to + /// include the identity so that this hashes differently, + /// even if the Image handles are the same between different images. + texture_identity: ResourceIdentity, format: vk::Format, mip_level: u32, depth_slice: u32, @@ -1008,7 +1108,7 @@ pub struct CommandEncoder { end_of_pass_timer_query: Option<(vk::QueryPool, u32)>, framebuffers: FastHashMap, - temp_texture_views: FastHashMap, + temp_texture_views: FastHashMap, counters: Arc, } @@ -1037,7 +1137,7 @@ impl Drop for CommandEncoder { } for (_, view) in self.temp_texture_views.drain() { - unsafe { self.device.raw.destroy_image_view(view, None) }; + unsafe { self.device.raw.destroy_image_view(view.raw, None) }; } self.counters.command_encoders.sub(1); From 2c81896e85620c4dcfd175eac9b088e25a0776cc Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Mon, 21 Jul 2025 04:51:57 -0700 Subject: [PATCH 045/303] Small changes to facilitate fuzzing (#7970) --- wgpu-core/src/command/bundle.rs | 14 +++++++++----- wgpu-core/src/id.rs | 28 ++++++++++++++++++++++------ wgpu-core/src/storage.rs | 6 +++++- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index 5044928b7b4..09f522f0013 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -435,16 +435,20 @@ impl RenderBundleEncoder { .map_pass_err(scope)?; } RenderCommand::DrawIndirect { .. } - | RenderCommand::MultiDrawIndirectCount { .. } => unimplemented!(), - RenderCommand::PushDebugGroup { color: _, len: _ } => unimplemented!(), - RenderCommand::InsertDebugMarker { color: _, len: _ } => unimplemented!(), - RenderCommand::PopDebugGroup => unimplemented!(), + | RenderCommand::MultiDrawIndirectCount { .. } + | RenderCommand::PushDebugGroup { color: _, len: _ } + | RenderCommand::InsertDebugMarker { color: _, len: _ } + | RenderCommand::PopDebugGroup => { + unimplemented!("not supported by a render bundle") + } // Must check the TIMESTAMP_QUERY_INSIDE_PASSES feature RenderCommand::WriteTimestamp { .. } | RenderCommand::BeginOcclusionQuery { .. } | RenderCommand::EndOcclusionQuery | RenderCommand::BeginPipelineStatisticsQuery { .. } - | RenderCommand::EndPipelineStatisticsQuery => unimplemented!(), + | RenderCommand::EndPipelineStatisticsQuery => { + unimplemented!("not supported by a render bundle") + } RenderCommand::ExecuteBundle(_) | RenderCommand::SetBlendConstant(_) | RenderCommand::SetStencilReference(_) diff --git a/wgpu-core/src/id.rs b/wgpu-core/src/id.rs index cac9c134811..79df7da7472 100644 --- a/wgpu-core/src/id.rs +++ b/wgpu-core/src/id.rs @@ -34,16 +34,20 @@ const _: () = { #[cfg_attr( any(feature = "serde", feature = "replay"), derive(serde::Deserialize), - serde(from = "SerialId") + serde(try_from = "SerialId") )] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct RawId(NonZeroU64); impl RawId { /// Zip together an identifier and return its raw underlying representation. + /// + /// # Panics + /// + /// If both ID components are zero. pub fn zip(index: Index, epoch: Epoch) -> RawId { let v = (index as u64) | ((epoch as u64) << 32); - Self(NonZeroU64::new(v).unwrap()) + Self(NonZeroU64::new(v).expect("IDs may not be zero")) } /// Unzip a raw identifier into its components. @@ -101,10 +105,22 @@ impl From for SerialId { } } -impl From for RawId { - fn from(id: SerialId) -> Self { - match id { - SerialId::Id(index, epoch) => RawId::zip(index, epoch), +pub struct ZeroIdError; + +impl fmt::Display for ZeroIdError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "IDs may not be zero") + } +} + +impl TryFrom for RawId { + type Error = ZeroIdError; + fn try_from(id: SerialId) -> Result { + let SerialId::Id(index, epoch) = id; + if index == 0 && epoch == 0 { + Err(ZeroIdError) + } else { + Ok(RawId::zip(index, epoch)) } } } diff --git a/wgpu-core/src/storage.rs b/wgpu-core/src/storage.rs index 3b87ed81761..8f04261006e 100644 --- a/wgpu-core/src/storage.rs +++ b/wgpu-core/src/storage.rs @@ -94,7 +94,11 @@ where pub(crate) fn remove(&mut self, id: Id) -> T { let (index, epoch) = id.unzip(); - match mem::replace(&mut self.map[index as usize], Element::Vacant) { + let stored = self + .map + .get_mut(index as usize) + .unwrap_or_else(|| panic!("{}[{:?}] does not exist", self.kind, id)); + match mem::replace(stored, Element::Vacant) { Element::Occupied(value, storage_epoch) => { assert_eq!(epoch, storage_epoch, "id epoch mismatch"); value From 942e59eabcfcdd2a6a16505a10e7501845bf9ef0 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Mon, 21 Jul 2025 04:52:50 -0700 Subject: [PATCH 046/303] [naga] Enforce a maximum size for any type (#7950) * [naga] Enforce a maximum size for any type Fixes #4339 Fixes #7383 * Doc fix and changelog entry --- CHANGELOG.md | 6 ++ naga/src/front/wgsl/error.rs | 22 +++++ naga/src/front/wgsl/lower/mod.rs | 39 ++++++++- naga/src/ir/mod.rs | 12 +++ naga/src/proc/layouter.rs | 18 +++- naga/src/proc/type_methods.rs | 39 ++++++--- naga/src/valid/mod.rs | 3 + naga/tests/naga/wgsl_errors.rs | 143 ++++++++++++++++++++++++++++++- 8 files changed, 266 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c27699365fb..1188ef4ef0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,12 @@ We have merged the acceleration structure feature into the `RayQuery` feature. T By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). +### Changes + +#### Naga + +Naga now requires that no type be larger than 1 GB. This limit may be lowered in the future; feedback on an appropriate value for the limit is welcome. By @andyleiserson in [#7950](https://github.com/gfx-rs/wgpu/pull/7950). + ## v26.0.1 (2025-07-10) ### Bug Fixes diff --git a/naga/src/front/wgsl/error.rs b/naga/src/front/wgsl/error.rs index 7f2c8181257..7101eb6fc9c 100644 --- a/naga/src/front/wgsl/error.rs +++ b/naga/src/front/wgsl/error.rs @@ -409,6 +409,12 @@ pub(crate) enum Error<'a> { accept_span: Span, accept_type: String, }, + StructMemberTooLarge { + member_name_span: Span, + }, + TypeTooLarge { + span: Span, + }, } impl From for Error<'_> { @@ -1367,6 +1373,22 @@ impl<'a> Error<'a> { ], notes: vec![], }, + Error::StructMemberTooLarge { member_name_span } => ParseError { + message: "struct member is too large".into(), + labels: vec![(member_name_span, "this member exceeds the maximum size".into())], + notes: vec![format!( + "the maximum size is {} bytes", + crate::valid::MAX_TYPE_SIZE + )], + }, + Error::TypeTooLarge { span } => ParseError { + message: "type is too large".into(), + labels: vec![(span, "this type exceeds the maximum size".into())], + notes: vec![format!( + "the maximum size is {} bytes", + crate::valid::MAX_TYPE_SIZE + )], + }, } } } diff --git a/naga/src/front/wgsl/lower/mod.rs b/naga/src/front/wgsl/lower/mod.rs index 7f702b82b93..a59bdad1e1c 100644 --- a/naga/src/front/wgsl/lower/mod.rs +++ b/naga/src/front/wgsl/lower/mod.rs @@ -7,7 +7,6 @@ use alloc::{ }; use core::num::NonZeroU32; -use crate::common::ForDebugWithTypes; use crate::front::wgsl::error::{Error, ExpectedToken, InvalidAssignmentType}; use crate::front::wgsl::index::Index; use crate::front::wgsl::parse::number::Number; @@ -18,6 +17,7 @@ use crate::{ common::wgsl::{TryToWgsl, TypeContext}, compact::KeepUnused, }; +use crate::{common::ForDebugWithTypes, proc::LayoutErrorInner}; use crate::{ir, proc}; use crate::{Arena, FastHashMap, FastIndexMap, Handle, Span}; @@ -3709,7 +3709,27 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { for member in s.members.iter() { let ty = self.resolve_ast_type(member.ty, &mut ctx.as_const())?; - ctx.layouter.update(ctx.module.to_ctx()).unwrap(); + ctx.layouter.update(ctx.module.to_ctx()).map_err(|err| { + let LayoutErrorInner::TooLarge = err.inner else { + unreachable!("unexpected layout error: {err:?}"); + }; + // Since anonymous types of struct members don't get a span, + // associate the error with the member. The layouter could have + // failed on any type that was pending layout, but if it wasn't + // the current struct member, it wasn't a struct member at all, + // because we resolve struct members one-by-one. + if ty == err.ty { + Box::new(Error::StructMemberTooLarge { + member_name_span: member.name.span, + }) + } else { + // Lots of type definitions don't get spans, so this error + // message may not be very useful. + Box::new(Error::TypeTooLarge { + span: ctx.module.types.get_span(err.ty), + }) + } + })?; let member_min_size = ctx.layouter[ty].size; let member_min_alignment = ctx.layouter[ty].alignment; @@ -3761,6 +3781,9 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { }); offset += member_size; + if offset > crate::valid::MAX_TYPE_SIZE { + return Err(Box::new(Error::TypeTooLarge { span })); + } } let size = struct_alignment.round_up(offset); @@ -3938,7 +3961,17 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { let base = self.resolve_ast_type(base, &mut ctx.as_const())?; let size = self.array_size(size, ctx)?; - ctx.layouter.update(ctx.module.to_ctx()).unwrap(); + // Determine the size of the base type, if needed. + ctx.layouter.update(ctx.module.to_ctx()).map_err(|err| { + let LayoutErrorInner::TooLarge = err.inner else { + unreachable!("unexpected layout error: {err:?}"); + }; + // Lots of type definitions don't get spans, so this error + // message may not be very useful. + Box::new(Error::TypeTooLarge { + span: ctx.module.types.get_span(err.ty), + }) + })?; let stride = ctx.layouter[base].to_stride(); ir::TypeInner::Array { base, size, stride } diff --git a/naga/src/ir/mod.rs b/naga/src/ir/mod.rs index 943dbc2458b..125ba818c3f 100644 --- a/naga/src/ir/mod.rs +++ b/naga/src/ir/mod.rs @@ -411,6 +411,18 @@ impl VectorSize { pub const MAX: usize = Self::Quad as usize; } +impl From for u8 { + fn from(size: VectorSize) -> u8 { + size as u8 + } +} + +impl From for u32 { + fn from(size: VectorSize) -> u32 { + size as u32 + } +} + /// Primitive type for a scalar. #[repr(u8)] #[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)] diff --git a/naga/src/proc/layouter.rs b/naga/src/proc/layouter.rs index 0001d92f28b..204a523c91b 100644 --- a/naga/src/proc/layouter.rs +++ b/naga/src/proc/layouter.rs @@ -1,6 +1,9 @@ use core::{fmt::Display, num::NonZeroU32, ops}; -use crate::arena::{Handle, HandleVec}; +use crate::{ + arena::{Handle, HandleVec}, + valid::MAX_TYPE_SIZE, +}; /// A newtype struct where its only valid values are powers of 2 #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] @@ -121,6 +124,12 @@ impl ops::Index> for Layouter { } } +/// Errors generated by the `Layouter`. +/// +/// All of these errors can be produced when validating an arbitrary module. +/// When processing WGSL source, only the `TooLarge` error should be +/// produced by the `Layouter`, as the front-end should not produce IR +/// that would result in the other errors. #[derive(Clone, Copy, Debug, PartialEq, thiserror::Error)] pub enum LayoutErrorInner { #[error("Array element type {0:?} doesn't exist")] @@ -129,6 +138,8 @@ pub enum LayoutErrorInner { InvalidStructMemberType(u32, Handle), #[error("Type width must be a power of two")] NonPowerOfTwoWidth, + #[error("Size exceeds limit of {MAX_TYPE_SIZE} bytes")] + TooLarge, } #[derive(Clone, Copy, Debug, PartialEq, thiserror::Error)] @@ -168,7 +179,10 @@ impl Layouter { use crate::TypeInner as Ti; for (ty_handle, ty) in gctx.types.iter().skip(self.layouts.len()) { - let size = ty.inner.size(gctx); + let size = ty + .inner + .try_size(gctx) + .ok_or_else(|| LayoutErrorInner::TooLarge.with(ty_handle))?; let layout = match ty.inner { Ti::Scalar(scalar) | Ti::Atomic(scalar) => { let alignment = Alignment::new(scalar.width as u32) diff --git a/naga/src/proc/type_methods.rs b/naga/src/proc/type_methods.rs index 289756a6795..c59d524f13e 100644 --- a/naga/src/proc/type_methods.rs +++ b/naga/src/proc/type_methods.rs @@ -4,7 +4,7 @@ //! [`Scalar`]: crate::Scalar //! [`ScalarKind`]: crate::ScalarKind -use crate::ir; +use crate::{ir, valid::MAX_TYPE_SIZE}; use super::TypeResolution; @@ -190,18 +190,19 @@ impl crate::TypeInner { } } - /// Get the size of this type. - pub fn size(&self, gctx: super::GlobalCtx) -> u32 { + /// Attempt to calculate the size of this type. Returns `None` if the size + /// exceeds the limit of [`crate::valid::MAX_TYPE_SIZE`]. + pub fn try_size(&self, gctx: super::GlobalCtx) -> Option { match *self { - Self::Scalar(scalar) | Self::Atomic(scalar) => scalar.width as u32, - Self::Vector { size, scalar } => size as u32 * scalar.width as u32, + Self::Scalar(scalar) | Self::Atomic(scalar) => Some(scalar.width as u32), + Self::Vector { size, scalar } => Some(size as u32 * scalar.width as u32), // matrices are treated as arrays of aligned columns Self::Matrix { columns, rows, scalar, - } => super::Alignment::from(rows) * scalar.width as u32 * columns as u32, - Self::Pointer { .. } | Self::ValuePointer { .. } => POINTER_SPAN, + } => Some(super::Alignment::from(rows) * scalar.width as u32 * columns as u32), + Self::Pointer { .. } | Self::ValuePointer { .. } => Some(POINTER_SPAN), Self::Array { base: _, size, @@ -215,17 +216,35 @@ impl crate::TypeInner { // A dynamically-sized array has to have at least one element Ok(crate::proc::IndexableLength::Dynamic) => 1, }; - count * stride + if count > MAX_TYPE_SIZE { + // It shouldn't be possible to have an array of a zero-sized type, but + // let's check just in case. + None + } else { + count + .checked_mul(stride) + .filter(|size| *size <= MAX_TYPE_SIZE) + } } - Self::Struct { span, .. } => span, + Self::Struct { span, .. } => Some(span), Self::Image { .. } | Self::Sampler { .. } | Self::AccelerationStructure { .. } | Self::RayQuery { .. } - | Self::BindingArray { .. } => 0, + | Self::BindingArray { .. } => Some(0), } } + /// Get the size of this type. + /// + /// Panics if the size exceeds the limit of [`crate::valid::MAX_TYPE_SIZE`]. + /// Validated modules should not contain such types. Code working with + /// modules prior to validation should use [`Self::try_size`] and handle the + /// error appropriately. + pub fn size(&self, gctx: super::GlobalCtx) -> u32 { + self.try_size(gctx).expect("type is too large") + } + /// Return the canonical form of `self`, or `None` if it's already in /// canonical form. /// diff --git a/naga/src/valid/mod.rs b/naga/src/valid/mod.rs index aef6a241646..cee5b7420db 100644 --- a/naga/src/valid/mod.rs +++ b/naga/src/valid/mod.rs @@ -35,6 +35,9 @@ pub use r#type::{Disalignment, PushConstantError, TypeError, TypeFlags, WidthErr use self::handles::InvalidHandleError; +/// Maximum size of a type, in bytes. +pub const MAX_TYPE_SIZE: u32 = 0x4000_0000; // 1GB + bitflags::bitflags! { /// Validation flags. /// diff --git a/naga/tests/naga/wgsl_errors.rs b/naga/tests/naga/wgsl_errors.rs index 5784192efdb..79ffe2a49fa 100644 --- a/naga/tests/naga/wgsl_errors.rs +++ b/naga/tests/naga/wgsl_errors.rs @@ -7,7 +7,10 @@ Tests for the WGSL front end. clippy::result_large_err )] -use naga::{compact::KeepUnused, valid::Capabilities}; +use naga::{ + compact::KeepUnused, + valid::{self, Capabilities}, +}; #[track_caller] fn check(input: &str, snapshot: &str) { @@ -3746,3 +3749,141 @@ fn invalid_clip_distances() { naga::valid::Capabilities::CLIP_DISTANCE } } + +#[cfg(feature = "wgsl-in")] +#[test] +fn max_type_size_large_array() { + // The total size of an array is not resolved until validation. Type aliases + // don't get spans so the error isn't very helpful. + check_validation! { + "alias LargeArray = array;": + Err(naga::valid::ValidationError::Layouter( + naga::proc::LayoutError { + inner: naga::proc::LayoutErrorInner::TooLarge, + .. + } + )) + } +} + +#[cfg(feature = "wgsl-in")] +#[test] +fn max_type_size_array_of_arrays() { + // If the size of the base type of an array is oversize, the error is raised + // during lowering. Anonymous types don't get spans so this error isn't very + // helpful. + check( + "alias ArrayOfArrays = array, 22>;", + r#"error: type is too large + = note: the maximum size is 1073741824 bytes + +"#, + ); +} + +#[cfg(feature = "wgsl-in")] +#[test] +fn max_type_size_override_array() { + // The validation that occurs after override processing should reject any + // arrays that were overridden to be larger than the maximum size. Type + // aliases don't get spans so the error isn't very helpful. + let source = r#" + override SIZE: u32 = 1; + alias ArrayOfOverrideArrays = array; + + var global: ArrayOfOverrideArrays; + + @compute @workgroup_size(64) + fn main() { + let used = &global; + } + "#; + let module = naga::front::wgsl::parse_str(source).expect("module should parse"); + let info = valid::Validator::new(Default::default(), valid::Capabilities::all()) + .validate(&module) + .expect("module should validate"); + + let overrides = hashbrown::HashMap::from([(String::from("SIZE"), f64::from((1 << 28) + 1))]); + let err = naga::back::pipeline_constants::process_overrides(&module, &info, None, &overrides) + .unwrap_err(); + let naga::back::pipeline_constants::PipelineConstantError::ValidationError(err) = err else { + panic!("expected a validation error, got {err:?}"); + }; + assert!(matches!( + err.into_inner(), + naga::valid::ValidationError::Layouter(naga::proc::LayoutError { + inner: naga::proc::LayoutErrorInner::TooLarge, + .. + }), + )); +} + +#[cfg(feature = "wgsl-in")] +#[test] +fn max_type_size_array_in_struct() { + // If a struct member is oversize, the error is raised during lowering. + // For struct members we can associate the error with the member. + check( + r#" + struct ContainsLargeArray { + arr: array, + } + "#, + r#"error: struct member is too large + ┌─ wgsl:3:17 + │ +3 │ arr: array, + │ ^^^ this member exceeds the maximum size + │ + = note: the maximum size is 1073741824 bytes + +"#, + ); +} + +#[cfg(feature = "wgsl-in")] +#[test] +fn max_type_size_two_arrays_in_struct() { + // The total size of a struct is checked during lowering. For a struct, + // we can associate the error with the struct itself. + check( + r#" + struct TwoArrays { + arr1: array, + arr2: array, + } + "#, + "error: type is too large + ┌─ wgsl:2:13 + │\x20\x20 +2 │ ╭ struct TwoArrays { +3 │ │ arr1: array, +4 │ │ arr2: array, + │ ╰───────────────────────────────────────────────^ this type exceeds the maximum size + │\x20\x20 + = note: the maximum size is 1073741824 bytes + +", + ); +} + +#[cfg(feature = "wgsl-in")] +#[test] +fn max_type_size_array_of_structs() { + // The total size of an array is not resolved until validation. Type aliases + // don't get spans so the error isn't very helpful. + check_validation! { + r#" + struct NotVeryBigStruct { + data: u32, + } + alias BigArrayOfStructs = array; + "#: + Err(naga::valid::ValidationError::Layouter( + naga::proc::LayoutError { + inner: naga::proc::LayoutErrorInner::TooLarge, + .. + } + )) + } +} From 601c4238b345fb55e8e185680e8d8ba3d048279b Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Mon, 21 Jul 2025 18:56:42 -0400 Subject: [PATCH 047/303] Update CI triggers (#7983) --- .github/workflows/ci.yml | 7 ++++--- .github/workflows/cts.yml | 14 ++++++++++---- .github/workflows/generate.yml | 10 ++++++++-- .github/workflows/shaders.yml | 7 ++++--- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ac088cd6008..4fca15ea6a8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,12 +3,13 @@ name: CI on: push: branches-ignore: [ - # We don't need to run on renovate PRs. + # Renovate branches are always PRs, so they will be covered + # by the pull_request event. "renovate/**", - # This is the branch the merge queue creates. + # Branches with the `gh-readonly-queue` prefix are used by the + # merge queue, so they are already covered by the `merge_group` event. "gh-readonly-queue/**", ] - tags: [v0.*] pull_request: merge_group: diff --git a/.github/workflows/cts.yml b/.github/workflows/cts.yml index f7a2e1bf288..4fd5511d210 100644 --- a/.github/workflows/cts.yml +++ b/.github/workflows/cts.yml @@ -1,11 +1,17 @@ name: CTS on: + push: + branches-ignore: [ + # Renovate branches are always PRs, so they will be covered + # by the pull_request event. + "renovate/**", + # Branches with the `gh-readonly-queue` prefix are used by the + # merge queue, so they are already covered by the `merge_group` event. + "gh-readonly-queue/**", + ] pull_request: - types: [labeled, opened, synchronize] - schedule: - - cron: "33 2 * * *" - workflow_dispatch: + merge_group: env: CARGO_INCREMENTAL: false diff --git a/.github/workflows/generate.yml b/.github/workflows/generate.yml index 8feff230e5d..db614ebc095 100644 --- a/.github/workflows/generate.yml +++ b/.github/workflows/generate.yml @@ -2,8 +2,14 @@ name: cargo-generate on: push: - branches: ["*"] - tags: [v0.*] + branches-ignore: [ + # Renovate branches are always PRs, so they will be covered + # by the pull_request event. + "renovate/**", + # Branches with the `gh-readonly-queue` prefix are used by the + # merge queue, so they are already covered by the `merge_group` event. + "gh-readonly-queue/**", + ] pull_request: merge_group: diff --git a/.github/workflows/shaders.yml b/.github/workflows/shaders.yml index b912c9d5dc4..3844d2b9625 100644 --- a/.github/workflows/shaders.yml +++ b/.github/workflows/shaders.yml @@ -3,12 +3,13 @@ name: Shaders on: push: branches-ignore: [ - # We don't need to run on renovate PRs. + # Renovate branches are always PRs, so they will be covered + # by the pull_request event. "renovate/**", - # This is the branch the merge queue creates. + # Branches with the `gh-readonly-queue` prefix are used by the + # merge queue, so they are already covered by the `merge_group` event. "gh-readonly-queue/**", ] - tags: [v0.*] pull_request: merge_group: From f5d8a0a06ad311247078d79109628bf092b93aae Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Tue, 22 Jul 2025 06:17:47 -0700 Subject: [PATCH 048/303] Additional validation of texture copies (#7935) * Additional validation of texture copies * Copies must not overlap. * Copies of multisampled or depth/stencil formats must span the entire texture. * Move no-op for zero-size copies after parameter validation. Closes #2951 Fixes #7844 * Fix issue with combined depth+stencil copy on dx12 * PR feedback --- cts_runner/test.lst | 16 +- wgpu-core/src/command/mod.rs | 4 +- wgpu-core/src/command/transfer.rs | 321 ++++++++++++++++++++---------- wgpu-core/src/device/queue.rs | 14 +- 4 files changed, 231 insertions(+), 124 deletions(-) diff --git a/cts_runner/test.lst b/cts_runner/test.lst index a34aa4b3797..21eb6b448b2 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -10,21 +10,7 @@ webgpu:api,validation,encoding,beginRenderPass:* webgpu:api,validation,encoding,cmds,clearBuffer:* webgpu:api,validation,encoding,cmds,compute_pass:set_pipeline:* webgpu:api,validation,encoding,cmds,compute_pass:dispatch_sizes:* -webgpu:api,validation,encoding,cmds,copyTextureToTexture:copy_with_invalid_or_destroyed_texture:* -webgpu:api,validation,encoding,cmds,copyTextureToTexture:texture,device_mismatch:* -webgpu:api,validation,encoding,cmds,copyTextureToTexture:mipmap_level:* -webgpu:api,validation,encoding,cmds,copyTextureToTexture:texture_usage:* -webgpu:api,validation,encoding,cmds,copyTextureToTexture:sample_count:* -//FAIL: webgpu:api,validation,encoding,cmds,copyTextureToTexture:multisampled_copy_restrictions:* -// texture_format_compatibility fails on Windows and Mac in CI. -// It passes locally on Mac. It is also a relatively long test. -//FAIL: webgpu:api,validation,encoding,cmds,copyTextureToTexture:texture_format_compatibility:* -//FAIL: webgpu:api,validation,encoding,cmds,copyTextureToTexture:depth_stencil_copy_restrictions:* -//FAIL: webgpu:api,validation,encoding,cmds,copyTextureToTexture:copy_ranges:* -//FAIL: webgpu:api,validation,encoding,cmds,copyTextureToTexture:copy_within_same_texture:* -//FAIL: webgpu:api,validation,encoding,cmds,copyTextureToTexture:copy_aspects:* -// Fails on Windows, https://github.com/gfx-rs/wgpu/issues/7844. -//FAIL: webgpu:api,validation,encoding,cmds,copyTextureToTexture:copy_ranges_with_compressed_texture_formats:* +webgpu:api,validation,encoding,cmds,copyTextureToTexture:* webgpu:api,validation,encoding,cmds,index_access:* //FAIL: webgpu:api,validation,encoding,cmds,render,draw:* webgpu:api,validation,encoding,cmds,render,draw:index_buffer_OOB:* diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 9587669c73d..8c23e4aef2f 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -289,7 +289,9 @@ impl CommandEncoderStatus { // Since we do not track the state of an invalid encoder, it is not // necessary to unlock an encoder that has been invalidated. fn invalidate>(&mut self, err: E) -> E { - *self = Self::Error(err.clone().into()); + let enc_err = err.clone().into(); + api_log!("Invalidating command encoder: {enc_err:?}"); + *self = Self::Error(enc_err); err } } diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 698228e4c6d..ab34af95187 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -1,4 +1,4 @@ -use alloc::{sync::Arc, vec::Vec}; +use alloc::{format, string::String, sync::Arc, vec, vec::Vec}; use arrayvec::ArrayVec; use thiserror::Error; @@ -65,6 +65,33 @@ pub enum TransferError { dimension: TextureErrorDimension, side: CopySide, }, + #[error("Partial copy of {start_offset}..{end_offset} on {dimension:?} dimension with size {texture_size} \ + is not supported for the {side:?} texture format {format:?} with {sample_count} samples")] + UnsupportedPartialTransfer { + format: wgt::TextureFormat, + sample_count: u32, + start_offset: u32, + end_offset: u32, + texture_size: u32, + dimension: TextureErrorDimension, + side: CopySide, + }, + #[error( + "Copying{} layers {}..{} to{} layers {}..{} of the same texture is not allowed", + if *src_aspects == wgt::TextureAspect::All { String::new() } else { format!(" {src_aspects:?}") }, + src_origin_z, + src_origin_z + array_layer_count, + if *dst_aspects == wgt::TextureAspect::All { String::new() } else { format!(" {dst_aspects:?}") }, + dst_origin_z, + dst_origin_z + array_layer_count, + )] + InvalidCopyWithinSameTexture { + src_aspects: wgt::TextureAspect, + dst_aspects: wgt::TextureAspect, + src_origin_z: u32, + dst_origin_z: u32, + array_layer_count: u32, + }, #[error("Unable to select texture aspect {aspect:?} from format {format:?}")] InvalidTextureAspect { format: wgt::TextureFormat, @@ -153,6 +180,8 @@ impl WebGpuError for TransferError { Self::BufferOverrun { .. } | Self::TextureOverrun { .. } + | Self::UnsupportedPartialTransfer { .. } + | Self::InvalidCopyWithinSameTexture { .. } | Self::InvalidTextureAspect { .. } | Self::InvalidTextureMipLevel { .. } | Self::InvalidDimensionExternal @@ -334,13 +363,16 @@ pub(crate) fn validate_linear_texture_data( Ok((bytes_in_copy, image_stride_bytes)) } -/// WebGPU's [validating texture copy range][vtcr] algorithm. +/// Validate the extent and alignment of a texture copy. /// -/// Copied with minor modifications from WebGPU standard. +/// Copied with minor modifications from WebGPU standard. This mostly follows +/// the [validating GPUTexelCopyTextureInfo][vtcti] and [validating texture copy +/// range][vtcr] algorithms. /// /// Returns the HAL copy extent and the layer count. /// -/// [vtcr]: https://gpuweb.github.io/gpuweb/#validating-texture-copy-range +/// [vtcti]: https://gpuweb.github.io/gpuweb/#abstract-opdef-validating-gputexelcopytextureinfo +/// [vtcr]: https://gpuweb.github.io/gpuweb/#abstract-opdef-validating-texture-copy-range pub(crate) fn validate_texture_copy_range( texture_copy_view: &wgt::TexelCopyTextureInfo, desc: &wgt::TextureDescriptor<(), Vec>, @@ -358,47 +390,55 @@ pub(crate) fn validate_texture_copy_range( // physical size can be larger than the virtual let extent = extent_virtual.physical_size(desc.format); - /// Return `Ok` if a run `size` texels long starting at `start_offset` falls - /// entirely within `texture_size`. Otherwise, return an appropriate a`Err`. - fn check_dimension( - dimension: TextureErrorDimension, - side: CopySide, - start_offset: u32, - size: u32, - texture_size: u32, - ) -> Result<(), TransferError> { + // Multisampled and depth-stencil formats do not support partial copies. + let requires_exact_size = desc.format.is_depth_stencil_format() || desc.sample_count > 1; + + // Return `Ok` if a run `size` texels long starting at `start_offset` is + // valid for `texture_size`. Otherwise, return an appropriate a`Err`. + let check_dimension = |dimension: TextureErrorDimension, + start_offset: u32, + size: u32, + texture_size: u32| + -> Result<(), TransferError> { + if requires_exact_size && (start_offset != 0 || size != texture_size) { + Err(TransferError::UnsupportedPartialTransfer { + format: desc.format, + sample_count: desc.sample_count, + start_offset, + end_offset: start_offset.wrapping_add(size), + texture_size, + dimension, + side: texture_side, + }) // Avoid underflow in the subtraction by checking start_offset against // texture_size first. - if start_offset <= texture_size && size <= texture_size - start_offset { - Ok(()) - } else { + } else if start_offset > texture_size || texture_size - start_offset < size { Err(TransferError::TextureOverrun { start_offset, end_offset: start_offset.wrapping_add(size), texture_size, dimension, - side, + side: texture_side, }) + } else { + Ok(()) } - } + }; check_dimension( TextureErrorDimension::X, - texture_side, texture_copy_view.origin.x, copy_size.width, extent.width, )?; check_dimension( TextureErrorDimension::Y, - texture_side, texture_copy_view.origin.y, copy_size.height, extent.height, )?; check_dimension( TextureErrorDimension::Z, - texture_side, texture_copy_view.origin.z, copy_size.depth_or_array_layers, extent.depth_or_array_layers, @@ -431,6 +471,50 @@ pub(crate) fn validate_texture_copy_range( Ok((copy_extent, array_layer_count)) } +/// Validate a copy within the same texture. +/// +/// This implements the WebGPU requirement that the [sets of subresources for +/// texture copy][srtc] of the source and destination be disjoint, i.e. that the +/// source and destination do not overlap. +/// +/// This function assumes that the copy ranges have already been validated with +/// `validate_texture_copy_range`. +/// +/// [srtc]: https://gpuweb.github.io/gpuweb/#abstract-opdef-set-of-subresources-for-texture-copy +pub(crate) fn validate_copy_within_same_texture( + src: &wgt::TexelCopyTextureInfo, + dst: &wgt::TexelCopyTextureInfo, + format: wgt::TextureFormat, + array_layer_count: u32, +) -> Result<(), TransferError> { + let src_aspects = hal::FormatAspects::new(format, src.aspect); + let dst_aspects = hal::FormatAspects::new(format, dst.aspect); + if (src_aspects & dst_aspects).is_empty() { + // Copying between different aspects (if it even makes sense), is okay. + return Ok(()); + } + + if src.origin.z >= dst.origin.z + array_layer_count + || dst.origin.z >= src.origin.z + array_layer_count + { + // Copying between non-overlapping layer ranges is okay. + return Ok(()); + } + + if src.mip_level != dst.mip_level { + // Copying between different mip levels is okay. + return Ok(()); + } + + Err(TransferError::InvalidCopyWithinSameTexture { + src_aspects: src.aspect, + dst_aspects: dst.aspect, + src_origin_z: src.origin.z, + dst_origin_z: dst.origin.z, + array_layer_count, + }) +} + fn handle_texture_init( init_kind: MemoryInitKind, cmd_buf_data: &mut CommandBufferMutable, @@ -742,15 +826,11 @@ impl Global { }); } - if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth_or_array_layers == 0 - { - log::trace!("Ignoring copy_buffer_to_texture of size 0"); - return Ok(()); - } - let dst_texture = hub.textures.get(destination.texture).get()?; + let src_buffer = hub.buffers.get(source.buffer).get()?; dst_texture.same_device_as(cmd_buf.as_ref())?; + src_buffer.same_device_as(cmd_buf.as_ref())?; let (hal_copy_size, array_layer_count) = validate_texture_copy_range( destination, @@ -764,6 +844,15 @@ impl Global { let snatch_guard = device.snatchable_lock.read(); + let src_raw = src_buffer.try_raw(&snatch_guard)?; + let dst_raw = dst_texture.try_raw(&snatch_guard)?; + + if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth_or_array_layers == 0 + { + log::trace!("Ignoring copy_buffer_to_texture of size 0"); + return Ok(()); + } + // Handle texture init *before* dealing with barrier transitions so we // have an easier time inserting "immediate-inits" that may be required // by prior discards in rare cases. @@ -776,16 +865,11 @@ impl Global { &snatch_guard, )?; - let src_buffer = hub.buffers.get(source.buffer).get()?; - - src_buffer.same_device_as(cmd_buf.as_ref())?; - let src_pending = cmd_buf_data .trackers .buffers .set_single(&src_buffer, wgt::BufferUses::COPY_SRC); - let src_raw = src_buffer.try_raw(&snatch_guard)?; src_buffer .check_usage(BufferUsages::COPY_SRC) .map_err(TransferError::MissingBufferUsage)?; @@ -797,7 +881,6 @@ impl Global { dst_range, wgt::TextureUses::COPY_DST, ); - let dst_raw = dst_texture.try_raw(&snatch_guard)?; dst_texture .check_usage(TextureUsages::COPY_DST) .map_err(TransferError::MissingTextureUsage)?; @@ -901,15 +984,11 @@ impl Global { }); } - if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth_or_array_layers == 0 - { - log::trace!("Ignoring copy_texture_to_buffer of size 0"); - return Ok(()); - } - let src_texture = hub.textures.get(source.texture).get()?; + let dst_buffer = hub.buffers.get(destination.buffer).get()?; src_texture.same_device_as(cmd_buf.as_ref())?; + dst_buffer.same_device_as(cmd_buf.as_ref())?; let (hal_copy_size, array_layer_count) = validate_texture_copy_range( source, @@ -922,23 +1001,6 @@ impl Global { let snatch_guard = device.snatchable_lock.read(); - // Handle texture init *before* dealing with barrier transitions so we - // have an easier time inserting "immediate-inits" that may be required - // by prior discards in rare cases. - handle_src_texture_init( - cmd_buf_data, - device, - source, - copy_size, - &src_texture, - &snatch_guard, - )?; - - let src_pending = cmd_buf_data.trackers.textures.set_single( - &src_texture, - src_range, - wgt::TextureUses::COPY_SRC, - ); let src_raw = src_texture.try_raw(&snatch_guard)?; src_texture .check_usage(TextureUsages::COPY_SRC) @@ -956,25 +1018,6 @@ impl Global { } .into()); } - let src_barrier = src_pending - .map(|pending| pending.into_hal(src_raw)) - .collect::>(); - - let dst_buffer = hub.buffers.get(destination.buffer).get()?; - - dst_buffer.same_device_as(cmd_buf.as_ref())?; - - let dst_pending = cmd_buf_data - .trackers - .buffers - .set_single(&dst_buffer, wgt::BufferUses::COPY_DST); - - let dst_raw = dst_buffer.try_raw(&snatch_guard)?; - dst_buffer - .check_usage(BufferUsages::COPY_DST) - .map_err(TransferError::MissingBufferUsage)?; - let dst_barrier = - dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); if !src_base.aspect.is_one() { return Err(TransferError::CopyAspectNotOne.into()); @@ -1005,6 +1048,46 @@ impl Global { .map_err(TransferError::from)?; } + let dst_raw = dst_buffer.try_raw(&snatch_guard)?; + dst_buffer + .check_usage(BufferUsages::COPY_DST) + .map_err(TransferError::MissingBufferUsage)?; + + if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth_or_array_layers == 0 + { + log::trace!("Ignoring copy_texture_to_buffer of size 0"); + return Ok(()); + } + + // Handle texture init *before* dealing with barrier transitions so we + // have an easier time inserting "immediate-inits" that may be required + // by prior discards in rare cases. + handle_src_texture_init( + cmd_buf_data, + device, + source, + copy_size, + &src_texture, + &snatch_guard, + )?; + + let src_pending = cmd_buf_data.trackers.textures.set_single( + &src_texture, + src_range, + wgt::TextureUses::COPY_SRC, + ); + let src_barrier = src_pending + .map(|pending| pending.into_hal(src_raw)) + .collect::>(); + + let dst_pending = cmd_buf_data + .trackers + .buffers + .set_single(&dst_buffer, wgt::BufferUses::COPY_DST); + + let dst_barrier = + dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); + cmd_buf_data.buffer_memory_init_actions.extend( dst_buffer.initialization_status.read().create_action( &dst_buffer, @@ -1078,12 +1161,6 @@ impl Global { }); } - if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth_or_array_layers == 0 - { - log::trace!("Ignoring copy_texture_to_texture of size 0"); - return Ok(()); - } - let src_texture = hub.textures.get(source.texture).get()?; let dst_texture = hub.textures.get(destination.texture).get()?; @@ -1115,6 +1192,15 @@ impl Global { copy_size, )?; + if Arc::as_ptr(&src_texture) == Arc::as_ptr(&dst_texture) { + validate_copy_within_same_texture( + source, + destination, + src_texture.desc.format, + array_layer_count, + )?; + } + let (src_range, src_tex_base) = extract_texture_selector(source, copy_size, &src_texture)?; let (dst_range, dst_tex_base) = @@ -1156,15 +1242,26 @@ impl Global { &snatch_guard, )?; + let src_raw = src_texture.try_raw(&snatch_guard)?; + src_texture + .check_usage(TextureUsages::COPY_SRC) + .map_err(TransferError::MissingTextureUsage)?; + let dst_raw = dst_texture.try_raw(&snatch_guard)?; + dst_texture + .check_usage(TextureUsages::COPY_DST) + .map_err(TransferError::MissingTextureUsage)?; + + if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth_or_array_layers == 0 + { + log::trace!("Ignoring copy_texture_to_texture of size 0"); + return Ok(()); + } + let src_pending = cmd_buf_data.trackers.textures.set_single( &src_texture, src_range, wgt::TextureUses::COPY_SRC, ); - let src_raw = src_texture.try_raw(&snatch_guard)?; - src_texture - .check_usage(TextureUsages::COPY_SRC) - .map_err(TransferError::MissingTextureUsage)?; //TODO: try to avoid this the collection. It's needed because both // `src_pending` and `dst_pending` try to hold `trackers.textures` mutably. @@ -1177,11 +1274,6 @@ impl Global { dst_range, wgt::TextureUses::COPY_DST, ); - let dst_raw = dst_texture.try_raw(&snatch_guard)?; - dst_texture - .check_usage(TextureUsages::COPY_DST) - .map_err(TransferError::MissingTextureUsage)?; - barriers.extend(dst_pending.map(|pending| pending.into_hal(dst_raw))); let hal_copy_size = hal::CopyExtent { @@ -1189,19 +1281,46 @@ impl Global { height: src_copy_size.height.min(dst_copy_size.height), depth: src_copy_size.depth.min(dst_copy_size.depth), }; - let regions = (0..array_layer_count) - .map(|rel_array_layer| { - let mut src_base = src_tex_base.clone(); - let mut dst_base = dst_tex_base.clone(); - src_base.array_layer += rel_array_layer; - dst_base.array_layer += rel_array_layer; + let regions = if dst_tex_base.aspect == hal::FormatAspects::DEPTH_STENCIL { + vec![ hal::TextureCopy { - src_base, - dst_base, + src_base: hal::TextureCopyBase { + aspect: hal::FormatAspects::DEPTH, + ..src_tex_base + }, + dst_base: hal::TextureCopyBase { + aspect: hal::FormatAspects::DEPTH, + ..dst_tex_base + }, size: hal_copy_size, - } - }) - .collect::>(); + }, + hal::TextureCopy { + src_base: hal::TextureCopyBase { + aspect: hal::FormatAspects::STENCIL, + ..src_tex_base + }, + dst_base: hal::TextureCopyBase { + aspect: hal::FormatAspects::STENCIL, + ..dst_tex_base + }, + size: hal_copy_size, + }, + ] + } else { + (0..array_layer_count) + .map(|rel_array_layer| { + let mut src_base = src_tex_base.clone(); + let mut dst_base = dst_tex_base.clone(); + src_base.array_layer += rel_array_layer; + dst_base.array_layer += rel_array_layer; + hal::TextureCopy { + src_base, + dst_base, + size: hal_copy_size, + } + }) + .collect() + }; let cmd_buf_raw = cmd_buf_data.encoder.open()?; unsafe { cmd_buf_raw.transition_textures(&barriers); diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 22261c13e46..208e12cbb40 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -717,11 +717,6 @@ impl Queue { self.device.check_is_valid()?; - if size.width == 0 || size.height == 0 || size.depth_or_array_layers == 0 { - log::trace!("Ignoring write_texture of size 0"); - return Ok(()); - } - let dst = destination.texture.get()?; let destination = wgt::TexelCopyTextureInfo { texture: (), @@ -774,6 +769,13 @@ impl Queue { let snatch_guard = self.device.snatchable_lock.read(); + let dst_raw = dst.try_raw(&snatch_guard)?; + + if size.width == 0 || size.height == 0 || size.depth_or_array_layers == 0 { + log::trace!("Ignoring write_texture of size 0"); + return Ok(()); + } + let mut pending_writes = self.pending_writes.lock(); let encoder = pending_writes.activate(); @@ -819,8 +821,6 @@ impl Queue { } } - let dst_raw = dst.try_raw(&snatch_guard)?; - let (block_width, block_height) = dst.desc.format.block_dimensions(); let width_in_blocks = size.width / block_width; let height_in_blocks = size.height / block_height; From c5efc89b0875c2a536446929e69c93395985d5c8 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Sat, 19 Jul 2025 17:13:21 -0400 Subject: [PATCH 049/303] hal/vulkan: add debug names to all swapchain semaphores --- wgpu-hal/src/vulkan/device.rs | 18 +++++++++++++----- wgpu-hal/src/vulkan/instance.rs | 2 ++ wgpu-hal/src/vulkan/mod.rs | 19 ++++++++++++++----- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index b1cbfd84102..8bfddd5d911 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -577,8 +577,8 @@ impl super::Device { // semaphores, since we prospectively need to provide the call to // acquire the next image with an unsignaled semaphore. let surface_semaphores = (0..=images.len()) - .map(|_| { - super::SwapchainImageSemaphores::new(&self.shared) + .map(|i| { + super::SwapchainImageSemaphores::new(&self.shared, i) .map(Mutex::new) .map(Arc::new) }) @@ -3018,11 +3018,19 @@ impl crate::Device for super::Device { } impl super::DeviceShared { - pub(super) fn new_binary_semaphore(&self) -> Result { + pub(super) fn new_binary_semaphore( + &self, + name: &str, + ) -> Result { unsafe { - self.raw + let semaphore = self + .raw .create_semaphore(&vk::SemaphoreCreateInfo::default(), None) - .map_err(super::map_host_device_oom_err) + .map_err(super::map_host_device_oom_err)?; + + self.set_object_name(semaphore, name); + + Ok(semaphore) } } diff --git a/wgpu-hal/src/vulkan/instance.rs b/wgpu-hal/src/vulkan/instance.rs index d7d7183330d..2e82e7d6be3 100644 --- a/wgpu-hal/src/vulkan/instance.rs +++ b/wgpu-hal/src/vulkan/instance.rs @@ -1129,6 +1129,8 @@ impl crate::Surface for super::Surface { } }; + log::error!("Got swapchain image {index}"); + drop(locked_swapchain_semaphores); // We only advance the surface semaphores if we successfully acquired an image, otherwise // we should try to re-acquire using the same semaphores. diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index a6bdff90d19..8f979663275 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -262,16 +262,22 @@ struct SwapchainImageSemaphores { /// /// [`acquire`]: SwapchainImageSemaphores::acquire previously_used_submission_index: crate::FenceValue, + + /// Which image this semaphore set is used for. + frame_index: usize, } impl SwapchainImageSemaphores { - fn new(device: &DeviceShared) -> Result { + fn new(device: &DeviceShared, frame_index: usize) -> Result { Ok(Self { - acquire: device.new_binary_semaphore()?, + acquire: device.new_binary_semaphore(&format!( + "SwapchainImageSemaphore: Image {frame_index} acquire" + ))?, should_wait_for_acquire: true, present: Vec::new(), present_index: 0, previously_used_submission_index: 0, + frame_index, }) } @@ -304,7 +310,10 @@ impl SwapchainImageSemaphores { let sem = match self.present.get(self.present_index) { Some(sem) => *sem, None => { - let sem = device.new_binary_semaphore()?; + let sem = device.new_binary_semaphore(&format!( + "SwapchainImageSemaphore: Image {} present semaphore {}", + self.frame_index, self.present_index + ))?; self.present.push(sem); sem } @@ -729,7 +738,7 @@ impl RelaySemaphores { fn new(device: &DeviceShared) -> Result { Ok(Self { wait: None, - signal: device.new_binary_semaphore()?, + signal: device.new_binary_semaphore("RelaySemaphores: 1")?, }) } @@ -744,7 +753,7 @@ impl RelaySemaphores { // The second submission should wait on `old.signal`, and then // signal a new semaphore which we'll create now. self.wait = Some(old.signal); - self.signal = device.new_binary_semaphore()?; + self.signal = device.new_binary_semaphore("RelaySemaphores: 2")?; } Some(ref mut wait) => { // What this submission signals, the next should wait. From 83badd52abfafc0badb24bcde6216d6dd64cd79d Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Sat, 19 Jul 2025 22:42:37 -0400 Subject: [PATCH 050/303] hal/vulkan: use different indexes for acquire and present --- wgpu-hal/src/vulkan/device.rs | 18 ++- wgpu-hal/src/vulkan/instance.rs | 32 +++-- wgpu-hal/src/vulkan/mod.rs | 243 ++++++++++++++++++++++---------- 3 files changed, 197 insertions(+), 96 deletions(-) diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 8bfddd5d911..6b66bfa6aaf 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -573,25 +573,29 @@ impl super::Device { let images = unsafe { functor.get_swapchain_images(raw) }.map_err(super::map_host_device_oom_err)?; - // NOTE: It's important that we define at least images.len() wait - // semaphores, since we prospectively need to provide the call to - // acquire the next image with an unsignaled semaphore. - let surface_semaphores = (0..=images.len()) + // NOTE: It's important that we define the same number of acquire/present semaphores + // as we will need to index into them with the image index. + let acquire_semaphores = (0..=images.len()) .map(|i| { - super::SwapchainImageSemaphores::new(&self.shared, i) + super::SwapchainAcquireSemaphore::new(&self.shared, i) .map(Mutex::new) .map(Arc::new) }) .collect::, _>>()?; + let present_semaphores = (0..=images.len()) + .map(|i| Arc::new(Mutex::new(super::SwapchainPresentSemaphores::new(i)))) + .collect::>(); + Ok(super::Swapchain { raw, functor, device: Arc::clone(&self.shared), images, config: config.clone(), - surface_semaphores, - next_semaphore_index: 0, + acquire_semaphores, + next_acquire_index: 0, + present_semaphores, next_present_time: None, }) } diff --git a/wgpu-hal/src/vulkan/instance.rs b/wgpu-hal/src/vulkan/instance.rs index 2e82e7d6be3..572ffcd3f0f 100644 --- a/wgpu-hal/src/vulkan/instance.rs +++ b/wgpu-hal/src/vulkan/instance.rs @@ -188,9 +188,18 @@ impl super::Swapchain { }; // We cannot take this by value, as the function returns `self`. - for semaphore in self.surface_semaphores.drain(..) { + for semaphore in self.acquire_semaphores.drain(..) { let arc_removed = Arc::into_inner(semaphore).expect( - "Trying to destroy a SurfaceSemaphores that is still in use by a SurfaceTexture", + "Trying to destroy a SurfaceAcquireSemaphores that is still in use by a SurfaceTexture", + ); + let mutex_removed = arc_removed.into_inner(); + + unsafe { mutex_removed.destroy(device) }; + } + + for semaphore in self.present_semaphores.drain(..) { + let arc_removed = Arc::into_inner(semaphore).expect( + "Trying to destroy a SurfacePresentSemaphores that is still in use by a SurfaceTexture", ); let mutex_removed = arc_removed.into_inner(); @@ -1074,9 +1083,9 @@ impl crate::Surface for super::Surface { timeout_ns = u64::MAX; } - let swapchain_semaphores_arc = swapchain.get_surface_semaphores(); + let acquire_semaphore_arc = swapchain.get_acquire_semaphore(); // Nothing should be using this, so we don't block, but panic if we fail to lock. - let locked_swapchain_semaphores = swapchain_semaphores_arc + let acquire_semaphore_guard = acquire_semaphore_arc .try_lock() .expect("Failed to lock a SwapchainSemaphores."); @@ -1095,7 +1104,7 @@ impl crate::Surface for super::Surface { // `vkAcquireNextImageKHR` again. swapchain.device.wait_for_fence( fence, - locked_swapchain_semaphores.previously_used_submission_index, + acquire_semaphore_guard.previously_used_submission_index, timeout_ns, )?; @@ -1105,7 +1114,7 @@ impl crate::Surface for super::Surface { swapchain.functor.acquire_next_image( swapchain.raw, timeout_ns, - locked_swapchain_semaphores.acquire, + acquire_semaphore_guard.acquire, vk::Fence::null(), ) } { @@ -1129,12 +1138,12 @@ impl crate::Surface for super::Surface { } }; - log::error!("Got swapchain image {index}"); - - drop(locked_swapchain_semaphores); + drop(acquire_semaphore_guard); // We only advance the surface semaphores if we successfully acquired an image, otherwise // we should try to re-acquire using the same semaphores. - swapchain.advance_surface_semaphores(); + swapchain.advance_acquire_semaphore(); + + let present_semaphore_arc = swapchain.get_present_semaphores(index); // special case for Intel Vulkan returning bizarre values (ugh) if swapchain.device.vendor_id == crate::auxil::db::intel::VENDOR && index > 0x100 { @@ -1158,7 +1167,8 @@ impl crate::Surface for super::Surface { }, identity, }, - surface_semaphores: swapchain_semaphores_arc, + acquire_semaphores: acquire_semaphore_arc, + present_semaphores: present_semaphore_arc, }; Ok(Some(crate::AcquiredSurfaceTexture { texture, diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 8f979663275..6608331f4fe 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -178,9 +178,9 @@ pub struct Instance { shared: Arc, } -/// The semaphores needed to use one image in a swapchain. +/// Semaphore used to acquire a swapchain image. #[derive(Debug)] -struct SwapchainImageSemaphores { +struct SwapchainAcquireSemaphore { /// A semaphore that is signaled when this image is safe for us to modify. /// /// When [`vkAcquireNextImageKHR`] returns the index of the next swapchain @@ -209,10 +209,70 @@ struct SwapchainImageSemaphores { /// wait. We set this flag when this image is acquired, and clear it the /// first time it's passed to [`Queue::submit`] as a surface texture. /// - /// [`acquire`]: SwapchainImageSemaphores::acquire + /// Additionally, semaphores can only be waited on once, so we need to ensure + /// that we only actually pass this semaphore to the first submission that + /// uses that image. + /// + /// [`acquire`]: SwapchainAcquireSemaphore::acquire /// [`Queue::submit`]: crate::Queue::submit should_wait_for_acquire: bool, + /// The fence value of the last command submission that wrote to this image. + /// + /// The next time we try to acquire this image, we'll block until + /// this submission finishes, proving that [`acquire`] is ready to + /// pass to `vkAcquireNextImageKHR` again. + /// + /// [`acquire`]: SwapchainAcquireSemaphore::acquire + previously_used_submission_index: crate::FenceValue, +} + +impl SwapchainAcquireSemaphore { + fn new(device: &DeviceShared, index: usize) -> Result { + Ok(Self { + acquire: device + .new_binary_semaphore(&format!("SwapchainImageSemaphore: Index {index} acquire"))?, + should_wait_for_acquire: true, + previously_used_submission_index: 0, + }) + } + + /// Sets the fence value which the next acquire will wait for. This prevents + /// the semaphore from being used while the previous submission is still in flight. + fn set_used_fence_value(&mut self, value: crate::FenceValue) { + self.previously_used_submission_index = value; + } + + /// Return the semaphore that commands drawing to this image should wait for, if any. + /// + /// This only returns `Some` once per acquisition; see + /// [`SwapchainAcquireSemaphore::should_wait_for_acquire`] for details. + fn get_acquire_wait_semaphore(&mut self) -> Option { + if self.should_wait_for_acquire { + self.should_wait_for_acquire = false; + Some(self.acquire) + } else { + None + } + } + + /// Indicates the cpu-side usage of this semaphore has finished for the frame, + /// so reset internal state to be ready for the next frame. + fn end_semaphore_usage(&mut self) { + // Reset the acquire semaphore, so that the next time we acquire this + // image, we can wait for it again. + self.should_wait_for_acquire = true; + } + + unsafe fn destroy(&self, device: &ash::Device) { + unsafe { + device.destroy_semaphore(self.acquire, None); + } + } +} + +#[derive(Debug)] +struct SwapchainPresentSemaphores { /// A pool of semaphores for ordering presentation after drawing. /// /// The first [`present_index`] semaphores in this vector are: @@ -244,64 +304,33 @@ struct SwapchainImageSemaphores { /// by the next present call. Any semaphores beyond that index were created /// for prior presents and are simply being retained for recycling. /// - /// [`present_index`]: SwapchainImageSemaphores::present_index + /// [`present_index`]: SwapchainPresentSemaphores::present_index /// [`vkQueuePresentKHR`]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#vkQueuePresentKHR /// [`vkQueueSubmit`]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#vkQueueSubmit present: Vec, /// The number of semaphores in [`present`] to be signalled for this submission. /// - /// [`present`]: SwapchainImageSemaphores::present + /// [`present`]: SwapchainPresentSemaphores::present present_index: usize, - /// The fence value of the last command submission that wrote to this image. - /// - /// The next time we try to acquire this image, we'll block until - /// this submission finishes, proving that [`acquire`] is ready to - /// pass to `vkAcquireNextImageKHR` again. - /// - /// [`acquire`]: SwapchainImageSemaphores::acquire - previously_used_submission_index: crate::FenceValue, - /// Which image this semaphore set is used for. frame_index: usize, } -impl SwapchainImageSemaphores { - fn new(device: &DeviceShared, frame_index: usize) -> Result { - Ok(Self { - acquire: device.new_binary_semaphore(&format!( - "SwapchainImageSemaphore: Image {frame_index} acquire" - ))?, - should_wait_for_acquire: true, +impl SwapchainPresentSemaphores { + pub fn new(frame_index: usize) -> Self { + Self { present: Vec::new(), present_index: 0, - previously_used_submission_index: 0, frame_index, - }) - } - - fn set_used_fence_value(&mut self, value: crate::FenceValue) { - self.previously_used_submission_index = value; - } - - /// Return the semaphore that commands drawing to this image should wait for, if any. - /// - /// This only returns `Some` once per acquisition; see - /// [`SwapchainImageSemaphores::should_wait_for_acquire`] for details. - fn get_acquire_wait_semaphore(&mut self) -> Option { - if self.should_wait_for_acquire { - self.should_wait_for_acquire = false; - Some(self.acquire) - } else { - None } } - /// Return a semaphore that a submission that writes to this image should + /// Return the semaphore that the next submission that writes to this image should /// signal when it's done. /// - /// See [`SwapchainImageSemaphores::present`] for details. + /// See [`SwapchainPresentSemaphores::present`] for details. fn get_submit_signal_semaphore( &mut self, device: &DeviceShared, @@ -324,29 +353,29 @@ impl SwapchainImageSemaphores { Ok(sem) } + /// Indicates the cpu-side usage of this semaphore has finished for the frame, + /// so reset internal state to be ready for the next frame. + fn end_semaphore_usage(&mut self) { + // Reset the index to 0, so that the next time we get a semaphore, we + // start from the beginning of the list. + self.present_index = 0; + } + /// Return the semaphores that a presentation of this image should wait on. /// /// Return a slice of semaphores that the call to [`vkQueueSubmit`] that /// ends this image's acquisition should wait for. See - /// [`SwapchainImageSemaphores::present`] for details. + /// [`SwapchainPresentSemaphores::present`] for details. /// /// Reset `self` to be ready for the next acquisition cycle. /// /// [`vkQueueSubmit`]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#vkQueueSubmit - fn get_present_wait_semaphores(&mut self) -> &[vk::Semaphore] { - let old_index = self.present_index; - - // Since this marks the end of this acquire/draw/present cycle, take the - // opportunity to reset `self` in preparation for the next acquisition. - self.present_index = 0; - self.should_wait_for_acquire = true; - - &self.present[0..old_index] + fn get_present_wait_semaphores(&mut self) -> Vec { + self.present[0..self.present_index].to_vec() } unsafe fn destroy(&self, device: &ash::Device) { unsafe { - device.destroy_semaphore(self.acquire, None); for sem in &self.present { device.destroy_semaphore(*sem, None); } @@ -360,16 +389,44 @@ struct Swapchain { device: Arc, images: Vec, config: crate::SurfaceConfiguration, - /// One wait semaphore per swapchain image. This will be associated with the - /// surface texture, and later collected during submission. - /// - /// We need this to be `Arc>` because we need to be able to pass this - /// data into the surface texture, so submit/present can use it. - surface_semaphores: Vec>>, - /// The index of the next semaphore to use. Ideally we would use the same - /// index as the image index, but we need to specify the semaphore as an argument - /// to the acquire_next_image function which is what tells us which image to use. - next_semaphore_index: usize, + + /// Semaphores used between image acquisition and the first submission + /// that uses that image. This is indexed using [`next_acquire_index`]. + /// + /// Because we need to provide this to [`vkAcquireNextImageKHR`], we haven't + /// received the swapchain image index for the frame yet, so we cannot use + /// that to index it. + /// + /// Before we pass this to [`vkAcquireNextImageKHR`], we ensure that we wait on + /// the submission indicated by [`previously_used_submission_index`]. This enusres + /// the semaphore is no longer in use before we use it. + /// + /// [`next_acquire_index`]: Swapchain::next_acquire_index + /// [`vkAcquireNextImageKHR`]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#vkAcquireNextImageKHR + /// [`previously_used_submission_index`]: SwapchainAcquireSemaphore::previously_used_submission_index + acquire_semaphores: Vec>>, + /// The index of the next acquire semaphore to use. + /// + /// This is incremented each time we acquire a new image, and wraps around + /// to 0 when it reaches the end of [`acquire_semaphores`]. + /// + /// [`acquire_semaphores`]: Swapchain::acquire_semaphores + next_acquire_index: usize, + + /// Semaphore sets used between all submissions that write to an image and + /// the presentation of that image. + /// + /// This is indexed by the swapchain image index returned by + /// [`vkAcquireNextImageKHR`]. + /// + /// We know it is safe to use these semaphores because use them + /// _after_ the acquire semaphore. Because the acquire semaphore + /// has been signaled, the previous presentation using that image + /// is known-finished, so this semaphore is no longer in use. + /// + /// [`vkAcquireNextImageKHR`]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#vkAcquireNextImageKHR + present_semaphores: Vec>>, + /// The present timing information which will be set in the next call to [`present()`](crate::Queue::present()). /// /// # Safety @@ -380,13 +437,20 @@ struct Swapchain { } impl Swapchain { - fn advance_surface_semaphores(&mut self) { - let semaphore_count = self.surface_semaphores.len(); - self.next_semaphore_index = (self.next_semaphore_index + 1) % semaphore_count; + /// Mark the current frame finished, advancing to the next acquire semaphore. + fn advance_acquire_semaphore(&mut self) { + let semaphore_count = self.acquire_semaphores.len(); + self.next_acquire_index = (self.next_acquire_index + 1) % semaphore_count; + } + + /// Get the next acquire semaphore that should be used with this swapchain. + fn get_acquire_semaphore(&self) -> Arc> { + self.acquire_semaphores[self.next_acquire_index].clone() } - fn get_surface_semaphores(&self) -> Arc> { - self.surface_semaphores[self.next_semaphore_index].clone() + /// Get the set of present semaphores that should be used with the given image index. + fn get_present_semaphores(&self, index: u32) -> Arc> { + self.present_semaphores[index as usize].clone() } } @@ -448,7 +512,8 @@ impl Surface { pub struct SurfaceTexture { index: u32, texture: Texture, - surface_semaphores: Arc>, + acquire_semaphores: Arc>, + present_semaphores: Arc>, } impl crate::DynSurfaceTexture for SurfaceTexture {} @@ -1384,9 +1449,10 @@ impl crate::Queue for Queue { let mut check = HashSet::with_capacity(surface_textures.len()); // We compare the Arcs by pointer, as Eq isn't well defined for SurfaceSemaphores. for st in surface_textures { - check.insert(Arc::as_ptr(&st.surface_semaphores)); + check.insert(Arc::as_ptr(&st.acquire_semaphores) as usize); + check.insert(Arc::as_ptr(&st.present_semaphores) as usize); } - check.len() == surface_textures.len() + check.len() == surface_textures.len() * 2 }, "More than one surface texture is being used from the same swapchain. This will cause a deadlock in release." ); @@ -1394,26 +1460,33 @@ impl crate::Queue for Queue { let locked_swapchain_semaphores = surface_textures .iter() .map(|st| { - st.surface_semaphores + let acquire = st + .acquire_semaphores .try_lock() - .expect("Failed to lock surface semaphore.") + .expect("Failed to lock surface acquire semaphore"); + let present = st + .present_semaphores + .try_lock() + .expect("Failed to lock surface present semaphore"); + + (acquire, present) }) .collect::>(); - for mut swapchain_semaphore in locked_swapchain_semaphores { - swapchain_semaphore.set_used_fence_value(signal_value); + for (mut acquire_semaphore, mut present_semaphores) in locked_swapchain_semaphores { + acquire_semaphore.set_used_fence_value(signal_value); // If we're the first submission to operate on this image, wait on // its acquire semaphore, to make sure the presentation engine is // done with it. - if let Some(sem) = swapchain_semaphore.get_acquire_wait_semaphore() { + if let Some(sem) = acquire_semaphore.get_acquire_wait_semaphore() { wait_stage_masks.push(vk::PipelineStageFlags::TOP_OF_PIPE); wait_semaphores.push(sem); } // Get a semaphore to signal when we're done writing to this surface // image. Presentation of this image will wait for this. - let signal_semaphore = swapchain_semaphore.get_submit_signal_semaphore(&self.device)?; + let signal_semaphore = present_semaphores.get_submit_signal_semaphore(&self.device)?; signal_semaphores.push_binary(signal_semaphore); } @@ -1488,14 +1561,28 @@ impl crate::Queue for Queue { ) -> Result<(), crate::SurfaceError> { let mut swapchain = surface.swapchain.write(); let ssc = swapchain.as_mut().unwrap(); - let mut swapchain_semaphores = texture.surface_semaphores.lock(); + let mut acquire_semaphore = texture.acquire_semaphores.lock(); + let mut present_semaphores = texture.present_semaphores.lock(); + + let wait_semaphores = present_semaphores.get_present_wait_semaphores(); + + // Reset the acquire and present semaphores internal state + // to be ready for the next frame. + // + // We do this before the actual call to present to ensure that + // even if this method errors and early outs, we have reset + // the state for next frame. + acquire_semaphore.end_semaphore_usage(); + present_semaphores.end_semaphore_usage(); + + drop(acquire_semaphore); let swapchains = [ssc.raw]; let image_indices = [texture.index]; let vk_info = vk::PresentInfoKHR::default() .swapchains(&swapchains) .image_indices(&image_indices) - .wait_semaphores(swapchain_semaphores.get_present_wait_semaphores()); + .wait_semaphores(&wait_semaphores); let mut display_timing; let present_times; From 63f3df86c80c5acc124d6c8ed633f97412ce739d Mon Sep 17 00:00:00 2001 From: teoxoy <28601907+teoxoy@users.noreply.github.com> Date: Fri, 18 Jul 2025 19:48:20 +0200 Subject: [PATCH 051/303] [wgpu-core] split command encoders from command buffers --- deno_webgpu/command_encoder.rs | 31 +---- deno_webgpu/device.rs | 1 - player/src/bin/play.rs | 14 +- player/src/lib.rs | 21 ++- player/tests/player/main.rs | 5 +- tests/tests/wgpu-gpu/mem_leaks.rs | 24 ++-- wgpu-core/src/as_hal.rs | 2 +- wgpu-core/src/command/clear.rs | 22 ++- wgpu-core/src/command/compute.rs | 39 +++--- wgpu-core/src/command/mod.rs | 125 +++++++++++------- wgpu-core/src/command/pass.rs | 6 +- wgpu-core/src/command/query.rs | 12 +- wgpu-core/src/command/ray_tracing.rs | 8 +- wgpu-core/src/command/render.rs | 41 +++--- wgpu-core/src/command/transfer.rs | 16 +-- wgpu-core/src/command/transition_resources.rs | 8 +- wgpu-core/src/device/global.rs | 27 ++-- wgpu-core/src/device/queue.rs | 10 +- wgpu-core/src/device/resource.rs | 8 +- wgpu-core/src/hub.rs | 6 +- wgpu-core/src/id.rs | 15 --- wgpu-hal/src/gles/queue.rs | 28 +++- wgpu/src/backend/wgpu_core.rs | 12 +- 23 files changed, 245 insertions(+), 236 deletions(-) diff --git a/deno_webgpu/command_encoder.rs b/deno_webgpu/command_encoder.rs index 318c52a7102..0106b0c0c8d 100644 --- a/deno_webgpu/command_encoder.rs +++ b/deno_webgpu/command_encoder.rs @@ -2,7 +2,6 @@ use std::borrow::Cow; use std::cell::RefCell; -use std::sync::atomic::{AtomicBool, Ordering}; use deno_core::cppgc::Ptr; use deno_core::op2; @@ -29,19 +28,11 @@ pub struct GPUCommandEncoder { pub id: wgpu_core::id::CommandEncoderId, pub label: String, - - pub finished: AtomicBool, } impl Drop for GPUCommandEncoder { fn drop(&mut self) { - // Command encoders and command buffers are both the same wgpu object. - // At the time `finished` is set, ownership of the id (and - // responsibility for dropping it) transfers from the encoder to the - // buffer. - if !self.finished.load(Ordering::SeqCst) { - self.instance.command_encoder_drop(self.id); - } + self.instance.command_encoder_drop(self.id); } } @@ -416,34 +407,22 @@ impl GPUCommandEncoder { fn finish( &self, #[webidl] descriptor: crate::command_buffer::GPUCommandBufferDescriptor, - ) -> Result { + ) -> GPUCommandBuffer { let wgpu_descriptor = wgpu_types::CommandBufferDescriptor { label: crate::transform_label(descriptor.label.clone()), }; - // TODO(https://github.com/gfx-rs/wgpu/issues/7812): This is not right, - // it should be a validation error, and it would be nice if we can just - // let wgpu generate it for us. The problem is that if the encoder was - // already finished, we transferred ownership of the id to a command - // buffer, so we have to bail out before we mint a duplicate command - // buffer with the same id below. - if self.finished.fetch_or(true, Ordering::SeqCst) { - return Err(JsErrorBox::type_error( - "The command encoder has already finished.", - )); - } - let (id, err) = self .instance - .command_encoder_finish(self.id, &wgpu_descriptor); + .command_encoder_finish(self.id, &wgpu_descriptor, None); self.error_handler.push_error(err); - Ok(GPUCommandBuffer { + GPUCommandBuffer { instance: self.instance.clone(), id, label: descriptor.label, - }) + } } fn push_debug_group(&self, #[webidl] group_label: String) { diff --git a/deno_webgpu/device.rs b/deno_webgpu/device.rs index 7a124824617..07915431756 100644 --- a/deno_webgpu/device.rs +++ b/deno_webgpu/device.rs @@ -498,7 +498,6 @@ impl GPUDevice { error_handler: self.error_handler.clone(), id, label, - finished: Default::default(), } } diff --git a/player/src/bin/play.rs b/player/src/bin/play.rs index 5d908a3a060..607c0c4f640 100644 --- a/player/src/bin/play.rs +++ b/player/src/bin/play.rs @@ -7,6 +7,7 @@ fn main() { use player::GlobalPlay as _; use wgc::device::trace; + use wgpu_core::identity::IdentityManager; use std::{ fs, @@ -52,7 +53,8 @@ fn main() { .unwrap(); let global = wgc::global::Global::new("player", &wgt::InstanceDescriptor::default()); - let mut command_buffer_id_manager = wgc::identity::IdentityManager::new(); + let mut command_encoder_id_manager = IdentityManager::new(); + let mut command_buffer_id_manager = IdentityManager::new(); #[cfg(feature = "winit")] let surface = unsafe { @@ -102,7 +104,14 @@ fn main() { unsafe { global.device_start_graphics_debugger_capture(device) }; while let Some(action) = actions.pop() { - global.process(device, queue, action, &dir, &mut command_buffer_id_manager); + global.process( + device, + queue, + action, + &dir, + &mut command_encoder_id_manager, + &mut command_buffer_id_manager, + ); } unsafe { global.device_stop_graphics_debugger_capture(device) }; @@ -164,6 +173,7 @@ fn main() { queue, action, &dir, + &mut command_encoder_id_manager, &mut command_buffer_id_manager, ); } diff --git a/player/src/lib.rs b/player/src/lib.rs index 4b805e9d478..8b5040c90fb 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -6,7 +6,7 @@ extern crate wgpu_core as wgc; extern crate wgpu_types as wgt; -use wgc::device::trace; +use wgc::{device::trace, identity::IdentityManager}; use std::{borrow::Cow, fs, path::Path}; @@ -15,6 +15,7 @@ pub trait GlobalPlay { &self, encoder: wgc::id::CommandEncoderId, commands: Vec, + command_buffer_id_manager: &mut IdentityManager, ) -> wgc::id::CommandBufferId; fn process( &self, @@ -22,7 +23,8 @@ pub trait GlobalPlay { queue: wgc::id::QueueId, action: trace::Action, dir: &Path, - comb_manager: &mut wgc::identity::IdentityManager, + command_encoder_id_manager: &mut IdentityManager, + command_buffer_id_manager: &mut IdentityManager, ); } @@ -31,6 +33,7 @@ impl GlobalPlay for wgc::global::Global { &self, encoder: wgc::id::CommandEncoderId, commands: Vec, + command_buffer_id_manager: &mut IdentityManager, ) -> wgc::id::CommandBufferId { for command in commands { match command { @@ -172,8 +175,11 @@ impl GlobalPlay for wgc::global::Global { } } } - let (cmd_buf, error) = - self.command_encoder_finish(encoder, &wgt::CommandBufferDescriptor { label: None }); + let (cmd_buf, error) = self.command_encoder_finish( + encoder, + &wgt::CommandBufferDescriptor { label: None }, + Some(command_buffer_id_manager.process()), + ); if let Some(e) = error { panic!("{e}"); } @@ -186,7 +192,8 @@ impl GlobalPlay for wgc::global::Global { queue: wgc::id::QueueId, action: trace::Action, dir: &Path, - comb_manager: &mut wgc::identity::IdentityManager, + command_encoder_id_manager: &mut IdentityManager, + command_buffer_id_manager: &mut IdentityManager, ) { use wgc::device::trace::Action; log::debug!("action {action:?}"); @@ -379,12 +386,12 @@ impl GlobalPlay for wgc::global::Global { let (encoder, error) = self.device_create_command_encoder( device, &wgt::CommandEncoderDescriptor { label: None }, - Some(comb_manager.process().into_command_encoder_id()), + Some(command_encoder_id_manager.process()), ); if let Some(e) = error { panic!("{e}"); } - let cmdbuf = self.encode_commands(encoder, commands); + let cmdbuf = self.encode_commands(encoder, commands, command_buffer_id_manager); self.queue_submit(queue, &[cmdbuf]).unwrap(); } Action::CreateBlas { id, desc, sizes } => { diff --git a/player/tests/player/main.rs b/player/tests/player/main.rs index 18f76e76e2c..aa5eb90e74a 100644 --- a/player/tests/player/main.rs +++ b/player/tests/player/main.rs @@ -20,6 +20,7 @@ use std::{ path::{Path, PathBuf}, slice, }; +use wgc::identity::IdentityManager; #[derive(serde::Deserialize)] struct RawId { @@ -104,7 +105,8 @@ impl Test<'_> { panic!("{e:?}"); } - let mut command_buffer_id_manager = wgc::identity::IdentityManager::new(); + let mut command_encoder_id_manager = IdentityManager::new(); + let mut command_buffer_id_manager = IdentityManager::new(); println!("\t\t\tRunning..."); for action in self.actions { global.process( @@ -112,6 +114,7 @@ impl Test<'_> { queue_id, action, dir, + &mut command_encoder_id_manager, &mut command_buffer_id_manager, ); } diff --git a/tests/tests/wgpu-gpu/mem_leaks.rs b/tests/tests/wgpu-gpu/mem_leaks.rs index 775d3aa5cb4..57df08fc8b3 100644 --- a/tests/tests/wgpu-gpu/mem_leaks.rs +++ b/tests/tests/wgpu-gpu/mem_leaks.rs @@ -179,7 +179,7 @@ async fn draw_test_with_reports( let global_report = ctx.instance.generate_report().unwrap(); let report = global_report.hub_report(); - assert_eq!(report.command_buffers.num_allocated, 1); + assert_eq!(report.command_encoders.num_allocated, 1); assert_eq!(report.buffers.num_allocated, 1); let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { @@ -206,7 +206,7 @@ async fn draw_test_with_reports( assert_eq!(report.pipeline_layouts.num_allocated, 1); assert_eq!(report.render_pipelines.num_allocated, 1); assert_eq!(report.compute_pipelines.num_allocated, 0); - assert_eq!(report.command_buffers.num_allocated, 1); + assert_eq!(report.command_encoders.num_allocated, 1); assert_eq!(report.render_bundles.num_allocated, 0); assert_eq!(report.texture_views.num_allocated, 1); assert_eq!(report.textures.num_allocated, 1); @@ -223,7 +223,7 @@ async fn draw_test_with_reports( let global_report = ctx.instance.generate_report().unwrap(); let report = global_report.hub_report(); - assert_eq!(report.command_buffers.num_kept_from_user, 1); + assert_eq!(report.command_encoders.num_kept_from_user, 1); assert_eq!(report.render_pipelines.num_kept_from_user, 0); assert_eq!(report.pipeline_layouts.num_kept_from_user, 0); assert_eq!(report.bind_group_layouts.num_kept_from_user, 0); @@ -231,7 +231,7 @@ async fn draw_test_with_reports( assert_eq!(report.buffers.num_kept_from_user, 0); assert_eq!(report.texture_views.num_kept_from_user, 0); assert_eq!(report.textures.num_kept_from_user, 0); - assert_eq!(report.command_buffers.num_allocated, 1); + assert_eq!(report.command_encoders.num_allocated, 1); assert_eq!(report.render_pipelines.num_allocated, 0); assert_eq!(report.pipeline_layouts.num_allocated, 0); assert_eq!(report.bind_group_layouts.num_allocated, 0); @@ -240,12 +240,18 @@ async fn draw_test_with_reports( assert_eq!(report.texture_views.num_allocated, 0); assert_eq!(report.textures.num_allocated, 0); - let submit_index = ctx.queue.submit(Some(encoder.finish())); + let command_buffer = encoder.finish(); + + let global_report = ctx.instance.generate_report().unwrap(); + let report = global_report.hub_report(); + assert_eq!(report.command_encoders.num_allocated, 0); + assert_eq!(report.command_buffers.num_allocated, 1); + + let submit_index = ctx.queue.submit(Some(command_buffer)); - // TODO: fix in https://github.com/gfx-rs/wgpu/pull/5141 - // let global_report = ctx.instance.generate_report().unwrap(); - // let report = global_report.hub_report(); - // assert_eq!(report.command_buffers.num_allocated, 0); + let global_report = ctx.instance.generate_report().unwrap(); + let report = global_report.hub_report(); + assert_eq!(report.command_buffers.num_allocated, 0); ctx.async_poll(wgpu::PollType::wait_for(submit_index)) .await diff --git a/wgpu-core/src/as_hal.rs b/wgpu-core/src/as_hal.rs index 8ad9cf3ea2f..8e646635989 100644 --- a/wgpu-core/src/as_hal.rs +++ b/wgpu-core/src/as_hal.rs @@ -346,7 +346,7 @@ impl Global { let hub = &self.hub; - let cmd_buf = hub.command_buffers.get(id.into_command_buffer_id()); + let cmd_buf = hub.command_encoders.get(id); let mut cmd_buf_data = cmd_buf.data.lock(); cmd_buf_data.record_as_hal_mut(|opt_cmd_buf| -> R { hal_command_encoder_callback(opt_cmd_buf.and_then(|cmd_buf| { diff --git a/wgpu-core/src/command/clear.rs b/wgpu-core/src/command/clear.rs index e18335fb69d..90a392a0f23 100644 --- a/wgpu-core/src/command/clear.rs +++ b/wgpu-core/src/command/clear.rs @@ -6,7 +6,7 @@ use crate::device::trace::Command as TraceCommand; use crate::{ api_log, command::EncoderStateError, - device::DeviceError, + device::{DeviceError, MissingFeatures}, get_lowest_common_denom, global::Global, id::{BufferId, CommandEncoderId, TextureId}, @@ -30,10 +30,10 @@ use wgt::{ #[derive(Clone, Debug, Error)] #[non_exhaustive] pub enum ClearError { - #[error("To use clear_texture the CLEAR_TEXTURE feature needs to be enabled")] - MissingClearTextureFeature, #[error(transparent)] DestroyedResource(#[from] DestroyedResourceError), + #[error(transparent)] + MissingFeatures(#[from] MissingFeatures), #[error("{0} can not be cleared")] NoValidTextureClearMode(ResourceErrorIdent), #[error("Buffer clear size {0:?} is not a multiple of `COPY_BUFFER_ALIGNMENT`")] @@ -84,12 +84,12 @@ impl WebGpuError for ClearError { fn webgpu_error_type(&self) -> ErrorType { let e: &dyn WebGpuError = match self { Self::DestroyedResource(e) => e, + Self::MissingFeatures(e) => e, Self::MissingBufferUsage(e) => e, Self::Device(e) => e, Self::EncoderState(e) => e, Self::InvalidResource(e) => e, Self::NoValidTextureClearMode(..) - | Self::MissingClearTextureFeature | Self::UnalignedFillSize(..) | Self::UnalignedBufferOffset(..) | Self::OffsetPlusSizeExceeds64BitBounds { .. } @@ -115,9 +115,7 @@ impl Global { let hub = &self.hub; - let cmd_buf = hub - .command_buffers - .get(command_encoder_id.into_command_buffer_id()); + let cmd_buf = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_buf.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), ClearError> { #[cfg(feature = "trace")] @@ -202,9 +200,7 @@ impl Global { let hub = &self.hub; - let cmd_buf = hub - .command_buffers - .get(command_encoder_id.into_command_buffer_id()); + let cmd_buf = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_buf.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), ClearError> { #[cfg(feature = "trace")] @@ -217,9 +213,9 @@ impl Global { cmd_buf.device.check_is_valid()?; - if !cmd_buf.support_clear_texture { - return Err(ClearError::MissingClearTextureFeature); - } + cmd_buf + .device + .require_features(wgt::Features::CLEAR_TEXTURE)?; let dst_texture = hub.textures.get(dst).get()?; diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index e6793a32d7b..015c0265d03 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -7,7 +7,9 @@ use wgt::{ use alloc::{borrow::Cow, boxed::Box, sync::Arc, vec::Vec}; use core::{fmt, str}; -use crate::command::{pass, EncoderStateError, PassStateError, TimestampWritesError}; +use crate::command::{ + pass, CommandEncoder, EncoderStateError, PassStateError, TimestampWritesError, +}; use crate::resource::DestroyedResourceError; use crate::{binding_model::BindError, resource::RawResourceAccess}; use crate::{ @@ -18,8 +20,8 @@ use crate::{ end_pipeline_statistics_query, memory_init::{fixup_discarded_surfaces, SurfacesInDiscardState}, pass_base, pass_try, validate_and_begin_pipeline_statistics_query, ArcPassTimestampWrites, - BasePass, BindGroupStateChange, CommandBuffer, CommandEncoderError, MapPassErr, - PassErrorScope, PassTimestampWrites, QueryUseError, StateChange, + BasePass, BindGroupStateChange, CommandEncoderError, MapPassErr, PassErrorScope, + PassTimestampWrites, QueryUseError, StateChange, }, device::{DeviceError, MissingDownlevelFlags, MissingFeatures}, global::Global, @@ -46,12 +48,12 @@ pub struct ComputePass { /// All pass data & records is stored here. base: ComputeBasePass, - /// Parent command buffer that this pass records commands into. + /// Parent command encoder that this pass records commands into. /// /// If this is `Some`, then the pass is in WebGPU's "open" state. If it is /// `None`, then the pass is in the "ended" state. /// See - parent: Option>, + parent: Option>, timestamp_writes: Option, @@ -61,8 +63,8 @@ pub struct ComputePass { } impl ComputePass { - /// If the parent command buffer is invalid, the returned pass will be invalid. - fn new(parent: Arc, desc: ArcComputePassDescriptor) -> Self { + /// If the parent command encoder is invalid, the returned pass will be invalid. + fn new(parent: Arc, desc: ArcComputePassDescriptor) -> Self { let ArcComputePassDescriptor { label, timestamp_writes, @@ -78,7 +80,7 @@ impl ComputePass { } } - fn new_invalid(parent: Arc, label: &Label, err: ComputePassError) -> Self { + fn new_invalid(parent: Arc, label: &Label, err: ComputePassError) -> Self { Self { base: BasePass::new_invalid(label, err), parent: Some(parent), @@ -308,7 +310,7 @@ impl<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder> ); } - CommandBuffer::drain_barriers( + CommandEncoder::drain_barriers( self.general.raw_encoder, &mut self.intermediate_trackers, self.general.snatch_guard, @@ -342,7 +344,7 @@ impl Global { let label = desc.label.as_deref().map(Cow::Borrowed); - let cmd_buf = hub.command_buffers.get(encoder_id.into_command_buffer_id()); + let cmd_buf = hub.command_encoders.get(encoder_id); let mut cmd_buf_data = cmd_buf.data.lock(); match cmd_buf_data.lock_encoder() { @@ -433,10 +435,7 @@ impl Global { ) { #[cfg(feature = "trace")] { - let cmd_buf = self - .hub - .command_buffers - .get(encoder_id.into_command_buffer_id()); + let cmd_buf = self.hub.command_encoders.get(encoder_id); let mut cmd_buf_data = cmd_buf.data.lock(); let cmd_buf_data = cmd_buf_data.get_inner(); @@ -750,10 +749,10 @@ impl Global { .. } = state; - // Stop the current command buffer. + // Stop the current command encoder. encoder.close().map_pass_err(pass_scope)?; - // Create a new command buffer, which we will insert _before_ the body of the compute pass. + // Create a new command encoder, which we will insert _before_ the body of the compute pass. // // Use that buffer to insert barriers and clear discarded images. let transit = encoder @@ -766,13 +765,13 @@ impl Global { device, &snatch_guard, ); - CommandBuffer::insert_barriers_from_tracker( + CommandEncoder::insert_barriers_from_tracker( transit, tracker, &intermediate_trackers, &snatch_guard, ); - // Close the command buffer, and swap it with the previous. + // Close the command encoder, and swap it with the previous. encoder.close_and_swap().map_pass_err(pass_scope)?; Ok(()) @@ -782,7 +781,7 @@ impl Global { fn set_pipeline( state: &mut State, - cmd_buf: &CommandBuffer, + cmd_buf: &CommandEncoder, pipeline: Arc, ) -> Result<(), ComputePassErrorInner> { pipeline.same_device_as(cmd_buf)?; @@ -859,7 +858,7 @@ fn dispatch(state: &mut State, groups: [u32; 3]) -> Result<(), ComputePassErrorI fn dispatch_indirect( state: &mut State, - cmd_buf: &CommandBuffer, + cmd_buf: &CommandEncoder, buffer: Arc, offset: u64, ) -> Result<(), ComputePassErrorInner> { diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 8c23e4aef2f..ae23ca56179 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -145,6 +145,9 @@ impl CommandEncoderStatus { // Encoder is ended. Invalidate the encoder, do not record anything, // and return an immediate validation error. Self::Finished(_) => Err(self.invalidate(EncoderStateError::Ended)), + Self::Error(CommandEncoderError::State(EncoderStateError::Ended)) => { + Err(EncoderStateError::Ended) + } // Encoder is already invalid. Do not record anything, but do not // return an immediate validation error. Self::Error(_) => Ok(()), @@ -173,6 +176,7 @@ impl CommandEncoderStatus { self.invalidate(EncoderStateError::Ended); f(None) } + Self::Error(CommandEncoderError::State(EncoderStateError::Ended)) => f(None), Self::Error(_) => f(None), Self::Transitioning => unreachable!(), } @@ -210,6 +214,10 @@ impl CommandEncoderStatus { Err(EncoderStateError::Ended) } Self::Locked(_) => Err(self.invalidate(EncoderStateError::Locked)), + st @ Self::Error(CommandEncoderError::State(EncoderStateError::Ended)) => { + *self = st; + Err(EncoderStateError::Ended) + } st @ Self::Error(_) => { *self = st; Err(EncoderStateError::Invalid) @@ -254,6 +262,10 @@ impl CommandEncoderStatus { *self = Self::Error(EncoderStateError::Unlocked.into()); Err(EncoderStateError::Unlocked) } + st @ Self::Error(CommandEncoderError::State(EncoderStateError::Ended)) => { + *self = st; + Err(EncoderStateError::Ended) + } st @ Self::Error(_) => { // Encoder is invalid. Do not record anything, but do not // return an immediate validation error. @@ -374,6 +386,26 @@ impl<'a> ops::DerefMut for RecordingGuard<'a> { } } +pub(crate) struct CommandEncoder { + pub(crate) device: Arc, + + pub(crate) label: String, + + /// The mutable state of this command encoder. + pub(crate) data: Mutex, +} + +crate::impl_resource_type!(CommandEncoder); +crate::impl_labeled!(CommandEncoder); +crate::impl_parent_device!(CommandEncoder); +crate::impl_storage_item!(CommandEncoder); + +impl Drop for CommandEncoder { + fn drop(&mut self) { + resource_log!("Drop {}", self.error_ident()); + } +} + /// A raw [`CommandEncoder`][rce], and the raw [`CommandBuffer`][rcb]s built from it. /// /// Each wgpu-core [`CommandBuffer`] owns an instance of this type, which is @@ -385,16 +417,11 @@ impl<'a> ops::DerefMut for RecordingGuard<'a> { /// commands into the middle of a recorded stream. However, hal queue submission /// accepts a series of command buffers at once, so we can simply break the /// stream up into multiple buffers, and then reorder the buffers. See -/// [`CommandEncoder::close_and_swap`] for a specific example of this. -/// -/// Note that a [`CommandEncoderId`] actually refers to a [`CommandBuffer`]. -/// Methods that take a command encoder id actually look up the command buffer, -/// and then use its encoder. +/// [`InnerCommandEncoder::close_and_swap`] for a specific example of this. /// /// [rce]: hal::Api::CommandEncoder /// [rcb]: hal::Api::CommandBuffer -/// [`CommandEncoderId`]: crate::id::CommandEncoderId -pub(crate) struct CommandEncoder { +pub(crate) struct InnerCommandEncoder { /// The underlying `wgpu_hal` [`CommandEncoder`]. /// /// Successfully executed command buffers' encoders are saved in a @@ -427,10 +454,10 @@ pub(crate) struct CommandEncoder { /// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder pub(crate) is_open: bool, - pub(crate) hal_label: Option, + pub(crate) label: String, } -impl CommandEncoder { +impl InnerCommandEncoder { /// Finish the current command buffer and insert it just before /// the last element in [`self.list`][l]. /// @@ -453,7 +480,7 @@ impl CommandEncoder { /// /// - If the encoder is not open. /// - /// [l]: CommandEncoder::list + /// [l]: InnerCommandEncoder::list /// [`transition_buffers`]: hal::CommandEncoder::transition_buffers /// [`transition_textures`]: hal::CommandEncoder::transition_textures fn close_and_swap(&mut self) -> Result<(), DeviceError> { @@ -476,7 +503,7 @@ impl CommandEncoder { /// /// - If the encoder is not open. /// - /// [l]: CommandEncoder::list + /// [l]: InnerCommandEncoder::list pub(crate) fn close_and_push_front(&mut self) -> Result<(), DeviceError> { assert!(self.is_open); self.is_open = false; @@ -497,7 +524,7 @@ impl CommandEncoder { /// /// - If the encoder is not open. /// - /// [l]: CommandEncoder::list + /// [l]: InnerCommandEncoder::list pub(crate) fn close(&mut self) -> Result<(), DeviceError> { assert!(self.is_open); self.is_open = false; @@ -518,7 +545,7 @@ impl CommandEncoder { /// /// On return, the underlying hal encoder is closed. /// - /// [l]: CommandEncoder::list + /// [l]: InnerCommandEncoder::list fn close_if_open(&mut self) -> Result<(), DeviceError> { if self.is_open { self.is_open = false; @@ -536,7 +563,7 @@ impl CommandEncoder { pub(crate) fn open(&mut self) -> Result<&mut dyn hal::DynCommandEncoder, DeviceError> { if !self.is_open { self.is_open = true; - let hal_label = self.hal_label.as_deref(); + let hal_label = hal_label(Some(&self.label), self.device.instance_flags); unsafe { self.raw.begin_encoding(hal_label) } .map_err(|e| self.device.handle_hal_error(e))?; } @@ -567,7 +594,7 @@ impl CommandEncoder { } } -impl Drop for CommandEncoder { +impl Drop for InnerCommandEncoder { fn drop(&mut self) { if self.is_open { unsafe { self.raw.discard_encoding() }; @@ -584,7 +611,7 @@ impl Drop for CommandEncoder { /// Look at the documentation for [`CommandBufferMutable`] for an explanation of /// the fields in this struct. This is the "built" counterpart to that type. pub(crate) struct BakedCommands { - pub(crate) encoder: CommandEncoder, + pub(crate) encoder: InnerCommandEncoder, pub(crate) trackers: Tracker, pub(crate) temp_resources: Vec, pub(crate) indirect_draw_validation_resources: crate::indirect_validation::DrawResources, @@ -598,7 +625,7 @@ pub struct CommandBufferMutable { /// they belong to. /// /// [`wgpu_hal::Api::CommandBuffer`]: hal::Api::CommandBuffer - pub(crate) encoder: CommandEncoder, + pub(crate) encoder: InnerCommandEncoder, /// All the resources that the commands recorded so far have referred to. pub(crate) trackers: Tracker, @@ -647,25 +674,11 @@ impl CommandBufferMutable { /// A buffer of commands to be submitted to the GPU for execution. /// -/// Whereas the WebGPU API uses two separate types for command buffers and -/// encoders, this type is a fusion of the two: -/// -/// - During command recording, this holds a [`CommandEncoder`] accepting this -/// buffer's commands. In this state, the [`CommandBuffer`] type behaves like -/// a WebGPU `GPUCommandEncoder`. -/// -/// - Once command recording is finished by calling -/// [`Global::command_encoder_finish`], no further recording is allowed. The -/// internal [`CommandEncoder`] is retained solely as a storage pool for the -/// raw command buffers. In this state, the value behaves like a WebGPU -/// `GPUCommandBuffer`. -/// -/// - Once a command buffer is submitted to the queue, it is removed from the id -/// registry, and its contents are taken to construct a [`BakedCommands`], -/// whose contents eventually become the property of the submission queue. +/// Once a command buffer is submitted to the queue, its contents are taken +/// to construct a [`BakedCommands`], whose contents eventually become the +/// property of the submission queue. pub struct CommandBuffer { pub(crate) device: Arc, - support_clear_texture: bool, /// The `label` from the descriptor used to create the resource. label: String, @@ -679,25 +692,24 @@ impl Drop for CommandBuffer { } } -impl CommandBuffer { +impl CommandEncoder { pub(crate) fn new( encoder: Box, device: &Arc, label: &Label, ) -> Self { - CommandBuffer { + CommandEncoder { device: device.clone(), - support_clear_texture: device.features.contains(wgt::Features::CLEAR_TEXTURE), label: label.to_string(), data: Mutex::new( rank::COMMAND_BUFFER_DATA, CommandEncoderStatus::Recording(CommandBufferMutable { - encoder: CommandEncoder { + encoder: InnerCommandEncoder { raw: ManuallyDrop::new(encoder), list: Vec::new(), device: device.clone(), is_open: false, - hal_label: label.to_hal(device.instance_flags).map(str::to_owned), + label: label.to_string(), }, trackers: Tracker::new(), buffer_memory_init_actions: Default::default(), @@ -723,9 +735,8 @@ impl CommandBuffer { label: &Label, err: CommandEncoderError, ) -> Self { - CommandBuffer { + CommandEncoder { device: device.clone(), - support_clear_texture: device.features.contains(wgt::Features::CLEAR_TEXTURE), label: label.to_string(), data: Mutex::new(rank::COMMAND_BUFFER_DATA, CommandEncoderStatus::Error(err)), } @@ -1123,22 +1134,40 @@ impl Global { pub fn command_encoder_finish( &self, encoder_id: id::CommandEncoderId, - _desc: &wgt::CommandBufferDescriptor { samplers: &[&sampler], textures: &[texture_binding], acceleration_structures: &[], + external_textures: &[], entries: &[ hal::BindGroupEntry { binding: 0, @@ -499,6 +500,7 @@ impl Example { samplers: &[], textures: &[], acceleration_structures: &[], + external_textures: &[], entries: &[hal::BindGroupEntry { binding: 0, resource_index: 0, diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index 4fcb6691393..2947d1a6014 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -622,6 +622,7 @@ impl Example { samplers: &[], textures: &[texture_binding], acceleration_structures: &[&tlas], + external_textures: &[], entries: &[ hal::BindGroupEntry { binding: 0, diff --git a/wgpu-hal/src/dynamic/device.rs b/wgpu-hal/src/dynamic/device.rs index fd7c10f254d..de66b1619f6 100644 --- a/wgpu-hal/src/dynamic/device.rs +++ b/wgpu-hal/src/dynamic/device.rs @@ -345,6 +345,11 @@ impl DynDevice for D { .iter() .map(|a| a.expect_downcast_ref()) .collect(); + let external_textures: Vec<_> = desc + .external_textures + .iter() + .map(|et| et.clone().expect_downcast()) + .collect(); let desc = BindGroupDescriptor { label: desc.label.to_owned(), @@ -354,6 +359,7 @@ impl DynDevice for D { textures: &textures, entries: desc.entries, acceleration_structures: &acceleration_structures, + external_textures: &external_textures, }; unsafe { D::create_bind_group(self, &desc) } diff --git a/wgpu-hal/src/dynamic/mod.rs b/wgpu-hal/src/dynamic/mod.rs index a8dbae94ee0..85d8ca00450 100644 --- a/wgpu-hal/src/dynamic/mod.rs +++ b/wgpu-hal/src/dynamic/mod.rs @@ -23,7 +23,8 @@ use wgt::WasmNotSendSync; use crate::{ AccelerationStructureAABBs, AccelerationStructureEntries, AccelerationStructureInstances, AccelerationStructureTriangleIndices, AccelerationStructureTriangleTransform, - AccelerationStructureTriangles, BufferBinding, ProgrammableStage, TextureBinding, + AccelerationStructureTriangles, BufferBinding, ExternalTextureBinding, ProgrammableStage, + TextureBinding, }; /// Base trait for all resources, allows downcasting via [`Any`]. @@ -143,6 +144,16 @@ impl<'a> TextureBinding<'a, dyn DynTextureView> { } } +impl<'a> ExternalTextureBinding<'a, dyn DynBuffer, dyn DynTextureView> { + pub fn expect_downcast( + self, + ) -> ExternalTextureBinding<'a, B, T> { + let planes = self.planes.map(|plane| plane.expect_downcast()); + let params = self.params.expect_downcast(); + ExternalTextureBinding { planes, params } + } +} + impl<'a> ProgrammableStage<'a, dyn DynShaderModule> { fn expect_downcast(self) -> ProgrammableStage<'a, T> { ProgrammableStage { diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index db5269ad4ad..1e92bbece34 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -2145,6 +2145,23 @@ impl<'a, T: DynTextureView + ?Sized> Clone for TextureBinding<'a, T> { } } +#[derive(Debug)] +pub struct ExternalTextureBinding<'a, B: DynBuffer + ?Sized, T: DynTextureView + ?Sized> { + pub planes: [TextureBinding<'a, T>; 3], + pub params: BufferBinding<'a, B>, +} + +impl<'a, B: DynBuffer + ?Sized, T: DynTextureView + ?Sized> Clone + for ExternalTextureBinding<'a, B, T> +{ + fn clone(&self) -> Self { + ExternalTextureBinding { + planes: self.planes.clone(), + params: self.params.clone(), + } + } +} + /// cbindgen:ignore #[derive(Clone, Debug)] pub struct BindGroupEntry { @@ -2178,6 +2195,7 @@ pub struct BindGroupDescriptor< pub textures: &'a [TextureBinding<'a, T>], pub entries: &'a [BindGroupEntry], pub acceleration_structures: &'a [&'a A], + pub external_textures: &'a [ExternalTextureBinding<'a, B, T>], } #[derive(Clone, Debug)] diff --git a/wgpu/src/api/bind_group.rs b/wgpu/src/api/bind_group.rs index 2f4ae007ff6..8471fca53fd 100644 --- a/wgpu/src/api/bind_group.rs +++ b/wgpu/src/api/bind_group.rs @@ -81,6 +81,12 @@ pub enum BindingResource<'a> { /// built using `build_acceleration_structures` a validation error is generated otherwise this is a part of the /// safety section of `build_acceleration_structures_unsafe_tlas` and so undefined behavior occurs. AccelerationStructure(&'a Tlas), + /// Binding is backed by an external texture. + /// + /// [`Features::EXTERNAL_TEXTURE`] must be supported to use this feature. + /// + /// Corresponds to [`wgt::BindingType::ExternalTexture`]. + ExternalTexture(&'a ExternalTexture), } #[cfg(send_sync)] static_assertions::assert_impl_all!(BindingResource<'_>: Send, Sync); diff --git a/wgpu/src/backend/webgpu.rs b/wgpu/src/backend/webgpu.rs index e2ceb57a6f6..3d918f24592 100644 --- a/wgpu/src/backend/webgpu.rs +++ b/wgpu/src/backend/webgpu.rs @@ -2017,6 +2017,9 @@ impl dispatch::DeviceInterface for WebDevice { crate::BindingResource::AccelerationStructure(_) => { unimplemented!("Raytracing not implemented for web") } + crate::BindingResource::ExternalTexture(_) => { + unimplemented!("ExternalTexture not implemented for web") + } }; webgpu_sys::GpuBindGroupEntry::new(binding.binding, &mapped_resource) diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index 245aa5911e7..0a5648227c0 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -1190,6 +1190,9 @@ impl dispatch::DeviceInterface for CoreDevice { acceleration_structure.inner.as_core().id, ) } + BindingResource::ExternalTexture(external_texture) => { + bm::BindingResource::ExternalTexture(external_texture.inner.as_core().id) + } }, }) .collect::>(); From f8756a6e1bcaf3e06eb84d652d31574a62b524c7 Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Mon, 2 Jun 2025 10:31:47 +0100 Subject: [PATCH 059/303] [wgpu] Add external texture validation tests Adds validation tests using the noop backend covering creation of external textures, and creation of bind groups containing external textures. --- .../wgpu-validation/api/external_texture.rs | 495 ++++++++++++++++++ wgpu-core/src/device/resource.rs | 16 +- 2 files changed, 501 insertions(+), 10 deletions(-) diff --git a/tests/tests/wgpu-validation/api/external_texture.rs b/tests/tests/wgpu-validation/api/external_texture.rs index ece0e060f4f..b3dcffb93f8 100644 --- a/tests/tests/wgpu-validation/api/external_texture.rs +++ b/tests/tests/wgpu-validation/api/external_texture.rs @@ -1,6 +1,365 @@ use wgpu::*; use wgpu_test::{fail, valid}; +/// Ensures an [`ExternalTexture`] can be created from a valid descriptor and planes, +/// but appropriate errors are returned for invalid descriptors and planes. +#[test] +fn create_external_texture() { + let (device, _queue) = wgpu::Device::noop(&DeviceDescriptor { + required_features: Features::EXTERNAL_TEXTURE, + ..Default::default() + }); + + let texture_descriptor = TextureDescriptor { + label: None, + size: Extent3d { + width: 512, + height: 512, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: TextureDimension::D2, + format: TextureFormat::Rgba8Unorm, + usage: TextureUsages::TEXTURE_BINDING, + view_formats: &[], + }; + + let r_texture = device.create_texture(&TextureDescriptor { + format: TextureFormat::R8Unorm, + ..texture_descriptor + }); + let r_view = r_texture.create_view(&TextureViewDescriptor::default()); + let rg_texture = device.create_texture(&TextureDescriptor { + format: TextureFormat::Rg8Unorm, + ..texture_descriptor + }); + let rg_view = rg_texture.create_view(&TextureViewDescriptor::default()); + let rgba_texture = device.create_texture(&TextureDescriptor { + format: TextureFormat::Rgba8Unorm, + ..texture_descriptor + }); + let rgba_view = rgba_texture.create_view(&TextureViewDescriptor::default()); + + let _ = valid(&device, || { + device.create_external_texture( + &ExternalTextureDescriptor { + format: ExternalTextureFormat::Rgba, + label: None, + width: r_texture.width(), + height: r_texture.height(), + yuv_conversion_matrix: [0.0; 16], + sample_transform: [0.0; 6], + load_transform: [0.0; 6], + }, + &[&rgba_view], + ) + }); + let _ = valid(&device, || { + device.create_external_texture( + &ExternalTextureDescriptor { + format: ExternalTextureFormat::Nv12, + label: None, + width: r_texture.width(), + height: r_texture.height(), + yuv_conversion_matrix: [0.0; 16], + sample_transform: [0.0; 6], + load_transform: [0.0; 6], + }, + &[&r_view, &rg_view], + ) + }); + let _ = valid(&device, || { + device.create_external_texture( + &ExternalTextureDescriptor { + format: ExternalTextureFormat::Yu12, + label: None, + width: r_texture.width(), + height: r_texture.height(), + yuv_conversion_matrix: [0.0; 16], + sample_transform: [0.0; 6], + load_transform: [0.0; 6], + }, + &[&r_view, &r_view, &r_view], + ) + }); + + // Wrong number of planes for format + let _ = fail( + &device, + || { + device.create_external_texture( + &ExternalTextureDescriptor { + format: ExternalTextureFormat::Rgba, + label: None, + width: r_texture.width(), + height: r_texture.height(), + yuv_conversion_matrix: [0.0; 16], + sample_transform: [0.0; 6], + load_transform: [0.0; 6], + }, + &[&r_view, &r_view], + ) + }, + Some("External texture format Rgba expects 1 planes, but given 2"), + ); + let _ = fail( + &device, + || { + device.create_external_texture( + &ExternalTextureDescriptor { + format: ExternalTextureFormat::Nv12, + label: None, + width: r_texture.width(), + height: r_texture.height(), + yuv_conversion_matrix: [0.0; 16], + sample_transform: [0.0; 6], + load_transform: [0.0; 6], + }, + &[&r_view], + ) + }, + Some("External texture format Nv12 expects 2 planes, but given 1"), + ); + let _ = fail( + &device, + || { + device.create_external_texture( + &ExternalTextureDescriptor { + format: ExternalTextureFormat::Yu12, + label: None, + width: r_texture.width(), + height: r_texture.height(), + yuv_conversion_matrix: [0.0; 16], + sample_transform: [0.0; 6], + load_transform: [0.0; 6], + }, + &[&r_view, &r_view], + ) + }, + Some("External texture format Yu12 expects 3 planes, but given 2"), + ); + + // Wrong plane formats + let _ = fail( + &device, + || { + device.create_external_texture( + &ExternalTextureDescriptor { + format: ExternalTextureFormat::Rgba, + label: None, + width: r_texture.width(), + height: r_texture.height(), + yuv_conversion_matrix: [0.0; 16], + sample_transform: [0.0; 6], + load_transform: [0.0; 6], + }, + &[&r_view], + ) + }, + Some("External texture format Rgba plane 0 expects format with 4 components but given view with format R8Unorm (1 components)"), + ); + let _ = fail( + &device, + || { + device.create_external_texture( + &ExternalTextureDescriptor { + format: ExternalTextureFormat::Nv12, + label: None, + width: r_texture.width(), + height: r_texture.height(), + yuv_conversion_matrix: [0.0; 16], + sample_transform: [0.0; 6], + load_transform: [0.0; 6], + }, + &[&r_view, &rgba_view], + ) + }, + Some("External texture format Nv12 plane 1 expects format with 2 components but given view with format Rgba8Unorm (4 components)"), + ); + let _ = fail( + &device, + || { + device.create_external_texture( + &ExternalTextureDescriptor { + format: ExternalTextureFormat::Yu12, + label: None, + width: r_texture.width(), + height: r_texture.height(), + yuv_conversion_matrix: [0.0; 16], + sample_transform: [0.0; 6], + load_transform: [0.0; 6], + }, + &[&r_view, &rg_view, &r_view], + ) + }, + Some("External texture format Yu12 plane 1 expects format with 1 components but given view with format Rg8Unorm (2 components)"), + ); + + // Wrong sample type + let uint_texture = device.create_texture(&TextureDescriptor { + format: TextureFormat::Rgba8Uint, + ..texture_descriptor + }); + let uint_view = uint_texture.create_view(&TextureViewDescriptor::default()); + let _ = fail( + &device, + || { + device.create_external_texture( + &ExternalTextureDescriptor { + format: ExternalTextureFormat::Rgba, + label: None, + width: uint_texture.width(), + height: uint_texture.height(), + yuv_conversion_matrix: [0.0; 16], + sample_transform: [0.0; 6], + load_transform: [0.0; 6], + }, + &[&uint_view], + ) + }, + Some("External texture planes expect a filterable float sample type, but given view with format Rgba8Uint (sample type Uint)"), + ); + + // Wrong texture dimension + let d3_texture = device.create_texture(&TextureDescriptor { + dimension: TextureDimension::D3, + ..texture_descriptor + }); + let d3_view = d3_texture.create_view(&TextureViewDescriptor::default()); + let _ = fail( + &device, + || { + device.create_external_texture( + &ExternalTextureDescriptor { + format: ExternalTextureFormat::Rgba, + label: None, + width: d3_texture.width(), + height: d3_texture.height(), + yuv_conversion_matrix: [0.0; 16], + sample_transform: [0.0; 6], + load_transform: [0.0; 6], + }, + &[&d3_view], + ) + }, + Some("External texture planes expect 2D dimension, but given view with dimension = D3"), + ); + + // Multisampled + let multisampled_texture = device.create_texture(&TextureDescriptor { + sample_count: 4, + usage: TextureUsages::RENDER_ATTACHMENT | TextureUsages::TEXTURE_BINDING, + ..texture_descriptor + }); + let multisampled_view = multisampled_texture.create_view(&TextureViewDescriptor::default()); + let _ = fail( + &device, + || { + device.create_external_texture( + &ExternalTextureDescriptor { + format: ExternalTextureFormat::Rgba, + label: None, + width: multisampled_texture.width(), + height: multisampled_texture.height(), + yuv_conversion_matrix: [0.0; 16], + sample_transform: [0.0; 6], + load_transform: [0.0; 6], + }, + &[&multisampled_view], + ) + }, + Some("External texture planes cannot be multisampled, but given view with samples = 4"), + ); + + // Missing TEXTURE_BINDING + let non_binding_texture = device.create_texture(&TextureDescriptor { + usage: TextureUsages::STORAGE_BINDING, + ..texture_descriptor + }); + let non_binding_view = non_binding_texture.create_view(&TextureViewDescriptor::default()); + let _ = fail( + &device, + || { + device.create_external_texture( + &ExternalTextureDescriptor { + format: ExternalTextureFormat::Rgba, + label: None, + width: non_binding_texture.width(), + height: non_binding_texture.height(), + yuv_conversion_matrix: [0.0; 16], + sample_transform: [0.0; 6], + load_transform: [0.0; 6], + }, + &[&non_binding_view], + ) + }, + Some("Usage flags TextureUsages(STORAGE_BINDING) of TextureView with '' label do not contain required usage flags TextureUsages(TEXTURE_BINDING)"), + ); +} + +/// Ensures an [`ExternalTexture`] can be bound to a [`BindingType::ExternalTexture`] +/// resource binding. +#[test] +fn external_texture_binding() { + let (device, _queue) = wgpu::Device::noop(&DeviceDescriptor { + required_features: Features::EXTERNAL_TEXTURE, + ..Default::default() + }); + + let bgl = valid(&device, || { + device.create_bind_group_layout(&BindGroupLayoutDescriptor { + label: None, + entries: &[BindGroupLayoutEntry { + binding: 0, + visibility: ShaderStages::FRAGMENT, + ty: BindingType::ExternalTexture, + count: None, + }], + }) + }); + + let texture_descriptor = TextureDescriptor { + label: None, + size: Extent3d { + width: 256, + height: 256, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: TextureDimension::D2, + format: TextureFormat::Rgba8Unorm, + usage: TextureUsages::TEXTURE_BINDING, + view_formats: &[], + }; + let external_texture_descriptor = ExternalTextureDescriptor { + label: None, + width: texture_descriptor.size.width, + height: texture_descriptor.size.height, + format: ExternalTextureFormat::Rgba, + yuv_conversion_matrix: [0.0; 16], + sample_transform: [0.0; 6], + load_transform: [0.0; 6], + }; + + valid(&device, || { + let texture = device.create_texture(&texture_descriptor); + let view = texture.create_view(&TextureViewDescriptor::default()); + let external_texture = + device.create_external_texture(&external_texture_descriptor, &[&view]); + + device.create_bind_group(&BindGroupDescriptor { + label: None, + layout: &bgl, + entries: &[BindGroupEntry { + binding: 0, + resource: BindingResource::ExternalTexture(&external_texture), + }], + }) + }); +} + /// Ensures a [`TextureView`] can be bound to a [`BindingType::ExternalTexture`] /// resource binding. #[test] @@ -160,3 +519,139 @@ fn external_texture_binding_texture_view() { Some("Texture binding 0 expects multisampled = false, but given a view with samples = 4"), ); } + +/// Ensures that submitting a command buffer referencing an external texture, any of +/// whose plane textures have already been destroyed, results in an error. +#[test] +fn destroyed_external_texture_plane() { + let (device, queue) = wgpu::Device::noop(&DeviceDescriptor { + required_features: Features::EXTERNAL_TEXTURE, + ..Default::default() + }); + + let target_texture = device.create_texture(&TextureDescriptor { + label: None, + size: Extent3d { + width: 512, + height: 512, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: TextureDimension::D2, + format: TextureFormat::Rgba8Unorm, + usage: TextureUsages::RENDER_ATTACHMENT, + view_formats: &[], + }); + let target_view = target_texture.create_view(&TextureViewDescriptor::default()); + + let plane_texture = device.create_texture(&TextureDescriptor { + label: Some("External texture plane"), + size: Extent3d { + width: 512, + height: 512, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: TextureDimension::D2, + format: TextureFormat::Rgba8Unorm, + usage: TextureUsages::TEXTURE_BINDING, + view_formats: &[], + }); + let plane_view = plane_texture.create_view(&TextureViewDescriptor::default()); + + let external_texture = device.create_external_texture( + &ExternalTextureDescriptor { + format: ExternalTextureFormat::Rgba, + label: None, + width: plane_texture.width(), + height: plane_texture.height(), + yuv_conversion_matrix: [0.0; 16], + sample_transform: [0.0; 6], + load_transform: [0.0; 6], + }, + &[&plane_view], + ); + + let module = device.create_shader_module(ShaderModuleDescriptor { + label: None, + source: ShaderSource::Wgsl(std::borrow::Cow::Borrowed( + " +@group(0) @binding(0) +var tex: texture_external; +@vertex fn vert_main() -> @builtin(position) vec4 { return vec4(0); } +@fragment fn frag_main() -> @location(0) vec4 { return textureLoad(tex, vec2(0)); }", + )), + }); + + let pipeline = device.create_render_pipeline(&RenderPipelineDescriptor { + label: None, + layout: None, + vertex: VertexState { + module: &module, + entry_point: None, + compilation_options: PipelineCompilationOptions::default(), + buffers: &[], + }, + primitive: PrimitiveState::default(), + depth_stencil: None, + multisample: MultisampleState::default(), + fragment: Some(FragmentState { + module: &module, + entry_point: None, + compilation_options: PipelineCompilationOptions::default(), + targets: &[Some(ColorTargetState { + format: target_texture.format(), + blend: None, + write_mask: ColorWrites::ALL, + })], + }), + multiview: None, + cache: None, + }); + + let bind_group = device.create_bind_group(&BindGroupDescriptor { + label: None, + layout: &pipeline.get_bind_group_layout(0), + entries: &[BindGroupEntry { + binding: 0, + resource: BindingResource::ExternalTexture(&external_texture), + }], + }); + + let mut encoder = device.create_command_encoder(&CommandEncoderDescriptor { label: None }); + let mut pass = encoder.begin_render_pass(&RenderPassDescriptor { + label: None, + color_attachments: &[Some(RenderPassColorAttachment { + view: &target_view, + depth_slice: None, + resolve_target: None, + ops: Operations { + load: LoadOp::Clear(Color { + r: 0.0, + g: 0.0, + b: 0.0, + a: 1.0, + }), + store: StoreOp::Store, + }, + })], + depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, + }); + + pass.set_pipeline(&pipeline); + pass.set_bind_group(0, &bind_group, &[]); + pass.draw(0..0, 0..0); + drop(pass); + + plane_texture.destroy(); + + fail( + &device, + || queue.submit([encoder.finish()]), + Some("Texture with 'External texture plane' label has been destroyed"), + ); +} diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index b653186e25b..3156769440d 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -2665,11 +2665,7 @@ impl Device { used.buffers .insert_single(external_texture.params.clone(), wgt::BufferUses::UNIFORM); - let params = hal::BufferBinding { - buffer: external_texture.params.try_raw(snatch_guard)?, - offset: 0, - size: wgt::BufferSize::new(external_texture.params.size), - }; + let params = external_texture.params.binding(0, None, snatch_guard)?.0; Ok(hal::ExternalTextureBinding { planes, params }) } @@ -2718,11 +2714,11 @@ impl Device { usage: internal_use, }, ]; - let params = hal::BufferBinding { - buffer: self.default_external_texture_params_buffer.as_ref(), - offset: 0, - size: None, - }; + let params = hal::BufferBinding::new_unchecked( + self.default_external_texture_params_buffer.as_ref(), + 0, + None, + ); Ok(hal::ExternalTextureBinding { planes, params }) } From ffd59691e093c257b10531e0a139418b1c700c25 Mon Sep 17 00:00:00 2001 From: Lucas Abel <22837557+uael@users.noreply.github.com> Date: Wed, 23 Jul 2025 17:32:38 +0200 Subject: [PATCH 060/303] [webgpu] fix device loss callback to be immediately drop (#7992) --- wgpu/src/backend/webgpu.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/wgpu/src/backend/webgpu.rs b/wgpu/src/backend/webgpu.rs index 3d918f24592..36ee0b55414 100644 --- a/wgpu/src/backend/webgpu.rs +++ b/wgpu/src/backend/webgpu.rs @@ -2391,6 +2391,9 @@ impl dispatch::DeviceInterface for WebDevice { ); }); let _ = self.inner.lost().then(&closure); + // Release memory management of this closure from Rust to the JS GC. + // TODO: This will leak if weak references is not supported. + closure.forget(); } fn on_uncaptured_error(&self, handler: Box) { @@ -2400,7 +2403,8 @@ impl dispatch::DeviceInterface for WebDevice { }) as Box); self.inner .set_onuncapturederror(Some(f.as_ref().unchecked_ref())); - // TODO: This will leak the memory associated with the error handler by default. + // Release memory management of this closure from Rust to the JS GC. + // TODO: This will leak if weak references is not supported. f.forget(); } From 1c43ac2c42bba8528d985b9992342045a6a7180e Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 23 Jul 2025 08:39:42 -0700 Subject: [PATCH 061/303] Additional validation of buffer-texture copies (#7948) * Additional validation of buffer-texture copies Fixes #7936, but leaves a TODO for #7947 * Skip tests failing on dx12 * Update comments and change unwrap_or to expect --- cts_runner/test.lst | 22 +++++++ wgpu-core/src/command/transfer.rs | 95 ++++++++++++++++++++++++++----- wgpu-core/src/conv.rs | 3 + wgpu-core/src/device/queue.rs | 18 +++--- wgpu-types/src/lib.rs | 2 + 5 files changed, 119 insertions(+), 21 deletions(-) diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 21eb6b448b2..3bac66e8481 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -34,6 +34,28 @@ webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bind_grou webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:buffer_binding,render_pipeline:* webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:sampler_binding,render_pipeline:* webgpu:api,validation,encoding,queries,general:occlusion_query,query_index:* +webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_usage_and_aspect:* +webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_buffer_size:* +fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_buffer_offset:format="depth32float";aspect="depth-only";copyType="CopyT2B" +fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_buffer_offset:format="depth24plus-stencil8";aspect="stencil-only";copyType="CopyB2T" +fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_buffer_offset:format="depth24plus-stencil8";aspect="stencil-only";copyType="CopyT2B" +//mix of PASS and FAIL: other subtests of copy_buffer_offset. Related bugs: +// https://github.com/gfx-rs/wgpu/issues/7946, https://github.com/gfx-rs/wgpu/issues/7947 +webgpu:api,validation,image_copy,buffer_texture_copies:sample_count:* +webgpu:api,validation,image_copy,buffer_texture_copies:texture_buffer_usages:* +webgpu:api,validation,image_copy,buffer_texture_copies:device_mismatch:* +fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="rgba8unorm";copyType="CopyB2T";dimension="2d" +fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="rgba8unorm";copyType="CopyT2B";dimension="2d" +fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="rgba8unorm";copyType="CopyB2T";dimension="3d" +fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="rgba8unorm";copyType="CopyT2B";dimension="3d" +fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="bgra8unorm";copyType="CopyB2T";dimension="2d" +fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="bgra8unorm";copyType="CopyT2B";dimension="2d" +fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="astc-4x4-unorm";copyType="CopyT2B";dimension="2d" +fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="astc-4x4-unorm";copyType="CopyB2T";dimension="2d" +fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="astc-4x4-unorm";copyType="CopyT2B";dimension="3d" +fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="astc-4x4-unorm";copyType="CopyB2T";dimension="3d" +//mix of PASS and FAIL: other subtests of offset_and_bytesPerRow. Related bugs: +// https://github.com/gfx-rs/wgpu/issues/7946, https://github.com/gfx-rs/wgpu/issues/7947 webgpu:api,validation,image_copy,layout_related:copy_end_overflows_u64:* webgpu:api,validation,image_copy,texture_related:format:dimension="1d";* webgpu:api,validation,queue,submit:command_buffer,device_mismatch:* diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 4d6c8d98ca4..56816fa87f4 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -363,6 +363,70 @@ pub(crate) fn validate_linear_texture_data( Ok((bytes_in_copy, image_stride_bytes)) } +/// Validation for texture/buffer copies. +/// +/// This implements the following checks from WebGPU's [validating texture buffer copy][vtbc] +/// algorithm: +/// * The texture must not be multisampled. +/// * The copy must be from/to a single aspect of the texture. +/// * If `aligned` is true, the buffer offset must be aligned appropriately. +/// +/// The following steps in the algorithm are implemented elsewhere: +/// * Invocation of other validation algorithms. +/// * The texture usage (COPY_DST / COPY_SRC) check. +/// * The check for non-copyable depth/stencil formats. The caller must perform +/// this check using `is_valid_copy_src_format` / `is_valid_copy_dst_format` +/// before calling this function. This function will panic if +/// [`wgt::TextureFormat::block_copy_size`] returns `None` due to a +/// non-copyable format. +/// +/// [vtbc]: https://gpuweb.github.io/gpuweb/#abstract-opdef-validating-texture-buffer-copy +pub(crate) fn validate_texture_buffer_copy( + texture_copy_view: &wgt::TexelCopyTextureInfo, + aspect: hal::FormatAspects, + desc: &wgt::TextureDescriptor<(), Vec>, + offset: BufferAddress, + aligned: bool, +) -> Result<(), TransferError> { + if desc.sample_count != 1 { + return Err(TransferError::InvalidSampleCount { + sample_count: desc.sample_count, + }); + } + + if !aspect.is_one() { + return Err(TransferError::CopyAspectNotOne); + } + + let mut offset_alignment = if desc.format.is_depth_stencil_format() { + 4 + } else { + // The case where `block_copy_size` returns `None` is currently + // unreachable both for the reason in the expect message, and also + // because the currently-defined non-copyable formats are depth/stencil + // formats so would take the `if` branch. + desc.format + .block_copy_size(Some(texture_copy_view.aspect)) + .expect("non-copyable formats should have been rejected previously") + }; + + // TODO(https://github.com/gfx-rs/wgpu/issues/7947): This does not match the spec. + // The spec imposes no alignment requirement if `!aligned`, and otherwise + // imposes only the `offset_alignment` as calculated above. wgpu currently + // can panic on alignments <4B, so we reject them here to avoid a panic. + if aligned { + offset_alignment = offset_alignment.max(4); + } else { + offset_alignment = 4; + } + + if offset % u64::from(offset_alignment) != 0 { + return Err(TransferError::UnalignedBufferOffset(offset)); + } + + Ok(()) +} + /// Validate the extent and alignment of a texture copy. /// /// Copied with minor modifications from WebGPU standard. This mostly follows @@ -884,10 +948,6 @@ impl Global { .map(|pending| pending.into_hal(dst_raw)) .collect::>(); - if !dst_base.aspect.is_one() { - return Err(TransferError::CopyAspectNotOne.into()); - } - if !conv::is_valid_copy_dst_texture_format(dst_texture.desc.format, destination.aspect) { return Err(TransferError::CopyToForbiddenTextureFormat { @@ -897,6 +957,14 @@ impl Global { .into()); } + validate_texture_buffer_copy( + destination, + dst_base.aspect, + &dst_texture.desc, + source.layout.offset, + true, // alignment required for buffer offset + )?; + let (required_buffer_bytes_in_copy, bytes_per_array_layer) = validate_linear_texture_data( &source.layout, @@ -999,12 +1067,7 @@ impl Global { src_texture .check_usage(TextureUsages::COPY_SRC) .map_err(TransferError::MissingTextureUsage)?; - if src_texture.desc.sample_count != 1 { - return Err(TransferError::InvalidSampleCount { - sample_count: src_texture.desc.sample_count, - } - .into()); - } + if source.mip_level >= src_texture.desc.mip_level_count { return Err(TransferError::InvalidMipLevel { requested: source.mip_level, @@ -1013,10 +1076,6 @@ impl Global { .into()); } - if !src_base.aspect.is_one() { - return Err(TransferError::CopyAspectNotOne.into()); - } - if !conv::is_valid_copy_src_texture_format(src_texture.desc.format, source.aspect) { return Err(TransferError::CopyFromForbiddenTextureFormat { format: src_texture.desc.format, @@ -1025,6 +1084,14 @@ impl Global { .into()); } + validate_texture_buffer_copy( + source, + src_base.aspect, + &src_texture.desc, + destination.layout.offset, + true, // alignment required for buffer offset + )?; + let (required_buffer_bytes_in_copy, bytes_per_array_layer) = validate_linear_texture_data( &destination.layout, diff --git a/wgpu-core/src/conv.rs b/wgpu-core/src/conv.rs index 5a5a27279bb..aa6ceb046d1 100644 --- a/wgpu-core/src/conv.rs +++ b/wgpu-core/src/conv.rs @@ -2,6 +2,9 @@ use wgt::TextureFormatFeatures; use crate::resource::{self, TextureDescriptor}; +// Some core-only texture format helpers. The helper methods on `TextureFormat` +// defined in wgpu-types may need to be modified along with the ones here. + pub fn is_valid_copy_src_texture_format( format: wgt::TextureFormat, aspect: wgt::TextureAspect, diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 6b4c1478b94..8a51e60a45b 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -19,9 +19,9 @@ use crate::device::trace::Action; use crate::{ api_log, command::{ - extract_texture_selector, validate_linear_texture_data, validate_texture_copy_range, - ClearError, CommandAllocator, CommandBuffer, CommandEncoder, CommandEncoderError, CopySide, - TexelCopyTextureInfo, TransferError, + extract_texture_selector, validate_linear_texture_data, validate_texture_buffer_copy, + validate_texture_copy_range, ClearError, CommandAllocator, CommandBuffer, CommandEncoder, + CommandEncoderError, CopySide, TexelCopyTextureInfo, TransferError, }, conv, device::{DeviceError, WaitIdleError}, @@ -737,10 +737,6 @@ impl Queue { let (selector, dst_base) = extract_texture_selector(&destination, size, &dst)?; - if !dst_base.aspect.is_one() { - return Err(TransferError::CopyAspectNotOne.into()); - } - if !conv::is_valid_copy_dst_texture_format(dst.desc.format, destination.aspect) { return Err(TransferError::CopyToForbiddenTextureFormat { format: dst.desc.format, @@ -749,6 +745,14 @@ impl Queue { .into()); } + validate_texture_buffer_copy( + &destination, + dst_base.aspect, + &dst.desc, + data_layout.offset, + false, // alignment not required for buffer offset + )?; + // Note: `_source_bytes_per_array_layer` is ignored since we // have a staging copy, and it can have a different value. let (required_bytes_in_copy, _source_bytes_per_array_layer) = validate_linear_texture_data( diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 256e5fa4579..6b51d50464a 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -2608,6 +2608,8 @@ impl TextureAspect { } } +// There are some additional texture format helpers in `wgpu-core/src/conv.rs`, +// that may need to be modified along with the ones here. impl TextureFormat { /// Returns the aspect-specific format of the original format /// From d9a6b4fa4a6051ccf169b7ab92ecf0db739b7903 Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Tue, 22 Jul 2025 15:07:01 -0700 Subject: [PATCH 062/303] [naga, wgpu-core] Add some docs for Naga validator creation. --- naga/src/valid/mod.rs | 14 +++++++++++++- wgpu-core/src/device/mod.rs | 14 +++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/naga/src/valid/mod.rs b/naga/src/valid/mod.rs index 6b4b514c6cf..fe45d3bfb07 100644 --- a/naga/src/valid/mod.rs +++ b/naga/src/valid/mod.rs @@ -459,7 +459,19 @@ impl crate::TypeInner { } impl Validator { - /// Construct a new validator instance. + /// Create a validator for Naga [`Module`]s. + /// + /// The `flags` argument indicates which stages of validation the + /// returned `Validator` should perform. Skipping stages can make + /// validation somewhat faster, but the validator may not reject some + /// invalid modules. Regardless of `flags`, validation always returns + /// a usable [`ModuleInfo`] value on success. + /// + /// If `flags` contains everything in `ValidationFlags::default()`, + /// then the returned Naga [`Validator`] will reject any [`Module`] + /// that would use capabilities not included in `capabilities`. + /// + /// [`Module`]: crate::Module pub fn new(flags: ValidationFlags, capabilities: Capabilities) -> Self { let subgroup_operations = if capabilities.contains(Capabilities::SUBGROUP) { use SubgroupOperationSet as S; diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index a57714900bc..0780e7ccffb 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -383,7 +383,19 @@ impl WebGpuError for MissingDownlevelFlags { } } -/// Create a validator with the given validation flags. +/// Create a validator for Naga [`Module`]s. +/// +/// Create a Naga [`Validator`] that ensures that each [`naga::Module`] +/// presented to it is valid, and uses no features not included in +/// `features` and `downlevel`. +/// +/// The validator can only catch invalid modules and feature misuse +/// reliably when the `flags` argument includes all the flags in +/// [`ValidationFlags::default()`]. +/// +/// [`Validator`]: naga::valid::Validator +/// [`Module`]: naga::Module +/// [`ValidationFlags::default()`]: naga::valid::ValidationFlags::default pub fn create_validator( features: wgt::Features, downlevel: wgt::DownlevelFlags, From b8c462ac3128bbe32cce5485aae42953a6ef94d4 Mon Sep 17 00:00:00 2001 From: Lucas Abel <22837557+uael@users.noreply.github.com> Date: Wed, 23 Jul 2025 18:06:42 +0200 Subject: [PATCH 063/303] [core] fix missing applies of `DISCARD_HAL_LABELS` (#7991) --- wgpu-core/src/command/clear.rs | 13 +++++++-- wgpu-core/src/command/compute.rs | 5 +++- wgpu-core/src/command/memory_init.rs | 2 ++ wgpu-core/src/command/mod.rs | 2 +- wgpu-core/src/command/render.rs | 12 ++++++-- wgpu-core/src/command/transfer.rs | 1 + wgpu-core/src/device/queue.rs | 29 ++++++++++++++++---- wgpu-core/src/device/ray_tracing.rs | 3 +- wgpu-core/src/instance.rs | 2 +- wgpu-core/src/lib.rs | 2 +- wgpu-core/src/present.rs | 5 +++- wgpu-core/src/resource.rs | 3 +- wgpu-core/src/scratch.rs | 4 +-- wgpu-core/src/timestamp_normalization/mod.rs | 13 +++++++-- 14 files changed, 73 insertions(+), 23 deletions(-) diff --git a/wgpu-core/src/command/clear.rs b/wgpu-core/src/command/clear.rs index 48896ffa053..593382aa931 100644 --- a/wgpu-core/src/command/clear.rs +++ b/wgpu-core/src/command/clear.rs @@ -9,6 +9,7 @@ use crate::{ device::{DeviceError, MissingFeatures}, get_lowest_common_denom, global::Global, + hal_label, id::{BufferId, CommandEncoderId, TextureId}, init_tracker::{MemoryInitKind, TextureInitRange}, resource::{ @@ -272,6 +273,7 @@ impl Global { &device.alignments, device.zero_buffer.as_ref(), &snatch_guard, + device.instance_flags, )?; Ok(()) @@ -287,6 +289,7 @@ pub(crate) fn clear_texture( alignments: &hal::Alignments, zero_buffer: &dyn hal::DynBuffer, snatch_guard: &SnatchGuard<'_>, + instance_flags: wgt::InstanceFlags, ) -> Result<(), ClearError> { let dst_raw = dst_texture.try_raw(snatch_guard)?; @@ -345,11 +348,11 @@ pub(crate) fn clear_texture( ), TextureClearMode::Surface { .. } => { drop(clear_mode); - clear_texture_via_render_passes(dst_texture, range, true, encoder)? + clear_texture_via_render_passes(dst_texture, range, true, encoder, instance_flags)? } TextureClearMode::RenderPass { is_color, .. } => { drop(clear_mode); - clear_texture_via_render_passes(dst_texture, range, is_color, encoder)? + clear_texture_via_render_passes(dst_texture, range, is_color, encoder, instance_flags)? } TextureClearMode::None => { return Err(ClearError::NoValidTextureClearMode( @@ -459,6 +462,7 @@ fn clear_texture_via_render_passes( range: TextureInitRange, is_color: bool, encoder: &mut dyn hal::DynCommandEncoder, + instance_flags: wgt::InstanceFlags, ) -> Result<(), ClearError> { assert_eq!(dst_texture.desc.dimension, wgt::TextureDimension::D2); @@ -513,7 +517,10 @@ fn clear_texture_via_render_passes( unsafe { encoder .begin_render_pass(&hal::RenderPassDescriptor { - label: Some("(wgpu internal) clear_texture clear pass"), + label: hal_label( + Some("(wgpu internal) clear_texture clear pass"), + instance_flags, + ), extent, sample_count: dst_texture.desc.sample_count, color_attachments, diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index 16b556c7b95..3d26d60ea79 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -756,7 +756,10 @@ impl Global { // // Use that buffer to insert barriers and clear discarded images. let transit = encoder - .open_pass(Some("(wgpu internal) Pre Pass")) + .open_pass(hal_label( + Some("(wgpu internal) Pre Pass"), + self.instance.flags, + )) .map_pass_err(pass_scope)?; fixup_discarded_surfaces( pending_discard_init_fixups.into_iter(), diff --git a/wgpu-core/src/command/memory_init.rs b/wgpu-core/src/command/memory_init.rs index 5ad9c7624b6..9057e637256 100644 --- a/wgpu-core/src/command/memory_init.rs +++ b/wgpu-core/src/command/memory_init.rs @@ -149,6 +149,7 @@ pub(crate) fn fixup_discarded_surfaces Result<&mut dyn hal::DynCommandEncoder, DeviceError> { if !self.is_open { self.is_open = true; - let hal_label = hal_label(Some(&self.label), self.device.instance_flags); + let hal_label = hal_label(Some(self.label.as_str()), self.device.instance_flags); unsafe { self.raw.begin_encoding(hal_label) } .map_err(|e| self.device.handle_hal_error(e))?; } diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 52e938063b9..aef81bc4a07 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1457,6 +1457,7 @@ impl RenderPassInfo { raw: &mut dyn hal::DynCommandEncoder, snatch_guard: &SnatchGuard, scope: &mut UsageScope<'_>, + instance_flags: wgt::InstanceFlags, ) -> Result<(), RenderPassErrorInner> { profiling::scope!("RenderPassInfo::finish"); unsafe { @@ -1497,7 +1498,10 @@ impl RenderPassInfo { ) }; let desc = hal::RenderPassDescriptor::<'_, _, dyn hal::DynTextureView> { - label: Some("(wgpu internal) Zero init discarded depth/stencil aspect"), + label: hal_label( + Some("(wgpu internal) Zero init discarded depth/stencil aspect"), + instance_flags, + ), extent: view.render_extent.unwrap(), sample_count: view.samples, color_attachments: &[], @@ -2201,6 +2205,7 @@ impl Global { state.general.raw_encoder, state.general.snatch_guard, &mut state.general.scope, + self.instance.flags, ) .map_pass_err(pass_scope)?; @@ -2217,7 +2222,10 @@ impl Global { { let transit = encoder - .open_pass(Some("(wgpu internal) Pre Pass")) + .open_pass(hal_label( + Some("(wgpu internal) Pre Pass"), + self.instance.flags, + )) .map_pass_err(pass_scope)?; fixup_discarded_surfaces( diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 56816fa87f4..fb9e4535fbf 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -618,6 +618,7 @@ fn handle_texture_init( &device.alignments, device.zero_buffer.as_ref(), snatch_guard, + device.instance_flags, )?; } } diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 8a51e60a45b..d946ec35a0b 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -27,6 +27,7 @@ use crate::{ device::{DeviceError, WaitIdleError}, get_lowest_common_denom, global::Global, + hal_label, id::{self, BlasId, QueueId}, init_tracker::{has_copy_partial_init_tracker_coverage, TextureInitRange}, lock::{rank, Mutex, MutexGuard, RwLock, RwLockWriteGuard}, @@ -57,6 +58,7 @@ impl Queue { pub(crate) fn new( device: Arc, raw: Box, + instance_flags: wgt::InstanceFlags, ) -> Result { let pending_encoder = device .command_allocator @@ -70,7 +72,7 @@ impl Queue { } }; - let mut pending_writes = PendingWrites::new(pending_encoder); + let mut pending_writes = PendingWrites::new(pending_encoder, instance_flags); let zero_buffer = device.zero_buffer.as_ref(); pending_writes.activate(); @@ -328,10 +330,14 @@ pub(crate) struct PendingWrites { dst_buffers: FastHashMap>, dst_textures: FastHashMap>, copied_blas_s: FastHashMap>, + instance_flags: wgt::InstanceFlags, } impl PendingWrites { - pub fn new(command_encoder: Box) -> Self { + pub fn new( + command_encoder: Box, + instance_flags: wgt::InstanceFlags, + ) -> Self { Self { command_encoder, is_recording: false, @@ -339,6 +345,7 @@ impl PendingWrites { dst_buffers: FastHashMap::default(), dst_textures: FastHashMap::default(), copied_blas_s: FastHashMap::default(), + instance_flags, } } @@ -423,7 +430,10 @@ impl PendingWrites { if !self.is_recording { unsafe { self.command_encoder - .begin_encoding(Some("(wgpu internal) PendingWrites")) + .begin_encoding(hal_label( + Some("(wgpu internal) PendingWrites"), + self.instance_flags, + )) .unwrap(); } self.is_recording = true; @@ -816,6 +826,7 @@ impl Queue { &self.device.alignments, self.device.zero_buffer.as_ref(), &snatch_guard, + self.device.instance_flags, ) .map_err(QueueWriteError::from)?; } @@ -1068,6 +1079,7 @@ impl Queue { &self.device.alignments, self.device.zero_buffer.as_ref(), &self.device.snatchable_lock.read(), + self.device.instance_flags, ) .map_err(QueueWriteError::from)?; } @@ -1221,7 +1233,10 @@ impl Queue { }; // execute resource transitions - if let Err(e) = baked.encoder.open_pass(Some("(wgpu internal) Transit")) { + if let Err(e) = baked.encoder.open_pass(hal_label( + Some("(wgpu internal) Transit"), + self.device.instance_flags, + )) { break 'error Err(e.into()); } @@ -1256,8 +1271,10 @@ impl Queue { // Note: we could technically do it after all of the command buffers, // but here we have a command encoder by hand, so it's easier to use it. if !used_surface_textures.is_empty() { - if let Err(e) = baked.encoder.open_pass(Some("(wgpu internal) Present")) - { + if let Err(e) = baked.encoder.open_pass(hal_label( + Some("(wgpu internal) Present"), + self.device.instance_flags, + )) { break 'error Err(e.into()); } let texture_barriers = trackers diff --git a/wgpu-core/src/device/ray_tracing.rs b/wgpu-core/src/device/ray_tracing.rs index 1daecf61907..b44a8719d3f 100644 --- a/wgpu-core/src/device/ray_tracing.rs +++ b/wgpu-core/src/device/ray_tracing.rs @@ -8,6 +8,7 @@ use crate::{ api_log, device::Device, global::Global, + hal_label, id::{self, BlasId, TlasId}, lock::RwLock, lock::{rank, Mutex}, @@ -231,7 +232,7 @@ impl Device { self.alignments.raw_tlas_instance_size * desc.max_instances.max(1) as usize; let instance_buffer = unsafe { self.raw().create_buffer(&hal::BufferDescriptor { - label: Some("(wgpu-core) instances_buffer"), + label: hal_label(Some("(wgpu-core) instances_buffer"), self.instance_flags), size: instance_buffer_size as u64, usage: wgt::BufferUses::COPY_DST | wgt::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index cf7629e40fa..99f967f033b 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -776,7 +776,7 @@ impl Adapter { let device = Device::new(hal_device.device, self, desc, instance_flags)?; let device = Arc::new(device); - let queue = Queue::new(device.clone(), hal_device.queue)?; + let queue = Queue::new(device.clone(), hal_device.queue, instance_flags)?; let queue = Arc::new(queue); device.set_queue(&queue); diff --git a/wgpu-core/src/lib.rs b/wgpu-core/src/lib.rs index a22e218d4d3..d5bd7e48432 100644 --- a/wgpu-core/src/lib.rs +++ b/wgpu-core/src/lib.rs @@ -141,7 +141,7 @@ impl<'a> LabelHelpers<'a> for Label<'a> { } } -pub fn hal_label(opt: Option<&str>, flags: wgt::InstanceFlags) -> Option<&str> { +pub fn hal_label>(opt: Option, flags: wgt::InstanceFlags) -> Option { if flags.contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) { return None; } diff --git a/wgpu-core/src/present.rs b/wgpu-core/src/present.rs index 743d784f786..4ad9a4c0f0b 100644 --- a/wgpu-core/src/present.rs +++ b/wgpu-core/src/present.rs @@ -177,7 +177,10 @@ impl Surface { drop(fence); let texture_desc = wgt::TextureDescriptor { - label: Some(alloc::borrow::Cow::Borrowed("")), + label: hal_label( + Some(alloc::borrow::Cow::Borrowed("")), + device.instance_flags, + ), size: wgt::Extent3d { width: config.width, height: config.height, diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index e9768798a78..6fe4d794bd3 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -22,6 +22,7 @@ use crate::{ queue, resource::DeferredDestroy, BufferMapPendingClosure, Device, DeviceError, DeviceMismatch, HostMap, MissingDownlevelFlags, MissingFeatures, }, + hal_label, init_tracker::{BufferInitTracker, TextureInitTracker}, lock::{rank, Mutex, RwLock}, ray_tracing::{BlasCompactReadyPendingClosure, BlasPrepareCompactError}, @@ -1017,7 +1018,7 @@ impl StagingBuffer { pub(crate) fn new(device: &Arc, size: wgt::BufferSize) -> Result { profiling::scope!("StagingBuffer::new"); let stage_desc = hal::BufferDescriptor { - label: crate::hal_label(Some("(wgpu internal) Staging"), device.instance_flags), + label: hal_label(Some("(wgpu internal) Staging"), device.instance_flags), size: size.get(), usage: wgt::BufferUses::MAP_WRITE | wgt::BufferUses::COPY_SRC, memory_flags: hal::MemoryFlags::TRANSIENT, diff --git a/wgpu-core/src/scratch.rs b/wgpu-core/src/scratch.rs index be12c7c4c13..797f9db1483 100644 --- a/wgpu-core/src/scratch.rs +++ b/wgpu-core/src/scratch.rs @@ -4,7 +4,7 @@ use core::mem::ManuallyDrop; use wgt::BufferUses; use crate::device::{Device, DeviceError}; -use crate::resource_log; +use crate::{hal_label, resource_log}; #[derive(Debug)] pub struct ScratchBuffer { @@ -18,7 +18,7 @@ impl ScratchBuffer { device .raw() .create_buffer(&hal::BufferDescriptor { - label: Some("(wgpu) scratch buffer"), + label: hal_label(Some("(wgpu) scratch buffer"), device.instance_flags), size: size.get(), usage: BufferUses::ACCELERATION_STRUCTURE_SCRATCH, memory_flags: hal::MemoryFlags::empty(), diff --git a/wgpu-core/src/timestamp_normalization/mod.rs b/wgpu-core/src/timestamp_normalization/mod.rs index dd9272069b5..eebf82bef7b 100644 --- a/wgpu-core/src/timestamp_normalization/mod.rs +++ b/wgpu-core/src/timestamp_normalization/mod.rs @@ -36,6 +36,7 @@ use wgt::PushConstantRange; use crate::{ device::{Device, DeviceError}, + hal_label, pipeline::{CreateComputePipelineError, CreateShaderModuleError}, resource::Buffer, snatch::SnatchGuard, @@ -112,7 +113,10 @@ impl TimestampNormalizer { let temporary_bind_group_layout = device .raw() .create_bind_group_layout(&hal::BindGroupLayoutDescriptor { - label: Some("Timestamp Normalization Bind Group Layout"), + label: hal_label( + Some("Timestamp Normalization Bind Group Layout"), + device.instance_flags, + ), flags: hal::BindGroupLayoutFlags::empty(), entries: &[wgt::BindGroupLayoutEntry { binding: 0, @@ -283,7 +287,7 @@ impl TimestampNormalizer { let bg = device .raw() .create_bind_group(&hal::BindGroupDescriptor { - label: Some(label), + label: hal_label(Some(label), device.instance_flags), layout: &*state.temporary_bind_group_layout, buffers: &[hal::BufferBinding::new_unchecked(buffer, 0, buffer_size)], samplers: &[], @@ -331,7 +335,10 @@ impl TimestampNormalizer { unsafe { encoder.transition_buffers(barrier.as_slice()); encoder.begin_compute_pass(&hal::ComputePassDescriptor { - label: Some("Timestamp normalization pass"), + label: hal_label( + Some("Timestamp normalization pass"), + buffer.device.instance_flags, + ), timestamp_writes: None, }); encoder.set_compute_pipeline(&*state.pipeline); From 2fcd41377c5abec020eae810674b29a6d219d428 Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Wed, 23 Jul 2025 09:09:45 -0700 Subject: [PATCH 064/303] [naga] Make Naga tests build when no features are enabled. (#7989) --- naga/tests/naga/validation.rs | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/naga/tests/naga/validation.rs b/naga/tests/naga/validation.rs index 9da549f8f14..78fb8ea37a5 100644 --- a/naga/tests/naga/validation.rs +++ b/naga/tests/naga/validation.rs @@ -34,7 +34,7 @@ fn populate_atomic_result() { // the differences between the test cases. fn try_variant( variant: Variant, - ) -> Result> { + ) -> Result> { let span = naga::Span::default(); let mut module = Module::default(); let ty_u32 = module.types.insert( @@ -135,7 +135,7 @@ fn populate_call_result() { // the differences between the test cases. fn try_variant( variant: Variant, - ) -> Result> { + ) -> Result> { let span = naga::Span::default(); let mut module = Module::default(); let ty_u32 = module.types.insert( @@ -211,9 +211,7 @@ fn emit_workgroup_uniform_load_result() { // // Looking at uses of the `wg_load` makes it easy to identify the // differences between the two variants. - fn variant( - wg_load: bool, - ) -> Result> { + fn variant(wg_load: bool) -> Result> { let span = naga::Span::default(); let mut module = Module::default(); let ty_u32 = module.types.insert( @@ -284,7 +282,7 @@ fn builtin_cross_product_args() { fn variant( size: VectorSize, arity: usize, - ) -> Result> { + ) -> Result> { let span = naga::Span::default(); let mut module = Module::default(); let ty_vec3f = module.types.insert( @@ -546,7 +544,7 @@ fn main(input: VertexOutput) {{ #[allow(dead_code)] struct BindingArrayFixture { - module: naga::Module, + module: Module, span: naga::Span, ty_u32: naga::Handle, ty_array: naga::Handle, @@ -556,7 +554,7 @@ struct BindingArrayFixture { impl BindingArrayFixture { fn new() -> Self { - let mut module = naga::Module::default(); + let mut module = Module::default(); let span = naga::Span::default(); let ty_u32 = module.types.insert( naga::Type { @@ -694,7 +692,7 @@ error: Function [1] 'main' is invalid #[cfg(feature = "wgsl-in")] #[test] fn bad_texture_dimensions_level() { - fn validate(level: &str) -> Result { + fn validate(level: &str) -> Result { let source = format!( r#" @group(0) @binding(0) @@ -710,9 +708,7 @@ fn bad_texture_dimensions_level() { .map_err(|err| err.into_inner()) // discard spans } - fn is_bad_level_error( - result: Result, - ) -> bool { + fn is_bad_level_error(result: Result) -> bool { matches!( result, Err(naga::valid::ValidationError::Function { @@ -739,7 +735,7 @@ fn arity_check() { use naga::Span; let _ = env_logger::builder().is_test(true).try_init(); - type Result = core::result::Result; + type Result = core::result::Result; fn validate(fun: ir::MathFunction, args: &[usize]) -> Result { let nowhere = Span::default(); @@ -924,6 +920,7 @@ fn main() { /// Parse and validate the module defined in `source`. /// /// Panics if unsuccessful. +#[cfg(feature = "wgsl-in")] fn parse_validate(source: &str) -> (Module, ModuleInfo) { let module = naga::front::wgsl::parse_str(source).expect("module should parse"); let info = valid::Validator::new(Default::default(), valid::Capabilities::all()) @@ -947,6 +944,7 @@ fn parse_validate(source: &str) -> (Module, ModuleInfo) { /// /// The optional `unused_body` can introduce additional objects to the module, /// to verify that they are adjusted correctly by compaction. +#[cfg(feature = "wgsl-in")] fn override_test(test_case: &str, unused_body: Option<&str>) { use hashbrown::HashMap; use naga::back::pipeline_constants::PipelineConstantError; From dbe64a769be2514375ba30b78f7457f279ef7c19 Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Wed, 23 Jul 2025 13:48:49 -0700 Subject: [PATCH 065/303] [naga hlsl-out] Fix odd name for a Handle. (#7996) --- naga/src/back/hlsl/writer.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/naga/src/back/hlsl/writer.rs b/naga/src/back/hlsl/writer.rs index 2f98b1fbfe5..0639623fd8b 100644 --- a/naga/src/back/hlsl/writer.rs +++ b/naga/src/back/hlsl/writer.rs @@ -392,8 +392,8 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { } // Write all globals - for (ty, _) in module.global_variables.iter() { - self.write_global(module, ty)?; + for (global, _) in module.global_variables.iter() { + self.write_global(module, global)?; } if !module.global_variables.is_empty() { From 4bd0f751f83025b22b4596749e47736643eba7f2 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 24 Jul 2025 17:52:11 -0400 Subject: [PATCH 066/303] Backport changelog from v26.0.2 (#7999) --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1188ef4ef0a..11ffb4533ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,17 @@ By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). Naga now requires that no type be larger than 1 GB. This limit may be lowered in the future; feedback on an appropriate value for the limit is welcome. By @andyleiserson in [#7950](https://github.com/gfx-rs/wgpu/pull/7950). +## v26.0.2 (2025-07-23) + +### Bug Fixes + +- Fixed vulkan validation error regarding the swapchain in latest SDK. By @cwfitzgerald in [#7971](https://github.com/gfx-rs/wgpu/pull/7971). +- Fixed flickering on AMD devices and crashes inside Renderdoc due to incorrect caching of `VkFramebuffer`s when the driver re-used image view handles. By @cwfitzgerald in [#7972](https://github.com/gfx-rs/wgpu/pull/7972). +> [!WARNING] +> There is formally a breaking change in `wgpu_hal::vulkan::Device::texture_from_raw` as there is now a `&self` receiver where +> there previously wasn't one. This will not affect you unless you explicitly use this api. We have gone ahead with the release +> as the bug was pervasive and made wgpu unusable for the affected people on v26. + ## v26.0.1 (2025-07-10) ### Bug Fixes From 68a10a01d9dc210ce92cc7f3e40cdb7bccf60ba5 Mon Sep 17 00:00:00 2001 From: Florian Denis Date: Fri, 25 Jul 2025 00:31:36 +0200 Subject: [PATCH 067/303] [egl] Fix robust context creation failing on some devices (#7952) --- wgpu-hal/src/gles/egl.rs | 132 +++++++++++++++++++++++++++------------ 1 file changed, 93 insertions(+), 39 deletions(-) diff --git a/wgpu-hal/src/gles/egl.rs b/wgpu-hal/src/gles/egl.rs index ce1dd1299cf..ff4d77a3357 100644 --- a/wgpu-hal/src/gles/egl.rs +++ b/wgpu-hal/src/gles/egl.rs @@ -574,7 +574,6 @@ impl Inner { }) .unwrap(); - let needs_robustness = true; let mut khr_context_flags = 0; let supports_khr_context = display_extensions.contains("EGL_KHR_create_context"); @@ -611,53 +610,108 @@ impl Inner { log::debug!("\tEGL context: -debug"); } } - if needs_robustness { - //Note: the core version can fail if robustness is not supported - // (regardless of whether the extension is supported!). - // In fact, Angle does precisely that awful behavior, so we don't try it there. - if version >= (1, 5) && !display_extensions.contains("EGL_ANGLE_") { - log::debug!("\tEGL context: +robust access"); - context_attributes.push(khronos_egl::CONTEXT_OPENGL_ROBUST_ACCESS); - context_attributes.push(khronos_egl::TRUE as _); - } else if display_extensions.contains("EGL_EXT_create_context_robustness") { - log::debug!("\tEGL context: +robust access EXT"); - context_attributes.push(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT); - context_attributes.push(khronos_egl::TRUE as _); - } else { - //Note: we aren't trying `EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR` - // because it's for desktop GL only, not GLES. - log::warn!("\tEGL context: -robust access"); - } - } + if khr_context_flags != 0 { context_attributes.push(EGL_CONTEXT_FLAGS_KHR); context_attributes.push(khr_context_flags); } - context_attributes.push(khronos_egl::NONE); gl_context_attributes.extend(&context_attributes); gles_context_attributes.extend(&context_attributes); - let context = if supports_opengl { - egl.create_context(display, config, None, &gl_context_attributes) - .or_else(|_| { - egl.bind_api(khronos_egl::OPENGL_ES_API).unwrap(); + let context = { + enum Robustness { + Core, + Ext, + } + + let mut robustness = if version >= (1, 5) { + Some(Robustness::Core) + } else if display_extensions.contains("EGL_EXT_create_context_robustness") { + Some(Robustness::Ext) + } else { + None + }; + + loop { + let robustness_attributes = match robustness { + Some(Robustness::Core) => { + vec![ + khronos_egl::CONTEXT_OPENGL_ROBUST_ACCESS, + khronos_egl::TRUE as _, + khronos_egl::NONE, + ] + } + Some(Robustness::Ext) => { + vec![ + EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, + khronos_egl::TRUE as _, + khronos_egl::NONE, + ] + } + None => vec![khronos_egl::NONE], + }; + + let mut gl_context_attributes = gl_context_attributes.clone(); + gl_context_attributes.extend(&robustness_attributes); + + let mut gles_context_attributes = gles_context_attributes.clone(); + gles_context_attributes.extend(&robustness_attributes); + + let result = if supports_opengl { + egl.create_context(display, config, None, &gl_context_attributes) + .or_else(|_| { + egl.bind_api(khronos_egl::OPENGL_ES_API).unwrap(); + egl.create_context(display, config, None, &gles_context_attributes) + }) + } else { egl.create_context(display, config, None, &gles_context_attributes) - }) - .map_err(|e| { - crate::InstanceError::with_source( - String::from("unable to create OpenGL or GLES 3.x context"), - e, - ) - }) - } else { - egl.create_context(display, config, None, &gles_context_attributes) - .map_err(|e| { - crate::InstanceError::with_source( - String::from("unable to create GLES 3.x context"), - e, - ) - }) + }; + + match (result, robustness) { + // We have a context at the requested robustness level + (Ok(_), robustness) => { + match robustness { + Some(Robustness::Core) => { + log::debug!("\tEGL context: +robust access"); + } + Some(Robustness::Ext) => { + log::debug!("\tEGL context: +robust access EXT"); + } + None => { + log::debug!("\tEGL context: -robust access"); + } + } + + break result; + } + + // BadAttribute could mean that context creation is not supported at the requested robustness level + // We try the next robustness level. + (Err(khronos_egl::Error::BadAttribute), Some(r)) => { + // Trying EXT robustness if Core robustness is not working + // and EXT robustness is supported. + robustness = if matches!(r, Robustness::Core) + && display_extensions.contains("EGL_EXT_create_context_robustness") + { + Some(Robustness::Ext) + } else { + None + }; + + continue; + } + + // Any other error, or depleted robustness levels, we give up. + _ => break result, + } + } + .map_err(|e| { + crate::InstanceError::with_source( + String::from("unable to create OpenGL or GLES 3.x context"), + e, + ) + }) }?; // Testing if context can be binded without surface From 074c0e7191bdb5940125121378050bd4376b9ad1 Mon Sep 17 00:00:00 2001 From: SupaMaggie70Incorporated <85136135+SupaMaggie70Incorporated@users.noreply.github.com> Date: Thu, 24 Jul 2025 19:58:56 -0500 Subject: [PATCH 068/303] Add mesh shading api to wgpu & wgpu-core (#7345) --- CHANGELOG.md | 1 + cts_runner/tests/integration.rs | 2 +- examples/README.md | 1 + examples/features/src/lib.rs | 1 + examples/features/src/main.rs | 6 + examples/features/src/mesh_shader/README.md | 9 + examples/features/src/mesh_shader/mod.rs | 142 ++++++ examples/features/src/mesh_shader/shader.frag | 11 + examples/features/src/mesh_shader/shader.mesh | 38 ++ examples/features/src/mesh_shader/shader.task | 16 + .../standalone/custom_backend/src/custom.rs | 7 + player/src/lib.rs | 6 + tests/tests/wgpu-gpu/main.rs | 1 + tests/tests/wgpu-gpu/mesh_shader/basic.frag | 9 + tests/tests/wgpu-gpu/mesh_shader/basic.mesh | 25 + tests/tests/wgpu-gpu/mesh_shader/basic.task | 6 + tests/tests/wgpu-gpu/mesh_shader/mod.rs | 310 +++++++++++++ .../tests/wgpu-gpu/mesh_shader/no-write.frag | 7 + wgpu-core/src/command/bundle.rs | 102 ++++- wgpu-core/src/command/draw.rs | 15 + wgpu-core/src/command/mod.rs | 14 +- wgpu-core/src/command/render.rs | 282 +++++++++--- wgpu-core/src/command/render_command.rs | 41 +- wgpu-core/src/device/global.rs | 170 +++++-- wgpu-core/src/device/resource.rs | 432 +++++++++++------- wgpu-core/src/device/trace.rs | 4 + wgpu-core/src/indirect_validation/draw.rs | 6 +- wgpu-core/src/pipeline.rs | 132 +++++- wgpu-core/src/validation.rs | 1 + wgpu-hal/examples/halmark/main.rs | 14 +- wgpu-hal/src/dx12/adapter.rs | 6 + wgpu-hal/src/dx12/device.rs | 23 +- wgpu-hal/src/dynamic/device.rs | 60 +-- wgpu-hal/src/gles/adapter.rs | 6 + wgpu-hal/src/gles/device.rs | 21 +- wgpu-hal/src/lib.rs | 56 +-- wgpu-hal/src/metal/adapter.rs | 6 + wgpu-hal/src/metal/device.rs | 31 +- wgpu-hal/src/noop/mod.rs | 16 +- wgpu-hal/src/vulkan/adapter.rs | 24 +- wgpu-hal/src/vulkan/conv.rs | 6 + wgpu-hal/src/vulkan/device.rs | 301 +++--------- wgpu-info/src/human.rs | 12 + wgpu-types/src/lib.rs | 66 ++- wgpu/src/api/device.rs | 7 + wgpu/src/api/render_pass.rs | 70 +++ wgpu/src/api/render_pipeline.rs | 90 ++++ wgpu/src/backend/webgpu.rs | 45 ++ wgpu/src/backend/wgpu_core.rs | 188 ++++++++ wgpu/src/dispatch.rs | 24 + 50 files changed, 2202 insertions(+), 667 deletions(-) create mode 100644 examples/features/src/mesh_shader/README.md create mode 100644 examples/features/src/mesh_shader/mod.rs create mode 100644 examples/features/src/mesh_shader/shader.frag create mode 100644 examples/features/src/mesh_shader/shader.mesh create mode 100644 examples/features/src/mesh_shader/shader.task create mode 100644 tests/tests/wgpu-gpu/mesh_shader/basic.frag create mode 100644 tests/tests/wgpu-gpu/mesh_shader/basic.mesh create mode 100644 tests/tests/wgpu-gpu/mesh_shader/basic.task create mode 100644 tests/tests/wgpu-gpu/mesh_shader/mod.rs create mode 100644 tests/tests/wgpu-gpu/mesh_shader/no-write.frag diff --git a/CHANGELOG.md b/CHANGELOG.md index 11ffb4533ad..7d9558c36b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -157,6 +157,7 @@ By @Vecvec in [#7829](https://github.com/gfx-rs/wgpu/pull/7829). - Add acceleration structure limits. By @Vecvec in [#7845](https://github.com/gfx-rs/wgpu/pull/7845). - Add support for clip-distances feature for Vulkan and GL backends. By @dzamkov in [#7730](https://github.com/gfx-rs/wgpu/pull/7730) - Added `wgpu_types::error::{ErrorType, WebGpuError}` for classification of errors according to WebGPU's [`GPUError`]'s classification scheme, and implement `WebGpuError` for existing errors. This allows users of `wgpu-core` to offload error classification onto the WGPU ecosystem, rather than having to do it themselves without sufficient information. By @ErichDonGubler in [#6547](https://github.com/gfx-rs/wgpu/pull/6547). +- Added mesh shader support to `wgpu`, with examples. Requires passthrough. By @SupaMaggie70Incorporated in [#7345](https://github.com/gfx-rs/wgpu/pull/7345). [`GPUError`]: https://www.w3.org/TR/webgpu/#gpuerror diff --git a/cts_runner/tests/integration.rs b/cts_runner/tests/integration.rs index 199f00e6315..bb2118b078c 100644 --- a/cts_runner/tests/integration.rs +++ b/cts_runner/tests/integration.rs @@ -34,7 +34,7 @@ impl Display for JsError { impl Debug for JsError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self) + write!(f, "{self}") } } diff --git a/examples/README.md b/examples/README.md index aa083bc390f..a303eb52920 100644 --- a/examples/README.md +++ b/examples/README.md @@ -43,6 +43,7 @@ These examples use a common framework to handle wgpu init, window creation, and - `ray_cube_fragment` - Demonstrates using ray queries with a fragment shader. - `ray_scene` - Demonstrates using ray queries and model loading - `ray_shadows` - Demonstrates a simple use of ray queries - high quality shadows - uses a light set with push constants to raytrace through an untransformed scene and detect whether there is something obstructing the light. +- `mesh_shader` - Rrenders a triangle to a window with mesh shaders, while showcasing most mesh shader related features(task shaders, payloads, per primitive data). #### Compute diff --git a/examples/features/src/lib.rs b/examples/features/src/lib.rs index 479f1d12e9a..271241f1ae0 100644 --- a/examples/features/src/lib.rs +++ b/examples/features/src/lib.rs @@ -13,6 +13,7 @@ pub mod hello_synchronization; pub mod hello_triangle; pub mod hello_windows; pub mod hello_workgroups; +pub mod mesh_shader; pub mod mipmap; pub mod msaa_line; pub mod multiple_render_targets; diff --git a/examples/features/src/main.rs b/examples/features/src/main.rs index b90c90d26cf..c9fc31259c9 100644 --- a/examples/features/src/main.rs +++ b/examples/features/src/main.rs @@ -182,6 +182,12 @@ const EXAMPLES: &[ExampleDesc] = &[ webgl: false, // No Ray-tracing extensions webgpu: false, // No Ray-tracing extensions (yet) }, + ExampleDesc { + name: "mesh_shader", + function: wgpu_examples::mesh_shader::main, + webgl: false, + webgpu: false, + }, ]; fn get_example_name() -> Option { diff --git a/examples/features/src/mesh_shader/README.md b/examples/features/src/mesh_shader/README.md new file mode 100644 index 00000000000..9b57d3e4907 --- /dev/null +++ b/examples/features/src/mesh_shader/README.md @@ -0,0 +1,9 @@ +# mesh_shader + +This example renders a triangle to a window with mesh shaders, while showcasing most mesh shader related features(task shaders, payloads, per primitive data). + +## To Run + +``` +cargo run --bin wgpu-examples mesh_shader +``` \ No newline at end of file diff --git a/examples/features/src/mesh_shader/mod.rs b/examples/features/src/mesh_shader/mod.rs new file mode 100644 index 00000000000..956722a661d --- /dev/null +++ b/examples/features/src/mesh_shader/mod.rs @@ -0,0 +1,142 @@ +use std::{io::Write, process::Stdio}; + +// Same as in mesh shader tests +fn compile_glsl( + device: &wgpu::Device, + data: &[u8], + shader_stage: &'static str, +) -> wgpu::ShaderModule { + let cmd = std::process::Command::new("glslc") + .args([ + &format!("-fshader-stage={shader_stage}"), + "-", + "-o", + "-", + "--target-env=vulkan1.2", + "--target-spv=spv1.4", + ]) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .expect("Failed to call glslc"); + cmd.stdin.as_ref().unwrap().write_all(data).unwrap(); + println!("{shader_stage}"); + let output = cmd.wait_with_output().expect("Error waiting for glslc"); + assert!(output.status.success()); + unsafe { + device.create_shader_module_passthrough(wgpu::ShaderModuleDescriptorPassthrough::SpirV( + wgpu::ShaderModuleDescriptorSpirV { + label: None, + source: wgpu::util::make_spirv_raw(&output.stdout), + }, + )) + } +} + +pub struct Example { + pipeline: wgpu::RenderPipeline, +} +impl crate::framework::Example for Example { + fn init( + config: &wgpu::SurfaceConfiguration, + _adapter: &wgpu::Adapter, + device: &wgpu::Device, + _queue: &wgpu::Queue, + ) -> Self { + let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: None, + bind_group_layouts: &[], + push_constant_ranges: &[], + }); + let (ts, ms, fs) = ( + compile_glsl(device, include_bytes!("shader.task"), "task"), + compile_glsl(device, include_bytes!("shader.mesh"), "mesh"), + compile_glsl(device, include_bytes!("shader.frag"), "frag"), + ); + let pipeline = device.create_mesh_pipeline(&wgpu::MeshPipelineDescriptor { + label: None, + layout: Some(&pipeline_layout), + task: Some(wgpu::TaskState { + module: &ts, + entry_point: Some("main"), + compilation_options: Default::default(), + }), + mesh: wgpu::MeshState { + module: &ms, + entry_point: Some("main"), + compilation_options: Default::default(), + }, + fragment: Some(wgpu::FragmentState { + module: &fs, + entry_point: Some("main"), + compilation_options: Default::default(), + targets: &[Some(config.view_formats[0].into())], + }), + primitive: wgpu::PrimitiveState { + cull_mode: Some(wgpu::Face::Back), + ..Default::default() + }, + depth_stencil: None, + multisample: Default::default(), + multiview: None, + cache: None, + }); + Self { pipeline } + } + fn render(&mut self, view: &wgpu::TextureView, device: &wgpu::Device, queue: &wgpu::Queue) { + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + { + let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: None, + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Clear(wgpu::Color { + r: 0.1, + g: 0.2, + b: 0.3, + a: 1.0, + }), + store: wgpu::StoreOp::Store, + }, + depth_slice: None, + })], + depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, + }); + rpass.push_debug_group("Prepare data for draw."); + rpass.set_pipeline(&self.pipeline); + rpass.pop_debug_group(); + rpass.insert_debug_marker("Draw!"); + rpass.draw_mesh_tasks(1, 1, 1); + } + queue.submit(Some(encoder.finish())); + } + fn required_downlevel_capabilities() -> wgpu::DownlevelCapabilities { + Default::default() + } + fn required_features() -> wgpu::Features { + wgpu::Features::EXPERIMENTAL_MESH_SHADER | wgpu::Features::SPIRV_SHADER_PASSTHROUGH + } + fn required_limits() -> wgpu::Limits { + wgpu::Limits::defaults().using_recommended_minimum_mesh_shader_values() + } + fn resize( + &mut self, + _config: &wgpu::SurfaceConfiguration, + _device: &wgpu::Device, + _queue: &wgpu::Queue, + ) { + // empty + } + fn update(&mut self, _event: winit::event::WindowEvent) { + // empty + } +} + +pub fn main() { + crate::framework::run::("mesh_shader"); +} diff --git a/examples/features/src/mesh_shader/shader.frag b/examples/features/src/mesh_shader/shader.frag new file mode 100644 index 00000000000..49624990f16 --- /dev/null +++ b/examples/features/src/mesh_shader/shader.frag @@ -0,0 +1,11 @@ +#version 450 +#extension GL_EXT_mesh_shader : require + +in VertexInput { layout(location = 0) vec4 color; } +vertexInput; +layout(location = 1) perprimitiveEXT in PrimitiveInput { vec4 colorMask; } +primitiveInput; + +layout(location = 0) out vec4 fragColor; + +void main() { fragColor = vertexInput.color * primitiveInput.colorMask; } \ No newline at end of file diff --git a/examples/features/src/mesh_shader/shader.mesh b/examples/features/src/mesh_shader/shader.mesh new file mode 100644 index 00000000000..7d350e8ce77 --- /dev/null +++ b/examples/features/src/mesh_shader/shader.mesh @@ -0,0 +1,38 @@ +#version 450 +#extension GL_EXT_mesh_shader : require + +const vec4[3] positions = {vec4(0., 1.0, 0., 1.0), vec4(-1.0, -1.0, 0., 1.0), + vec4(1.0, -1.0, 0., 1.0)}; +const vec4[3] colors = {vec4(0., 1., 0., 1.), vec4(0., 0., 1., 1.), + vec4(1., 0., 0., 1.)}; + +// This is an inefficient workgroup size.Ideally the total thread count would be +// a multiple of 64 +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; +struct PayloadData { + vec4 colorMask; + bool visible; +}; +taskPayloadSharedEXT PayloadData payloadData; + +out VertexOutput { layout(location = 0) vec4 color; } +vertexOutput[]; +layout(location = 1) perprimitiveEXT out PrimitiveOutput { vec4 colorMask; } +primitiveOutput[]; + +shared uint sharedData; + +layout(triangles, max_vertices = 3, max_primitives = 1) out; +void main() { + sharedData = 5; + SetMeshOutputsEXT(3, 1); + gl_MeshVerticesEXT[0].gl_Position = positions[0]; + gl_MeshVerticesEXT[1].gl_Position = positions[1]; + gl_MeshVerticesEXT[2].gl_Position = positions[2]; + vertexOutput[0].color = colors[0] * payloadData.colorMask; + vertexOutput[1].color = colors[1] * payloadData.colorMask; + vertexOutput[2].color = colors[2] * payloadData.colorMask; + gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(0, 1, 2); + primitiveOutput[0].colorMask = vec4(1.0, 0.0, 1.0, 1.0); + gl_MeshPrimitivesEXT[0].gl_CullPrimitiveEXT = !payloadData.visible; +} \ No newline at end of file diff --git a/examples/features/src/mesh_shader/shader.task b/examples/features/src/mesh_shader/shader.task new file mode 100644 index 00000000000..6c766bc83ae --- /dev/null +++ b/examples/features/src/mesh_shader/shader.task @@ -0,0 +1,16 @@ +#version 450 +#extension GL_EXT_mesh_shader : require + +layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in; + +struct TaskPayload { + vec4 colorMask; + bool visible; +}; +taskPayloadSharedEXT TaskPayload taskPayload; + +void main() { + taskPayload.colorMask = vec4(1.0, 1.0, 0.0, 1.0); + taskPayload.visible = true; + EmitMeshTasksEXT(3, 1, 1); +} \ No newline at end of file diff --git a/examples/standalone/custom_backend/src/custom.rs b/examples/standalone/custom_backend/src/custom.rs index 8ca7df80bdb..6381c48d1d4 100644 --- a/examples/standalone/custom_backend/src/custom.rs +++ b/examples/standalone/custom_backend/src/custom.rs @@ -161,6 +161,13 @@ impl DeviceInterface for CustomDevice { unimplemented!() } + fn create_mesh_pipeline( + &self, + _desc: &wgpu::MeshPipelineDescriptor<'_>, + ) -> wgpu::custom::DispatchRenderPipeline { + unimplemented!() + } + fn create_compute_pipeline( &self, desc: &wgpu::ComputePipelineDescriptor<'_>, diff --git a/player/src/lib.rs b/player/src/lib.rs index 24c520c276c..5076db0267d 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -333,6 +333,12 @@ impl GlobalPlay for wgc::global::Global { panic!("{e}"); } } + Action::CreateMeshPipeline { id, desc } => { + let (_, error) = self.device_create_mesh_pipeline(device, &desc, Some(id)); + if let Some(e) = error { + panic!("{e}"); + } + } Action::DestroyRenderPipeline(id) => { self.render_pipeline_drop(id); } diff --git a/tests/tests/wgpu-gpu/main.rs b/tests/tests/wgpu-gpu/main.rs index 8fd24c43435..2e5462f2e6f 100644 --- a/tests/tests/wgpu-gpu/main.rs +++ b/tests/tests/wgpu-gpu/main.rs @@ -34,6 +34,7 @@ mod image_atomics; mod instance; mod life_cycle; mod mem_leaks; +mod mesh_shader; mod nv12_texture; mod occlusion_query; mod oob_indexing; diff --git a/tests/tests/wgpu-gpu/mesh_shader/basic.frag b/tests/tests/wgpu-gpu/mesh_shader/basic.frag new file mode 100644 index 00000000000..9d2b777326f --- /dev/null +++ b/tests/tests/wgpu-gpu/mesh_shader/basic.frag @@ -0,0 +1,9 @@ +#version 450 +#extension GL_EXT_mesh_shader : require + +in VertexInput { layout(location = 0) vec4 color; } +vertexInput; + +layout(location = 0) out vec4 fragColor; + +void main() { fragColor = vertexInput.color; } \ No newline at end of file diff --git a/tests/tests/wgpu-gpu/mesh_shader/basic.mesh b/tests/tests/wgpu-gpu/mesh_shader/basic.mesh new file mode 100644 index 00000000000..400cafb36f0 --- /dev/null +++ b/tests/tests/wgpu-gpu/mesh_shader/basic.mesh @@ -0,0 +1,25 @@ +#version 450 +#extension GL_EXT_mesh_shader : require + +const vec4[3] positions = {vec4(0., 1.0, 0., 1.0), vec4(-1.0, -1.0, 0., 1.0), + vec4(1.0, -1.0, 0., 1.0)}; +const vec4[3] colors = {vec4(0., 1., 0., 1.), vec4(0., 0., 1., 1.), + vec4(1., 0., 0., 1.)}; + +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; + +out VertexOutput { layout(location = 0) vec4 color; } +vertexOutput[]; + +layout(triangles, max_vertices = 3, max_primitives = 1) out; + +void main() { + SetMeshOutputsEXT(3, 1); + gl_MeshVerticesEXT[0].gl_Position = positions[0]; + gl_MeshVerticesEXT[1].gl_Position = positions[1]; + gl_MeshVerticesEXT[2].gl_Position = positions[2]; + vertexOutput[0].color = colors[0]; + vertexOutput[1].color = colors[1]; + vertexOutput[2].color = colors[2]; + gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(0, 1, 2); +} \ No newline at end of file diff --git a/tests/tests/wgpu-gpu/mesh_shader/basic.task b/tests/tests/wgpu-gpu/mesh_shader/basic.task new file mode 100644 index 00000000000..418cffa3f6c --- /dev/null +++ b/tests/tests/wgpu-gpu/mesh_shader/basic.task @@ -0,0 +1,6 @@ +#version 450 +#extension GL_EXT_mesh_shader : require + +layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in; + +void main() { EmitMeshTasksEXT(1, 1, 1); } \ No newline at end of file diff --git a/tests/tests/wgpu-gpu/mesh_shader/mod.rs b/tests/tests/wgpu-gpu/mesh_shader/mod.rs new file mode 100644 index 00000000000..cd1ca425429 --- /dev/null +++ b/tests/tests/wgpu-gpu/mesh_shader/mod.rs @@ -0,0 +1,310 @@ +use std::{io::Write, process::Stdio}; + +use wgpu::util::DeviceExt; +use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; + +// Same as in mesh shader example +fn compile_glsl( + device: &wgpu::Device, + data: &[u8], + shader_stage: &'static str, +) -> wgpu::ShaderModule { + let cmd = std::process::Command::new("glslc") + .args([ + &format!("-fshader-stage={shader_stage}"), + "-", + "-o", + "-", + "--target-env=vulkan1.2", + "--target-spv=spv1.4", + ]) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .expect("Failed to call glslc"); + cmd.stdin.as_ref().unwrap().write_all(data).unwrap(); + println!("{shader_stage}"); + let output = cmd.wait_with_output().expect("Error waiting for glslc"); + assert!(output.status.success()); + unsafe { + device.create_shader_module_passthrough(wgpu::ShaderModuleDescriptorPassthrough::SpirV( + wgpu::ShaderModuleDescriptorSpirV { + label: None, + source: wgpu::util::make_spirv_raw(&output.stdout), + }, + )) + } +} + +fn create_depth( + device: &wgpu::Device, +) -> (wgpu::Texture, wgpu::TextureView, wgpu::DepthStencilState) { + let image_size = wgpu::Extent3d { + width: 64, + height: 64, + depth_or_array_layers: 1, + }; + let depth_texture = device.create_texture(&wgpu::TextureDescriptor { + label: None, + size: image_size, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Depth32Float, + usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING, + view_formats: &[], + }); + let depth_view = depth_texture.create_view(&Default::default()); + let state = wgpu::DepthStencilState { + format: wgpu::TextureFormat::Depth32Float, + depth_write_enabled: true, + depth_compare: wgpu::CompareFunction::Less, // 1. + stencil: wgpu::StencilState::default(), // 2. + bias: wgpu::DepthBiasState::default(), + }; + (depth_texture, depth_view, state) +} + +fn mesh_pipeline_build( + ctx: &TestingContext, + task: Option<&[u8]>, + mesh: &[u8], + frag: Option<&[u8]>, + draw: bool, +) { + let device = &ctx.device; + let (_depth_image, depth_view, depth_state) = create_depth(device); + let task = task.map(|t| compile_glsl(device, t, "task")); + let mesh = compile_glsl(device, mesh, "mesh"); + let frag = frag.map(|f| compile_glsl(device, f, "frag")); + let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: None, + bind_group_layouts: &[], + push_constant_ranges: &[], + }); + let pipeline = device.create_mesh_pipeline(&wgpu::MeshPipelineDescriptor { + label: None, + layout: Some(&layout), + task: task.as_ref().map(|task| wgpu::TaskState { + module: task, + entry_point: Some("main"), + compilation_options: Default::default(), + }), + mesh: wgpu::MeshState { + module: &mesh, + entry_point: Some("main"), + compilation_options: Default::default(), + }, + fragment: frag.as_ref().map(|frag| wgpu::FragmentState { + module: frag, + entry_point: Some("main"), + targets: &[], + compilation_options: Default::default(), + }), + primitive: wgpu::PrimitiveState { + cull_mode: Some(wgpu::Face::Back), + ..Default::default() + }, + depth_stencil: Some(depth_state), + multisample: Default::default(), + multiview: None, + cache: None, + }); + if draw { + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + { + let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: None, + color_attachments: &[], + depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment { + view: &depth_view, + depth_ops: Some(wgpu::Operations { + load: wgpu::LoadOp::Clear(1.0), + store: wgpu::StoreOp::Store, + }), + stencil_ops: None, + }), + timestamp_writes: None, + occlusion_query_set: None, + }); + pass.set_pipeline(&pipeline); + pass.draw_mesh_tasks(1, 1, 1); + } + ctx.queue.submit(Some(encoder.finish())); + ctx.device.poll(wgpu::PollType::Wait).unwrap(); + } +} + +#[derive(PartialEq, Eq, Clone, Copy)] +pub enum DrawType { + #[allow(dead_code)] + Standard, + Indirect, + MultiIndirect, + MultiIndirectCount, +} + +fn mesh_draw(ctx: &TestingContext, draw_type: DrawType) { + let device = &ctx.device; + let (_depth_image, depth_view, depth_state) = create_depth(device); + let task = compile_glsl(device, BASIC_TASK, "task"); + let mesh = compile_glsl(device, BASIC_MESH, "mesh"); + let frag = compile_glsl(device, NO_WRITE_FRAG, "frag"); + let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: None, + bind_group_layouts: &[], + push_constant_ranges: &[], + }); + let pipeline = device.create_mesh_pipeline(&wgpu::MeshPipelineDescriptor { + label: None, + layout: Some(&layout), + task: Some(wgpu::TaskState { + module: &task, + entry_point: Some("main"), + compilation_options: Default::default(), + }), + mesh: wgpu::MeshState { + module: &mesh, + entry_point: Some("main"), + compilation_options: Default::default(), + }, + fragment: Some(wgpu::FragmentState { + module: &frag, + entry_point: Some("main"), + targets: &[], + compilation_options: Default::default(), + }), + primitive: wgpu::PrimitiveState { + cull_mode: Some(wgpu::Face::Back), + ..Default::default() + }, + depth_stencil: Some(depth_state), + multisample: Default::default(), + multiview: None, + cache: None, + }); + let buffer = match draw_type { + DrawType::Standard => None, + DrawType::Indirect | DrawType::MultiIndirect | DrawType::MultiIndirectCount => Some( + device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: None, + usage: wgpu::BufferUsages::INDIRECT, + contents: bytemuck::bytes_of(&[1u32; 4]), + }), + ), + }; + let count_buffer = match draw_type { + DrawType::MultiIndirectCount => Some(device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: None, + usage: wgpu::BufferUsages::INDIRECT, + contents: bytemuck::bytes_of(&[1u32; 1]), + }, + )), + _ => None, + }; + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + { + let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: None, + color_attachments: &[], + depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment { + view: &depth_view, + depth_ops: Some(wgpu::Operations { + load: wgpu::LoadOp::Clear(1.0), + store: wgpu::StoreOp::Store, + }), + stencil_ops: None, + }), + timestamp_writes: None, + occlusion_query_set: None, + }); + pass.set_pipeline(&pipeline); + match draw_type { + DrawType::Standard => pass.draw_mesh_tasks(1, 1, 1), + DrawType::Indirect => pass.draw_mesh_tasks_indirect(buffer.as_ref().unwrap(), 0), + DrawType::MultiIndirect => { + pass.multi_draw_mesh_tasks_indirect(buffer.as_ref().unwrap(), 0, 1) + } + DrawType::MultiIndirectCount => pass.multi_draw_mesh_tasks_indirect_count( + buffer.as_ref().unwrap(), + 0, + count_buffer.as_ref().unwrap(), + 0, + 1, + ), + } + pass.draw_mesh_tasks_indirect(buffer.as_ref().unwrap(), 0); + } + ctx.queue.submit(Some(encoder.finish())); + ctx.device.poll(wgpu::PollType::Wait).unwrap(); +} + +const BASIC_TASK: &[u8] = include_bytes!("basic.task"); +const BASIC_MESH: &[u8] = include_bytes!("basic.mesh"); +//const BASIC_FRAG: &[u8] = include_bytes!("basic.frag.spv"); +const NO_WRITE_FRAG: &[u8] = include_bytes!("no-write.frag"); + +fn default_gpu_test_config(draw_type: DrawType) -> GpuTestConfiguration { + GpuTestConfiguration::new().parameters( + TestParameters::default() + .test_features_limits() + .features( + wgpu::Features::EXPERIMENTAL_MESH_SHADER + | wgpu::Features::SPIRV_SHADER_PASSTHROUGH + | match draw_type { + DrawType::Standard | DrawType::Indirect => wgpu::Features::empty(), + DrawType::MultiIndirect => wgpu::Features::MULTI_DRAW_INDIRECT, + DrawType::MultiIndirectCount => wgpu::Features::MULTI_DRAW_INDIRECT_COUNT, + }, + ) + .limits(wgpu::Limits::default().using_recommended_minimum_mesh_shader_values()), + ) +} + +// Mesh pipeline configs +#[gpu_test] +static MESH_PIPELINE_BASIC_MESH: GpuTestConfiguration = default_gpu_test_config(DrawType::Standard) + .run_sync(|ctx| { + mesh_pipeline_build(&ctx, None, BASIC_MESH, None, true); + }); +#[gpu_test] +static MESH_PIPELINE_BASIC_TASK_MESH: GpuTestConfiguration = + default_gpu_test_config(DrawType::Standard).run_sync(|ctx| { + mesh_pipeline_build(&ctx, Some(BASIC_TASK), BASIC_MESH, None, true); + }); +#[gpu_test] +static MESH_PIPELINE_BASIC_MESH_FRAG: GpuTestConfiguration = + default_gpu_test_config(DrawType::Standard).run_sync(|ctx| { + mesh_pipeline_build(&ctx, None, BASIC_MESH, Some(NO_WRITE_FRAG), true); + }); +#[gpu_test] +static MESH_PIPELINE_BASIC_TASK_MESH_FRAG: GpuTestConfiguration = + default_gpu_test_config(DrawType::Standard).run_sync(|ctx| { + mesh_pipeline_build( + &ctx, + Some(BASIC_TASK), + BASIC_MESH, + Some(NO_WRITE_FRAG), + true, + ); + }); + +// Mesh draw +#[gpu_test] +static MESH_DRAW_INDIRECT: GpuTestConfiguration = default_gpu_test_config(DrawType::Indirect) + .run_sync(|ctx| { + mesh_draw(&ctx, DrawType::Indirect); + }); +#[gpu_test] +static MESH_MULTI_DRAW_INDIRECT: GpuTestConfiguration = + default_gpu_test_config(DrawType::MultiIndirect).run_sync(|ctx| { + mesh_draw(&ctx, DrawType::MultiIndirect); + }); +#[gpu_test] +static MESH_MULTI_DRAW_INDIRECT_COUNT: GpuTestConfiguration = + default_gpu_test_config(DrawType::MultiIndirectCount).run_sync(|ctx| { + mesh_draw(&ctx, DrawType::MultiIndirectCount); + }); diff --git a/tests/tests/wgpu-gpu/mesh_shader/no-write.frag b/tests/tests/wgpu-gpu/mesh_shader/no-write.frag new file mode 100644 index 00000000000..d0512bb0fad --- /dev/null +++ b/tests/tests/wgpu-gpu/mesh_shader/no-write.frag @@ -0,0 +1,7 @@ +#version 450 +#extension GL_EXT_mesh_shader : require + +in VertexInput { layout(location = 0) vec4 color; } +vertexInput; + +void main() {} \ No newline at end of file diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index 09f522f0013..8e8bf90b146 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -123,7 +123,7 @@ use crate::{ use super::{ pass, render_command::{ArcRenderCommand, RenderCommand}, - DrawKind, + DrawCommandFamily, DrawKind, }; /// Describes a [`RenderBundleEncoder`]. @@ -380,7 +380,7 @@ impl RenderBundleEncoder { } => { let scope = PassErrorScope::Draw { kind: DrawKind::Draw, - indexed: false, + family: DrawCommandFamily::Draw, }; draw( &mut state, @@ -401,7 +401,7 @@ impl RenderBundleEncoder { } => { let scope = PassErrorScope::Draw { kind: DrawKind::Draw, - indexed: true, + family: DrawCommandFamily::DrawIndexed, }; draw_indexed( &mut state, @@ -414,15 +414,33 @@ impl RenderBundleEncoder { ) .map_pass_err(scope)?; } + RenderCommand::DrawMeshTasks { + group_count_x, + group_count_y, + group_count_z, + } => { + let scope = PassErrorScope::Draw { + kind: DrawKind::Draw, + family: DrawCommandFamily::DrawMeshTasks, + }; + draw_mesh_tasks( + &mut state, + &base.dynamic_offsets, + group_count_x, + group_count_y, + group_count_z, + ) + .map_pass_err(scope)?; + } RenderCommand::DrawIndirect { buffer_id, offset, count: 1, - indexed, + family, } => { let scope = PassErrorScope::Draw { kind: DrawKind::DrawIndirect, - indexed, + family, }; multi_draw_indirect( &mut state, @@ -430,7 +448,7 @@ impl RenderBundleEncoder { &buffer_guard, buffer_id, offset, - indexed, + family, ) .map_pass_err(scope)?; } @@ -787,13 +805,48 @@ fn draw_indexed( Ok(()) } +fn draw_mesh_tasks( + state: &mut State, + dynamic_offsets: &[u32], + group_count_x: u32, + group_count_y: u32, + group_count_z: u32, +) -> Result<(), RenderBundleErrorInner> { + let pipeline = state.pipeline()?; + let used_bind_groups = pipeline.used_bind_groups; + + let groups_size_limit = state.device.limits.max_task_workgroups_per_dimension; + let max_groups = state.device.limits.max_task_workgroup_total_count; + if group_count_x > groups_size_limit + || group_count_y > groups_size_limit + || group_count_z > groups_size_limit + || group_count_x * group_count_y * group_count_z > max_groups + { + return Err(RenderBundleErrorInner::Draw(DrawError::InvalidGroupSize { + current: [group_count_x, group_count_y, group_count_z], + limit: groups_size_limit, + max_total: max_groups, + })); + } + + if group_count_x > 0 && group_count_y > 0 && group_count_z > 0 { + state.flush_binds(used_bind_groups, dynamic_offsets); + state.commands.push(ArcRenderCommand::DrawMeshTasks { + group_count_x, + group_count_y, + group_count_z, + }); + } + Ok(()) +} + fn multi_draw_indirect( state: &mut State, dynamic_offsets: &[u32], buffer_guard: &crate::storage::Storage>, buffer_id: id::Id, offset: u64, - indexed: bool, + family: DrawCommandFamily, ) -> Result<(), RenderBundleErrorInner> { state .device @@ -809,7 +862,7 @@ fn multi_draw_indirect( let vertex_limits = super::VertexLimits::new(state.vertex_buffer_sizes(), &pipeline.steps); - let stride = super::get_stride_of_indirect_args(indexed); + let stride = super::get_stride_of_indirect_args(family); state .buffer_memory_init_actions .extend(buffer.initialization_status.read().create_action( @@ -818,7 +871,7 @@ fn multi_draw_indirect( MemoryInitKind::NeedsInitializedMemory, )); - let vertex_or_index_limit = if indexed { + let vertex_or_index_limit = if family == DrawCommandFamily::DrawIndexed { let index = match state.index { Some(ref mut index) => index, None => return Err(DrawError::MissingIndexBuffer.into()), @@ -844,7 +897,7 @@ fn multi_draw_indirect( buffer, offset, count: 1, - indexed, + family, vertex_or_index_limit, instance_limit, @@ -1066,11 +1119,18 @@ impl RenderBundle { ) }; } + Cmd::DrawMeshTasks { + group_count_x, + group_count_y, + group_count_z, + } => unsafe { + raw.draw_mesh_tasks(*group_count_x, *group_count_y, *group_count_z); + }, Cmd::DrawIndirect { buffer, offset, count: 1, - indexed, + family, vertex_or_index_limit, instance_limit, @@ -1081,7 +1141,7 @@ impl RenderBundle { &self.device, buffer, *offset, - *indexed, + *family, *vertex_or_index_limit, *instance_limit, )?; @@ -1092,10 +1152,14 @@ impl RenderBundle { } else { (buffer.try_raw(snatch_guard)?, *offset) }; - if *indexed { - unsafe { raw.draw_indexed_indirect(buffer, offset, 1) }; - } else { - unsafe { raw.draw_indirect(buffer, offset, 1) }; + match family { + DrawCommandFamily::Draw => unsafe { raw.draw_indirect(buffer, offset, 1) }, + DrawCommandFamily::DrawIndexed => unsafe { + raw.draw_indexed_indirect(buffer, offset, 1) + }, + DrawCommandFamily::DrawMeshTasks => unsafe { + raw.draw_mesh_tasks_indirect(buffer, offset, 1); + }, } } Cmd::DrawIndirect { .. } | Cmd::MultiDrawIndirectCount { .. } => { @@ -1597,7 +1661,7 @@ where pub mod bundle_ffi { use super::{RenderBundleEncoder, RenderCommand}; - use crate::{id, RawString}; + use crate::{command::DrawCommandFamily, id, RawString}; use core::{convert::TryInto, slice}; use wgt::{BufferAddress, BufferSize, DynamicOffset, IndexFormat}; @@ -1752,7 +1816,7 @@ pub mod bundle_ffi { buffer_id, offset, count: 1, - indexed: false, + family: DrawCommandFamily::Draw, }); } @@ -1765,7 +1829,7 @@ pub mod bundle_ffi { buffer_id, offset, count: 1, - indexed: true, + family: DrawCommandFamily::DrawIndexed, }); } diff --git a/wgpu-core/src/command/draw.rs b/wgpu-core/src/command/draw.rs index adb83643d98..7a57077a4fa 100644 --- a/wgpu-core/src/command/draw.rs +++ b/wgpu-core/src/command/draw.rs @@ -56,6 +56,21 @@ pub enum DrawError { }, #[error(transparent)] BindingSizeTooSmall(#[from] LateMinBufferBindingSizeMismatch), + + #[error( + "Wrong pipeline type for this draw command. Attempted to call {} draw command on {} pipeline", + if *wanted_mesh_pipeline {"mesh shader"} else {"standard"}, + if *wanted_mesh_pipeline {"standard"} else {"mesh shader"}, + )] + WrongPipelineType { wanted_mesh_pipeline: bool }, + #[error( + "Each current draw group size dimension ({current:?}) must be less or equal to {limit}, and the product must be less or equal to {max_total}" + )] + InvalidGroupSize { + current: [u32; 3], + limit: u32, + max_total: u32, + }, } impl WebGpuError for DrawError { diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 354a6ebac71..3abcf8307c6 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -1442,6 +1442,15 @@ pub enum DrawKind { MultiDrawIndirectCount, } +/// The type of draw command(indexed or not, or mesh shader) +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum DrawCommandFamily { + Draw, + DrawIndexed, + DrawMeshTasks, +} + /// A command that can be recorded in a pass or bundle. /// /// This is used to provide context for errors during command recording. @@ -1480,7 +1489,10 @@ pub enum PassErrorScope { #[error("In a set_scissor_rect command")] SetScissorRect, #[error("In a draw command, kind: {kind:?}")] - Draw { kind: DrawKind, indexed: bool }, + Draw { + kind: DrawKind, + family: DrawCommandFamily, + }, #[error("In a write_timestamp command")] WriteTimestamp, #[error("In a begin_occlusion_query command")] diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index aef81bc4a07..ba5fdbcd7d0 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -54,7 +54,7 @@ use super::{ memory_init::TextureSurfaceDiscard, CommandBufferTextureMemoryActions, CommandEncoder, QueryResetMap, }; -use super::{DrawKind, Rect}; +use super::{DrawCommandFamily, DrawKind, Rect}; use crate::binding_model::{BindError, PushConstantUploadError}; pub use wgt::{LoadOp, StoreOp}; @@ -513,7 +513,7 @@ struct State<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { impl<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> State<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { - fn is_ready(&self, indexed: bool) -> Result<(), DrawError> { + fn is_ready(&self, family: DrawCommandFamily) -> Result<(), DrawError> { if let Some(pipeline) = self.pipeline.as_ref() { self.general.binder.check_compatibility(pipeline.as_ref())?; self.general.binder.check_late_buffer_bindings()?; @@ -537,7 +537,7 @@ impl<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> }); } - if indexed { + if family == DrawCommandFamily::DrawIndexed { // Pipeline expects an index buffer if let Some(pipeline_index_format) = pipeline.strip_index_format { // We have a buffer bound @@ -556,6 +556,11 @@ impl<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> } } } + if (family == DrawCommandFamily::DrawMeshTasks) != pipeline.is_mesh { + return Err(DrawError::WrongPipelineType { + wanted_mesh_pipeline: !pipeline.is_mesh, + }); + } Ok(()) } else { Err(DrawError::MissingPipeline(pass::MissingPipeline)) @@ -2013,7 +2018,7 @@ impl Global { } => { let scope = PassErrorScope::Draw { kind: DrawKind::Draw, - indexed: false, + family: DrawCommandFamily::Draw, }; draw( &mut state, @@ -2033,7 +2038,7 @@ impl Global { } => { let scope = PassErrorScope::Draw { kind: DrawKind::Draw, - indexed: true, + family: DrawCommandFamily::DrawIndexed, }; draw_indexed( &mut state, @@ -2045,11 +2050,28 @@ impl Global { ) .map_pass_err(scope)?; } + ArcRenderCommand::DrawMeshTasks { + group_count_x, + group_count_y, + group_count_z, + } => { + let scope = PassErrorScope::Draw { + kind: DrawKind::Draw, + family: DrawCommandFamily::DrawMeshTasks, + }; + draw_mesh_tasks( + &mut state, + group_count_x, + group_count_y, + group_count_z, + ) + .map_pass_err(scope)?; + } ArcRenderCommand::DrawIndirect { buffer, offset, count, - indexed, + family, vertex_or_index_limit: _, instance_limit: _, @@ -2060,7 +2082,7 @@ impl Global { } else { DrawKind::DrawIndirect }, - indexed, + family, }; multi_draw_indirect( &mut state, @@ -2070,7 +2092,7 @@ impl Global { buffer, offset, count, - indexed, + family, ) .map_pass_err(scope)?; } @@ -2080,11 +2102,11 @@ impl Global { count_buffer, count_buffer_offset, max_count, - indexed, + family, } => { let scope = PassErrorScope::Draw { kind: DrawKind::MultiDrawIndirectCount, - indexed, + family, }; multi_draw_indirect_count( &mut state, @@ -2094,7 +2116,7 @@ impl Global { count_buffer, count_buffer_offset, max_count, - indexed, + family, ) .map_pass_err(scope)?; } @@ -2545,7 +2567,7 @@ fn draw( ) -> Result<(), DrawError> { api_log!("RenderPass::draw {vertex_count} {instance_count} {first_vertex} {first_instance}"); - state.is_ready(false)?; + state.is_ready(DrawCommandFamily::Draw)?; state .vertex @@ -2579,7 +2601,7 @@ fn draw_indexed( ) -> Result<(), DrawError> { api_log!("RenderPass::draw_indexed {index_count} {instance_count} {first_index} {base_vertex} {first_instance}"); - state.is_ready(true)?; + state.is_ready(DrawCommandFamily::DrawIndexed)?; let last_index = first_index as u64 + index_count as u64; let index_limit = state.index.limit; @@ -2608,6 +2630,45 @@ fn draw_indexed( Ok(()) } +fn draw_mesh_tasks( + state: &mut State, + group_count_x: u32, + group_count_y: u32, + group_count_z: u32, +) -> Result<(), DrawError> { + api_log!("RenderPass::draw_mesh_tasks {group_count_x} {group_count_y} {group_count_z}"); + + state.is_ready(DrawCommandFamily::DrawMeshTasks)?; + + let groups_size_limit = state + .general + .device + .limits + .max_task_workgroups_per_dimension; + let max_groups = state.general.device.limits.max_task_workgroup_total_count; + if group_count_x > groups_size_limit + || group_count_y > groups_size_limit + || group_count_z > groups_size_limit + || group_count_x * group_count_y * group_count_z > max_groups + { + return Err(DrawError::InvalidGroupSize { + current: [group_count_x, group_count_y, group_count_z], + limit: groups_size_limit, + max_total: max_groups, + }); + } + + unsafe { + if group_count_x > 0 && group_count_y > 0 && group_count_z > 0 { + state + .general + .raw_encoder + .draw_mesh_tasks(group_count_x, group_count_y, group_count_z); + } + } + Ok(()) +} + fn multi_draw_indirect( state: &mut State, indirect_draw_validation_resources: &mut crate::indirect_validation::DrawResources, @@ -2616,14 +2677,14 @@ fn multi_draw_indirect( indirect_buffer: Arc, offset: u64, count: u32, - indexed: bool, + family: DrawCommandFamily, ) -> Result<(), RenderPassErrorInner> { api_log!( - "RenderPass::draw_indirect (indexed:{indexed}) {} {offset} {count:?}", + "RenderPass::draw_indirect (family:{family:?}) {} {offset} {count:?}", indirect_buffer.error_ident() ); - state.is_ready(indexed)?; + state.is_ready(family)?; if count != 1 { state @@ -2645,7 +2706,7 @@ fn multi_draw_indirect( return Err(RenderPassErrorInner::UnalignedIndirectBufferOffset(offset)); } - let stride = get_stride_of_indirect_args(indexed); + let stride = get_stride_of_indirect_args(family); let end_offset = offset + stride * count as u64; if end_offset > indirect_buffer.size { @@ -2667,18 +2728,21 @@ fn multi_draw_indirect( fn draw( raw_encoder: &mut dyn hal::DynCommandEncoder, - indexed: bool, + family: DrawCommandFamily, indirect_buffer: &dyn hal::DynBuffer, offset: u64, count: u32, ) { - match indexed { - false => unsafe { + match family { + DrawCommandFamily::Draw => unsafe { raw_encoder.draw_indirect(indirect_buffer, offset, count); }, - true => unsafe { + DrawCommandFamily::DrawIndexed => unsafe { raw_encoder.draw_indexed_indirect(indirect_buffer, offset, count); }, + DrawCommandFamily::DrawMeshTasks => unsafe { + raw_encoder.draw_mesh_tasks_indirect(indirect_buffer, offset, count); + }, } } @@ -2703,7 +2767,7 @@ fn multi_draw_indirect( indirect_draw_validation_batcher: &'a mut crate::indirect_validation::DrawBatcher, indirect_buffer: Arc, - indexed: bool, + family: DrawCommandFamily, vertex_or_index_limit: u64, instance_limit: u64, } @@ -2715,7 +2779,7 @@ fn multi_draw_indirect( self.device, &self.indirect_buffer, offset, - self.indexed, + self.family, self.vertex_or_index_limit, self.instance_limit, )?; @@ -2731,7 +2795,7 @@ fn multi_draw_indirect( .get_dst_buffer(draw_data.buffer_index); draw( self.raw_encoder, - self.indexed, + self.family, dst_buffer, draw_data.offset, draw_data.count, @@ -2745,8 +2809,8 @@ fn multi_draw_indirect( indirect_draw_validation_resources, indirect_draw_validation_batcher, indirect_buffer, - indexed, - vertex_or_index_limit: if indexed { + family, + vertex_or_index_limit: if family == DrawCommandFamily::DrawIndexed { state.index.limit } else { state.vertex.limits.vertex_limit @@ -2781,7 +2845,7 @@ fn multi_draw_indirect( draw( state.general.raw_encoder, - indexed, + family, indirect_buffer.try_raw(state.general.snatch_guard)?, offset, count, @@ -2799,17 +2863,17 @@ fn multi_draw_indirect_count( count_buffer: Arc, count_buffer_offset: u64, max_count: u32, - indexed: bool, + family: DrawCommandFamily, ) -> Result<(), RenderPassErrorInner> { api_log!( - "RenderPass::multi_draw_indirect_count (indexed:{indexed}) {} {offset} {} {count_buffer_offset:?} {max_count:?}", + "RenderPass::multi_draw_indirect_count (family:{family:?}) {} {offset} {} {count_buffer_offset:?} {max_count:?}", indirect_buffer.error_ident(), count_buffer.error_ident() ); - state.is_ready(indexed)?; + state.is_ready(family)?; - let stride = get_stride_of_indirect_args(indexed); + let stride = get_stride_of_indirect_args(family); state .general @@ -2879,8 +2943,8 @@ fn multi_draw_indirect_count( ), ); - match indexed { - false => unsafe { + match family { + DrawCommandFamily::Draw => unsafe { state.general.raw_encoder.draw_indirect_count( indirect_raw, offset, @@ -2889,7 +2953,7 @@ fn multi_draw_indirect_count( max_count, ); }, - true => unsafe { + DrawCommandFamily::DrawIndexed => unsafe { state.general.raw_encoder.draw_indexed_indirect_count( indirect_raw, offset, @@ -2898,6 +2962,15 @@ fn multi_draw_indirect_count( max_count, ); }, + DrawCommandFamily::DrawMeshTasks => unsafe { + state.general.raw_encoder.draw_mesh_tasks_indirect_count( + indirect_raw, + offset, + count_raw, + count_buffer_offset, + max_count, + ); + }, } Ok(()) } @@ -3250,7 +3323,7 @@ impl Global { ) -> Result<(), PassStateError> { let scope = PassErrorScope::Draw { kind: DrawKind::Draw, - indexed: false, + family: DrawCommandFamily::Draw, }; let base = pass_base!(pass, scope); @@ -3275,7 +3348,7 @@ impl Global { ) -> Result<(), PassStateError> { let scope = PassErrorScope::Draw { kind: DrawKind::Draw, - indexed: true, + family: DrawCommandFamily::DrawIndexed, }; let base = pass_base!(pass, scope); @@ -3290,6 +3363,27 @@ impl Global { Ok(()) } + pub fn render_pass_draw_mesh_tasks( + &self, + pass: &mut RenderPass, + group_count_x: u32, + group_count_y: u32, + group_count_z: u32, + ) -> Result<(), RenderPassError> { + let scope = PassErrorScope::Draw { + kind: DrawKind::Draw, + family: DrawCommandFamily::DrawMeshTasks, + }; + let base = pass_base!(pass, scope); + + base.commands.push(ArcRenderCommand::DrawMeshTasks { + group_count_x, + group_count_y, + group_count_z, + }); + Ok(()) + } + pub fn render_pass_draw_indirect( &self, pass: &mut RenderPass, @@ -3298,7 +3392,7 @@ impl Global { ) -> Result<(), PassStateError> { let scope = PassErrorScope::Draw { kind: DrawKind::DrawIndirect, - indexed: false, + family: DrawCommandFamily::Draw, }; let base = pass_base!(pass, scope); @@ -3306,7 +3400,7 @@ impl Global { buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), offset, count: 1, - indexed: false, + family: DrawCommandFamily::Draw, vertex_or_index_limit: 0, instance_limit: 0, @@ -3323,7 +3417,32 @@ impl Global { ) -> Result<(), PassStateError> { let scope = PassErrorScope::Draw { kind: DrawKind::DrawIndirect, - indexed: true, + family: DrawCommandFamily::DrawIndexed, + }; + let base = pass_base!(pass, scope); + + base.commands.push(ArcRenderCommand::DrawIndirect { + buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), + offset, + count: 1, + family: DrawCommandFamily::DrawIndexed, + + vertex_or_index_limit: 0, + instance_limit: 0, + }); + + Ok(()) + } + + pub fn render_pass_draw_mesh_tasks_indirect( + &self, + pass: &mut RenderPass, + buffer_id: id::BufferId, + offset: BufferAddress, + ) -> Result<(), RenderPassError> { + let scope = PassErrorScope::Draw { + kind: DrawKind::DrawIndirect, + family: DrawCommandFamily::DrawMeshTasks, }; let base = pass_base!(pass, scope); @@ -3331,7 +3450,7 @@ impl Global { buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), offset, count: 1, - indexed: true, + family: DrawCommandFamily::DrawMeshTasks, vertex_or_index_limit: 0, instance_limit: 0, @@ -3349,7 +3468,7 @@ impl Global { ) -> Result<(), PassStateError> { let scope = PassErrorScope::Draw { kind: DrawKind::MultiDrawIndirect, - indexed: false, + family: DrawCommandFamily::Draw, }; let base = pass_base!(pass, scope); @@ -3357,7 +3476,7 @@ impl Global { buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), offset, count, - indexed: false, + family: DrawCommandFamily::Draw, vertex_or_index_limit: 0, instance_limit: 0, @@ -3375,7 +3494,33 @@ impl Global { ) -> Result<(), PassStateError> { let scope = PassErrorScope::Draw { kind: DrawKind::MultiDrawIndirect, - indexed: true, + family: DrawCommandFamily::DrawIndexed, + }; + let base = pass_base!(pass, scope); + + base.commands.push(ArcRenderCommand::DrawIndirect { + buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), + offset, + count, + family: DrawCommandFamily::DrawIndexed, + + vertex_or_index_limit: 0, + instance_limit: 0, + }); + + Ok(()) + } + + pub fn render_pass_multi_draw_mesh_tasks_indirect( + &self, + pass: &mut RenderPass, + buffer_id: id::BufferId, + offset: BufferAddress, + count: u32, + ) -> Result<(), RenderPassError> { + let scope = PassErrorScope::Draw { + kind: DrawKind::MultiDrawIndirect, + family: DrawCommandFamily::DrawMeshTasks, }; let base = pass_base!(pass, scope); @@ -3383,7 +3528,7 @@ impl Global { buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), offset, count, - indexed: true, + family: DrawCommandFamily::DrawMeshTasks, vertex_or_index_limit: 0, instance_limit: 0, @@ -3403,7 +3548,7 @@ impl Global { ) -> Result<(), PassStateError> { let scope = PassErrorScope::Draw { kind: DrawKind::MultiDrawIndirectCount, - indexed: false, + family: DrawCommandFamily::Draw, }; let base = pass_base!(pass, scope); @@ -3418,7 +3563,7 @@ impl Global { ), count_buffer_offset, max_count, - indexed: false, + family: DrawCommandFamily::Draw, }); Ok(()) @@ -3435,7 +3580,39 @@ impl Global { ) -> Result<(), PassStateError> { let scope = PassErrorScope::Draw { kind: DrawKind::MultiDrawIndirectCount, - indexed: true, + family: DrawCommandFamily::DrawIndexed, + }; + let base = pass_base!(pass, scope); + + base.commands + .push(ArcRenderCommand::MultiDrawIndirectCount { + buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), + offset, + count_buffer: pass_try!( + base, + scope, + self.resolve_render_pass_buffer_id(count_buffer_id) + ), + count_buffer_offset, + max_count, + family: DrawCommandFamily::DrawIndexed, + }); + + Ok(()) + } + + pub fn render_pass_multi_draw_mesh_tasks_indirect_count( + &self, + pass: &mut RenderPass, + buffer_id: id::BufferId, + offset: BufferAddress, + count_buffer_id: id::BufferId, + count_buffer_offset: BufferAddress, + max_count: u32, + ) -> Result<(), RenderPassError> { + let scope = PassErrorScope::Draw { + kind: DrawKind::MultiDrawIndirectCount, + family: DrawCommandFamily::DrawMeshTasks, }; let base = pass_base!(pass, scope); @@ -3450,7 +3627,7 @@ impl Global { ), count_buffer_offset, max_count, - indexed: true, + family: DrawCommandFamily::DrawMeshTasks, }); Ok(()) @@ -3607,9 +3784,10 @@ impl Global { } } -pub(crate) const fn get_stride_of_indirect_args(indexed: bool) -> u64 { - match indexed { - false => size_of::() as u64, - true => size_of::() as u64, +pub(crate) const fn get_stride_of_indirect_args(family: DrawCommandFamily) -> u64 { + match family { + DrawCommandFamily::Draw => size_of::() as u64, + DrawCommandFamily::DrawIndexed => size_of::() as u64, + DrawCommandFamily::DrawMeshTasks => size_of::() as u64, } } diff --git a/wgpu-core/src/command/render_command.rs b/wgpu-core/src/command/render_command.rs index 6564238548f..f2972f9949d 100644 --- a/wgpu-core/src/command/render_command.rs +++ b/wgpu-core/src/command/render_command.rs @@ -2,7 +2,7 @@ use alloc::sync::Arc; use wgt::{BufferAddress, BufferSize, Color}; -use super::{Rect, RenderBundle}; +use super::{DrawCommandFamily, Rect, RenderBundle}; use crate::{ binding_model::BindGroup, id, @@ -82,11 +82,16 @@ pub enum RenderCommand { base_vertex: i32, first_instance: u32, }, + DrawMeshTasks { + group_count_x: u32, + group_count_y: u32, + group_count_z: u32, + }, DrawIndirect { buffer_id: id::BufferId, offset: BufferAddress, count: u32, - indexed: bool, + family: DrawCommandFamily, }, MultiDrawIndirectCount { buffer_id: id::BufferId, @@ -94,7 +99,7 @@ pub enum RenderCommand { count_buffer_id: id::BufferId, count_buffer_offset: BufferAddress, max_count: u32, - indexed: bool, + family: DrawCommandFamily, }, PushDebugGroup { color: u32, @@ -310,12 +315,21 @@ impl RenderCommand { base_vertex, first_instance, }, + RenderCommand::DrawMeshTasks { + group_count_x, + group_count_y, + group_count_z, + } => ArcRenderCommand::DrawMeshTasks { + group_count_x, + group_count_y, + group_count_z, + }, RenderCommand::DrawIndirect { buffer_id, offset, count, - indexed, + family, } => ArcRenderCommand::DrawIndirect { buffer: buffers_guard.get(buffer_id).get().map_err(|e| { RenderPassError { @@ -325,14 +339,14 @@ impl RenderCommand { } else { DrawKind::DrawIndirect }, - indexed, + family, }, inner: e.into(), } })?, offset, count, - indexed, + family, vertex_or_index_limit: 0, instance_limit: 0, @@ -344,11 +358,11 @@ impl RenderCommand { count_buffer_id, count_buffer_offset, max_count, - indexed, + family, } => { let scope = PassErrorScope::Draw { kind: DrawKind::MultiDrawIndirectCount, - indexed, + family, }; ArcRenderCommand::MultiDrawIndirectCount { buffer: buffers_guard.get(buffer_id).get().map_err(|e| { @@ -366,7 +380,7 @@ impl RenderCommand { )?, count_buffer_offset, max_count, - indexed, + family, } } @@ -473,11 +487,16 @@ pub enum ArcRenderCommand { base_vertex: i32, first_instance: u32, }, + DrawMeshTasks { + group_count_x: u32, + group_count_y: u32, + group_count_z: u32, + }, DrawIndirect { buffer: Arc, offset: BufferAddress, count: u32, - indexed: bool, + family: DrawCommandFamily, /// This limit is only populated for commands in a [`RenderBundle`]. vertex_or_index_limit: u64, @@ -490,7 +509,7 @@ pub enum ArcRenderCommand { count_buffer: Arc, count_buffer_offset: BufferAddress, max_count: u32, - indexed: bool, + family: DrawCommandFamily, }, PushDebugGroup { #[cfg_attr(not(any(feature = "serde", feature = "replay")), allow(dead_code))] diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index a76b24537cc..92f10fc07fc 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -16,8 +16,9 @@ use crate::{ id::{self, AdapterId, DeviceId, QueueId, SurfaceId}, instance::{self, Adapter, Surface}, pipeline::{ - self, ResolvedComputePipelineDescriptor, ResolvedFragmentState, - ResolvedProgrammableStageDescriptor, ResolvedRenderPipelineDescriptor, ResolvedVertexState, + self, RenderPipelineVertexProcessor, ResolvedComputePipelineDescriptor, + ResolvedFragmentState, ResolvedGeneralRenderPipelineDescriptor, ResolvedMeshState, + ResolvedProgrammableStageDescriptor, ResolvedTaskState, ResolvedVertexState, }, present, resource::{ @@ -1346,17 +1347,55 @@ impl Global { let fid = hub.render_pipelines.prepare(id_in); - let error = 'error: { - let device = self.hub.devices.get(device_id); + let device = self.hub.devices.get(device_id); + #[cfg(feature = "trace")] + if let Some(ref mut trace) = *device.trace.lock() { + trace.add(trace::Action::CreateRenderPipeline { + id: fid.id(), + desc: desc.clone(), + }); + } + self.device_create_general_render_pipeline(desc.clone().into(), device, fid) + } - #[cfg(feature = "trace")] - if let Some(ref mut trace) = *device.trace.lock() { - trace.add(trace::Action::CreateRenderPipeline { - id: fid.id(), - desc: desc.clone(), - }); - } + pub fn device_create_mesh_pipeline( + &self, + device_id: DeviceId, + desc: &pipeline::MeshPipelineDescriptor, + id_in: Option, + ) -> ( + id::RenderPipelineId, + Option, + ) { + let hub = &self.hub; + + let fid = hub.render_pipelines.prepare(id_in); + + let device = self.hub.devices.get(device_id); + #[cfg(feature = "trace")] + if let Some(ref mut trace) = *device.trace.lock() { + trace.add(trace::Action::CreateMeshPipeline { + id: fid.id(), + desc: desc.clone(), + }); + } + self.device_create_general_render_pipeline(desc.clone().into(), device, fid) + } + fn device_create_general_render_pipeline( + &self, + desc: pipeline::GeneralRenderPipelineDescriptor, + device: Arc, + fid: crate::registry::FutureId>, + ) -> ( + id::RenderPipelineId, + Option, + ) { + profiling::scope!("Device::create_general_render_pipeline"); + + let hub = &self.hub; + + let error = 'error: { if let Err(e) = device.check_is_valid() { break 'error e.into(); } @@ -1379,31 +1418,83 @@ impl Global { Err(e) => break 'error e.into(), }; - let vertex = { - let module = hub - .shader_modules - .get(desc.vertex.stage.module) - .get() - .map_err(|e| pipeline::CreateRenderPipelineError::Stage { - stage: wgt::ShaderStages::VERTEX, - error: e.into(), - }); - let module = match module { - Ok(module) => module, - Err(e) => break 'error e, - }; - let stage = ResolvedProgrammableStageDescriptor { - module, - entry_point: desc.vertex.stage.entry_point.clone(), - constants: desc.vertex.stage.constants.clone(), - zero_initialize_workgroup_memory: desc - .vertex - .stage - .zero_initialize_workgroup_memory, - }; - ResolvedVertexState { - stage, - buffers: desc.vertex.buffers.clone(), + let vertex = match desc.vertex { + RenderPipelineVertexProcessor::Vertex(ref vertex) => { + let module = hub + .shader_modules + .get(vertex.stage.module) + .get() + .map_err(|e| pipeline::CreateRenderPipelineError::Stage { + stage: wgt::ShaderStages::VERTEX, + error: e.into(), + }); + let module = match module { + Ok(module) => module, + Err(e) => break 'error e, + }; + let stage = ResolvedProgrammableStageDescriptor { + module, + entry_point: vertex.stage.entry_point.clone(), + constants: vertex.stage.constants.clone(), + zero_initialize_workgroup_memory: vertex + .stage + .zero_initialize_workgroup_memory, + }; + RenderPipelineVertexProcessor::Vertex(ResolvedVertexState { + stage, + buffers: vertex.buffers.clone(), + }) + } + RenderPipelineVertexProcessor::Mesh(ref task, ref mesh) => { + let task_module = if let Some(task) = task { + let module = hub + .shader_modules + .get(task.stage.module) + .get() + .map_err(|e| pipeline::CreateRenderPipelineError::Stage { + stage: wgt::ShaderStages::VERTEX, + error: e.into(), + }); + let module = match module { + Ok(module) => module, + Err(e) => break 'error e, + }; + let state = ResolvedProgrammableStageDescriptor { + module, + entry_point: task.stage.entry_point.clone(), + constants: task.stage.constants.clone(), + zero_initialize_workgroup_memory: task + .stage + .zero_initialize_workgroup_memory, + }; + Some(ResolvedTaskState { stage: state }) + } else { + None + }; + let mesh_module = + hub.shader_modules + .get(mesh.stage.module) + .get() + .map_err(|e| pipeline::CreateRenderPipelineError::Stage { + stage: wgt::ShaderStages::MESH, + error: e.into(), + }); + let mesh_module = match mesh_module { + Ok(module) => module, + Err(e) => break 'error e, + }; + let mesh_stage = ResolvedProgrammableStageDescriptor { + module: mesh_module, + entry_point: mesh.stage.entry_point.clone(), + constants: mesh.stage.constants.clone(), + zero_initialize_workgroup_memory: mesh + .stage + .zero_initialize_workgroup_memory, + }; + RenderPipelineVertexProcessor::Mesh( + task_module, + ResolvedMeshState { stage: mesh_stage }, + ) } }; @@ -1424,10 +1515,7 @@ impl Global { module, entry_point: state.stage.entry_point.clone(), constants: state.stage.constants.clone(), - zero_initialize_workgroup_memory: desc - .vertex - .stage - .zero_initialize_workgroup_memory, + zero_initialize_workgroup_memory: state.stage.zero_initialize_workgroup_memory, }; Some(ResolvedFragmentState { stage, @@ -1437,7 +1525,7 @@ impl Global { None }; - let desc = ResolvedRenderPipelineDescriptor { + let desc = ResolvedGeneralRenderPipelineDescriptor { label: desc.label.clone(), layout, vertex, diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 3156769440d..ed03fce774b 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -3472,7 +3472,7 @@ impl Device { pub(crate) fn create_render_pipeline( self: &Arc, - desc: pipeline::ResolvedRenderPipelineDescriptor, + desc: pipeline::ResolvedGeneralRenderPipelineDescriptor, ) -> Result, pipeline::CreateRenderPipelineError> { use wgt::TextureFormatFeatureFlags as Tfff; @@ -3513,127 +3513,137 @@ impl Device { let mut io = validation::StageIo::default(); let mut validated_stages = wgt::ShaderStages::empty(); - let mut vertex_steps = Vec::with_capacity(desc.vertex.buffers.len()); - let mut vertex_buffers = Vec::with_capacity(desc.vertex.buffers.len()); - let mut total_attributes = 0; + let mut vertex_steps; + let mut vertex_buffers; + let mut total_attributes; let mut shader_expects_dual_source_blending = false; let mut pipeline_expects_dual_source_blending = false; - for (i, vb_state) in desc.vertex.buffers.iter().enumerate() { - // https://gpuweb.github.io/gpuweb/#abstract-opdef-validating-gpuvertexbufferlayout - - if vb_state.array_stride > self.limits.max_vertex_buffer_array_stride as u64 { - return Err(pipeline::CreateRenderPipelineError::VertexStrideTooLarge { - index: i as u32, - given: vb_state.array_stride as u32, - limit: self.limits.max_vertex_buffer_array_stride, - }); - } - if vb_state.array_stride % wgt::VERTEX_ALIGNMENT != 0 { - return Err(pipeline::CreateRenderPipelineError::UnalignedVertexStride { - index: i as u32, - stride: vb_state.array_stride, - }); - } - - let max_stride = if vb_state.array_stride == 0 { - self.limits.max_vertex_buffer_array_stride as u64 - } else { - vb_state.array_stride - }; - let mut last_stride = 0; - for attribute in vb_state.attributes.iter() { - let attribute_stride = attribute.offset + attribute.format.size(); - if attribute_stride > max_stride { - return Err( - pipeline::CreateRenderPipelineError::VertexAttributeStrideTooLarge { - location: attribute.shader_location, - given: attribute_stride as u32, - limit: max_stride as u32, - }, - ); + if let pipeline::RenderPipelineVertexProcessor::Vertex(ref vertex) = desc.vertex { + vertex_steps = Vec::with_capacity(vertex.buffers.len()); + vertex_buffers = Vec::with_capacity(vertex.buffers.len()); + total_attributes = 0; + shader_expects_dual_source_blending = false; + pipeline_expects_dual_source_blending = false; + for (i, vb_state) in vertex.buffers.iter().enumerate() { + // https://gpuweb.github.io/gpuweb/#abstract-opdef-validating-gpuvertexbufferlayout + + if vb_state.array_stride > self.limits.max_vertex_buffer_array_stride as u64 { + return Err(pipeline::CreateRenderPipelineError::VertexStrideTooLarge { + index: i as u32, + given: vb_state.array_stride as u32, + limit: self.limits.max_vertex_buffer_array_stride, + }); } - - let required_offset_alignment = attribute.format.size().min(4); - if attribute.offset % required_offset_alignment != 0 { - return Err( - pipeline::CreateRenderPipelineError::InvalidVertexAttributeOffset { - location: attribute.shader_location, - offset: attribute.offset, - }, - ); + if vb_state.array_stride % wgt::VERTEX_ALIGNMENT != 0 { + return Err(pipeline::CreateRenderPipelineError::UnalignedVertexStride { + index: i as u32, + stride: vb_state.array_stride, + }); } - if attribute.shader_location >= self.limits.max_vertex_attributes { - return Err( - pipeline::CreateRenderPipelineError::TooManyVertexAttributes { - given: attribute.shader_location, - limit: self.limits.max_vertex_attributes, - }, - ); - } + let max_stride = if vb_state.array_stride == 0 { + self.limits.max_vertex_buffer_array_stride as u64 + } else { + vb_state.array_stride + }; + let mut last_stride = 0; + for attribute in vb_state.attributes.iter() { + let attribute_stride = attribute.offset + attribute.format.size(); + if attribute_stride > max_stride { + return Err( + pipeline::CreateRenderPipelineError::VertexAttributeStrideTooLarge { + location: attribute.shader_location, + given: attribute_stride as u32, + limit: max_stride as u32, + }, + ); + } - last_stride = last_stride.max(attribute_stride); - } - vertex_steps.push(pipeline::VertexStep { - stride: vb_state.array_stride, - last_stride, - mode: vb_state.step_mode, - }); - if vb_state.attributes.is_empty() { - continue; - } - vertex_buffers.push(hal::VertexBufferLayout { - array_stride: vb_state.array_stride, - step_mode: vb_state.step_mode, - attributes: vb_state.attributes.as_ref(), - }); + let required_offset_alignment = attribute.format.size().min(4); + if attribute.offset % required_offset_alignment != 0 { + return Err( + pipeline::CreateRenderPipelineError::InvalidVertexAttributeOffset { + location: attribute.shader_location, + offset: attribute.offset, + }, + ); + } - for attribute in vb_state.attributes.iter() { - if attribute.offset >= 0x10000000 { - return Err( - pipeline::CreateRenderPipelineError::InvalidVertexAttributeOffset { - location: attribute.shader_location, - offset: attribute.offset, - }, - ); - } + if attribute.shader_location >= self.limits.max_vertex_attributes { + return Err( + pipeline::CreateRenderPipelineError::TooManyVertexAttributes { + given: attribute.shader_location, + limit: self.limits.max_vertex_attributes, + }, + ); + } - if let wgt::VertexFormat::Float64 - | wgt::VertexFormat::Float64x2 - | wgt::VertexFormat::Float64x3 - | wgt::VertexFormat::Float64x4 = attribute.format - { - self.require_features(wgt::Features::VERTEX_ATTRIBUTE_64BIT)?; + last_stride = last_stride.max(attribute_stride); } + vertex_steps.push(pipeline::VertexStep { + stride: vb_state.array_stride, + last_stride, + mode: vb_state.step_mode, + }); + if vb_state.attributes.is_empty() { + continue; + } + vertex_buffers.push(hal::VertexBufferLayout { + array_stride: vb_state.array_stride, + step_mode: vb_state.step_mode, + attributes: vb_state.attributes.as_ref(), + }); - let previous = io.insert( - attribute.shader_location, - validation::InterfaceVar::vertex_attribute(attribute.format), - ); + for attribute in vb_state.attributes.iter() { + if attribute.offset >= 0x10000000 { + return Err( + pipeline::CreateRenderPipelineError::InvalidVertexAttributeOffset { + location: attribute.shader_location, + offset: attribute.offset, + }, + ); + } - if previous.is_some() { - return Err(pipeline::CreateRenderPipelineError::ShaderLocationClash( + if let wgt::VertexFormat::Float64 + | wgt::VertexFormat::Float64x2 + | wgt::VertexFormat::Float64x3 + | wgt::VertexFormat::Float64x4 = attribute.format + { + self.require_features(wgt::Features::VERTEX_ATTRIBUTE_64BIT)?; + } + + let previous = io.insert( attribute.shader_location, - )); + validation::InterfaceVar::vertex_attribute(attribute.format), + ); + + if previous.is_some() { + return Err(pipeline::CreateRenderPipelineError::ShaderLocationClash( + attribute.shader_location, + )); + } } + total_attributes += vb_state.attributes.len(); } - total_attributes += vb_state.attributes.len(); - } - if vertex_buffers.len() > self.limits.max_vertex_buffers as usize { - return Err(pipeline::CreateRenderPipelineError::TooManyVertexBuffers { - given: vertex_buffers.len() as u32, - limit: self.limits.max_vertex_buffers, - }); - } - if total_attributes > self.limits.max_vertex_attributes as usize { - return Err( - pipeline::CreateRenderPipelineError::TooManyVertexAttributes { - given: total_attributes as u32, - limit: self.limits.max_vertex_attributes, - }, - ); - } + if vertex_buffers.len() > self.limits.max_vertex_buffers as usize { + return Err(pipeline::CreateRenderPipelineError::TooManyVertexBuffers { + given: vertex_buffers.len() as u32, + limit: self.limits.max_vertex_buffers, + }); + } + if total_attributes > self.limits.max_vertex_attributes as usize { + return Err( + pipeline::CreateRenderPipelineError::TooManyVertexAttributes { + given: total_attributes as u32, + limit: self.limits.max_vertex_attributes, + }, + ); + } + } else { + vertex_steps = Vec::new(); + vertex_buffers = Vec::new(); + }; if desc.primitive.strip_index_format.is_some() && !desc.primitive.topology.is_strip() { return Err( @@ -3843,44 +3853,132 @@ impl Device { sc }; - let vertex_entry_point_name; - let vertex_stage = { - let stage_desc = &desc.vertex.stage; - let stage = wgt::ShaderStages::VERTEX; + let mut vertex_stage = None; + let mut task_stage = None; + let mut mesh_stage = None; + let mut _vertex_entry_point_name = String::new(); + let mut _task_entry_point_name = String::new(); + let mut _mesh_entry_point_name = String::new(); + match desc.vertex { + pipeline::RenderPipelineVertexProcessor::Vertex(ref vertex) => { + vertex_stage = { + let stage_desc = &vertex.stage; + let stage = wgt::ShaderStages::VERTEX; + + let vertex_shader_module = &stage_desc.module; + vertex_shader_module.same_device(self)?; + + let stage_err = + |error| pipeline::CreateRenderPipelineError::Stage { stage, error }; + + _vertex_entry_point_name = vertex_shader_module + .finalize_entry_point_name( + stage, + stage_desc.entry_point.as_ref().map(|ep| ep.as_ref()), + ) + .map_err(stage_err)?; - let vertex_shader_module = &stage_desc.module; - vertex_shader_module.same_device(self)?; + if let Some(ref interface) = vertex_shader_module.interface { + io = interface + .check_stage( + &mut binding_layout_source, + &mut shader_binding_sizes, + &_vertex_entry_point_name, + stage, + io, + desc.depth_stencil.as_ref().map(|d| d.depth_compare), + ) + .map_err(stage_err)?; + validated_stages |= stage; + } + Some(hal::ProgrammableStage { + module: vertex_shader_module.raw(), + entry_point: &_vertex_entry_point_name, + constants: &stage_desc.constants, + zero_initialize_workgroup_memory: stage_desc + .zero_initialize_workgroup_memory, + }) + }; + } + pipeline::RenderPipelineVertexProcessor::Mesh(ref task, ref mesh) => { + task_stage = if let Some(task) = task { + let stage_desc = &task.stage; + let stage = wgt::ShaderStages::TASK; + let task_shader_module = &stage_desc.module; + task_shader_module.same_device(self)?; + + let stage_err = + |error| pipeline::CreateRenderPipelineError::Stage { stage, error }; + + _task_entry_point_name = task_shader_module + .finalize_entry_point_name( + stage, + stage_desc.entry_point.as_ref().map(|ep| ep.as_ref()), + ) + .map_err(stage_err)?; - let stage_err = |error| pipeline::CreateRenderPipelineError::Stage { stage, error }; + if let Some(ref interface) = task_shader_module.interface { + io = interface + .check_stage( + &mut binding_layout_source, + &mut shader_binding_sizes, + &_task_entry_point_name, + stage, + io, + desc.depth_stencil.as_ref().map(|d| d.depth_compare), + ) + .map_err(stage_err)?; + validated_stages |= stage; + } + Some(hal::ProgrammableStage { + module: task_shader_module.raw(), + entry_point: &_task_entry_point_name, + constants: &stage_desc.constants, + zero_initialize_workgroup_memory: stage_desc + .zero_initialize_workgroup_memory, + }) + } else { + None + }; + mesh_stage = { + let stage_desc = &mesh.stage; + let stage = wgt::ShaderStages::MESH; + let mesh_shader_module = &stage_desc.module; + mesh_shader_module.same_device(self)?; - vertex_entry_point_name = vertex_shader_module - .finalize_entry_point_name( - stage, - stage_desc.entry_point.as_ref().map(|ep| ep.as_ref()), - ) - .map_err(stage_err)?; - - if let Some(ref interface) = vertex_shader_module.interface { - io = interface - .check_stage( - &mut binding_layout_source, - &mut shader_binding_sizes, - &vertex_entry_point_name, - stage, - io, - desc.depth_stencil.as_ref().map(|d| d.depth_compare), - ) - .map_err(stage_err)?; - validated_stages |= stage; - } + let stage_err = + |error| pipeline::CreateRenderPipelineError::Stage { stage, error }; - hal::ProgrammableStage { - module: vertex_shader_module.raw(), - entry_point: &vertex_entry_point_name, - constants: &stage_desc.constants, - zero_initialize_workgroup_memory: stage_desc.zero_initialize_workgroup_memory, + _mesh_entry_point_name = mesh_shader_module + .finalize_entry_point_name( + stage, + stage_desc.entry_point.as_ref().map(|ep| ep.as_ref()), + ) + .map_err(stage_err)?; + + if let Some(ref interface) = mesh_shader_module.interface { + io = interface + .check_stage( + &mut binding_layout_source, + &mut shader_binding_sizes, + &_mesh_entry_point_name, + stage, + io, + desc.depth_stencil.as_ref().map(|d| d.depth_compare), + ) + .map_err(stage_err)?; + validated_stages |= stage; + } + Some(hal::ProgrammableStage { + module: mesh_shader_module.raw(), + entry_point: &_mesh_entry_point_name, + constants: &stage_desc.constants, + zero_initialize_workgroup_memory: stage_desc + .zero_initialize_workgroup_memory, + }) + }; } - }; + } let fragment_entry_point_name; let fragment_stage = match desc.fragment { @@ -4029,20 +4127,29 @@ impl Device { None => None, }; - let pipeline_desc = hal::RenderPipelineDescriptor { - label: desc.label.to_hal(self.instance_flags), - layout: pipeline_layout.raw(), - vertex_buffers: &vertex_buffers, - vertex_stage, - primitive: desc.primitive, - depth_stencil: desc.depth_stencil.clone(), - multisample: desc.multisample, - fragment_stage, - color_targets, - multiview: desc.multiview, - cache: cache.as_ref().map(|it| it.raw()), - }; - let raw = + let is_mesh = mesh_stage.is_some(); + let raw = { + let pipeline_desc = hal::RenderPipelineDescriptor { + label: desc.label.to_hal(self.instance_flags), + layout: pipeline_layout.raw(), + vertex_processor: match vertex_stage { + Some(vertex_stage) => hal::VertexProcessor::Standard { + vertex_buffers: &vertex_buffers, + vertex_stage, + }, + None => hal::VertexProcessor::Mesh { + task_stage, + mesh_stage: mesh_stage.unwrap(), + }, + }, + primitive: desc.primitive, + depth_stencil: desc.depth_stencil.clone(), + multisample: desc.multisample, + fragment_stage, + color_targets, + multiview: desc.multiview, + cache: cache.as_ref().map(|it| it.raw()), + }; unsafe { self.raw().create_render_pipeline(&pipeline_desc) }.map_err( |err| match err { hal::PipelineError::Device(error) => { @@ -4061,7 +4168,8 @@ impl Device { pipeline::CreateRenderPipelineError::PipelineConstants { stage, error } } }, - )?; + )? + }; let pass_context = RenderPassContext { attachments: AttachmentData { @@ -4095,10 +4203,19 @@ impl Device { flags |= pipeline::PipelineFlags::WRITES_STENCIL; } } - let shader_modules = { let mut shader_modules = ArrayVec::new(); - shader_modules.push(desc.vertex.stage.module); + match desc.vertex { + pipeline::RenderPipelineVertexProcessor::Vertex(vertex) => { + shader_modules.push(vertex.stage.module) + } + pipeline::RenderPipelineVertexProcessor::Mesh(task, mesh) => { + if let Some(task) = task { + shader_modules.push(task.stage.module); + } + shader_modules.push(mesh.stage.module); + } + } shader_modules.extend(desc.fragment.map(|f| f.stage.module)); shader_modules }; @@ -4115,6 +4232,7 @@ impl Device { late_sized_buffer_groups, label: desc.label.to_string(), tracking_data: TrackingData::new(self.tracker_indices.render_pipelines.clone()), + is_mesh, }; let pipeline = Arc::new(pipeline); diff --git a/wgpu-core/src/device/trace.rs b/wgpu-core/src/device/trace.rs index 602264b5c35..58d26e4b079 100644 --- a/wgpu-core/src/device/trace.rs +++ b/wgpu-core/src/device/trace.rs @@ -103,6 +103,10 @@ pub enum Action<'a> { id: id::RenderPipelineId, desc: crate::pipeline::RenderPipelineDescriptor<'a>, }, + CreateMeshPipeline { + id: id::RenderPipelineId, + desc: crate::pipeline::MeshPipelineDescriptor<'a>, + }, DestroyRenderPipeline(id::RenderPipelineId), CreatePipelineCache { id: id::PipelineCacheId, diff --git a/wgpu-core/src/indirect_validation/draw.rs b/wgpu-core/src/indirect_validation/draw.rs index 886fc5bc9b7..db23b0469d7 100644 --- a/wgpu-core/src/indirect_validation/draw.rs +++ b/wgpu-core/src/indirect_validation/draw.rs @@ -919,7 +919,7 @@ impl DrawBatcher { device: &Device, src_buffer: &Arc, offset: u64, - indexed: bool, + family: crate::command::DrawCommandFamily, vertex_or_index_limit: u64, instance_limit: u64, ) -> Result<(usize, u64), DeviceError> { @@ -929,7 +929,7 @@ impl DrawBatcher { } else { 0 }; - let stride = extra + crate::command::get_stride_of_indirect_args(indexed); + let stride = extra + crate::command::get_stride_of_indirect_args(family); let (dst_resource_index, dst_offset) = indirect_draw_validation_resources .get_dst_subrange(stride, &mut self.current_dst_entry)?; @@ -941,7 +941,7 @@ impl DrawBatcher { let src_buffer_tracker_index = src_buffer.tracker_index(); let entry = MetadataEntry::new( - indexed, + family == crate::command::DrawCommandFamily::DrawIndexed, src_offset, dst_offset, vertex_or_index_limit, diff --git a/wgpu-core/src/pipeline.rs b/wgpu-core/src/pipeline.rs index 7d055b7052b..f67cc65e2af 100644 --- a/wgpu-core/src/pipeline.rs +++ b/wgpu-core/src/pipeline.rs @@ -402,6 +402,33 @@ pub struct FragmentState<'a, SM = ShaderModuleId> { /// cbindgen:ignore pub type ResolvedFragmentState<'a> = FragmentState<'a, Arc>; +/// Describes the task shader in a mesh shader pipeline. +#[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct TaskState<'a, SM = ShaderModuleId> { + /// The compiled task stage and its entry point. + pub stage: ProgrammableStageDescriptor<'a, SM>, +} + +pub type ResolvedTaskState<'a> = TaskState<'a, Arc>; + +/// Describes the mesh shader in a mesh shader pipeline. +#[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct MeshState<'a, SM = ShaderModuleId> { + /// The compiled mesh stage and its entry point. + pub stage: ProgrammableStageDescriptor<'a, SM>, +} + +pub type ResolvedMeshState<'a> = MeshState<'a, Arc>; + +#[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub(crate) enum RenderPipelineVertexProcessor<'a, SM = ShaderModuleId> { + Vertex(VertexState<'a, SM>), + Mesh(Option>, MeshState<'a, SM>), +} + /// Describes a render (graphics) pipeline. #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -433,10 +460,109 @@ pub struct RenderPipelineDescriptor< /// The pipeline cache to use when creating this pipeline. pub cache: Option, } +/// Describes a mesh shader pipeline. +#[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct MeshPipelineDescriptor< + 'a, + PLL = PipelineLayoutId, + SM = ShaderModuleId, + PLC = PipelineCacheId, +> { + pub label: Label<'a>, + /// The layout of bind groups for this pipeline. + pub layout: Option, + /// The task processing state for this pipeline. + pub task: Option>, + /// The mesh processing state for this pipeline + pub mesh: MeshState<'a, SM>, + /// The properties of the pipeline at the primitive assembly and rasterization level. + #[cfg_attr(feature = "serde", serde(default))] + pub primitive: wgt::PrimitiveState, + /// The effect of draw calls on the depth and stencil aspects of the output target, if any. + #[cfg_attr(feature = "serde", serde(default))] + pub depth_stencil: Option, + /// The multi-sampling properties of the pipeline. + #[cfg_attr(feature = "serde", serde(default))] + pub multisample: wgt::MultisampleState, + /// The fragment processing state for this pipeline. + pub fragment: Option>, + /// If the pipeline will be used with a multiview render pass, this indicates how many array + /// layers the attachments will have. + pub multiview: Option, + /// The pipeline cache to use when creating this pipeline. + pub cache: Option, +} + +/// Describes a render (graphics) pipeline. +#[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub(crate) struct GeneralRenderPipelineDescriptor< + 'a, + PLL = PipelineLayoutId, + SM = ShaderModuleId, + PLC = PipelineCacheId, +> { + pub label: Label<'a>, + /// The layout of bind groups for this pipeline. + pub layout: Option, + /// The vertex processing state for this pipeline. + pub vertex: RenderPipelineVertexProcessor<'a, SM>, + /// The properties of the pipeline at the primitive assembly and rasterization level. + #[cfg_attr(feature = "serde", serde(default))] + pub primitive: wgt::PrimitiveState, + /// The effect of draw calls on the depth and stencil aspects of the output target, if any. + #[cfg_attr(feature = "serde", serde(default))] + pub depth_stencil: Option, + /// The multi-sampling properties of the pipeline. + #[cfg_attr(feature = "serde", serde(default))] + pub multisample: wgt::MultisampleState, + /// The fragment processing state for this pipeline. + pub fragment: Option>, + /// If the pipeline will be used with a multiview render pass, this indicates how many array + /// layers the attachments will have. + pub multiview: Option, + /// The pipeline cache to use when creating this pipeline. + pub cache: Option, +} +impl<'a, PLL, SM, PLC> From> + for GeneralRenderPipelineDescriptor<'a, PLL, SM, PLC> +{ + fn from(value: RenderPipelineDescriptor<'a, PLL, SM, PLC>) -> Self { + Self { + label: value.label, + layout: value.layout, + vertex: RenderPipelineVertexProcessor::Vertex(value.vertex), + primitive: value.primitive, + depth_stencil: value.depth_stencil, + multisample: value.multisample, + fragment: value.fragment, + multiview: value.multiview, + cache: value.cache, + } + } +} +impl<'a, PLL, SM, PLC> From> + for GeneralRenderPipelineDescriptor<'a, PLL, SM, PLC> +{ + fn from(value: MeshPipelineDescriptor<'a, PLL, SM, PLC>) -> Self { + Self { + label: value.label, + layout: value.layout, + vertex: RenderPipelineVertexProcessor::Mesh(value.task, value.mesh), + primitive: value.primitive, + depth_stencil: value.depth_stencil, + multisample: value.multisample, + fragment: value.fragment, + multiview: value.multiview, + cache: value.cache, + } + } +} /// cbindgen:ignore -pub type ResolvedRenderPipelineDescriptor<'a> = - RenderPipelineDescriptor<'a, Arc, Arc, Arc>; +pub(crate) type ResolvedGeneralRenderPipelineDescriptor<'a> = + GeneralRenderPipelineDescriptor<'a, Arc, Arc, Arc>; #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -649,6 +775,8 @@ pub struct RenderPipeline { /// The `label` from the descriptor used to create the resource. pub(crate) label: String, pub(crate) tracking_data: TrackingData, + /// Whether this is a mesh shader pipeline + pub(crate) is_mesh: bool, } impl Drop for RenderPipeline { diff --git a/wgpu-core/src/validation.rs b/wgpu-core/src/validation.rs index 5bddd8a5b0c..2127604064d 100644 --- a/wgpu-core/src/validation.rs +++ b/wgpu-core/src/validation.rs @@ -1288,6 +1288,7 @@ impl Interface { ) } naga::ShaderStage::Compute => (false, 0), + // TODO: add validation for these, see https://github.com/gfx-rs/wgpu/issues/8003 naga::ShaderStage::Task | naga::ShaderStage::Mesh => { unreachable!() } diff --git a/wgpu-hal/examples/halmark/main.rs b/wgpu-hal/examples/halmark/main.rs index 36675e3b705..22f211c909b 100644 --- a/wgpu-hal/examples/halmark/main.rs +++ b/wgpu-hal/examples/halmark/main.rs @@ -254,13 +254,15 @@ impl Example { let pipeline_desc = hal::RenderPipelineDescriptor { label: None, layout: &pipeline_layout, - vertex_stage: hal::ProgrammableStage { - module: &shader, - entry_point: "vs_main", - constants: &constants, - zero_initialize_workgroup_memory: true, + vertex_processor: hal::VertexProcessor::Standard { + vertex_stage: hal::ProgrammableStage { + module: &shader, + entry_point: "vs_main", + constants: &constants, + zero_initialize_workgroup_memory: true, + }, + vertex_buffers: &[], }, - vertex_buffers: &[], fragment_stage: Some(hal::ProgrammableStage { module: &shader, entry_point: "fs_main", diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index 5c0bee01732..22d52be4d7e 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -613,6 +613,12 @@ impl super::Adapter { // store buffer sizes using 32 bit ints (a situation we have already encountered with vulkan). max_buffer_size: i32::MAX as u64, max_non_sampler_bindings: 1_000_000, + + max_task_workgroup_total_count: 0, + max_task_workgroups_per_dimension: 0, + max_mesh_multiview_count: 0, + max_mesh_output_layers: 0, + max_blas_primitive_count: if supports_ray_tracing { 1 << 29 // 2^29 } else { diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 7d245e8ce31..5d3a6ac8d45 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -1747,8 +1747,16 @@ impl crate::Device for super::Device { let (topology_class, topology) = conv::map_topology(desc.primitive.topology); let mut shader_stages = wgt::ShaderStages::VERTEX; + let (vertex_stage_desc, vertex_buffers_desc) = match &desc.vertex_processor { + crate::VertexProcessor::Standard { + vertex_buffers, + vertex_stage, + } => (vertex_stage, *vertex_buffers), + crate::VertexProcessor::Mesh { .. } => unreachable!(), + }; + let blob_vs = self.load_shader( - &desc.vertex_stage, + vertex_stage_desc, desc.layout, naga::ShaderStage::Vertex, desc.fragment_stage.as_ref(), @@ -1765,7 +1773,7 @@ impl crate::Device for super::Device { let mut input_element_descs = Vec::new(); for (i, (stride, vbuf)) in vertex_strides .iter_mut() - .zip(desc.vertex_buffers) + .zip(vertex_buffers_desc) .enumerate() { *stride = NonZeroU32::new(vbuf.array_stride as u32); @@ -1919,17 +1927,6 @@ impl crate::Device for super::Device { }) } - unsafe fn create_mesh_pipeline( - &self, - _desc: &crate::MeshPipelineDescriptor< - ::PipelineLayout, - ::ShaderModule, - ::PipelineCache, - >, - ) -> Result<::RenderPipeline, crate::PipelineError> { - unreachable!() - } - unsafe fn destroy_render_pipeline(&self, _pipeline: super::RenderPipeline) { self.counters.render_pipelines.sub(1); } diff --git a/wgpu-hal/src/dynamic/device.rs b/wgpu-hal/src/dynamic/device.rs index de66b1619f6..1f6ed912689 100644 --- a/wgpu-hal/src/dynamic/device.rs +++ b/wgpu-hal/src/dynamic/device.rs @@ -4,10 +4,10 @@ use crate::{ AccelerationStructureBuildSizes, AccelerationStructureDescriptor, Api, BindGroupDescriptor, BindGroupLayoutDescriptor, BufferDescriptor, BufferMapping, CommandEncoderDescriptor, ComputePipelineDescriptor, Device, DeviceError, FenceValue, - GetAccelerationStructureBuildSizesDescriptor, Label, MemoryRange, MeshPipelineDescriptor, - PipelineCacheDescriptor, PipelineCacheError, PipelineError, PipelineLayoutDescriptor, - RenderPipelineDescriptor, SamplerDescriptor, ShaderError, ShaderInput, ShaderModuleDescriptor, - TextureDescriptor, TextureViewDescriptor, TlasInstance, + GetAccelerationStructureBuildSizesDescriptor, Label, MemoryRange, PipelineCacheDescriptor, + PipelineCacheError, PipelineError, PipelineLayoutDescriptor, RenderPipelineDescriptor, + SamplerDescriptor, ShaderError, ShaderInput, ShaderModuleDescriptor, TextureDescriptor, + TextureViewDescriptor, TlasInstance, }; use super::{ @@ -100,14 +100,6 @@ pub trait DynDevice: DynResource { dyn DynPipelineCache, >, ) -> Result, PipelineError>; - unsafe fn create_mesh_pipeline( - &self, - desc: &MeshPipelineDescriptor< - dyn DynPipelineLayout, - dyn DynShaderModule, - dyn DynPipelineCache, - >, - ) -> Result, PipelineError>; unsafe fn destroy_render_pipeline(&self, pipeline: Box); unsafe fn create_compute_pipeline( @@ -394,8 +386,22 @@ impl DynDevice for D { let desc = RenderPipelineDescriptor { label: desc.label, layout: desc.layout.expect_downcast_ref(), - vertex_buffers: desc.vertex_buffers, - vertex_stage: desc.vertex_stage.clone().expect_downcast(), + vertex_processor: match &desc.vertex_processor { + crate::VertexProcessor::Standard { + vertex_buffers, + vertex_stage, + } => crate::VertexProcessor::Standard { + vertex_buffers, + vertex_stage: vertex_stage.clone().expect_downcast(), + }, + crate::VertexProcessor::Mesh { + task_stage: task, + mesh_stage: mesh, + } => crate::VertexProcessor::Mesh { + task_stage: task.as_ref().map(|a| a.clone().expect_downcast()), + mesh_stage: mesh.clone().expect_downcast(), + }, + }, primitive: desc.primitive, depth_stencil: desc.depth_stencil.clone(), multisample: desc.multisample, @@ -409,32 +415,6 @@ impl DynDevice for D { .map(|b| -> Box { Box::new(b) }) } - unsafe fn create_mesh_pipeline( - &self, - desc: &MeshPipelineDescriptor< - dyn DynPipelineLayout, - dyn DynShaderModule, - dyn DynPipelineCache, - >, - ) -> Result, PipelineError> { - let desc = MeshPipelineDescriptor { - label: desc.label, - layout: desc.layout.expect_downcast_ref(), - task_stage: desc.task_stage.clone().map(|f| f.expect_downcast()), - mesh_stage: desc.mesh_stage.clone().expect_downcast(), - primitive: desc.primitive, - depth_stencil: desc.depth_stencil.clone(), - multisample: desc.multisample, - fragment_stage: desc.fragment_stage.clone().map(|f| f.expect_downcast()), - color_targets: desc.color_targets, - multiview: desc.multiview, - cache: desc.cache.map(|c| c.expect_downcast_ref()), - }; - - unsafe { D::create_mesh_pipeline(self, &desc) } - .map(|b| -> Box { Box::new(b) }) - } - unsafe fn destroy_render_pipeline(&self, pipeline: Box) { unsafe { D::destroy_render_pipeline(self, pipeline.unbox()) }; } diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index d9d2812ccdd..865f35013c7 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -801,6 +801,12 @@ impl super::Adapter { max_compute_workgroups_per_dimension, max_buffer_size: i32::MAX as u64, max_non_sampler_bindings: u32::MAX, + + max_task_workgroup_total_count: 0, + max_task_workgroups_per_dimension: 0, + max_mesh_multiview_count: 0, + max_mesh_output_layers: 0, + max_blas_primitive_count: 0, max_blas_geometry_count: 0, max_tlas_instance_count: 0, diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index be9cc03fbe5..0b1b77e11bc 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -1363,9 +1363,16 @@ impl crate::Device for super::Device { super::PipelineCache, >, ) -> Result { + let (vertex_stage, vertex_buffers) = match &desc.vertex_processor { + crate::VertexProcessor::Standard { + vertex_buffers, + ref vertex_stage, + } => (vertex_stage, vertex_buffers), + crate::VertexProcessor::Mesh { .. } => unreachable!(), + }; let gl = &self.shared.context.lock(); let mut shaders = ArrayVec::new(); - shaders.push((naga::ShaderStage::Vertex, &desc.vertex_stage)); + shaders.push((naga::ShaderStage::Vertex, vertex_stage)); if let Some(ref fs) = desc.fragment_stage { shaders.push((naga::ShaderStage::Fragment, fs)); } @@ -1375,7 +1382,7 @@ impl crate::Device for super::Device { let (vertex_buffers, vertex_attributes) = { let mut buffers = Vec::new(); let mut attributes = Vec::new(); - for (index, vb_layout) in desc.vertex_buffers.iter().enumerate() { + for (index, vb_layout) in vertex_buffers.iter().enumerate() { buffers.push(super::VertexBufferDesc { step: vb_layout.step_mode, stride: vb_layout.array_stride as u32, @@ -1430,16 +1437,6 @@ impl crate::Device for super::Device { alpha_to_coverage_enabled: desc.multisample.alpha_to_coverage_enabled, }) } - unsafe fn create_mesh_pipeline( - &self, - _desc: &crate::MeshPipelineDescriptor< - ::PipelineLayout, - ::ShaderModule, - ::PipelineCache, - >, - ) -> Result<::RenderPipeline, crate::PipelineError> { - unreachable!() - } unsafe fn destroy_render_pipeline(&self, pipeline: super::RenderPipeline) { // If the pipeline only has 2 strong references remaining, they're `pipeline` and `program_cache` diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 1e92bbece34..e6b4e0b0f89 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -931,15 +931,6 @@ pub trait Device: WasmNotSendSync { ::PipelineCache, >, ) -> Result<::RenderPipeline, PipelineError>; - #[allow(clippy::type_complexity)] - unsafe fn create_mesh_pipeline( - &self, - desc: &MeshPipelineDescriptor< - ::PipelineLayout, - ::ShaderModule, - ::PipelineCache, - >, - ) -> Result<::RenderPipeline, PipelineError>; unsafe fn destroy_render_pipeline(&self, pipeline: ::RenderPipeline); #[allow(clippy::type_complexity)] @@ -2323,6 +2314,20 @@ pub struct VertexBufferLayout<'a> { pub attributes: &'a [wgt::VertexAttribute], } +#[derive(Clone, Debug)] +pub enum VertexProcessor<'a, M: DynShaderModule + ?Sized> { + Standard { + /// The format of any vertex buffers used with this pipeline. + vertex_buffers: &'a [VertexBufferLayout<'a>], + /// The vertex stage for this pipeline. + vertex_stage: ProgrammableStage<'a, M>, + }, + Mesh { + task_stage: Option>, + mesh_stage: ProgrammableStage<'a, M>, + }, +} + /// Describes a render (graphics) pipeline. #[derive(Clone, Debug)] pub struct RenderPipelineDescriptor< @@ -2334,37 +2339,8 @@ pub struct RenderPipelineDescriptor< pub label: Label<'a>, /// The layout of bind groups for this pipeline. pub layout: &'a Pl, - /// The format of any vertex buffers used with this pipeline. - pub vertex_buffers: &'a [VertexBufferLayout<'a>], - /// The vertex stage for this pipeline. - pub vertex_stage: ProgrammableStage<'a, M>, - /// The properties of the pipeline at the primitive assembly and rasterization level. - pub primitive: wgt::PrimitiveState, - /// The effect of draw calls on the depth and stencil aspects of the output target, if any. - pub depth_stencil: Option, - /// The multi-sampling properties of the pipeline. - pub multisample: wgt::MultisampleState, - /// The fragment stage for this pipeline. - pub fragment_stage: Option>, - /// The effect of draw calls on the color aspect of the output target. - pub color_targets: &'a [Option], - /// If the pipeline will be used with a multiview render pass, this indicates how many array - /// layers the attachments will have. - pub multiview: Option, - /// The cache which will be used and filled when compiling this pipeline - pub cache: Option<&'a Pc>, -} -pub struct MeshPipelineDescriptor< - 'a, - Pl: DynPipelineLayout + ?Sized, - M: DynShaderModule + ?Sized, - Pc: DynPipelineCache + ?Sized, -> { - pub label: Label<'a>, - /// The layout of bind groups for this pipeline. - pub layout: &'a Pl, - pub task_stage: Option>, - pub mesh_stage: ProgrammableStage<'a, M>, + /// The vertex processing state(vertex shader + buffers or task + mesh shaders) + pub vertex_processor: VertexProcessor<'a, M>, /// The properties of the pipeline at the primitive assembly and rasterization level. pub primitive: wgt::PrimitiveState, /// The effect of draw calls on the depth and stencil aspects of the output target, if any. diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index 6ecbff679f3..7ab14ca76d2 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -1077,6 +1077,12 @@ impl super::PrivateCapabilities { max_compute_workgroups_per_dimension: 0xFFFF, max_buffer_size: self.max_buffer_size, max_non_sampler_bindings: u32::MAX, + + max_task_workgroup_total_count: 0, + max_task_workgroups_per_dimension: 0, + max_mesh_multiview_count: 0, + max_mesh_output_layers: 0, + max_blas_primitive_count: 0, // When added: 2^28 from https://developer.apple.com/documentation/metal/mtlaccelerationstructureusage/extendedlimits max_blas_geometry_count: 0, // When added: 2^24 max_tlas_instance_count: 0, // When added: 2^24 diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index f4a79de640c..fbb166c2723 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -1056,6 +1056,14 @@ impl crate::Device for super::Device { super::PipelineCache, >, ) -> Result { + let (desc_vertex_stage, desc_vertex_buffers) = match &desc.vertex_processor { + crate::VertexProcessor::Standard { + vertex_buffers, + vertex_stage, + } => (vertex_stage, *vertex_buffers), + crate::VertexProcessor::Mesh { .. } => unreachable!(), + }; + objc::rc::autoreleasepool(|| { let descriptor = metal::RenderPipelineDescriptor::new(); @@ -1074,7 +1082,7 @@ impl crate::Device for super::Device { // Vertex shader let (vs_lib, vs_info) = { let mut vertex_buffer_mappings = Vec::::new(); - for (i, vbl) in desc.vertex_buffers.iter().enumerate() { + for (i, vbl) in desc_vertex_buffers.iter().enumerate() { let mut attributes = Vec::::new(); for attribute in vbl.attributes.iter() { attributes.push(naga::back::msl::AttributeMapping { @@ -1103,7 +1111,7 @@ impl crate::Device for super::Device { } let vs = self.load_shader( - &desc.vertex_stage, + desc_vertex_stage, &vertex_buffer_mappings, desc.layout, primitive_class, @@ -1216,12 +1224,12 @@ impl crate::Device for super::Device { None => None, }; - if desc.layout.total_counters.vs.buffers + (desc.vertex_buffers.len() as u32) + if desc.layout.total_counters.vs.buffers + (desc_vertex_buffers.len() as u32) > self.shared.private_caps.max_vertex_buffers { let msg = format!( "pipeline needs too many buffers in the vertex stage: {} vertex and {} layout", - desc.vertex_buffers.len(), + desc_vertex_buffers.len(), desc.layout.total_counters.vs.buffers ); return Err(crate::PipelineError::Linkage( @@ -1230,9 +1238,9 @@ impl crate::Device for super::Device { )); } - if !desc.vertex_buffers.is_empty() { + if !desc_vertex_buffers.is_empty() { let vertex_descriptor = metal::VertexDescriptor::new(); - for (i, vb) in desc.vertex_buffers.iter().enumerate() { + for (i, vb) in desc_vertex_buffers.iter().enumerate() { let buffer_index = self.shared.private_caps.max_vertex_buffers as u64 - 1 - i as u64; let buffer_desc = vertex_descriptor.layouts().object_at(buffer_index).unwrap(); @@ -1318,17 +1326,6 @@ impl crate::Device for super::Device { }) } - unsafe fn create_mesh_pipeline( - &self, - _desc: &crate::MeshPipelineDescriptor< - ::PipelineLayout, - ::ShaderModule, - ::PipelineCache, - >, - ) -> Result<::RenderPipeline, crate::PipelineError> { - unreachable!() - } - unsafe fn destroy_render_pipeline(&self, _pipeline: super::RenderPipeline) { self.counters.render_pipelines.sub(1); } diff --git a/wgpu-hal/src/noop/mod.rs b/wgpu-hal/src/noop/mod.rs index ef2d51294da..55965a7e2fb 100644 --- a/wgpu-hal/src/noop/mod.rs +++ b/wgpu-hal/src/noop/mod.rs @@ -179,6 +179,12 @@ const CAPABILITIES: crate::Capabilities = { max_subgroup_size: ALLOC_MAX_U32, max_push_constant_size: ALLOC_MAX_U32, max_non_sampler_bindings: ALLOC_MAX_U32, + + max_task_workgroup_total_count: 0, + max_task_workgroups_per_dimension: 0, + max_mesh_multiview_count: 0, + max_mesh_output_layers: 0, + max_blas_primitive_count: ALLOC_MAX_U32, max_blas_geometry_count: ALLOC_MAX_U32, max_tlas_instance_count: ALLOC_MAX_U32, @@ -375,16 +381,6 @@ impl crate::Device for Context { ) -> Result { Ok(Resource) } - unsafe fn create_mesh_pipeline( - &self, - desc: &crate::MeshPipelineDescriptor< - ::PipelineLayout, - ::ShaderModule, - ::PipelineCache, - >, - ) -> Result<::RenderPipeline, crate::PipelineError> { - Ok(Resource) - } unsafe fn destroy_render_pipeline(&self, pipeline: Resource) {} unsafe fn create_compute_pipeline( &self, diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index a06616c6133..c2b05f91c76 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -932,7 +932,7 @@ pub struct PhysicalDeviceProperties { /// Additional `vk::PhysicalDevice` properties from the /// `VK_EXT_mesh_shader` extension. - _mesh_shader: Option>, + mesh_shader: Option>, /// The device API version. /// @@ -1160,6 +1160,20 @@ impl PhysicalDeviceProperties { let max_compute_workgroups_per_dimension = limits.max_compute_work_group_count[0] .min(limits.max_compute_work_group_count[1]) .min(limits.max_compute_work_group_count[2]); + let ( + max_task_workgroup_total_count, + max_task_workgroups_per_dimension, + max_mesh_multiview_count, + max_mesh_output_layers, + ) = match self.mesh_shader { + Some(m) => ( + m.max_task_work_group_total_count, + m.max_task_work_group_count.into_iter().min().unwrap(), + m.max_mesh_multiview_view_count, + m.max_mesh_output_layers, + ), + None => (0, 0, 0, 0), + }; // Prevent very large buffers on mesa and most android devices. let is_nvidia = self.properties.vendor_id == crate::auxil::db::nvidia::VENDOR; @@ -1267,6 +1281,12 @@ impl PhysicalDeviceProperties { max_compute_workgroups_per_dimension, max_buffer_size, max_non_sampler_bindings: u32::MAX, + + max_task_workgroup_total_count, + max_task_workgroups_per_dimension, + max_mesh_multiview_count, + max_mesh_output_layers, + max_blas_primitive_count, max_blas_geometry_count, max_tlas_instance_count, @@ -1401,7 +1421,7 @@ impl super::InstanceShared { if supports_mesh_shader { let next = capabilities - ._mesh_shader + .mesh_shader .insert(vk::PhysicalDeviceMeshShaderPropertiesEXT::default()); properties2 = properties2.push_next(next); } diff --git a/wgpu-hal/src/vulkan/conv.rs b/wgpu-hal/src/vulkan/conv.rs index 5177896ac5b..5d067c0ef0f 100644 --- a/wgpu-hal/src/vulkan/conv.rs +++ b/wgpu-hal/src/vulkan/conv.rs @@ -747,6 +747,12 @@ pub fn map_shader_stage(stage: wgt::ShaderStages) -> vk::ShaderStageFlags { if stage.contains(wgt::ShaderStages::COMPUTE) { flags |= vk::ShaderStageFlags::COMPUTE; } + if stage.contains(wgt::ShaderStages::TASK) { + flags |= vk::ShaderStageFlags::TASK_EXT; + } + if stage.contains(wgt::ShaderStages::MESH) { + flags |= vk::ShaderStageFlags::MESH_EXT; + } flags } diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 6b66bfa6aaf..ecaf1f4062f 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -1979,25 +1979,32 @@ impl crate::Device for super::Device { ..Default::default() }; let mut stages = ArrayVec::<_, { crate::MAX_CONCURRENT_SHADER_STAGES }>::new(); - let mut vertex_buffers = Vec::with_capacity(desc.vertex_buffers.len()); + let mut vertex_buffers = Vec::new(); let mut vertex_attributes = Vec::new(); - for (i, vb) in desc.vertex_buffers.iter().enumerate() { - vertex_buffers.push(vk::VertexInputBindingDescription { - binding: i as u32, - stride: vb.array_stride as u32, - input_rate: match vb.step_mode { - wgt::VertexStepMode::Vertex => vk::VertexInputRate::VERTEX, - wgt::VertexStepMode::Instance => vk::VertexInputRate::INSTANCE, - }, - }); - for at in vb.attributes { - vertex_attributes.push(vk::VertexInputAttributeDescription { - location: at.shader_location, + if let crate::VertexProcessor::Standard { + vertex_buffers: desc_vertex_buffers, + vertex_stage: _, + } = &desc.vertex_processor + { + vertex_buffers = Vec::with_capacity(desc_vertex_buffers.len()); + for (i, vb) in desc_vertex_buffers.iter().enumerate() { + vertex_buffers.push(vk::VertexInputBindingDescription { binding: i as u32, - format: conv::map_vertex_format(at.format), - offset: at.offset as u32, + stride: vb.array_stride as u32, + input_rate: match vb.step_mode { + wgt::VertexStepMode::Vertex => vk::VertexInputRate::VERTEX, + wgt::VertexStepMode::Instance => vk::VertexInputRate::INSTANCE, + }, }); + for at in vb.attributes { + vertex_attributes.push(vk::VertexInputAttributeDescription { + location: at.shader_location, + binding: i as u32, + format: conv::map_vertex_format(at.format), + offset: at.offset as u32, + }); + } } } @@ -2009,12 +2016,41 @@ impl crate::Device for super::Device { .topology(conv::map_topology(desc.primitive.topology)) .primitive_restart_enable(desc.primitive.strip_index_format.is_some()); - let compiled_vs = self.compile_stage( - &desc.vertex_stage, - naga::ShaderStage::Vertex, - &desc.layout.binding_arrays, - )?; - stages.push(compiled_vs.create_info); + let mut compiled_vs = None; + let mut compiled_ms = None; + let mut compiled_ts = None; + match &desc.vertex_processor { + crate::VertexProcessor::Standard { + vertex_buffers: _, + vertex_stage, + } => { + compiled_vs = Some(self.compile_stage( + vertex_stage, + naga::ShaderStage::Vertex, + &desc.layout.binding_arrays, + )?); + stages.push(compiled_vs.as_ref().unwrap().create_info); + } + crate::VertexProcessor::Mesh { + task_stage, + mesh_stage, + } => { + if let Some(t) = task_stage.as_ref() { + compiled_ts = Some(self.compile_stage( + t, + naga::ShaderStage::Task, + &desc.layout.binding_arrays, + )?); + stages.push(compiled_ts.as_ref().unwrap().create_info); + } + compiled_ms = Some(self.compile_stage( + mesh_stage, + naga::ShaderStage::Mesh, + &desc.layout.binding_arrays, + )?); + stages.push(compiled_ms.as_ref().unwrap().create_info); + } + } let compiled_fs = match desc.fragment_stage { Some(ref stage) => { let compiled = self.compile_stage( @@ -2177,228 +2213,13 @@ impl crate::Device for super::Device { unsafe { self.shared.set_object_name(raw, label) }; } - if let Some(raw_module) = compiled_vs.temp_raw_module { - unsafe { self.shared.raw.destroy_shader_module(raw_module, None) }; - } if let Some(CompiledStage { temp_raw_module: Some(raw_module), .. - }) = compiled_fs + }) = compiled_vs { unsafe { self.shared.raw.destroy_shader_module(raw_module, None) }; } - - self.counters.render_pipelines.add(1); - - Ok(super::RenderPipeline { raw }) - } - unsafe fn create_mesh_pipeline( - &self, - desc: &crate::MeshPipelineDescriptor< - ::PipelineLayout, - ::ShaderModule, - ::PipelineCache, - >, - ) -> Result<::RenderPipeline, crate::PipelineError> { - let dynamic_states = [ - vk::DynamicState::VIEWPORT, - vk::DynamicState::SCISSOR, - vk::DynamicState::BLEND_CONSTANTS, - vk::DynamicState::STENCIL_REFERENCE, - ]; - let mut compatible_rp_key = super::RenderPassKey { - sample_count: desc.multisample.count, - multiview: desc.multiview, - ..Default::default() - }; - let mut stages = ArrayVec::<_, { crate::MAX_CONCURRENT_SHADER_STAGES }>::new(); - - let vk_input_assembly = vk::PipelineInputAssemblyStateCreateInfo::default() - .topology(conv::map_topology(desc.primitive.topology)) - .primitive_restart_enable(desc.primitive.strip_index_format.is_some()); - - let compiled_ts = match desc.task_stage { - Some(ref stage) => { - let mut compiled = self.compile_stage( - stage, - naga::ShaderStage::Task, - &desc.layout.binding_arrays, - )?; - compiled.create_info.stage = vk::ShaderStageFlags::TASK_EXT; - stages.push(compiled.create_info); - Some(compiled) - } - None => None, - }; - - let mut compiled_ms = self.compile_stage( - &desc.mesh_stage, - naga::ShaderStage::Mesh, - &desc.layout.binding_arrays, - )?; - compiled_ms.create_info.stage = vk::ShaderStageFlags::MESH_EXT; - stages.push(compiled_ms.create_info); - let compiled_fs = match desc.fragment_stage { - Some(ref stage) => { - let compiled = self.compile_stage( - stage, - naga::ShaderStage::Fragment, - &desc.layout.binding_arrays, - )?; - stages.push(compiled.create_info); - Some(compiled) - } - None => None, - }; - - let mut vk_rasterization = vk::PipelineRasterizationStateCreateInfo::default() - .polygon_mode(conv::map_polygon_mode(desc.primitive.polygon_mode)) - .front_face(conv::map_front_face(desc.primitive.front_face)) - .line_width(1.0) - .depth_clamp_enable(desc.primitive.unclipped_depth); - if let Some(face) = desc.primitive.cull_mode { - vk_rasterization = vk_rasterization.cull_mode(conv::map_cull_face(face)) - } - let mut vk_rasterization_conservative_state = - vk::PipelineRasterizationConservativeStateCreateInfoEXT::default() - .conservative_rasterization_mode( - vk::ConservativeRasterizationModeEXT::OVERESTIMATE, - ); - if desc.primitive.conservative { - vk_rasterization = vk_rasterization.push_next(&mut vk_rasterization_conservative_state); - } - - let mut vk_depth_stencil = vk::PipelineDepthStencilStateCreateInfo::default(); - if let Some(ref ds) = desc.depth_stencil { - let vk_format = self.shared.private_caps.map_texture_format(ds.format); - let vk_layout = if ds.is_read_only(desc.primitive.cull_mode) { - vk::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL - } else { - vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL - }; - compatible_rp_key.depth_stencil = Some(super::DepthStencilAttachmentKey { - base: super::AttachmentKey::compatible(vk_format, vk_layout), - stencil_ops: crate::AttachmentOps::all(), - }); - - if ds.is_depth_enabled() { - vk_depth_stencil = vk_depth_stencil - .depth_test_enable(true) - .depth_write_enable(ds.depth_write_enabled) - .depth_compare_op(conv::map_comparison(ds.depth_compare)); - } - if ds.stencil.is_enabled() { - let s = &ds.stencil; - let front = conv::map_stencil_face(&s.front, s.read_mask, s.write_mask); - let back = conv::map_stencil_face(&s.back, s.read_mask, s.write_mask); - vk_depth_stencil = vk_depth_stencil - .stencil_test_enable(true) - .front(front) - .back(back); - } - - if ds.bias.is_enabled() { - vk_rasterization = vk_rasterization - .depth_bias_enable(true) - .depth_bias_constant_factor(ds.bias.constant as f32) - .depth_bias_clamp(ds.bias.clamp) - .depth_bias_slope_factor(ds.bias.slope_scale); - } - } - - let vk_viewport = vk::PipelineViewportStateCreateInfo::default() - .flags(vk::PipelineViewportStateCreateFlags::empty()) - .scissor_count(1) - .viewport_count(1); - - let vk_sample_mask = [ - desc.multisample.mask as u32, - (desc.multisample.mask >> 32) as u32, - ]; - let vk_multisample = vk::PipelineMultisampleStateCreateInfo::default() - .rasterization_samples(vk::SampleCountFlags::from_raw(desc.multisample.count)) - .alpha_to_coverage_enable(desc.multisample.alpha_to_coverage_enabled) - .sample_mask(&vk_sample_mask); - - let mut vk_attachments = Vec::with_capacity(desc.color_targets.len()); - for cat in desc.color_targets { - let (key, attarchment) = if let Some(cat) = cat.as_ref() { - let mut vk_attachment = vk::PipelineColorBlendAttachmentState::default() - .color_write_mask(vk::ColorComponentFlags::from_raw(cat.write_mask.bits())); - if let Some(ref blend) = cat.blend { - let (color_op, color_src, color_dst) = conv::map_blend_component(&blend.color); - let (alpha_op, alpha_src, alpha_dst) = conv::map_blend_component(&blend.alpha); - vk_attachment = vk_attachment - .blend_enable(true) - .color_blend_op(color_op) - .src_color_blend_factor(color_src) - .dst_color_blend_factor(color_dst) - .alpha_blend_op(alpha_op) - .src_alpha_blend_factor(alpha_src) - .dst_alpha_blend_factor(alpha_dst); - } - - let vk_format = self.shared.private_caps.map_texture_format(cat.format); - ( - Some(super::ColorAttachmentKey { - base: super::AttachmentKey::compatible( - vk_format, - vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, - ), - resolve: None, - }), - vk_attachment, - ) - } else { - (None, vk::PipelineColorBlendAttachmentState::default()) - }; - - compatible_rp_key.colors.push(key); - vk_attachments.push(attarchment); - } - - let vk_color_blend = - vk::PipelineColorBlendStateCreateInfo::default().attachments(&vk_attachments); - - let vk_dynamic_state = - vk::PipelineDynamicStateCreateInfo::default().dynamic_states(&dynamic_states); - - let raw_pass = self.shared.make_render_pass(compatible_rp_key)?; - - let vk_infos = [{ - vk::GraphicsPipelineCreateInfo::default() - .layout(desc.layout.raw) - .stages(&stages) - .input_assembly_state(&vk_input_assembly) - .rasterization_state(&vk_rasterization) - .viewport_state(&vk_viewport) - .multisample_state(&vk_multisample) - .depth_stencil_state(&vk_depth_stencil) - .color_blend_state(&vk_color_blend) - .dynamic_state(&vk_dynamic_state) - .render_pass(raw_pass) - }]; - - let pipeline_cache = desc - .cache - .map(|it| it.raw) - .unwrap_or(vk::PipelineCache::null()); - - let mut raw_vec = { - profiling::scope!("vkCreateGraphicsPipelines"); - unsafe { - self.shared - .raw - .create_graphics_pipelines(pipeline_cache, &vk_infos, None) - .map_err(|(_, e)| super::map_pipeline_err(e)) - }? - }; - - let raw = raw_vec.pop().unwrap(); - if let Some(label) = desc.label { - unsafe { self.shared.set_object_name(raw, label) }; - } - // NOTE: this could leak shaders in case of an error. if let Some(CompiledStage { temp_raw_module: Some(raw_module), .. @@ -2406,7 +2227,11 @@ impl crate::Device for super::Device { { unsafe { self.shared.raw.destroy_shader_module(raw_module, None) }; } - if let Some(raw_module) = compiled_ms.temp_raw_module { + if let Some(CompiledStage { + temp_raw_module: Some(raw_module), + .. + }) = compiled_ms + { unsafe { self.shared.raw.destroy_shader_module(raw_module, None) }; } if let Some(CompiledStage { diff --git a/wgpu-info/src/human.rs b/wgpu-info/src/human.rs index d56cc324dc6..f0930bd0212 100644 --- a/wgpu-info/src/human.rs +++ b/wgpu-info/src/human.rs @@ -160,6 +160,12 @@ fn print_adapter(output: &mut impl io::Write, report: &AdapterReport, idx: usize max_subgroup_size, max_push_constant_size, max_non_sampler_bindings, + + max_task_workgroup_total_count, + max_task_workgroups_per_dimension, + max_mesh_multiview_count, + max_mesh_output_layers, + max_blas_primitive_count, max_blas_geometry_count, max_tlas_instance_count, @@ -200,6 +206,12 @@ fn print_adapter(output: &mut impl io::Write, report: &AdapterReport, idx: usize writeln!(output, "\t\t Max Compute Workgroup Size Y: {max_compute_workgroup_size_y}")?; writeln!(output, "\t\t Max Compute Workgroup Size Z: {max_compute_workgroup_size_z}")?; writeln!(output, "\t\t Max Compute Workgroups Per Dimension: {max_compute_workgroups_per_dimension}")?; + + writeln!(output, "\t\t Max Task Workgroup Total Count: {max_task_workgroup_total_count}")?; + writeln!(output, "\t\t Max Task Workgroups Per Dimension: {max_task_workgroups_per_dimension}")?; + writeln!(output, "\t\t Max Mesh Multiview Count: {max_mesh_multiview_count}")?; + writeln!(output, "\t\t Max Mesh Output Layers: {max_mesh_output_layers}")?; + writeln!(output, "\t\t Max BLAS Primitive count: {max_blas_primitive_count}")?; writeln!(output, "\t\t Max BLAS Geometry count: {max_blas_geometry_count}")?; writeln!(output, "\t\t Max TLAS Instance count: {max_tlas_instance_count}")?; diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 6b51d50464a..573028759d6 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -615,6 +615,17 @@ pub struct Limits { /// This limit only affects the d3d12 backend. Using a large number will allow the device /// to create many bind groups at the cost of a large up-front allocation at device creation. pub max_non_sampler_bindings: u32, + + /// The maximum total value of x*y*z for a given `draw_mesh_tasks` command + pub max_task_workgroup_total_count: u32, + /// The maximum value for each dimension of a `RenderPass::draw_mesh_tasks(x, y, z)` operation. + /// Defaults to 65535. Higher is "better". + pub max_task_workgroups_per_dimension: u32, + /// The maximum number of layers that can be output from a mesh shader + pub max_mesh_output_layers: u32, + /// The maximum number of views that can be used by a mesh shader + pub max_mesh_multiview_count: u32, + /// The maximum number of primitive (ex: triangles, aabbs) a BLAS is allowed to have. Requesting /// more than 0 during device creation only makes sense if [`Features::EXPERIMENTAL_RAY_QUERY`] /// is enabled. @@ -683,6 +694,10 @@ impl Limits { /// max_subgroup_size: 0, /// max_push_constant_size: 0, /// max_non_sampler_bindings: 1_000_000, + /// max_task_workgroup_total_count: 0, + /// max_task_workgroups_per_dimension: 0, + /// max_mesh_multiview_count: 0, + /// max_mesh_output_layers: 0, /// max_blas_primitive_count: 0, /// max_blas_geometry_count: 0, /// max_tlas_instance_count: 0, @@ -731,6 +746,12 @@ impl Limits { max_subgroup_size: 0, max_push_constant_size: 0, max_non_sampler_bindings: 1_000_000, + + max_task_workgroup_total_count: 0, + max_task_workgroups_per_dimension: 0, + max_mesh_multiview_count: 0, + max_mesh_output_layers: 0, + max_blas_primitive_count: 0, max_blas_geometry_count: 0, max_tlas_instance_count: 0, @@ -780,6 +801,12 @@ impl Limits { /// max_compute_workgroups_per_dimension: 65535, /// max_buffer_size: 256 << 20, // (256 MiB) /// max_non_sampler_bindings: 1_000_000, + /// + /// max_task_workgroup_total_count: 0, + /// max_task_workgroups_per_dimension: 0, + /// max_mesh_multiview_count: 0, + /// max_mesh_output_layers: 0, + /// /// max_blas_primitive_count: 0, /// max_blas_geometry_count: 0, /// max_tlas_instance_count: 0, @@ -797,6 +824,11 @@ impl Limits { max_color_attachments: 4, // see: https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf#page=7 max_compute_workgroup_storage_size: 16352, + + max_task_workgroups_per_dimension: 0, + max_task_workgroup_total_count: 0, + max_mesh_multiview_count: 0, + max_mesh_output_layers: 0, ..Self::defaults() } } @@ -844,6 +876,12 @@ impl Limits { /// max_compute_workgroups_per_dimension: 0, // + /// max_buffer_size: 256 << 20, // (256 MiB), /// max_non_sampler_bindings: 1_000_000, + /// + /// max_task_workgroup_total_count: 0, + /// max_task_workgroups_per_dimension: 0, + /// max_mesh_multiview_count: 0, + /// max_mesh_output_layers: 0, + /// /// max_blas_primitive_count: 0, /// max_blas_geometry_count: 0, /// max_tlas_instance_count: 0, @@ -929,6 +967,24 @@ impl Limits { } } + /// The recommended minimum limits for mesh shaders if you enable [`Features::EXPERIMENTAL_MESH_SHADER`] + /// + /// These are chosen somewhat arbitrarily. They are small enough that they should cover all physical devices, + /// but not necessarily all use cases. + #[must_use] + pub const fn using_recommended_minimum_mesh_shader_values(self) -> Self { + Self { + // Literally just made this up as 256^2 or 2^16. + // My GPU supports 2^22, and compute shaders don't have this kind of limit. + // This very likely is never a real limiter + max_task_workgroup_total_count: 65536, + max_task_workgroups_per_dimension: 256, + max_mesh_multiview_count: 1, + max_mesh_output_layers: 1024, + ..self + } + } + /// Compares every limits within self is within the limits given in `allowed`. /// /// If you need detailed information on failures, look at [`Limits::check_limits_with_fail_fn`]. @@ -1008,6 +1064,12 @@ impl Limits { } compare!(max_push_constant_size, Less); compare!(max_non_sampler_bindings, Less); + + compare!(max_task_workgroup_total_count, Less); + compare!(max_task_workgroups_per_dimension, Less); + compare!(max_mesh_multiview_count, Less); + compare!(max_mesh_output_layers, Less); + compare!(max_blas_primitive_count, Less); compare!(max_blas_geometry_count, Less); compare!(max_tlas_instance_count, Less); @@ -1402,9 +1464,9 @@ bitflags::bitflags! { const COMPUTE = 1 << 2; /// Binding is visible from the vertex and fragment shaders of a render pipeline. const VERTEX_FRAGMENT = Self::VERTEX.bits() | Self::FRAGMENT.bits(); - /// Binding is visible from the task shader of a mesh pipeline + /// Binding is visible from the task shader of a mesh pipeline. const TASK = 1 << 3; - /// Binding is visible from the mesh shader of a mesh pipeline + /// Binding is visible from the mesh shader of a mesh pipeline. const MESH = 1 << 4; } } diff --git a/wgpu/src/api/device.rs b/wgpu/src/api/device.rs index 2a192e2b3b8..401431bcbda 100644 --- a/wgpu/src/api/device.rs +++ b/wgpu/src/api/device.rs @@ -245,6 +245,13 @@ impl Device { RenderPipeline { inner: pipeline } } + /// Creates a mesh shader based [`RenderPipeline`]. + #[must_use] + pub fn create_mesh_pipeline(&self, desc: &MeshPipelineDescriptor<'_>) -> RenderPipeline { + let pipeline = self.inner.create_mesh_pipeline(desc); + RenderPipeline { inner: pipeline } + } + /// Creates a [`ComputePipeline`]. #[must_use] pub fn create_compute_pipeline(&self, desc: &ComputePipelineDescriptor<'_>) -> ComputePipeline { diff --git a/wgpu/src/api/render_pass.rs b/wgpu/src/api/render_pass.rs index 0092c2af748..8163b4261f0 100644 --- a/wgpu/src/api/render_pass.rs +++ b/wgpu/src/api/render_pass.rs @@ -226,6 +226,12 @@ impl RenderPass<'_> { self.inner.draw_indexed(indices, base_vertex, instances); } + /// Draws using a mesh shader pipeline + pub fn draw_mesh_tasks(&mut self, group_count_x: u32, group_count_y: u32, group_count_z: u32) { + self.inner + .draw_mesh_tasks(group_count_x, group_count_y, group_count_z); + } + /// Draws primitives from the active vertex buffer(s) based on the contents of the `indirect_buffer`. /// /// This is like calling [`RenderPass::draw`] but the contents of the call are specified in the `indirect_buffer`. @@ -249,6 +255,25 @@ impl RenderPass<'_> { .draw_indexed_indirect(&indirect_buffer.inner, indirect_offset); } + /// Draws using a mesh shader pipeline, + /// based on the contents of the `indirect_buffer` + /// + /// This is like calling [`RenderPass::draw_mesh_tasks`] but the contents of the call are specified in the `indirect_buffer`. + /// The structure expected in the `indirect_buffer` must conform to [`DispatchIndirectArgs`](crate::util::DispatchIndirectArgs). + /// + /// Indirect drawing has some caveats depending on the features available. We are not currently able to validate + /// these and issue an error. + /// + /// See details on the individual flags for more information. + pub fn draw_mesh_tasks_indirect( + &mut self, + indirect_buffer: &Buffer, + indirect_offset: BufferAddress, + ) { + self.inner + .draw_mesh_tasks_indirect(&indirect_buffer.inner, indirect_offset); + } + /// Execute a [render bundle][RenderBundle], which is a set of pre-recorded commands /// that can be run together. /// @@ -307,6 +332,23 @@ impl RenderPass<'_> { .multi_draw_indexed_indirect(&indirect_buffer.inner, indirect_offset, count); } + /// Dispatches multiple draw calls based on the contents of the `indirect_buffer`. + /// `count` draw calls are issued. + /// + /// The structure expected in the `indirect_buffer` must conform to [`DispatchIndirectArgs`](crate::util::DispatchIndirectArgs). + /// + /// This drawing command uses the current render state, as set by preceding `set_*()` methods. + /// It is not affected by changes to the state that are performed after it is called. + pub fn multi_draw_mesh_tasks_indirect( + &mut self, + indirect_buffer: &Buffer, + indirect_offset: BufferAddress, + count: u32, + ) { + self.inner + .multi_draw_mesh_tasks_indirect(&indirect_buffer.inner, indirect_offset, count); + } + #[cfg(custom)] /// Returns custom implementation of RenderPass (if custom backend and is internally T) pub fn as_custom(&self) -> Option<&T> { @@ -395,6 +437,34 @@ impl RenderPass<'_> { max_count, ); } + + /// Dispatches multiple draw calls based on the contents of the `indirect_buffer`. The count buffer is read to determine how many draws to issue. + /// + /// The indirect buffer must be long enough to account for `max_count` draws, however only `count` + /// draws will be read. If `count` is greater than `max_count`, `max_count` will be used. + /// + /// The structure expected in the `indirect_buffer` must conform to [`DispatchIndirectArgs`](crate::util::DispatchIndirectArgs). + /// + /// These draw structures are expected to be tightly packed. + /// + /// This drawing command uses the current render state, as set by preceding `set_*()` methods. + /// It is not affected by changes to the state that are performed after it is called. + pub fn multi_draw_mesh_tasks_indirect_count( + &mut self, + indirect_buffer: &Buffer, + indirect_offset: BufferAddress, + count_buffer: &Buffer, + count_offset: BufferAddress, + max_count: u32, + ) { + self.inner.multi_draw_mesh_tasks_indirect_count( + &indirect_buffer.inner, + indirect_offset, + &count_buffer.inner, + count_offset, + max_count, + ); + } } /// [`Features::PUSH_CONSTANTS`] must be enabled on the device in order to call these functions. diff --git a/wgpu/src/api/render_pipeline.rs b/wgpu/src/api/render_pipeline.rs index 27f96bce734..e887bb4b97e 100644 --- a/wgpu/src/api/render_pipeline.rs +++ b/wgpu/src/api/render_pipeline.rs @@ -145,6 +145,48 @@ pub struct FragmentState<'a> { #[cfg(send_sync)] static_assertions::assert_impl_all!(FragmentState<'_>: Send, Sync); +/// Describes the task shader stage in a mesh shader pipeline. +/// +/// For use in [`MeshPipelineDescriptor`] +#[derive(Clone, Debug)] +pub struct TaskState<'a> { + /// The compiled shader module for this stage. + pub module: &'a ShaderModule, + /// The name of the entry point in the compiled shader to use. + /// + /// If [`Some`], there must be a vertex-stage shader entry point with this name in `module`. + /// Otherwise, expect exactly one vertex-stage entry point in `module`, which will be + /// selected. + pub entry_point: Option<&'a str>, + /// Advanced options for when this pipeline is compiled + /// + /// This implements `Default`, and for most users can be set to `Default::default()` + pub compilation_options: PipelineCompilationOptions<'a>, +} +#[cfg(send_sync)] +static_assertions::assert_impl_all!(TaskState<'_>: Send, Sync); + +/// Describes the mesh shader stage in a mesh shader pipeline. +/// +/// For use in [`MeshPipelineDescriptor`] +#[derive(Clone, Debug)] +pub struct MeshState<'a> { + /// The compiled shader module for this stage. + pub module: &'a ShaderModule, + /// The name of the entry point in the compiled shader to use. + /// + /// If [`Some`], there must be a vertex-stage shader entry point with this name in `module`. + /// Otherwise, expect exactly one vertex-stage entry point in `module`, which will be + /// selected. + pub entry_point: Option<&'a str>, + /// Advanced options for when this pipeline is compiled + /// + /// This implements `Default`, and for most users can be set to `Default::default()` + pub compilation_options: PipelineCompilationOptions<'a>, +} +#[cfg(send_sync)] +static_assertions::assert_impl_all!(MeshState<'_>: Send, Sync); + /// Describes a render (graphics) pipeline. /// /// For use with [`Device::create_render_pipeline`]. @@ -193,3 +235,51 @@ pub struct RenderPipelineDescriptor<'a> { } #[cfg(send_sync)] static_assertions::assert_impl_all!(RenderPipelineDescriptor<'_>: Send, Sync); + +/// Describes a mesh shader (graphics) pipeline. +/// +/// For use with [`Device::create_mesh_pipeline`]. +#[derive(Clone, Debug)] +pub struct MeshPipelineDescriptor<'a> { + /// Debug label of the pipeline. This will show up in graphics debuggers for easy identification. + pub label: Label<'a>, + /// The layout of bind groups for this pipeline. + /// + /// If this is set, then [`Device::create_render_pipeline`] will raise a validation error if + /// the layout doesn't match what the shader module(s) expect. + /// + /// Using the same [`PipelineLayout`] for many [`RenderPipeline`] or [`ComputePipeline`] + /// pipelines guarantees that you don't have to rebind any resources when switching between + /// those pipelines. + /// + /// ## Default pipeline layout + /// + /// If `layout` is `None`, then the pipeline has a [default layout] created and used instead. + /// The default layout is deduced from the shader modules. + /// + /// You can use [`RenderPipeline::get_bind_group_layout`] to create bind groups for use with the + /// default layout. However, these bind groups cannot be used with any other pipelines. This is + /// convenient for simple pipelines, but using an explicit layout is recommended in most cases. + /// + /// [default layout]: https://www.w3.org/TR/webgpu/#default-pipeline-layout + pub layout: Option<&'a PipelineLayout>, + /// The compiled task stage, its entry point, and the color targets. + pub task: Option>, + /// The compiled mesh stage and its entry point + pub mesh: MeshState<'a>, + /// The properties of the pipeline at the primitive assembly and rasterization level. + pub primitive: PrimitiveState, + /// The effect of draw calls on the depth and stencil aspects of the output target, if any. + pub depth_stencil: Option, + /// The multi-sampling properties of the pipeline. + pub multisample: MultisampleState, + /// The compiled fragment stage, its entry point, and the color targets. + pub fragment: Option>, + /// If the pipeline will be used with a multiview render pass, this indicates how many array + /// layers the attachments will have. + pub multiview: Option, + /// The pipeline cache to use when creating this pipeline. + pub cache: Option<&'a PipelineCache>, +} +#[cfg(send_sync)] +static_assertions::assert_impl_all!(MeshPipelineDescriptor<'_>: Send, Sync); diff --git a/wgpu/src/backend/webgpu.rs b/wgpu/src/backend/webgpu.rs index 36ee0b55414..28fcc99b848 100644 --- a/wgpu/src/backend/webgpu.rs +++ b/wgpu/src/backend/webgpu.rs @@ -823,6 +823,12 @@ fn map_wgt_limits(limits: webgpu_sys::GpuSupportedLimits) -> wgt::Limits { max_push_constant_size: wgt::Limits::default().max_push_constant_size, max_non_sampler_bindings: wgt::Limits::default().max_non_sampler_bindings, max_inter_stage_shader_components: wgt::Limits::default().max_inter_stage_shader_components, + + max_task_workgroup_total_count: wgt::Limits::default().max_task_workgroup_total_count, + max_task_workgroups_per_dimension: wgt::Limits::default().max_task_workgroups_per_dimension, + max_mesh_output_layers: wgt::Limits::default().max_mesh_output_layers, + max_mesh_multiview_count: wgt::Limits::default().max_mesh_multiview_count, + max_blas_primitive_count: wgt::Limits::default().max_blas_primitive_count, max_blas_geometry_count: wgt::Limits::default().max_blas_geometry_count, max_tlas_instance_count: wgt::Limits::default().max_tlas_instance_count, @@ -2174,6 +2180,13 @@ impl dispatch::DeviceInterface for WebDevice { .into() } + fn create_mesh_pipeline( + &self, + _desc: &crate::MeshPipelineDescriptor<'_>, + ) -> dispatch::DispatchRenderPipeline { + panic!("MESH_SHADER feature must be enabled to call create_mesh_pipeline") + } + fn create_compute_pipeline( &self, desc: &crate::ComputePipelineDescriptor<'_>, @@ -3415,6 +3428,10 @@ impl dispatch::RenderPassInterface for WebRenderPassEncoder { ) } + fn draw_mesh_tasks(&mut self, _group_count_x: u32, _group_count_y: u32, _group_count_z: u32) { + panic!("MESH_SHADER feature must be enabled to call draw_mesh_tasks") + } + fn draw_indirect( &mut self, indirect_buffer: &dispatch::DispatchBuffer, @@ -3435,6 +3452,14 @@ impl dispatch::RenderPassInterface for WebRenderPassEncoder { .draw_indexed_indirect_with_f64(&buffer.inner, indirect_offset as f64); } + fn draw_mesh_tasks_indirect( + &mut self, + _indirect_buffer: &dispatch::DispatchBuffer, + _indirect_offset: crate::BufferAddress, + ) { + panic!("MESH_SHADER feature must be enabled to call draw_mesh_tasks_indirect") + } + fn multi_draw_indirect( &mut self, indirect_buffer: &dispatch::DispatchBuffer, @@ -3465,6 +3490,15 @@ impl dispatch::RenderPassInterface for WebRenderPassEncoder { } } + fn multi_draw_mesh_tasks_indirect( + &mut self, + _indirect_buffer: &dispatch::DispatchBuffer, + _indirect_offset: crate::BufferAddress, + _count: u32, + ) { + panic!("MESH_SHADER feature must be enabled to call multi_draw_mesh_tasks_indirect") + } + fn multi_draw_indirect_count( &mut self, _indirect_buffer: &dispatch::DispatchBuffer, @@ -3489,6 +3523,17 @@ impl dispatch::RenderPassInterface for WebRenderPassEncoder { panic!("MULTI_DRAW_INDIRECT_COUNT feature must be enabled to call multi_draw_indexed_indirect_count") } + fn multi_draw_mesh_tasks_indirect_count( + &mut self, + _indirect_buffer: &dispatch::DispatchBuffer, + _indirect_offset: crate::BufferAddress, + _count_buffer: &dispatch::DispatchBuffer, + _count_buffer_offset: crate::BufferAddress, + _max_count: u32, + ) { + panic!("MESH_SHADER feature must be enabled to call multi_draw_mesh_tasks_indirect_count") + } + fn insert_debug_marker(&mut self, _label: &str) { // Not available in gecko yet // self.inner.insert_debug_marker(label); diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index 0a5648227c0..b97f20870cd 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -1354,6 +1354,102 @@ impl dispatch::DeviceInterface for CoreDevice { .into() } + fn create_mesh_pipeline( + &self, + desc: &crate::MeshPipelineDescriptor<'_>, + ) -> dispatch::DispatchRenderPipeline { + use wgc::pipeline as pipe; + + let mesh_constants = desc + .mesh + .compilation_options + .constants + .iter() + .map(|&(key, value)| (String::from(key), value)) + .collect(); + let descriptor = pipe::MeshPipelineDescriptor { + label: desc.label.map(Borrowed), + task: desc.task.as_ref().map(|task| { + let task_constants = task + .compilation_options + .constants + .iter() + .map(|&(key, value)| (String::from(key), value)) + .collect(); + pipe::TaskState { + stage: pipe::ProgrammableStageDescriptor { + module: task.module.inner.as_core().id, + entry_point: task.entry_point.map(Borrowed), + constants: task_constants, + zero_initialize_workgroup_memory: desc + .mesh + .compilation_options + .zero_initialize_workgroup_memory, + }, + } + }), + mesh: pipe::MeshState { + stage: pipe::ProgrammableStageDescriptor { + module: desc.mesh.module.inner.as_core().id, + entry_point: desc.mesh.entry_point.map(Borrowed), + constants: mesh_constants, + zero_initialize_workgroup_memory: desc + .mesh + .compilation_options + .zero_initialize_workgroup_memory, + }, + }, + layout: desc.layout.map(|layout| layout.inner.as_core().id), + primitive: desc.primitive, + depth_stencil: desc.depth_stencil.clone(), + multisample: desc.multisample, + fragment: desc.fragment.as_ref().map(|frag| { + let frag_constants = frag + .compilation_options + .constants + .iter() + .map(|&(key, value)| (String::from(key), value)) + .collect(); + pipe::FragmentState { + stage: pipe::ProgrammableStageDescriptor { + module: frag.module.inner.as_core().id, + entry_point: frag.entry_point.map(Borrowed), + constants: frag_constants, + zero_initialize_workgroup_memory: frag + .compilation_options + .zero_initialize_workgroup_memory, + }, + targets: Borrowed(frag.targets), + } + }), + multiview: desc.multiview, + cache: desc.cache.map(|cache| cache.inner.as_core().id), + }; + + let (id, error) = self + .context + .0 + .device_create_mesh_pipeline(self.id, &descriptor, None); + if let Some(cause) = error { + if let wgc::pipeline::CreateRenderPipelineError::Internal { stage, ref error } = cause { + log::error!("Shader translation error for stage {stage:?}: {error}"); + log::error!("Please report it to https://github.com/gfx-rs/wgpu"); + } + self.context.handle_error( + &self.error_sink, + cause, + desc.label, + "Device::create_render_pipeline", + ); + } + CoreRenderPipeline { + context: self.context.clone(), + id, + error_sink: Arc::clone(&self.error_sink), + } + .into() + } + fn create_compute_pipeline( &self, desc: &crate::ComputePipelineDescriptor<'_>, @@ -3125,6 +3221,22 @@ impl dispatch::RenderPassInterface for CoreRenderPass { } } + fn draw_mesh_tasks(&mut self, group_count_x: u32, group_count_y: u32, group_count_z: u32) { + if let Err(cause) = self.context.0.render_pass_draw_mesh_tasks( + &mut self.pass, + group_count_x, + group_count_y, + group_count_z, + ) { + self.context.handle_error( + &self.error_sink, + cause, + self.pass.label(), + "RenderPass::draw_mesh_tasks", + ); + } + } + fn draw_indirect( &mut self, indirect_buffer: &dispatch::DispatchBuffer, @@ -3167,6 +3279,27 @@ impl dispatch::RenderPassInterface for CoreRenderPass { } } + fn draw_mesh_tasks_indirect( + &mut self, + indirect_buffer: &dispatch::DispatchBuffer, + indirect_offset: crate::BufferAddress, + ) { + let indirect_buffer = indirect_buffer.as_core(); + + if let Err(cause) = self.context.0.render_pass_draw_mesh_tasks_indirect( + &mut self.pass, + indirect_buffer.id, + indirect_offset, + ) { + self.context.handle_error( + &self.error_sink, + cause, + self.pass.label(), + "RenderPass::draw_mesh_tasks_indirect", + ); + } + } + fn multi_draw_indirect( &mut self, indirect_buffer: &dispatch::DispatchBuffer, @@ -3213,6 +3346,29 @@ impl dispatch::RenderPassInterface for CoreRenderPass { } } + fn multi_draw_mesh_tasks_indirect( + &mut self, + indirect_buffer: &dispatch::DispatchBuffer, + indirect_offset: crate::BufferAddress, + count: u32, + ) { + let indirect_buffer = indirect_buffer.as_core(); + + if let Err(cause) = self.context.0.render_pass_multi_draw_mesh_tasks_indirect( + &mut self.pass, + indirect_buffer.id, + indirect_offset, + count, + ) { + self.context.handle_error( + &self.error_sink, + cause, + self.pass.label(), + "RenderPass::multi_draw_mesh_tasks_indirect", + ); + } + } + fn multi_draw_indirect_count( &mut self, indirect_buffer: &dispatch::DispatchBuffer, @@ -3273,6 +3429,38 @@ impl dispatch::RenderPassInterface for CoreRenderPass { } } + fn multi_draw_mesh_tasks_indirect_count( + &mut self, + indirect_buffer: &dispatch::DispatchBuffer, + indirect_offset: crate::BufferAddress, + count_buffer: &dispatch::DispatchBuffer, + count_buffer_offset: crate::BufferAddress, + max_count: u32, + ) { + let indirect_buffer = indirect_buffer.as_core(); + let count_buffer = count_buffer.as_core(); + + if let Err(cause) = self + .context + .0 + .render_pass_multi_draw_mesh_tasks_indirect_count( + &mut self.pass, + indirect_buffer.id, + indirect_offset, + count_buffer.id, + count_buffer_offset, + max_count, + ) + { + self.context.handle_error( + &self.error_sink, + cause, + self.pass.label(), + "RenderPass::multi_draw_mesh_tasks_indirect_count", + ); + } + } + fn insert_debug_marker(&mut self, label: &str) { if let Err(cause) = self .context diff --git a/wgpu/src/dispatch.rs b/wgpu/src/dispatch.rs index f7af8c3751b..3b549a659ee 100644 --- a/wgpu/src/dispatch.rs +++ b/wgpu/src/dispatch.rs @@ -147,6 +147,10 @@ pub trait DeviceInterface: CommonTraits { &self, desc: &crate::RenderPipelineDescriptor<'_>, ) -> DispatchRenderPipeline; + fn create_mesh_pipeline( + &self, + desc: &crate::MeshPipelineDescriptor<'_>, + ) -> DispatchRenderPipeline; fn create_compute_pipeline( &self, desc: &crate::ComputePipelineDescriptor<'_>, @@ -420,6 +424,7 @@ pub trait RenderPassInterface: CommonTraits { fn draw(&mut self, vertices: Range, instances: Range); fn draw_indexed(&mut self, indices: Range, base_vertex: i32, instances: Range); + fn draw_mesh_tasks(&mut self, group_count_x: u32, group_count_y: u32, group_count_z: u32); fn draw_indirect( &mut self, indirect_buffer: &DispatchBuffer, @@ -430,6 +435,11 @@ pub trait RenderPassInterface: CommonTraits { indirect_buffer: &DispatchBuffer, indirect_offset: crate::BufferAddress, ); + fn draw_mesh_tasks_indirect( + &mut self, + indirect_buffer: &DispatchBuffer, + indirect_offset: crate::BufferAddress, + ); fn multi_draw_indirect( &mut self, @@ -451,6 +461,12 @@ pub trait RenderPassInterface: CommonTraits { count_buffer_offset: crate::BufferAddress, max_count: u32, ); + fn multi_draw_mesh_tasks_indirect( + &mut self, + indirect_buffer: &DispatchBuffer, + indirect_offset: crate::BufferAddress, + count: u32, + ); fn multi_draw_indexed_indirect_count( &mut self, indirect_buffer: &DispatchBuffer, @@ -459,6 +475,14 @@ pub trait RenderPassInterface: CommonTraits { count_buffer_offset: crate::BufferAddress, max_count: u32, ); + fn multi_draw_mesh_tasks_indirect_count( + &mut self, + indirect_buffer: &DispatchBuffer, + indirect_offset: crate::BufferAddress, + count_buffer: &DispatchBuffer, + count_buffer_offset: crate::BufferAddress, + max_count: u32, + ); fn insert_debug_marker(&mut self, label: &str); fn push_debug_group(&mut self, group_label: &str); From d8b7e81a0245965436744d318d7b2221cc2458df Mon Sep 17 00:00:00 2001 From: SupaMaggie70Incorporated <85136135+SupaMaggie70Incorporated@users.noreply.github.com> Date: Thu, 24 Jul 2025 23:05:12 -0500 Subject: [PATCH 069/303] Updated mesh shader limits to be llvmpipe compatible (#8004) Co-authored-by: Andy Leiserson --- wgpu-types/src/lib.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 573028759d6..6252e5c6778 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -979,8 +979,10 @@ impl Limits { // This very likely is never a real limiter max_task_workgroup_total_count: 65536, max_task_workgroups_per_dimension: 256, - max_mesh_multiview_count: 1, - max_mesh_output_layers: 1024, + // llvmpipe reports 0 multiview count, which just means no multiview is allowed + max_mesh_multiview_count: 0, + // llvmpipe once again requires this to be 8. An RTX 3060 supports well over 1024. + max_mesh_output_layers: 8, ..self } } From bf86ac3489614ed2b212ea2ff361dbf302c127dc Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Fri, 25 Jul 2025 11:16:57 -0700 Subject: [PATCH 070/303] Two small vulkan changes (#8001) --- wgpu-hal/src/vulkan/adapter.rs | 5 +++-- wgpu-hal/src/vulkan/device.rs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index c2b05f91c76..19c1ffe4ca7 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -1175,13 +1175,14 @@ impl PhysicalDeviceProperties { None => (0, 0, 0, 0), }; - // Prevent very large buffers on mesa and most android devices. + // Prevent very large buffers on mesa and most android devices, and in all cases + // don't risk confusing JS by exceeding the range of a double. let is_nvidia = self.properties.vendor_id == crate::auxil::db::nvidia::VENDOR; let max_buffer_size = if (cfg!(target_os = "linux") || cfg!(target_os = "android")) && !is_nvidia { i32::MAX as u64 } else { - u64::MAX + 1u64 << 52 }; let mut max_binding_array_elements = 0; diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index ecaf1f4062f..87054416922 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -236,7 +236,7 @@ impl super::DeviceShared { &self, buffer: &'a super::Buffer, ranges: I, - ) -> Option> { + ) -> Option>> { let block = buffer.block.as_ref()?.lock(); let mask = self.private_caps.non_coherent_map_mask; Some(ranges.map(move |range| { From ec1ab06bff78e740b397212f70d7abd63eda860d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 28 Jul 2025 11:38:26 -0400 Subject: [PATCH 071/303] Update cts digest to e110f5e (#8015) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- cts_runner/revision.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cts_runner/revision.txt b/cts_runner/revision.txt index a80cc61d951..3b266dec117 100644 --- a/cts_runner/revision.txt +++ b/cts_runner/revision.txt @@ -1 +1 @@ -7bdef028de174c1d236d8531f574194a12a4f1f6 +e110f5e8b978a8eb43f243defff6f545b71df96f From d913042f1dba141ebb0304c62ef197283bdd5174 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 28 Jul 2025 11:38:48 -0400 Subject: [PATCH 072/303] Update Rust crate criterion to 0.7 (#8016) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Cargo.lock | 19 +++++-------------- Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a67c3562eb..eb0bc1f2188 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -934,9 +934,9 @@ dependencies = [ [[package]] name = "criterion" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bf7af66b0989381bd0be551bd7cc91912a655a58c6918420c9527b1fd8b4679" +checksum = "e1c047a62b0cc3e145fa84415a3191f628e980b194c2755aa12300a4e6cbd928" dependencies = [ "anes", "cast", @@ -957,12 +957,12 @@ dependencies = [ [[package]] name = "criterion-plot" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +checksum = "9b1bcc0dc7dfae599d84ad0b1a55f80cde8af3725da8313b528da95ef783e338" dependencies = [ "cast", - "itertools 0.10.5", + "itertools 0.13.0", ] [[package]] @@ -2138,15 +2138,6 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.13.0" diff --git a/Cargo.toml b/Cargo.toml index e8af139f6fd..529a0e92035 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,7 +106,7 @@ bytemuck = { version = "1.22", features = [ cargo_metadata = "0.21" cfg_aliases = "0.2.1" cfg-if = "1" -criterion = "0.6" +criterion = "0.7" codespan-reporting = { version = "0.12", default-features = false } ctor = "0.4" diff = "0.1" From 747384493dc725b2a26ffd661d7a7326e60e40d3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 28 Jul 2025 11:38:57 -0400 Subject: [PATCH 073/303] Update Cargo.lock (#8017) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Cargo.lock | 58 +++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eb0bc1f2188..93ea2a182cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -998,9 +998,9 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "ctor" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4735f265ba6a1188052ca32d461028a7d1125868be18e287e756019da7607b5" +checksum = "ec09e802f5081de6157da9a75701d6c713d8dc3ba52571fd4bd25f412644e8a6" dependencies = [ "ctor-proc-macro", "dtor", @@ -1008,9 +1008,9 @@ dependencies = [ [[package]] name = "ctor-proc-macro" -version = "0.0.5" +version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f211af61d8efdd104f96e57adf5e426ba1bc3ed7a4ead616e15e5881fd79c4d" +checksum = "e2931af7e13dc045d8e9d26afccc6fa115d64e115c9c84b1166288b46f6782c2" [[package]] name = "cts_runner" @@ -1745,9 +1745,9 @@ dependencies = [ [[package]] name = "glam" -version = "0.30.4" +version = "0.30.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50a99dbe56b72736564cfa4b85bf9a33079f16ae8b74983ab06af3b1a3696b11" +checksum = "f2d1aab06663bdce00d6ca5e5ed586ec8d18033a771906c993a1e3755b368d85" dependencies = [ "bytemuck", ] @@ -2123,9 +2123,9 @@ dependencies = [ [[package]] name = "io-uring" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013" +checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" dependencies = [ "bitflags 2.9.1", "cfg-if", @@ -2301,7 +2301,7 @@ checksum = "4488594b9328dee448adb906d8b126d9b7deb7cf5c22161ee591610bb1be83c0" dependencies = [ "bitflags 2.9.1", "libc", - "redox_syscall 0.5.14", + "redox_syscall 0.5.16", ] [[package]] @@ -2336,9 +2336,9 @@ checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "litrs" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" +checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" [[package]] name = "lock-analyzer" @@ -3068,9 +3068,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "owned_ttf_parser" -version = "0.25.0" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4" +checksum = "36820e9051aca1014ddc75770aab4d68bc1e9e632f0f5627c4086bc216fb583b" dependencies = [ "ttf-parser", ] @@ -3101,7 +3101,7 @@ dependencies = [ "cfg-if", "libc", "petgraph 0.6.5", - "redox_syscall 0.5.14", + "redox_syscall 0.5.16", "smallvec", "thread-id", "windows-targets 0.52.6", @@ -3314,9 +3314,9 @@ checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" [[package]] name = "prettyplease" -version = "0.2.35" +version = "0.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a" +checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2" dependencies = [ "proc-macro2", "syn", @@ -3481,9 +3481,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.14" +version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3a5d9f0aba1dbcec1cc47f0ff94a4b778fe55bca98a6dfa92e4e094e57b1c4" +checksum = "7251471db004e509f4e75a62cca9435365b5ec7bcdff530d612ac7c87c44a792" dependencies = [ "bitflags 2.9.1", ] @@ -3575,9 +3575,9 @@ checksum = "a157657054ffe556d8858504af8a672a054a6e0bd9e8ee531059100c0fa11bb2" [[package]] name = "rustc-demangle" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] name = "rustc-hash" @@ -3916,12 +3916,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.10" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4204,9 +4204,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.46.1" +version = "1.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17" +checksum = "43864ed400b6043a4757a25c7a64a8efde741aed79a056a2fb348a406701bb35" dependencies = [ "backtrace", "bytes", @@ -4219,7 +4219,7 @@ dependencies = [ "slab", "socket2", "tokio-macros", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -5011,7 +5011,7 @@ dependencies = [ "env_logger", "pollster", "wgpu", - "winit 0.30.11", + "winit 0.30.12", ] [[package]] @@ -5764,9 +5764,9 @@ dependencies = [ [[package]] name = "winit" -version = "0.30.11" +version = "0.30.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4409c10174df8779dc29a4788cac85ed84024ccbc1743b776b21a520ee1aaf4" +checksum = "c66d4b9ed69c4009f6321f762d6e61ad8a2389cd431b97cb1e146812e9e6c732" dependencies = [ "ahash", "android-activity 0.6.0", From 1583c2481a9901d9879930067ca0e5617bced827 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Mon, 28 Jul 2025 19:19:17 -0700 Subject: [PATCH 074/303] Another fix for texture copy validation (#8019) --- tests/tests/wgpu-gpu/queue_transfer.rs | 51 ++++++++++++++++++++++++++ wgpu-core/src/command/transfer.rs | 5 ++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/tests/tests/wgpu-gpu/queue_transfer.rs b/tests/tests/wgpu-gpu/queue_transfer.rs index 9196f7fcbf5..8ad4dee7a30 100644 --- a/tests/tests/wgpu-gpu/queue_transfer.rs +++ b/tests/tests/wgpu-gpu/queue_transfer.rs @@ -99,3 +99,54 @@ static QUEUE_WRITE_TEXTURE_OVERFLOW: GpuTestConfiguration = Some("end up overrunning the bounds of the destination texture"), ); }); + +#[gpu_test] +static QUEUE_WRITE_TEXTURE_BUFFER_OOB: GpuTestConfiguration = + GpuTestConfiguration::new().run_sync(|ctx| { + // Test that transfers overrunning the end of the source buffer, or + // where offset + size overflows a u64, are rejected. + for offset in [120, u64::MAX - 3] { + let texture = ctx.device.create_texture(&wgpu::TextureDescriptor { + label: None, + size: wgpu::Extent3d { + width: 146, + height: 25, + depth_or_array_layers: 192, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rgba32Float, + usage: wgpu::TextureUsages::COPY_DST, + view_formats: &[], + }); + + let data = vec![255; 128]; + + fail( + &ctx.device, + || { + ctx.queue.write_texture( + wgpu::TexelCopyTextureInfo { + texture: &texture, + mip_level: 0, + origin: wgpu::Origin3d { x: 0, y: 0, z: 1 }, + aspect: wgpu::TextureAspect::All, + }, + &data, + wgpu::TexelCopyBufferLayout { + offset, + bytes_per_row: Some(16), + rows_per_image: Some(1), + }, + wgpu::Extent3d { + width: 1, + height: 1, + depth_or_array_layers: 1, + }, + ); + }, + Some("would end up overrunning the bounds of the source buffer"), + ); + } + }); diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index fb9e4535fbf..36d3f092fd4 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -351,10 +351,11 @@ pub(crate) fn validate_linear_texture_data( } } - if offset + bytes_in_copy > buffer_size { + // Avoid underflow in the subtraction by checking bytes_in_copy against buffer_size first. + if bytes_in_copy > buffer_size || offset > buffer_size - bytes_in_copy { return Err(TransferError::BufferOverrun { start_offset: offset, - end_offset: offset + bytes_in_copy, + end_offset: offset.wrapping_add(bytes_in_copy), buffer_size, side: buffer_side, }); From 50890630483f1d0d7821accf053628d4443d2d11 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Tue, 29 Jul 2025 10:18:26 -0700 Subject: [PATCH 075/303] Allow copying one layer of depth/stencil textures (#8020) This fixes a regression introduced by #7935. --- cts_runner/test.lst | 6 ++++++ wgpu-core/src/command/transfer.rs | 9 +++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 3bac66e8481..e81c3ab1c77 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -5,6 +5,12 @@ webgpu:api,operation,compute,basic:memcpy:* //FAIL: webgpu:api,operation,compute,basic:large_dispatch:* webgpu:api,operation,compute_pipeline,overrides:* webgpu:api,operation,device,lost:* +// This is all the storeOp tests, but some of them fail if run in a single invocation. +// https://github.com/gfx-rs/wgpu/issues/8021 +webgpu:api,operation,render_pass,storeOp:render_pass_store_op,color_attachment_with_depth_stencil_attachment:* +webgpu:api,operation,render_pass,storeOp:render_pass_store_op,color_attachment_only:* +webgpu:api,operation,render_pass,storeOp:render_pass_store_op,multiple_color_attachments:* +webgpu:api,operation,render_pass,storeOp:render_pass_store_op,depth_stencil_attachment_only:* webgpu:api,validation,encoding,beginComputePass:* webgpu:api,validation,encoding,beginRenderPass:* webgpu:api,validation,encoding,cmds,clearBuffer:* diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 36d3f092fd4..c16f9e0365e 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -455,7 +455,8 @@ pub(crate) fn validate_texture_copy_range( // physical size can be larger than the virtual let extent = extent_virtual.physical_size(desc.format); - // Multisampled and depth-stencil formats do not support partial copies. + // Multisampled and depth-stencil formats do not support partial copies + // on x and y dimensions, but do support copying a subset of layers. let requires_exact_size = desc.format.is_depth_stencil_format() || desc.sample_count > 1; // Return `Ok` if a run `size` texels long starting at `start_offset` is @@ -463,7 +464,8 @@ pub(crate) fn validate_texture_copy_range( let check_dimension = |dimension: TextureErrorDimension, start_offset: u32, size: u32, - texture_size: u32| + texture_size: u32, + requires_exact_size: bool| -> Result<(), TransferError> { if requires_exact_size && (start_offset != 0 || size != texture_size) { Err(TransferError::UnsupportedPartialTransfer { @@ -495,18 +497,21 @@ pub(crate) fn validate_texture_copy_range( texture_copy_view.origin.x, copy_size.width, extent.width, + requires_exact_size, )?; check_dimension( TextureErrorDimension::Y, texture_copy_view.origin.y, copy_size.height, extent.height, + requires_exact_size, )?; check_dimension( TextureErrorDimension::Z, texture_copy_view.origin.z, copy_size.depth_or_array_layers, extent.depth_or_array_layers, + false, // partial copy always allowed on Z/layer dimension )?; if texture_copy_view.origin.x % block_width != 0 { From 36ae215e9cfb0defb94f889f55edc18c5b87f150 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 30 Jul 2025 05:35:12 -0700 Subject: [PATCH 076/303] Fix image copy regressions (#8022) * Restore allowance of unaligned buffer-texture copies This fixes a regression introduced by #7948. However, it makes it possible to reach a panic in initialize_buffer_memory if the copy requires initializing a region of memory that is not 4B aligned. * Fix CopyT2T of multi-layer depth/stencil textures * Adjust test list --- cts_runner/test.lst | 13 ++++++ wgpu-core/src/command/transfer.rs | 77 +++++++++++-------------------- 2 files changed, 40 insertions(+), 50 deletions(-) diff --git a/cts_runner/test.lst b/cts_runner/test.lst index e81c3ab1c77..1b7059a4deb 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -1,6 +1,14 @@ unittests:* webgpu:api,operation,command_buffer,basic:* webgpu:api,operation,command_buffer,copyBufferToBuffer:* +fails-if(vulkan) webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth24plus" +fails-if(vulkan) webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth24plus-stencil8" +fails-if(vulkan) webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth16unorm" +fails-if(vulkan) webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth32float" +fails-if(vulkan) webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth32float-stencil8" +webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="stencil8" +// Fails with OOM in CI. +fails-if(dx12) webgpu:api,operation,command_buffer,image_copy:offsets_and_sizes:* webgpu:api,operation,compute,basic:memcpy:* //FAIL: webgpu:api,operation,compute,basic:large_dispatch:* webgpu:api,operation,compute_pipeline,overrides:* @@ -63,6 +71,8 @@ fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and //mix of PASS and FAIL: other subtests of offset_and_bytesPerRow. Related bugs: // https://github.com/gfx-rs/wgpu/issues/7946, https://github.com/gfx-rs/wgpu/issues/7947 webgpu:api,validation,image_copy,layout_related:copy_end_overflows_u64:* +// Fails with OOM in CI. +fails-if(dx12) webgpu:api,validation,image_copy,layout_related:offset_alignment:* webgpu:api,validation,image_copy,texture_related:format:dimension="1d";* webgpu:api,validation,queue,submit:command_buffer,device_mismatch:* webgpu:api,validation,queue,submit:command_buffer,duplicate_buffers:* @@ -92,6 +102,9 @@ webgpu:api,validation,encoding,queries,general:occlusion_query,query_type:* webgpu:shader,execution,expression,call,builtin,textureSample:sampled_1d_coords:* webgpu:shader,execution,expression,call,builtin,textureSampleBaseClampToEdge:2d_coords:stage="c";textureType="texture_2d";* webgpu:shader,execution,flow_control,return:* +// Many other vertex_buffer_access subtests also passing, but there are too many to enumerate. +// Fails on Metal in CI only, not when running locally. +fails-if(metal) webgpu:shader,execution,robust_access_vertex:vertex_buffer_access:indexed=true;indirect=false;drawCallTestParameter="baseVertex";type="float32x4";additionalBuffers=4;partialLastNumber=false;offsetVertexBuffer=true webgpu:shader,validation,expression,call,builtin,max:values:* webgpu:shader,validation,statement,statement_behavior:invalid_statements:body="break" webgpu:shader,validation,statement,statement_behavior:invalid_statements:body="break_if" diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index c16f9e0365e..3a818e148cb 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -1,4 +1,4 @@ -use alloc::{format, string::String, sync::Arc, vec, vec::Vec}; +use alloc::{format, string::String, sync::Arc, vec::Vec}; use arrayvec::ArrayVec; use thiserror::Error; @@ -399,7 +399,7 @@ pub(crate) fn validate_texture_buffer_copy( return Err(TransferError::CopyAspectNotOne); } - let mut offset_alignment = if desc.format.is_depth_stencil_format() { + let offset_alignment = if desc.format.is_depth_stencil_format() { 4 } else { // The case where `block_copy_size` returns `None` is currently @@ -411,17 +411,7 @@ pub(crate) fn validate_texture_buffer_copy( .expect("non-copyable formats should have been rejected previously") }; - // TODO(https://github.com/gfx-rs/wgpu/issues/7947): This does not match the spec. - // The spec imposes no alignment requirement if `!aligned`, and otherwise - // imposes only the `offset_alignment` as calculated above. wgpu currently - // can panic on alignments <4B, so we reject them here to avoid a panic. - if aligned { - offset_alignment = offset_alignment.max(4); - } else { - offset_alignment = 4; - } - - if offset % u64::from(offset_alignment) != 0 { + if aligned && offset % u64::from(offset_alignment) != 0 { return Err(TransferError::UnalignedBufferOffset(offset)); } @@ -1347,45 +1337,32 @@ impl Global { height: src_copy_size.height.min(dst_copy_size.height), depth: src_copy_size.depth.min(dst_copy_size.depth), }; + + let regions = (0..array_layer_count).map(|rel_array_layer| { + let mut src_base = src_tex_base.clone(); + let mut dst_base = dst_tex_base.clone(); + src_base.array_layer += rel_array_layer; + dst_base.array_layer += rel_array_layer; + hal::TextureCopy { + src_base, + dst_base, + size: hal_copy_size, + } + }); + let regions = if dst_tex_base.aspect == hal::FormatAspects::DEPTH_STENCIL { - vec![ - hal::TextureCopy { - src_base: hal::TextureCopyBase { - aspect: hal::FormatAspects::DEPTH, - ..src_tex_base - }, - dst_base: hal::TextureCopyBase { - aspect: hal::FormatAspects::DEPTH, - ..dst_tex_base - }, - size: hal_copy_size, - }, - hal::TextureCopy { - src_base: hal::TextureCopyBase { - aspect: hal::FormatAspects::STENCIL, - ..src_tex_base - }, - dst_base: hal::TextureCopyBase { - aspect: hal::FormatAspects::STENCIL, - ..dst_tex_base - }, - size: hal_copy_size, - }, - ] - } else { - (0..array_layer_count) - .map(|rel_array_layer| { - let mut src_base = src_tex_base.clone(); - let mut dst_base = dst_tex_base.clone(); - src_base.array_layer += rel_array_layer; - dst_base.array_layer += rel_array_layer; - hal::TextureCopy { - src_base, - dst_base, - size: hal_copy_size, - } + regions + .flat_map(|region| { + let (mut depth, mut stencil) = (region.clone(), region); + depth.src_base.aspect = hal::FormatAspects::DEPTH; + depth.dst_base.aspect = hal::FormatAspects::DEPTH; + stencil.src_base.aspect = hal::FormatAspects::STENCIL; + stencil.dst_base.aspect = hal::FormatAspects::STENCIL; + [depth, stencil] }) - .collect() + .collect::>() + } else { + regions.collect::>() }; let cmd_buf_raw = cmd_buf_data.encoder.open()?; unsafe { From 9f654c623533c0b58ebd6ee5ac2b9524bd5034e4 Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Mon, 2 Jun 2025 17:21:23 +0100 Subject: [PATCH 077/303] [naga] Generate special type for external texture params buffer During wgsl lowering, if we encounter an external texture type then generate the `ExternalTextureParams` struct. This will be required by most Naga backends to implement external textures. This type is not actually used by wgsl-in or the IR. However, generating it in Naga IR ensures tricky details such as member alignment are handled for us. wgsl-out must ensure it does *not* generate code for this type, as it handles external textures natively. --- naga/src/back/wgsl/writer.rs | 20 +++- naga/src/compact/mod.rs | 12 ++ naga/src/front/type_gen.rs | 94 ++++++++++++++++ naga/src/front/wgsl/lower/mod.rs | 28 ++++- naga/src/ir/mod.rs | 22 ++++ naga/tests/out/ir/spv-fetch_depth.compact.ron | 1 + naga/tests/out/ir/spv-fetch_depth.ron | 1 + naga/tests/out/ir/spv-shadow.compact.ron | 1 + naga/tests/out/ir/spv-shadow.ron | 1 + .../out/ir/spv-spec-constants.compact.ron | 1 + naga/tests/out/ir/spv-spec-constants.ron | 1 + naga/tests/out/ir/wgsl-access.compact.ron | 1 + naga/tests/out/ir/wgsl-access.ron | 1 + naga/tests/out/ir/wgsl-collatz.compact.ron | 1 + naga/tests/out/ir/wgsl-collatz.ron | 1 + .../out/ir/wgsl-const_assert.compact.ron | 1 + naga/tests/out/ir/wgsl-const_assert.ron | 1 + .../out/ir/wgsl-diagnostic-filter.compact.ron | 1 + naga/tests/out/ir/wgsl-diagnostic-filter.ron | 1 + .../out/ir/wgsl-index-by-value.compact.ron | 1 + naga/tests/out/ir/wgsl-index-by-value.ron | 1 + .../tests/out/ir/wgsl-local-const.compact.ron | 1 + naga/tests/out/ir/wgsl-local-const.ron | 1 + naga/tests/out/ir/wgsl-must-use.compact.ron | 1 + naga/tests/out/ir/wgsl-must-use.ron | 1 + ...ides-atomicCompareExchangeWeak.compact.ron | 1 + ...sl-overrides-atomicCompareExchangeWeak.ron | 1 + .../ir/wgsl-overrides-ray-query.compact.ron | 1 + .../tests/out/ir/wgsl-overrides-ray-query.ron | 1 + naga/tests/out/ir/wgsl-overrides.compact.ron | 1 + naga/tests/out/ir/wgsl-overrides.ron | 1 + .../out/ir/wgsl-storage-textures.compact.ron | 1 + naga/tests/out/ir/wgsl-storage-textures.ron | 1 + ...l-template-list-trailing-comma.compact.ron | 1 + .../ir/wgsl-template-list-trailing-comma.ron | 1 + .../out/ir/wgsl-texture-external.compact.ron | 106 ++++++++++++++---- naga/tests/out/ir/wgsl-texture-external.ron | 106 ++++++++++++++---- .../ir/wgsl-types_with_comments.compact.ron | 1 + .../tests/out/ir/wgsl-types_with_comments.ron | 1 + wgpu-core/src/device/resource.rs | 13 ++- 40 files changed, 386 insertions(+), 47 deletions(-) diff --git a/naga/src/back/wgsl/writer.rs b/naga/src/back/wgsl/writer.rs index 58c1b734f09..dd2696c17f7 100644 --- a/naga/src/back/wgsl/writer.rs +++ b/naga/src/back/wgsl/writer.rs @@ -109,12 +109,28 @@ impl Writer { self.required_polyfills.clear(); } - fn is_builtin_wgsl_struct(&self, module: &Module, handle: Handle) -> bool { + /// Determine if `ty` is the Naga IR presentation of a WGSL builtin type. + /// + /// Return true if `ty` refers to the Naga IR form of a WGSL builtin type + /// like `__atomic_compare_exchange_result`. + /// + /// Even though the module may use the type, the WGSL backend should avoid + /// emitting a definition for it, since it is [predeclared] in WGSL. + /// + /// This also covers types like [`NagaExternalTextureParams`], which other + /// backends use to lower WGSL constructs like external textures to their + /// implementations. WGSL can express these directly, so the types need not + /// be emitted. + /// + /// [predeclared]: https://www.w3.org/TR/WGSL/#predeclared + /// [`NagaExternalTextureParams`]: crate::ir::SpecialTypes::external_texture_params + fn is_builtin_wgsl_struct(&self, module: &Module, ty: Handle) -> bool { module .special_types .predeclared_types .values() - .any(|t| *t == handle) + .any(|t| *t == ty) + || Some(ty) == module.special_types.external_texture_params } pub fn write(&mut self, module: &Module, info: &valid::ModuleInfo) -> BackendResult { diff --git a/naga/src/compact/mod.rs b/naga/src/compact/mod.rs index fe4296be844..7fbb5c532f2 100644 --- a/naga/src/compact/mod.rs +++ b/naga/src/compact/mod.rs @@ -380,6 +380,7 @@ impl<'module> ModuleTracer<'module> { ref ray_intersection, ref ray_vertex_return, ref predeclared_types, + ref external_texture_params, } = *special_types; if let Some(ray_desc) = *ray_desc { @@ -391,6 +392,12 @@ impl<'module> ModuleTracer<'module> { if let Some(ray_vertex_return) = *ray_vertex_return { self.types_used.insert(ray_vertex_return); } + // The `external_texture_params` type is generated purely as a + // convenience to the backends. While it will never actually be used in + // the IR, it must be marked as used so that it survives compaction. + if let Some(external_texture_params) = *external_texture_params { + self.types_used.insert(external_texture_params); + } for (_, &handle) in predeclared_types { self.types_used.insert(handle); } @@ -532,6 +539,7 @@ impl ModuleMap { ref mut ray_intersection, ref mut ray_vertex_return, ref mut predeclared_types, + ref mut external_texture_params, } = *special; if let Some(ref mut ray_desc) = *ray_desc { @@ -545,6 +553,10 @@ impl ModuleMap { self.types.adjust(ray_vertex_return); } + if let Some(ref mut external_texture_params) = *external_texture_params { + self.types.adjust(external_texture_params); + } + for handle in predeclared_types.values_mut() { self.types.adjust(handle); } diff --git a/naga/src/front/type_gen.rs b/naga/src/front/type_gen.rs index 9a01b637d5a..d58561796bd 100644 --- a/naga/src/front/type_gen.rs +++ b/naga/src/front/type_gen.rs @@ -276,6 +276,100 @@ impl crate::Module { handle } + /// Generate [`SpecialTypes::external_texture_params`]. + /// + /// [`SpecialTypes::external_texture_params`]: crate::ir::SpecialTypes::external_texture_params + pub fn generate_external_texture_params_type(&mut self) -> Handle { + if let Some(handle) = self.special_types.external_texture_params { + return handle; + } + + let ty_u32 = self.types.insert( + crate::Type { + name: None, + inner: crate::TypeInner::Scalar(crate::Scalar::U32), + }, + Span::UNDEFINED, + ); + let ty_vec2u = self.types.insert( + crate::Type { + name: None, + inner: crate::TypeInner::Vector { + size: crate::VectorSize::Bi, + scalar: crate::Scalar::U32, + }, + }, + Span::UNDEFINED, + ); + let ty_mat3x2f = self.types.insert( + crate::Type { + name: None, + inner: crate::TypeInner::Matrix { + columns: crate::VectorSize::Tri, + rows: crate::VectorSize::Bi, + scalar: crate::Scalar::F32, + }, + }, + Span::UNDEFINED, + ); + let ty_mat4x4f = self.types.insert( + crate::Type { + name: None, + inner: crate::TypeInner::Matrix { + columns: crate::VectorSize::Quad, + rows: crate::VectorSize::Quad, + scalar: crate::Scalar::F32, + }, + }, + Span::UNDEFINED, + ); + + let handle = self.types.insert( + crate::Type { + name: Some("NagaExternalTextureParams".to_string()), + inner: crate::TypeInner::Struct { + members: vec![ + crate::StructMember { + name: Some("yuv_conversion_matrix".to_string()), + ty: ty_mat4x4f, + binding: None, + offset: 0, + }, + crate::StructMember { + name: Some("sample_transform".to_string()), + ty: ty_mat3x2f, + binding: None, + offset: 64, + }, + crate::StructMember { + name: Some("load_transform".to_string()), + ty: ty_mat3x2f, + binding: None, + offset: 88, + }, + crate::StructMember { + name: Some("size".to_string()), + ty: ty_vec2u, + binding: None, + offset: 112, + }, + crate::StructMember { + name: Some("num_planes".to_string()), + ty: ty_u32, + binding: None, + offset: 120, + }, + ], + span: 128, + }, + }, + Span::UNDEFINED, + ); + + self.special_types.external_texture_params = Some(handle); + handle + } + /// Populate this module's [`SpecialTypes::predeclared_types`] type and return the handle. /// /// [`SpecialTypes::predeclared_types`]: crate::SpecialTypes::predeclared_types diff --git a/naga/src/front/wgsl/lower/mod.rs b/naga/src/front/wgsl/lower/mod.rs index c8545ca654a..3b6e7806c32 100644 --- a/naga/src/front/wgsl/lower/mod.rs +++ b/naga/src/front/wgsl/lower/mod.rs @@ -3983,11 +3983,29 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { dim, arrayed, class, - } => ir::TypeInner::Image { - dim, - arrayed, - class, - }, + } => { + if class == crate::ImageClass::External { + // Other than the WGSL backend, every backend that supports + // external textures does so by lowering them to a set of + // ordinary textures and some parameters saying how to + // sample from them. We don't know which backend will + // consume the `Module` we're building, but in case it's not + // WGSL, populate `SpecialTypes::external_texture_params` + // with the type the backend will use for the parameter + // buffer. + // + // This is *not* the type we are lowering here: that's an + // ordinary `TypeInner::Image`. But the fact we are + // lowering a `texture_external` implies the backends may + // need `SpecialTypes::external_texture_params` too. + ctx.module.generate_external_texture_params_type(); + } + ir::TypeInner::Image { + dim, + arrayed, + class, + } + } ast::Type::Sampler { comparison } => ir::TypeInner::Sampler { comparison }, ast::Type::AccelerationStructure { vertex_return } => { ir::TypeInner::AccelerationStructure { vertex_return } diff --git a/naga/src/ir/mod.rs b/naga/src/ir/mod.rs index 0101954849f..1744ff92fcd 100644 --- a/naga/src/ir/mod.rs +++ b/naga/src/ir/mod.rs @@ -2346,6 +2346,28 @@ pub struct SpecialTypes { /// Call [`Module::generate_vertex_return_type`] pub ray_vertex_return: Option>, + /// Struct containing parameters required by some backends to emit code for + /// [`ImageClass::External`] textures. + /// + /// See `wgpu_core::device::resource::ExternalTextureParams` for the + /// documentation of each field. + /// + /// In WGSL, this type would be: + /// + /// ```ignore + /// struct NagaExternalTextureParams { // align size offset + /// yuv_conversion_matrix: mat4x4, // 16 64 0 + /// sample_transform: mat3x2, // 8 24 64 + /// load_transform: mat3x2, // 8 24 88 + /// size: vec2, // 8 8 112 + /// num_planes: u32, // 4 4 120 + /// } // whole struct: 16 128 + /// ``` + /// + /// Call [`Module::generate_external_texture_params_type`] to populate this + /// if needed and return the handle. + pub external_texture_params: Option>, + /// Types for predeclared wgsl types instantiated on demand. /// /// Call [`Module::generate_predeclared_type`] to populate this if diff --git a/naga/tests/out/ir/spv-fetch_depth.compact.ron b/naga/tests/out/ir/spv-fetch_depth.compact.ron index 024f918022c..c2b7b9b5f6e 100644 --- a/naga/tests/out/ir/spv-fetch_depth.compact.ron +++ b/naga/tests/out/ir/spv-fetch_depth.compact.ron @@ -67,6 +67,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [ diff --git a/naga/tests/out/ir/spv-fetch_depth.ron b/naga/tests/out/ir/spv-fetch_depth.ron index 8daa29847ff..dd019d62aa8 100644 --- a/naga/tests/out/ir/spv-fetch_depth.ron +++ b/naga/tests/out/ir/spv-fetch_depth.ron @@ -130,6 +130,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [ diff --git a/naga/tests/out/ir/spv-shadow.compact.ron b/naga/tests/out/ir/spv-shadow.compact.ron index 7f4e6df5c1a..04547e651ce 100644 --- a/naga/tests/out/ir/spv-shadow.compact.ron +++ b/naga/tests/out/ir/spv-shadow.compact.ron @@ -155,6 +155,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [ diff --git a/naga/tests/out/ir/spv-shadow.ron b/naga/tests/out/ir/spv-shadow.ron index 35a9e48befc..0babda31f58 100644 --- a/naga/tests/out/ir/spv-shadow.ron +++ b/naga/tests/out/ir/spv-shadow.ron @@ -278,6 +278,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [ diff --git a/naga/tests/out/ir/spv-spec-constants.compact.ron b/naga/tests/out/ir/spv-spec-constants.compact.ron index 698a8072584..a07dd0aca04 100644 --- a/naga/tests/out/ir/spv-spec-constants.compact.ron +++ b/naga/tests/out/ir/spv-spec-constants.compact.ron @@ -171,6 +171,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [ diff --git a/naga/tests/out/ir/spv-spec-constants.ron b/naga/tests/out/ir/spv-spec-constants.ron index 5afd71ed657..643d3c7303c 100644 --- a/naga/tests/out/ir/spv-spec-constants.ron +++ b/naga/tests/out/ir/spv-spec-constants.ron @@ -262,6 +262,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [ diff --git a/naga/tests/out/ir/wgsl-access.compact.ron b/naga/tests/out/ir/wgsl-access.compact.ron index 5e15ff84caf..fff8d0bcf9b 100644 --- a/naga/tests/out/ir/wgsl-access.compact.ron +++ b/naga/tests/out/ir/wgsl-access.compact.ron @@ -421,6 +421,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-access.ron b/naga/tests/out/ir/wgsl-access.ron index 5e15ff84caf..fff8d0bcf9b 100644 --- a/naga/tests/out/ir/wgsl-access.ron +++ b/naga/tests/out/ir/wgsl-access.ron @@ -421,6 +421,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-collatz.compact.ron b/naga/tests/out/ir/wgsl-collatz.compact.ron index ce0d6d8c89b..30168b26292 100644 --- a/naga/tests/out/ir/wgsl-collatz.compact.ron +++ b/naga/tests/out/ir/wgsl-collatz.compact.ron @@ -44,6 +44,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-collatz.ron b/naga/tests/out/ir/wgsl-collatz.ron index ce0d6d8c89b..30168b26292 100644 --- a/naga/tests/out/ir/wgsl-collatz.ron +++ b/naga/tests/out/ir/wgsl-collatz.ron @@ -44,6 +44,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-const_assert.compact.ron b/naga/tests/out/ir/wgsl-const_assert.compact.ron index c10c9f97d32..4d77a57494d 100644 --- a/naga/tests/out/ir/wgsl-const_assert.compact.ron +++ b/naga/tests/out/ir/wgsl-const_assert.compact.ron @@ -4,6 +4,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-const_assert.ron b/naga/tests/out/ir/wgsl-const_assert.ron index c10c9f97d32..4d77a57494d 100644 --- a/naga/tests/out/ir/wgsl-const_assert.ron +++ b/naga/tests/out/ir/wgsl-const_assert.ron @@ -4,6 +4,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-diagnostic-filter.compact.ron b/naga/tests/out/ir/wgsl-diagnostic-filter.compact.ron index dc4d2defdbd..10f533f1059 100644 --- a/naga/tests/out/ir/wgsl-diagnostic-filter.compact.ron +++ b/naga/tests/out/ir/wgsl-diagnostic-filter.compact.ron @@ -4,6 +4,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-diagnostic-filter.ron b/naga/tests/out/ir/wgsl-diagnostic-filter.ron index dc4d2defdbd..10f533f1059 100644 --- a/naga/tests/out/ir/wgsl-diagnostic-filter.ron +++ b/naga/tests/out/ir/wgsl-diagnostic-filter.ron @@ -4,6 +4,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-index-by-value.compact.ron b/naga/tests/out/ir/wgsl-index-by-value.compact.ron index 8f3de4f3e2e..31a60105410 100644 --- a/naga/tests/out/ir/wgsl-index-by-value.compact.ron +++ b/naga/tests/out/ir/wgsl-index-by-value.compact.ron @@ -81,6 +81,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-index-by-value.ron b/naga/tests/out/ir/wgsl-index-by-value.ron index 8f3de4f3e2e..31a60105410 100644 --- a/naga/tests/out/ir/wgsl-index-by-value.ron +++ b/naga/tests/out/ir/wgsl-index-by-value.ron @@ -81,6 +81,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-local-const.compact.ron b/naga/tests/out/ir/wgsl-local-const.compact.ron index 8bce0bb0084..b7deb55aca5 100644 --- a/naga/tests/out/ir/wgsl-local-const.compact.ron +++ b/naga/tests/out/ir/wgsl-local-const.compact.ron @@ -26,6 +26,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [ diff --git a/naga/tests/out/ir/wgsl-local-const.ron b/naga/tests/out/ir/wgsl-local-const.ron index 8bce0bb0084..b7deb55aca5 100644 --- a/naga/tests/out/ir/wgsl-local-const.ron +++ b/naga/tests/out/ir/wgsl-local-const.ron @@ -26,6 +26,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [ diff --git a/naga/tests/out/ir/wgsl-must-use.compact.ron b/naga/tests/out/ir/wgsl-must-use.compact.ron index 0534e736397..4d148b9061d 100644 --- a/naga/tests/out/ir/wgsl-must-use.compact.ron +++ b/naga/tests/out/ir/wgsl-must-use.compact.ron @@ -12,6 +12,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-must-use.ron b/naga/tests/out/ir/wgsl-must-use.ron index 0534e736397..4d148b9061d 100644 --- a/naga/tests/out/ir/wgsl-must-use.ron +++ b/naga/tests/out/ir/wgsl-must-use.ron @@ -12,6 +12,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-overrides-atomicCompareExchangeWeak.compact.ron b/naga/tests/out/ir/wgsl-overrides-atomicCompareExchangeWeak.compact.ron index ac45d5bad6a..1e568ebbc3d 100644 --- a/naga/tests/out/ir/wgsl-overrides-atomicCompareExchangeWeak.compact.ron +++ b/naga/tests/out/ir/wgsl-overrides-atomicCompareExchangeWeak.compact.ron @@ -53,6 +53,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: { AtomicCompareExchangeWeakResult(( kind: Uint, diff --git a/naga/tests/out/ir/wgsl-overrides-atomicCompareExchangeWeak.ron b/naga/tests/out/ir/wgsl-overrides-atomicCompareExchangeWeak.ron index ac45d5bad6a..1e568ebbc3d 100644 --- a/naga/tests/out/ir/wgsl-overrides-atomicCompareExchangeWeak.ron +++ b/naga/tests/out/ir/wgsl-overrides-atomicCompareExchangeWeak.ron @@ -53,6 +53,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: { AtomicCompareExchangeWeakResult(( kind: Uint, diff --git a/naga/tests/out/ir/wgsl-overrides-ray-query.compact.ron b/naga/tests/out/ir/wgsl-overrides-ray-query.compact.ron index 0848ed2b73c..649ba28d476 100644 --- a/naga/tests/out/ir/wgsl-overrides-ray-query.compact.ron +++ b/naga/tests/out/ir/wgsl-overrides-ray-query.compact.ron @@ -85,6 +85,7 @@ ray_desc: Some(5), ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-overrides-ray-query.ron b/naga/tests/out/ir/wgsl-overrides-ray-query.ron index 0848ed2b73c..649ba28d476 100644 --- a/naga/tests/out/ir/wgsl-overrides-ray-query.ron +++ b/naga/tests/out/ir/wgsl-overrides-ray-query.ron @@ -85,6 +85,7 @@ ray_desc: Some(5), ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-overrides.compact.ron b/naga/tests/out/ir/wgsl-overrides.compact.ron index 4c40ef32de7..eca51561070 100644 --- a/naga/tests/out/ir/wgsl-overrides.compact.ron +++ b/naga/tests/out/ir/wgsl-overrides.compact.ron @@ -26,6 +26,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-overrides.ron b/naga/tests/out/ir/wgsl-overrides.ron index 4c40ef32de7..eca51561070 100644 --- a/naga/tests/out/ir/wgsl-overrides.ron +++ b/naga/tests/out/ir/wgsl-overrides.ron @@ -26,6 +26,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-storage-textures.compact.ron b/naga/tests/out/ir/wgsl-storage-textures.compact.ron index 4f1325da561..eb70e3badd2 100644 --- a/naga/tests/out/ir/wgsl-storage-textures.compact.ron +++ b/naga/tests/out/ir/wgsl-storage-textures.compact.ron @@ -71,6 +71,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-storage-textures.ron b/naga/tests/out/ir/wgsl-storage-textures.ron index 4f1325da561..eb70e3badd2 100644 --- a/naga/tests/out/ir/wgsl-storage-textures.ron +++ b/naga/tests/out/ir/wgsl-storage-textures.ron @@ -71,6 +71,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-template-list-trailing-comma.compact.ron b/naga/tests/out/ir/wgsl-template-list-trailing-comma.compact.ron index 67ec4ffb52d..bfcd83f7f35 100644 --- a/naga/tests/out/ir/wgsl-template-list-trailing-comma.compact.ron +++ b/naga/tests/out/ir/wgsl-template-list-trailing-comma.compact.ron @@ -28,6 +28,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-template-list-trailing-comma.ron b/naga/tests/out/ir/wgsl-template-list-trailing-comma.ron index 67ec4ffb52d..bfcd83f7f35 100644 --- a/naga/tests/out/ir/wgsl-template-list-trailing-comma.ron +++ b/naga/tests/out/ir/wgsl-template-list-trailing-comma.ron @@ -28,6 +28,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-texture-external.compact.ron b/naga/tests/out/ir/wgsl-texture-external.compact.ron index 4c0876618da..2bceb18a51f 100644 --- a/naga/tests/out/ir/wgsl-texture-external.compact.ron +++ b/naga/tests/out/ir/wgsl-texture-external.compact.ron @@ -2,34 +2,101 @@ types: [ ( name: None, - inner: Image( - dim: D2, - arrayed: false, - class: External, + inner: Scalar(( + kind: Uint, + width: 4, + )), + ), + ( + name: None, + inner: Vector( + size: Bi, + scalar: ( + kind: Uint, + width: 4, + ), ), ), ( name: None, - inner: Sampler( - comparison: false, + inner: Matrix( + columns: Tri, + rows: Bi, + scalar: ( + kind: Float, + width: 4, + ), ), ), ( name: None, - inner: Vector( - size: Quad, + inner: Matrix( + columns: Quad, + rows: Quad, scalar: ( kind: Float, width: 4, ), ), ), + ( + name: Some("NagaExternalTextureParams"), + inner: Struct( + members: [ + ( + name: Some("yuv_conversion_matrix"), + ty: 3, + binding: None, + offset: 0, + ), + ( + name: Some("sample_transform"), + ty: 2, + binding: None, + offset: 64, + ), + ( + name: Some("load_transform"), + ty: 2, + binding: None, + offset: 88, + ), + ( + name: Some("size"), + ty: 1, + binding: None, + offset: 112, + ), + ( + name: Some("num_planes"), + ty: 0, + binding: None, + offset: 120, + ), + ], + span: 128, + ), + ), + ( + name: None, + inner: Image( + dim: D2, + arrayed: false, + class: External, + ), + ), + ( + name: None, + inner: Sampler( + comparison: false, + ), + ), ( name: None, inner: Vector( - size: Bi, + size: Quad, scalar: ( - kind: Uint, + kind: Float, width: 4, ), ), @@ -39,6 +106,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: Some(4), predeclared_types: {}, ), constants: [], @@ -51,7 +119,7 @@ group: 0, binding: 0, )), - ty: 0, + ty: 5, init: None, ), ( @@ -61,7 +129,7 @@ group: 0, binding: 1, )), - ty: 1, + ty: 6, init: None, ), ], @@ -72,28 +140,28 @@ arguments: [ ( name: Some("t"), - ty: 0, + ty: 5, binding: None, ), ], result: Some(( - ty: 2, + ty: 7, binding: None, )), local_variables: [ ( name: Some("a"), - ty: 2, + ty: 7, init: None, ), ( name: Some("b"), - ty: 2, + ty: 7, init: None, ), ( name: Some("c"), - ty: 3, + ty: 1, init: None, ), ], @@ -217,7 +285,7 @@ name: Some("fragment_main"), arguments: [], result: Some(( - ty: 2, + ty: 7, binding: Some(Location( location: 0, interpolation: Some(Perspective), @@ -256,7 +324,7 @@ name: Some("vertex_main"), arguments: [], result: Some(( - ty: 2, + ty: 7, binding: Some(BuiltIn(Position( invariant: false, ))), diff --git a/naga/tests/out/ir/wgsl-texture-external.ron b/naga/tests/out/ir/wgsl-texture-external.ron index 4c0876618da..2bceb18a51f 100644 --- a/naga/tests/out/ir/wgsl-texture-external.ron +++ b/naga/tests/out/ir/wgsl-texture-external.ron @@ -2,34 +2,101 @@ types: [ ( name: None, - inner: Image( - dim: D2, - arrayed: false, - class: External, + inner: Scalar(( + kind: Uint, + width: 4, + )), + ), + ( + name: None, + inner: Vector( + size: Bi, + scalar: ( + kind: Uint, + width: 4, + ), ), ), ( name: None, - inner: Sampler( - comparison: false, + inner: Matrix( + columns: Tri, + rows: Bi, + scalar: ( + kind: Float, + width: 4, + ), ), ), ( name: None, - inner: Vector( - size: Quad, + inner: Matrix( + columns: Quad, + rows: Quad, scalar: ( kind: Float, width: 4, ), ), ), + ( + name: Some("NagaExternalTextureParams"), + inner: Struct( + members: [ + ( + name: Some("yuv_conversion_matrix"), + ty: 3, + binding: None, + offset: 0, + ), + ( + name: Some("sample_transform"), + ty: 2, + binding: None, + offset: 64, + ), + ( + name: Some("load_transform"), + ty: 2, + binding: None, + offset: 88, + ), + ( + name: Some("size"), + ty: 1, + binding: None, + offset: 112, + ), + ( + name: Some("num_planes"), + ty: 0, + binding: None, + offset: 120, + ), + ], + span: 128, + ), + ), + ( + name: None, + inner: Image( + dim: D2, + arrayed: false, + class: External, + ), + ), + ( + name: None, + inner: Sampler( + comparison: false, + ), + ), ( name: None, inner: Vector( - size: Bi, + size: Quad, scalar: ( - kind: Uint, + kind: Float, width: 4, ), ), @@ -39,6 +106,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: Some(4), predeclared_types: {}, ), constants: [], @@ -51,7 +119,7 @@ group: 0, binding: 0, )), - ty: 0, + ty: 5, init: None, ), ( @@ -61,7 +129,7 @@ group: 0, binding: 1, )), - ty: 1, + ty: 6, init: None, ), ], @@ -72,28 +140,28 @@ arguments: [ ( name: Some("t"), - ty: 0, + ty: 5, binding: None, ), ], result: Some(( - ty: 2, + ty: 7, binding: None, )), local_variables: [ ( name: Some("a"), - ty: 2, + ty: 7, init: None, ), ( name: Some("b"), - ty: 2, + ty: 7, init: None, ), ( name: Some("c"), - ty: 3, + ty: 1, init: None, ), ], @@ -217,7 +285,7 @@ name: Some("fragment_main"), arguments: [], result: Some(( - ty: 2, + ty: 7, binding: Some(Location( location: 0, interpolation: Some(Perspective), @@ -256,7 +324,7 @@ name: Some("vertex_main"), arguments: [], result: Some(( - ty: 2, + ty: 7, binding: Some(BuiltIn(Position( invariant: false, ))), diff --git a/naga/tests/out/ir/wgsl-types_with_comments.compact.ron b/naga/tests/out/ir/wgsl-types_with_comments.compact.ron index dde1bd367b0..1139fab1976 100644 --- a/naga/tests/out/ir/wgsl-types_with_comments.compact.ron +++ b/naga/tests/out/ir/wgsl-types_with_comments.compact.ron @@ -37,6 +37,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [ diff --git a/naga/tests/out/ir/wgsl-types_with_comments.ron b/naga/tests/out/ir/wgsl-types_with_comments.ron index 3a23c49c4f2..a1761c17c8e 100644 --- a/naga/tests/out/ir/wgsl-types_with_comments.ron +++ b/naga/tests/out/ir/wgsl-types_with_comments.ron @@ -62,6 +62,7 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, + external_texture_params: None, predeclared_types: {}, ), constants: [ diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index ed03fce774b..3f212f80eef 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -85,9 +85,18 @@ pub struct ExternalTextureParams { /// to RGBA. /// This is ignored when `num_planes` is 1. pub yuv_conversion_matrix: [f32; 16], - /// 3x2 column-major matrix with which to multiply texture coordinates - /// prior to sampling from the external texture. + /// 3x2 column-major matrix with which to multiply normalized texture + /// coordinates prior to sampling from the external texture. This may + /// scale, translate, flip, and rotate in 90-degree increments, but the + /// result of transforming the rectangle (0,0)..(1,1) must be an + /// axis-aligned rectangle that falls within the bounds of (0,0)..(1,1). pub sample_transform: [f32; 6], + /// 3x2 column-major matrix with which to multiply unnormalized texture + /// coordinates prior to loading from the external texture. This may scale, + /// translate, flip, and rotate in 90-degree increments, but the result of + /// transforming the rectangle (0,0)..(texture_size - 1) must be an + /// axis-aligned rectangle that falls within the bounds of + /// (0,0)..(texture_size - 1). pub load_transform: [f32; 6], /// Size of the external texture. This value should be returned by size /// queries in shader code. Note that this may not match the dimensions of From 0448b460333634aa0e6595f25b19a9704d70d91f Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Mon, 2 Jun 2025 17:21:23 +0100 Subject: [PATCH 078/303] [naga] Reserve names for each plane and params buffer of external texture Adds new `NameKey` variants `ExternalTextureGlobalVariable` and `ExternalTextureFunctionArgument`, like their non-external-texture cousins but additionally keyed by either being a specific plane index or params buffer. For each external texture global variable or function argument reserve additional names for 3 planes and the params buffer. For Naga backends which must represent external textures as multiple variables/arguments, this will allow them to uniquely name each one. --- naga/src/back/mod.rs | 25 +++++++++++++ naga/src/proc/mod.rs | 2 +- naga/src/proc/namer.rs | 83 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 1 deletion(-) diff --git a/naga/src/back/mod.rs b/naga/src/back/mod.rs index d7b14475bff..0d13d63dd9b 100644 --- a/naga/src/back/mod.rs +++ b/naga/src/back/mod.rs @@ -196,6 +196,31 @@ impl FunctionCtx<'_> { } } + /// Helper method that generates a [`NameKey`](crate::proc::NameKey) for an external texture + /// function argument. + /// + /// # Panics + /// - If the function arguments are less or equal to `arg` + /// - If `self.ty` is not `FunctionType::Function`. + pub const fn external_texture_argument_key( + &self, + arg: u32, + external_texture_key: crate::proc::ExternalTextureNameKey, + ) -> crate::proc::NameKey { + match self.ty { + FunctionType::Function(handle) => { + crate::proc::NameKey::ExternalTextureFunctionArgument( + handle, + arg, + external_texture_key, + ) + } + FunctionType::EntryPoint(_) => { + panic!("External textures cannot be used as arguments to entry points") + } + } + } + /// Returns true if the given expression points to a fixed-function pipeline input. pub fn is_fixed_function_input( &self, diff --git a/naga/src/proc/mod.rs b/naga/src/proc/mod.rs index f2584c64b3d..413e49c1eed 100644 --- a/naga/src/proc/mod.rs +++ b/naga/src/proc/mod.rs @@ -18,7 +18,7 @@ pub use constant_evaluator::{ pub use emitter::Emitter; pub use index::{BoundsCheckPolicies, BoundsCheckPolicy, IndexableLength, IndexableLengthError}; pub use layouter::{Alignment, LayoutError, LayoutErrorInner, Layouter, TypeLayout}; -pub use namer::{EntryPointIndex, NameKey, Namer}; +pub use namer::{EntryPointIndex, ExternalTextureNameKey, NameKey, Namer}; pub use overloads::{Conclusion, MissingSpecialType, OverloadSet, Rule}; pub use terminator::ensure_block_returns; use thiserror::Error; diff --git a/naga/src/proc/namer.rs b/naga/src/proc/namer.rs index 504617dd1d3..0b812ff036a 100644 --- a/naga/src/proc/namer.rs +++ b/naga/src/proc/namer.rs @@ -15,6 +15,40 @@ use crate::{arena::Handle, FastHashMap, FastHashSet}; pub type EntryPointIndex = u16; const SEPARATOR: char = '_'; +/// A component of a lowered external texture. +/// +/// Whereas the WGSL backend implements [`ImageClass::External`] +/// images directly, most other Naga backends lower them to a +/// collection of ordinary textures that represent individual planes +/// (as received from a video decoder, perhaps), together with a +/// struct of parameters saying how they should be cropped, sampled, +/// and color-converted. +/// +/// This lowering means that individual globals and function +/// parameters in Naga IR must be split out by the backends into +/// collections of globals and parameters of simpler types. +/// +/// A value of this enum serves as a name key for one specific +/// component in the lowered representation of an external texture. +/// That is, these keys are for variables/parameters that do not exist +/// in the Naga IR, only in its lowered form. +/// +/// [`ImageClass::External`]: crate::ir::ImageClass::External +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub enum ExternalTextureNameKey { + Plane(usize), + Params, +} + +impl ExternalTextureNameKey { + const ALL: &[(&str, ExternalTextureNameKey)] = &[ + ("_plane0", ExternalTextureNameKey::Plane(0)), + ("_plane1", ExternalTextureNameKey::Plane(1)), + ("_plane2", ExternalTextureNameKey::Plane(2)), + ("_params", ExternalTextureNameKey::Params), + ]; +} + #[derive(Debug, Eq, Hash, PartialEq)] pub enum NameKey { Constant(Handle), @@ -37,6 +71,17 @@ pub enum NameKey { /// Entry point version of `FunctionOobLocal`. EntryPointOobLocal(EntryPointIndex, Handle), + + /// A global variable holding a component of a lowered external texture. + /// + /// See [`ExternalTextureNameKey`] for details. + ExternalTextureGlobalVariable(Handle, ExternalTextureNameKey), + + /// A function argument holding a component of a lowered external + /// texture. + /// + /// See [`ExternalTextureNameKey`] for details. + ExternalTextureFunctionArgument(Handle, u32, ExternalTextureNameKey), } /// This processor assigns names to all the things in a module @@ -272,6 +317,27 @@ impl Namer { for (index, arg) in fun.arguments.iter().enumerate() { let name = self.call_or(&arg.name, "param"); output.insert(NameKey::FunctionArgument(fun_handle, index as u32), name); + + if matches!( + module.types[arg.ty].inner, + crate::TypeInner::Image { + class: crate::ImageClass::External, + .. + } + ) { + let base = arg.name.as_deref().unwrap_or("param"); + for &(suffix, ext_key) in ExternalTextureNameKey::ALL { + let name = self.call(&format!("{base}_{suffix}")); + output.insert( + NameKey::ExternalTextureFunctionArgument( + fun_handle, + index as u32, + ext_key, + ), + name, + ); + } + } } for (handle, var) in fun.local_variables.iter() { let name = self.call_or(&var.name, "local"); @@ -282,6 +348,23 @@ impl Namer { for (handle, var) in module.global_variables.iter() { let name = self.call_or(&var.name, "global"); output.insert(NameKey::GlobalVariable(handle), name); + + if matches!( + module.types[var.ty].inner, + crate::TypeInner::Image { + class: crate::ImageClass::External, + .. + } + ) { + let base = var.name.as_deref().unwrap_or("global"); + for &(suffix, ext_key) in ExternalTextureNameKey::ALL { + let name = self.call(&format!("{base}_{suffix}")); + output.insert( + NameKey::ExternalTextureGlobalVariable(handle, ext_key), + name, + ); + } + } } for (handle, constant) in module.constants.iter() { From e1ccb6632cb9cd641ce4a14e40cc0e08411d673a Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Mon, 2 Jun 2025 17:21:23 +0100 Subject: [PATCH 079/303] [naga hlsl-out] Implement external texture support This adds HLSL backend support for `ImageClass::External` (ie WGSL's `external_texture` texture type). For each external texture global variable in the IR, we declare 3 `Texture2D` globals as well as a `cbuffer` for the params. The additional bindings required by these are found in the newly added `external_texture_binding_map`. Unique names for each can be obtained using `NameKey::ExternalTextureGlobalVariable`. For functions that contain ImageQuery::Size, ImageLoad, or ImageSample expressions for external textures, ensure we have generated wrapper functions for those expressions. When emitting code for the expressions themselves, simply insert a call to the wrapper function. For size queries, we return the value provided in the params struct. If that value is [0, 0] then we query the size of the plane 0 texture and return that. For load and sample, we sample the textures based on the number of planes specified in the params struct. If there is more than one plane we additionally perform YUV to RGB conversion using the provided matrix. Unfortunately HLSL does not allow structs to contain textures, meaning we are unable to wrap the 3 textures and params struct variables in a single variable that can be passed around. For our wrapper functions we therefore ensure they take the three textures and the params as consecutive arguments. Likewise, when declaring user-defined functions with external texture arguments, we expand the single external texture argument into 4 consecutive arguments. (Using NameKey::ExternalTextureFunctionArgument to ensure unique names for each.) Thankfully external textures can only be used as either global variables or function arguments. This means we only have to handle the `Expression::GlobalVariable` and `Expression::FunctionArgument` cases of `write_expr()`. Since in both cases we know the external texture can only be an argument to either a user-defined function or one of our wrapper functions, we can simply emit the names of the variables for each three textures and the params struct in a comma-separated list. --- naga-cli/src/bin/naga.rs | 1 + naga/src/back/hlsl/help.rs | 468 ++++++++++++++---- naga/src/back/hlsl/keywords.rs | 2 + naga/src/back/hlsl/mod.rs | 185 ++++++- naga/src/back/hlsl/writer.rs | 265 ++++++++-- naga/src/ir/mod.rs | 14 + naga/src/valid/type.rs | 9 + naga/tests/in/wgsl/texture-external.toml | 15 +- .../tests/out/hlsl/wgsl-texture-external.hlsl | 143 ++++++ naga/tests/out/hlsl/wgsl-texture-external.ron | 20 + wgpu-core/src/device/resource.rs | 59 ++- wgpu-hal/src/dx12/device.rs | 1 + wgpu-types/src/lib.rs | 56 ++- 13 files changed, 1090 insertions(+), 148 deletions(-) create mode 100644 naga/tests/out/hlsl/wgsl-texture-external.hlsl create mode 100644 naga/tests/out/hlsl/wgsl-texture-external.ron diff --git a/naga-cli/src/bin/naga.rs b/naga-cli/src/bin/naga.rs index b018058613c..44369e9df7d 100644 --- a/naga-cli/src/bin/naga.rs +++ b/naga-cli/src/bin/naga.rs @@ -539,6 +539,7 @@ fn run() -> anyhow::Result<()> { let missing = match Path::new(path).extension().and_then(|ex| ex.to_str()) { Some("wgsl") => C::CLIP_DISTANCE | C::CULL_DISTANCE, Some("metal") => C::CULL_DISTANCE | C::TEXTURE_EXTERNAL, + Some("hlsl") => C::empty(), _ => C::TEXTURE_EXTERNAL, }; caps & !missing diff --git a/naga/src/back/hlsl/help.rs b/naga/src/back/hlsl/help.rs index bea917547b5..70c0a692a33 100644 --- a/naga/src/back/hlsl/help.rs +++ b/naga/src/back/hlsl/help.rs @@ -33,8 +33,8 @@ use super::{ super::FunctionCtx, writer::{ ABS_FUNCTION, DIV_FUNCTION, EXTRACT_BITS_FUNCTION, F2I32_FUNCTION, F2I64_FUNCTION, - F2U32_FUNCTION, F2U64_FUNCTION, IMAGE_SAMPLE_BASE_CLAMP_TO_EDGE_FUNCTION, - INSERT_BITS_FUNCTION, MOD_FUNCTION, NEG_FUNCTION, + F2U32_FUNCTION, F2U64_FUNCTION, IMAGE_LOAD_EXTERNAL_FUNCTION, + IMAGE_SAMPLE_BASE_CLAMP_TO_EDGE_FUNCTION, INSERT_BITS_FUNCTION, MOD_FUNCTION, NEG_FUNCTION, }, BackendResult, WrappedType, }; @@ -45,8 +45,14 @@ pub(super) struct WrappedArrayLength { pub(super) writable: bool, } +#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)] +pub(super) struct WrappedImageLoad { + pub(super) class: crate::ImageClass, +} + #[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)] pub(super) struct WrappedImageSample { + pub(super) class: crate::ImageClass, pub(super) clamp_to_edge: bool, } @@ -195,7 +201,11 @@ impl super::Writer<'_, W> { let storage_format_str = format.to_hlsl_str(); write!(self.out, "<{storage_format_str}>")? } - crate::ImageClass::External => unimplemented!(), + crate::ImageClass::External => { + unreachable!( + "external images should be handled by `write_global_external_texture`" + ); + } } Ok(()) } @@ -254,12 +264,236 @@ impl super::Writer<'_, W> { Ok(()) } + pub(super) fn write_wrapped_image_load_function( + &mut self, + module: &crate::Module, + load: WrappedImageLoad, + ) -> BackendResult { + match load { + WrappedImageLoad { + class: crate::ImageClass::External, + } => { + let l1 = crate::back::Level(1); + let l2 = l1.next(); + let l3 = l2.next(); + let params_ty_name = &self.names + [&NameKey::Type(module.special_types.external_texture_params.unwrap())]; + writeln!(self.out, "float4 {IMAGE_LOAD_EXTERNAL_FUNCTION}(")?; + writeln!(self.out, "{l1}Texture2D plane0,")?; + writeln!(self.out, "{l1}Texture2D plane1,")?; + writeln!(self.out, "{l1}Texture2D plane2,")?; + writeln!(self.out, "{l1}{params_ty_name} params,")?; + writeln!(self.out, "{l1}uint2 coords)")?; + writeln!(self.out, "{{")?; + writeln!(self.out, "{l1}uint2 plane0_size;")?; + writeln!( + self.out, + "{l1}plane0.GetDimensions(plane0_size.x, plane0_size.y);" + )?; + // Clamp coords to provided size of external texture to prevent OOB read. + // If params.size is zero then clamp to the actual size of the texture. + writeln!( + self.out, + "{l1}uint2 cropped_size = any(params.size) ? params.size : plane0_size;" + )?; + writeln!(self.out, "{l1}coords = min(coords, cropped_size - 1);")?; + + // Apply load transformation. We declare our matrices as row_major in + // HLSL, therefore we must reverse the order of this multiplication + writeln!(self.out, "{l1}float3x2 load_transform = float3x2(")?; + writeln!(self.out, "{l2}params.load_transform_0,")?; + writeln!(self.out, "{l2}params.load_transform_1,")?; + writeln!(self.out, "{l2}params.load_transform_2")?; + writeln!(self.out, "{l1});")?; + writeln!(self.out, "{l1}uint2 plane0_coords = uint2(round(mul(float3(coords, 1.0), load_transform)));")?; + writeln!(self.out, "{l1}if (params.num_planes == 1u) {{")?; + // For single plane, simply read from plane0 + writeln!( + self.out, + "{l2}return plane0.Load(uint3(plane0_coords, 0u));" + )?; + writeln!(self.out, "{l1}}} else {{")?; + + // Chroma planes may be subsampled so we must scale the coords accordingly. + writeln!(self.out, "{l2}uint2 plane1_size;")?; + writeln!( + self.out, + "{l2}plane1.GetDimensions(plane1_size.x, plane1_size.y);" + )?; + writeln!(self.out, "{l2}uint2 plane1_coords = uint2(floor(float2(plane0_coords) * float2(plane1_size) / float2(plane0_size)));")?; + + // For multi-plane, read the Y value from plane 0 + writeln!( + self.out, + "{l2}float y = plane0.Load(uint3(plane0_coords, 0u)).x;" + )?; + + writeln!(self.out, "{l2}float2 uv;")?; + writeln!(self.out, "{l2}if (params.num_planes == 2u) {{")?; + // Read UV from interleaved plane 1 + writeln!( + self.out, + "{l3}uv = plane1.Load(uint3(plane1_coords, 0u)).xy;" + )?; + writeln!(self.out, "{l2}}} else {{")?; + // Read U and V from planes 1 and 2 respectively + writeln!(self.out, "{l3}uint2 plane2_size;")?; + writeln!( + self.out, + "{l3}plane2.GetDimensions(plane2_size.x, plane2_size.y);" + )?; + writeln!(self.out, "{l3}uint2 plane2_coords = uint2(floor(float2(plane0_coords) * float2(plane2_size) / float2(plane0_size)));")?; + writeln!(self.out, "{l3}uv = float2(plane1.Load(uint3(plane1_coords, 0u)).x, plane2.Load(uint3(plane2_coords, 0u)).x);")?; + writeln!(self.out, "{l2}}}")?; + + // Convert from YUV to RGB. We declare our matrices as row_major in HLSL, + // therefore we must reverse the order of this multiplication + writeln!( + self.out, + "{l2}return mul(float4(y, uv, 1.0), params.yuv_conversion_matrix);" + )?; + + writeln!(self.out, "{l1}}}")?; + writeln!(self.out, "}}")?; + writeln!(self.out)?; + } + _ => {} + } + + Ok(()) + } + pub(super) fn write_wrapped_image_sample_function( &mut self, + module: &crate::Module, sample: WrappedImageSample, ) -> BackendResult { match sample { WrappedImageSample { + class: crate::ImageClass::External, + clamp_to_edge: true, + } => { + let l1 = crate::back::Level(1); + let l2 = l1.next(); + let l3 = l2.next(); + let params_ty_name = &self.names + [&NameKey::Type(module.special_types.external_texture_params.unwrap())]; + writeln!( + self.out, + "float4 {IMAGE_SAMPLE_BASE_CLAMP_TO_EDGE_FUNCTION}(" + )?; + writeln!(self.out, "{l1}Texture2D plane0,")?; + writeln!(self.out, "{l1}Texture2D plane1,")?; + writeln!(self.out, "{l1}Texture2D plane2,")?; + writeln!(self.out, "{l1}{params_ty_name} params,")?; + writeln!(self.out, "{l1}SamplerState samp,")?; + writeln!(self.out, "{l1}float2 coords)")?; + writeln!(self.out, "{{")?; + writeln!(self.out, "{l1}float2 plane0_size;")?; + writeln!( + self.out, + "{l1}plane0.GetDimensions(plane0_size.x, plane0_size.y);" + )?; + writeln!(self.out, "{l1}float3x2 sample_transform = float3x2(")?; + writeln!(self.out, "{l2}params.sample_transform_0,")?; + writeln!(self.out, "{l2}params.sample_transform_1,")?; + writeln!(self.out, "{l2}params.sample_transform_2")?; + writeln!(self.out, "{l1});")?; + // Apply sample transformation. We declare our matrices as row_major in + // HLSL, therefore we must reverse the order of this multiplication + writeln!( + self.out, + "{l1}coords = mul(float3(coords, 1.0), sample_transform);" + )?; + // Calculate the sample bounds. The purported size of the texture + // (params.size) is irrelevant here as we are dealing with normalized + // coordinates. Usually we would clamp to (0,0)..(1,1). However, we must + // apply the sample transformation to that, also bearing in mind that it + // may contain a flip on either axis. We calculate and adjust for the + // half-texel separately for each plane as it depends on the actual + // texture size which may vary between planes. + writeln!( + self.out, + "{l1}float2 bounds_min = mul(float3(0.0, 0.0, 1.0), sample_transform);" + )?; + writeln!( + self.out, + "{l1}float2 bounds_max = mul(float3(1.0, 1.0, 1.0), sample_transform);" + )?; + writeln!(self.out, "{l1}float4 bounds = float4(min(bounds_min, bounds_max), max(bounds_min, bounds_max));")?; + writeln!( + self.out, + "{l1}float2 plane0_half_texel = float2(0.5, 0.5) / plane0_size;" + )?; + writeln!( + self.out, + "{l1}float2 plane0_coords = clamp(coords, bounds.xy + plane0_half_texel, bounds.zw - plane0_half_texel);" + )?; + writeln!(self.out, "{l1}if (params.num_planes == 1u) {{")?; + // For single plane, simply sample from plane0 + writeln!( + self.out, + "{l2}return plane0.SampleLevel(samp, plane0_coords, 0.0f);" + )?; + writeln!(self.out, "{l1}}} else {{")?; + + writeln!(self.out, "{l2}float2 plane1_size;")?; + writeln!( + self.out, + "{l2}plane1.GetDimensions(plane1_size.x, plane1_size.y);" + )?; + writeln!( + self.out, + "{l2}float2 plane1_half_texel = float2(0.5, 0.5) / plane1_size;" + )?; + writeln!( + self.out, + "{l2}float2 plane1_coords = clamp(coords, bounds.xy + plane1_half_texel, bounds.zw - plane1_half_texel);" + )?; + + // For multi-plane, sample the Y value from plane 0 + writeln!( + self.out, + "{l2}float y = plane0.SampleLevel(samp, plane0_coords, 0.0f).x;" + )?; + writeln!(self.out, "{l2}float2 uv;")?; + writeln!(self.out, "{l2}if (params.num_planes == 2u) {{")?; + // Sample UV from interleaved plane 1 + writeln!( + self.out, + "{l3}uv = plane1.SampleLevel(samp, plane1_coords, 0.0f).xy;" + )?; + writeln!(self.out, "{l2}}} else {{")?; + // Sample U and V from planes 1 and 2 respectively + writeln!(self.out, "{l3}float2 plane2_size;")?; + writeln!( + self.out, + "{l3}plane2.GetDimensions(plane2_size.x, plane2_size.y);" + )?; + writeln!( + self.out, + "{l3}float2 plane2_half_texel = float2(0.5, 0.5) / plane2_size;" + )?; + writeln!(self.out, "{l3}float2 plane2_coords = clamp(coords, bounds.xy + plane2_half_texel, bounds.zw - plane2_half_texel);")?; + writeln!(self.out, "{l3}uv = float2(plane1.SampleLevel(samp, plane1_coords, 0.0f).x, plane2.SampleLevel(samp, plane2_coords, 0.0f).x);")?; + writeln!(self.out, "{l2}}}")?; + + // Convert from YUV to RGB. We declare our matrices as row_major in HLSL, + // therefore we must reverse the order of this multiplication + writeln!( + self.out, + "{l2}return mul(float4(y, uv, 1.0), params.yuv_conversion_matrix);" + )?; + writeln!(self.out, "{l1}}}")?; + writeln!(self.out, "}}")?; + writeln!(self.out)?; + } + WrappedImageSample { + class: + crate::ImageClass::Sampled { + kind: ScalarKind::Float, + multi: false, + }, clamp_to_edge: true, } => { writeln!(self.out, "float4 {IMAGE_SAMPLE_BASE_CLAMP_TO_EDGE_FUNCTION}(Texture2D tex, SamplerState samp, float2 coords) {{")?; @@ -291,7 +525,7 @@ impl super::Writer<'_, W> { crate::ImageClass::Depth { multi: false } => "Depth", crate::ImageClass::Sampled { multi: false, .. } => "", crate::ImageClass::Storage { .. } => "RW", - crate::ImageClass::External => unimplemented!(), + crate::ImageClass::External => "External", }; let arrayed_str = if query.arrayed { "Array" } else { "" }; let query_str = match query.query { @@ -322,102 +556,133 @@ impl super::Writer<'_, W> { ImageDimension as IDim, }; - const ARGUMENT_VARIABLE_NAME: &str = "tex"; - const RETURN_VARIABLE_NAME: &str = "ret"; - const MIP_LEVEL_PARAM: &str = "mip_level"; - - // Write function return type and name - let ret_ty = func_ctx.resolve_type(expr_handle, &module.types); - self.write_value_type(module, ret_ty)?; - write!(self.out, " ")?; - self.write_wrapped_image_query_function_name(wiq)?; + match wiq.class { + crate::ImageClass::External => { + if wiq.query != ImageQuery::Size { + return Err(super::Error::Custom( + "External images only support `Size` queries".into(), + )); + } - // Write function parameters - write!(self.out, "(")?; - // Texture always first parameter - self.write_image_type(wiq.dim, wiq.arrayed, wiq.class)?; - write!(self.out, " {ARGUMENT_VARIABLE_NAME}")?; - // Mipmap is a second parameter if exists - if let ImageQuery::SizeLevel = wiq.query { - write!(self.out, ", uint {MIP_LEVEL_PARAM}")?; - } - writeln!(self.out, ")")?; + write!(self.out, "uint2 ")?; + self.write_wrapped_image_query_function_name(wiq)?; + let params_name = &self.names + [&NameKey::Type(module.special_types.external_texture_params.unwrap())]; + // Only plane0 and params are used by this implementation, but it's easier to + // always take all of them as arguments so that we can unconditionally expand an + // external texture expression each of its parts. + writeln!(self.out, "(Texture2D plane0, Texture2D plane1, Texture2D plane2, {params_name} params) {{")?; + let l1 = crate::back::Level(1); + let l2 = l1.next(); + writeln!(self.out, "{l1}if (any(params.size)) {{")?; + writeln!(self.out, "{l2}return params.size;")?; + writeln!(self.out, "{l1}}} else {{")?; + // params.size == (0, 0) indicates to query and return plane 0's actual size + writeln!(self.out, "{l2}uint2 ret;")?; + writeln!(self.out, "{l2}plane0.GetDimensions(ret.x, ret.y);")?; + writeln!(self.out, "{l2}return ret;")?; + writeln!(self.out, "{l1}}}")?; + writeln!(self.out, "}}")?; + writeln!(self.out)?; + } + _ => { + const ARGUMENT_VARIABLE_NAME: &str = "tex"; + const RETURN_VARIABLE_NAME: &str = "ret"; + const MIP_LEVEL_PARAM: &str = "mip_level"; + + // Write function return type and name + let ret_ty = func_ctx.resolve_type(expr_handle, &module.types); + self.write_value_type(module, ret_ty)?; + write!(self.out, " ")?; + self.write_wrapped_image_query_function_name(wiq)?; + + // Write function parameters + write!(self.out, "(")?; + // Texture always first parameter + self.write_image_type(wiq.dim, wiq.arrayed, wiq.class)?; + write!(self.out, " {ARGUMENT_VARIABLE_NAME}")?; + // Mipmap is a second parameter if exists + if let ImageQuery::SizeLevel = wiq.query { + write!(self.out, ", uint {MIP_LEVEL_PARAM}")?; + } + writeln!(self.out, ")")?; - // Write function body - writeln!(self.out, "{{")?; + // Write function body + writeln!(self.out, "{{")?; - let array_coords = usize::from(wiq.arrayed); - // extra parameter is the mip level count or the sample count - let extra_coords = match wiq.class { - crate::ImageClass::Storage { .. } => 0, - crate::ImageClass::Sampled { .. } | crate::ImageClass::Depth { .. } => 1, - crate::ImageClass::External => unimplemented!(), - }; + let array_coords = usize::from(wiq.arrayed); + // extra parameter is the mip level count or the sample count + let extra_coords = match wiq.class { + crate::ImageClass::Storage { .. } => 0, + crate::ImageClass::Sampled { .. } | crate::ImageClass::Depth { .. } => 1, + crate::ImageClass::External => unreachable!(), + }; - // GetDimensions Overloaded Methods - // https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-getdimensions#overloaded-methods - let (ret_swizzle, number_of_params) = match wiq.query { - ImageQuery::Size | ImageQuery::SizeLevel => { - let ret = match wiq.dim { - IDim::D1 => "x", - IDim::D2 => "xy", - IDim::D3 => "xyz", - IDim::Cube => "xy", + // GetDimensions Overloaded Methods + // https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-getdimensions#overloaded-methods + let (ret_swizzle, number_of_params) = match wiq.query { + ImageQuery::Size | ImageQuery::SizeLevel => { + let ret = match wiq.dim { + IDim::D1 => "x", + IDim::D2 => "xy", + IDim::D3 => "xyz", + IDim::Cube => "xy", + }; + (ret, ret.len() + array_coords + extra_coords) + } + ImageQuery::NumLevels | ImageQuery::NumSamples | ImageQuery::NumLayers => { + if wiq.arrayed || wiq.dim == IDim::D3 { + ("w", 4) + } else { + ("z", 3) + } + } }; - (ret, ret.len() + array_coords + extra_coords) - } - ImageQuery::NumLevels | ImageQuery::NumSamples | ImageQuery::NumLayers => { - if wiq.arrayed || wiq.dim == IDim::D3 { - ("w", 4) - } else { - ("z", 3) - } - } - }; - // Write `GetDimensions` function. - writeln!(self.out, "{INDENT}uint4 {RETURN_VARIABLE_NAME};")?; - write!(self.out, "{INDENT}{ARGUMENT_VARIABLE_NAME}.GetDimensions(")?; - match wiq.query { - ImageQuery::SizeLevel => { - write!(self.out, "{MIP_LEVEL_PARAM}, ")?; - } - _ => match wiq.class { - crate::ImageClass::Sampled { multi: true, .. } - | crate::ImageClass::Depth { multi: true } - | crate::ImageClass::Storage { .. } => {} - _ => { - // Write zero mipmap level for supported types - write!(self.out, "0, ")?; + // Write `GetDimensions` function. + writeln!(self.out, "{INDENT}uint4 {RETURN_VARIABLE_NAME};")?; + write!(self.out, "{INDENT}{ARGUMENT_VARIABLE_NAME}.GetDimensions(")?; + match wiq.query { + ImageQuery::SizeLevel => { + write!(self.out, "{MIP_LEVEL_PARAM}, ")?; + } + _ => match wiq.class { + crate::ImageClass::Sampled { multi: true, .. } + | crate::ImageClass::Depth { multi: true } + | crate::ImageClass::Storage { .. } => {} + _ => { + // Write zero mipmap level for supported types + write!(self.out, "0, ")?; + } + }, } - }, - } - for component in COMPONENTS[..number_of_params - 1].iter() { - write!(self.out, "{RETURN_VARIABLE_NAME}.{component}, ")?; - } + for component in COMPONENTS[..number_of_params - 1].iter() { + write!(self.out, "{RETURN_VARIABLE_NAME}.{component}, ")?; + } - // write last parameter without comma and space for last parameter - write!( - self.out, - "{}.{}", - RETURN_VARIABLE_NAME, - COMPONENTS[number_of_params - 1] - )?; + // write last parameter without comma and space for last parameter + write!( + self.out, + "{}.{}", + RETURN_VARIABLE_NAME, + COMPONENTS[number_of_params - 1] + )?; - writeln!(self.out, ");")?; + writeln!(self.out, ");")?; - // Write return value - writeln!( - self.out, - "{INDENT}return {RETURN_VARIABLE_NAME}.{ret_swizzle};" - )?; - - // End of function body - writeln!(self.out, "}}")?; - // Write extra new line - writeln!(self.out)?; + // Write return value + writeln!( + self.out, + "{INDENT}return {RETURN_VARIABLE_NAME}.{ret_swizzle};" + )?; + // End of function body + writeln!(self.out, "}}")?; + // Write extra new line + writeln!(self.out)?; + } + } Ok(()) } @@ -1557,10 +1822,31 @@ impl super::Writer<'_, W> { self.write_wrapped_array_length_function(wal)?; } } - crate::Expression::ImageSample { clamp_to_edge, .. } => { - let wrapped = WrappedImageSample { clamp_to_edge }; + crate::Expression::ImageLoad { image, .. } => { + let class = match *func_ctx.resolve_type(image, &module.types) { + crate::TypeInner::Image { class, .. } => class, + _ => unreachable!(), + }; + let wrapped = WrappedImageLoad { class }; + if self.wrapped.insert(WrappedType::ImageLoad(wrapped)) { + self.write_wrapped_image_load_function(module, wrapped)?; + } + } + crate::Expression::ImageSample { + image, + clamp_to_edge, + .. + } => { + let class = match *func_ctx.resolve_type(image, &module.types) { + crate::TypeInner::Image { class, .. } => class, + _ => unreachable!(), + }; + let wrapped = WrappedImageSample { + class, + clamp_to_edge, + }; if self.wrapped.insert(WrappedType::ImageSample(wrapped)) { - self.write_wrapped_image_sample_function(wrapped)?; + self.write_wrapped_image_sample_function(module, wrapped)?; } } crate::Expression::ImageQuery { image, query } => { diff --git a/naga/src/back/hlsl/keywords.rs b/naga/src/back/hlsl/keywords.rs index f38d47483f7..7b2ab839d4c 100644 --- a/naga/src/back/hlsl/keywords.rs +++ b/naga/src/back/hlsl/keywords.rs @@ -826,6 +826,7 @@ pub const RESERVED: &[&str] = &[ super::writer::INSERT_BITS_FUNCTION, super::writer::SAMPLER_HEAP_VAR, super::writer::COMPARISON_SAMPLER_HEAP_VAR, + super::writer::SAMPLE_EXTERNAL_TEXTURE_FUNCTION, super::writer::ABS_FUNCTION, super::writer::DIV_FUNCTION, super::writer::MOD_FUNCTION, @@ -834,6 +835,7 @@ pub const RESERVED: &[&str] = &[ super::writer::F2U32_FUNCTION, super::writer::F2I64_FUNCTION, super::writer::F2U64_FUNCTION, + super::writer::IMAGE_LOAD_EXTERNAL_FUNCTION, super::writer::IMAGE_SAMPLE_BASE_CLAMP_TO_EDGE_FUNCTION, ]; diff --git a/naga/src/back/hlsl/mod.rs b/naga/src/back/hlsl/mod.rs index 7f553980402..8df06cf1323 100644 --- a/naga/src/back/hlsl/mod.rs +++ b/naga/src/back/hlsl/mod.rs @@ -106,6 +106,37 @@ index buffer for each bind group. This buffer is accessed in the shader to get t sampler index within the heap. See the wgpu_hal dx12 backend documentation for more information. +# External textures + +Support for [`crate::ImageClass::External`] textures is implemented by lowering +each external texture global variable to 3 `Texture2D`s, and a `cbuffer` +of type `NagaExternalTextureParams`. This provides up to 3 planes of texture +data (for example single planar RGBA, or separate Y, Cb, and Cr planes), and the +parameters buffer containing information describing how to handle these +correctly. The bind target to use for each of these globals is specified via +[`Options::external_texture_binding_map`]. + +External textures are supported by WGSL's `textureDimensions()`, +`textureLoad()`, and `textureSampleBaseClampToEdge()` built-in functions. These +are implemented using helper functions. See the following functions for how +these are generated: + * `Writer::write_wrapped_image_query_function` + * `Writer::write_wrapped_image_load_function` + * `Writer::write_wrapped_image_sample_function` + +Ideally the set of global variables could be wrapped in a single struct that +could conveniently be passed around. But, alas, HLSL does not allow structs to +have `Texture2D` members. Fortunately, however, external textures can only be +used as arguments to either built-in or user-defined functions. We therefore +expand any external texture function argument to four consecutive arguments (3 +textures and the params struct) when declaring user-defined functions, and +ensure our built-in function implementations take the same arguments. Then, +whenever we need to emit an external texture in `Writer::write_expr`, which +fortunately can only ever be for a global variable or function argument, we +simply emit the variable name of each of the three textures and the parameters +struct in a comma-separated list. This won't win any awards for elegance, but +it works for our purposes. + [hlsl]: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl [ilov]: https://gpuweb.github.io/gpuweb/wgsl/#internal-value-layout [16bb]: https://github.com/microsoft/DirectXShaderCompiler/wiki/Buffer-Packing#constant-buffer-packing @@ -126,6 +157,35 @@ use thiserror::Error; use crate::{back, ir, proc}; +/// Direct3D 12 binding information for a global variable. +/// +/// This type provides the HLSL-specific information Naga needs to declare and +/// access an HLSL global variable that cannot be derived from the `Module` +/// itself. +/// +/// An HLSL global variable declaration includes details that the Direct3D API +/// will use to refer to it. For example: +/// +/// RWByteAddressBuffer s_sasm : register(u0, space2); +/// +/// This defines a global `s_sasm` that a Direct3D root signature would refer to +/// as register `0` in register space `2` in a `UAV` descriptor range. Naga can +/// infer the register's descriptor range type from the variable's address class +/// (writable [`Storage`] variables are implemented by Direct3D Unordered Access +/// Views, the `u` register type), but the register number and register space +/// must be supplied by the user. +/// +/// The [`back::hlsl::Options`] structure provides `BindTarget`s for various +/// situations in which Naga may need to generate an HLSL global variable, like +/// [`binding_map`] for Naga global variables, or [`push_constants_target`] for +/// a module's sole [`PushConstant`] variable. See those fields' documentation +/// for details. +/// +/// [`Storage`]: crate::ir::AddressSpace::Storage +/// [`back::hlsl::Options`]: Options +/// [`binding_map`]: Options::binding_map +/// [`push_constants_target`]: Options::push_constants_target +/// [`PushConstant`]: crate::ir::AddressSpace::PushConstant #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serialize", derive(serde::Serialize))] #[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] @@ -335,6 +395,62 @@ where pub type DynamicStorageBufferOffsetsTargets = alloc::collections::BTreeMap; +/// HLSL binding information for a Naga [`External`] image global variable. +/// +/// See the module documentation's section on [External textures][mod] for details. +/// +/// [`External`]: crate::ir::ImageClass::External +/// [mod]: #external-textures +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serialize", derive(serde::Serialize))] +#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] +pub struct ExternalTextureBindTarget { + /// HLSL binding information for the individual plane textures. + /// + /// Each of these should refer to an HLSL `Texture2D` holding one + /// plane of data for the external texture. The exact meaning of each plane + /// varies at runtime depending on where the external texture's data + /// originated. + pub planes: [BindTarget; 3], + + /// HLSL binding information for a buffer holding the sampling parameters. + /// + /// This should refer to a cbuffer of type `NagaExternalTextureParams`, that + /// the code Naga generates for `textureSampleBaseClampToEdge` consults to + /// decide how to combine the data in [`planes`] to get the result required + /// by the spec. + /// + /// [`planes`]: Self::planes + pub params: BindTarget, +} + +#[cfg(any(feature = "serialize", feature = "deserialize"))] +#[cfg_attr(feature = "serialize", derive(serde::Serialize))] +#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] +struct ExternalTextureBindingMapSerialization { + resource_binding: crate::ResourceBinding, + bind_target: ExternalTextureBindTarget, +} + +#[cfg(feature = "deserialize")] +fn deserialize_external_texture_binding_map<'de, D>( + deserializer: D, +) -> Result +where + D: serde::Deserializer<'de>, +{ + use serde::Deserialize; + + let vec = Vec::::deserialize(deserializer)?; + let mut map = ExternalTextureBindingMap::default(); + for item in vec { + map.insert(item.resource_binding, item.bind_target); + } + Ok(map) +} +pub type ExternalTextureBindingMap = + alloc::collections::BTreeMap; + /// Shorthand result used internally by the backend type BackendResult = Result<(), Error>; @@ -354,21 +470,47 @@ pub enum EntryPointError { pub struct Options { /// The hlsl shader model to be used pub shader_model: ShaderModel, - /// Map of resources association to binding locations. + + /// HLSL binding information for each Naga global variable. + /// + /// This maps Naga [`GlobalVariable`]'s [`ResourceBinding`]s to a + /// [`BindTarget`] specifying its register number and space, along with + /// other details necessary to generate a full HLSL declaration for it, + /// or to access its value. + /// + /// This must provide a [`BindTarget`] for every [`GlobalVariable`] in the + /// [`Module`] that has a [`binding`]. + /// + /// [`GlobalVariable`]: crate::ir::GlobalVariable + /// [`ResourceBinding`]: crate::ir::ResourceBinding + /// [`Module`]: crate::ir::Module + /// [`binding`]: crate::ir::GlobalVariable::binding #[cfg_attr( feature = "deserialize", serde(deserialize_with = "deserialize_binding_map") )] pub binding_map: BindingMap, + /// Don't panic on missing bindings, instead generate any HLSL. pub fake_missing_bindings: bool, /// Add special constants to `SV_VertexIndex` and `SV_InstanceIndex`, /// to make them work like in Vulkan/Metal, with help of the host. pub special_constants_binding: Option, - /// Bind target of the push constant buffer + + /// HLSL binding information for the [`PushConstant`] global, if present. + /// + /// If a module contains a global in the [`PushConstant`] address space, the + /// `dx12` backend stores its value directly in the root signature as a + /// series of [`D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS`], whose binding + /// information is given here. + /// + /// [`PushConstant`]: crate::ir::AddressSpace::PushConstant + /// [`D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS`]: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_root_parameter_type pub push_constants_target: Option, - /// Bind target of the sampler heap and comparison sampler heap. + + /// HLSL binding information for the sampler heap and comparison sampler heap. pub sampler_heap_target: SamplerHeapBindTargets, + /// Mapping of each bind group's sampler index buffer to a bind target. #[cfg_attr( feature = "deserialize", @@ -381,6 +523,18 @@ pub struct Options { serde(deserialize_with = "deserialize_storage_buffer_offsets") )] pub dynamic_storage_buffer_offsets_targets: DynamicStorageBufferOffsetsTargets, + #[cfg_attr( + feature = "deserialize", + serde(deserialize_with = "deserialize_external_texture_binding_map") + )] + + /// HLSL binding information for [`External`] image global variables. + /// + /// See [`ExternalTextureBindTarget`] for details. + /// + /// [`External`]: crate::ir::ImageClass::External + pub external_texture_binding_map: ExternalTextureBindingMap, + /// Should workgroup variables be zero initialized (by polyfilling)? pub zero_initialize_workgroup_memory: bool, /// Should we restrict indexing of vectors, matrices and arrays? @@ -401,6 +555,7 @@ impl Default for Options { sampler_buffer_binding_map: alloc::collections::BTreeMap::default(), push_constants_target: None, dynamic_storage_buffer_offsets_targets: alloc::collections::BTreeMap::new(), + external_texture_binding_map: ExternalTextureBindingMap::default(), zero_initialize_workgroup_memory: true, restrict_indexing: true, force_loop_bounding: true, @@ -425,6 +580,29 @@ impl Options { None => Err(EntryPointError::MissingBinding(*res_binding)), } } + + fn resolve_external_texture_resource_binding( + &self, + res_binding: &crate::ResourceBinding, + ) -> Result { + match self.external_texture_binding_map.get(res_binding) { + Some(target) => Ok(*target), + None if self.fake_missing_bindings => { + let fake = BindTarget { + space: res_binding.group as u8, + register: res_binding.binding, + binding_array_size: None, + dynamic_storage_buffer_offsets_index: None, + restrict_indexing: false, + }; + Ok(ExternalTextureBindTarget { + planes: [fake, fake, fake], + params: fake, + }) + } + None => Err(EntryPointError::MissingBinding(*res_binding)), + } + } } /// Reflection info for entry point names. @@ -479,6 +657,7 @@ enum WrappedType { ArrayLength(help::WrappedArrayLength), ImageSample(help::WrappedImageSample), ImageQuery(help::WrappedImageQuery), + ImageLoad(help::WrappedImageLoad), ImageLoadScalar(crate::Scalar), Constructor(help::WrappedConstructor), StructMatrixAccess(help::WrappedStructMatrixAccess), diff --git a/naga/src/back/hlsl/writer.rs b/naga/src/back/hlsl/writer.rs index 0639623fd8b..357b8597521 100644 --- a/naga/src/back/hlsl/writer.rs +++ b/naga/src/back/hlsl/writer.rs @@ -17,7 +17,7 @@ use super::{ use crate::{ back::{self, get_entry_points, Baked}, common, - proc::{self, index, NameKey}, + proc::{self, index, ExternalTextureNameKey, NameKey}, valid, Handle, Module, RayQueryFunction, Scalar, ScalarKind, ShaderStage, TypeInner, }; @@ -34,6 +34,7 @@ pub(crate) const EXTRACT_BITS_FUNCTION: &str = "naga_extractBits"; pub(crate) const INSERT_BITS_FUNCTION: &str = "naga_insertBits"; pub(crate) const SAMPLER_HEAP_VAR: &str = "nagaSamplerHeap"; pub(crate) const COMPARISON_SAMPLER_HEAP_VAR: &str = "nagaComparisonSamplerHeap"; +pub(crate) const SAMPLE_EXTERNAL_TEXTURE_FUNCTION: &str = "nagaSampleExternalTexture"; pub(crate) const ABS_FUNCTION: &str = "naga_abs"; pub(crate) const DIV_FUNCTION: &str = "naga_div"; pub(crate) const MOD_FUNCTION: &str = "naga_mod"; @@ -44,6 +45,7 @@ pub(crate) const F2I64_FUNCTION: &str = "naga_f2i64"; pub(crate) const F2U64_FUNCTION: &str = "naga_f2u64"; pub(crate) const IMAGE_SAMPLE_BASE_CLAMP_TO_EDGE_FUNCTION: &str = "nagaTextureSampleBaseClampToEdge"; +pub(crate) const IMAGE_LOAD_EXTERNAL_FUNCTION: &str = "nagaTextureLoadExternal"; enum Index { Expression(Handle), @@ -431,6 +433,10 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { .find(|&(var_handle, var)| match var.binding { Some(ref binding) if !info[var_handle].is_empty() => { self.options.resolve_resource_binding(binding).is_err() + && self + .options + .resolve_external_texture_resource_binding(binding) + .is_err() } _ => false, }) @@ -473,8 +479,14 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { match var.binding { Some(ref binding) if !info[var_handle].is_empty() => { if let Err(err) = self.options.resolve_resource_binding(binding) { - ep_error = Some(err); - break; + if self + .options + .resolve_external_texture_resource_binding(binding) + .is_err() + { + ep_error = Some(err); + break; + } } } _ => {} @@ -904,6 +916,25 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { let global = &module.global_variables[handle]; let inner = &module.types[global.ty].inner; + let handle_ty = match *inner { + TypeInner::BindingArray { ref base, .. } => &module.types[*base].inner, + _ => inner, + }; + + // External textures are handled entirely differently, so defer entirely to that method. + // We do so prior to calling resolve_resource_binding() below, as we even need to resolve + // their bindings separately. + let is_external_texture = matches!( + *handle_ty, + TypeInner::Image { + class: crate::ImageClass::External, + .. + } + ); + if is_external_texture { + return self.write_global_external_texture(module, handle, global); + } + if let Some(ref binding) = global.binding { if let Err(err) = self.options.resolve_resource_binding(binding) { log::info!( @@ -916,11 +947,6 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { } } - let handle_ty = match *inner { - TypeInner::BindingArray { ref base, .. } => &module.types[*base].inner, - _ => inner, - }; - // Samplers are handled entirely differently, so defer entirely to that method. let is_sampler = matches!(*handle_ty, TypeInner::Sampler { .. }); @@ -1133,6 +1159,70 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { Ok(()) } + /// Write the declarations for an external texture global variable. + /// These are emitted as multiple global variables: Three `Texture2D`s + /// (one for each plane) and a parameters cbuffer. + fn write_global_external_texture( + &mut self, + module: &Module, + handle: Handle, + global: &crate::GlobalVariable, + ) -> BackendResult { + let res_binding = global + .binding + .as_ref() + .expect("External texture global variables must have a resource binding"); + let ext_tex_bindings = match self + .options + .resolve_external_texture_resource_binding(res_binding) + { + Ok(bindings) => bindings, + Err(err) => { + log::info!( + "Skipping global {:?} (name {:?}) for being inaccessible: {}", + handle, + global.name, + err, + ); + return Ok(()); + } + }; + + let mut write_plane = |bt: &super::BindTarget, name| -> BackendResult { + write!( + self.out, + "Texture2D {}: register(t{}", + name, bt.register + )?; + if bt.space != 0 { + write!(self.out, ", space{}", bt.space)?; + } + writeln!(self.out, ");")?; + Ok(()) + }; + for (i, bt) in ext_tex_bindings.planes.iter().enumerate() { + let plane_name = &self.names + [&NameKey::ExternalTextureGlobalVariable(handle, ExternalTextureNameKey::Plane(i))]; + write_plane(bt, plane_name)?; + } + + let params_name = &self.names + [&NameKey::ExternalTextureGlobalVariable(handle, ExternalTextureNameKey::Params)]; + let params_ty_name = + &self.names[&NameKey::Type(module.special_types.external_texture_params.unwrap())]; + write!( + self.out, + "cbuffer {}: register(b{}", + params_name, ext_tex_bindings.params.register + )?; + if ext_tex_bindings.params.space != 0 { + write!(self.out, ", space{}", ext_tex_bindings.params.space)?; + } + writeln!(self.out, ") {{ {params_ty_name} {params_name}; }};")?; + + Ok(()) + } + /// Helper method used to write global constants /// /// # Notes @@ -1485,26 +1575,8 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { if index != 0 { write!(self.out, ", ")?; } - // Write argument type - let arg_ty = match module.types[arg.ty].inner { - // pointers in function arguments are expected and resolve to `inout` - TypeInner::Pointer { base, .. } => { - //TODO: can we narrow this down to just `in` when possible? - write!(self.out, "inout ")?; - base - } - _ => arg.ty, - }; - self.write_type(module, arg_ty)?; - - let argument_name = - &self.names[&NameKey::FunctionArgument(handle, index as u32)]; - // Write argument name. Space is important. - write!(self.out, " {argument_name}")?; - if let TypeInner::Array { base, size, .. } = module.types[arg_ty].inner { - self.write_array_size(module, base, size)?; - } + self.write_function_argument(module, handle, arg, index)?; } } back::FunctionType::EntryPoint(ep_index) => { @@ -1618,6 +1690,74 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { Ok(()) } + fn write_function_argument( + &mut self, + module: &Module, + handle: Handle, + arg: &crate::FunctionArgument, + index: usize, + ) -> BackendResult { + // External texture arguments must be expanded into separate + // arguments for each plane and the params buffer. + if let TypeInner::Image { + class: crate::ImageClass::External, + .. + } = module.types[arg.ty].inner + { + return self.write_function_external_texture_argument(module, handle, index); + } + + // Write argument type + let arg_ty = match module.types[arg.ty].inner { + // pointers in function arguments are expected and resolve to `inout` + TypeInner::Pointer { base, .. } => { + //TODO: can we narrow this down to just `in` when possible? + write!(self.out, "inout ")?; + base + } + _ => arg.ty, + }; + self.write_type(module, arg_ty)?; + + let argument_name = &self.names[&NameKey::FunctionArgument(handle, index as u32)]; + + // Write argument name. Space is important. + write!(self.out, " {argument_name}")?; + if let TypeInner::Array { base, size, .. } = module.types[arg_ty].inner { + self.write_array_size(module, base, size)?; + } + + Ok(()) + } + + fn write_function_external_texture_argument( + &mut self, + module: &Module, + handle: Handle, + index: usize, + ) -> BackendResult { + let plane_names = [0, 1, 2].map(|i| { + &self.names[&NameKey::ExternalTextureFunctionArgument( + handle, + index as u32, + ExternalTextureNameKey::Plane(i), + )] + }); + let params_name = &self.names[&NameKey::ExternalTextureFunctionArgument( + handle, + index as u32, + ExternalTextureNameKey::Params, + )]; + let params_ty_name = + &self.names[&NameKey::Type(module.special_types.external_texture_params.unwrap())]; + write!( + self.out, + "Texture2D {}, Texture2D {}, Texture2D {}, {params_ty_name} {params_name}", + plane_names[0], plane_names[1], plane_names[2], + )?; + Ok(()) + } + fn need_workgroup_variables_initialization( &mut self, func_ctx: &back::FunctionCtx, @@ -3117,9 +3257,34 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { } } Expression::FunctionArgument(pos) => { - let key = func_ctx.argument_key(pos); - let name = &self.names[&key]; - write!(self.out, "{name}")?; + let ty = func_ctx.resolve_type(expr, &module.types); + + // We know that any external texture function argument has been expanded into + // separate consecutive arguments for each plane and the parameters buffer. And we + // also know that external textures can only ever be used as an argument to another + // function. Therefore we can simply emit each of the expanded arguments in a + // consecutive comma-separated list. + if let TypeInner::Image { + class: crate::ImageClass::External, + .. + } = *ty + { + let plane_names = [0, 1, 2].map(|i| { + &self.names[&func_ctx + .external_texture_argument_key(pos, ExternalTextureNameKey::Plane(i))] + }); + let params_name = &self.names[&func_ctx + .external_texture_argument_key(pos, ExternalTextureNameKey::Params)]; + write!( + self.out, + "{}, {}, {}, {}", + plane_names[0], plane_names[1], plane_names[2], params_name + )?; + } else { + let key = func_ctx.argument_key(pos); + let name = &self.names[&key]; + write!(self.out, "{name}")?; + } } Expression::ImageSample { coordinate, @@ -3282,7 +3447,34 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { let is_storage_space = matches!(global_variable.space, crate::AddressSpace::Storage { .. }); - if !is_binding_array_of_samplers && !is_storage_space { + // Our external texture global variable has been expanded into multiple + // global variables, one for each plane and the parameters buffer. + // External textures can only ever be used as arguments to a function + // call, and we know that an external texture argument to any function + // will have been expanded to separate consecutive arguments for each + // plane and the parameters buffer. Therefore we can simply emit each of + // the expanded global variables in a consecutive comma-separated list. + if let TypeInner::Image { + class: crate::ImageClass::External, + .. + } = *ty + { + let plane_names = [0, 1, 2].map(|i| { + &self.names[&NameKey::ExternalTextureGlobalVariable( + handle, + ExternalTextureNameKey::Plane(i), + )] + }); + let params_name = &self.names[&NameKey::ExternalTextureGlobalVariable( + handle, + ExternalTextureNameKey::Params, + )]; + write!( + self.out, + "{}, {}, {}, {}", + plane_names[0], plane_names[1], plane_names[2], params_name + )?; + } else if !is_binding_array_of_samplers && !is_storage_space { let name = &self.names[&NameKey::GlobalVariable(handle)]; write!(self.out, "{name}")?; } @@ -4113,6 +4305,17 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { ) -> Result<(), Error> { let mut wrapping_type = None; match *func_ctx.resolve_type(image, &module.types) { + TypeInner::Image { + class: crate::ImageClass::External, + .. + } => { + write!(self.out, "{IMAGE_LOAD_EXTERNAL_FUNCTION}(")?; + self.write_expr(module, image, func_ctx)?; + write!(self.out, ", ")?; + self.write_expr(module, coordinate, func_ctx)?; + write!(self.out, ")")?; + return Ok(()); + } TypeInner::Image { class: crate::ImageClass::Storage { format, .. }, .. diff --git a/naga/src/ir/mod.rs b/naga/src/ir/mod.rs index 1744ff92fcd..50cc89a5b4c 100644 --- a/naga/src/ir/mod.rs +++ b/naga/src/ir/mod.rs @@ -347,7 +347,21 @@ pub enum AddressSpace { Storage { access: StorageAccess }, /// Opaque handles, such as samplers and images. Handle, + /// Push constants. + /// + /// A [`Module`] may contain at most one [`GlobalVariable`] in + /// this address space. Its contents are provided not by a buffer + /// but by `SetPushConstant` pass commands, allowing the CPU to + /// establish different values for each draw/dispatch. + /// + /// `PushConstant` variables may not contain `f16` values, even if + /// the [`SHADER_FLOAT16`] capability is enabled. + /// + /// Backends generally place tight limits on the size of + /// `PushConstant` variables. + /// + /// [`SHADER_FLOAT16`]: crate::valid::Capabilities::SHADER_FLOAT16 PushConstant, } diff --git a/naga/src/valid/type.rs b/naga/src/valid/type.rs index 095fd7f882b..8aa3c04f207 100644 --- a/naga/src/valid/type.rs +++ b/naga/src/valid/type.rs @@ -261,6 +261,15 @@ impl super::Validator { } } + /// Check whether `scalar` is a permitted scalar width. + /// + /// If `scalar` is not a width allowed by the selected [`Capabilities`], + /// return an error explaining why. + /// + /// If `scalar` is allowed, return a [`PushConstantCompatibility`] result + /// that says whether `scalar` is allowed specifically in push constants. + /// + /// [`Capabilities`]: crate::valid::Capabilities pub(super) const fn check_width( &self, scalar: crate::Scalar, diff --git a/naga/tests/in/wgsl/texture-external.toml b/naga/tests/in/wgsl/texture-external.toml index f8f46d4223e..3ea75be88d2 100644 --- a/naga/tests/in/wgsl/texture-external.toml +++ b/naga/tests/in/wgsl/texture-external.toml @@ -1,2 +1,15 @@ god_mode = true -targets = "IR | WGSL" +targets = "HLSL | IR | WGSL" + +[[hlsl.binding_map]] +resource_binding = { group = 0, binding = 1 } +bind_target = { register = 0, space = 0 } + +[[hlsl.external_texture_binding_map]] +resource_binding = { group = 0, binding = 0 } +bind_target.planes = [ + { space = 0, register = 0 }, + { space = 0, register = 1 }, + { space = 0, register = 2 }, +] +bind_target.params = { space = 0, register = 3 } diff --git a/naga/tests/out/hlsl/wgsl-texture-external.hlsl b/naga/tests/out/hlsl/wgsl-texture-external.hlsl new file mode 100644 index 00000000000..517d6a724a8 --- /dev/null +++ b/naga/tests/out/hlsl/wgsl-texture-external.hlsl @@ -0,0 +1,143 @@ +struct NagaExternalTextureParams { + row_major float4x4 yuv_conversion_matrix; + float2 sample_transform_0; float2 sample_transform_1; float2 sample_transform_2; + float2 load_transform_0; float2 load_transform_1; float2 load_transform_2; + uint2 size; + uint num_planes; + int _end_pad_0; +}; + +Texture2D tex_plane0_: register(t0); +Texture2D tex_plane1_: register(t1); +Texture2D tex_plane2_: register(t2); +cbuffer tex_params: register(b3) { NagaExternalTextureParams tex_params; }; +SamplerState nagaSamplerHeap[2048]: register(s0, space0); +SamplerComparisonState nagaComparisonSamplerHeap[2048]: register(s0, space1); +StructuredBuffer nagaGroup0SamplerIndexArray : register(t0, space255); +static const SamplerState samp = nagaSamplerHeap[nagaGroup0SamplerIndexArray[0]]; + +float4 nagaTextureSampleBaseClampToEdge( + Texture2D plane0, + Texture2D plane1, + Texture2D plane2, + NagaExternalTextureParams params, + SamplerState samp, + float2 coords) +{ + float2 plane0_size; + plane0.GetDimensions(plane0_size.x, plane0_size.y); + float3x2 sample_transform = float3x2( + params.sample_transform_0, + params.sample_transform_1, + params.sample_transform_2 + ); + coords = mul(float3(coords, 1.0), sample_transform); + float2 bounds_min = mul(float3(0.0, 0.0, 1.0), sample_transform); + float2 bounds_max = mul(float3(1.0, 1.0, 1.0), sample_transform); + float4 bounds = float4(min(bounds_min, bounds_max), max(bounds_min, bounds_max)); + float2 plane0_half_texel = float2(0.5, 0.5) / plane0_size; + float2 plane0_coords = clamp(coords, bounds.xy + plane0_half_texel, bounds.zw - plane0_half_texel); + if (params.num_planes == 1u) { + return plane0.SampleLevel(samp, plane0_coords, 0.0f); + } else { + float2 plane1_size; + plane1.GetDimensions(plane1_size.x, plane1_size.y); + float2 plane1_half_texel = float2(0.5, 0.5) / plane1_size; + float2 plane1_coords = clamp(coords, bounds.xy + plane1_half_texel, bounds.zw - plane1_half_texel); + float y = plane0.SampleLevel(samp, plane0_coords, 0.0f).x; + float2 uv; + if (params.num_planes == 2u) { + uv = plane1.SampleLevel(samp, plane1_coords, 0.0f).xy; + } else { + float2 plane2_size; + plane2.GetDimensions(plane2_size.x, plane2_size.y); + float2 plane2_half_texel = float2(0.5, 0.5) / plane2_size; + float2 plane2_coords = clamp(coords, bounds.xy + plane2_half_texel, bounds.zw - plane2_half_texel); + uv = float2(plane1.SampleLevel(samp, plane1_coords, 0.0f).x, plane2.SampleLevel(samp, plane2_coords, 0.0f).x); + } + return mul(float4(y, uv, 1.0), params.yuv_conversion_matrix); + } +} + +float4 nagaTextureLoadExternal( + Texture2D plane0, + Texture2D plane1, + Texture2D plane2, + NagaExternalTextureParams params, + uint2 coords) +{ + uint2 plane0_size; + plane0.GetDimensions(plane0_size.x, plane0_size.y); + uint2 cropped_size = any(params.size) ? params.size : plane0_size; + coords = min(coords, cropped_size - 1); + float3x2 load_transform = float3x2( + params.load_transform_0, + params.load_transform_1, + params.load_transform_2 + ); + uint2 plane0_coords = uint2(round(mul(float3(coords, 1.0), load_transform))); + if (params.num_planes == 1u) { + return plane0.Load(uint3(plane0_coords, 0u)); + } else { + uint2 plane1_size; + plane1.GetDimensions(plane1_size.x, plane1_size.y); + uint2 plane1_coords = uint2(floor(float2(plane0_coords) * float2(plane1_size) / float2(plane0_size))); + float y = plane0.Load(uint3(plane0_coords, 0u)).x; + float2 uv; + if (params.num_planes == 2u) { + uv = plane1.Load(uint3(plane1_coords, 0u)).xy; + } else { + uint2 plane2_size; + plane2.GetDimensions(plane2_size.x, plane2_size.y); + uint2 plane2_coords = uint2(floor(float2(plane0_coords) * float2(plane2_size) / float2(plane0_size))); + uv = float2(plane1.Load(uint3(plane1_coords, 0u)).x, plane2.Load(uint3(plane2_coords, 0u)).x); + } + return mul(float4(y, uv, 1.0), params.yuv_conversion_matrix); + } +} + +uint2 NagaExternalDimensions2D(Texture2D plane0, Texture2D plane1, Texture2D plane2, NagaExternalTextureParams params) { + if (any(params.size)) { + return params.size; + } else { + uint2 ret; + plane0.GetDimensions(ret.x, ret.y); + return ret; + } +} + +float4 test(Texture2D t_plane0_, Texture2D t_plane1_, Texture2D t_plane2_, NagaExternalTextureParams t_params) +{ + float4 a = (float4)0; + float4 b = (float4)0; + uint2 c = (uint2)0; + + float4 _e4 = nagaTextureSampleBaseClampToEdge(t_plane0_, t_plane1_, t_plane2_, t_params, samp, (0.0).xx); + a = _e4; + float4 _e8 = nagaTextureLoadExternal(t_plane0_, t_plane1_, t_plane2_, t_params, (0u).xx); + b = _e8; + c = NagaExternalDimensions2D(t_plane0_, t_plane1_, t_plane2_, t_params); + float4 _e12 = a; + float4 _e13 = b; + uint2 _e15 = c; + return ((_e12 + _e13) + float2(_e15).xyxy); +} + +float4 fragment_main() : SV_Target0 +{ + const float4 _e1 = test(tex_plane0_, tex_plane1_, tex_plane2_, tex_params); + return _e1; +} + +float4 vertex_main() : SV_Position +{ + const float4 _e1 = test(tex_plane0_, tex_plane1_, tex_plane2_, tex_params); + return _e1; +} + +[numthreads(1, 1, 1)] +void compute_main() +{ + const float4 _e1 = test(tex_plane0_, tex_plane1_, tex_plane2_, tex_params); + return; +} diff --git a/naga/tests/out/hlsl/wgsl-texture-external.ron b/naga/tests/out/hlsl/wgsl-texture-external.ron new file mode 100644 index 00000000000..23afa21e1f5 --- /dev/null +++ b/naga/tests/out/hlsl/wgsl-texture-external.ron @@ -0,0 +1,20 @@ +( + vertex:[ + ( + entry_point:"vertex_main", + target_profile:"vs_5_1", + ), + ], + fragment:[ + ( + entry_point:"fragment_main", + target_profile:"ps_5_1", + ), + ], + compute:[ + ( + entry_point:"compute_main", + target_profile:"cs_5_1", + ), + ], +) diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 3f212f80eef..5fe0de4134c 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -83,26 +83,55 @@ pub(crate) struct CommandIndices { pub struct ExternalTextureParams { /// 4x4 column-major matrix with which to convert sampled YCbCr values /// to RGBA. + /// /// This is ignored when `num_planes` is 1. pub yuv_conversion_matrix: [f32; 16], - /// 3x2 column-major matrix with which to multiply normalized texture - /// coordinates prior to sampling from the external texture. This may - /// scale, translate, flip, and rotate in 90-degree increments, but the - /// result of transforming the rectangle (0,0)..(1,1) must be an - /// axis-aligned rectangle that falls within the bounds of (0,0)..(1,1). + + /// Transform to apply to [`ImageSample`] coordinates. + /// + /// This is a 3x2 column-major matrix representing an affine transform from + /// normalized texture coordinates to the normalized coordinates that should + /// be sampled from the external texture's underlying plane(s). + /// + /// This transform may scale, translate, flip, and rotate in 90-degree + /// increments, but the result of transforming the rectangle (0,0)..(1,1) + /// must be an axis-aligned rectangle that falls within the bounds of + /// (0,0)..(1,1). + /// + /// [`ImageSample`]: naga::ir::Expression::ImageSample pub sample_transform: [f32; 6], - /// 3x2 column-major matrix with which to multiply unnormalized texture - /// coordinates prior to loading from the external texture. This may scale, - /// translate, flip, and rotate in 90-degree increments, but the result of - /// transforming the rectangle (0,0)..(texture_size - 1) must be an - /// axis-aligned rectangle that falls within the bounds of - /// (0,0)..(texture_size - 1). + + /// Transform to apply to [`ImageLoad`] coordinates. + /// + /// This is a 3x2 column-major matrix representing an affine transform from + /// non-normalized texel coordinates to the non-normalized coordinates of + /// the texel that should be loaded from the external texture's underlying + /// plane 0. For planes 1 and 2, if present, plane 0's coordinates are + /// scaled according to the textures' relative sizes. + /// + /// This transform may scale, translate, flip, and rotate in 90-degree + /// increments, but the result of transforming the rectangle (0,0)..[`size`] + /// must be an axis-aligned rectangle that falls within the bounds of + /// (0,0)..[`size`]. + /// + /// [`ImageLoad`]: naga::ir::Expression::ImageLoad + /// [`size`]: Self::size pub load_transform: [f32; 6], - /// Size of the external texture. This value should be returned by size - /// queries in shader code. Note that this may not match the dimensions of - /// the underlying texture(s). A value of [0, 0] indicates that the actual - /// size of plane 0 should be used. + + /// Size of the external texture. + /// + /// This is the value that should be returned by size queries in shader + /// code; it does not necessarily match the dimensions of the underlying + /// texture(s). As a special case, if this is `[0, 0]`, the actual size of + /// plane 0 should be used instead. + /// + /// This must be consistent with [`sample_transform`]: it should be the size + /// in texels of the rectangle covered by the square (0,0)..(1,1) after + /// [`sample_transform`] has been applied to it. + /// + /// [`sample_transform`]: Self::sample_transform pub size: [u32; 2], + /// Number of planes. 1 indicates a single RGBA plane. 2 indicates a Y /// plane and an interleaved CbCr plane. 3 indicates separate Y, Cb, and Cr /// planes. diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 5d3a6ac8d45..d8bdd2b1d5f 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -1388,6 +1388,7 @@ impl crate::Device for super::Device { restrict_indexing: true, sampler_heap_target, sampler_buffer_binding_map, + external_texture_binding_map: hlsl::ExternalTextureBindingMap::default(), force_loop_bounding: true, }, }) diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 6252e5c6778..d70fd3803cc 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -6285,6 +6285,20 @@ pub enum ExternalTextureFormat { /// Describes an [`ExternalTexture`](../wgpu/struct.ExternalTexture.html). /// +/// Note that [`width`] and [`height`] are the values that should be returned by +/// size queries in shader code; they do not necessarily match the dimensions of +/// the underlying plane texture(s). As a special case, if `(width, height)` is +/// `(0, 0)`, the actual size of the first underlying plane should be used instead. +/// +/// The size given by [`width`] and [`height`] must be consistent with +/// [`sample_transform`]: they should be the size in texels of the rectangle +/// covered by the square (0,0)..(1,1) after [`sample_transform`] has been applied +/// to it. +/// +/// [`width`]: Self::width +/// [`height`]: Self::height +/// [`sample_transform`]: Self::sample_transform +/// /// Corresponds to [WebGPU `GPUExternalTextureDescriptor`]( /// https://gpuweb.github.io/gpuweb/#dictdef-gpuexternaltexturedescriptor). #[repr(C)] @@ -6294,23 +6308,51 @@ pub struct ExternalTextureDescriptor { /// Debug label of the external texture. This will show up in graphics /// debuggers for easy identification. pub label: L, - /// Width of the external texture. Note that both this and `height` may - /// not match the dimensions of the underlying texture(s). This could be - /// due to a crop rect or rotation. + + /// Width of the external texture. pub width: u32, + /// Height of the external texture. pub height: u32, + /// Format of the external texture. pub format: ExternalTextureFormat, + /// 4x4 column-major matrix with which to convert sampled YCbCr values /// to RGBA. /// This is ignored when `format` is [`ExternalTextureFormat::Rgba`]. pub yuv_conversion_matrix: [f32; 16], - /// 3x2 column-major matrix with which to multiply normalized texture - /// coordinates prior to sampling from the external texture. + + /// Transform to apply to [`ImageSample`] coordinates. + /// + /// This is a 3x2 column-major matrix representing an affine transform from + /// normalized texture coordinates to the normalized coordinates that should + /// be sampled from the external texture's underlying plane(s). + /// + /// This transform may scale, translate, flip, and rotate in 90-degree + /// increments, but the result of transforming the rectangle (0,0)..(1,1) + /// must be an axis-aligned rectangle that falls within the bounds of + /// (0,0)..(1,1). + /// + /// [`ImageSample`]: https://docs.rs/naga/latest/naga/ir/enum.Expression.html#variant.ImageSample pub sample_transform: [f32; 6], - /// 3x2 column-major matrix with which to multiply unnormalized texture - /// coordinates prior to loading from the external texture. + + /// Transform to apply to [`ImageLoad`] coordinates. + /// + /// This is a 3x2 column-major matrix representing an affine transform from + /// non-normalized texel coordinates to the non-normalized coordinates of + /// the texel that should be loaded from the external texture's underlying + /// plane 0. For planes 1 and 2, if present, plane 0's coordinates are + /// scaled according to the textures' relative sizes. + /// + /// This transform may scale, translate, flip, and rotate in 90-degree + /// increments, but the result of transforming the rectangle (0,0)..([`width`], + /// [`height`]) must be an axis-aligned rectangle that falls within the bounds + /// of (0,0)..([`width`], [`height`]). + /// + /// [`ImageLoad`]: https://docs.rs/naga/latest/naga/ir/enum.Expression.html#variant.ImageLoad + /// [`width`]: Self::width + /// [`height`]: Self::height pub load_transform: [f32; 6], } From 59f815a9b9148ad916c460d034d9c0eb902fe73a Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Wed, 30 Jul 2025 15:32:28 +0100 Subject: [PATCH 080/303] [naga] Have validation reject shaders containing binding arrays of external textures For simplicity's sake our initial implementation of external textures will not support binding arrays of external textures. We should therefore reject any shaders which use them during validation. Their implementation will be tracked in #8027. naga/src/valid/type.rs JJ: JJ: Lines starting with "JJ:" (like this one) will be removed. --- naga/src/valid/type.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/naga/src/valid/type.rs b/naga/src/valid/type.rs index 8aa3c04f207..e8b83ff08f3 100644 --- a/naga/src/valid/type.rs +++ b/naga/src/valid/type.rs @@ -133,6 +133,8 @@ pub enum TypeError { InvalidDynamicArray(String, Handle), #[error("The base handle {0:?} has to be a struct")] BindingArrayBaseTypeNotStruct(Handle), + #[error("Binding arrays of external textures are not yet supported")] + BindingArrayBaseExternalTextures, #[error("Structure member[{index}] at {offset} overlaps the previous member")] MemberOverlap { index: u32, offset: u32 }, #[error( @@ -803,6 +805,17 @@ impl super::Validator { _ => return Err(TypeError::BindingArrayBaseTypeNotStruct(base)), }; } + if matches!( + gctx.types[base].inner, + crate::TypeInner::Image { + class: crate::ImageClass::External, + .. + } + ) { + // Binding arrays of external textures are not yet supported. + // https://github.com/gfx-rs/wgpu/issues/8027 + return Err(TypeError::BindingArrayBaseExternalTextures); + } if !base_info.flags.contains(TypeFlags::CREATION_RESOLVED) { return Err(TypeError::InvalidData(base)); From 58b613587245d003a385cbba26cbeff6c0af736d Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Wed, 30 Jul 2025 19:58:08 -0400 Subject: [PATCH 081/303] hal/vulkan: Clear framebuffer cache during command buffer reset (#8031) --- wgpu-hal/src/vulkan/command.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index 65ee0daa994..ec9e44f2ee6 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -180,6 +180,10 @@ impl crate::CommandEncoder for super::CommandEncoder { self.free .extend(cmd_bufs.into_iter().map(|cmd_buf| cmd_buf.raw)); self.free.append(&mut self.discarded); + // Delete framebuffers from the framebuffer cache + for (_, framebuffer) in self.framebuffers.drain() { + unsafe { self.device.raw.destroy_framebuffer(framebuffer, None) }; + } let _ = unsafe { self.device .raw From 45e96e593fa8e3c9767de385c08899764018889e Mon Sep 17 00:00:00 2001 From: sagudev <16504129+sagudev@users.noreply.github.com> Date: Thu, 31 Jul 2025 22:05:05 +0200 Subject: [PATCH 082/303] docs: Fix comment in `COPY_BYTES_PER_ROW_ALIGNMENT` to include `copy_texture_to_buffer` (#8029) --- wgpu-types/src/lib.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index d70fd3803cc..10ec85121aa 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -72,12 +72,14 @@ pub type ShaderLocation = u32; /// [dynamic bind group offsets](../wgpu/struct.RenderPass.html#method.set_bind_group). pub type DynamicOffset = u32; -/// Buffer-to-texture copies must have [`bytes_per_row`] aligned to this number. +/// Buffer-texture copies must have [`bytes_per_row`] aligned to this number. /// -/// This doesn't apply to [`Queue::write_texture`][Qwt], only to [`copy_buffer_to_texture()`]. +/// This doesn't apply to [`Queue::write_texture`][Qwt], only to [`copy_buffer_to_texture()`] +/// and [`copy_texture_to_buffer()`]. /// /// [`bytes_per_row`]: TexelCopyBufferLayout::bytes_per_row /// [`copy_buffer_to_texture()`]: ../wgpu/struct.Queue.html#method.copy_buffer_to_texture +/// [`copy_texture_to_buffer()`]: ../wgpu/struct.Queue.html#method.copy_texture_to_buffer /// [Qwt]: ../wgpu/struct.Queue.html#method.write_texture pub const COPY_BYTES_PER_ROW_ALIGNMENT: u32 = 256; From f25a79595a2030ff906e592f2b27cf41f73e6b1b Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Thu, 31 Jul 2025 22:10:15 -0700 Subject: [PATCH 083/303] Add a missing condition to viewport validation (#8040) --- cts_runner/test.lst | 1 + wgpu-core/src/command/render.rs | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 1b7059a4deb..727530d299d 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -29,6 +29,7 @@ webgpu:api,validation,encoding,cmds,index_access:* //FAIL: webgpu:api,validation,encoding,cmds,render,draw:* webgpu:api,validation,encoding,cmds,render,draw:index_buffer_OOB:* webgpu:api,validation,encoding,cmds,render,draw:unused_buffer_bound:* +webgpu:api,validation,encoding,cmds,render,dynamic_state:* webgpu:api,validation,encoding,cmds,render,setIndexBuffer:* webgpu:api,validation,encoding,cmds,render,setVertexBuffer:* webgpu:api,validation,encoding,encoder_state:* diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index ba5fdbcd7d0..12d5bc86d15 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -2520,7 +2520,10 @@ fn set_viewport( } .into()); } - if !(0.0..=1.0).contains(&depth_min) || !(0.0..=1.0).contains(&depth_max) { + if !(0.0..=1.0).contains(&depth_min) + || !(0.0..=1.0).contains(&depth_max) + || depth_min > depth_max + { return Err(RenderCommandError::InvalidViewportDepth(depth_min, depth_max).into()); } let r = hal::Rect { From df40889e1bd7221b133028d03143b4d8951bfcac Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Sun, 13 Jul 2025 02:08:12 -0400 Subject: [PATCH 084/303] Prepare for miri --- .config/nextest.toml | 4 ++++ naga/tests/naga/example_wgsl.rs | 3 +++ naga/tests/naga/snapshots.rs | 11 ++++++++--- player/tests/player/main.rs | 1 + tests/Cargo.toml | 4 +++- tests/src/image.rs | 20 ++++++++++---------- tests/tests/wgpu-compile/main.rs | 1 + tests/tests/wgpu-dependency/main.rs | 2 +- tests/tests/wgpu-validation/api/instance.rs | 2 +- 9 files changed, 32 insertions(+), 16 deletions(-) diff --git a/.config/nextest.toml b/.config/nextest.toml index 64b3b84cba3..32c8d09d91d 100644 --- a/.config/nextest.toml +++ b/.config/nextest.toml @@ -6,6 +6,10 @@ slow-timeout = { period = "45s", terminate-after = 2 } fail-fast = false retries = 0 +[profile.default-miri] +# Miri is very very slow, so give it a much longer timeout. +slow-timeout = { period = "120s", terminate-after = 4 } + # Use two threads for tests with "2 threads" in their name [[profile.default.overrides]] filter = 'test(~2_threads) | test(~2 threads)' diff --git a/naga/tests/naga/example_wgsl.rs b/naga/tests/naga/example_wgsl.rs index 5edb39af837..d9c642a1c54 100644 --- a/naga/tests/naga/example_wgsl.rs +++ b/naga/tests/naga/example_wgsl.rs @@ -4,6 +4,9 @@ use naga::{front::wgsl, valid::Validator}; use std::{ffi::OsStr, fs, path::Path}; /// Runs through all example shaders and ensures they are valid wgsl. +// While we _can_ run this test under miri, it is extremely slow (>5 minutes), +// and naga isn't the primary target for miri testing, so we disable it. +#[cfg(not(miri))] #[test] pub fn parse_example_wgsl() { let example_path = Path::new(env!("CARGO_MANIFEST_DIR")) diff --git a/naga/tests/naga/snapshots.rs b/naga/tests/naga/snapshots.rs index e6e848deb7a..37a068d2709 100644 --- a/naga/tests/naga/snapshots.rs +++ b/naga/tests/naga/snapshots.rs @@ -818,7 +818,9 @@ fn write_output_wgsl( input.write_output_file("wgsl", "wgsl", string); } -#[cfg(feature = "wgsl-in")] +// While we _can_ run this test under miri, it is extremely slow (>5 minutes), +// and naga isn't the primary target for miri testing, so we disable it. +#[cfg(all(feature = "wgsl-in", not(miri)))] #[test] fn convert_snapshots_wgsl() { let _ = env_logger::try_init(); @@ -843,7 +845,8 @@ fn convert_snapshots_wgsl() { } } -#[cfg(feature = "spv-in")] +// miri doesn't allow us to shell out to `spirv-as` +#[cfg(all(feature = "spv-in", not(miri)))] #[test] fn convert_snapshots_spv() { use std::process::Command; @@ -892,7 +895,9 @@ fn convert_snapshots_spv() { } } -#[cfg(feature = "glsl-in")] +// While we _can_ run this test under miri, it is extremely slow (>5 minutes), +// and naga isn't the primary target for miri testing, so we disable it. +#[cfg(all(feature = "glsl-in", not(miri)))] #[allow(unused_variables)] #[test] fn convert_snapshots_glsl() { diff --git a/player/tests/player/main.rs b/player/tests/player/main.rs index aa5eb90e74a..ca0e728aec0 100644 --- a/player/tests/player/main.rs +++ b/player/tests/player/main.rs @@ -245,6 +245,7 @@ impl Corpus { } } +#[cfg(not(miri))] #[test] fn test_api() { env_logger::init(); diff --git a/tests/Cargo.toml b/tests/Cargo.toml index d93f7338939..95301df9488 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -67,9 +67,11 @@ trybuild.workspace = true # Cargo-metadata doesn't compile on wasm due to old cargo-util-schemas dependency. cargo_metadata.workspace = true env_logger.workspace = true -nv-flip.workspace = true parking_lot = { workspace = true, features = ["deadlock_detection"] } +[target.'cfg(not(any(target_arch = "wasm32", miri)))'.dependencies] +nv-flip.workspace = true + # Webassembly [target.'cfg(target_arch = "wasm32")'.dependencies] console_log.workspace = true diff --git a/tests/src/image.rs b/tests/src/image.rs index dee861b22d0..5cb66a647f8 100644 --- a/tests/src/image.rs +++ b/tests/src/image.rs @@ -7,7 +7,7 @@ use wgpu::*; use crate::TestingContext; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(not(any(target_arch = "wasm32", miri)))] async fn read_png(path: impl AsRef, width: u32, height: u32) -> Option> { let data = match std::fs::read(&path) { Ok(f) => f, @@ -45,7 +45,7 @@ async fn read_png(path: impl AsRef, width: u32, height: u32) -> Option, width: u32, @@ -64,7 +64,7 @@ async fn write_png( writer.write_image_data(data).unwrap(); } -#[cfg_attr(target_arch = "wasm32", allow(unused))] +#[cfg_attr(any(target_arch = "wasm32", miri), allow(unused))] fn add_alpha(input: &[u8]) -> Vec { input .chunks_exact(3) @@ -72,7 +72,7 @@ fn add_alpha(input: &[u8]) -> Vec { .collect() } -#[cfg_attr(target_arch = "wasm32", allow(unused))] +#[cfg_attr(any(target_arch = "wasm32", miri), allow(unused))] fn remove_alpha(input: &[u8]) -> Vec { input .chunks_exact(4) @@ -81,7 +81,7 @@ fn remove_alpha(input: &[u8]) -> Vec { .collect() } -#[cfg(not(target_arch = "wasm32"))] +#[cfg(not(any(target_arch = "wasm32", miri)))] fn print_flip(pool: &mut nv_flip::FlipPool) { println!("\tMean: {:.6}", pool.mean()); println!("\tMin Value: {:.6}", pool.min_value()); @@ -115,7 +115,7 @@ pub enum ComparisonType { } impl ComparisonType { - #[cfg(not(target_arch = "wasm32"))] + #[cfg(not(any(target_arch = "wasm32", miri)))] fn check(&self, pool: &mut nv_flip::FlipPool) -> bool { match *self { ComparisonType::Mean(v) => { @@ -148,7 +148,7 @@ impl ComparisonType { } } -#[cfg(not(target_arch = "wasm32"))] +#[cfg(not(any(target_arch = "wasm32", miri)))] pub async fn compare_image_output( path: impl AsRef + AsRef, adapter_info: &wgpu::AdapterInfo, @@ -250,7 +250,7 @@ pub async fn compare_image_output( } } -#[cfg(target_arch = "wasm32")] +#[cfg(any(target_arch = "wasm32", miri))] pub async fn compare_image_output( path: impl AsRef + AsRef, adapter_info: &wgpu::AdapterInfo, @@ -259,13 +259,13 @@ pub async fn compare_image_output( test_with_alpha: &[u8], checks: &[ComparisonType], ) { - #[cfg(target_arch = "wasm32")] + #[cfg(any(target_arch = "wasm32", miri))] { let _ = (path, adapter_info, width, height, test_with_alpha, checks); } } -#[cfg_attr(target_arch = "wasm32", allow(unused))] +#[cfg_attr(any(target_arch = "wasm32", miri), allow(unused))] fn sanitize_for_path(s: &str) -> String { s.chars() .map(|ch| if ch.is_ascii_alphanumeric() { ch } else { '_' }) diff --git a/tests/tests/wgpu-compile/main.rs b/tests/tests/wgpu-compile/main.rs index f35a0cd24b6..e435171c4a7 100644 --- a/tests/tests/wgpu-compile/main.rs +++ b/tests/tests/wgpu-compile/main.rs @@ -1,3 +1,4 @@ +#![cfg(not(miri))] // Tests that ensure that various constructs that should not compile do not compile. #[test] diff --git a/tests/tests/wgpu-dependency/main.rs b/tests/tests/wgpu-dependency/main.rs index baf3f1bde51..ac96afdb0e1 100644 --- a/tests/tests/wgpu-dependency/main.rs +++ b/tests/tests/wgpu-dependency/main.rs @@ -1,6 +1,6 @@ // Cargo-metadata doesn't compile on wasm due to old cargo-util-schemas dependency. // Since this test isn't dependent on the current architecture, we can just skip it on wasm without any issues. -#![cfg(not(target_arch = "wasm32"))] +#![cfg(not(any(target_arch = "wasm32", miri)))] use std::process::Command; diff --git a/tests/tests/wgpu-validation/api/instance.rs b/tests/tests/wgpu-validation/api/instance.rs index 4f30e90293f..5385b71a2b8 100644 --- a/tests/tests/wgpu-validation/api/instance.rs +++ b/tests/tests/wgpu-validation/api/instance.rs @@ -1,5 +1,5 @@ mod multi_instance { - #![cfg(not(target_arch = "wasm32"))] + #![cfg(not(any(target_arch = "wasm32", miri)))] async fn get() -> wgpu::Adapter { let adapter = { From fdc4d421e7a0c4c1a8a4eeaf14daf5e47f5ce541 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Sun, 13 Jul 2025 02:48:47 -0400 Subject: [PATCH 085/303] Add cargo xtask miri --- xtask/src/main.rs | 10 ++++++++++ xtask/src/miri.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 xtask/src/miri.rs diff --git a/xtask/src/main.rs b/xtask/src/main.rs index f9fa3528cbb..1c23ceeb765 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -7,6 +7,7 @@ use anyhow::Context; use pico_args::Arguments; mod cts; +mod miri; mod run_wasm; mod test; mod util; @@ -37,6 +38,14 @@ Commands: All extra arguments will be forwarded to cargo-nextest (NOT wgpu-info) + miri + Run all miri-compatible tests under miri. Requires a nightly toolchain + with the x86_64-unknown-linux-gnu target and miri component installed. + + --toolchain The toolchain to use for miri tests. + Must be a nightly toolchain. + Defaults to `nightly`. + vendor-web-sys Re-vendor the WebGPU web-sys bindings. @@ -85,6 +94,7 @@ fn main() -> anyhow::Result { match subcommand.as_deref() { Some("cts") => cts::run_cts(shell, args)?, Some("run-wasm") => run_wasm::run_wasm(shell, args)?, + Some("miri") => miri::run_miri(shell, args)?, Some("test") => test::run_tests(shell, args)?, Some("vendor-web-sys") => vendor_web_sys::run_vendor_web_sys(shell, args)?, Some(subcommand) => { diff --git a/xtask/src/miri.rs b/xtask/src/miri.rs new file mode 100644 index 00000000000..572f3da8c9b --- /dev/null +++ b/xtask/src/miri.rs @@ -0,0 +1,29 @@ +use pico_args::Arguments; +use xshell::Shell; + +pub fn run_miri(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { + let toolchain: String = args + .opt_value_from_str("--toolchain")? + .unwrap_or_else(|| String::from("nightly")); + + shell + .cmd("rustup") + .args([ + "run", + &toolchain, + "cargo", + "miri", + "nextest", + "run", + "--target", + "x86_64-unknown-linux-gnu", + ]) + .env( + "MIRIFLAGS", + "-Zmiri-disable-isolation -Zmiri-deterministic-floats", + ) + .quiet() + .run()?; + + Ok(()) +} From 86d5211f84b6a69b348c3725f80db0ead55a605d Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Sun, 13 Jul 2025 03:48:52 -0400 Subject: [PATCH 086/303] Add support for running tests on the noop backend --- tests/src/expectations.rs | 4 ++-- tests/src/init.rs | 11 +++++++++-- tests/src/native.rs | 37 +++++++++++++++++++++++++------------ tests/src/params.rs | 14 +++++++++++++- tests/src/report.rs | 14 ++++++++++++++ wgpu-hal/src/noop/mod.rs | 32 ++++++++++++++++++++++---------- xtask/src/miri.rs | 1 + 7 files changed, 86 insertions(+), 27 deletions(-) diff --git a/tests/src/expectations.rs b/tests/src/expectations.rs index a9375c37e05..78d4ece9744 100644 --- a/tests/src/expectations.rs +++ b/tests/src/expectations.rs @@ -36,7 +36,7 @@ use core::fmt; /// [skip]: super::TestParameters::skip /// [expect_fail]: super::TestParameters::expect_fail /// [`AdapterInfo`]: wgpu::AdapterInfo -#[derive(Default, Clone)] +#[derive(Default, Clone, PartialEq)] pub struct FailureCase { /// Backends expected to fail, or `None` for any backend. /// @@ -334,7 +334,7 @@ impl FailureReason { } } -#[derive(Default, Clone)] +#[derive(Default, Clone, PartialEq)] pub enum FailureBehavior { /// Assert that the test fails for the given reason. /// diff --git a/tests/src/init.rs b/tests/src/init.rs index d2aac6f14e1..bee5af689c7 100644 --- a/tests/src/init.rs +++ b/tests/src/init.rs @@ -65,8 +65,15 @@ pub fn initialize_instance(backends: wgpu::Backends, params: &TestParameters) -> ..Default::default() } .with_env(), - // TODO(https://github.com/gfx-rs/wgpu/issues/7119): Enable noop backend? - noop: wgpu::NoopBackendOptions::default(), + // Allow the noop backend to be used in tests. This will not be used unless + // WGPU_GPU_TESTS_USE_NOOP_BACKEND env var is set, because wgpu-info will not + // enumerate the noop backend. + // + // However, we use wasm_bindgen_test to run tests on wasm, and wgpu + // will chose the noop on wasm32 for some reason. + noop: wgpu::NoopBackendOptions { + enable: !cfg!(target_arch = "wasm32"), + }, }, }) } diff --git a/tests/src/native.rs b/tests/src/native.rs index eb12d22a5f9..4f56c79ada1 100644 --- a/tests/src/native.rs +++ b/tests/src/native.rs @@ -81,19 +81,32 @@ pub fn main() -> MainResult { use crate::report::GpuReport; - let config_text = { - profiling::scope!("Reading .gpuconfig"); - &std::fs::read_to_string(format!("{}/../.gpuconfig", env!("CARGO_MANIFEST_DIR"))) - .context("Failed to read .gpuconfig, did you run the tests via `cargo xtask test`?")? + // If this environment variable is set, we will only enumerate the noop backend. The + // main use case is running tests with miri, where we can't even enumerate adapters, + // as we cannot load DLLs or make any external calls. + let use_noop = std::env::var("WGPU_GPU_TESTS_USE_NOOP_BACKEND").as_deref() == Ok("1"); + + let report = if use_noop { + GpuReport::noop_only() + } else { + let config_text = { + profiling::scope!("Reading .gpuconfig"); + &std::fs::read_to_string(format!("{}/../.gpuconfig", env!("CARGO_MANIFEST_DIR"))) + .context( + "Failed to read .gpuconfig, did you run the tests via `cargo xtask test`?", + )? + }; + let mut report = + GpuReport::from_json(config_text).context("Could not parse .gpuconfig JSON")?; + + // Filter out the adapters that are not part of WGPU_BACKEND. + let wgpu_backends = wgpu::Backends::from_env().unwrap_or_default(); + report + .devices + .retain(|report| wgpu_backends.contains(wgpu::Backends::from(report.info.backend))); + + report }; - let mut report = - GpuReport::from_json(config_text).context("Could not parse .gpuconfig JSON")?; - - // Filter out the adapters that are not part of WGPU_BACKEND. - let wgpu_backends = wgpu::Backends::from_env().unwrap_or_default(); - report - .devices - .retain(|report| wgpu_backends.contains(wgpu::Backends::from(report.info.backend))); let mut test_guard = TEST_LIST.lock(); // Iterate through all the tests. Creating a test per adapter. diff --git a/tests/src/params.rs b/tests/src/params.rs index f2c4d531a15..d7339225cb0 100644 --- a/tests/src/params.rs +++ b/tests/src/params.rs @@ -41,7 +41,9 @@ impl Default for TestParameters { required_limits: Limits::downlevel_webgl2_defaults(), required_instance_flags: InstanceFlags::empty(), force_fxc: false, - skips: Vec::new(), + // By default we skip the noop backend, and enable it if the test + // parameters ask us to remove it. + skips: vec![FailureCase::backend(wgpu::Backends::NOOP)], failures: Vec::new(), } } @@ -94,6 +96,16 @@ impl TestParameters { self.skips.push(when); self } + + /// Enable testing against the noop backend and miri. + /// + /// The noop backend does not execute any operations, but allows us to test + /// validation and memory safety. + pub fn enable_noop(mut self) -> Self { + self.skips + .retain(|case| *case != FailureCase::backend(wgpu::Backends::NOOP)); + self + } } /// Information about a test, including if if it should be skipped. diff --git a/tests/src/report.rs b/tests/src/report.rs index b26bdbfaf39..ed3cc03e461 100644 --- a/tests/src/report.rs +++ b/tests/src/report.rs @@ -15,6 +15,20 @@ pub(crate) struct GpuReport { } impl GpuReport { + #[cfg(not(target_arch = "wasm32"))] + /// Creates a new GpuReport with a single noop adapter. + pub(crate) fn noop_only() -> Self { + GpuReport { + devices: vec![AdapterReport { + info: wgpu::hal::noop::adapter_info(), + features: Features::all(), + limits: wgpu::hal::noop::CAPABILITIES.limits, + downlevel_caps: wgpu::hal::noop::CAPABILITIES.downlevel, + texture_format_features: HashMap::new(), // todo + }], + } + } + #[cfg_attr(target_arch = "wasm32", allow(unused))] pub(crate) fn from_json(file: &str) -> serde_json::Result { profiling::scope!("Parsing .gpuconfig"); diff --git a/wgpu-hal/src/noop/mod.rs b/wgpu-hal/src/noop/mod.rs index 55965a7e2fb..abd7c628a98 100644 --- a/wgpu-hal/src/noop/mod.rs +++ b/wgpu-hal/src/noop/mod.rs @@ -120,22 +120,34 @@ impl crate::Instance for Context { ) -> Vec> { vec![crate::ExposedAdapter { adapter: Context, - info: wgt::AdapterInfo { - name: String::from("noop wgpu backend"), - vendor: 0, - device: 0, - device_type: wgt::DeviceType::Cpu, - driver: String::from("wgpu"), - driver_info: String::new(), - backend: wgt::Backend::Noop, - }, + info: adapter_info(), features: wgt::Features::all(), capabilities: CAPABILITIES, }] } } -const CAPABILITIES: crate::Capabilities = { +/// Returns the adapter info for the noop backend. +/// +/// This is used in the test harness to construct info about +/// the noop backend adapter without actually initializing wgpu. +pub fn adapter_info() -> wgt::AdapterInfo { + wgt::AdapterInfo { + name: String::from("noop wgpu backend"), + vendor: 0, + device: 0, + device_type: wgt::DeviceType::Cpu, + driver: String::from("wgpu"), + driver_info: String::new(), + backend: wgt::Backend::Noop, + } +} + +/// The capabilities of the noop backend. +/// +/// This is used in the test harness to construct capabilities +/// of the noop backend without actually initializing wgpu. +pub const CAPABILITIES: crate::Capabilities = { /// Guaranteed to be no bigger than isize::MAX which is the maximum size of an allocation, /// except on 16-bit platforms which we certainly don’t fit in. const ALLOC_MAX_U32: u32 = i32::MAX as u32; diff --git a/xtask/src/miri.rs b/xtask/src/miri.rs index 572f3da8c9b..075b115fdfa 100644 --- a/xtask/src/miri.rs +++ b/xtask/src/miri.rs @@ -22,6 +22,7 @@ pub fn run_miri(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { "MIRIFLAGS", "-Zmiri-disable-isolation -Zmiri-deterministic-floats", ) + .env("WGPU_GPU_TESTS_USE_NOOP_BACKEND", "1") .quiet() .run()?; From 09d0c94576553382e924710e06d9d34f55da6b25 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Sun, 13 Jul 2025 20:35:50 -0400 Subject: [PATCH 087/303] Use explicit test enumeration --- .../features/src/big_compute_buffers/mod.rs | 2 +- .../features/src/big_compute_buffers/tests.rs | 2 +- examples/features/src/boids/mod.rs | 2 +- examples/features/src/bunnymark/mod.rs | 2 +- .../features/src/conservative_raster/mod.rs | 2 +- examples/features/src/cube/mod.rs | 4 +- .../features/src/hello_synchronization/mod.rs | 2 +- .../src/hello_synchronization/tests.rs | 2 +- examples/features/src/lib.rs | 50 +++++++++- examples/features/src/mipmap/mod.rs | 4 +- examples/features/src/msaa_line/mod.rs | 2 +- .../src/multiple_render_targets/mod.rs | 2 +- examples/features/src/ray_cube_compute/mod.rs | 2 +- .../features/src/ray_cube_fragment/mod.rs | 2 +- examples/features/src/ray_cube_normals/mod.rs | 2 +- examples/features/src/ray_scene/mod.rs | 2 +- examples/features/src/ray_shadows/mod.rs | 2 +- .../features/src/ray_traced_triangle/mod.rs | 2 +- examples/features/src/shadow/mod.rs | 2 +- examples/features/src/skybox/mod.rs | 8 +- examples/features/src/srgb_blend/mod.rs | 4 +- .../features/src/stencil_triangles/mod.rs | 2 +- examples/features/src/texture_arrays/mod.rs | 25 ++--- .../features/src/timestamp_queries/mod.rs | 8 +- examples/features/src/water/mod.rs | 2 +- tests/src/config.rs | 2 + tests/src/lib.rs | 13 ++- tests/src/native.rs | 7 +- tests/tests/wgpu-gpu/bgra8unorm_storage.rs | 6 +- .../tests/wgpu-gpu/bind_group_layout_dedup.rs | 15 ++- tests/tests/wgpu-gpu/bind_groups.rs | 14 ++- tests/tests/wgpu-gpu/binding_array/buffers.rs | 13 ++- tests/tests/wgpu-gpu/binding_array/mod.rs | 7 ++ .../binding_array/sampled_textures.rs | 10 +- .../tests/wgpu-gpu/binding_array/samplers.rs | 8 +- .../binding_array/storage_textures.rs | 11 ++- tests/tests/wgpu-gpu/buffer.rs | 15 ++- tests/tests/wgpu-gpu/buffer_copy.rs | 6 +- tests/tests/wgpu-gpu/buffer_usages.rs | 12 ++- tests/tests/wgpu-gpu/clear_texture.rs | 16 +++- tests/tests/wgpu-gpu/clip_distances.rs | 8 +- tests/tests/wgpu-gpu/cloneable_types.rs | 6 +- .../tests/wgpu-gpu/compute_pass_ownership.rs | 13 ++- tests/tests/wgpu-gpu/device.rs | 24 ++++- .../wgpu-gpu/dispatch_workgroups_indirect.rs | 13 ++- tests/tests/wgpu-gpu/draw_indirect.rs | 28 +++++- tests/tests/wgpu-gpu/dual_source_blending.rs | 11 ++- tests/tests/wgpu-gpu/encoder.rs | 12 ++- tests/tests/wgpu-gpu/float32_filterable.rs | 9 +- tests/tests/wgpu-gpu/image_atomics/mod.rs | 12 ++- tests/tests/wgpu-gpu/instance.rs | 6 +- tests/tests/wgpu-gpu/life_cycle.rs | 13 ++- tests/tests/wgpu-gpu/main.rs | 94 ++++++++++++++++--- tests/tests/wgpu-gpu/mem_leaks.rs | 14 +++ tests/tests/wgpu-gpu/mesh_shader/mod.rs | 16 +++- tests/tests/wgpu-gpu/nv12_texture/mod.rs | 12 ++- tests/tests/wgpu-gpu/occlusion_query/mod.rs | 6 +- tests/tests/wgpu-gpu/oob_indexing.rs | 7 ++ tests/tests/wgpu-gpu/oom.rs | 12 +++ tests/tests/wgpu-gpu/pipeline.rs | 12 ++- tests/tests/wgpu-gpu/pipeline_cache.rs | 4 + tests/tests/wgpu-gpu/poll.rs | 13 ++- tests/tests/wgpu-gpu/push_constants.rs | 8 +- tests/tests/wgpu-gpu/query_set.rs | 6 +- tests/tests/wgpu-gpu/queue_transfer.rs | 10 +- tests/tests/wgpu-gpu/ray_tracing/as_build.rs | 24 ++++- tests/tests/wgpu-gpu/ray_tracing/as_create.rs | 4 + .../wgpu-gpu/ray_tracing/as_use_after_free.rs | 4 + tests/tests/wgpu-gpu/ray_tracing/limits.rs | 4 + tests/tests/wgpu-gpu/ray_tracing/mod.rs | 9 ++ tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs | 7 ++ tests/tests/wgpu-gpu/ray_tracing/shader.rs | 5 + tests/tests/wgpu-gpu/regression/issue_3349.rs | 7 +- tests/tests/wgpu-gpu/regression/issue_3457.rs | 6 +- tests/tests/wgpu-gpu/regression/issue_4024.rs | 6 +- tests/tests/wgpu-gpu/regression/issue_4122.rs | 8 +- tests/tests/wgpu-gpu/regression/issue_4485.rs | 8 +- tests/tests/wgpu-gpu/regression/issue_4514.rs | 8 +- tests/tests/wgpu-gpu/regression/issue_5553.rs | 6 +- tests/tests/wgpu-gpu/regression/issue_6317.rs | 6 +- tests/tests/wgpu-gpu/regression/issue_6467.rs | 6 +- tests/tests/wgpu-gpu/regression/issue_6827.rs | 8 +- tests/tests/wgpu-gpu/render_pass_ownership.rs | 13 ++- tests/tests/wgpu-gpu/render_target.rs | 14 ++- .../wgpu-gpu/resource_descriptor_accessor.rs | 6 +- tests/tests/wgpu-gpu/resource_error.rs | 6 +- tests/tests/wgpu-gpu/samplers.rs | 14 ++- tests/tests/wgpu-gpu/scissor_tests/mod.rs | 11 ++- .../wgpu-gpu/shader/array_size_overrides.rs | 4 + .../shader/compilation_messages/mod.rs | 6 +- tests/tests/wgpu-gpu/shader/data_builtins.rs | 6 +- tests/tests/wgpu-gpu/shader/mod.rs | 12 ++- .../tests/wgpu-gpu/shader/numeric_builtins.rs | 11 ++- tests/tests/wgpu-gpu/shader/struct_layout.rs | 15 ++- .../shader/workgroup_size_overrides.rs | 4 + .../shader/zero_init_workgroup_mem.rs | 6 +- .../wgpu-gpu/shader_primitive_index/mod.rs | 4 + .../tests/wgpu-gpu/shader_view_format/mod.rs | 4 + .../tests/wgpu-gpu/subgroup_operations/mod.rs | 6 +- tests/tests/wgpu-gpu/texture_binding/mod.rs | 6 +- tests/tests/wgpu-gpu/texture_blit.rs | 9 +- tests/tests/wgpu-gpu/texture_bounds.rs | 4 + tests/tests/wgpu-gpu/texture_view_creation.rs | 10 +- .../wgpu-gpu/timestamp_normalization/mod.rs | 4 + .../wgpu-gpu/timestamp_normalization/utils.rs | 4 + tests/tests/wgpu-gpu/timestamp_query.rs | 8 +- tests/tests/wgpu-gpu/transfer.rs | 6 +- tests/tests/wgpu-gpu/transition_resources.rs | 6 +- tests/tests/wgpu-gpu/vertex_formats/mod.rs | 4 + tests/tests/wgpu-gpu/vertex_indices/mod.rs | 4 + tests/tests/wgpu-gpu/write_texture.rs | 11 ++- .../zero_init_texture_after_discard.rs | 13 ++- wgpu-macros/src/lib.rs | 16 ++-- 113 files changed, 898 insertions(+), 138 deletions(-) diff --git a/examples/features/src/big_compute_buffers/mod.rs b/examples/features/src/big_compute_buffers/mod.rs index 579ab8a79f3..5a4399fe7c0 100644 --- a/examples/features/src/big_compute_buffers/mod.rs +++ b/examples/features/src/big_compute_buffers/mod.rs @@ -248,4 +248,4 @@ pub fn main() { #[cfg(test)] #[cfg(not(target_arch = "wasm32"))] -mod tests; +pub mod tests; diff --git a/examples/features/src/big_compute_buffers/tests.rs b/examples/features/src/big_compute_buffers/tests.rs index 5ca93b631cf..d6c522610ce 100644 --- a/examples/features/src/big_compute_buffers/tests.rs +++ b/examples/features/src/big_compute_buffers/tests.rs @@ -2,7 +2,7 @@ use super::*; use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters}; #[gpu_test] -static TWO_BUFFERS: GpuTestConfiguration = GpuTestConfiguration::new() +pub static TWO_BUFFERS: GpuTestConfiguration = GpuTestConfiguration::new() .parameters( TestParameters::default() .features( diff --git a/examples/features/src/boids/mod.rs b/examples/features/src/boids/mod.rs index 9ee19a55020..d272442275a 100644 --- a/examples/features/src/boids/mod.rs +++ b/examples/features/src/boids/mod.rs @@ -323,7 +323,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] -static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "boids", // Generated on 1080ti on Vk/Windows image_path: "/examples/features/src/boids/screenshot.png", diff --git a/examples/features/src/bunnymark/mod.rs b/examples/features/src/bunnymark/mod.rs index 9ac69cac378..689eb329dfd 100644 --- a/examples/features/src/bunnymark/mod.rs +++ b/examples/features/src/bunnymark/mod.rs @@ -434,7 +434,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] -static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "bunnymark", image_path: "/examples/features/src/bunnymark/screenshot.png", width: 1024, diff --git a/examples/features/src/conservative_raster/mod.rs b/examples/features/src/conservative_raster/mod.rs index c05f0cb9140..d2f5c74fdec 100644 --- a/examples/features/src/conservative_raster/mod.rs +++ b/examples/features/src/conservative_raster/mod.rs @@ -317,7 +317,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] -static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "conservative-raster", image_path: "/examples/features/src/conservative_raster/screenshot.png", width: 1024, diff --git a/examples/features/src/cube/mod.rs b/examples/features/src/cube/mod.rs index f3e9f768035..686dca3782e 100644 --- a/examples/features/src/cube/mod.rs +++ b/examples/features/src/cube/mod.rs @@ -381,7 +381,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] -static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "cube", // Generated on 1080ti on Vk/Windows image_path: "/examples/features/src/cube/screenshot.png", @@ -397,7 +397,7 @@ static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTest #[cfg(test)] #[wgpu_test::gpu_test] -static TEST_LINES: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST_LINES: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "cube-lines", // Generated on 1080ti on Vk/Windows image_path: "/examples/features/src/cube/screenshot-lines.png", diff --git a/examples/features/src/hello_synchronization/mod.rs b/examples/features/src/hello_synchronization/mod.rs index 39b76b6d073..da2f103f248 100644 --- a/examples/features/src/hello_synchronization/mod.rs +++ b/examples/features/src/hello_synchronization/mod.rs @@ -208,4 +208,4 @@ pub fn main() { } #[cfg(test)] -mod tests; +pub mod tests; diff --git a/examples/features/src/hello_synchronization/tests.rs b/examples/features/src/hello_synchronization/tests.rs index 756289a3637..ff34abbd091 100644 --- a/examples/features/src/hello_synchronization/tests.rs +++ b/examples/features/src/hello_synchronization/tests.rs @@ -2,7 +2,7 @@ use super::*; use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters}; #[gpu_test] -static SYNC: GpuTestConfiguration = GpuTestConfiguration::new() +pub static SYNC: GpuTestConfiguration = GpuTestConfiguration::new() .parameters( // Taken from hello-compute tests. TestParameters::default() diff --git a/examples/features/src/lib.rs b/examples/features/src/lib.rs index 271241f1ae0..baacf6a6b39 100644 --- a/examples/features/src/lib.rs +++ b/examples/features/src/lib.rs @@ -36,4 +36,52 @@ pub mod uniform_values; pub mod water; #[cfg(test)] -wgpu_test::gpu_test_main!(); +fn all_tests() -> Vec { + #[cfg_attr( + target_arch = "wasm32", + expect(unused_mut, reason = "non-wasm32 needs this mutable") + )] + let mut test_list = vec![ + boids::TEST, + bunnymark::TEST, + conservative_raster::TEST, + cube::TEST, + cube::TEST_LINES, + hello_synchronization::tests::SYNC, + mipmap::TEST, + mipmap::TEST_QUERY, + msaa_line::TEST, + multiple_render_targets::TEST, + ray_cube_compute::TEST, + ray_cube_fragment::TEST, + ray_cube_normals::TEST, + ray_scene::TEST, + ray_shadows::TEST, + ray_traced_triangle::TEST, + shadow::TEST, + skybox::TEST, + skybox::TEST_ASTC, + skybox::TEST_BCN, + skybox::TEST_ETC2, + srgb_blend::TEST_LINEAR, + srgb_blend::TEST_SRGB, + stencil_triangles::TEST, + texture_arrays::TEST, + texture_arrays::TEST_NON_UNIFORM, + texture_arrays::TEST_UNIFORM, + timestamp_queries::tests::TIMESTAMPS_ENCODER, + timestamp_queries::tests::TIMESTAMPS_PASSES, + timestamp_queries::tests::TIMESTAMPS_PASS_BOUNDARIES, + water::TEST, + ]; + + #[cfg(not(target_arch = "wasm32"))] + { + test_list.push(big_compute_buffers::tests::TWO_BUFFERS); + } + + test_list +} + +#[cfg(test)] +wgpu_test::gpu_test_main!(all_tests()); diff --git a/examples/features/src/mipmap/mod.rs b/examples/features/src/mipmap/mod.rs index f9d4febafa0..5e5cc3d34e0 100644 --- a/examples/features/src/mipmap/mod.rs +++ b/examples/features/src/mipmap/mod.rs @@ -508,7 +508,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] -static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "mipmap", image_path: "/examples/features/src/mipmap/screenshot.png", width: 1024, @@ -521,7 +521,7 @@ static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTest #[cfg(test)] #[wgpu_test::gpu_test] -static TEST_QUERY: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST_QUERY: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "mipmap-query", image_path: "/examples/features/src/mipmap/screenshot_query.png", width: 1024, diff --git a/examples/features/src/msaa_line/mod.rs b/examples/features/src/msaa_line/mod.rs index df58994db6e..71c6b277c4b 100644 --- a/examples/features/src/msaa_line/mod.rs +++ b/examples/features/src/msaa_line/mod.rs @@ -321,7 +321,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] -static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "msaa-line", image_path: "/examples/features/src/msaa_line/screenshot.png", width: 1024, diff --git a/examples/features/src/multiple_render_targets/mod.rs b/examples/features/src/multiple_render_targets/mod.rs index 61726c3fb1c..d708f701f0b 100644 --- a/examples/features/src/multiple_render_targets/mod.rs +++ b/examples/features/src/multiple_render_targets/mod.rs @@ -536,7 +536,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] -static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: EXAMPLE_NAME, image_path: "/examples/features/src/multiple_render_targets/screenshot.png", width: 1024, diff --git a/examples/features/src/ray_cube_compute/mod.rs b/examples/features/src/ray_cube_compute/mod.rs index 9492822ad77..3d875b1c745 100644 --- a/examples/features/src/ray_cube_compute/mod.rs +++ b/examples/features/src/ray_cube_compute/mod.rs @@ -486,7 +486,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] -static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "ray_cube_compute", image_path: "/examples/features/src/ray_cube_compute/screenshot.png", width: 1024, diff --git a/examples/features/src/ray_cube_fragment/mod.rs b/examples/features/src/ray_cube_fragment/mod.rs index 94db6b59f52..dde26e02832 100644 --- a/examples/features/src/ray_cube_fragment/mod.rs +++ b/examples/features/src/ray_cube_fragment/mod.rs @@ -372,7 +372,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] -static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "ray_cube_fragment", image_path: "/examples/features/src/ray_cube_fragment/screenshot.png", width: 1024, diff --git a/examples/features/src/ray_cube_normals/mod.rs b/examples/features/src/ray_cube_normals/mod.rs index e21974eabfb..4620b7551c0 100644 --- a/examples/features/src/ray_cube_normals/mod.rs +++ b/examples/features/src/ray_cube_normals/mod.rs @@ -472,7 +472,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] -static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "ray_cube_normals", image_path: "/examples/features/src/ray_cube_normals/screenshot.png", width: 1024, diff --git a/examples/features/src/ray_scene/mod.rs b/examples/features/src/ray_scene/mod.rs index 66717c5a87c..21c2aada802 100644 --- a/examples/features/src/ray_scene/mod.rs +++ b/examples/features/src/ray_scene/mod.rs @@ -552,7 +552,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] -static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "ray_scene", image_path: "/examples/features/src/ray_scene/screenshot.png", width: 1024, diff --git a/examples/features/src/ray_shadows/mod.rs b/examples/features/src/ray_shadows/mod.rs index 8b93fb275a2..559ac32342a 100644 --- a/examples/features/src/ray_shadows/mod.rs +++ b/examples/features/src/ray_shadows/mod.rs @@ -370,7 +370,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] -static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "ray_shadows", image_path: "/examples/features/src/ray_shadows/screenshot.png", width: 1024, diff --git a/examples/features/src/ray_traced_triangle/mod.rs b/examples/features/src/ray_traced_triangle/mod.rs index 9d3d0cb3794..0df2e829d2b 100644 --- a/examples/features/src/ray_traced_triangle/mod.rs +++ b/examples/features/src/ray_traced_triangle/mod.rs @@ -431,7 +431,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] -static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "ray_traced_triangle", image_path: "/examples/features/src/ray_traced_triangle/screenshot.png", width: 1024, diff --git a/examples/features/src/shadow/mod.rs b/examples/features/src/shadow/mod.rs index 4be97dadde2..b89d2c902dc 100644 --- a/examples/features/src/shadow/mod.rs +++ b/examples/features/src/shadow/mod.rs @@ -839,7 +839,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] -static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "shadow", image_path: "/examples/features/src/shadow/screenshot.png", width: 1024, diff --git a/examples/features/src/skybox/mod.rs b/examples/features/src/skybox/mod.rs index 2484e6f25d3..699f6615ba9 100644 --- a/examples/features/src/skybox/mod.rs +++ b/examples/features/src/skybox/mod.rs @@ -470,7 +470,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] -static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "skybox", image_path: "/examples/features/src/skybox/screenshot.png", width: 1024, @@ -485,7 +485,7 @@ static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTest #[cfg(test)] #[wgpu_test::gpu_test] -static TEST_BCN: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST_BCN: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "skybox-bc7", image_path: "/examples/features/src/skybox/screenshot_bc7.png", width: 1024, @@ -498,7 +498,7 @@ static TEST_BCN: crate::framework::ExampleTestParams = crate::framework::Example #[cfg(test)] #[wgpu_test::gpu_test] -static TEST_ETC2: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST_ETC2: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "skybox-etc2", image_path: "/examples/features/src/skybox/screenshot_etc2.png", width: 1024, @@ -511,7 +511,7 @@ static TEST_ETC2: crate::framework::ExampleTestParams = crate::framework::Exampl #[cfg(test)] #[wgpu_test::gpu_test] -static TEST_ASTC: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST_ASTC: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "skybox-astc", image_path: "/examples/features/src/skybox/screenshot_astc.png", width: 1024, diff --git a/examples/features/src/srgb_blend/mod.rs b/examples/features/src/srgb_blend/mod.rs index d91e8cd41ae..fcd59265b76 100644 --- a/examples/features/src/srgb_blend/mod.rs +++ b/examples/features/src/srgb_blend/mod.rs @@ -223,7 +223,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] -static TEST_SRGB: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST_SRGB: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "srgb-blend-srg", // Generated on WARP/Windows image_path: "/examples/features/src/srgb_blend/screenshot-srgb.png", @@ -237,7 +237,7 @@ static TEST_SRGB: crate::framework::ExampleTestParams = crate::framework::Exampl #[cfg(test)] #[wgpu_test::gpu_test] -static TEST_LINEAR: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST_LINEAR: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "srgb-blend-linear", // Generated on WARP/Windows image_path: "/examples/features/src/srgb_blend/screenshot-linear.png", diff --git a/examples/features/src/stencil_triangles/mod.rs b/examples/features/src/stencil_triangles/mod.rs index 5216f225937..e1e44acf40f 100644 --- a/examples/features/src/stencil_triangles/mod.rs +++ b/examples/features/src/stencil_triangles/mod.rs @@ -245,7 +245,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] -static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "stencil-triangles", image_path: "/examples/features/src/stencil_triangles/screenshot.png", width: 1024, diff --git a/examples/features/src/texture_arrays/mod.rs b/examples/features/src/texture_arrays/mod.rs index 1062ff04b90..e7615444200 100644 --- a/examples/features/src/texture_arrays/mod.rs +++ b/examples/features/src/texture_arrays/mod.rs @@ -431,7 +431,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] -static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "texture-arrays", image_path: "/examples/features/src/texture_arrays/screenshot.png", width: 1024, @@ -444,20 +444,21 @@ static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTest #[cfg(test)] #[wgpu_test::gpu_test] -static TEST_UNIFORM: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { - name: "texture-arrays-uniform", - image_path: "/examples/features/src/texture_arrays/screenshot.png", - width: 1024, - height: 768, - optional_features: wgpu::Features::empty(), - base_test_parameters: wgpu_test::TestParameters::default(), - comparisons: &[wgpu_test::ComparisonType::Mean(0.0)], - _phantom: std::marker::PhantomData::, -}; +pub static TEST_UNIFORM: crate::framework::ExampleTestParams = + crate::framework::ExampleTestParams { + name: "texture-arrays-uniform", + image_path: "/examples/features/src/texture_arrays/screenshot.png", + width: 1024, + height: 768, + optional_features: wgpu::Features::empty(), + base_test_parameters: wgpu_test::TestParameters::default(), + comparisons: &[wgpu_test::ComparisonType::Mean(0.0)], + _phantom: std::marker::PhantomData::, + }; #[cfg(test)] #[wgpu_test::gpu_test] -static TEST_NON_UNIFORM: crate::framework::ExampleTestParams = +pub static TEST_NON_UNIFORM: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "texture-arrays-non-uniform", image_path: "/examples/features/src/texture_arrays/screenshot.png", diff --git a/examples/features/src/timestamp_queries/mod.rs b/examples/features/src/timestamp_queries/mod.rs index c0fce563d12..23746a6ee6a 100644 --- a/examples/features/src/timestamp_queries/mod.rs +++ b/examples/features/src/timestamp_queries/mod.rs @@ -426,13 +426,13 @@ pub fn main() { } #[cfg(test)] -mod tests { +pub mod tests { use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration}; use super::{submit_render_and_compute_pass_with_queries, QueryResults}; #[gpu_test] - static TIMESTAMPS_PASS_BOUNDARIES: GpuTestConfiguration = GpuTestConfiguration::new() + pub static TIMESTAMPS_PASS_BOUNDARIES: GpuTestConfiguration = GpuTestConfiguration::new() .parameters( wgpu_test::TestParameters::default() .limits(wgpu::Limits::downlevel_defaults()) @@ -441,7 +441,7 @@ mod tests { .run_sync(|ctx| test_timestamps(ctx, false, false)); #[gpu_test] - static TIMESTAMPS_ENCODER: GpuTestConfiguration = GpuTestConfiguration::new() + pub static TIMESTAMPS_ENCODER: GpuTestConfiguration = GpuTestConfiguration::new() .parameters( wgpu_test::TestParameters::default() .limits(wgpu::Limits::downlevel_defaults()) @@ -455,7 +455,7 @@ mod tests { .run_sync(|ctx| test_timestamps(ctx, true, false)); #[gpu_test] - static TIMESTAMPS_PASSES: GpuTestConfiguration = GpuTestConfiguration::new() + pub static TIMESTAMPS_PASSES: GpuTestConfiguration = GpuTestConfiguration::new() .parameters( wgpu_test::TestParameters::default() .limits(wgpu::Limits::downlevel_defaults()) diff --git a/examples/features/src/water/mod.rs b/examples/features/src/water/mod.rs index 08b8f57e015..5d1241fce39 100644 --- a/examples/features/src/water/mod.rs +++ b/examples/features/src/water/mod.rs @@ -823,7 +823,7 @@ pub fn main() { #[cfg(test)] #[wgpu_test::gpu_test] -static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { +pub static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTestParams { name: "water", image_path: "/examples/features/src/water/screenshot.png", width: 1024, diff --git a/tests/src/config.rs b/tests/src/config.rs index 62d3e56091b..a73cb821a12 100644 --- a/tests/src/config.rs +++ b/tests/src/config.rs @@ -118,3 +118,5 @@ impl Default for GpuTestConfiguration { Self::new() } } + +pub type GpuTestInitializer = fn() -> GpuTestConfiguration; diff --git a/tests/src/lib.rs b/tests/src/lib.rs index 5c33cf3eeef..b3f65351e4a 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -17,7 +17,7 @@ mod run; pub use init::initialize_html_canvas; pub use self::image::ComparisonType; -pub use config::GpuTestConfiguration; +pub use config::{GpuTestConfiguration, GpuTestInitializer}; #[doc(hidden)] pub use ctor; pub use expectations::{FailureApplicationReasons, FailureBehavior, FailureCase, FailureReason}; @@ -114,17 +114,22 @@ pub fn did_oom(device: &wgpu::Device, callback: impl FnOnce() -> T) -> (bool, } /// Adds the necessary main function for our gpu test harness. +/// +/// Takes a single argument which is an expression that evaluates to `Vec`. #[macro_export] macro_rules! gpu_test_main { - () => { + ($tests: expr) => { #[cfg(target_arch = "wasm32")] wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); #[cfg(target_arch = "wasm32")] - fn main() {} + fn main() { + // Ensure that value is used so that warnings don't happen. + let _ = $tests; + } #[cfg(not(target_arch = "wasm32"))] fn main() -> $crate::native::MainResult { - $crate::native::main() + $crate::native::main($tests) } }; } diff --git a/tests/src/native.rs b/tests/src/native.rs index 4f56c79ada1..be660bb7543 100644 --- a/tests/src/native.rs +++ b/tests/src/native.rs @@ -9,6 +9,7 @@ use parking_lot::Mutex; use crate::{ config::GpuTestConfiguration, params::TestInfo, report::AdapterReport, run::execute_test, + GpuTestInitializer, }; type NativeTestFuture = Pin + Send>>; @@ -76,7 +77,7 @@ pub static TEST_LIST: Mutex> = Mutex::new(Vec:: pub type MainResult = anyhow::Result<()>; /// Main function that runs every gpu function once for every adapter on the system. -pub fn main() -> MainResult { +pub fn main(tests: Vec) -> MainResult { use anyhow::Context; use crate::report::GpuReport; @@ -108,9 +109,9 @@ pub fn main() -> MainResult { report }; - let mut test_guard = TEST_LIST.lock(); // Iterate through all the tests. Creating a test per adapter. - execute_native(test_guard.drain(..).flat_map(|test| { + execute_native(tests.into_iter().flat_map(|initializer| { + let test = initializer(); report .devices .iter() diff --git a/tests/tests/wgpu-gpu/bgra8unorm_storage.rs b/tests/tests/wgpu-gpu/bgra8unorm_storage.rs index eaa549ab6fc..87ae3e62f3d 100644 --- a/tests/tests/wgpu-gpu/bgra8unorm_storage.rs +++ b/tests/tests/wgpu-gpu/bgra8unorm_storage.rs @@ -2,7 +2,11 @@ use std::borrow::Cow; -use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; + +pub fn all_tests(vec: &mut Vec) { + vec.push(BGRA8_UNORM_STORAGE); +} const SHADER_SRC: &str = " @group(0) @binding(0) var tex: texture_storage_2d; diff --git a/tests/tests/wgpu-gpu/bind_group_layout_dedup.rs b/tests/tests/wgpu-gpu/bind_group_layout_dedup.rs index b97b9cff10e..3164367f8b5 100644 --- a/tests/tests/wgpu-gpu/bind_group_layout_dedup.rs +++ b/tests/tests/wgpu-gpu/bind_group_layout_dedup.rs @@ -1,6 +1,19 @@ use std::num::NonZeroU64; -use wgpu_test::{fail, gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + fail, gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + BIND_GROUP_LAYOUT_DEDUPLICATION, + BIND_GROUP_LAYOUT_DEDUPLICATION_WITH_DROPPED_USER_HANDLE, + GET_DERIVED_BGL, + SEPARATE_PIPELINES_HAVE_INCOMPATIBLE_DERIVED_BGLS, + DERIVED_BGLS_INCOMPATIBLE_WITH_REGULAR_BGLS, + BIND_GROUP_LAYOUT_DEDUPLICATION_DERIVED, + ]); +} const SHADER_SRC: &str = " @group(0) @binding(0) diff --git a/tests/tests/wgpu-gpu/bind_groups.rs b/tests/tests/wgpu-gpu/bind_groups.rs index 6dc57c43246..f01d8010f75 100644 --- a/tests/tests/wgpu-gpu/bind_groups.rs +++ b/tests/tests/wgpu-gpu/bind_groups.rs @@ -1,7 +1,19 @@ use std::num::NonZeroU64; use wgpu::{BufferUsages, PollType}; -use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + gpu_test, FailureCase, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + MULTIPLE_BINDINGS_WITH_DIFFERENT_SIZES, + BIND_GROUP_NONFILTERING_LAYOUT_NONFILTERING_SAMPLER, + BIND_GROUP_NONFILTERING_LAYOUT_MIN_SAMPLER, + BIND_GROUP_NONFILTERING_LAYOUT_MAG_SAMPLER, + BIND_GROUP_NONFILTERING_LAYOUT_MIPMAP_SAMPLER, + ]); +} /// Create two bind groups against the same bind group layout, in the same /// compute pass, but against two different shaders that have different binding diff --git a/tests/tests/wgpu-gpu/binding_array/buffers.rs b/tests/tests/wgpu-gpu/binding_array/buffers.rs index 44a53aa39dd..9a9701f12a3 100644 --- a/tests/tests/wgpu-gpu/binding_array/buffers.rs +++ b/tests/tests/wgpu-gpu/binding_array/buffers.rs @@ -1,7 +1,18 @@ use std::num::{NonZeroU32, NonZeroU64}; use wgpu::*; -use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + gpu_test, FailureCase, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(tests: &mut Vec) { + tests.extend([ + BINDING_ARRAY_UNIFORM_BUFFERS, + PARTIAL_BINDING_ARRAY_UNIFORM_BUFFERS, + BINDING_ARRAY_STORAGE_BUFFERS, + PARTIAL_BINDING_ARRAY_STORAGE_BUFFERS, + ]); +} #[gpu_test] static BINDING_ARRAY_UNIFORM_BUFFERS: GpuTestConfiguration = GpuTestConfiguration::new() diff --git a/tests/tests/wgpu-gpu/binding_array/mod.rs b/tests/tests/wgpu-gpu/binding_array/mod.rs index 4b8972fcdb2..753b1101351 100644 --- a/tests/tests/wgpu-gpu/binding_array/mod.rs +++ b/tests/tests/wgpu-gpu/binding_array/mod.rs @@ -2,3 +2,10 @@ mod buffers; mod sampled_textures; mod samplers; mod storage_textures; + +pub fn all_tests(tests: &mut Vec) { + buffers::all_tests(tests); + sampled_textures::all_tests(tests); + samplers::all_tests(tests); + storage_textures::all_tests(tests); +} diff --git a/tests/tests/wgpu-gpu/binding_array/sampled_textures.rs b/tests/tests/wgpu-gpu/binding_array/sampled_textures.rs index 320cf3e1079..c445857a92f 100644 --- a/tests/tests/wgpu-gpu/binding_array/sampled_textures.rs +++ b/tests/tests/wgpu-gpu/binding_array/sampled_textures.rs @@ -2,9 +2,17 @@ use std::num::NonZeroU32; use wgpu::*; use wgpu_test::{ - gpu_test, image::ReadbackBuffers, GpuTestConfiguration, TestParameters, TestingContext, + gpu_test, image::ReadbackBuffers, GpuTestConfiguration, GpuTestInitializer, TestParameters, + TestingContext, }; +pub fn all_tests(tests: &mut Vec) { + tests.extend([ + BINDING_ARRAY_SAMPLED_TEXTURES, + PARTIAL_BINDING_ARRAY_SAMPLED_TEXTURES, + ]); +} + #[gpu_test] static BINDING_ARRAY_SAMPLED_TEXTURES: GpuTestConfiguration = GpuTestConfiguration::new() .parameters( diff --git a/tests/tests/wgpu-gpu/binding_array/samplers.rs b/tests/tests/wgpu-gpu/binding_array/samplers.rs index b0c3cf36fad..636a5487697 100644 --- a/tests/tests/wgpu-gpu/binding_array/samplers.rs +++ b/tests/tests/wgpu-gpu/binding_array/samplers.rs @@ -1,7 +1,13 @@ use std::num::{NonZeroU32, NonZeroU64}; use wgpu::*; -use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(tests: &mut Vec) { + tests.extend([BINDING_ARRAY_SAMPLERS, PARTIAL_BINDING_ARRAY_SAMPLERS]); +} #[gpu_test] static BINDING_ARRAY_SAMPLERS: GpuTestConfiguration = GpuTestConfiguration::new() diff --git a/tests/tests/wgpu-gpu/binding_array/storage_textures.rs b/tests/tests/wgpu-gpu/binding_array/storage_textures.rs index 1118247551d..69cec788c4f 100644 --- a/tests/tests/wgpu-gpu/binding_array/storage_textures.rs +++ b/tests/tests/wgpu-gpu/binding_array/storage_textures.rs @@ -2,10 +2,17 @@ use std::num::NonZeroU32; use wgpu::*; use wgpu_test::{ - gpu_test, image::ReadbackBuffers, FailureCase, GpuTestConfiguration, TestParameters, - TestingContext, + gpu_test, image::ReadbackBuffers, FailureCase, GpuTestConfiguration, GpuTestInitializer, + TestParameters, TestingContext, }; +pub fn all_tests(tests: &mut Vec) { + tests.extend([ + BINDING_ARRAY_STORAGE_TEXTURES, + PARTIAL_BINDING_ARRAY_STORAGE_TEXTURES, + ]); +} + #[gpu_test] static BINDING_ARRAY_STORAGE_TEXTURES: GpuTestConfiguration = GpuTestConfiguration::new() .parameters( diff --git a/tests/tests/wgpu-gpu/buffer.rs b/tests/tests/wgpu-gpu/buffer.rs index 463820d48c2..8992708457e 100644 --- a/tests/tests/wgpu-gpu/buffer.rs +++ b/tests/tests/wgpu-gpu/buffer.rs @@ -1,4 +1,17 @@ -use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + gpu_test, FailureCase, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + EMPTY_BUFFER, + MAP_OFFSET, + MINIMUM_BUFFER_BINDING_SIZE_LAYOUT, + MINIMUM_BUFFER_BINDING_SIZE_DISPATCH, + CLEAR_OFFSET_OUTSIDE_RESOURCE_BOUNDS, + CLEAR_OFFSET_PLUS_SIZE_OUTSIDE_U64_BOUNDS, + ]); +} async fn test_empty_buffer_range(ctx: &TestingContext, buffer_size: u64, label: &str) { let r = wgpu::BufferUsages::MAP_READ; diff --git a/tests/tests/wgpu-gpu/buffer_copy.rs b/tests/tests/wgpu-gpu/buffer_copy.rs index 8968d9227f7..e5d3851a4a3 100644 --- a/tests/tests/wgpu-gpu/buffer_copy.rs +++ b/tests/tests/wgpu-gpu/buffer_copy.rs @@ -2,7 +2,11 @@ use wgpu::BufferAddress; -use wgpu_test::{fail_if, gpu_test, GpuTestConfiguration}; +use wgpu_test::{fail_if, gpu_test, GpuTestConfiguration, GpuTestInitializer}; + +pub fn all_tests(vec: &mut Vec) { + vec.push(COPY_ALIGNMENT); +} fn try_copy( ctx: &wgpu_test::TestingContext, diff --git a/tests/tests/wgpu-gpu/buffer_usages.rs b/tests/tests/wgpu-gpu/buffer_usages.rs index 4c5312e12b9..a5c6fe696ef 100644 --- a/tests/tests/wgpu-gpu/buffer_usages.rs +++ b/tests/tests/wgpu-gpu/buffer_usages.rs @@ -2,7 +2,17 @@ use wgpu::BufferAddress; use wgpu::{BufferUsages as Bu, MapMode as Ma}; -use wgpu_test::{fail_if, gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + fail_if, gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + BUFFER_USAGE, + BUFFER_USAGE_MAPPABLE_PRIMARY_BUFFERS, + BUFFER_MAP_ASYNC_MAP_STATE, + ]); +} const BUFFER_SIZE: BufferAddress = 1234; diff --git a/tests/tests/wgpu-gpu/clear_texture.rs b/tests/tests/wgpu-gpu/clear_texture.rs index 23883b2418c..aee78b2a07e 100644 --- a/tests/tests/wgpu-gpu/clear_texture.rs +++ b/tests/tests/wgpu-gpu/clear_texture.rs @@ -1,8 +1,20 @@ use wgpu_test::{ - gpu_test, image::ReadbackBuffers, FailureCase, GpuTestConfiguration, TestParameters, - TestingContext, + gpu_test, image::ReadbackBuffers, FailureCase, GpuTestConfiguration, GpuTestInitializer, + TestParameters, TestingContext, }; +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + CLEAR_TEXTURE_UNCOMPRESSED_GLES, + CLEAR_TEXTURE_UNCOMPRESSED, + CLEAR_TEXTURE_DEPTH, + CLEAR_TEXTURE_DEPTH32_STENCIL8, + CLEAR_TEXTURE_COMPRESSED_BCN, + CLEAR_TEXTURE_COMPRESSED_ASTC, + CLEAR_TEXTURE_COMPRESSED_ETC2, + ]); +} + static TEXTURE_FORMATS_UNCOMPRESSED_GLES_COMPAT: &[wgpu::TextureFormat] = &[ wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Snorm, diff --git a/tests/tests/wgpu-gpu/clip_distances.rs b/tests/tests/wgpu-gpu/clip_distances.rs index 26961d7e098..3152333e8dd 100644 --- a/tests/tests/wgpu-gpu/clip_distances.rs +++ b/tests/tests/wgpu-gpu/clip_distances.rs @@ -1,4 +1,10 @@ -use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.push(CLIP_DISTANCES); +} #[gpu_test] static CLIP_DISTANCES: GpuTestConfiguration = GpuTestConfiguration::new() diff --git a/tests/tests/wgpu-gpu/cloneable_types.rs b/tests/tests/wgpu-gpu/cloneable_types.rs index b38fbbd2964..eac6edb17e8 100644 --- a/tests/tests/wgpu-gpu/cloneable_types.rs +++ b/tests/tests/wgpu-gpu/cloneable_types.rs @@ -1,4 +1,8 @@ -use wgpu_test::{gpu_test, TestingContext}; +use wgpu_test::{gpu_test, GpuTestInitializer, TestingContext}; + +pub fn all_tests(vec: &mut Vec) { + vec.push(CLONEABLE_BUFFERS); +} #[gpu_test] static CLONEABLE_BUFFERS: GpuTestConfiguration = diff --git a/tests/tests/wgpu-gpu/compute_pass_ownership.rs b/tests/tests/wgpu-gpu/compute_pass_ownership.rs index 168ad8bd789..e988dcc48c3 100644 --- a/tests/tests/wgpu-gpu/compute_pass_ownership.rs +++ b/tests/tests/wgpu-gpu/compute_pass_ownership.rs @@ -4,7 +4,18 @@ use std::num::NonZeroU64; use wgpu::util::DeviceExt as _; -use wgpu_test::{gpu_test, valid, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + gpu_test, valid, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + COMPUTE_PASS_RESOURCE_OWNERSHIP, + COMPUTE_PASS_QUERY_SET_OWNERSHIP_PIPELINE_STATISTICS, + COMPUTE_PASS_QUERY_SET_OWNERSHIP_TIMESTAMPS, + COMPUTE_PASS_KEEP_ENCODER_ALIVE, + ]); +} const SHADER_SRC: &str = " @group(0) @binding(0) diff --git a/tests/tests/wgpu-gpu/device.rs b/tests/tests/wgpu-gpu/device.rs index 53904d2e182..7de961d5063 100644 --- a/tests/tests/wgpu-gpu/device.rs +++ b/tests/tests/wgpu-gpu/device.rs @@ -1,6 +1,28 @@ use std::sync::atomic::AtomicBool; -use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + gpu_test, FailureCase, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + CROSS_DEVICE_BIND_GROUP_USAGE, + DEVICE_DESTROY_THEN_MORE, + DEVICE_DESTROY_THEN_LOST, + DIFFERENT_BGL_ORDER_BW_SHADER_AND_API, + DEVICE_DESTROY_THEN_BUFFER_CLEANUP, + DEVICE_AND_QUEUE_HAVE_DIFFERENT_IDS, + ]); + + #[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))] + { + vec.extend([ + DEVICE_LIFETIME_CHECK, + MULTIPLE_DEVICES, + REQUEST_DEVICE_ERROR_MESSAGE_NATIVE, + ]); + } +} #[gpu_test] static CROSS_DEVICE_BIND_GROUP_USAGE: GpuTestConfiguration = GpuTestConfiguration::new() diff --git a/tests/tests/wgpu-gpu/dispatch_workgroups_indirect.rs b/tests/tests/wgpu-gpu/dispatch_workgroups_indirect.rs index c915abf75ac..9010389b107 100644 --- a/tests/tests/wgpu-gpu/dispatch_workgroups_indirect.rs +++ b/tests/tests/wgpu-gpu/dispatch_workgroups_indirect.rs @@ -1,4 +1,15 @@ -use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + NUM_WORKGROUPS_BUILTIN, + DISCARD_DISPATCH, + RESET_BIND_GROUPS, + ZERO_SIZED_BUFFER, + ]); +} /// Make sure that the num_workgroups builtin works properly (it requires a workaround on D3D12). #[gpu_test] diff --git a/tests/tests/wgpu-gpu/draw_indirect.rs b/tests/tests/wgpu-gpu/draw_indirect.rs index ac88c43bc71..ab2f090980d 100644 --- a/tests/tests/wgpu-gpu/draw_indirect.rs +++ b/tests/tests/wgpu-gpu/draw_indirect.rs @@ -2,7 +2,33 @@ use wgpu::{ util::{BufferInitDescriptor, DeviceExt}, vertex_attr_array, }; -use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend(&[ + DRAW, + DRAW_OOB_START, + DRAW_OOB_COUNT, + INSTANCED_DRAW, + INSTANCED_DRAW_OOB_START, + INSTANCED_DRAW_OOB_COUNT, + INSTANCED_DRAW_OOB_INSTANCE_START, + INSTANCED_DRAW_OOB_INSTANCE_COUNT, + INSTANCED_DRAW_WITH_NON_ZERO_FIRST_INSTANCE, + INSTANCED_DRAW_WITH_NON_ZERO_FIRST_INSTANCE_MISSING_FEATURE, + INDEXED_DRAW, + INDEXED_DRAW_OOB_START, + INDEXED_DRAW_OOB_COUNT, + INSTANCED_INDEXED_DRAW, + INSTANCED_INDEXED_DRAW_OOB_START, + INSTANCED_INDEXED_DRAW_OOB_COUNT, + INSTANCED_INDEXED_DRAW_OOB_INSTANCE_START, + INSTANCED_INDEXED_DRAW_OOB_INSTANCE_COUNT, + INDIRECT_BUFFER_OFFSETS, + ]); +} struct TestData { kind: Kind, diff --git a/tests/tests/wgpu-gpu/dual_source_blending.rs b/tests/tests/wgpu-gpu/dual_source_blending.rs index 997cdd1a32f..3bd55945a37 100644 --- a/tests/tests/wgpu-gpu/dual_source_blending.rs +++ b/tests/tests/wgpu-gpu/dual_source_blending.rs @@ -1,5 +1,14 @@ use wgpu::*; -use wgpu_test::{fail, gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + fail, gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + DUAL_SOURCE_BLENDING_FEATURE_DISABLED, + DUAL_SOURCE_BLENDING_FEATURE_ENABLED, + ]); +} const VERTEX_SHADER: &str = r#" @vertex diff --git a/tests/tests/wgpu-gpu/encoder.rs b/tests/tests/wgpu-gpu/encoder.rs index aa91173130f..699a1280be2 100644 --- a/tests/tests/wgpu-gpu/encoder.rs +++ b/tests/tests/wgpu-gpu/encoder.rs @@ -1,9 +1,19 @@ use wgpu::util::DeviceExt; use wgpu::CommandEncoder; use wgpu_test::{ - fail, gpu_test, FailureCase, GpuTestConfiguration, TestParameters, TestingContext, + fail, gpu_test, FailureCase, GpuTestConfiguration, GpuTestInitializer, TestParameters, + TestingContext, }; +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + DROP_ENCODER, + DROP_QUEUE_BEFORE_CREATING_COMMAND_ENCODER, + DROP_ENCODER_AFTER_ERROR, + ENCODER_OPERATIONS_FAIL_WHILE_PASS_ALIVE, + ]); +} + #[gpu_test] static DROP_ENCODER: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| { let encoder = ctx diff --git a/tests/tests/wgpu-gpu/float32_filterable.rs b/tests/tests/wgpu-gpu/float32_filterable.rs index 5376f924d17..ba623e0bee0 100644 --- a/tests/tests/wgpu-gpu/float32_filterable.rs +++ b/tests/tests/wgpu-gpu/float32_filterable.rs @@ -1,6 +1,13 @@ //! Tests for FLOAT32_FILTERABLE feature. -use wgpu_test::{fail, gpu_test, GpuTestConfiguration, TestParameters}; +use wgpu_test::{fail, gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + FLOAT32_FILTERABLE_WITHOUT_FEATURE, + FLOAT32_FILTERABLE_WITH_FEATURE, + ]); +} fn create_texture_binding(device: &wgpu::Device, format: wgpu::TextureFormat, filterable: bool) { let texture = device.create_texture(&wgpu::TextureDescriptor { diff --git a/tests/tests/wgpu-gpu/image_atomics/mod.rs b/tests/tests/wgpu-gpu/image_atomics/mod.rs index 0063602f4d0..c11d9250ab4 100644 --- a/tests/tests/wgpu-gpu/image_atomics/mod.rs +++ b/tests/tests/wgpu-gpu/image_atomics/mod.rs @@ -2,9 +2,19 @@ use wgpu::ShaderModuleDescriptor; use wgpu_test::{ - fail, gpu_test, image::ReadbackBuffers, GpuTestConfiguration, TestParameters, TestingContext, + fail, gpu_test, image::ReadbackBuffers, GpuTestConfiguration, GpuTestInitializer, + TestParameters, TestingContext, }; +pub fn all_tests(tests: &mut Vec) { + tests.extend([ + IMAGE_64_ATOMICS, + IMAGE_32_ATOMICS, + IMAGE_ATOMICS_NOT_ENABLED, + IMAGE_ATOMICS_NOT_SUPPORTED, + ]); +} + #[gpu_test] static IMAGE_64_ATOMICS: GpuTestConfiguration = GpuTestConfiguration::new() .parameters( diff --git a/tests/tests/wgpu-gpu/instance.rs b/tests/tests/wgpu-gpu/instance.rs index c74b7aedd27..6f882b62586 100644 --- a/tests/tests/wgpu-gpu/instance.rs +++ b/tests/tests/wgpu-gpu/instance.rs @@ -1,4 +1,8 @@ -use wgpu_test::{gpu_test, GpuTestConfiguration}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer}; + +pub fn all_tests(vec: &mut Vec) { + vec.push(INITIALIZE); +} #[gpu_test] static INITIALIZE: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|_ctx| {}); diff --git a/tests/tests/wgpu-gpu/life_cycle.rs b/tests/tests/wgpu-gpu/life_cycle.rs index ff0b90b0247..869f963f2e5 100644 --- a/tests/tests/wgpu-gpu/life_cycle.rs +++ b/tests/tests/wgpu-gpu/life_cycle.rs @@ -1,5 +1,16 @@ use wgpu::{util::DeviceExt, Backends}; -use wgpu_test::{fail, gpu_test, FailureCase, GpuTestConfiguration, TestParameters}; +use wgpu_test::{ + fail, gpu_test, FailureCase, GpuTestConfiguration, GpuTestInitializer, TestParameters, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + BUFFER_DESTROY, + TEXTURE_DESTROY, + BUFFER_DESTROY_BEFORE_SUBMIT, + TEXTURE_DESTROY_BEFORE_SUBMIT, + ]); +} #[gpu_test] static BUFFER_DESTROY: GpuTestConfiguration = diff --git a/tests/tests/wgpu-gpu/main.rs b/tests/tests/wgpu-gpu/main.rs index 2e5462f2e6f..a0785fe44e2 100644 --- a/tests/tests/wgpu-gpu/main.rs +++ b/tests/tests/wgpu-gpu/main.rs @@ -1,14 +1,14 @@ mod regression { - mod issue_3349; - mod issue_3457; - mod issue_4024; - mod issue_4122; - mod issue_4485; - mod issue_4514; - mod issue_5553; - mod issue_6317; - mod issue_6467; - mod issue_6827; + pub mod issue_3349; + pub mod issue_3457; + pub mod issue_4024; + pub mod issue_4122; + pub mod issue_4485; + pub mod issue_4514; + pub mod issue_5553; + pub mod issue_6317; + pub mod issue_6467; + pub mod issue_6827; } mod bgra8unorm_storage; @@ -69,4 +69,76 @@ mod vertex_indices; mod write_texture; mod zero_init_texture_after_discard; -wgpu_test::gpu_test_main!(); +fn all_tests() -> Vec { + let mut tests = Vec::new(); + + bgra8unorm_storage::all_tests(&mut tests); + bind_group_layout_dedup::all_tests(&mut tests); + bind_groups::all_tests(&mut tests); + binding_array::all_tests(&mut tests); + buffer_copy::all_tests(&mut tests); + buffer_usages::all_tests(&mut tests); + buffer::all_tests(&mut tests); + clear_texture::all_tests(&mut tests); + clip_distances::all_tests(&mut tests); + cloneable_types::all_tests(&mut tests); + compute_pass_ownership::all_tests(&mut tests); + device::all_tests(&mut tests); + dispatch_workgroups_indirect::all_tests(&mut tests); + draw_indirect::all_tests(&mut tests); + dual_source_blending::all_tests(&mut tests); + encoder::all_tests(&mut tests); + float32_filterable::all_tests(&mut tests); + image_atomics::all_tests(&mut tests); + instance::all_tests(&mut tests); + life_cycle::all_tests(&mut tests); + mem_leaks::all_tests(&mut tests); + mesh_shader::all_tests(&mut tests); + nv12_texture::all_tests(&mut tests); + occlusion_query::all_tests(&mut tests); + oob_indexing::all_tests(&mut tests); + oom::all_tests(&mut tests); + pipeline_cache::all_tests(&mut tests); + pipeline::all_tests(&mut tests); + poll::all_tests(&mut tests); + push_constants::all_tests(&mut tests); + query_set::all_tests(&mut tests); + queue_transfer::all_tests(&mut tests); + ray_tracing::all_tests(&mut tests); + regression::issue_3349::all_tests(&mut tests); + regression::issue_3457::all_tests(&mut tests); + regression::issue_4024::all_tests(&mut tests); + regression::issue_4122::all_tests(&mut tests); + regression::issue_4485::all_tests(&mut tests); + regression::issue_4514::all_tests(&mut tests); + regression::issue_5553::all_tests(&mut tests); + regression::issue_6317::all_tests(&mut tests); + regression::issue_6467::all_tests(&mut tests); + regression::issue_6827::all_tests(&mut tests); + render_pass_ownership::all_tests(&mut tests); + render_target::all_tests(&mut tests); + resource_descriptor_accessor::all_tests(&mut tests); + resource_error::all_tests(&mut tests); + samplers::all_tests(&mut tests); + scissor_tests::all_tests(&mut tests); + shader_primitive_index::all_tests(&mut tests); + shader_view_format::all_tests(&mut tests); + shader::all_tests(&mut tests); + subgroup_operations::all_tests(&mut tests); + texture_binding::all_tests(&mut tests); + texture_blit::all_tests(&mut tests); + texture_bounds::all_tests(&mut tests); + texture_view_creation::all_tests(&mut tests); + timestamp_normalization::all_tests(&mut tests); + timestamp_query::all_tests(&mut tests); + transfer::all_tests(&mut tests); + transition_resources::all_tests(&mut tests); + vertex_formats::all_tests(&mut tests); + vertex_indices::all_tests(&mut tests); + write_texture::all_tests(&mut tests); + zero_init_texture_after_discard::all_tests(&mut tests); + + tests +} + +wgpu_test::gpu_test_main!(all_tests()); diff --git a/tests/tests/wgpu-gpu/mem_leaks.rs b/tests/tests/wgpu-gpu/mem_leaks.rs index 57df08fc8b3..456b04e8ebb 100644 --- a/tests/tests/wgpu-gpu/mem_leaks.rs +++ b/tests/tests/wgpu-gpu/mem_leaks.rs @@ -1,3 +1,17 @@ +#[allow( + clippy::allow_attributes, + reason = "Using expect is going to be much more verbose" +)] +#[allow(clippy::ptr_arg)] +pub fn all_tests(_vec: &mut Vec) { + #[cfg(any( + not(target_arch = "wasm32"), + target_os = "emscripten", + feature = "webgl" + ))] + _vec.push(SIMPLE_DRAW_CHECK_MEM_LEAKS); +} + #[cfg(any( not(target_arch = "wasm32"), target_os = "emscripten", diff --git a/tests/tests/wgpu-gpu/mesh_shader/mod.rs b/tests/tests/wgpu-gpu/mesh_shader/mod.rs index cd1ca425429..8a0bdf4b80f 100644 --- a/tests/tests/wgpu-gpu/mesh_shader/mod.rs +++ b/tests/tests/wgpu-gpu/mesh_shader/mod.rs @@ -1,7 +1,21 @@ use std::{io::Write, process::Stdio}; use wgpu::util::DeviceExt; -use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(tests: &mut Vec) { + tests.extend([ + MESH_PIPELINE_BASIC_MESH, + MESH_PIPELINE_BASIC_TASK_MESH, + MESH_PIPELINE_BASIC_MESH_FRAG, + MESH_PIPELINE_BASIC_TASK_MESH_FRAG, + MESH_DRAW_INDIRECT, + MESH_MULTI_DRAW_INDIRECT, + MESH_MULTI_DRAW_INDIRECT_COUNT, + ]); +} // Same as in mesh shader example fn compile_glsl( diff --git a/tests/tests/wgpu-gpu/nv12_texture/mod.rs b/tests/tests/wgpu-gpu/nv12_texture/mod.rs index 33fe17e8896..bbe3c450847 100644 --- a/tests/tests/wgpu-gpu/nv12_texture/mod.rs +++ b/tests/tests/wgpu-gpu/nv12_texture/mod.rs @@ -1,6 +1,16 @@ //! Tests for nv12 texture creation and sampling. -use wgpu_test::{fail, gpu_test, GpuTestConfiguration, TestParameters}; +use wgpu_test::{fail, gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; + +pub fn all_tests(tests: &mut Vec) { + tests.extend([ + NV12_TEXTURE_CREATION_SAMPLING, + NV12_TEXTURE_VIEW_PLANE_ON_NON_PLANAR_FORMAT, + NV12_TEXTURE_VIEW_PLANE_OUT_OF_BOUNDS, + NV12_TEXTURE_BAD_FORMAT_VIEW_PLANE, + NV12_TEXTURE_BAD_SIZE, + ]); +} #[gpu_test] static NV12_TEXTURE_CREATION_SAMPLING: GpuTestConfiguration = GpuTestConfiguration::new() diff --git a/tests/tests/wgpu-gpu/occlusion_query/mod.rs b/tests/tests/wgpu-gpu/occlusion_query/mod.rs index cb47ac6981c..a30b0dc5893 100644 --- a/tests/tests/wgpu-gpu/occlusion_query/mod.rs +++ b/tests/tests/wgpu-gpu/occlusion_query/mod.rs @@ -1,5 +1,9 @@ use wgpu::InstanceFlags; -use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters}; +use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, GpuTestInitializer, TestParameters}; + +pub fn all_tests(vec: &mut Vec) { + vec.push(OCCLUSION_QUERY); +} #[gpu_test] static OCCLUSION_QUERY: GpuTestConfiguration = GpuTestConfiguration::new() diff --git a/tests/tests/wgpu-gpu/oob_indexing.rs b/tests/tests/wgpu-gpu/oob_indexing.rs index be5257b7887..c5d323a8114 100644 --- a/tests/tests/wgpu-gpu/oob_indexing.rs +++ b/tests/tests/wgpu-gpu/oob_indexing.rs @@ -1,6 +1,13 @@ use wgpu::{Backend, Backends}; use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters, TestingContext}; +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + RESTRICT_WORKGROUP_PRIVATE_FUNCTION_LET, + D3D12_RESTRICT_DYNAMIC_BUFFERS, + ]); +} + /// Tests that writing and reading to the max length of a container (vec, mat, array) /// in the workgroup, private and function address spaces + let declarations /// will instead write to and read from the last element. diff --git a/tests/tests/wgpu-gpu/oom.rs b/tests/tests/wgpu-gpu/oom.rs index d1889f71a60..c69915b579c 100644 --- a/tests/tests/wgpu-gpu/oom.rs +++ b/tests/tests/wgpu-gpu/oom.rs @@ -5,8 +5,20 @@ use wgpu::{ CreateTlasDescriptor, Error, ErrorFilter, Extent3d, Features, QuerySetDescriptor, QueryType, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages, VertexFormat, }; +use wgpu_test::GpuTestInitializer; use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters}; +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + TEXTURE_OOM_TEST, + BUFFER_OOM_TEST, + MAPPING_BUFFER_OOM_TEST, + QUERY_SET_OOM_TEST, + BLAS_OOM_TEST, + TLAS_OOM_TEST, + ]); +} + // Tests in this file must all end with "OOM_TEST" so that nextest doesn't run any other tests while it runs one of the OOM tests. // This is done so that other tests that create resources will not fail with OOM errors due to the OOM tests running in parallel. diff --git a/tests/tests/wgpu-gpu/pipeline.rs b/tests/tests/wgpu-gpu/pipeline.rs index 8e9c91e5273..5ec40915c6f 100644 --- a/tests/tests/wgpu-gpu/pipeline.rs +++ b/tests/tests/wgpu-gpu/pipeline.rs @@ -1,4 +1,14 @@ -use wgpu_test::{fail, gpu_test, GpuTestConfiguration, TestParameters}; +use wgpu_test::{fail, gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + COMPUTE_PIPELINE_DEFAULT_LAYOUT_BAD_MODULE, + COMPUTE_PIPELINE_DEFAULT_LAYOUT_BAD_BGL_INDEX, + RENDER_PIPELINE_DEFAULT_LAYOUT_BAD_MODULE, + RENDER_PIPELINE_DEFAULT_LAYOUT_BAD_BGL_INDEX, + NO_TARGETLESS_RENDER, + ]); +} const INVALID_SHADER_DESC: wgpu::ShaderModuleDescriptor = wgpu::ShaderModuleDescriptor { label: Some("invalid shader"), diff --git a/tests/tests/wgpu-gpu/pipeline_cache.rs b/tests/tests/wgpu-gpu/pipeline_cache.rs index 0149c336203..2d66f99d9bc 100644 --- a/tests/tests/wgpu-gpu/pipeline_cache.rs +++ b/tests/tests/wgpu-gpu/pipeline_cache.rs @@ -2,6 +2,10 @@ use std::{fmt::Write, num::NonZeroU64}; use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; +pub fn all_tests(vec: &mut Vec) { + vec.push(PIPELINE_CACHE); +} + /// We want to test that using a pipeline cache doesn't cause failure /// /// It would be nice if we could also assert that reusing a pipeline cache would make compilation diff --git a/tests/tests/wgpu-gpu/poll.rs b/tests/tests/wgpu-gpu/poll.rs index cb93efb3034..15a4db54e95 100644 --- a/tests/tests/wgpu-gpu/poll.rs +++ b/tests/tests/wgpu-gpu/poll.rs @@ -6,7 +6,18 @@ use wgpu::{ CommandEncoderDescriptor, ComputePassDescriptor, PollType, ShaderStages, }; -use wgpu_test::{gpu_test, GpuTestConfiguration, TestingContext}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer, TestingContext}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + WAIT, + DOUBLE_WAIT, + WAIT_ON_SUBMISSION, + DOUBLE_WAIT_ON_SUBMISSION, + WAIT_OUT_OF_ORDER, + WAIT_AFTER_BAD_SUBMISSION, + ]); +} fn generate_dummy_work(ctx: &TestingContext) -> CommandBuffer { let buffer = ctx.device.create_buffer(&BufferDescriptor { diff --git a/tests/tests/wgpu-gpu/push_constants.rs b/tests/tests/wgpu-gpu/push_constants.rs index b3119442f73..f1fb0f8c660 100644 --- a/tests/tests/wgpu-gpu/push_constants.rs +++ b/tests/tests/wgpu-gpu/push_constants.rs @@ -3,7 +3,13 @@ use std::num::NonZeroU64; use wgpu::util::RenderEncoder; use wgpu::*; -use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([PARTIAL_UPDATE, RENDER_PASS_TEST]); +} /// We want to test that partial updates to push constants work as expected. /// diff --git a/tests/tests/wgpu-gpu/query_set.rs b/tests/tests/wgpu-gpu/query_set.rs index 69d0f868dbf..4858560dda8 100644 --- a/tests/tests/wgpu-gpu/query_set.rs +++ b/tests/tests/wgpu-gpu/query_set.rs @@ -1,4 +1,8 @@ -use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; + +pub fn all_tests(vec: &mut Vec) { + vec.push(DROP_FAILED_TIMESTAMP_QUERY_SET); +} #[gpu_test] static DROP_FAILED_TIMESTAMP_QUERY_SET: GpuTestConfiguration = GpuTestConfiguration::new() diff --git a/tests/tests/wgpu-gpu/queue_transfer.rs b/tests/tests/wgpu-gpu/queue_transfer.rs index 8ad4dee7a30..7397568cd95 100644 --- a/tests/tests/wgpu-gpu/queue_transfer.rs +++ b/tests/tests/wgpu-gpu/queue_transfer.rs @@ -1,7 +1,15 @@ //! Tests for buffer copy validation. use wgpu::PollType; -use wgpu_test::{fail, gpu_test, GpuTestConfiguration}; +use wgpu_test::{fail, gpu_test, GpuTestConfiguration, GpuTestInitializer}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + QUEUE_WRITE_TEXTURE_THEN_DESTROY, + QUEUE_WRITE_TEXTURE_OVERFLOW, + QUEUE_WRITE_TEXTURE_BUFFER_OOB, + ]); +} #[gpu_test] static QUEUE_WRITE_TEXTURE_THEN_DESTROY: GpuTestConfiguration = GpuTestConfiguration::new() diff --git a/tests/tests/wgpu-gpu/ray_tracing/as_build.rs b/tests/tests/wgpu-gpu/ray_tracing/as_build.rs index 2ba80294c92..558bc626537 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/as_build.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/as_build.rs @@ -3,7 +3,29 @@ use std::iter; use crate::ray_tracing::{acceleration_structure_limits, AsBuildContext}; use wgpu::util::{BufferInitDescriptor, DeviceExt}; use wgpu::*; -use wgpu_test::{fail, fail_if, gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + fail, fail_if, gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters, + TestingContext, +}; + +pub fn all_tests(tests: &mut Vec) { + tests.extend([ + UNBUILT_BLAS, + UNBUILT_BLAS_COMPACTION, + BLAS_COMPACTION_WITHOUT_FLAGS, + UNPREPARED_BLAS_COMPACTION, + BLAS_COMPACTION, + OUT_OF_ORDER_AS_BUILD, + OUT_OF_ORDER_AS_BUILD_USE, + EMPTY_BUILD, + BUILD_WITH_TRANSFORM, + ONLY_BLAS_VERTEX_RETURN, + ONLY_TLAS_VERTEX_RETURN, + EXTRA_FORMAT_BUILD, + MISALIGNED_BUILD, + TOO_SMALL_STRIDE_BUILD, + ]); +} #[gpu_test] static UNBUILT_BLAS: GpuTestConfiguration = GpuTestConfiguration::new() diff --git a/tests/tests/wgpu-gpu/ray_tracing/as_create.rs b/tests/tests/wgpu-gpu/ray_tracing/as_create.rs index 703e6e5f689..76ccbc9d8c3 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/as_create.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/as_create.rs @@ -8,6 +8,10 @@ use wgpu::{IndexFormat, VertexFormat}; use wgpu_macros::gpu_test; use wgpu_test::{fail, GpuTestConfiguration, TestParameters, TestingContext}; +pub fn all_tests(tests: &mut Vec) { + tests.extend([BLAS_INVALID_VERTEX_FORMAT, BLAS_MISMATCHED_INDEX]); +} + #[gpu_test] static BLAS_INVALID_VERTEX_FORMAT: GpuTestConfiguration = GpuTestConfiguration::new() .parameters( diff --git a/tests/tests/wgpu-gpu/ray_tracing/as_use_after_free.rs b/tests/tests/wgpu-gpu/ray_tracing/as_use_after_free.rs index 8a090b47063..970f28d2115 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/as_use_after_free.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/as_use_after_free.rs @@ -13,6 +13,10 @@ use wgpu::{ use wgpu_macros::gpu_test; use wgpu_test::{GpuTestConfiguration, TestParameters, TestingContext}; +pub fn all_tests(tests: &mut Vec) { + tests.push(ACCELERATION_STRUCTURE_USE_AFTER_FREE); +} + fn required_features() -> wgpu::Features { wgpu::Features::EXPERIMENTAL_RAY_QUERY } diff --git a/tests/tests/wgpu-gpu/ray_tracing/limits.rs b/tests/tests/wgpu-gpu/ray_tracing/limits.rs index 172c5818af1..d8448eec62e 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/limits.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/limits.rs @@ -10,6 +10,10 @@ use wgpu::{ use wgpu_macros::gpu_test; use wgpu_test::{fail, GpuTestConfiguration, TestParameters, TestingContext}; +pub fn all_tests(tests: &mut Vec) { + tests.push(LIMITS_HIT); +} + #[gpu_test] static LIMITS_HIT: GpuTestConfiguration = GpuTestConfiguration::new() .parameters( diff --git a/tests/tests/wgpu-gpu/ray_tracing/mod.rs b/tests/tests/wgpu-gpu/ray_tracing/mod.rs index b72b3466ca7..4ae2bbd9b0e 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/mod.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/mod.rs @@ -18,6 +18,15 @@ mod limits; mod scene; mod shader; +pub fn all_tests(tests: &mut Vec) { + as_build::all_tests(tests); + as_create::all_tests(tests); + as_use_after_free::all_tests(tests); + limits::all_tests(tests); + scene::all_tests(tests); + shader::all_tests(tests); +} + fn acceleration_structure_limits() -> wgpu::Limits { wgpu::Limits::default().using_minimum_supported_acceleration_structure_values() } diff --git a/tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs b/tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs index e258a828103..45cf7924d02 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs @@ -9,6 +9,13 @@ use glam::{Affine3A, Quat, Vec3}; mod mesh_gen; +pub fn all_tests(tests: &mut Vec) { + tests.extend([ + ACCELERATION_STRUCTURE_BUILD_NO_INDEX, + ACCELERATION_STRUCTURE_BUILD_WITH_INDEX, + ]); +} + fn acceleration_structure_build(ctx: &TestingContext, use_index_buffer: bool) { let max_instances = 1000; let device = &ctx.device; diff --git a/tests/tests/wgpu-gpu/ray_tracing/shader.rs b/tests/tests/wgpu-gpu/ray_tracing/shader.rs index d7fb7b0158a..fcd29af52e6 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/shader.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/shader.rs @@ -5,10 +5,15 @@ use wgpu::{ }; use wgpu::{AccelerationStructureFlags, BufferUsages}; use wgpu_macros::gpu_test; +use wgpu_test::GpuTestInitializer; use wgpu_test::{GpuTestConfiguration, TestParameters, TestingContext}; const STRUCT_SIZE: wgpu::BufferAddress = 176; +pub fn all_tests(tests: &mut Vec) { + tests.push(ACCESS_ALL_STRUCT_MEMBERS); +} + #[gpu_test] static ACCESS_ALL_STRUCT_MEMBERS: GpuTestConfiguration = GpuTestConfiguration::new() .parameters( diff --git a/tests/tests/wgpu-gpu/regression/issue_3349.rs b/tests/tests/wgpu-gpu/regression/issue_3349.rs index 14629636a3f..adee4eb6527 100644 --- a/tests/tests/wgpu-gpu/regression/issue_3349.rs +++ b/tests/tests/wgpu-gpu/regression/issue_3349.rs @@ -1,8 +1,13 @@ use wgpu::util::DeviceExt; use wgpu_test::{ - gpu_test, image::ReadbackBuffers, GpuTestConfiguration, TestParameters, TestingContext, + gpu_test, image::ReadbackBuffers, GpuTestConfiguration, GpuTestInitializer, TestParameters, + TestingContext, }; +pub fn all_tests(vec: &mut Vec) { + vec.push(MULTI_STAGE_DATA_BINDING); +} + /// We thought we had an OpenGL bug that, when running without explicit in-shader locations, /// we will not properly bind uniform buffers to both the vertex and fragment /// shaders. This turned out to not reproduce at all with this test case. diff --git a/tests/tests/wgpu-gpu/regression/issue_3457.rs b/tests/tests/wgpu-gpu/regression/issue_3457.rs index e71e97d844b..1a84ecba32c 100644 --- a/tests/tests/wgpu-gpu/regression/issue_3457.rs +++ b/tests/tests/wgpu-gpu/regression/issue_3457.rs @@ -1,7 +1,11 @@ -use wgpu_test::{gpu_test, GpuTestConfiguration}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer}; use wgpu::*; +pub fn all_tests(vec: &mut Vec) { + vec.push(PASS_RESET_VERTEX_BUFFER); +} + /// The core issue here was that we weren't properly disabling vertex attributes on GL /// when a renderpass ends. This ended up being rather tricky to test for as GL is remarkably /// tolerant of errors. This test, with the fix not-applied, only fails on WebGL. diff --git a/tests/tests/wgpu-gpu/regression/issue_4024.rs b/tests/tests/wgpu-gpu/regression/issue_4024.rs index 1541f0500ac..8e648813d6d 100644 --- a/tests/tests/wgpu-gpu/regression/issue_4024.rs +++ b/tests/tests/wgpu-gpu/regression/issue_4024.rs @@ -1,10 +1,14 @@ use std::sync::Arc; use parking_lot::Mutex; -use wgpu_test::{gpu_test, GpuTestConfiguration}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer}; use wgpu::*; +pub fn all_tests(vec: &mut Vec) { + vec.push(QUEUE_SUBMITTED_CALLBACK_ORDERING); +} + /// The WebGPU specification has very specific requirements about the ordering of map_async /// and on_submitted_work_done callbacks. Specifically, all map_async callbacks that are initiated /// before a given on_submitted_work_done callback must be invoked before the on_submitted_work_done diff --git a/tests/tests/wgpu-gpu/regression/issue_4122.rs b/tests/tests/wgpu-gpu/regression/issue_4122.rs index 27b66e1ae0f..f59897a19d0 100644 --- a/tests/tests/wgpu-gpu/regression/issue_4122.rs +++ b/tests/tests/wgpu-gpu/regression/issue_4122.rs @@ -1,6 +1,12 @@ use std::ops::Range; -use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.push(CLEAR_BUFFER_RANGE_RESPECTED); +} async fn fill_test(ctx: &TestingContext, range: Range, size: u64) -> bool { let gpu_buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor { diff --git a/tests/tests/wgpu-gpu/regression/issue_4485.rs b/tests/tests/wgpu-gpu/regression/issue_4485.rs index 9d6c83955fa..aa6e27bfebc 100644 --- a/tests/tests/wgpu-gpu/regression/issue_4485.rs +++ b/tests/tests/wgpu-gpu/regression/issue_4485.rs @@ -1,4 +1,10 @@ -use wgpu_test::{gpu_test, image, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + gpu_test, image, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.push(CONTINUE_SWITCH); +} /// FXC doesn't accept `continue` inside a switch. Instead we store a flag for whether /// the loop should continue that is checked after the switch. diff --git a/tests/tests/wgpu-gpu/regression/issue_4514.rs b/tests/tests/wgpu-gpu/regression/issue_4514.rs index b523dcd330b..8eb9b436fae 100644 --- a/tests/tests/wgpu-gpu/regression/issue_4514.rs +++ b/tests/tests/wgpu-gpu/regression/issue_4514.rs @@ -1,4 +1,10 @@ -use wgpu_test::{gpu_test, image, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + gpu_test, image, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.push(DEGENERATE_SWITCH); +} /// FXC and potentially some glsl consumers have a bug when handling switch statements on a constant /// with just a default case. (not sure if the constant part is relevant) diff --git a/tests/tests/wgpu-gpu/regression/issue_5553.rs b/tests/tests/wgpu-gpu/regression/issue_5553.rs index 01ffb59d1a2..b9f99612166 100644 --- a/tests/tests/wgpu-gpu/regression/issue_5553.rs +++ b/tests/tests/wgpu-gpu/regression/issue_5553.rs @@ -1,7 +1,11 @@ -use wgpu_test::{gpu_test, GpuTestConfiguration}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer}; use wgpu::*; +pub fn all_tests(vec: &mut Vec) { + vec.push(ALLOW_INPUT_NOT_CONSUMED); +} + /// Previously, for every user-defined vertex output a fragment shader had to have a corresponding /// user-defined input. This would generate `StageError::InputNotConsumed`. /// diff --git a/tests/tests/wgpu-gpu/regression/issue_6317.rs b/tests/tests/wgpu-gpu/regression/issue_6317.rs index 20945006f74..e955d2a5aa6 100644 --- a/tests/tests/wgpu-gpu/regression/issue_6317.rs +++ b/tests/tests/wgpu-gpu/regression/issue_6317.rs @@ -1,6 +1,10 @@ use wgpu::{DownlevelFlags, Limits}; use wgpu_macros::gpu_test; -use wgpu_test::{fail, GpuTestConfiguration, TestParameters}; +use wgpu_test::{fail, GpuTestConfiguration, GpuTestInitializer, TestParameters}; + +pub fn all_tests(vec: &mut Vec) { + vec.push(NON_FATAL_ERRORS_IN_QUEUE_SUBMIT); +} #[gpu_test] static NON_FATAL_ERRORS_IN_QUEUE_SUBMIT: GpuTestConfiguration = GpuTestConfiguration::new() diff --git a/tests/tests/wgpu-gpu/regression/issue_6467.rs b/tests/tests/wgpu-gpu/regression/issue_6467.rs index 75ccc43a993..9458eb51126 100644 --- a/tests/tests/wgpu-gpu/regression/issue_6467.rs +++ b/tests/tests/wgpu-gpu/regression/issue_6467.rs @@ -1,5 +1,9 @@ use wgpu::util::DeviceExt; -use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; + +pub fn all_tests(vec: &mut Vec) { + vec.push(ZERO_WORKGROUP_COUNT); +} /// Running a compute shader with a total workgroup count of zero implies that no work /// should be done, and is a user error. Vulkan and DX12 accept this invalid input with grace, but diff --git a/tests/tests/wgpu-gpu/regression/issue_6827.rs b/tests/tests/wgpu-gpu/regression/issue_6827.rs index 2cb1bbd0392..af29947285e 100644 --- a/tests/tests/wgpu-gpu/regression/issue_6827.rs +++ b/tests/tests/wgpu-gpu/regression/issue_6827.rs @@ -1,6 +1,12 @@ use std::sync::Arc; -use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + gpu_test, FailureCase, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(tests: &mut Vec) { + tests.extend([TEST_SINGLE_WRITE, TEST_SCATTER]); +} #[gpu_test] static TEST_SINGLE_WRITE: GpuTestConfiguration = GpuTestConfiguration::new() diff --git a/tests/tests/wgpu-gpu/render_pass_ownership.rs b/tests/tests/wgpu-gpu/render_pass_ownership.rs index e3574e3760b..c803c765307 100644 --- a/tests/tests/wgpu-gpu/render_pass_ownership.rs +++ b/tests/tests/wgpu-gpu/render_pass_ownership.rs @@ -12,7 +12,18 @@ use std::num::NonZeroU64; use wgpu::util::DeviceExt as _; -use wgpu_test::{gpu_test, valid, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + gpu_test, valid, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + RENDER_PASS_RESOURCE_OWNERSHIP, + RENDER_PASS_QUERY_SET_OWNERSHIP_PIPELINE_STATISTICS, + RENDER_PASS_QUERY_SET_OWNERSHIP_TIMESTAMPS, + RENDER_PASS_KEEP_ENCODER_ALIVE, + ]); +} // Minimal shader with buffer based side effect - only needed to check whether the render pass has executed at all. const SHADER_SRC: &str = " diff --git a/tests/tests/wgpu-gpu/render_target.rs b/tests/tests/wgpu-gpu/render_target.rs index 9c4723b6af1..9e69e805d8e 100644 --- a/tests/tests/wgpu-gpu/render_target.rs +++ b/tests/tests/wgpu-gpu/render_target.rs @@ -2,7 +2,19 @@ use wgpu::{ util::{BufferInitDescriptor, DeviceExt}, vertex_attr_array, }; -use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + DRAW_TO_2D_VIEW, + DRAW_TO_2D_ARRAY_VIEW, + RESOLVE_TO_2D_VIEW, + RESOLVE_TO_2D_ARRAY_VIEW, + DRAW_TO_3D_VIEW, + ]); +} #[gpu_test] static DRAW_TO_2D_VIEW: GpuTestConfiguration = GpuTestConfiguration::new() diff --git a/tests/tests/wgpu-gpu/resource_descriptor_accessor.rs b/tests/tests/wgpu-gpu/resource_descriptor_accessor.rs index ee984da60e4..88472739e9e 100644 --- a/tests/tests/wgpu-gpu/resource_descriptor_accessor.rs +++ b/tests/tests/wgpu-gpu/resource_descriptor_accessor.rs @@ -1,4 +1,8 @@ -use wgpu_test::{gpu_test, GpuTestConfiguration}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer}; + +pub fn all_tests(vec: &mut Vec) { + vec.push(BUFFER_SIZE_AND_USAGE); +} #[gpu_test] static BUFFER_SIZE_AND_USAGE: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| { diff --git a/tests/tests/wgpu-gpu/resource_error.rs b/tests/tests/wgpu-gpu/resource_error.rs index d071053ebd1..eb8390b904d 100644 --- a/tests/tests/wgpu-gpu/resource_error.rs +++ b/tests/tests/wgpu-gpu/resource_error.rs @@ -1,4 +1,8 @@ -use wgpu_test::{fail, gpu_test, valid, GpuTestConfiguration}; +use wgpu_test::{fail, gpu_test, valid, GpuTestConfiguration, GpuTestInitializer}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([BAD_BUFFER, BAD_TEXTURE]); +} #[gpu_test] static BAD_BUFFER: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| { diff --git a/tests/tests/wgpu-gpu/samplers.rs b/tests/tests/wgpu-gpu/samplers.rs index adb49d067eb..40b984d21f7 100644 --- a/tests/tests/wgpu-gpu/samplers.rs +++ b/tests/tests/wgpu-gpu/samplers.rs @@ -2,7 +2,19 @@ //! //! Do some tests to ensure things are working correctly and nothing gets mad. -use wgpu_test::{did_oom, gpu_test, valid, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + did_oom, gpu_test, valid, GpuTestConfiguration, GpuTestInitializer, TestParameters, + TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + SAMPLER_DEDUPLICATION, + SAMPLER_CREATION_FAILURE, + SAMPLER_SINGLE_BIND_GROUP, + SAMPLER_MULTI_BIND_GROUP, + ]); +} // A number large enough to likely cause sampler caches to run out of space // on some devices. diff --git a/tests/tests/wgpu-gpu/scissor_tests/mod.rs b/tests/tests/wgpu-gpu/scissor_tests/mod.rs index ab958daf312..14b81eb4337 100644 --- a/tests/tests/wgpu-gpu/scissor_tests/mod.rs +++ b/tests/tests/wgpu-gpu/scissor_tests/mod.rs @@ -1,4 +1,13 @@ -use wgpu_test::{gpu_test, image, GpuTestConfiguration, TestingContext}; +use wgpu_test::{gpu_test, image, GpuTestConfiguration, GpuTestInitializer, TestingContext}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + SCISSOR_TEST_FULL_RECT, + SCISSOR_TEST_EMPTY_RECT, + SCISSOR_TEST_EMPTY_RECT_WITH_OFFSET, + SCISSOR_TEST_CUSTOM_RECT, + ]); +} struct Rect { x: u32, diff --git a/tests/tests/wgpu-gpu/shader/array_size_overrides.rs b/tests/tests/wgpu-gpu/shader/array_size_overrides.rs index a39db5d17c7..d1756660d1f 100644 --- a/tests/tests/wgpu-gpu/shader/array_size_overrides.rs +++ b/tests/tests/wgpu-gpu/shader/array_size_overrides.rs @@ -3,6 +3,10 @@ use wgpu::util::DeviceExt; use wgpu::{BufferDescriptor, BufferUsages, MapMode, PollType}; use wgpu_test::{fail_if, gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; +pub fn all_tests(vec: &mut Vec) { + vec.push(ARRAY_SIZE_OVERRIDES); +} + const SHADER: &str = r#" const testing_shared: array = array(8); override n = testing_shared[0u]; diff --git a/tests/tests/wgpu-gpu/shader/compilation_messages/mod.rs b/tests/tests/wgpu-gpu/shader/compilation_messages/mod.rs index 09000205a24..c641565ad9a 100644 --- a/tests/tests/wgpu-gpu/shader/compilation_messages/mod.rs +++ b/tests/tests/wgpu-gpu/shader/compilation_messages/mod.rs @@ -1,6 +1,10 @@ use wgpu::include_wgsl; -use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([SHADER_COMPILE_SUCCESS, SHADER_COMPILE_ERROR]); +} #[gpu_test] static SHADER_COMPILE_SUCCESS: GpuTestConfiguration = GpuTestConfiguration::new() diff --git a/tests/tests/wgpu-gpu/shader/data_builtins.rs b/tests/tests/wgpu-gpu/shader/data_builtins.rs index f6f24f32419..d17691b9425 100644 --- a/tests/tests/wgpu-gpu/shader/data_builtins.rs +++ b/tests/tests/wgpu-gpu/shader/data_builtins.rs @@ -1,7 +1,11 @@ use wgpu::{DownlevelFlags, Limits}; use crate::shader::{shader_input_output_test, InputStorageType, ShaderTest}; -use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([UNPACK4xU8, UNPACK4xI8, PACK4xU8, PACK4xI8]); +} #[allow(non_snake_case)] fn create_unpack4xU8_test() -> Vec { diff --git a/tests/tests/wgpu-gpu/shader/mod.rs b/tests/tests/wgpu-gpu/shader/mod.rs index 15d4c5e5cf7..44928cf439b 100644 --- a/tests/tests/wgpu-gpu/shader/mod.rs +++ b/tests/tests/wgpu-gpu/shader/mod.rs @@ -13,7 +13,7 @@ use wgpu::{ ShaderModuleDescriptor, ShaderSource, ShaderStages, }; -use wgpu_test::TestingContext; +use wgpu_test::{GpuTestInitializer, TestingContext}; pub mod array_size_overrides; pub mod compilation_messages; @@ -23,6 +23,16 @@ pub mod struct_layout; pub mod workgroup_size_overrides; pub mod zero_init_workgroup_mem; +pub fn all_tests(tests: &mut Vec) { + array_size_overrides::all_tests(tests); + compilation_messages::all_tests(tests); + data_builtins::all_tests(tests); + numeric_builtins::all_tests(tests); + struct_layout::all_tests(tests); + workgroup_size_overrides::all_tests(tests); + zero_init_workgroup_mem::all_tests(tests); +} + #[derive(Clone, Copy, PartialEq)] enum InputStorageType { Uniform, diff --git a/tests/tests/wgpu-gpu/shader/numeric_builtins.rs b/tests/tests/wgpu-gpu/shader/numeric_builtins.rs index bbdd379ba0d..1416f9b378a 100644 --- a/tests/tests/wgpu-gpu/shader/numeric_builtins.rs +++ b/tests/tests/wgpu-gpu/shader/numeric_builtins.rs @@ -1,7 +1,16 @@ use wgpu::{DownlevelFlags, Limits}; use crate::shader::{shader_input_output_test, InputStorageType, ShaderTest}; -use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + NUMERIC_BUILTINS, + INT64_ATOMIC_MIN_MAX, + INT64_ATOMIC_ALL_OPS, + FLOAT32_ATOMIC, + ]); +} fn create_numeric_builtin_test() -> Vec { let mut tests = Vec::new(); diff --git a/tests/tests/wgpu-gpu/shader/struct_layout.rs b/tests/tests/wgpu-gpu/shader/struct_layout.rs index e9378f4012d..8cb4501af5d 100644 --- a/tests/tests/wgpu-gpu/shader/struct_layout.rs +++ b/tests/tests/wgpu-gpu/shader/struct_layout.rs @@ -3,7 +3,20 @@ use std::fmt::Write; use wgpu::{Backends, DownlevelFlags, Features, Limits}; use crate::shader::{shader_input_output_test, InputStorageType, ShaderTest, MAX_BUFFER_SIZE}; -use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters}; +use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, GpuTestInitializer, TestParameters}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + UNIFORM_INPUT, + STORAGE_INPUT, + PUSH_CONSTANT_INPUT, + UNIFORM_INPUT_INT64, + STORAGE_INPUT_INT64, + PUSH_CONSTANT_INPUT_INT64, + UNIFORM_INPUT_F16, + STORAGE_INPUT_F16, + ]); +} #[gpu_test] static UNIFORM_INPUT: GpuTestConfiguration = GpuTestConfiguration::new() diff --git a/tests/tests/wgpu-gpu/shader/workgroup_size_overrides.rs b/tests/tests/wgpu-gpu/shader/workgroup_size_overrides.rs index d61760707f0..a3de36c5201 100644 --- a/tests/tests/wgpu-gpu/shader/workgroup_size_overrides.rs +++ b/tests/tests/wgpu-gpu/shader/workgroup_size_overrides.rs @@ -3,6 +3,10 @@ use wgpu::util::DeviceExt; use wgpu::{BufferDescriptor, BufferUsages, MapMode, PollType}; use wgpu_test::{fail_if, gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; +pub fn all_tests(vec: &mut Vec) { + vec.push(WORKGROUP_SIZE_OVERRIDES); +} + const SHADER: &str = r#" override n = 3; diff --git a/tests/tests/wgpu-gpu/shader/zero_init_workgroup_mem.rs b/tests/tests/wgpu-gpu/shader/zero_init_workgroup_mem.rs index 1aaf7341d17..fd9ed467df9 100644 --- a/tests/tests/wgpu-gpu/shader/zero_init_workgroup_mem.rs +++ b/tests/tests/wgpu-gpu/shader/zero_init_workgroup_mem.rs @@ -8,7 +8,11 @@ use wgpu::{ ShaderStages, }; -use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; + +pub fn all_tests(vec: &mut Vec) { + vec.push(ZERO_INIT_WORKGROUP_MEMORY); +} #[gpu_test] static ZERO_INIT_WORKGROUP_MEMORY: GpuTestConfiguration = GpuTestConfiguration::new() diff --git a/tests/tests/wgpu-gpu/shader_primitive_index/mod.rs b/tests/tests/wgpu-gpu/shader_primitive_index/mod.rs index 83832c01d7e..eb6e6fa1d23 100644 --- a/tests/tests/wgpu-gpu/shader_primitive_index/mod.rs +++ b/tests/tests/wgpu-gpu/shader_primitive_index/mod.rs @@ -1,6 +1,10 @@ use wgpu::util::DeviceExt; use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; +pub fn all_tests(vec: &mut Vec) { + vec.extend([DRAW, DRAW_INDEXED]); +} + // // These tests render two triangles to a 2x2 render target. The first triangle // in the vertex buffer covers the bottom-left pixel, the second triangle diff --git a/tests/tests/wgpu-gpu/shader_view_format/mod.rs b/tests/tests/wgpu-gpu/shader_view_format/mod.rs index 849e050b855..d17f0e67572 100644 --- a/tests/tests/wgpu-gpu/shader_view_format/mod.rs +++ b/tests/tests/wgpu-gpu/shader_view_format/mod.rs @@ -1,6 +1,10 @@ use wgpu::{util::DeviceExt, DownlevelFlags, Limits, TextureFormat}; use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; +pub fn all_tests(vec: &mut Vec) { + vec.push(REINTERPRET_SRGB); +} + #[gpu_test] static REINTERPRET_SRGB: GpuTestConfiguration = GpuTestConfiguration::new() .parameters( diff --git a/tests/tests/wgpu-gpu/subgroup_operations/mod.rs b/tests/tests/wgpu-gpu/subgroup_operations/mod.rs index 7e50ea5051b..41f444da80a 100644 --- a/tests/tests/wgpu-gpu/subgroup_operations/mod.rs +++ b/tests/tests/wgpu-gpu/subgroup_operations/mod.rs @@ -1,6 +1,10 @@ use std::num::NonZeroU64; -use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; + +pub fn all_tests(vec: &mut Vec) { + vec.push(SUBGROUP_OPERATIONS); +} const THREAD_COUNT: u64 = 128; const TEST_COUNT: u32 = 37; diff --git a/tests/tests/wgpu-gpu/texture_binding/mod.rs b/tests/tests/wgpu-gpu/texture_binding/mod.rs index 74be773a6f1..4f154c36277 100644 --- a/tests/tests/wgpu-gpu/texture_binding/mod.rs +++ b/tests/tests/wgpu-gpu/texture_binding/mod.rs @@ -7,7 +7,11 @@ use wgpu::{ TextureDescriptor, TextureDimension, TextureFormat, TextureUsages, }; use wgpu_macros::gpu_test; -use wgpu_test::{GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([TEXTURE_BINDING, SINGLE_SCALAR_LOAD]); +} #[gpu_test] static TEXTURE_BINDING: GpuTestConfiguration = GpuTestConfiguration::new() diff --git a/tests/tests/wgpu-gpu/texture_blit.rs b/tests/tests/wgpu-gpu/texture_blit.rs index 6cc30cdaecd..e93587710d6 100644 --- a/tests/tests/wgpu-gpu/texture_blit.rs +++ b/tests/tests/wgpu-gpu/texture_blit.rs @@ -1,4 +1,11 @@ -use wgpu_test::{gpu_test, GpuTestConfiguration}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + TEXTURE_BLIT_WITH_LINEAR_FILTER_TEST, + TEXTURE_BLIT_WITH_NEAREST_FILTER_TEST, + ]); +} #[gpu_test] static TEXTURE_BLIT_WITH_LINEAR_FILTER_TEST: GpuTestConfiguration = GpuTestConfiguration::new() diff --git a/tests/tests/wgpu-gpu/texture_bounds.rs b/tests/tests/wgpu-gpu/texture_bounds.rs index 01e34d1317e..2f330294a9a 100644 --- a/tests/tests/wgpu-gpu/texture_bounds.rs +++ b/tests/tests/wgpu-gpu/texture_bounds.rs @@ -2,6 +2,10 @@ use wgpu_test::{fail_if, gpu_test, GpuTestConfiguration}; +pub fn all_tests(vec: &mut Vec) { + vec.push(BAD_COPY_ORIGIN_TEST); +} + #[gpu_test] static BAD_COPY_ORIGIN_TEST: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| { let try_origin = |origin, size, should_panic| { diff --git a/tests/tests/wgpu-gpu/texture_view_creation.rs b/tests/tests/wgpu-gpu/texture_view_creation.rs index d6880fb6203..82d9fd91f9f 100644 --- a/tests/tests/wgpu-gpu/texture_view_creation.rs +++ b/tests/tests/wgpu-gpu/texture_view_creation.rs @@ -1,5 +1,13 @@ use wgpu::*; -use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters}; +use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, GpuTestInitializer, TestParameters}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + STENCIL_ONLY_VIEW_CREATION, + DEPTH_ONLY_VIEW_CREATION, + SHARED_USAGE_VIEW_CREATION, + ]); +} #[gpu_test] static STENCIL_ONLY_VIEW_CREATION: GpuTestConfiguration = GpuTestConfiguration::new() diff --git a/tests/tests/wgpu-gpu/timestamp_normalization/mod.rs b/tests/tests/wgpu-gpu/timestamp_normalization/mod.rs index 95adf51c882..9c793028c2f 100644 --- a/tests/tests/wgpu-gpu/timestamp_normalization/mod.rs +++ b/tests/tests/wgpu-gpu/timestamp_normalization/mod.rs @@ -1 +1,5 @@ mod utils; + +pub fn all_tests(tests: &mut Vec) { + utils::all_tests(tests); +} diff --git a/tests/tests/wgpu-gpu/timestamp_normalization/utils.rs b/tests/tests/wgpu-gpu/timestamp_normalization/utils.rs index b68e2e0f6fd..e0cadc58327 100644 --- a/tests/tests/wgpu-gpu/timestamp_normalization/utils.rs +++ b/tests/tests/wgpu-gpu/timestamp_normalization/utils.rs @@ -8,6 +8,10 @@ use nanorand::Rng; use wgpu::{util::DeviceExt, Limits}; use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; +pub fn all_tests(vec: &mut Vec) { + vec.extend([U64_MUL_U32, SHIFT_RIGHT_U96]); +} + #[repr(C)] #[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)] struct Uint96(u32, u32, u32); diff --git a/tests/tests/wgpu-gpu/timestamp_query.rs b/tests/tests/wgpu-gpu/timestamp_query.rs index ed2ae8d9277..08e29c54635 100644 --- a/tests/tests/wgpu-gpu/timestamp_query.rs +++ b/tests/tests/wgpu-gpu/timestamp_query.rs @@ -2,7 +2,13 @@ use wgpu::{ util::DeviceExt, ComputePassTimestampWrites, Features, InstanceFlags, QUERY_RESOLVE_BUFFER_ALIGNMENT, }; -use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters, TestingContext}; +use wgpu_test::{ + gpu_test, FailureCase, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.push(TIMESTAMP_QUERY); +} const SHADER: &str = r#" @compute @workgroup_size(1) diff --git a/tests/tests/wgpu-gpu/transfer.rs b/tests/tests/wgpu-gpu/transfer.rs index cce4b0f7d60..bb37218b29a 100644 --- a/tests/tests/wgpu-gpu/transfer.rs +++ b/tests/tests/wgpu-gpu/transfer.rs @@ -1,4 +1,8 @@ -use wgpu_test::{fail, gpu_test, GpuTestConfiguration}; +use wgpu_test::{fail, gpu_test, GpuTestConfiguration, GpuTestInitializer}; + +pub fn all_tests(vec: &mut Vec) { + vec.push(COPY_OVERFLOW_Z); +} #[gpu_test] static COPY_OVERFLOW_Z: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| { diff --git a/tests/tests/wgpu-gpu/transition_resources.rs b/tests/tests/wgpu-gpu/transition_resources.rs index 5ae8f9a2725..11f9a04b385 100644 --- a/tests/tests/wgpu-gpu/transition_resources.rs +++ b/tests/tests/wgpu-gpu/transition_resources.rs @@ -1,4 +1,8 @@ -use wgpu_test::{gpu_test, GpuTestConfiguration}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer}; + +pub fn all_tests(vec: &mut Vec) { + vec.push(TRANSITION_RESOURCES); +} #[gpu_test] static TRANSITION_RESOURCES: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| { diff --git a/tests/tests/wgpu-gpu/vertex_formats/mod.rs b/tests/tests/wgpu-gpu/vertex_formats/mod.rs index f63bc2d695e..88f7659307e 100644 --- a/tests/tests/wgpu-gpu/vertex_formats/mod.rs +++ b/tests/tests/wgpu-gpu/vertex_formats/mod.rs @@ -6,6 +6,10 @@ use wgpu::util::{BufferInitDescriptor, DeviceExt}; use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters, TestingContext}; +pub fn all_tests(vec: &mut Vec) { + vec.extend([VERTEX_FORMATS_ALL, VERTEX_FORMATS_10_10_10_2]); +} + #[derive(Debug, Copy, Clone)] enum TestCase { UnormsAndSnorms, diff --git a/tests/tests/wgpu-gpu/vertex_indices/mod.rs b/tests/tests/wgpu-gpu/vertex_indices/mod.rs index 709380ff342..6d53e960829 100644 --- a/tests/tests/wgpu-gpu/vertex_indices/mod.rs +++ b/tests/tests/wgpu-gpu/vertex_indices/mod.rs @@ -11,6 +11,10 @@ use wgpu::util::{BufferInitDescriptor, DeviceExt, RenderEncoder}; use wgpu::RenderBundleDescriptor; use wgpu_test::{gpu_test, GpuTestConfiguration, TestParameters, TestingContext}; +pub fn all_tests(vec: &mut Vec) { + vec.push(VERTEX_INDICES); +} + /// Generic struct representing a draw call struct Draw { vertex: Range, diff --git a/tests/tests/wgpu-gpu/write_texture.rs b/tests/tests/wgpu-gpu/write_texture.rs index c02042c78bb..5ec343259b0 100644 --- a/tests/tests/wgpu-gpu/write_texture.rs +++ b/tests/tests/wgpu-gpu/write_texture.rs @@ -1,7 +1,16 @@ //! Tests for texture copy use wgpu::*; -use wgpu_test::{gpu_test, GpuTestConfiguration}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + WRITE_TEXTURE_SUBSET_2D, + WRITE_TEXTURE_SUBSET_3D, + WRITE_TEXTURE_NO_OOB, + WRITE_TEXTURE_VIA_STAGING_BUFFER, + ]); +} #[gpu_test] static WRITE_TEXTURE_SUBSET_2D: GpuTestConfiguration = diff --git a/tests/tests/wgpu-gpu/zero_init_texture_after_discard.rs b/tests/tests/wgpu-gpu/zero_init_texture_after_discard.rs index fa3f70023a2..5d52b6e982a 100644 --- a/tests/tests/wgpu-gpu/zero_init_texture_after_discard.rs +++ b/tests/tests/wgpu-gpu/zero_init_texture_after_discard.rs @@ -1,9 +1,18 @@ use wgpu::*; use wgpu_test::{ - gpu_test, image::ReadbackBuffers, FailureCase, GpuTestConfiguration, TestParameters, - TestingContext, + gpu_test, image::ReadbackBuffers, FailureCase, GpuTestConfiguration, GpuTestInitializer, + TestParameters, TestingContext, }; +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + DISCARDING_COLOR_TARGET_RESETS_TEXTURE_INIT_STATE_CHECK_VISIBLE_ON_COPY_AFTER_SUBMIT, + DISCARDING_COLOR_TARGET_RESETS_TEXTURE_INIT_STATE_CHECK_VISIBLE_ON_COPY_IN_SAME_ENCODER, + DISCARDING_DEPTH_TARGET_RESETS_TEXTURE_INIT_STATE_CHECK_VISIBLE_ON_COPY_IN_SAME_ENCODER, + DISCARDING_EITHER_DEPTH_OR_STENCIL_ASPECT_TEST, + ]); +} + // Checks if discarding a color target resets its init state, causing a zero read of this texture when copied in after submit of the encoder. #[gpu_test] static DISCARDING_COLOR_TARGET_RESETS_TEXTURE_INIT_STATE_CHECK_VISIBLE_ON_COPY_AFTER_SUBMIT: diff --git a/wgpu-macros/src/lib.rs b/wgpu-macros/src/lib.rs index ffda346108b..eeafca5de60 100644 --- a/wgpu-macros/src/lib.rs +++ b/wgpu-macros/src/lib.rs @@ -9,29 +9,27 @@ use syn::Ident; #[proc_macro_attribute] pub fn gpu_test(_attr: TokenStream, item: TokenStream) -> TokenStream { let input_static = syn::parse_macro_input!(item as syn::ItemStatic); + let vis = input_static.vis; let expr = &input_static.expr; let ident = &input_static.ident; let ident_str = ident.to_string(); let ident_lower = ident_str.to_snake_case(); - let register_test_name = Ident::new(&format!("{ident_lower}_initializer"), ident.span()); + let register_test_name = Ident::new(&format!("{ident}"), ident.span()); let test_name_webgl = Ident::new(&format!("{ident_lower}_webgl"), ident.span()); quote! { - #[cfg(not(target_arch = "wasm32"))] - #[::wgpu_test::ctor::ctor(crate_path = ::wgpu_test::ctor)] - fn #register_test_name() { + #[allow(non_snake_case)] + #vis fn #register_test_name() -> ::wgpu_test::GpuTestConfiguration { struct S; - ::wgpu_test::native::TEST_LIST.lock().push( - // Allow any type that can be converted to a GpuTestConfiguration - ::wgpu_test::GpuTestConfiguration::from(#expr).name_from_init_function_typename::(#ident_lower) - ) + // Allow any type that can be converted to a GpuTestConfiguration + ::wgpu_test::GpuTestConfiguration::from(#expr).name_from_init_function_typename::(#ident_lower) } #[cfg(target_arch = "wasm32")] #[wasm_bindgen_test::wasm_bindgen_test] - async fn #test_name_webgl() { + #vis async fn #test_name_webgl() { struct S; // Allow any type that can be converted to a GpuTestConfiguration From 3e153fb8eca178f6df76c253d0998d48bc061a03 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Mon, 14 Jul 2025 00:27:13 -0400 Subject: [PATCH 088/303] Label no-op supporting tests --- naga/tests/naga/example_wgsl.rs | 2 +- naga/tests/naga/snapshots.rs | 9 +- player/tests/player/main.rs | 2 +- tests/tests/wgpu-compile/main.rs | 1 + .../tests/wgpu-gpu/bind_group_layout_dedup.rs | 36 +++- tests/tests/wgpu-gpu/bind_groups.rs | 11 +- tests/tests/wgpu-gpu/buffer.rs | 124 ++++++------- tests/tests/wgpu-gpu/buffer_copy.rs | 88 +++++----- tests/tests/wgpu-gpu/buffer_usages.rs | 34 ++-- tests/tests/wgpu-gpu/cloneable_types.rs | 7 +- .../tests/wgpu-gpu/compute_pass_ownership.rs | 6 +- tests/tests/wgpu-gpu/device.rs | 24 ++- .../wgpu-gpu/dispatch_workgroups_indirect.rs | 5 +- tests/tests/wgpu-gpu/draw_indirect.rs | 14 +- tests/tests/wgpu-gpu/dual_source_blending.rs | 8 +- tests/tests/wgpu-gpu/encoder.rs | 36 ++-- tests/tests/wgpu-gpu/float32_filterable.rs | 8 +- tests/tests/wgpu-gpu/image_atomics/mod.rs | 4 +- tests/tests/wgpu-gpu/instance.rs | 6 +- tests/tests/wgpu-gpu/life_cycle.rs | 18 +- tests/tests/wgpu-gpu/mem_leaks.rs | 3 +- tests/tests/wgpu-gpu/nv12_texture/mod.rs | 30 +++- tests/tests/wgpu-gpu/pipeline.rs | 18 +- tests/tests/wgpu-gpu/poll.rs | 42 +++-- tests/tests/wgpu-gpu/query_set.rs | 2 +- tests/tests/wgpu-gpu/queue_transfer.rs | 8 +- tests/tests/wgpu-gpu/ray_tracing/as_build.rs | 27 ++- tests/tests/wgpu-gpu/ray_tracing/as_create.rs | 6 +- tests/tests/wgpu-gpu/ray_tracing/limits.rs | 3 +- tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs | 6 +- tests/tests/wgpu-gpu/regression/issue_3457.rs | 7 +- tests/tests/wgpu-gpu/regression/issue_4024.rs | 3 +- tests/tests/wgpu-gpu/regression/issue_4122.rs | 2 +- tests/tests/wgpu-gpu/regression/issue_4485.rs | 2 +- tests/tests/wgpu-gpu/regression/issue_4514.rs | 2 +- tests/tests/wgpu-gpu/regression/issue_5553.rs | 7 +- tests/tests/wgpu-gpu/regression/issue_6317.rs | 3 +- tests/tests/wgpu-gpu/regression/issue_6467.rs | 6 +- tests/tests/wgpu-gpu/render_pass_ownership.rs | 6 +- .../wgpu-gpu/resource_descriptor_accessor.rs | 30 ++-- tests/tests/wgpu-gpu/resource_error.rs | 124 ++++++------- tests/tests/wgpu-gpu/samplers.rs | 10 +- .../shader/compilation_messages/mod.rs | 4 +- tests/tests/wgpu-gpu/texture_binding/mod.rs | 3 +- tests/tests/wgpu-gpu/texture_blit.rs | 4 +- tests/tests/wgpu-gpu/texture_bounds.rs | 164 +++++++++--------- tests/tests/wgpu-gpu/texture_view_creation.rs | 14 +- tests/tests/wgpu-gpu/transfer.rs | 130 +++++++------- tests/tests/wgpu-gpu/transition_resources.rs | 62 +++---- tests/tests/wgpu-gpu/write_texture.rs | 7 +- 50 files changed, 682 insertions(+), 496 deletions(-) diff --git a/naga/tests/naga/example_wgsl.rs b/naga/tests/naga/example_wgsl.rs index d9c642a1c54..2e1062d7b67 100644 --- a/naga/tests/naga/example_wgsl.rs +++ b/naga/tests/naga/example_wgsl.rs @@ -6,7 +6,7 @@ use std::{ffi::OsStr, fs, path::Path}; /// Runs through all example shaders and ensures they are valid wgsl. // While we _can_ run this test under miri, it is extremely slow (>5 minutes), // and naga isn't the primary target for miri testing, so we disable it. -#[cfg(not(miri))] +#[cfg_attr(miri, ignore)] #[test] pub fn parse_example_wgsl() { let example_path = Path::new(env!("CARGO_MANIFEST_DIR")) diff --git a/naga/tests/naga/snapshots.rs b/naga/tests/naga/snapshots.rs index 37a068d2709..e2288eee918 100644 --- a/naga/tests/naga/snapshots.rs +++ b/naga/tests/naga/snapshots.rs @@ -820,7 +820,8 @@ fn write_output_wgsl( // While we _can_ run this test under miri, it is extremely slow (>5 minutes), // and naga isn't the primary target for miri testing, so we disable it. -#[cfg(all(feature = "wgsl-in", not(miri)))] +#[cfg(feature = "wgsl-in")] +#[cfg_attr(miri, ignore)] #[test] fn convert_snapshots_wgsl() { let _ = env_logger::try_init(); @@ -846,7 +847,8 @@ fn convert_snapshots_wgsl() { } // miri doesn't allow us to shell out to `spirv-as` -#[cfg(all(feature = "spv-in", not(miri)))] +#[cfg(feature = "spv-in")] +#[cfg_attr(miri, ignore)] #[test] fn convert_snapshots_spv() { use std::process::Command; @@ -897,7 +899,8 @@ fn convert_snapshots_spv() { // While we _can_ run this test under miri, it is extremely slow (>5 minutes), // and naga isn't the primary target for miri testing, so we disable it. -#[cfg(all(feature = "glsl-in", not(miri)))] +#[cfg(feature = "glsl-in")] +#[cfg_attr(miri, ignore)] #[allow(unused_variables)] #[test] fn convert_snapshots_glsl() { diff --git a/player/tests/player/main.rs b/player/tests/player/main.rs index ca0e728aec0..1e16c3f0359 100644 --- a/player/tests/player/main.rs +++ b/player/tests/player/main.rs @@ -245,7 +245,7 @@ impl Corpus { } } -#[cfg(not(miri))] +#[cfg_attr(miri, ignore)] #[test] fn test_api() { env_logger::init(); diff --git a/tests/tests/wgpu-compile/main.rs b/tests/tests/wgpu-compile/main.rs index e435171c4a7..a5edfa73b45 100644 --- a/tests/tests/wgpu-compile/main.rs +++ b/tests/tests/wgpu-compile/main.rs @@ -1,6 +1,7 @@ #![cfg(not(miri))] // Tests that ensure that various constructs that should not compile do not compile. +#[cfg_attr(miri, ignore)] #[test] fn compile_fail() { let t = trybuild::TestCases::new(); diff --git a/tests/tests/wgpu-gpu/bind_group_layout_dedup.rs b/tests/tests/wgpu-gpu/bind_group_layout_dedup.rs index 3164367f8b5..ee91b907b0d 100644 --- a/tests/tests/wgpu-gpu/bind_group_layout_dedup.rs +++ b/tests/tests/wgpu-gpu/bind_group_layout_dedup.rs @@ -40,7 +40,11 @@ const ENTRY: wgpu::BindGroupLayoutEntry = wgpu::BindGroupLayoutEntry { #[gpu_test] static BIND_GROUP_LAYOUT_DEDUPLICATION: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().test_features_limits()) + .parameters( + TestParameters::default() + .test_features_limits() + .enable_noop(), + ) .run_async(bgl_dedupe); async fn bgl_dedupe(ctx: TestingContext) { @@ -120,7 +124,11 @@ async fn bgl_dedupe(ctx: TestingContext) { #[gpu_test] static BIND_GROUP_LAYOUT_DEDUPLICATION_WITH_DROPPED_USER_HANDLE: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().test_features_limits()) + .parameters( + TestParameters::default() + .test_features_limits() + .enable_noop(), + ) .run_sync(bgl_dedupe_with_dropped_user_handle); // https://github.com/gfx-rs/wgpu/issues/4824 @@ -203,7 +211,11 @@ fn bgl_dedupe_with_dropped_user_handle(ctx: TestingContext) { #[gpu_test] static GET_DERIVED_BGL: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().test_features_limits()) + .parameters( + TestParameters::default() + .test_features_limits() + .enable_noop(), + ) .run_sync(get_derived_bgl); fn get_derived_bgl(ctx: TestingContext) { @@ -277,7 +289,11 @@ fn get_derived_bgl(ctx: TestingContext) { #[gpu_test] static SEPARATE_PIPELINES_HAVE_INCOMPATIBLE_DERIVED_BGLS: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().test_features_limits()) + .parameters( + TestParameters::default() + .test_features_limits() + .enable_noop(), + ) .run_sync(separate_pipelines_have_incompatible_derived_bgls); fn separate_pipelines_have_incompatible_derived_bgls(ctx: TestingContext) { @@ -341,7 +357,11 @@ fn separate_pipelines_have_incompatible_derived_bgls(ctx: TestingContext) { #[gpu_test] static DERIVED_BGLS_INCOMPATIBLE_WITH_REGULAR_BGLS: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().test_features_limits()) + .parameters( + TestParameters::default() + .test_features_limits() + .enable_noop(), + ) .run_sync(derived_bgls_incompatible_with_regular_bgls); fn derived_bgls_incompatible_with_regular_bgls(ctx: TestingContext) { @@ -412,7 +432,11 @@ fn derived_bgls_incompatible_with_regular_bgls(ctx: TestingContext) { #[gpu_test] static BIND_GROUP_LAYOUT_DEDUPLICATION_DERIVED: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().test_features_limits()) + .parameters( + TestParameters::default() + .test_features_limits() + .enable_noop(), + ) .run_sync(bgl_dedupe_derived); fn bgl_dedupe_derived(ctx: TestingContext) { diff --git a/tests/tests/wgpu-gpu/bind_groups.rs b/tests/tests/wgpu-gpu/bind_groups.rs index f01d8010f75..c8b0acad57f 100644 --- a/tests/tests/wgpu-gpu/bind_groups.rs +++ b/tests/tests/wgpu-gpu/bind_groups.rs @@ -176,14 +176,15 @@ static MULTIPLE_BINDINGS_WITH_DIFFERENT_SIZES: GpuTestConfiguration = GpuTestCon .parameters( TestParameters::default() .limits(wgpu::Limits::downlevel_defaults()) - .expect_fail(FailureCase::always()), // https://github.com/gfx-rs/wgpu/issues/7359 + .expect_fail(FailureCase::always()) + .enable_noop(), // https://github.com/gfx-rs/wgpu/issues/7359 ) .run_sync(multiple_bindings_with_differing_sizes); #[gpu_test] static BIND_GROUP_NONFILTERING_LAYOUT_NONFILTERING_SAMPLER: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { try_sampler_nonfiltering_layout( ctx, @@ -201,7 +202,7 @@ static BIND_GROUP_NONFILTERING_LAYOUT_NONFILTERING_SAMPLER: GpuTestConfiguration #[gpu_test] static BIND_GROUP_NONFILTERING_LAYOUT_MIN_SAMPLER: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { try_sampler_nonfiltering_layout( ctx, @@ -219,7 +220,7 @@ static BIND_GROUP_NONFILTERING_LAYOUT_MIN_SAMPLER: GpuTestConfiguration = #[gpu_test] static BIND_GROUP_NONFILTERING_LAYOUT_MAG_SAMPLER: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { try_sampler_nonfiltering_layout( ctx, @@ -237,7 +238,7 @@ static BIND_GROUP_NONFILTERING_LAYOUT_MAG_SAMPLER: GpuTestConfiguration = #[gpu_test] static BIND_GROUP_NONFILTERING_LAYOUT_MIPMAP_SAMPLER: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { try_sampler_nonfiltering_layout( ctx, diff --git a/tests/tests/wgpu-gpu/buffer.rs b/tests/tests/wgpu-gpu/buffer.rs index 8992708457e..3ae848ed529 100644 --- a/tests/tests/wgpu-gpu/buffer.rs +++ b/tests/tests/wgpu-gpu/buffer.rs @@ -95,78 +95,84 @@ async fn test_empty_buffer_range(ctx: &TestingContext, buffer_size: u64, label: #[gpu_test] static EMPTY_BUFFER: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().expect_fail(FailureCase::always())) + .parameters( + TestParameters::default() + .expect_fail(FailureCase::always()) + .enable_noop(), + ) .run_async(|ctx| async move { test_empty_buffer_range(&ctx, 2048, "regular buffer").await; test_empty_buffer_range(&ctx, 0, "zero-sized buffer").await; }); #[gpu_test] -static MAP_OFFSET: GpuTestConfiguration = GpuTestConfiguration::new().run_async(|ctx| async move { - // This test writes 16 bytes at the beginning of buffer mapped mapped with - // an offset of 32 bytes. Then the buffer is copied into another buffer that - // is read back and we check that the written bytes are correctly placed at - // offset 32..48. - // The goal is to check that get_mapped_range did not accidentally double-count - // the mapped offset. - - let write_buf = ctx.device.create_buffer(&wgpu::BufferDescriptor { - label: None, - size: 256, - usage: wgpu::BufferUsages::MAP_WRITE | wgpu::BufferUsages::COPY_SRC, - mapped_at_creation: false, - }); - let read_buf = ctx.device.create_buffer(&wgpu::BufferDescriptor { - label: None, - size: 256, - usage: wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::COPY_DST, - mapped_at_creation: false, - }); - - write_buf - .slice(32..) - .map_async(wgpu::MapMode::Write, move |result| { - result.unwrap(); +static MAP_OFFSET: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_async(|ctx| async move { + // This test writes 16 bytes at the beginning of buffer mapped mapped with + // an offset of 32 bytes. Then the buffer is copied into another buffer that + // is read back and we check that the written bytes are correctly placed at + // offset 32..48. + // The goal is to check that get_mapped_range did not accidentally double-count + // the mapped offset. + + let write_buf = ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 256, + usage: wgpu::BufferUsages::MAP_WRITE | wgpu::BufferUsages::COPY_SRC, + mapped_at_creation: false, + }); + let read_buf = ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 256, + usage: wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false, }); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + write_buf + .slice(32..) + .map_async(wgpu::MapMode::Write, move |result| { + result.unwrap(); + }); - { - let slice = write_buf.slice(32..48); - let mut view = slice.get_mapped_range_mut(); - for byte in &mut view[..] { - *byte = 2; + ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + + { + let slice = write_buf.slice(32..48); + let mut view = slice.get_mapped_range_mut(); + for byte in &mut view[..] { + *byte = 2; + } } - } - write_buf.unmap(); + write_buf.unmap(); - let mut encoder = ctx - .device - .create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + let mut encoder = ctx + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); - encoder.copy_buffer_to_buffer(&write_buf, 0, &read_buf, 0, 256); + encoder.copy_buffer_to_buffer(&write_buf, 0, &read_buf, 0, 256); - ctx.queue.submit(Some(encoder.finish())); + ctx.queue.submit(Some(encoder.finish())); - read_buf - .slice(..) - .map_async(wgpu::MapMode::Read, Result::unwrap); + read_buf + .slice(..) + .map_async(wgpu::MapMode::Read, Result::unwrap); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); - let slice = read_buf.slice(..); - let view = slice.get_mapped_range(); - for byte in &view[0..32] { - assert_eq!(*byte, 0); - } - for byte in &view[32..48] { - assert_eq!(*byte, 2); - } - for byte in &view[48..] { - assert_eq!(*byte, 0); - } -}); + let slice = read_buf.slice(..); + let view = slice.get_mapped_range(); + for byte in &view[0..32] { + assert_eq!(*byte, 0); + } + for byte in &view[32..48] { + assert_eq!(*byte, 2); + } + for byte in &view[48..] { + assert_eq!(*byte, 0); + } + }); /// The WebGPU algorithm [validating shader binding][vsb] requires /// implementations to check that buffer bindings are large enough to @@ -177,7 +183,7 @@ static MAP_OFFSET: GpuTestConfiguration = GpuTestConfiguration::new().run_async( /// 16 for that variable's group/index. Pipeline creation should fail. #[gpu_test] static MINIMUM_BUFFER_BINDING_SIZE_LAYOUT: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().test_features_limits()) + .parameters(TestParameters::default().test_features_limits().enable_noop()) .run_sync(|ctx| { // Create a shader module that statically uses a storage buffer. let shader_module = ctx @@ -247,7 +253,7 @@ static MINIMUM_BUFFER_BINDING_SIZE_LAYOUT: GpuTestConfiguration = GpuTestConfigu /// binding. Command recording should fail. #[gpu_test] static MINIMUM_BUFFER_BINDING_SIZE_DISPATCH: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().test_features_limits()) + .parameters(TestParameters::default().test_features_limits().enable_noop()) .run_sync(|ctx| { // This test tries to use a bindgroup layout with a // min_binding_size of 16 to an index whose WGSL type requires 32 @@ -344,7 +350,7 @@ static MINIMUM_BUFFER_BINDING_SIZE_DISPATCH: GpuTestConfiguration = GpuTestConfi #[gpu_test] static CLEAR_OFFSET_OUTSIDE_RESOURCE_BOUNDS: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { let size = 16; @@ -370,7 +376,7 @@ static CLEAR_OFFSET_OUTSIDE_RESOURCE_BOUNDS: GpuTestConfiguration = GpuTestConfi #[gpu_test] static CLEAR_OFFSET_PLUS_SIZE_OUTSIDE_U64_BOUNDS: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { let buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor { label: None, diff --git a/tests/tests/wgpu-gpu/buffer_copy.rs b/tests/tests/wgpu-gpu/buffer_copy.rs index e5d3851a4a3..a3091d21681 100644 --- a/tests/tests/wgpu-gpu/buffer_copy.rs +++ b/tests/tests/wgpu-gpu/buffer_copy.rs @@ -2,7 +2,7 @@ use wgpu::BufferAddress; -use wgpu_test::{fail_if, gpu_test, GpuTestConfiguration, GpuTestInitializer}; +use wgpu_test::{fail_if, gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; pub fn all_tests(vec: &mut Vec) { vec.push(COPY_ALIGNMENT); @@ -26,49 +26,51 @@ fn try_copy( } #[gpu_test] -static COPY_ALIGNMENT: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| { - try_copy(&ctx, 0, 0, None); - try_copy( - &ctx, - 4, - 16 + 1, - Some("copy size 17 does not respect `copy_buffer_alignment`"), - ); - try_copy( - &ctx, - 64, - 20 + 2, - Some("copy size 22 does not respect `copy_buffer_alignment`"), - ); - try_copy( - &ctx, - 256, - 44 + 3, - Some("copy size 47 does not respect `copy_buffer_alignment`"), - ); - try_copy(&ctx, 1024, 8 + 4, None); +static COPY_ALIGNMENT: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_sync(|ctx| { + try_copy(&ctx, 0, 0, None); + try_copy( + &ctx, + 4, + 16 + 1, + Some("copy size 17 does not respect `copy_buffer_alignment`"), + ); + try_copy( + &ctx, + 64, + 20 + 2, + Some("copy size 22 does not respect `copy_buffer_alignment`"), + ); + try_copy( + &ctx, + 256, + 44 + 3, + Some("copy size 47 does not respect `copy_buffer_alignment`"), + ); + try_copy(&ctx, 1024, 8 + 4, None); - try_copy(&ctx, 0, 4, None); - try_copy( - &ctx, - 4 + 1, - 8, - Some("buffer offset 5 is not aligned to block size or `copy_buffer_alignment`"), - ); - try_copy( - &ctx, - 64 + 2, - 12, - Some("buffer offset 66 is not aligned to block size or `copy_buffer_alignment`"), - ); - try_copy( - &ctx, - 256 + 3, - 16, - Some("buffer offset 259 is not aligned to block size or `copy_buffer_alignment`"), - ); - try_copy(&ctx, 1024 + 4, 4, None); -}); + try_copy(&ctx, 0, 4, None); + try_copy( + &ctx, + 4 + 1, + 8, + Some("buffer offset 5 is not aligned to block size or `copy_buffer_alignment`"), + ); + try_copy( + &ctx, + 64 + 2, + 12, + Some("buffer offset 66 is not aligned to block size or `copy_buffer_alignment`"), + ); + try_copy( + &ctx, + 256 + 3, + 16, + Some("buffer offset 259 is not aligned to block size or `copy_buffer_alignment`"), + ); + try_copy(&ctx, 1024 + 4, 4, None); + }); const BUFFER_SIZE: BufferAddress = 1234; diff --git a/tests/tests/wgpu-gpu/buffer_usages.rs b/tests/tests/wgpu-gpu/buffer_usages.rs index a5c6fe696ef..f4ee67bafaf 100644 --- a/tests/tests/wgpu-gpu/buffer_usages.rs +++ b/tests/tests/wgpu-gpu/buffer_usages.rs @@ -59,20 +59,26 @@ fn try_create(ctx: TestingContext, usages: &[(bool, &[wgpu::BufferUsages])]) { } #[gpu_test] -static BUFFER_USAGE: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| { - try_create( - ctx, - &[ - (false, ALWAYS_VALID), - (true, NEEDS_MAPPABLE_PRIMARY_BUFFERS), - (true, ALWAYS_FAIL), - ], - ); -}); +static BUFFER_USAGE: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_sync(|ctx| { + try_create( + ctx, + &[ + (false, ALWAYS_VALID), + (true, NEEDS_MAPPABLE_PRIMARY_BUFFERS), + (true, ALWAYS_FAIL), + ], + ); + }); #[gpu_test] static BUFFER_USAGE_MAPPABLE_PRIMARY_BUFFERS: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().features(wgpu::Features::MAPPABLE_PRIMARY_BUFFERS)) + .parameters( + TestParameters::default() + .features(wgpu::Features::MAPPABLE_PRIMARY_BUFFERS) + .enable_noop(), + ) .run_sync(|ctx| { try_create( ctx, @@ -169,7 +175,11 @@ async fn map_test( #[gpu_test] static BUFFER_MAP_ASYNC_MAP_STATE: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().features(wgpu::Features::MAPPABLE_PRIMARY_BUFFERS)) + .parameters( + TestParameters::default() + .features(wgpu::Features::MAPPABLE_PRIMARY_BUFFERS) + .enable_noop(), + ) .run_async(move |ctx| async move { for usage_type in ["invalid", "read", "write"] { for map_mode_type in [Ma::Read, Ma::Write] { diff --git a/tests/tests/wgpu-gpu/cloneable_types.rs b/tests/tests/wgpu-gpu/cloneable_types.rs index eac6edb17e8..cf09d24fffa 100644 --- a/tests/tests/wgpu-gpu/cloneable_types.rs +++ b/tests/tests/wgpu-gpu/cloneable_types.rs @@ -1,12 +1,13 @@ -use wgpu_test::{gpu_test, GpuTestInitializer, TestingContext}; +use wgpu_test::{gpu_test, GpuTestInitializer, TestParameters, TestingContext}; pub fn all_tests(vec: &mut Vec) { vec.push(CLONEABLE_BUFFERS); } #[gpu_test] -static CLONEABLE_BUFFERS: GpuTestConfiguration = - wgpu_test::GpuTestConfiguration::new().run_sync(cloneable_buffers); +static CLONEABLE_BUFFERS: GpuTestConfiguration = wgpu_test::GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_sync(cloneable_buffers); // Test a basic case of cloneable types where you clone the buffer to be able // to access the buffer inside the callback as well as outside. diff --git a/tests/tests/wgpu-gpu/compute_pass_ownership.rs b/tests/tests/wgpu-gpu/compute_pass_ownership.rs index e988dcc48c3..2903a517ce5 100644 --- a/tests/tests/wgpu-gpu/compute_pass_ownership.rs +++ b/tests/tests/wgpu-gpu/compute_pass_ownership.rs @@ -175,7 +175,11 @@ async fn compute_pass_query_set_ownership_timestamps(ctx: TestingContext) { #[gpu_test] static COMPUTE_PASS_KEEP_ENCODER_ALIVE: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().test_features_limits()) + .parameters( + TestParameters::default() + .test_features_limits() + .enable_noop(), + ) .run_async(compute_pass_keep_encoder_alive); async fn compute_pass_keep_encoder_alive(ctx: TestingContext) { diff --git a/tests/tests/wgpu-gpu/device.rs b/tests/tests/wgpu-gpu/device.rs index 7de961d5063..002ce316a21 100644 --- a/tests/tests/wgpu-gpu/device.rs +++ b/tests/tests/wgpu-gpu/device.rs @@ -26,7 +26,11 @@ pub fn all_tests(vec: &mut Vec) { #[gpu_test] static CROSS_DEVICE_BIND_GROUP_USAGE: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().expect_fail(FailureCase::always())) + .parameters( + TestParameters::default() + .expect_fail(FailureCase::always()) + .enable_noop(), + ) .run_async(|ctx| async move { // Create a bind group using a layout from another device. This should be a validation // error but currently crashes. @@ -53,7 +57,7 @@ static CROSS_DEVICE_BIND_GROUP_USAGE: GpuTestConfiguration = GpuTestConfiguratio #[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))] #[gpu_test] static DEVICE_LIFETIME_CHECK: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { ctx.instance.poll_all(false); @@ -80,7 +84,7 @@ static DEVICE_LIFETIME_CHECK: GpuTestConfiguration = GpuTestConfiguration::new() #[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))] #[gpu_test] static MULTIPLE_DEVICES: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { use pollster::FutureExt as _; ctx.adapter @@ -162,7 +166,11 @@ async fn request_device_error_message() { // should turn into no-ops, per spec. #[gpu_test] static DEVICE_DESTROY_THEN_MORE: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().features(wgpu::Features::CLEAR_TEXTURE)) + .parameters( + TestParameters::default() + .features(wgpu::Features::CLEAR_TEXTURE) + .enable_noop(), + ) .run_sync(|ctx| { // Create some resources on the device that we will attempt to use *after* losing // the device. @@ -474,7 +482,7 @@ static DEVICE_DESTROY_THEN_MORE: GpuTestConfiguration = GpuTestConfiguration::ne #[gpu_test] static DEVICE_DESTROY_THEN_LOST: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_async(|ctx| async move { // This test checks that when device.destroy is called, the provided // DeviceLostClosure is called with reason DeviceLostReason::Destroyed. @@ -509,7 +517,7 @@ static DEVICE_DESTROY_THEN_LOST: GpuTestConfiguration = GpuTestConfiguration::ne #[gpu_test] static DIFFERENT_BGL_ORDER_BW_SHADER_AND_API: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { // This test addresses a bug found in multiple backends where `wgpu_core` and `wgpu_hal` // backends made different assumptions about the element order of vectors of bind group @@ -636,7 +644,7 @@ static DIFFERENT_BGL_ORDER_BW_SHADER_AND_API: GpuTestConfiguration = GpuTestConf #[gpu_test] static DEVICE_DESTROY_THEN_BUFFER_CLEANUP: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { // When a device is destroyed, its resources should be released, // without causing a deadlock. @@ -675,7 +683,7 @@ static DEVICE_DESTROY_THEN_BUFFER_CLEANUP: GpuTestConfiguration = GpuTestConfigu #[gpu_test] static DEVICE_AND_QUEUE_HAVE_DIFFERENT_IDS: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_async(|ctx| async move { let TestingContext { adapter, diff --git a/tests/tests/wgpu-gpu/dispatch_workgroups_indirect.rs b/tests/tests/wgpu-gpu/dispatch_workgroups_indirect.rs index 9010389b107..24a38604f24 100644 --- a/tests/tests/wgpu-gpu/dispatch_workgroups_indirect.rs +++ b/tests/tests/wgpu-gpu/dispatch_workgroups_indirect.rs @@ -74,7 +74,7 @@ static RESET_BIND_GROUPS: GpuTestConfiguration = GpuTestConfiguration::new() .limits(wgpu::Limits { max_push_constant_size: 4, ..wgpu::Limits::downlevel_defaults() - }), + }).enable_noop(), ) .run_async(|ctx| async move { ctx.device.push_error_scope(wgpu::ErrorFilter::Validation); @@ -116,7 +116,8 @@ static ZERO_SIZED_BUFFER: GpuTestConfiguration = GpuTestConfiguration::new() .limits(wgpu::Limits { max_push_constant_size: 4, ..wgpu::Limits::downlevel_defaults() - }), + }) + .enable_noop(), ) .run_async(|ctx| async move { ctx.device.push_error_scope(wgpu::ErrorFilter::Validation); diff --git a/tests/tests/wgpu-gpu/draw_indirect.rs b/tests/tests/wgpu-gpu/draw_indirect.rs index ab2f090980d..a0c8253be0b 100644 --- a/tests/tests/wgpu-gpu/draw_indirect.rs +++ b/tests/tests/wgpu-gpu/draw_indirect.rs @@ -343,12 +343,18 @@ macro_rules! make_test { ($name:ident, $test_data:expr, $expect_noop:expr, $features:expr) => { #[gpu_test] static $name: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters( - TestParameters::default() + .parameters({ + let params = TestParameters::default() .downlevel_flags(wgpu::DownlevelFlags::INDIRECT_EXECUTION) .features($features) - .limits(wgpu::Limits::downlevel_defaults()), - ) + .limits(wgpu::Limits::downlevel_defaults()); + + if $expect_noop { + params.enable_noop() + } else { + params + } + }) .run_async(|ctx| run_test(ctx, $test_data, $expect_noop)); }; } diff --git a/tests/tests/wgpu-gpu/dual_source_blending.rs b/tests/tests/wgpu-gpu/dual_source_blending.rs index 3bd55945a37..eeffa72e524 100644 --- a/tests/tests/wgpu-gpu/dual_source_blending.rs +++ b/tests/tests/wgpu-gpu/dual_source_blending.rs @@ -55,7 +55,7 @@ fn blend_state_with_dual_source_blending() -> BlendState { #[gpu_test] static DUAL_SOURCE_BLENDING_FEATURE_DISABLED: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_async(dual_source_blending_disabled); async fn dual_source_blending_disabled(ctx: TestingContext) { @@ -118,7 +118,11 @@ async fn dual_source_blending_disabled(ctx: TestingContext) { #[gpu_test] static DUAL_SOURCE_BLENDING_FEATURE_ENABLED: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().features(wgpu::Features::DUAL_SOURCE_BLENDING)) + .parameters( + TestParameters::default() + .features(wgpu::Features::DUAL_SOURCE_BLENDING) + .enable_noop(), + ) .run_async(dual_source_blending_enabled); async fn dual_source_blending_enabled(ctx: TestingContext) { diff --git a/tests/tests/wgpu-gpu/encoder.rs b/tests/tests/wgpu-gpu/encoder.rs index 699a1280be2..426ef3c808e 100644 --- a/tests/tests/wgpu-gpu/encoder.rs +++ b/tests/tests/wgpu-gpu/encoder.rs @@ -15,17 +15,23 @@ pub fn all_tests(vec: &mut Vec) { } #[gpu_test] -static DROP_ENCODER: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| { - let encoder = ctx - .device - .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); - drop(encoder); -}); +static DROP_ENCODER: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_sync(|ctx| { + let encoder = ctx + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); + drop(encoder); + }); #[gpu_test] static DROP_QUEUE_BEFORE_CREATING_COMMAND_ENCODER: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().expect_fail(FailureCase::always())) + .parameters( + TestParameters::default() + .expect_fail(FailureCase::always()) + .enable_noop(), + ) .run_sync(|ctx| { // Use the device after the queue is dropped. Currently this panics // but it probably shouldn't. @@ -38,7 +44,7 @@ static DROP_QUEUE_BEFORE_CREATING_COMMAND_ENCODER: GpuTestConfiguration = #[gpu_test] static DROP_ENCODER_AFTER_ERROR: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { let mut encoder = ctx .device @@ -82,11 +88,15 @@ static DROP_ENCODER_AFTER_ERROR: GpuTestConfiguration = GpuTestConfiguration::ne #[gpu_test] static ENCODER_OPERATIONS_FAIL_WHILE_PASS_ALIVE: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().features( - wgpu::Features::CLEAR_TEXTURE - | wgpu::Features::TIMESTAMP_QUERY - | wgpu::Features::TIMESTAMP_QUERY_INSIDE_ENCODERS, - )) + .parameters( + TestParameters::default() + .features( + wgpu::Features::CLEAR_TEXTURE + | wgpu::Features::TIMESTAMP_QUERY + | wgpu::Features::TIMESTAMP_QUERY_INSIDE_ENCODERS, + ) + .enable_noop(), + ) .run_sync(encoder_operations_fail_while_pass_alive); fn encoder_operations_fail_while_pass_alive(ctx: TestingContext) { diff --git a/tests/tests/wgpu-gpu/float32_filterable.rs b/tests/tests/wgpu-gpu/float32_filterable.rs index ba623e0bee0..c18a3e6416d 100644 --- a/tests/tests/wgpu-gpu/float32_filterable.rs +++ b/tests/tests/wgpu-gpu/float32_filterable.rs @@ -53,7 +53,7 @@ fn create_texture_binding(device: &wgpu::Device, format: wgpu::TextureFormat, fi #[gpu_test] static FLOAT32_FILTERABLE_WITHOUT_FEATURE: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { let device = &ctx.device; // Unorm textures are always filterable @@ -80,7 +80,11 @@ static FLOAT32_FILTERABLE_WITHOUT_FEATURE: GpuTestConfiguration = GpuTestConfigu #[gpu_test] static FLOAT32_FILTERABLE_WITH_FEATURE: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().features(wgpu::Features::FLOAT32_FILTERABLE)) + .parameters( + TestParameters::default() + .features(wgpu::Features::FLOAT32_FILTERABLE) + .enable_noop(), + ) .run_sync(|ctx| { let device = &ctx.device; // With the feature enabled, it does work! diff --git a/tests/tests/wgpu-gpu/image_atomics/mod.rs b/tests/tests/wgpu-gpu/image_atomics/mod.rs index c11d9250ab4..0d1b3d080da 100644 --- a/tests/tests/wgpu-gpu/image_atomics/mod.rs +++ b/tests/tests/wgpu-gpu/image_atomics/mod.rs @@ -172,7 +172,7 @@ async fn test_format( #[gpu_test] static IMAGE_ATOMICS_NOT_ENABLED: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { let size = wgpu::Extent3d { width: 256, @@ -200,7 +200,7 @@ static IMAGE_ATOMICS_NOT_ENABLED: GpuTestConfiguration = GpuTestConfiguration::n #[gpu_test] static IMAGE_ATOMICS_NOT_SUPPORTED: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().features(wgpu::Features::TEXTURE_ATOMIC)) + .parameters(TestParameters::default().features(wgpu::Features::TEXTURE_ATOMIC).enable_noop()) .run_sync(|ctx| { let size = wgpu::Extent3d { width: 256, diff --git a/tests/tests/wgpu-gpu/instance.rs b/tests/tests/wgpu-gpu/instance.rs index 6f882b62586..adab85f2a33 100644 --- a/tests/tests/wgpu-gpu/instance.rs +++ b/tests/tests/wgpu-gpu/instance.rs @@ -1,8 +1,10 @@ -use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; pub fn all_tests(vec: &mut Vec) { vec.push(INITIALIZE); } #[gpu_test] -static INITIALIZE: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|_ctx| {}); +static INITIALIZE: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_sync(|_ctx| {}); diff --git a/tests/tests/wgpu-gpu/life_cycle.rs b/tests/tests/wgpu-gpu/life_cycle.rs index 869f963f2e5..c7c5786b979 100644 --- a/tests/tests/wgpu-gpu/life_cycle.rs +++ b/tests/tests/wgpu-gpu/life_cycle.rs @@ -13,8 +13,9 @@ pub fn all_tests(vec: &mut Vec) { } #[gpu_test] -static BUFFER_DESTROY: GpuTestConfiguration = - GpuTestConfiguration::new().run_async(|ctx| async move { +static BUFFER_DESTROY: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_async(|ctx| async move { let buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor { label: Some("buffer"), size: 256, @@ -80,8 +81,9 @@ static BUFFER_DESTROY: GpuTestConfiguration = }); #[gpu_test] -static TEXTURE_DESTROY: GpuTestConfiguration = - GpuTestConfiguration::new().run_async(|ctx| async move { +static TEXTURE_DESTROY: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_async(|ctx| async move { let texture = ctx.device.create_texture(&wgpu::TextureDescriptor { label: None, size: wgpu::Extent3d { @@ -118,7 +120,9 @@ static TEXTURE_DESTROY: GpuTestConfiguration = static BUFFER_DESTROY_BEFORE_SUBMIT: GpuTestConfiguration = GpuTestConfiguration::new() .parameters( // https://github.com/gfx-rs/wgpu/issues/7854 - TestParameters::default().skip(FailureCase::backend_adapter(Backends::VULKAN, "llvmpipe")), + TestParameters::default() + .skip(FailureCase::backend_adapter(Backends::VULKAN, "llvmpipe")) + .enable_noop(), ) .run_sync(|ctx| { let buffer_source = ctx @@ -158,7 +162,9 @@ static BUFFER_DESTROY_BEFORE_SUBMIT: GpuTestConfiguration = GpuTestConfiguration static TEXTURE_DESTROY_BEFORE_SUBMIT: GpuTestConfiguration = GpuTestConfiguration::new() .parameters( // https://github.com/gfx-rs/wgpu/issues/7854 - TestParameters::default().skip(FailureCase::backend_adapter(Backends::VULKAN, "llvmpipe")), + TestParameters::default() + .skip(FailureCase::backend_adapter(Backends::VULKAN, "llvmpipe")) + .enable_noop(), ) .run_sync(|ctx| { let descriptor = wgpu::TextureDescriptor { diff --git a/tests/tests/wgpu-gpu/mem_leaks.rs b/tests/tests/wgpu-gpu/mem_leaks.rs index 456b04e8ebb..c58981d5b1a 100644 --- a/tests/tests/wgpu-gpu/mem_leaks.rs +++ b/tests/tests/wgpu-gpu/mem_leaks.rs @@ -310,7 +310,8 @@ static SIMPLE_DRAW_CHECK_MEM_LEAKS: wgpu_test::GpuTestConfiguration = .parameters( wgpu_test::TestParameters::default() .test_features_limits() - .features(wgpu::Features::VERTEX_WRITABLE_STORAGE), + .features(wgpu::Features::VERTEX_WRITABLE_STORAGE) + .enable_noop(), ) .run_async(|ctx| { draw_test_with_reports(ctx, &[0, 1, 2, 3, 4, 5], |cmb| { diff --git a/tests/tests/wgpu-gpu/nv12_texture/mod.rs b/tests/tests/wgpu-gpu/nv12_texture/mod.rs index bbe3c450847..ced957ca382 100644 --- a/tests/tests/wgpu-gpu/nv12_texture/mod.rs +++ b/tests/tests/wgpu-gpu/nv12_texture/mod.rs @@ -14,7 +14,11 @@ pub fn all_tests(tests: &mut Vec) { #[gpu_test] static NV12_TEXTURE_CREATION_SAMPLING: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().features(wgpu::Features::TEXTURE_FORMAT_NV12)) + .parameters( + TestParameters::default() + .features(wgpu::Features::TEXTURE_FORMAT_NV12) + .enable_noop(), + ) .run_sync(|ctx| { let size = wgpu::Extent3d { width: 256, @@ -135,7 +139,11 @@ static NV12_TEXTURE_CREATION_SAMPLING: GpuTestConfiguration = GpuTestConfigurati #[gpu_test] static NV12_TEXTURE_VIEW_PLANE_ON_NON_PLANAR_FORMAT: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().features(wgpu::Features::TEXTURE_FORMAT_NV12)) + .parameters( + TestParameters::default() + .features(wgpu::Features::TEXTURE_FORMAT_NV12) + .enable_noop(), + ) .run_sync(|ctx| { let size = wgpu::Extent3d { width: 256, @@ -166,7 +174,11 @@ static NV12_TEXTURE_VIEW_PLANE_ON_NON_PLANAR_FORMAT: GpuTestConfiguration = #[gpu_test] static NV12_TEXTURE_VIEW_PLANE_OUT_OF_BOUNDS: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().features(wgpu::Features::TEXTURE_FORMAT_NV12)) + .parameters( + TestParameters::default() + .features(wgpu::Features::TEXTURE_FORMAT_NV12) + .enable_noop(), + ) .run_sync(|ctx| { let size = wgpu::Extent3d { width: 256, @@ -198,7 +210,11 @@ static NV12_TEXTURE_VIEW_PLANE_OUT_OF_BOUNDS: GpuTestConfiguration = GpuTestConf #[gpu_test] static NV12_TEXTURE_BAD_FORMAT_VIEW_PLANE: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().features(wgpu::Features::TEXTURE_FORMAT_NV12)) + .parameters( + TestParameters::default() + .features(wgpu::Features::TEXTURE_FORMAT_NV12) + .enable_noop(), + ) .run_sync(|ctx| { let size = wgpu::Extent3d { width: 256, @@ -230,7 +246,11 @@ static NV12_TEXTURE_BAD_FORMAT_VIEW_PLANE: GpuTestConfiguration = GpuTestConfigu #[gpu_test] static NV12_TEXTURE_BAD_SIZE: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().features(wgpu::Features::TEXTURE_FORMAT_NV12)) + .parameters( + TestParameters::default() + .features(wgpu::Features::TEXTURE_FORMAT_NV12) + .enable_noop(), + ) .run_sync(|ctx| { let size = wgpu::Extent3d { width: 255, diff --git a/tests/tests/wgpu-gpu/pipeline.rs b/tests/tests/wgpu-gpu/pipeline.rs index 5ec40915c6f..aa62032a5f1 100644 --- a/tests/tests/wgpu-gpu/pipeline.rs +++ b/tests/tests/wgpu-gpu/pipeline.rs @@ -42,7 +42,7 @@ const TRIVIAL_FRAGMENT_SHADER_DESC: wgpu::ShaderModuleDescriptor = wgpu::ShaderM #[gpu_test] static COMPUTE_PIPELINE_DEFAULT_LAYOUT_BAD_MODULE: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { ctx.device.push_error_scope(wgpu::ErrorFilter::Validation); @@ -72,7 +72,11 @@ static COMPUTE_PIPELINE_DEFAULT_LAYOUT_BAD_MODULE: GpuTestConfiguration = #[gpu_test] static COMPUTE_PIPELINE_DEFAULT_LAYOUT_BAD_BGL_INDEX: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().test_features_limits()) + .parameters( + TestParameters::default() + .test_features_limits() + .enable_noop(), + ) .run_sync(|ctx| { ctx.device.push_error_scope(wgpu::ErrorFilter::Validation); @@ -101,7 +105,7 @@ static COMPUTE_PIPELINE_DEFAULT_LAYOUT_BAD_BGL_INDEX: GpuTestConfiguration = #[gpu_test] static RENDER_PIPELINE_DEFAULT_LAYOUT_BAD_MODULE: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { ctx.device.push_error_scope(wgpu::ErrorFilter::Validation); @@ -138,7 +142,11 @@ static RENDER_PIPELINE_DEFAULT_LAYOUT_BAD_MODULE: GpuTestConfiguration = #[gpu_test] static RENDER_PIPELINE_DEFAULT_LAYOUT_BAD_BGL_INDEX: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().test_features_limits()) + .parameters( + TestParameters::default() + .test_features_limits() + .enable_noop(), + ) .run_sync(|ctx| { ctx.device.push_error_scope(wgpu::ErrorFilter::Validation); @@ -186,7 +194,7 @@ static RENDER_PIPELINE_DEFAULT_LAYOUT_BAD_BGL_INDEX: GpuTestConfiguration = #[gpu_test] static NO_TARGETLESS_RENDER: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { fail( &ctx.device, diff --git a/tests/tests/wgpu-gpu/poll.rs b/tests/tests/wgpu-gpu/poll.rs index 15a4db54e95..70d3b393c7e 100644 --- a/tests/tests/wgpu-gpu/poll.rs +++ b/tests/tests/wgpu-gpu/poll.rs @@ -6,7 +6,9 @@ use wgpu::{ CommandEncoderDescriptor, ComputePassDescriptor, PollType, ShaderStages, }; -use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer, TestingContext}; +use wgpu_test::{ + gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; pub fn all_tests(vec: &mut Vec) { vec.extend([ @@ -64,16 +66,19 @@ fn generate_dummy_work(ctx: &TestingContext) -> CommandBuffer { } #[gpu_test] -static WAIT: GpuTestConfiguration = GpuTestConfiguration::new().run_async(|ctx| async move { - let cmd_buf = generate_dummy_work(&ctx); +static WAIT: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_async(|ctx| async move { + let cmd_buf = generate_dummy_work(&ctx); - ctx.queue.submit(Some(cmd_buf)); - ctx.async_poll(PollType::wait()).await.unwrap(); -}); + ctx.queue.submit(Some(cmd_buf)); + ctx.async_poll(PollType::wait()).await.unwrap(); + }); #[gpu_test] -static DOUBLE_WAIT: GpuTestConfiguration = - GpuTestConfiguration::new().run_async(|ctx| async move { +static DOUBLE_WAIT: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_async(|ctx| async move { let cmd_buf = generate_dummy_work(&ctx); ctx.queue.submit(Some(cmd_buf)); @@ -82,8 +87,9 @@ static DOUBLE_WAIT: GpuTestConfiguration = }); #[gpu_test] -static WAIT_ON_SUBMISSION: GpuTestConfiguration = - GpuTestConfiguration::new().run_async(|ctx| async move { +static WAIT_ON_SUBMISSION: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_async(|ctx| async move { let cmd_buf = generate_dummy_work(&ctx); let index = ctx.queue.submit(Some(cmd_buf)); @@ -91,8 +97,9 @@ static WAIT_ON_SUBMISSION: GpuTestConfiguration = }); #[gpu_test] -static DOUBLE_WAIT_ON_SUBMISSION: GpuTestConfiguration = - GpuTestConfiguration::new().run_async(|ctx| async move { +static DOUBLE_WAIT_ON_SUBMISSION: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_async(|ctx| async move { let cmd_buf = generate_dummy_work(&ctx); let index = ctx.queue.submit(Some(cmd_buf)); @@ -103,8 +110,9 @@ static DOUBLE_WAIT_ON_SUBMISSION: GpuTestConfiguration = }); #[gpu_test] -static WAIT_OUT_OF_ORDER: GpuTestConfiguration = - GpuTestConfiguration::new().run_async(|ctx| async move { +static WAIT_OUT_OF_ORDER: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_async(|ctx| async move { let cmd_buf1 = generate_dummy_work(&ctx); let cmd_buf2 = generate_dummy_work(&ctx); @@ -120,7 +128,11 @@ static WAIT_OUT_OF_ORDER: GpuTestConfiguration = /// console. #[gpu_test] static WAIT_AFTER_BAD_SUBMISSION: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(wgpu_test::TestParameters::default().skip(wgpu_test::FailureCase::webgl2())) + .parameters( + wgpu_test::TestParameters::default() + .skip(wgpu_test::FailureCase::webgl2()) + .enable_noop(), + ) .run_async(wait_after_bad_submission); async fn wait_after_bad_submission(ctx: TestingContext) { diff --git a/tests/tests/wgpu-gpu/query_set.rs b/tests/tests/wgpu-gpu/query_set.rs index 4858560dda8..4aee905d3fb 100644 --- a/tests/tests/wgpu-gpu/query_set.rs +++ b/tests/tests/wgpu-gpu/query_set.rs @@ -6,7 +6,7 @@ pub fn all_tests(vec: &mut Vec) { #[gpu_test] static DROP_FAILED_TIMESTAMP_QUERY_SET: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { // Enter an error scope, so the validation catch-all doesn't // report the error too early. diff --git a/tests/tests/wgpu-gpu/queue_transfer.rs b/tests/tests/wgpu-gpu/queue_transfer.rs index 7397568cd95..79abefaca28 100644 --- a/tests/tests/wgpu-gpu/queue_transfer.rs +++ b/tests/tests/wgpu-gpu/queue_transfer.rs @@ -1,7 +1,7 @@ //! Tests for buffer copy validation. use wgpu::PollType; -use wgpu_test::{fail, gpu_test, GpuTestConfiguration, GpuTestInitializer}; +use wgpu_test::{fail, gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; pub fn all_tests(vec: &mut Vec) { vec.extend([ @@ -13,6 +13,7 @@ pub fn all_tests(vec: &mut Vec) { #[gpu_test] static QUEUE_WRITE_TEXTURE_THEN_DESTROY: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { let texture = ctx.device.create_texture(&wgpu::TextureDescriptor { label: None, @@ -61,8 +62,9 @@ static QUEUE_WRITE_TEXTURE_THEN_DESTROY: GpuTestConfiguration = GpuTestConfigura }); #[gpu_test] -static QUEUE_WRITE_TEXTURE_OVERFLOW: GpuTestConfiguration = - GpuTestConfiguration::new().run_sync(|ctx| { +static QUEUE_WRITE_TEXTURE_OVERFLOW: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_sync(|ctx| { let texture = ctx.device.create_texture(&wgpu::TextureDescriptor { label: None, size: wgpu::Extent3d { diff --git a/tests/tests/wgpu-gpu/ray_tracing/as_build.rs b/tests/tests/wgpu-gpu/ray_tracing/as_build.rs index 558bc626537..af9a811a7e5 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/as_build.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/as_build.rs @@ -66,7 +66,8 @@ static UNBUILT_BLAS_COMPACTION: GpuTestConfiguration = GpuTestConfiguration::new TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY) + .enable_noop(), ) .run_sync(unbuilt_blas_compaction); @@ -128,7 +129,8 @@ static UNPREPARED_BLAS_COMPACTION: GpuTestConfiguration = GpuTestConfiguration:: TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY) + .enable_noop(), ) .run_sync(unprepared_blas_compaction); @@ -295,7 +297,8 @@ static OUT_OF_ORDER_AS_BUILD_USE: GpuTestConfiguration = GpuTestConfiguration::n TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY) + .enable_noop(), ) .run_sync(out_of_order_as_build_use); @@ -477,7 +480,8 @@ static EMPTY_BUILD: GpuTestConfiguration = GpuTestConfiguration::new() TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY) + .enable_noop(), ) .run_sync(empty_build); fn empty_build(ctx: TestingContext) { @@ -498,7 +502,8 @@ static BUILD_WITH_TRANSFORM: GpuTestConfiguration = GpuTestConfiguration::new() TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY) + .enable_noop(), ) .run_sync(build_with_transform); @@ -710,7 +715,8 @@ static ONLY_TLAS_VERTEX_RETURN: GpuTestConfiguration = GpuTestConfiguration::new .features( wgpu::Features::EXPERIMENTAL_RAY_QUERY | wgpu::Features::EXPERIMENTAL_RAY_HIT_VERTEX_RETURN, - ), + ) + .enable_noop(), ) .run_sync(only_tlas_vertex_return); @@ -749,7 +755,8 @@ static EXTRA_FORMAT_BUILD: GpuTestConfiguration = GpuTestConfiguration::new() .features( wgpu::Features::EXPERIMENTAL_RAY_QUERY | wgpu::Features::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS, - ), + ) + .enable_noop(), ) .run_sync(|ctx| test_as_build_format_stride(ctx, VertexFormat::Snorm16x4, 6, false)); @@ -759,7 +766,8 @@ static MISALIGNED_BUILD: GpuTestConfiguration = GpuTestConfiguration::new() TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY) + .enable_noop(), ) // Larger than the minimum size, but not aligned as required .run_sync(|ctx| test_as_build_format_stride(ctx, VertexFormat::Float32x3, 13, true)); @@ -770,7 +778,8 @@ static TOO_SMALL_STRIDE_BUILD: GpuTestConfiguration = GpuTestConfiguration::new( TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY) + .enable_noop(), ) // Aligned as required, but smaller than minimum size .run_sync(|ctx| test_as_build_format_stride(ctx, VertexFormat::Float32x3, 8, true)); diff --git a/tests/tests/wgpu-gpu/ray_tracing/as_create.rs b/tests/tests/wgpu-gpu/ray_tracing/as_create.rs index 76ccbc9d8c3..19edb096be2 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/as_create.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/as_create.rs @@ -18,7 +18,8 @@ static BLAS_INVALID_VERTEX_FORMAT: GpuTestConfiguration = GpuTestConfiguration:: TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY) + .enable_noop(), ) .run_sync(invalid_vertex_format_blas_create); @@ -59,7 +60,8 @@ static BLAS_MISMATCHED_INDEX: GpuTestConfiguration = GpuTestConfiguration::new() TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY) + .enable_noop(), ) .run_sync(mismatched_index_blas_create); diff --git a/tests/tests/wgpu-gpu/ray_tracing/limits.rs b/tests/tests/wgpu-gpu/ray_tracing/limits.rs index d8448eec62e..c1ee870f83d 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/limits.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/limits.rs @@ -26,7 +26,8 @@ static LIMITS_HIT: GpuTestConfiguration = GpuTestConfiguration::new() max_acceleration_structures_per_shader_stage: 1, ..Limits::default() }) - .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY) + .enable_noop(), ) .run_sync(hit_limits); diff --git a/tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs b/tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs index 45cf7924d02..d71092dd846 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs @@ -110,7 +110,8 @@ static ACCELERATION_STRUCTURE_BUILD_NO_INDEX: GpuTestConfiguration = GpuTestConf TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY) + .enable_noop(), ) .run_sync(|ctx| { acceleration_structure_build(&ctx, false); @@ -122,7 +123,8 @@ static ACCELERATION_STRUCTURE_BUILD_WITH_INDEX: GpuTestConfiguration = GpuTestCo TestParameters::default() .test_features_limits() .limits(acceleration_structure_limits()) - .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY), + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY) + .enable_noop(), ) .run_sync(|ctx| { acceleration_structure_build(&ctx, true); diff --git a/tests/tests/wgpu-gpu/regression/issue_3457.rs b/tests/tests/wgpu-gpu/regression/issue_3457.rs index 1a84ecba32c..4b7503776ea 100644 --- a/tests/tests/wgpu-gpu/regression/issue_3457.rs +++ b/tests/tests/wgpu-gpu/regression/issue_3457.rs @@ -1,4 +1,4 @@ -use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; use wgpu::*; @@ -19,8 +19,9 @@ pub fn all_tests(vec: &mut Vec) { /// We use non-consecutive vertex attribute locations (0 and 5) in order to also test /// that we unset the correct locations (see PR #3706). #[gpu_test] -static PASS_RESET_VERTEX_BUFFER: GpuTestConfiguration = - GpuTestConfiguration::new().run_async(|ctx| async move { +static PASS_RESET_VERTEX_BUFFER: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_async(|ctx| async move { let module = ctx .device .create_shader_module(include_wgsl!("issue_3457.wgsl")); diff --git a/tests/tests/wgpu-gpu/regression/issue_4024.rs b/tests/tests/wgpu-gpu/regression/issue_4024.rs index 8e648813d6d..036a44f6161 100644 --- a/tests/tests/wgpu-gpu/regression/issue_4024.rs +++ b/tests/tests/wgpu-gpu/regression/issue_4024.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use parking_lot::Mutex; -use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; use wgpu::*; @@ -18,6 +18,7 @@ pub fn all_tests(vec: &mut Vec) { /// to add them to. This is incorrect, as we do not immediately invoke map_async callbacks. #[gpu_test] static QUEUE_SUBMITTED_CALLBACK_ORDERING: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) .run_async(|ctx| async move { // Create a mappable buffer let buffer = ctx.device.create_buffer(&BufferDescriptor { diff --git a/tests/tests/wgpu-gpu/regression/issue_4122.rs b/tests/tests/wgpu-gpu/regression/issue_4122.rs index f59897a19d0..e858c800fe1 100644 --- a/tests/tests/wgpu-gpu/regression/issue_4122.rs +++ b/tests/tests/wgpu-gpu/regression/issue_4122.rs @@ -91,7 +91,7 @@ async fn fill_test(ctx: &TestingContext, range: Range, size: u64) -> bool { /// This test will fail on nvidia if the bug is not properly worked around. #[gpu_test] static CLEAR_BUFFER_RANGE_RESPECTED: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_async(|ctx| async move { // This hits most of the cases in nvidia's clear buffer bug let mut succeeded = true; diff --git a/tests/tests/wgpu-gpu/regression/issue_4485.rs b/tests/tests/wgpu-gpu/regression/issue_4485.rs index aa6e27bfebc..5c814377822 100644 --- a/tests/tests/wgpu-gpu/regression/issue_4485.rs +++ b/tests/tests/wgpu-gpu/regression/issue_4485.rs @@ -16,7 +16,7 @@ pub fn all_tests(vec: &mut Vec) { /// This also tests that shaders generated with this fix execute correctly. #[gpu_test] static CONTINUE_SWITCH: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().force_fxc(true)) + .parameters(TestParameters::default().force_fxc(true).enable_noop()) .run_async(|ctx| async move { test_impl(&ctx).await }); async fn test_impl(ctx: &TestingContext) { diff --git a/tests/tests/wgpu-gpu/regression/issue_4514.rs b/tests/tests/wgpu-gpu/regression/issue_4514.rs index 8eb9b436fae..f3ad2051a90 100644 --- a/tests/tests/wgpu-gpu/regression/issue_4514.rs +++ b/tests/tests/wgpu-gpu/regression/issue_4514.rs @@ -16,7 +16,7 @@ pub fn all_tests(vec: &mut Vec) { /// bug is avoided there. #[gpu_test] static DEGENERATE_SWITCH: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().force_fxc(true)) + .parameters(TestParameters::default().force_fxc(true).enable_noop()) .run_async(|ctx| async move { test_impl(&ctx).await }); async fn test_impl(ctx: &TestingContext) { diff --git a/tests/tests/wgpu-gpu/regression/issue_5553.rs b/tests/tests/wgpu-gpu/regression/issue_5553.rs index b9f99612166..7c1884dc3a9 100644 --- a/tests/tests/wgpu-gpu/regression/issue_5553.rs +++ b/tests/tests/wgpu-gpu/regression/issue_5553.rs @@ -1,4 +1,4 @@ -use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; use wgpu::*; @@ -14,8 +14,9 @@ pub fn all_tests(vec: &mut Vec) { /// the fragment inputs. This is necessary for generating correct hlsl: /// https://github.com/gfx-rs/wgpu/issues/5553 #[gpu_test] -static ALLOW_INPUT_NOT_CONSUMED: GpuTestConfiguration = - GpuTestConfiguration::new().run_async(|ctx| async move { +static ALLOW_INPUT_NOT_CONSUMED: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_async(|ctx| async move { let module = ctx .device .create_shader_module(include_wgsl!("issue_5553.wgsl")); diff --git a/tests/tests/wgpu-gpu/regression/issue_6317.rs b/tests/tests/wgpu-gpu/regression/issue_6317.rs index e955d2a5aa6..fd42885be62 100644 --- a/tests/tests/wgpu-gpu/regression/issue_6317.rs +++ b/tests/tests/wgpu-gpu/regression/issue_6317.rs @@ -11,7 +11,8 @@ static NON_FATAL_ERRORS_IN_QUEUE_SUBMIT: GpuTestConfiguration = GpuTestConfigura .parameters( TestParameters::default() .downlevel_flags(DownlevelFlags::COMPUTE_SHADERS) - .limits(Limits::downlevel_defaults()), + .limits(Limits::downlevel_defaults()) + .enable_noop(), ) .run_sync(|ctx| { let shader_with_trivial_bind_group = concat!( diff --git a/tests/tests/wgpu-gpu/regression/issue_6467.rs b/tests/tests/wgpu-gpu/regression/issue_6467.rs index 9458eb51126..84d680d012c 100644 --- a/tests/tests/wgpu-gpu/regression/issue_6467.rs +++ b/tests/tests/wgpu-gpu/regression/issue_6467.rs @@ -13,7 +13,11 @@ pub fn all_tests(vec: &mut Vec) { /// The following test should successfully do nothing on all platforms. #[gpu_test] static ZERO_WORKGROUP_COUNT: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().limits(wgpu::Limits::default())) + .parameters( + TestParameters::default() + .limits(wgpu::Limits::default()) + .enable_noop(), + ) .run_async(|ctx| async move { let module = ctx .device diff --git a/tests/tests/wgpu-gpu/render_pass_ownership.rs b/tests/tests/wgpu-gpu/render_pass_ownership.rs index c803c765307..3e2b1a9831d 100644 --- a/tests/tests/wgpu-gpu/render_pass_ownership.rs +++ b/tests/tests/wgpu-gpu/render_pass_ownership.rs @@ -268,7 +268,11 @@ async fn render_pass_query_set_ownership_timestamps(ctx: TestingContext) { #[gpu_test] static RENDER_PASS_KEEP_ENCODER_ALIVE: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().test_features_limits()) + .parameters( + TestParameters::default() + .test_features_limits() + .enable_noop(), + ) .run_async(render_pass_keep_encoder_alive); async fn render_pass_keep_encoder_alive(ctx: TestingContext) { diff --git a/tests/tests/wgpu-gpu/resource_descriptor_accessor.rs b/tests/tests/wgpu-gpu/resource_descriptor_accessor.rs index 88472739e9e..5a25ab0cb98 100644 --- a/tests/tests/wgpu-gpu/resource_descriptor_accessor.rs +++ b/tests/tests/wgpu-gpu/resource_descriptor_accessor.rs @@ -1,21 +1,23 @@ -use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; pub fn all_tests(vec: &mut Vec) { vec.push(BUFFER_SIZE_AND_USAGE); } #[gpu_test] -static BUFFER_SIZE_AND_USAGE: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| { - let buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor { - label: None, - size: 1234, - usage: wgpu::BufferUsages::COPY_SRC | wgpu::BufferUsages::COPY_DST, - mapped_at_creation: false, - }); +static BUFFER_SIZE_AND_USAGE: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_sync(|ctx| { + let buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 1234, + usage: wgpu::BufferUsages::COPY_SRC | wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false, + }); - assert_eq!(buffer.size(), 1234); - assert_eq!( - buffer.usage(), - wgpu::BufferUsages::COPY_SRC | wgpu::BufferUsages::COPY_DST - ); -}); + assert_eq!(buffer.size(), 1234); + assert_eq!( + buffer.usage(), + wgpu::BufferUsages::COPY_SRC | wgpu::BufferUsages::COPY_DST + ); + }); diff --git a/tests/tests/wgpu-gpu/resource_error.rs b/tests/tests/wgpu-gpu/resource_error.rs index eb8390b904d..e8f9235498a 100644 --- a/tests/tests/wgpu-gpu/resource_error.rs +++ b/tests/tests/wgpu-gpu/resource_error.rs @@ -1,70 +1,74 @@ -use wgpu_test::{fail, gpu_test, valid, GpuTestConfiguration, GpuTestInitializer}; +use wgpu_test::{fail, gpu_test, valid, GpuTestConfiguration, GpuTestInitializer, TestParameters}; pub fn all_tests(vec: &mut Vec) { vec.extend([BAD_BUFFER, BAD_TEXTURE]); } #[gpu_test] -static BAD_BUFFER: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| { - // Create a buffer with bad parameters and call a few methods. - // Validation should fail but there should be not panic. - let buffer = fail( - &ctx.device, - || { - ctx.device.create_buffer(&wgpu::BufferDescriptor { - label: None, - size: 99999999, - usage: wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::STORAGE, - mapped_at_creation: false, - }) - }, - Some("`map` usage can only be combined with the opposite `copy`"), - ); +static BAD_BUFFER: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_sync(|ctx| { + // Create a buffer with bad parameters and call a few methods. + // Validation should fail but there should be not panic. + let buffer = fail( + &ctx.device, + || { + ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 99999999, + usage: wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::STORAGE, + mapped_at_creation: false, + }) + }, + Some("`map` usage can only be combined with the opposite `copy`"), + ); - fail( - &ctx.device, - || buffer.slice(..).map_async(wgpu::MapMode::Write, |_| {}), - Some("Buffer with '' label is invalid"), - ); - fail( - &ctx.device, - || buffer.unmap(), - Some("Buffer with '' label is invalid"), - ); - valid(&ctx.device, || buffer.destroy()); - valid(&ctx.device, || buffer.destroy()); -}); + fail( + &ctx.device, + || buffer.slice(..).map_async(wgpu::MapMode::Write, |_| {}), + Some("Buffer with '' label is invalid"), + ); + fail( + &ctx.device, + || buffer.unmap(), + Some("Buffer with '' label is invalid"), + ); + valid(&ctx.device, || buffer.destroy()); + valid(&ctx.device, || buffer.destroy()); + }); #[gpu_test] -static BAD_TEXTURE: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| { - let texture = fail( - &ctx.device, - || { - ctx.device.create_texture(&wgpu::TextureDescriptor { - label: None, - size: wgpu::Extent3d { - width: 0, - height: 12345678, - depth_or_array_layers: 9001, - }, - mip_level_count: 2000, - sample_count: 27, - dimension: wgpu::TextureDimension::D2, - format: wgpu::TextureFormat::Rgba8UnormSrgb, - usage: wgpu::TextureUsages::all(), - view_formats: &[], - }) - }, - Some("dimension x is zero"), - ); +static BAD_TEXTURE: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_sync(|ctx| { + let texture = fail( + &ctx.device, + || { + ctx.device.create_texture(&wgpu::TextureDescriptor { + label: None, + size: wgpu::Extent3d { + width: 0, + height: 12345678, + depth_or_array_layers: 9001, + }, + mip_level_count: 2000, + sample_count: 27, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rgba8UnormSrgb, + usage: wgpu::TextureUsages::all(), + view_formats: &[], + }) + }, + Some("dimension x is zero"), + ); - fail( - &ctx.device, - || { - let _ = texture.create_view(&wgpu::TextureViewDescriptor::default()); - }, - Some("Texture with '' label is invalid"), - ); - valid(&ctx.device, || texture.destroy()); - valid(&ctx.device, || texture.destroy()); -}); + fail( + &ctx.device, + || { + let _ = texture.create_view(&wgpu::TextureViewDescriptor::default()); + }, + Some("Texture with '' label is invalid"), + ); + valid(&ctx.device, || texture.destroy()); + valid(&ctx.device, || texture.destroy()); + }); diff --git a/tests/tests/wgpu-gpu/samplers.rs b/tests/tests/wgpu-gpu/samplers.rs index 40b984d21f7..1192426e41e 100644 --- a/tests/tests/wgpu-gpu/samplers.rs +++ b/tests/tests/wgpu-gpu/samplers.rs @@ -21,8 +21,9 @@ pub fn all_tests(vec: &mut Vec) { const PROBABLY_PROBLEMATIC_SAMPLER_COUNT: u32 = 8 * 1024; #[gpu_test] -static SAMPLER_DEDUPLICATION: GpuTestConfiguration = - GpuTestConfiguration::new().run_sync(sampler_deduplication); +static SAMPLER_DEDUPLICATION: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_sync(sampler_deduplication); // Create a large number of samplers from the same two descriptors. // @@ -71,8 +72,9 @@ fn sampler_deduplication(ctx: TestingContext) { } #[gpu_test] -static SAMPLER_CREATION_FAILURE: GpuTestConfiguration = - GpuTestConfiguration::new().run_sync(sampler_creation_failure); +static SAMPLER_CREATION_FAILURE: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_sync(sampler_creation_failure); /// We want to test that sampler creation properly fails when we hit internal sampler /// cache limits. As we don't actually know what the limit is, we first create as many diff --git a/tests/tests/wgpu-gpu/shader/compilation_messages/mod.rs b/tests/tests/wgpu-gpu/shader/compilation_messages/mod.rs index c641565ad9a..9304836a15e 100644 --- a/tests/tests/wgpu-gpu/shader/compilation_messages/mod.rs +++ b/tests/tests/wgpu-gpu/shader/compilation_messages/mod.rs @@ -8,7 +8,7 @@ pub fn all_tests(vec: &mut Vec) { #[gpu_test] static SHADER_COMPILE_SUCCESS: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_async(|ctx| async move { let sm = ctx .device @@ -22,7 +22,7 @@ static SHADER_COMPILE_SUCCESS: GpuTestConfiguration = GpuTestConfiguration::new( #[gpu_test] static SHADER_COMPILE_ERROR: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default()) + .parameters(TestParameters::default().enable_noop()) .run_async(|ctx| async move { ctx.device.push_error_scope(wgpu::ErrorFilter::Validation); let sm = ctx diff --git a/tests/tests/wgpu-gpu/texture_binding/mod.rs b/tests/tests/wgpu-gpu/texture_binding/mod.rs index 4f154c36277..a77b3c23386 100644 --- a/tests/tests/wgpu-gpu/texture_binding/mod.rs +++ b/tests/tests/wgpu-gpu/texture_binding/mod.rs @@ -18,7 +18,8 @@ static TEXTURE_BINDING: GpuTestConfiguration = GpuTestConfiguration::new() .parameters( TestParameters::default() .test_features_limits() - .downlevel_flags(DownlevelFlags::WEBGPU_TEXTURE_FORMAT_SUPPORT), + .downlevel_flags(DownlevelFlags::WEBGPU_TEXTURE_FORMAT_SUPPORT) + .enable_noop(), ) .run_sync(texture_binding); diff --git a/tests/tests/wgpu-gpu/texture_blit.rs b/tests/tests/wgpu-gpu/texture_blit.rs index e93587710d6..e2b0a6c6e8a 100644 --- a/tests/tests/wgpu-gpu/texture_blit.rs +++ b/tests/tests/wgpu-gpu/texture_blit.rs @@ -1,4 +1,4 @@ -use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; pub fn all_tests(vec: &mut Vec) { vec.extend([ @@ -9,6 +9,7 @@ pub fn all_tests(vec: &mut Vec) { #[gpu_test] static TEXTURE_BLIT_WITH_LINEAR_FILTER_TEST: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { let source = ctx.device.create_texture(&wgpu::TextureDescriptor { label: None, @@ -60,6 +61,7 @@ static TEXTURE_BLIT_WITH_LINEAR_FILTER_TEST: GpuTestConfiguration = GpuTestConfi #[gpu_test] static TEXTURE_BLIT_WITH_NEAREST_FILTER_TEST: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { let source = ctx.device.create_texture(&wgpu::TextureDescriptor { label: None, diff --git a/tests/tests/wgpu-gpu/texture_bounds.rs b/tests/tests/wgpu-gpu/texture_bounds.rs index 2f330294a9a..561e3635471 100644 --- a/tests/tests/wgpu-gpu/texture_bounds.rs +++ b/tests/tests/wgpu-gpu/texture_bounds.rs @@ -1,95 +1,97 @@ //! Tests for texture copy bounds checks. -use wgpu_test::{fail_if, gpu_test, GpuTestConfiguration}; +use wgpu_test::{fail_if, gpu_test, GpuTestConfiguration, TestParameters}; pub fn all_tests(vec: &mut Vec) { vec.push(BAD_COPY_ORIGIN_TEST); } #[gpu_test] -static BAD_COPY_ORIGIN_TEST: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| { - let try_origin = |origin, size, should_panic| { - let texture = ctx.device.create_texture(&TEXTURE_DESCRIPTOR); - let data = vec![255; BUFFER_SIZE as usize]; +static BAD_COPY_ORIGIN_TEST: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_sync(|ctx| { + let try_origin = |origin, size, should_panic| { + let texture = ctx.device.create_texture(&TEXTURE_DESCRIPTOR); + let data = vec![255; BUFFER_SIZE as usize]; - fail_if( - &ctx.device, - should_panic, - || { - ctx.queue.write_texture( - wgpu::TexelCopyTextureInfo { - texture: &texture, - mip_level: 0, - origin, - aspect: wgpu::TextureAspect::All, - }, - &data, - BUFFER_COPY_LAYOUT, - size, - ) - }, - None, - ); - }; + fail_if( + &ctx.device, + should_panic, + || { + ctx.queue.write_texture( + wgpu::TexelCopyTextureInfo { + texture: &texture, + mip_level: 0, + origin, + aspect: wgpu::TextureAspect::All, + }, + &data, + BUFFER_COPY_LAYOUT, + size, + ) + }, + None, + ); + }; - try_origin(wgpu::Origin3d { x: 0, y: 0, z: 0 }, TEXTURE_SIZE, false); - try_origin(wgpu::Origin3d { x: 1, y: 0, z: 0 }, TEXTURE_SIZE, true); - try_origin(wgpu::Origin3d { x: 0, y: 1, z: 0 }, TEXTURE_SIZE, true); - try_origin(wgpu::Origin3d { x: 0, y: 0, z: 1 }, TEXTURE_SIZE, true); + try_origin(wgpu::Origin3d { x: 0, y: 0, z: 0 }, TEXTURE_SIZE, false); + try_origin(wgpu::Origin3d { x: 1, y: 0, z: 0 }, TEXTURE_SIZE, true); + try_origin(wgpu::Origin3d { x: 0, y: 1, z: 0 }, TEXTURE_SIZE, true); + try_origin(wgpu::Origin3d { x: 0, y: 0, z: 1 }, TEXTURE_SIZE, true); - try_origin( - wgpu::Origin3d { - x: TEXTURE_SIZE.width - 1, - y: TEXTURE_SIZE.height - 1, - z: TEXTURE_SIZE.depth_or_array_layers - 1, - }, - wgpu::Extent3d { - width: 1, - height: 1, - depth_or_array_layers: 1, - }, - false, - ); - try_origin( - wgpu::Origin3d { - x: u32::MAX, - y: 0, - z: 0, - }, - wgpu::Extent3d { - width: 1, - height: 1, - depth_or_array_layers: 1, - }, - true, - ); - try_origin( - wgpu::Origin3d { - x: u32::MAX, - y: 0, - z: 0, - }, - wgpu::Extent3d { - width: 1, - height: 1, - depth_or_array_layers: 1, - }, - true, - ); - try_origin( - wgpu::Origin3d { - x: u32::MAX, - y: 0, - z: 0, - }, - wgpu::Extent3d { - width: 1, - height: 1, - depth_or_array_layers: 1, - }, - true, - ); -}); + try_origin( + wgpu::Origin3d { + x: TEXTURE_SIZE.width - 1, + y: TEXTURE_SIZE.height - 1, + z: TEXTURE_SIZE.depth_or_array_layers - 1, + }, + wgpu::Extent3d { + width: 1, + height: 1, + depth_or_array_layers: 1, + }, + false, + ); + try_origin( + wgpu::Origin3d { + x: u32::MAX, + y: 0, + z: 0, + }, + wgpu::Extent3d { + width: 1, + height: 1, + depth_or_array_layers: 1, + }, + true, + ); + try_origin( + wgpu::Origin3d { + x: u32::MAX, + y: 0, + z: 0, + }, + wgpu::Extent3d { + width: 1, + height: 1, + depth_or_array_layers: 1, + }, + true, + ); + try_origin( + wgpu::Origin3d { + x: u32::MAX, + y: 0, + z: 0, + }, + wgpu::Extent3d { + width: 1, + height: 1, + depth_or_array_layers: 1, + }, + true, + ); + }); const TEXTURE_SIZE: wgpu::Extent3d = wgpu::Extent3d { width: 64, diff --git a/tests/tests/wgpu-gpu/texture_view_creation.rs b/tests/tests/wgpu-gpu/texture_view_creation.rs index 82d9fd91f9f..5bf7ae1fa94 100644 --- a/tests/tests/wgpu-gpu/texture_view_creation.rs +++ b/tests/tests/wgpu-gpu/texture_view_creation.rs @@ -14,7 +14,8 @@ static STENCIL_ONLY_VIEW_CREATION: GpuTestConfiguration = GpuTestConfiguration:: .parameters( TestParameters::default() .skip(FailureCase::webgl2()) // WebGL doesn't have stencil only views - .limits(wgpu::Limits::downlevel_defaults()), + .limits(wgpu::Limits::downlevel_defaults()) + .enable_noop(), ) .run_async(|ctx| async move { for format in [TextureFormat::Stencil8, TextureFormat::Depth24PlusStencil8] { @@ -42,8 +43,9 @@ static STENCIL_ONLY_VIEW_CREATION: GpuTestConfiguration = GpuTestConfiguration:: }); #[gpu_test] -static DEPTH_ONLY_VIEW_CREATION: GpuTestConfiguration = - GpuTestConfiguration::new().run_async(|ctx| async move { +static DEPTH_ONLY_VIEW_CREATION: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_async(|ctx| async move { for format in [ TextureFormat::Depth16Unorm, TextureFormat::Depth24Plus, @@ -74,7 +76,11 @@ static DEPTH_ONLY_VIEW_CREATION: GpuTestConfiguration = #[gpu_test] static SHARED_USAGE_VIEW_CREATION: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters(TestParameters::default().downlevel_flags(DownlevelFlags::VIEW_FORMATS)) + .parameters( + TestParameters::default() + .downlevel_flags(DownlevelFlags::VIEW_FORMATS) + .enable_noop(), + ) .run_async(|ctx| async move { { let (texture_format, view_format) = diff --git a/tests/tests/wgpu-gpu/transfer.rs b/tests/tests/wgpu-gpu/transfer.rs index bb37218b29a..0e2adbbc2c0 100644 --- a/tests/tests/wgpu-gpu/transfer.rs +++ b/tests/tests/wgpu-gpu/transfer.rs @@ -1,73 +1,75 @@ -use wgpu_test::{fail, gpu_test, GpuTestConfiguration, GpuTestInitializer}; +use wgpu_test::{fail, gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; pub fn all_tests(vec: &mut Vec) { vec.push(COPY_OVERFLOW_Z); } #[gpu_test] -static COPY_OVERFLOW_Z: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| { - let mut encoder = ctx - .device - .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); +static COPY_OVERFLOW_Z: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_sync(|ctx| { + let mut encoder = ctx + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); - let t1 = ctx.device.create_texture(&wgpu::TextureDescriptor { - label: None, - dimension: wgpu::TextureDimension::D2, - size: wgpu::Extent3d { - width: 256, - height: 256, - depth_or_array_layers: 1, - }, - format: wgpu::TextureFormat::Rgba8Uint, - usage: wgpu::TextureUsages::COPY_DST, - mip_level_count: 1, - sample_count: 1, - view_formats: &[], - }); - let t2 = ctx.device.create_texture(&wgpu::TextureDescriptor { - label: None, - dimension: wgpu::TextureDimension::D2, - size: wgpu::Extent3d { - width: 256, - height: 256, - depth_or_array_layers: 1, - }, - format: wgpu::TextureFormat::Rgba8Uint, - usage: wgpu::TextureUsages::COPY_DST, - mip_level_count: 1, - sample_count: 1, - view_formats: &[], - }); + let t1 = ctx.device.create_texture(&wgpu::TextureDescriptor { + label: None, + dimension: wgpu::TextureDimension::D2, + size: wgpu::Extent3d { + width: 256, + height: 256, + depth_or_array_layers: 1, + }, + format: wgpu::TextureFormat::Rgba8Uint, + usage: wgpu::TextureUsages::COPY_DST, + mip_level_count: 1, + sample_count: 1, + view_formats: &[], + }); + let t2 = ctx.device.create_texture(&wgpu::TextureDescriptor { + label: None, + dimension: wgpu::TextureDimension::D2, + size: wgpu::Extent3d { + width: 256, + height: 256, + depth_or_array_layers: 1, + }, + format: wgpu::TextureFormat::Rgba8Uint, + usage: wgpu::TextureUsages::COPY_DST, + mip_level_count: 1, + sample_count: 1, + view_formats: &[], + }); - fail( - &ctx.device, - || { - // Validation should catch the silly selected z layer range without panicking. - encoder.copy_texture_to_texture( - wgpu::TexelCopyTextureInfo { - texture: &t1, - mip_level: 1, - origin: wgpu::Origin3d::ZERO, - aspect: wgpu::TextureAspect::All, - }, - wgpu::TexelCopyTextureInfo { - texture: &t2, - mip_level: 1, - origin: wgpu::Origin3d { - x: 0, - y: 0, - z: 3824276442, + fail( + &ctx.device, + || { + // Validation should catch the silly selected z layer range without panicking. + encoder.copy_texture_to_texture( + wgpu::TexelCopyTextureInfo { + texture: &t1, + mip_level: 1, + origin: wgpu::Origin3d::ZERO, + aspect: wgpu::TextureAspect::All, + }, + wgpu::TexelCopyTextureInfo { + texture: &t2, + mip_level: 1, + origin: wgpu::Origin3d { + x: 0, + y: 0, + z: 3824276442, + }, + aspect: wgpu::TextureAspect::All, }, - aspect: wgpu::TextureAspect::All, - }, - wgpu::Extent3d { - width: 100, - height: 3, - depth_or_array_layers: 613286111, - }, - ); - ctx.queue.submit(Some(encoder.finish())); - }, - Some("unable to select texture mip level"), - ); -}); + wgpu::Extent3d { + width: 100, + height: 3, + depth_or_array_layers: 613286111, + }, + ); + ctx.queue.submit(Some(encoder.finish())); + }, + Some("unable to select texture mip level"), + ); + }); diff --git a/tests/tests/wgpu-gpu/transition_resources.rs b/tests/tests/wgpu-gpu/transition_resources.rs index 11f9a04b385..f46e5c9bb84 100644 --- a/tests/tests/wgpu-gpu/transition_resources.rs +++ b/tests/tests/wgpu-gpu/transition_resources.rs @@ -1,39 +1,41 @@ -use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; pub fn all_tests(vec: &mut Vec) { vec.push(TRANSITION_RESOURCES); } #[gpu_test] -static TRANSITION_RESOURCES: GpuTestConfiguration = GpuTestConfiguration::new().run_sync(|ctx| { - let texture = ctx.device.create_texture(&wgpu::TextureDescriptor { - label: None, - size: wgpu::Extent3d { - width: 32, - height: 32, - depth_or_array_layers: 1, - }, - mip_level_count: 1, - sample_count: 1, - dimension: wgpu::TextureDimension::D2, - format: wgpu::TextureFormat::Rgba8Unorm, - usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING, - view_formats: &[], - }); +static TRANSITION_RESOURCES: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_sync(|ctx| { + let texture = ctx.device.create_texture(&wgpu::TextureDescriptor { + label: None, + size: wgpu::Extent3d { + width: 32, + height: 32, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rgba8Unorm, + usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING, + view_formats: &[], + }); - let mut encoder = ctx - .device - .create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + let mut encoder = ctx + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); - encoder.transition_resources( - std::iter::empty(), - [wgpu::TextureTransition { - texture: &texture, - selector: None, - state: wgpu::TextureUses::COLOR_TARGET, - }] - .into_iter(), - ); + encoder.transition_resources( + std::iter::empty(), + [wgpu::TextureTransition { + texture: &texture, + selector: None, + state: wgpu::TextureUses::COLOR_TARGET, + }] + .into_iter(), + ); - ctx.queue.submit([encoder.finish()]); -}); + ctx.queue.submit([encoder.finish()]); + }); diff --git a/tests/tests/wgpu-gpu/write_texture.rs b/tests/tests/wgpu-gpu/write_texture.rs index 5ec343259b0..2b6ad11e836 100644 --- a/tests/tests/wgpu-gpu/write_texture.rs +++ b/tests/tests/wgpu-gpu/write_texture.rs @@ -1,7 +1,7 @@ //! Tests for texture copy use wgpu::*; -use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer}; +use wgpu_test::{gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; pub fn all_tests(vec: &mut Vec) { vec.extend([ @@ -199,8 +199,9 @@ static WRITE_TEXTURE_SUBSET_3D: GpuTestConfiguration = }); #[gpu_test] -static WRITE_TEXTURE_NO_OOB: GpuTestConfiguration = - GpuTestConfiguration::new().run_async(|ctx| async move { +static WRITE_TEXTURE_NO_OOB: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_async(|ctx| async move { let size = 256; let tex = ctx.device.create_texture(&wgpu::TextureDescriptor { From fe22fe2bf245ec97472d11c1107a504144656eb7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 4 Aug 2025 09:28:36 -0700 Subject: [PATCH 089/303] Update cts digest to a46bb82 (#8044) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- cts_runner/revision.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cts_runner/revision.txt b/cts_runner/revision.txt index 3b266dec117..f5b9ec29ac0 100644 --- a/cts_runner/revision.txt +++ b/cts_runner/revision.txt @@ -1 +1 @@ -e110f5e8b978a8eb43f243defff6f545b71df96f +a46bb820fc62687ca8c4bfec1657e65c327458fd From 4938f86cfe2bb55c7079f3dd8d395cf926c958c8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 4 Aug 2025 09:29:57 -0700 Subject: [PATCH 090/303] Update Cargo.lock (#8045) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Cargo.lock | 111 +++++++++++++++++++++++++++-------------------------- 1 file changed, 56 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 93ea2a182cc..f7175cce623 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -652,9 +652,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.30" +version = "1.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7" +checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2" dependencies = [ "jobserver", "libc", @@ -743,9 +743,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.41" +version = "4.5.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9" +checksum = "ed87a9d530bb41a67537289bafcac159cb3ee28460e0a4571123d2a778a6a882" dependencies = [ "clap_builder", "clap_derive", @@ -753,9 +753,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.41" +version = "4.5.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d" +checksum = "64f4f3f3c77c94aff3c7e9aac9a2ca1974a5adf392a8bb751e827d6d127ab966" dependencies = [ "anstream", "anstyle", @@ -2284,7 +2284,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.53.2", + "windows-targets 0.53.3", ] [[package]] @@ -2295,13 +2295,13 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4488594b9328dee448adb906d8b126d9b7deb7cf5c22161ee591610bb1be83c0" +checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" dependencies = [ "bitflags 2.9.1", "libc", - "redox_syscall 0.5.16", + "redox_syscall 0.5.17", ] [[package]] @@ -2519,7 +2519,7 @@ dependencies = [ "spirv", "strum 0.27.2", "thiserror 2.0.12", - "toml 0.9.2", + "toml 0.9.4", "unicode-ident", "walkdir", ] @@ -3101,7 +3101,7 @@ dependencies = [ "cfg-if", "libc", "petgraph 0.6.5", - "redox_syscall 0.5.16", + "redox_syscall 0.5.17", "smallvec", "thread-id", "windows-targets 0.52.6", @@ -3241,9 +3241,9 @@ dependencies = [ [[package]] name = "polling" -version = "3.9.0" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee9b2fa7a4517d2c91ff5bc6c297a427a96749d15f98fcdbb22c05571a4d4b7" +checksum = "b5bd19146350fe804f7cb2669c851c03d69da628803dab0d98018142aaa5d829" dependencies = [ "cfg-if", "concurrent-queue", @@ -3481,9 +3481,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.16" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7251471db004e509f4e75a62cca9435365b5ec7bcdff530d612ac7c87c44a792" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ "bitflags 2.9.1", ] @@ -3746,9 +3746,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.141" +version = "1.0.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3" +checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" dependencies = [ "indexmap", "itoa", @@ -3812,9 +3812,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.5" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" dependencies = [ "libc", ] @@ -3899,8 +3899,8 @@ dependencies = [ "wayland-client", "wayland-csd-frame", "wayland-cursor", - "wayland-protocols 0.32.8", - "wayland-protocols-wlr 0.3.8", + "wayland-protocols 0.32.9", + "wayland-protocols-wlr 0.3.9", "wayland-scanner", "xkeysym", ] @@ -4204,9 +4204,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.47.0" +version = "1.47.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43864ed400b6043a4757a25c7a64a8efde741aed79a056a2fb348a406701bb35" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" dependencies = [ "backtrace", "bytes", @@ -4247,9 +4247,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed0aee96c12fa71097902e0bb061a5e1ebd766a6636bb605ba401c45c1650eac" +checksum = "41ae868b5a0f67631c14589f7e250c1ea2c574ee5ba21c6c8dd4b1485705a5a1" dependencies = [ "indexmap", "serde", @@ -4385,9 +4385,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.106" +version = "1.0.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65af40ad689f2527aebbd37a0a816aea88ff5f774ceabe99de5be02f2f91dae2" +checksum = "32e257d7246e7a9fd015fb0b28b330a8d4142151a33f03e6a497754f4b1f6a8e" dependencies = [ "glob", "serde", @@ -4395,7 +4395,7 @@ dependencies = [ "serde_json", "target-triple", "termcolor", - "toml 0.9.2", + "toml 0.9.4", ] [[package]] @@ -4714,13 +4714,13 @@ dependencies = [ [[package]] name = "wayland-backend" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe770181423e5fc79d3e2a7f4410b7799d5aab1de4372853de3c6aa13ca24121" +checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35" dependencies = [ "cc", "downcast-rs", - "rustix 0.38.44", + "rustix 1.0.8", "scoped-tls", "smallvec", "wayland-sys", @@ -4728,12 +4728,12 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.10" +version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978fa7c67b0847dbd6a9f350ca2569174974cd4082737054dbb7fbb79d7d9a61" +checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d" dependencies = [ "bitflags 2.9.1", - "rustix 0.38.44", + "rustix 1.0.8", "wayland-backend", "wayland-scanner", ] @@ -4751,11 +4751,11 @@ dependencies = [ [[package]] name = "wayland-cursor" -version = "0.31.10" +version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a65317158dec28d00416cb16705934070aef4f8393353d41126c54264ae0f182" +checksum = "447ccc440a881271b19e9989f75726d60faa09b95b0200a9b7eb5cc47c3eeb29" dependencies = [ - "rustix 0.38.44", + "rustix 1.0.8", "wayland-client", "xcursor", ] @@ -4774,9 +4774,9 @@ dependencies = [ [[package]] name = "wayland-protocols" -version = "0.32.8" +version = "0.32.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "779075454e1e9a521794fed15886323ea0feda3f8b0fc1390f5398141310422a" +checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901" dependencies = [ "bitflags 2.9.1", "wayland-backend", @@ -4799,14 +4799,14 @@ dependencies = [ [[package]] name = "wayland-protocols-plasma" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fd38cdad69b56ace413c6bcc1fbf5acc5e2ef4af9d5f8f1f9570c0c83eae175" +checksum = "a07a14257c077ab3279987c4f8bb987851bf57081b93710381daea94f2c2c032" dependencies = [ "bitflags 2.9.1", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.8", + "wayland-protocols 0.32.9", "wayland-scanner", ] @@ -4825,22 +4825,22 @@ dependencies = [ [[package]] name = "wayland-protocols-wlr" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cb6cdc73399c0e06504c437fe3cf886f25568dd5454473d565085b36d6a8bbf" +checksum = "efd94963ed43cf9938a090ca4f7da58eb55325ec8200c3848963e98dc25b78ec" dependencies = [ "bitflags 2.9.1", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.8", + "wayland-protocols 0.32.9", "wayland-scanner", ] [[package]] name = "wayland-scanner" -version = "0.31.6" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "896fdafd5d28145fce7958917d69f2fd44469b1d4e861cb5961bcbeebc6d1484" +checksum = "54cb1e9dc49da91950bdfd8b848c49330536d9d1fb03d4bfec8cae50caa50ae3" dependencies = [ "proc-macro2", "quick-xml", @@ -4849,9 +4849,9 @@ dependencies = [ [[package]] name = "wayland-sys" -version = "0.31.6" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbcebb399c77d5aa9fa5db874806ee7b4eba4e73650948e8f93963f128896615" +checksum = "34949b42822155826b41db8e5d0c1be3a2bd296c747577a43a3e6daefc296142" dependencies = [ "dlib", "log", @@ -5459,7 +5459,7 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.2", + "windows-targets 0.53.3", ] [[package]] @@ -5510,10 +5510,11 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.2" +version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" dependencies = [ + "windows-link", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", @@ -5804,8 +5805,8 @@ dependencies = [ "wasm-bindgen-futures", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.8", - "wayland-protocols-plasma 0.3.8", + "wayland-protocols 0.32.9", + "wayland-protocols-plasma 0.3.9", "web-sys", "web-time 1.1.0", "windows-sys 0.52.0", From a1168613d2a1b52629f62d78b79fd66c51e52056 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Tue, 5 Aug 2025 04:37:09 +1200 Subject: [PATCH 091/303] Prevent resources for acceleration structures being created if they are not enabled (#8036) * Prevent resources for acceleration structures being created if acceleration structures aren't supported. --- CHANGELOG.md | 4 ++ tests/tests/wgpu-gpu/ray_tracing/as_create.rs | 45 ++++++++++++++++++- wgpu-core/src/device/resource.rs | 24 +++++++++- wgpu-core/src/resource.rs | 3 ++ 4 files changed, 74 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d9558c36b5..489efaa6080 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,10 @@ By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). ### Changes +#### General + +- Prevent resources for acceleration structures being created if acceleration structures are not enabled. By @Vecvec in [#8036](https://github.com/gfx-rs/wgpu/pull/8036). + #### Naga Naga now requires that no type be larger than 1 GB. This limit may be lowered in the future; feedback on an appropriate value for the limit is welcome. By @andyleiserson in [#7950](https://github.com/gfx-rs/wgpu/pull/7950). diff --git a/tests/tests/wgpu-gpu/ray_tracing/as_create.rs b/tests/tests/wgpu-gpu/ray_tracing/as_create.rs index 19edb096be2..8f424c5f1bf 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/as_create.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/as_create.rs @@ -9,7 +9,11 @@ use wgpu_macros::gpu_test; use wgpu_test::{fail, GpuTestConfiguration, TestParameters, TestingContext}; pub fn all_tests(tests: &mut Vec) { - tests.extend([BLAS_INVALID_VERTEX_FORMAT, BLAS_MISMATCHED_INDEX]); + tests.extend([ + BLAS_INVALID_VERTEX_FORMAT, + BLAS_MISMATCHED_INDEX, + UNSUPPORTED_ACCELERATION_STRUCTURE_RESOURCES, + ]); } #[gpu_test] @@ -124,3 +128,42 @@ fn mismatched_index_blas_create(ctx: TestingContext) { None, ); } + +#[gpu_test] +static UNSUPPORTED_ACCELERATION_STRUCTURE_RESOURCES: GpuTestConfiguration = + GpuTestConfiguration::new() + .parameters(TestParameters::default().test_features_limits()) + .run_sync(unsupported_acceleration_structure_resources); + +fn unsupported_acceleration_structure_resources(ctx: TestingContext) { + fail( + &ctx.device, + || { + ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 4, + usage: wgpu::BufferUsages::BLAS_INPUT, + mapped_at_creation: false, + }) + }, + None, + ); + fail( + &ctx.device, + || { + ctx.device + .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: None, + entries: &[wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::COMPUTE, + ty: wgpu::BindingType::AccelerationStructure { + vertex_return: false, + }, + count: None, + }], + }) + }, + None, + ); +} diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 5fe0de4134c..68a425c0594 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -795,6 +795,13 @@ impl Device { }); } + if desc + .usage + .intersects(wgt::BufferUsages::BLAS_INPUT | wgt::BufferUsages::TLAS_INPUT) + { + self.require_features(wgt::Features::EXPERIMENTAL_RAY_QUERY)?; + } + if desc.usage.contains(wgt::BufferUsages::INDEX) && desc.usage.contains( wgt::BufferUsages::VERTEX @@ -2303,7 +2310,22 @@ impl Device { }, ) } - Bt::AccelerationStructure { .. } => (None, WritableStorage::No), + Bt::AccelerationStructure { vertex_return } => { + self.require_features(wgt::Features::EXPERIMENTAL_RAY_QUERY) + .map_err(|e| binding_model::CreateBindGroupLayoutError::Entry { + binding: entry.binding, + error: e.into(), + })?; + if vertex_return { + self.require_features(wgt::Features::EXPERIMENTAL_RAY_HIT_VERTEX_RETURN) + .map_err(|e| binding_model::CreateBindGroupLayoutError::Entry { + binding: entry.binding, + error: e.into(), + })?; + } + + (None, WritableStorage::No) + } Bt::ExternalTexture => { self.require_features(wgt::Features::EXTERNAL_TEXTURE) .map_err(|e| binding_model::CreateBindGroupLayoutError::Entry { diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 6fe4d794bd3..8d51298a711 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -912,6 +912,8 @@ pub enum CreateBufferError { MaxBufferSize { requested: u64, maximum: u64 }, #[error(transparent)] MissingDownlevelFlags(#[from] MissingDownlevelFlags), + #[error(transparent)] + MissingFeatures(#[from] MissingFeatures), #[error("Failed to create bind group for indirect buffer validation: {0}")] IndirectValidationBindGroup(DeviceError), } @@ -929,6 +931,7 @@ impl WebGpuError for CreateBufferError { Self::AccessError(e) => e, Self::MissingDownlevelFlags(e) => e, Self::IndirectValidationBindGroup(e) => e, + Self::MissingFeatures(e) => e, Self::UnalignedSize | Self::InvalidUsage(_) From 7cb642eba7bb3f25dff14ce9a7b7916c2911b314 Mon Sep 17 00:00:00 2001 From: atlv Date: Tue, 5 Aug 2025 10:43:54 -0400 Subject: [PATCH 092/303] fix STATUS_HEAP_CORRUPTION crash in create_sampler (#8043) Co-authored-by: Erich Gubler --- CHANGELOG.md | 6 ++++++ wgpu-hal/src/vulkan/device.rs | 12 +++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 489efaa6080..4360ce16004 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,12 @@ By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). Naga now requires that no type be larger than 1 GB. This limit may be lowered in the future; feedback on an appropriate value for the limit is welcome. By @andyleiserson in [#7950](https://github.com/gfx-rs/wgpu/pull/7950). +### Bug Fixes + +#### Vulkan + +Fix `STATUS_HEAP_CORRUPTION` crash when concurrently calling `create_sampler`. By @atlv24 in [#8043](https://github.com/gfx-rs/wgpu/pull/8043). + ## v26.0.2 (2025-07-23) ### Bug Fixes diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 87054416922..1d229635317 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -1404,19 +1404,21 @@ impl crate::Device for super::Device { create_info = create_info.border_color(conv::map_border_color(color)); } - let raw = self - .shared - .sampler_cache - .lock() - .create_sampler(&self.shared.raw, create_info)?; + let mut sampler_cache_guard = self.shared.sampler_cache.lock(); + + let raw = sampler_cache_guard.create_sampler(&self.shared.raw, create_info)?; // Note: Cached samplers will just continually overwrite the label // // https://github.com/gfx-rs/wgpu/issues/6867 if let Some(label) = desc.label { + // SAFETY: we are holding a lock on the sampler cache, + // so we can only be setting the name from one thread. unsafe { self.shared.set_object_name(raw, label) }; } + drop(sampler_cache_guard); + self.counters.samplers.add(1); Ok(super::Sampler { raw, create_info }) From 910143d622e9bc3b3237b0ad2018574e49b6fadc Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Tue, 5 Aug 2025 07:52:50 -0700 Subject: [PATCH 093/303] Check for more cases of unbalanced debug groups (#8048) Fixes #3911 --- cts_runner/test.lst | 14 ++++++++----- deno_webgpu/render_bundle.rs | 12 ++++++++--- wgpu-core/src/command/compute.rs | 15 ++++++++++---- wgpu-core/src/command/mod.rs | 34 ++++++++++++++++++++++++++++++++ wgpu-core/src/command/pass.rs | 16 +++------------ wgpu-core/src/command/render.rs | 17 +++++++++++----- 6 files changed, 78 insertions(+), 30 deletions(-) diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 727530d299d..26c1db582eb 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -25,6 +25,13 @@ webgpu:api,validation,encoding,cmds,clearBuffer:* webgpu:api,validation,encoding,cmds,compute_pass:set_pipeline:* webgpu:api,validation,encoding,cmds,compute_pass:dispatch_sizes:* webgpu:api,validation,encoding,cmds,copyTextureToTexture:* +webgpu:api,validation,encoding,cmds,debug:debug_group_balanced:encoderType="non-pass" +webgpu:api,validation,encoding,cmds,debug:debug_group_balanced:encoderType="compute%20pass" +webgpu:api,validation,encoding,cmds,debug:debug_group_balanced:encoderType="render%20pass" +//FAIL: webgpu:api,validation,encoding,cmds,debug:debug_group_balanced:encoderType="render%20bundle" +// https://github.com/gfx-rs/wgpu/issues/8039 +webgpu:api,validation,encoding,cmds,debug:debug_group:* +webgpu:api,validation,encoding,cmds,debug:debug_marker:* webgpu:api,validation,encoding,cmds,index_access:* //FAIL: webgpu:api,validation,encoding,cmds,render,draw:* webgpu:api,validation,encoding,cmds,render,draw:index_buffer_OOB:* @@ -75,11 +82,7 @@ webgpu:api,validation,image_copy,layout_related:copy_end_overflows_u64:* // Fails with OOM in CI. fails-if(dx12) webgpu:api,validation,image_copy,layout_related:offset_alignment:* webgpu:api,validation,image_copy,texture_related:format:dimension="1d";* -webgpu:api,validation,queue,submit:command_buffer,device_mismatch:* -webgpu:api,validation,queue,submit:command_buffer,duplicate_buffers:* -webgpu:api,validation,queue,submit:command_buffer,submit_invalidates:* -//FAIL: webgpu:api,validation,queue,submit:command_buffer,invalid_submit_invalidates:* -// https://github.com/gfx-rs/wgpu/issues/3911#issuecomment-2972995675 +webgpu:api,validation,queue,submit:command_buffer,* webgpu:api,validation,render_pass,render_pass_descriptor:attachments,* webgpu:api,validation,render_pass,render_pass_descriptor:resolveTarget,* webgpu:api,validation,texture,rg11b10ufloat_renderable:* @@ -93,6 +96,7 @@ webgpu:api,operation,rendering,color_target_state:blend_constant,setting:* webgpu:api,operation,rendering,depth:* webgpu:api,operation,rendering,draw:* webgpu:api,operation,shader_module,compilation_info:* +// Likely due to https://github.com/gfx-rs/wgpu/issues/7357. fails-if(metal) webgpu:api,operation,uncapturederror:iff_uncaptured:* //FAIL: webgpu:shader,execution,expression,call,builtin,select:* // - Fails with `const`/abstract int cases on all platforms because of . diff --git a/deno_webgpu/render_bundle.rs b/deno_webgpu/render_bundle.rs index de6dec87815..da31929d84a 100644 --- a/deno_webgpu/render_bundle.rs +++ b/deno_webgpu/render_bundle.rs @@ -20,6 +20,13 @@ use crate::buffer::GPUBuffer; use crate::texture::GPUTextureFormat; use crate::Instance; +fn c_string_truncated_at_first_nul>>(src: T) -> std::ffi::CString { + std::ffi::CString::new(src).unwrap_or_else(|err| { + let nul_pos = err.nul_position(); + std::ffi::CString::new(err.into_vec().split_at(nul_pos).0).unwrap() + }) +} + pub struct GPURenderBundleEncoder { pub instance: Instance, pub error_handler: super::error::ErrorHandler, @@ -70,7 +77,7 @@ impl GPURenderBundleEncoder { .as_mut() .ok_or_else(|| JsErrorBox::generic("Encoder has already been finished"))?; - let label = std::ffi::CString::new(group_label).unwrap(); + let label = c_string_truncated_at_first_nul(group_label); // SAFETY: the string the raw pointer points to lives longer than the below // function invocation. unsafe { @@ -99,8 +106,7 @@ impl GPURenderBundleEncoder { .as_mut() .ok_or_else(|| JsErrorBox::generic("Encoder has already been finished"))?; - let label = std::ffi::CString::new(marker_label).unwrap(); - + let label = c_string_truncated_at_first_nul(marker_label); // SAFETY: the string the raw pointer points to lives longer than the below // function invocation. unsafe { diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index 3d26d60ea79..0d8aaf27eb2 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -8,7 +8,7 @@ use alloc::{borrow::Cow, boxed::Box, sync::Arc, vec::Vec}; use core::{fmt, str}; use crate::command::{ - pass, CommandEncoder, EncoderStateError, PassStateError, TimestampWritesError, + pass, CommandEncoder, DebugGroupError, EncoderStateError, PassStateError, TimestampWritesError, }; use crate::resource::DestroyedResourceError; use crate::{binding_model::BindError, resource::RawResourceAccess}; @@ -146,6 +146,8 @@ pub enum ComputePassErrorInner { #[error("Parent encoder is invalid")] InvalidParentEncoder, #[error(transparent)] + DebugGroupError(#[from] DebugGroupError), + #[error(transparent)] BindGroupIndexOutOfRange(#[from] pass::BindGroupIndexOutOfRange), #[error(transparent)] DestroyedResource(#[from] DestroyedResourceError), @@ -162,8 +164,6 @@ pub enum ComputePassErrorInner { #[error(transparent)] MissingBufferUsage(#[from] MissingBufferUsageError), #[error(transparent)] - InvalidPopDebugGroup(#[from] pass::InvalidPopDebugGroup), - #[error(transparent)] Dispatch(#[from] DispatchError), #[error(transparent)] Bind(#[from] BindError), @@ -226,6 +226,7 @@ impl WebGpuError for ComputePassError { let e: &dyn WebGpuError = match inner { ComputePassErrorInner::Device(e) => e, ComputePassErrorInner::EncoderState(e) => e, + ComputePassErrorInner::DebugGroupError(e) => e, ComputePassErrorInner::DestroyedResource(e) => e, ComputePassErrorInner::ResourceUsageCompatibility(e) => e, ComputePassErrorInner::MissingBufferUsage(e) => e, @@ -238,7 +239,6 @@ impl WebGpuError for ComputePassError { ComputePassErrorInner::InvalidResource(e) => e, ComputePassErrorInner::TimestampWrites(e) => e, ComputePassErrorInner::InvalidValuesOffset(e) => e, - ComputePassErrorInner::InvalidPopDebugGroup(e) => e, ComputePassErrorInner::InvalidParentEncoder | ComputePassErrorInner::BindGroupIndexOutOfRange { .. } @@ -734,6 +734,13 @@ impl Global { } } + if state.general.debug_scope_depth > 0 { + Err( + ComputePassErrorInner::DebugGroupError(DebugGroupError::MissingPop) + .map_pass_err(pass_scope), + )?; + } + unsafe { state.general.raw_encoder.end_compute_pass(); } diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 3abcf8307c6..2467784d57a 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -284,6 +284,10 @@ impl CommandEncoderStatus { Self::Recording(mut inner) => { if let Err(err) = inner.encoder.close_if_open() { Self::Error(err.into()) + } else if inner.debug_scope_depth > 0 { + Self::Error(CommandEncoderError::DebugGroupError( + DebugGroupError::MissingPop, + )) } else { // Note: if we want to stop tracking the swapchain texture view, // this is the place to do it. @@ -648,6 +652,8 @@ pub struct CommandBufferMutable { indirect_draw_validation_resources: crate::indirect_validation::DrawResources, + debug_scope_depth: u32, + #[cfg(feature = "trace")] pub(crate) commands: Option>, } @@ -721,6 +727,7 @@ impl CommandEncoder { temp_resources: Default::default(), indirect_draw_validation_resources: crate::indirect_validation::DrawResources::new(device.clone()), + debug_scope_depth: 0, #[cfg(feature = "trace")] commands: if device.trace.lock().is_some() { Some(Vec::new()) @@ -1041,6 +1048,8 @@ pub enum CommandEncoderError { #[error(transparent)] ResourceUsage(#[from] ResourceUsageCompatibilityError), #[error(transparent)] + DebugGroupError(#[from] DebugGroupError), + #[error(transparent)] MissingFeatures(#[from] MissingFeatures), #[error(transparent)] Transfer(#[from] TransferError), @@ -1094,6 +1103,7 @@ impl WebGpuError for CommandEncoderError { let e: &dyn WebGpuError = match self { Self::Device(e) => e, Self::InvalidResource(e) => e, + Self::DebugGroupError(e) => e, Self::MissingFeatures(e) => e, Self::State(e) => e, Self::DestroyedResource(e) => e, @@ -1110,6 +1120,23 @@ impl WebGpuError for CommandEncoderError { } } +#[derive(Clone, Debug, Error)] +#[non_exhaustive] +pub enum DebugGroupError { + #[error("Cannot pop debug group, because number of pushed debug groups is zero")] + InvalidPop, + #[error("A debug group was not popped before the encoder was finished")] + MissingPop, +} + +impl WebGpuError for DebugGroupError { + fn webgpu_error_type(&self) -> ErrorType { + match self { + Self::InvalidPop | Self::MissingPop => ErrorType::Validation, + } + } +} + #[derive(Clone, Debug, Error)] #[non_exhaustive] pub enum TimestampWritesError { @@ -1175,6 +1202,8 @@ impl Global { let cmd_enc = hub.command_encoders.get(encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { + cmd_buf_data.debug_scope_depth += 1; + #[cfg(feature = "trace")] if let Some(ref mut list) = cmd_buf_data.commands { list.push(TraceCommand::PushDebugGroup(label.to_owned())); @@ -1244,6 +1273,11 @@ impl Global { let cmd_enc = hub.command_encoders.get(encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { + if cmd_buf_data.debug_scope_depth == 0 { + return Err(DebugGroupError::InvalidPop.into()); + } + cmd_buf_data.debug_scope_depth -= 1; + #[cfg(feature = "trace")] if let Some(ref mut list) = cmd_buf_data.commands { list.push(TraceCommand::PopDebugGroup); diff --git a/wgpu-core/src/command/pass.rs b/wgpu-core/src/command/pass.rs index 146711ced17..916f99118e0 100644 --- a/wgpu-core/src/command/pass.rs +++ b/wgpu-core/src/command/pass.rs @@ -3,7 +3,7 @@ use crate::binding_model::{BindError, BindGroup, PushConstantUploadError}; use crate::command::bind::Binder; use crate::command::memory_init::{CommandBufferTextureMemoryActions, SurfacesInDiscardState}; -use crate::command::{CommandEncoder, QueryResetMap, QueryUseError}; +use crate::command::{CommandEncoder, DebugGroupError, QueryResetMap, QueryUseError}; use crate::device::{Device, DeviceError, MissingFeatures}; use crate::init_tracker::BufferInitTrackerAction; use crate::pipeline::LateSizedBufferGroup; @@ -42,16 +42,6 @@ impl WebGpuError for InvalidValuesOffset { } } -#[derive(Clone, Debug, Error)] -#[error("Cannot pop debug group, because number of pushed debug groups is zero")] -pub struct InvalidPopDebugGroup; - -impl WebGpuError for InvalidPopDebugGroup { - fn webgpu_error_type(&self) -> ErrorType { - ErrorType::Validation - } -} - pub(crate) struct BaseState<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { pub(crate) device: &'cmd_enc Arc, @@ -332,12 +322,12 @@ pub(crate) fn push_debug_group(state: &mut BaseState, string_data: &[u8], len: u pub(crate) fn pop_debug_group(state: &mut BaseState) -> Result<(), E> where - E: From, + E: From, { api_log!("Pass::pop_debug_group"); if state.debug_scope_depth == 0 { - return Err(InvalidPopDebugGroup.into()); + return Err(DebugGroupError::InvalidPop.into()); } state.debug_scope_depth -= 1; if !state diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 12d5bc86d15..abc8163c63a 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -11,8 +11,8 @@ use wgt::{ use crate::command::{ pass, pass_base, pass_try, validate_and_begin_occlusion_query, - validate_and_begin_pipeline_statistics_query, EncoderStateError, InnerCommandEncoder, - PassStateError, TimestampWritesError, + validate_and_begin_pipeline_statistics_query, DebugGroupError, EncoderStateError, + InnerCommandEncoder, PassStateError, TimestampWritesError, }; use crate::pipeline::{RenderPipeline, VertexStep}; use crate::resource::RawResourceAccess; @@ -671,6 +671,8 @@ pub enum RenderPassErrorInner { EncoderState(#[from] EncoderStateError), #[error("Parent encoder is invalid")] InvalidParentEncoder, + #[error(transparent)] + DebugGroupError(#[from] DebugGroupError), #[error("The format of the {location} ({format:?}) is not resolvable")] UnsupportedResolveTargetFormat { location: AttachmentErrorLocation, @@ -738,8 +740,6 @@ pub enum RenderPassErrorInner { count_buffer_size: u64, }, #[error(transparent)] - InvalidPopDebugGroup(#[from] pass::InvalidPopDebugGroup), - #[error(transparent)] ResourceUsageCompatibility(#[from] ResourceUsageCompatibilityError), #[error("Render bundle has incompatible targets, {0}")] IncompatibleBundleTargets(#[from] RenderPassCompatibilityError), @@ -842,6 +842,7 @@ impl WebGpuError for RenderPassError { RenderPassErrorInner::Device(e) => e, RenderPassErrorInner::ColorAttachment(e) => e, RenderPassErrorInner::EncoderState(e) => e, + RenderPassErrorInner::DebugGroupError(e) => e, RenderPassErrorInner::MissingFeatures(e) => e, RenderPassErrorInner::MissingDownlevelFlags(e) => e, RenderPassErrorInner::RenderCommand(e) => e, @@ -854,7 +855,6 @@ impl WebGpuError for RenderPassError { RenderPassErrorInner::InvalidAttachment(e) => e, RenderPassErrorInner::TimestampWrites(e) => e, RenderPassErrorInner::InvalidValuesOffset(e) => e, - RenderPassErrorInner::InvalidPopDebugGroup(e) => e, RenderPassErrorInner::InvalidParentEncoder | RenderPassErrorInner::UnsupportedResolveTargetFormat { .. } @@ -2220,6 +2220,13 @@ impl Global { } } + if state.general.debug_scope_depth > 0 { + Err( + RenderPassErrorInner::DebugGroupError(DebugGroupError::MissingPop) + .map_pass_err(pass_scope), + )?; + } + state .info .finish( From 88a814719492bb9f4a2893ae8d7094ac9d5f1f95 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Tue, 5 Aug 2025 19:35:20 -0400 Subject: [PATCH 094/303] test(deno_webgpu): add `--release` to `cargo xtask cts` (#8053) --- xtask/src/cts.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/xtask/src/cts.rs b/xtask/src/cts.rs index 31f3fad3493..2dfbb2013f7 100644 --- a/xtask/src/cts.rs +++ b/xtask/src/cts.rs @@ -63,6 +63,7 @@ struct TestLine { pub fn run_cts(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { let skip_checkout = args.contains("--skip-checkout"); let llvm_cov = args.contains("--llvm-cov"); + let release = args.contains("--release"); let running_on_backend = args.opt_value_from_str::<_, String>("--backend")?; if running_on_backend.is_none() { @@ -220,13 +221,18 @@ pub fn run_cts(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { } log::info!("Running {}", test.selector.to_string_lossy()); - shell + let mut cmd = shell .cmd("cargo") .args(run_flags) .args(["--manifest-path".as_ref(), wgpu_cargo_toml.as_os_str()]) .args(["-p", "cts_runner"]) - .args(["--bin", "cts_runner"]) - .args(["--", "./tools/run_deno", "--verbose"]) + .args(["--bin", "cts_runner"]); + + if release { + cmd = cmd.arg("--release") + } + + cmd.args(["--", "./tools/run_deno", "--verbose"]) .args([&test.selector]) .run() .context("CTS failed")?; From 8cd4bd602fdc09aef3692ab018f17eca21422712 Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Wed, 25 Jun 2025 08:48:57 +0100 Subject: [PATCH 095/303] [naga hlsl-out] Handle external texture color space conversion This adds several fields to `ExternalTextureDescriptor`, specifying how to handle color space conversion for an external texture. These fields consist of transfer functions for the source and destination color spaces, and a matrix for converting between gamuts. This allows `ImageSample` and `ImageLoad` operations on external textures to return values in a desired destination color space rather than the source color space of the underlying planes. These fields are plumbed through to the `ExternalTextureParams` uniform buffer from which they are exposed to the shader. Following conversion from YUV to RGB after sampling/loading from the external texture planes, the shader uses them to gamma decode to linear RGB in the source color space, convert from source to destination gamut, then finally gamma encode to non-linear RGB in the destination color space. --- naga/src/back/hlsl/help.rs | 70 +++++++++-- naga/src/back/wgsl/writer.rs | 1 + naga/src/compact/mod.rs | 11 ++ naga/src/front/type_gen.rs | 105 ++++++++++++++--- naga/src/front/wgsl/lower/mod.rs | 13 ++- naga/src/ir/mod.rs | 41 +++++-- .../tests/out/hlsl/wgsl-texture-external.hlsl | 31 ++++- naga/tests/out/ir/spv-fetch_depth.compact.ron | 1 + naga/tests/out/ir/spv-fetch_depth.ron | 1 + naga/tests/out/ir/spv-shadow.compact.ron | 1 + naga/tests/out/ir/spv-shadow.ron | 1 + .../out/ir/spv-spec-constants.compact.ron | 1 + naga/tests/out/ir/spv-spec-constants.ron | 1 + naga/tests/out/ir/wgsl-access.compact.ron | 1 + naga/tests/out/ir/wgsl-access.ron | 1 + naga/tests/out/ir/wgsl-collatz.compact.ron | 1 + naga/tests/out/ir/wgsl-collatz.ron | 1 + .../out/ir/wgsl-const_assert.compact.ron | 1 + naga/tests/out/ir/wgsl-const_assert.ron | 1 + .../out/ir/wgsl-diagnostic-filter.compact.ron | 1 + naga/tests/out/ir/wgsl-diagnostic-filter.ron | 1 + .../out/ir/wgsl-index-by-value.compact.ron | 1 + naga/tests/out/ir/wgsl-index-by-value.ron | 1 + .../tests/out/ir/wgsl-local-const.compact.ron | 1 + naga/tests/out/ir/wgsl-local-const.ron | 1 + naga/tests/out/ir/wgsl-must-use.compact.ron | 1 + naga/tests/out/ir/wgsl-must-use.ron | 1 + ...ides-atomicCompareExchangeWeak.compact.ron | 1 + ...sl-overrides-atomicCompareExchangeWeak.ron | 1 + .../ir/wgsl-overrides-ray-query.compact.ron | 1 + .../tests/out/ir/wgsl-overrides-ray-query.ron | 1 + naga/tests/out/ir/wgsl-overrides.compact.ron | 1 + naga/tests/out/ir/wgsl-overrides.ron | 1 + .../out/ir/wgsl-storage-textures.compact.ron | 1 + naga/tests/out/ir/wgsl-storage-textures.ron | 1 + ...l-template-list-trailing-comma.compact.ron | 1 + .../ir/wgsl-template-list-trailing-comma.ron | 1 + .../out/ir/wgsl-texture-external.compact.ron | 109 ++++++++++++++---- naga/tests/out/ir/wgsl-texture-external.ron | 109 ++++++++++++++---- .../ir/wgsl-types_with_comments.compact.ron | 1 + .../tests/out/ir/wgsl-types_with_comments.ron | 1 + .../wgpu-validation/api/external_texture.rs | 45 ++++++++ wgpu-core/src/device/resource.rs | 57 ++++++++- wgpu-types/src/lib.rs | 49 ++++++++ wgpu/src/lib.rs | 29 ++--- 45 files changed, 604 insertions(+), 98 deletions(-) diff --git a/naga/src/back/hlsl/help.rs b/naga/src/back/hlsl/help.rs index 70c0a692a33..8083d15e863 100644 --- a/naga/src/back/hlsl/help.rs +++ b/naga/src/back/hlsl/help.rs @@ -264,6 +264,61 @@ impl super::Writer<'_, W> { Ok(()) } + /// Helper function used by [`Self::write_wrapped_image_load_function`] and + /// [`Self::write_wrapped_image_sample_function`] to write the shared YUV + /// to RGB conversion code for external textures. Expects the preceding + /// code to declare the Y component as a `float` variable of name `y`, the + /// UV components as a `float2` variable of name `uv`, and the external + /// texture params as a variable of name `params`. The emitted code will + /// return the result. + fn write_convert_yuv_to_rgb_and_return( + &mut self, + level: crate::back::Level, + y: &str, + uv: &str, + params: &str, + ) -> BackendResult { + let l1 = level; + let l2 = l1.next(); + + // Convert from YUV to non-linear RGB in the source color space. We + // declare our matrices as row_major in HLSL, therefore we must reverse + // the order of this multiplication + writeln!( + self.out, + "{l1}float3 srcGammaRgb = mul(float4({y}, {uv}, 1.0), {params}.yuv_conversion_matrix).rgb;" + )?; + + // Apply the inverse of the source transfer function to convert to + // linear RGB in the source color space. + writeln!( + self.out, + "{l1}float3 srcLinearRgb = srcGammaRgb < {params}.src_tf.k * {params}.src_tf.b ?" + )?; + writeln!(self.out, "{l2}srcGammaRgb / {params}.src_tf.k :")?; + writeln!(self.out, "{l2}pow((srcGammaRgb + {params}.src_tf.a - 1.0) / {params}.src_tf.a, {params}.src_tf.g);")?; + + // Multiply by the gamut conversion matrix to convert to linear RGB in + // the destination color space. We declare our matrices as row_major in + // HLSL, therefore we must reverse the order of this multiplication. + writeln!( + self.out, + "{l1}float3 dstLinearRgb = mul(srcLinearRgb, {params}.gamut_conversion_matrix);" + )?; + + // Finally, apply the dest transfer function to convert to non-linear + // RGB in the destination color space, and return the result. + writeln!( + self.out, + "{l1}float3 dstGammaRgb = dstLinearRgb < {params}.dst_tf.b ?" + )?; + writeln!(self.out, "{l2}{params}.dst_tf.k * dstLinearRgb :")?; + writeln!(self.out, "{l2}{params}.dst_tf.a * pow(dstLinearRgb, 1.0 / {params}.dst_tf.g) - ({params}.dst_tf.a - 1);")?; + + writeln!(self.out, "{l1}return float4(dstGammaRgb, 1.0);")?; + Ok(()) + } + pub(super) fn write_wrapped_image_load_function( &mut self, module: &crate::Module, @@ -346,12 +401,7 @@ impl super::Writer<'_, W> { writeln!(self.out, "{l3}uv = float2(plane1.Load(uint3(plane1_coords, 0u)).x, plane2.Load(uint3(plane2_coords, 0u)).x);")?; writeln!(self.out, "{l2}}}")?; - // Convert from YUV to RGB. We declare our matrices as row_major in HLSL, - // therefore we must reverse the order of this multiplication - writeln!( - self.out, - "{l2}return mul(float4(y, uv, 1.0), params.yuv_conversion_matrix);" - )?; + self.write_convert_yuv_to_rgb_and_return(l2, "y", "uv", "params")?; writeln!(self.out, "{l1}}}")?; writeln!(self.out, "}}")?; @@ -478,12 +528,8 @@ impl super::Writer<'_, W> { writeln!(self.out, "{l3}uv = float2(plane1.SampleLevel(samp, plane1_coords, 0.0f).x, plane2.SampleLevel(samp, plane2_coords, 0.0f).x);")?; writeln!(self.out, "{l2}}}")?; - // Convert from YUV to RGB. We declare our matrices as row_major in HLSL, - // therefore we must reverse the order of this multiplication - writeln!( - self.out, - "{l2}return mul(float4(y, uv, 1.0), params.yuv_conversion_matrix);" - )?; + self.write_convert_yuv_to_rgb_and_return(l2, "y", "uv", "params")?; + writeln!(self.out, "{l1}}}")?; writeln!(self.out, "}}")?; writeln!(self.out)?; diff --git a/naga/src/back/wgsl/writer.rs b/naga/src/back/wgsl/writer.rs index dd2696c17f7..8982242daca 100644 --- a/naga/src/back/wgsl/writer.rs +++ b/naga/src/back/wgsl/writer.rs @@ -131,6 +131,7 @@ impl Writer { .values() .any(|t| *t == ty) || Some(ty) == module.special_types.external_texture_params + || Some(ty) == module.special_types.external_texture_transfer_function } pub fn write(&mut self, module: &Module, info: &valid::ModuleInfo) -> BackendResult { diff --git a/naga/src/compact/mod.rs b/naga/src/compact/mod.rs index 7fbb5c532f2..d059ba21e4f 100644 --- a/naga/src/compact/mod.rs +++ b/naga/src/compact/mod.rs @@ -381,6 +381,7 @@ impl<'module> ModuleTracer<'module> { ref ray_vertex_return, ref predeclared_types, ref external_texture_params, + ref external_texture_transfer_function, } = *special_types; if let Some(ray_desc) = *ray_desc { @@ -398,6 +399,9 @@ impl<'module> ModuleTracer<'module> { if let Some(external_texture_params) = *external_texture_params { self.types_used.insert(external_texture_params); } + if let Some(external_texture_transfer_function) = *external_texture_transfer_function { + self.types_used.insert(external_texture_transfer_function); + } for (_, &handle) in predeclared_types { self.types_used.insert(handle); } @@ -540,6 +544,7 @@ impl ModuleMap { ref mut ray_vertex_return, ref mut predeclared_types, ref mut external_texture_params, + ref mut external_texture_transfer_function, } = *special; if let Some(ref mut ray_desc) = *ray_desc { @@ -557,6 +562,12 @@ impl ModuleMap { self.types.adjust(external_texture_params); } + if let Some(ref mut external_texture_transfer_function) = + *external_texture_transfer_function + { + self.types.adjust(external_texture_transfer_function); + } + for handle in predeclared_types.values_mut() { self.types.adjust(handle); } diff --git a/naga/src/front/type_gen.rs b/naga/src/front/type_gen.rs index d58561796bd..4165f051db0 100644 --- a/naga/src/front/type_gen.rs +++ b/naga/src/front/type_gen.rs @@ -276,14 +276,29 @@ impl crate::Module { handle } - /// Generate [`SpecialTypes::external_texture_params`]. + /// Generate [`SpecialTypes::external_texture_params`] and + /// [`SpecialTypes::external_texture_transfer_function`]. + /// + /// Other than the WGSL backend, every backend that supports external + /// textures does so by lowering them to a set of ordinary textures and + /// some parameters saying how to sample from them. These types are used + /// for said parameters. Note that they are not used by the IR, but + /// generated purely as a convenience for the backends. /// /// [`SpecialTypes::external_texture_params`]: crate::ir::SpecialTypes::external_texture_params - pub fn generate_external_texture_params_type(&mut self) -> Handle { - if let Some(handle) = self.special_types.external_texture_params { - return handle; + /// [`SpecialTypes::external_texture_transfer_function`]: crate::ir::SpecialTypes::external_texture_transfer_function + pub fn generate_external_texture_types(&mut self) { + if self.special_types.external_texture_params.is_some() { + return; } + let ty_f32 = self.types.insert( + crate::Type { + name: None, + inner: crate::TypeInner::Scalar(crate::Scalar::F32), + }, + Span::UNDEFINED, + ); let ty_u32 = self.types.insert( crate::Type { name: None, @@ -312,6 +327,17 @@ impl crate::Module { }, Span::UNDEFINED, ); + let ty_mat3x3f = self.types.insert( + crate::Type { + name: None, + inner: crate::TypeInner::Matrix { + columns: crate::VectorSize::Tri, + rows: crate::VectorSize::Tri, + scalar: crate::Scalar::F32, + }, + }, + Span::UNDEFINED, + ); let ty_mat4x4f = self.types.insert( crate::Type { name: None, @@ -324,7 +350,44 @@ impl crate::Module { Span::UNDEFINED, ); - let handle = self.types.insert( + let transfer_fn_handle = self.types.insert( + crate::Type { + name: Some("NagaExternalTextureTransferFn".to_string()), + inner: crate::TypeInner::Struct { + members: vec![ + crate::StructMember { + name: Some("a".to_string()), + ty: ty_f32, + binding: None, + offset: 0, + }, + crate::StructMember { + name: Some("b".to_string()), + ty: ty_f32, + binding: None, + offset: 4, + }, + crate::StructMember { + name: Some("g".to_string()), + ty: ty_f32, + binding: None, + offset: 8, + }, + crate::StructMember { + name: Some("k".to_string()), + ty: ty_f32, + binding: None, + offset: 12, + }, + ], + span: 16, + }, + }, + Span::UNDEFINED, + ); + self.special_types.external_texture_transfer_function = Some(transfer_fn_handle); + + let params_handle = self.types.insert( crate::Type { name: Some("NagaExternalTextureParams".to_string()), inner: crate::TypeInner::Struct { @@ -335,39 +398,55 @@ impl crate::Module { binding: None, offset: 0, }, + crate::StructMember { + name: Some("gamut_conversion_matrix".to_string()), + ty: ty_mat3x3f, + binding: None, + offset: 64, + }, + crate::StructMember { + name: Some("src_tf".to_string()), + ty: transfer_fn_handle, + binding: None, + offset: 112, + }, + crate::StructMember { + name: Some("dst_tf".to_string()), + ty: transfer_fn_handle, + binding: None, + offset: 128, + }, crate::StructMember { name: Some("sample_transform".to_string()), ty: ty_mat3x2f, binding: None, - offset: 64, + offset: 144, }, crate::StructMember { name: Some("load_transform".to_string()), ty: ty_mat3x2f, binding: None, - offset: 88, + offset: 168, }, crate::StructMember { name: Some("size".to_string()), ty: ty_vec2u, binding: None, - offset: 112, + offset: 192, }, crate::StructMember { name: Some("num_planes".to_string()), ty: ty_u32, binding: None, - offset: 120, + offset: 200, }, ], - span: 128, + span: 208, }, }, Span::UNDEFINED, ); - - self.special_types.external_texture_params = Some(handle); - handle + self.special_types.external_texture_params = Some(params_handle); } /// Populate this module's [`SpecialTypes::predeclared_types`] type and return the handle. diff --git a/naga/src/front/wgsl/lower/mod.rs b/naga/src/front/wgsl/lower/mod.rs index 3b6e7806c32..e90d7eab0a8 100644 --- a/naga/src/front/wgsl/lower/mod.rs +++ b/naga/src/front/wgsl/lower/mod.rs @@ -3991,14 +3991,15 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { // sample from them. We don't know which backend will // consume the `Module` we're building, but in case it's not // WGSL, populate `SpecialTypes::external_texture_params` - // with the type the backend will use for the parameter + // and `SpecialTypes::external_texture_transfer_function` + // with the types the backend will use for the parameter // buffer. // - // This is *not* the type we are lowering here: that's an - // ordinary `TypeInner::Image`. But the fact we are - // lowering a `texture_external` implies the backends may - // need `SpecialTypes::external_texture_params` too. - ctx.module.generate_external_texture_params_type(); + // Neither of these are the type we are lowering here: + // that's an ordinary `TypeInner::Image`. But the fact we + // are lowering a `texture_external` implies the backends + // may need these additional types too. + ctx.module.generate_external_texture_types(); } ir::TypeInner::Image { dim, diff --git a/naga/src/ir/mod.rs b/naga/src/ir/mod.rs index 50cc89a5b4c..257445952b8 100644 --- a/naga/src/ir/mod.rs +++ b/naga/src/ir/mod.rs @@ -2369,19 +2369,42 @@ pub struct SpecialTypes { /// In WGSL, this type would be: /// /// ```ignore - /// struct NagaExternalTextureParams { // align size offset - /// yuv_conversion_matrix: mat4x4, // 16 64 0 - /// sample_transform: mat3x2, // 8 24 64 - /// load_transform: mat3x2, // 8 24 88 - /// size: vec2, // 8 8 112 - /// num_planes: u32, // 4 4 120 - /// } // whole struct: 16 128 + /// struct NagaExternalTextureParams { // align size offset + /// yuv_conversion_matrix: mat4x4, // 16 64 0 + /// gamut_conversion_matrix: mat3x3, // 16 48 64 + /// src_tf: NagaExternalTextureTransferFn, // 4 16 112 + /// dst_tf: NagaExternalTextureTransferFn, // 4 16 128 + /// sample_transform: mat3x2, // 8 24 144 + /// load_transform: mat3x2, // 8 24 168 + /// size: vec2, // 8 8 192 + /// num_planes: u32, // 4 4 200 + /// } // whole struct: 16 208 /// ``` /// - /// Call [`Module::generate_external_texture_params_type`] to populate this - /// if needed and return the handle. + /// Call [`Module::generate_external_texture_types`] to populate this if + /// needed. pub external_texture_params: Option>, + /// Struct describing a gamma encoding transfer function. Member of + /// `NagaExternalTextureParams`, describing how the backend should perform + /// color space conversion when sampling from [`ImageClass::External`] + /// textures. + /// + /// In WGSL, this type would be: + /// + /// ```ignore + /// struct NagaExternalTextureTransferFn { // align size offset + /// a: f32, // 4 4 0 + /// b: f32, // 4 4 4 + /// g: f32, // 4 4 8 + /// k: f32, // 4 4 12 + /// } // whole struct: 4 16 + /// ``` + /// + /// Call [`Module::generate_external_texture_types`] to populate this if + /// needed. + pub external_texture_transfer_function: Option>, + /// Types for predeclared wgsl types instantiated on demand. /// /// Call [`Module::generate_predeclared_type`] to populate this if diff --git a/naga/tests/out/hlsl/wgsl-texture-external.hlsl b/naga/tests/out/hlsl/wgsl-texture-external.hlsl index 517d6a724a8..dbf57609d8b 100644 --- a/naga/tests/out/hlsl/wgsl-texture-external.hlsl +++ b/naga/tests/out/hlsl/wgsl-texture-external.hlsl @@ -1,5 +1,16 @@ +struct NagaExternalTextureTransferFn { + float a; + float b; + float g; + float k; +}; + struct NagaExternalTextureParams { row_major float4x4 yuv_conversion_matrix; + row_major float3x3 gamut_conversion_matrix; + int _pad2_0; + NagaExternalTextureTransferFn src_tf; + NagaExternalTextureTransferFn dst_tf; float2 sample_transform_0; float2 sample_transform_1; float2 sample_transform_2; float2 load_transform_0; float2 load_transform_1; float2 load_transform_2; uint2 size; @@ -55,7 +66,15 @@ float4 nagaTextureSampleBaseClampToEdge( float2 plane2_coords = clamp(coords, bounds.xy + plane2_half_texel, bounds.zw - plane2_half_texel); uv = float2(plane1.SampleLevel(samp, plane1_coords, 0.0f).x, plane2.SampleLevel(samp, plane2_coords, 0.0f).x); } - return mul(float4(y, uv, 1.0), params.yuv_conversion_matrix); + float3 srcGammaRgb = mul(float4(y, uv, 1.0), params.yuv_conversion_matrix).rgb; + float3 srcLinearRgb = srcGammaRgb < params.src_tf.k * params.src_tf.b ? + srcGammaRgb / params.src_tf.k : + pow((srcGammaRgb + params.src_tf.a - 1.0) / params.src_tf.a, params.src_tf.g); + float3 dstLinearRgb = mul(srcLinearRgb, params.gamut_conversion_matrix); + float3 dstGammaRgb = dstLinearRgb < params.dst_tf.b ? + params.dst_tf.k * dstLinearRgb : + params.dst_tf.a * pow(dstLinearRgb, 1.0 / params.dst_tf.g) - (params.dst_tf.a - 1); + return float4(dstGammaRgb, 1.0); } } @@ -92,7 +111,15 @@ float4 nagaTextureLoadExternal( uint2 plane2_coords = uint2(floor(float2(plane0_coords) * float2(plane2_size) / float2(plane0_size))); uv = float2(plane1.Load(uint3(plane1_coords, 0u)).x, plane2.Load(uint3(plane2_coords, 0u)).x); } - return mul(float4(y, uv, 1.0), params.yuv_conversion_matrix); + float3 srcGammaRgb = mul(float4(y, uv, 1.0), params.yuv_conversion_matrix).rgb; + float3 srcLinearRgb = srcGammaRgb < params.src_tf.k * params.src_tf.b ? + srcGammaRgb / params.src_tf.k : + pow((srcGammaRgb + params.src_tf.a - 1.0) / params.src_tf.a, params.src_tf.g); + float3 dstLinearRgb = mul(srcLinearRgb, params.gamut_conversion_matrix); + float3 dstGammaRgb = dstLinearRgb < params.dst_tf.b ? + params.dst_tf.k * dstLinearRgb : + params.dst_tf.a * pow(dstLinearRgb, 1.0 / params.dst_tf.g) - (params.dst_tf.a - 1); + return float4(dstGammaRgb, 1.0); } } diff --git a/naga/tests/out/ir/spv-fetch_depth.compact.ron b/naga/tests/out/ir/spv-fetch_depth.compact.ron index c2b7b9b5f6e..1fbee2deb35 100644 --- a/naga/tests/out/ir/spv-fetch_depth.compact.ron +++ b/naga/tests/out/ir/spv-fetch_depth.compact.ron @@ -68,6 +68,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [ diff --git a/naga/tests/out/ir/spv-fetch_depth.ron b/naga/tests/out/ir/spv-fetch_depth.ron index dd019d62aa8..186f78354ad 100644 --- a/naga/tests/out/ir/spv-fetch_depth.ron +++ b/naga/tests/out/ir/spv-fetch_depth.ron @@ -131,6 +131,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [ diff --git a/naga/tests/out/ir/spv-shadow.compact.ron b/naga/tests/out/ir/spv-shadow.compact.ron index 04547e651ce..b49cd9b55be 100644 --- a/naga/tests/out/ir/spv-shadow.compact.ron +++ b/naga/tests/out/ir/spv-shadow.compact.ron @@ -156,6 +156,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [ diff --git a/naga/tests/out/ir/spv-shadow.ron b/naga/tests/out/ir/spv-shadow.ron index 0babda31f58..e1f0f60b6bb 100644 --- a/naga/tests/out/ir/spv-shadow.ron +++ b/naga/tests/out/ir/spv-shadow.ron @@ -279,6 +279,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [ diff --git a/naga/tests/out/ir/spv-spec-constants.compact.ron b/naga/tests/out/ir/spv-spec-constants.compact.ron index a07dd0aca04..3fa6ffef4ff 100644 --- a/naga/tests/out/ir/spv-spec-constants.compact.ron +++ b/naga/tests/out/ir/spv-spec-constants.compact.ron @@ -172,6 +172,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [ diff --git a/naga/tests/out/ir/spv-spec-constants.ron b/naga/tests/out/ir/spv-spec-constants.ron index 643d3c7303c..94c90aa78f9 100644 --- a/naga/tests/out/ir/spv-spec-constants.ron +++ b/naga/tests/out/ir/spv-spec-constants.ron @@ -263,6 +263,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [ diff --git a/naga/tests/out/ir/wgsl-access.compact.ron b/naga/tests/out/ir/wgsl-access.compact.ron index fff8d0bcf9b..30e88984f3c 100644 --- a/naga/tests/out/ir/wgsl-access.compact.ron +++ b/naga/tests/out/ir/wgsl-access.compact.ron @@ -422,6 +422,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-access.ron b/naga/tests/out/ir/wgsl-access.ron index fff8d0bcf9b..30e88984f3c 100644 --- a/naga/tests/out/ir/wgsl-access.ron +++ b/naga/tests/out/ir/wgsl-access.ron @@ -422,6 +422,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-collatz.compact.ron b/naga/tests/out/ir/wgsl-collatz.compact.ron index 30168b26292..f72c652d032 100644 --- a/naga/tests/out/ir/wgsl-collatz.compact.ron +++ b/naga/tests/out/ir/wgsl-collatz.compact.ron @@ -45,6 +45,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-collatz.ron b/naga/tests/out/ir/wgsl-collatz.ron index 30168b26292..f72c652d032 100644 --- a/naga/tests/out/ir/wgsl-collatz.ron +++ b/naga/tests/out/ir/wgsl-collatz.ron @@ -45,6 +45,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-const_assert.compact.ron b/naga/tests/out/ir/wgsl-const_assert.compact.ron index 4d77a57494d..2816364f88b 100644 --- a/naga/tests/out/ir/wgsl-const_assert.compact.ron +++ b/naga/tests/out/ir/wgsl-const_assert.compact.ron @@ -5,6 +5,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-const_assert.ron b/naga/tests/out/ir/wgsl-const_assert.ron index 4d77a57494d..2816364f88b 100644 --- a/naga/tests/out/ir/wgsl-const_assert.ron +++ b/naga/tests/out/ir/wgsl-const_assert.ron @@ -5,6 +5,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-diagnostic-filter.compact.ron b/naga/tests/out/ir/wgsl-diagnostic-filter.compact.ron index 10f533f1059..c5746696d52 100644 --- a/naga/tests/out/ir/wgsl-diagnostic-filter.compact.ron +++ b/naga/tests/out/ir/wgsl-diagnostic-filter.compact.ron @@ -5,6 +5,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-diagnostic-filter.ron b/naga/tests/out/ir/wgsl-diagnostic-filter.ron index 10f533f1059..c5746696d52 100644 --- a/naga/tests/out/ir/wgsl-diagnostic-filter.ron +++ b/naga/tests/out/ir/wgsl-diagnostic-filter.ron @@ -5,6 +5,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-index-by-value.compact.ron b/naga/tests/out/ir/wgsl-index-by-value.compact.ron index 31a60105410..a4f84a7a6b2 100644 --- a/naga/tests/out/ir/wgsl-index-by-value.compact.ron +++ b/naga/tests/out/ir/wgsl-index-by-value.compact.ron @@ -82,6 +82,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-index-by-value.ron b/naga/tests/out/ir/wgsl-index-by-value.ron index 31a60105410..a4f84a7a6b2 100644 --- a/naga/tests/out/ir/wgsl-index-by-value.ron +++ b/naga/tests/out/ir/wgsl-index-by-value.ron @@ -82,6 +82,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-local-const.compact.ron b/naga/tests/out/ir/wgsl-local-const.compact.ron index b7deb55aca5..512972657ed 100644 --- a/naga/tests/out/ir/wgsl-local-const.compact.ron +++ b/naga/tests/out/ir/wgsl-local-const.compact.ron @@ -27,6 +27,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [ diff --git a/naga/tests/out/ir/wgsl-local-const.ron b/naga/tests/out/ir/wgsl-local-const.ron index b7deb55aca5..512972657ed 100644 --- a/naga/tests/out/ir/wgsl-local-const.ron +++ b/naga/tests/out/ir/wgsl-local-const.ron @@ -27,6 +27,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [ diff --git a/naga/tests/out/ir/wgsl-must-use.compact.ron b/naga/tests/out/ir/wgsl-must-use.compact.ron index 4d148b9061d..a701a6805da 100644 --- a/naga/tests/out/ir/wgsl-must-use.compact.ron +++ b/naga/tests/out/ir/wgsl-must-use.compact.ron @@ -13,6 +13,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-must-use.ron b/naga/tests/out/ir/wgsl-must-use.ron index 4d148b9061d..a701a6805da 100644 --- a/naga/tests/out/ir/wgsl-must-use.ron +++ b/naga/tests/out/ir/wgsl-must-use.ron @@ -13,6 +13,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-overrides-atomicCompareExchangeWeak.compact.ron b/naga/tests/out/ir/wgsl-overrides-atomicCompareExchangeWeak.compact.ron index 1e568ebbc3d..640ee25ca49 100644 --- a/naga/tests/out/ir/wgsl-overrides-atomicCompareExchangeWeak.compact.ron +++ b/naga/tests/out/ir/wgsl-overrides-atomicCompareExchangeWeak.compact.ron @@ -54,6 +54,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: { AtomicCompareExchangeWeakResult(( kind: Uint, diff --git a/naga/tests/out/ir/wgsl-overrides-atomicCompareExchangeWeak.ron b/naga/tests/out/ir/wgsl-overrides-atomicCompareExchangeWeak.ron index 1e568ebbc3d..640ee25ca49 100644 --- a/naga/tests/out/ir/wgsl-overrides-atomicCompareExchangeWeak.ron +++ b/naga/tests/out/ir/wgsl-overrides-atomicCompareExchangeWeak.ron @@ -54,6 +54,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: { AtomicCompareExchangeWeakResult(( kind: Uint, diff --git a/naga/tests/out/ir/wgsl-overrides-ray-query.compact.ron b/naga/tests/out/ir/wgsl-overrides-ray-query.compact.ron index 649ba28d476..f65e8f186db 100644 --- a/naga/tests/out/ir/wgsl-overrides-ray-query.compact.ron +++ b/naga/tests/out/ir/wgsl-overrides-ray-query.compact.ron @@ -86,6 +86,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-overrides-ray-query.ron b/naga/tests/out/ir/wgsl-overrides-ray-query.ron index 649ba28d476..f65e8f186db 100644 --- a/naga/tests/out/ir/wgsl-overrides-ray-query.ron +++ b/naga/tests/out/ir/wgsl-overrides-ray-query.ron @@ -86,6 +86,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-overrides.compact.ron b/naga/tests/out/ir/wgsl-overrides.compact.ron index eca51561070..81221ff7941 100644 --- a/naga/tests/out/ir/wgsl-overrides.compact.ron +++ b/naga/tests/out/ir/wgsl-overrides.compact.ron @@ -27,6 +27,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-overrides.ron b/naga/tests/out/ir/wgsl-overrides.ron index eca51561070..81221ff7941 100644 --- a/naga/tests/out/ir/wgsl-overrides.ron +++ b/naga/tests/out/ir/wgsl-overrides.ron @@ -27,6 +27,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-storage-textures.compact.ron b/naga/tests/out/ir/wgsl-storage-textures.compact.ron index eb70e3badd2..ec63fecac27 100644 --- a/naga/tests/out/ir/wgsl-storage-textures.compact.ron +++ b/naga/tests/out/ir/wgsl-storage-textures.compact.ron @@ -72,6 +72,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-storage-textures.ron b/naga/tests/out/ir/wgsl-storage-textures.ron index eb70e3badd2..ec63fecac27 100644 --- a/naga/tests/out/ir/wgsl-storage-textures.ron +++ b/naga/tests/out/ir/wgsl-storage-textures.ron @@ -72,6 +72,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-template-list-trailing-comma.compact.ron b/naga/tests/out/ir/wgsl-template-list-trailing-comma.compact.ron index bfcd83f7f35..a8208c09b86 100644 --- a/naga/tests/out/ir/wgsl-template-list-trailing-comma.compact.ron +++ b/naga/tests/out/ir/wgsl-template-list-trailing-comma.compact.ron @@ -29,6 +29,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-template-list-trailing-comma.ron b/naga/tests/out/ir/wgsl-template-list-trailing-comma.ron index bfcd83f7f35..a8208c09b86 100644 --- a/naga/tests/out/ir/wgsl-template-list-trailing-comma.ron +++ b/naga/tests/out/ir/wgsl-template-list-trailing-comma.ron @@ -29,6 +29,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [], diff --git a/naga/tests/out/ir/wgsl-texture-external.compact.ron b/naga/tests/out/ir/wgsl-texture-external.compact.ron index 2bceb18a51f..dbffbddcdc7 100644 --- a/naga/tests/out/ir/wgsl-texture-external.compact.ron +++ b/naga/tests/out/ir/wgsl-texture-external.compact.ron @@ -1,5 +1,12 @@ ( types: [ + ( + name: None, + inner: Scalar(( + kind: Float, + width: 4, + )), + ), ( name: None, inner: Scalar(( @@ -28,6 +35,17 @@ ), ), ), + ( + name: None, + inner: Matrix( + columns: Tri, + rows: Tri, + scalar: ( + kind: Float, + width: 4, + ), + ), + ), ( name: None, inner: Matrix( @@ -39,42 +57,92 @@ ), ), ), + ( + name: Some("NagaExternalTextureTransferFn"), + inner: Struct( + members: [ + ( + name: Some("a"), + ty: 0, + binding: None, + offset: 0, + ), + ( + name: Some("b"), + ty: 0, + binding: None, + offset: 4, + ), + ( + name: Some("g"), + ty: 0, + binding: None, + offset: 8, + ), + ( + name: Some("k"), + ty: 0, + binding: None, + offset: 12, + ), + ], + span: 16, + ), + ), ( name: Some("NagaExternalTextureParams"), inner: Struct( members: [ ( name: Some("yuv_conversion_matrix"), - ty: 3, + ty: 5, binding: None, offset: 0, ), ( - name: Some("sample_transform"), - ty: 2, + name: Some("gamut_conversion_matrix"), + ty: 4, binding: None, offset: 64, ), + ( + name: Some("src_tf"), + ty: 6, + binding: None, + offset: 112, + ), + ( + name: Some("dst_tf"), + ty: 6, + binding: None, + offset: 128, + ), + ( + name: Some("sample_transform"), + ty: 3, + binding: None, + offset: 144, + ), ( name: Some("load_transform"), - ty: 2, + ty: 3, binding: None, - offset: 88, + offset: 168, ), ( name: Some("size"), - ty: 1, + ty: 2, binding: None, - offset: 112, + offset: 192, ), ( name: Some("num_planes"), - ty: 0, + ty: 1, binding: None, - offset: 120, + offset: 200, ), ], - span: 128, + span: 208, ), ), ( @@ -106,7 +174,8 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, - external_texture_params: Some(4), + external_texture_params: Some(7), + external_texture_transfer_function: Some(6), predeclared_types: {}, ), constants: [], @@ -119,7 +188,7 @@ group: 0, binding: 0, )), - ty: 5, + ty: 8, init: None, ), ( @@ -129,7 +198,7 @@ group: 0, binding: 1, )), - ty: 6, + ty: 9, init: None, ), ], @@ -140,28 +209,28 @@ arguments: [ ( name: Some("t"), - ty: 5, + ty: 8, binding: None, ), ], result: Some(( - ty: 7, + ty: 10, binding: None, )), local_variables: [ ( name: Some("a"), - ty: 7, + ty: 10, init: None, ), ( name: Some("b"), - ty: 7, + ty: 10, init: None, ), ( name: Some("c"), - ty: 1, + ty: 2, init: None, ), ], @@ -285,7 +354,7 @@ name: Some("fragment_main"), arguments: [], result: Some(( - ty: 7, + ty: 10, binding: Some(Location( location: 0, interpolation: Some(Perspective), @@ -324,7 +393,7 @@ name: Some("vertex_main"), arguments: [], result: Some(( - ty: 7, + ty: 10, binding: Some(BuiltIn(Position( invariant: false, ))), diff --git a/naga/tests/out/ir/wgsl-texture-external.ron b/naga/tests/out/ir/wgsl-texture-external.ron index 2bceb18a51f..dbffbddcdc7 100644 --- a/naga/tests/out/ir/wgsl-texture-external.ron +++ b/naga/tests/out/ir/wgsl-texture-external.ron @@ -1,5 +1,12 @@ ( types: [ + ( + name: None, + inner: Scalar(( + kind: Float, + width: 4, + )), + ), ( name: None, inner: Scalar(( @@ -28,6 +35,17 @@ ), ), ), + ( + name: None, + inner: Matrix( + columns: Tri, + rows: Tri, + scalar: ( + kind: Float, + width: 4, + ), + ), + ), ( name: None, inner: Matrix( @@ -39,42 +57,92 @@ ), ), ), + ( + name: Some("NagaExternalTextureTransferFn"), + inner: Struct( + members: [ + ( + name: Some("a"), + ty: 0, + binding: None, + offset: 0, + ), + ( + name: Some("b"), + ty: 0, + binding: None, + offset: 4, + ), + ( + name: Some("g"), + ty: 0, + binding: None, + offset: 8, + ), + ( + name: Some("k"), + ty: 0, + binding: None, + offset: 12, + ), + ], + span: 16, + ), + ), ( name: Some("NagaExternalTextureParams"), inner: Struct( members: [ ( name: Some("yuv_conversion_matrix"), - ty: 3, + ty: 5, binding: None, offset: 0, ), ( - name: Some("sample_transform"), - ty: 2, + name: Some("gamut_conversion_matrix"), + ty: 4, binding: None, offset: 64, ), + ( + name: Some("src_tf"), + ty: 6, + binding: None, + offset: 112, + ), + ( + name: Some("dst_tf"), + ty: 6, + binding: None, + offset: 128, + ), + ( + name: Some("sample_transform"), + ty: 3, + binding: None, + offset: 144, + ), ( name: Some("load_transform"), - ty: 2, + ty: 3, binding: None, - offset: 88, + offset: 168, ), ( name: Some("size"), - ty: 1, + ty: 2, binding: None, - offset: 112, + offset: 192, ), ( name: Some("num_planes"), - ty: 0, + ty: 1, binding: None, - offset: 120, + offset: 200, ), ], - span: 128, + span: 208, ), ), ( @@ -106,7 +174,8 @@ ray_desc: None, ray_intersection: None, ray_vertex_return: None, - external_texture_params: Some(4), + external_texture_params: Some(7), + external_texture_transfer_function: Some(6), predeclared_types: {}, ), constants: [], @@ -119,7 +188,7 @@ group: 0, binding: 0, )), - ty: 5, + ty: 8, init: None, ), ( @@ -129,7 +198,7 @@ group: 0, binding: 1, )), - ty: 6, + ty: 9, init: None, ), ], @@ -140,28 +209,28 @@ arguments: [ ( name: Some("t"), - ty: 5, + ty: 8, binding: None, ), ], result: Some(( - ty: 7, + ty: 10, binding: None, )), local_variables: [ ( name: Some("a"), - ty: 7, + ty: 10, init: None, ), ( name: Some("b"), - ty: 7, + ty: 10, init: None, ), ( name: Some("c"), - ty: 1, + ty: 2, init: None, ), ], @@ -285,7 +354,7 @@ name: Some("fragment_main"), arguments: [], result: Some(( - ty: 7, + ty: 10, binding: Some(Location( location: 0, interpolation: Some(Perspective), @@ -324,7 +393,7 @@ name: Some("vertex_main"), arguments: [], result: Some(( - ty: 7, + ty: 10, binding: Some(BuiltIn(Position( invariant: false, ))), diff --git a/naga/tests/out/ir/wgsl-types_with_comments.compact.ron b/naga/tests/out/ir/wgsl-types_with_comments.compact.ron index 1139fab1976..7186209f00e 100644 --- a/naga/tests/out/ir/wgsl-types_with_comments.compact.ron +++ b/naga/tests/out/ir/wgsl-types_with_comments.compact.ron @@ -38,6 +38,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [ diff --git a/naga/tests/out/ir/wgsl-types_with_comments.ron b/naga/tests/out/ir/wgsl-types_with_comments.ron index a1761c17c8e..480b0d2337f 100644 --- a/naga/tests/out/ir/wgsl-types_with_comments.ron +++ b/naga/tests/out/ir/wgsl-types_with_comments.ron @@ -63,6 +63,7 @@ ray_intersection: None, ray_vertex_return: None, external_texture_params: None, + external_texture_transfer_function: None, predeclared_types: {}, ), constants: [ diff --git a/tests/tests/wgpu-validation/api/external_texture.rs b/tests/tests/wgpu-validation/api/external_texture.rs index b3dcffb93f8..989fe5ac8ae 100644 --- a/tests/tests/wgpu-validation/api/external_texture.rs +++ b/tests/tests/wgpu-validation/api/external_texture.rs @@ -49,6 +49,9 @@ fn create_external_texture() { width: r_texture.width(), height: r_texture.height(), yuv_conversion_matrix: [0.0; 16], + gamut_conversion_matrix: [0.0; 9], + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), sample_transform: [0.0; 6], load_transform: [0.0; 6], }, @@ -63,6 +66,9 @@ fn create_external_texture() { width: r_texture.width(), height: r_texture.height(), yuv_conversion_matrix: [0.0; 16], + gamut_conversion_matrix: [0.0; 9], + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), sample_transform: [0.0; 6], load_transform: [0.0; 6], }, @@ -77,6 +83,9 @@ fn create_external_texture() { width: r_texture.width(), height: r_texture.height(), yuv_conversion_matrix: [0.0; 16], + gamut_conversion_matrix: [0.0; 9], + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), sample_transform: [0.0; 6], load_transform: [0.0; 6], }, @@ -95,6 +104,9 @@ fn create_external_texture() { width: r_texture.width(), height: r_texture.height(), yuv_conversion_matrix: [0.0; 16], + gamut_conversion_matrix: [0.0; 9], + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), sample_transform: [0.0; 6], load_transform: [0.0; 6], }, @@ -113,6 +125,9 @@ fn create_external_texture() { width: r_texture.width(), height: r_texture.height(), yuv_conversion_matrix: [0.0; 16], + gamut_conversion_matrix: [0.0; 9], + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), sample_transform: [0.0; 6], load_transform: [0.0; 6], }, @@ -131,6 +146,9 @@ fn create_external_texture() { width: r_texture.width(), height: r_texture.height(), yuv_conversion_matrix: [0.0; 16], + gamut_conversion_matrix: [0.0; 9], + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), sample_transform: [0.0; 6], load_transform: [0.0; 6], }, @@ -151,6 +169,9 @@ fn create_external_texture() { width: r_texture.width(), height: r_texture.height(), yuv_conversion_matrix: [0.0; 16], + gamut_conversion_matrix: [0.0; 9], + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), sample_transform: [0.0; 6], load_transform: [0.0; 6], }, @@ -169,6 +190,9 @@ fn create_external_texture() { width: r_texture.width(), height: r_texture.height(), yuv_conversion_matrix: [0.0; 16], + gamut_conversion_matrix: [0.0; 9], + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), sample_transform: [0.0; 6], load_transform: [0.0; 6], }, @@ -187,6 +211,9 @@ fn create_external_texture() { width: r_texture.width(), height: r_texture.height(), yuv_conversion_matrix: [0.0; 16], + gamut_conversion_matrix: [0.0; 9], + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), sample_transform: [0.0; 6], load_transform: [0.0; 6], }, @@ -212,6 +239,9 @@ fn create_external_texture() { width: uint_texture.width(), height: uint_texture.height(), yuv_conversion_matrix: [0.0; 16], + gamut_conversion_matrix: [0.0; 9], + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), sample_transform: [0.0; 6], load_transform: [0.0; 6], }, @@ -237,6 +267,9 @@ fn create_external_texture() { width: d3_texture.width(), height: d3_texture.height(), yuv_conversion_matrix: [0.0; 16], + gamut_conversion_matrix: [0.0; 9], + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), sample_transform: [0.0; 6], load_transform: [0.0; 6], }, @@ -263,6 +296,9 @@ fn create_external_texture() { width: multisampled_texture.width(), height: multisampled_texture.height(), yuv_conversion_matrix: [0.0; 16], + gamut_conversion_matrix: [0.0; 9], + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), sample_transform: [0.0; 6], load_transform: [0.0; 6], }, @@ -288,6 +324,9 @@ fn create_external_texture() { width: non_binding_texture.width(), height: non_binding_texture.height(), yuv_conversion_matrix: [0.0; 16], + gamut_conversion_matrix: [0.0; 9], + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), sample_transform: [0.0; 6], load_transform: [0.0; 6], }, @@ -339,6 +378,9 @@ fn external_texture_binding() { height: texture_descriptor.size.height, format: ExternalTextureFormat::Rgba, yuv_conversion_matrix: [0.0; 16], + gamut_conversion_matrix: [0.0; 9], + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), sample_transform: [0.0; 6], load_transform: [0.0; 6], }; @@ -568,6 +610,9 @@ fn destroyed_external_texture_plane() { width: plane_texture.width(), height: plane_texture.height(), yuv_conversion_matrix: [0.0; 16], + gamut_conversion_matrix: [0.0; 9], + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), sample_transform: [0.0; 6], load_transform: [0.0; 6], }, diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 68a425c0594..b55676ea5be 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -76,8 +76,12 @@ pub(crate) struct CommandIndices { pub(crate) next_acceleration_structure_build_command_index: u64, } -/// Parameters provided to shaders via a uniform buffer, describing a -/// [`binding_model::BindingResource::ExternalTexture`] resource binding. +/// Parameters provided to shaders via a uniform buffer of the type +/// [`NagaExternalTextureParams`], describing an [`ExternalTexture`] resource +/// binding. +/// +/// [`NagaExternalTextureParams`]: naga::SpecialTypes::external_texture_params +/// [`ExternalTexture`]: binding_model::BindingResource::ExternalTexture #[repr(C)] #[derive(Copy, Clone, bytemuck::Zeroable, bytemuck::Pod)] pub struct ExternalTextureParams { @@ -87,6 +91,29 @@ pub struct ExternalTextureParams { /// This is ignored when `num_planes` is 1. pub yuv_conversion_matrix: [f32; 16], + /// 3x3 column-major matrix to transform linear RGB values in the source + /// color space to linear RGB values in the destination color space. In + /// combination with [`Self::src_transfer_function`] and + /// [`Self::dst_transfer_function`] this can be used to ensure that + /// [`ImageSample`] and [`ImageLoad`] operations return values in the + /// desired destination color space rather than the source color space of + /// the underlying planes. + /// + /// Includes a padding element after each column. + /// + /// [`ImageSample`]: naga::ir::Expression::ImageSample + /// [`ImageLoad`]: naga::ir::Expression::ImageLoad + pub gamut_conversion_matrix: [f32; 12], + + /// Transfer function for the source color space. The *inverse* of this + /// will be applied to decode non-linear RGB to linear RGB in the source + /// color space. + pub src_transfer_function: wgt::ExternalTextureTransferFunction, + + /// Transfer function for the destination color space. This will be applied + /// to encode linear RGB to non-linear RGB in the destination color space. + pub dst_transfer_function: wgt::ExternalTextureTransferFunction, + /// Transform to apply to [`ImageSample`] coordinates. /// /// This is a 3x2 column-major matrix representing an affine transform from @@ -140,8 +167,26 @@ pub struct ExternalTextureParams { impl ExternalTextureParams { pub fn from_desc(desc: &wgt::ExternalTextureDescriptor) -> Self { + let gamut_conversion_matrix = [ + desc.gamut_conversion_matrix[0], + desc.gamut_conversion_matrix[1], + desc.gamut_conversion_matrix[2], + 0.0, // padding + desc.gamut_conversion_matrix[3], + desc.gamut_conversion_matrix[4], + desc.gamut_conversion_matrix[5], + 0.0, // padding + desc.gamut_conversion_matrix[6], + desc.gamut_conversion_matrix[7], + desc.gamut_conversion_matrix[8], + 0.0, // padding + ]; + Self { yuv_conversion_matrix: desc.yuv_conversion_matrix, + gamut_conversion_matrix, + src_transfer_function: desc.src_transfer_function, + dst_transfer_function: desc.dst_transfer_function, size: [desc.width, desc.height], sample_transform: desc.sample_transform, load_transform: desc.load_transform, @@ -445,6 +490,14 @@ impl Device { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, ], + #[rustfmt::skip] + gamut_conversion_matrix: [ + 1.0, 0.0, 0.0, /* padding */ 0.0, + 0.0, 1.0, 0.0, /* padding */ 0.0, + 0.0, 0.0, 1.0, /* padding */ 0.0, + ], + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), size: [0, 0], #[rustfmt::skip] sample_transform: [ diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 10ec85121aa..2e21cb904af 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -6285,6 +6285,31 @@ pub enum ExternalTextureFormat { Yu12, } +/// Parameters describing a gamma encoding transfer function in the form +/// tf = { k * linear | linear < b +/// { a * pow(linear, 1/g) - (a-1) | linear >= b +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq, bytemuck::Zeroable, bytemuck::Pod)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[allow(missing_docs)] +pub struct ExternalTextureTransferFunction { + pub a: f32, + pub b: f32, + pub g: f32, + pub k: f32, +} + +impl Default for ExternalTextureTransferFunction { + fn default() -> Self { + Self { + a: 1.0, + b: 1.0, + g: 1.0, + k: 1.0, + } + } +} + /// Describes an [`ExternalTexture`](../wgpu/struct.ExternalTexture.html). /// /// Note that [`width`] and [`height`] are the values that should be returned by @@ -6325,6 +6350,27 @@ pub struct ExternalTextureDescriptor { /// This is ignored when `format` is [`ExternalTextureFormat::Rgba`]. pub yuv_conversion_matrix: [f32; 16], + /// 3x3 column-major matrix to transform linear RGB values in the source + /// color space to linear RGB values in the destination color space. In + /// combination with [`Self::src_transfer_function`] and + /// [`Self::dst_transfer_function`] this can be used to ensure that + /// [`ImageSample`] and [`ImageLoad`] operations return values in the + /// desired destination color space rather than the source color space of + /// the underlying planes. + /// + /// [`ImageSample`]: https://docs.rs/naga/latest/naga/ir/enum.Expression.html#variant.ImageSample + /// [`ImageLoad`]: https://docs.rs/naga/latest/naga/ir/enum.Expression.html#variant.ImageLoad + pub gamut_conversion_matrix: [f32; 9], + + /// Transfer function for the source color space. The *inverse* of this + /// will be applied to decode non-linear RGB to linear RGB in the source + /// color space. + pub src_transfer_function: ExternalTextureTransferFunction, + + /// Transfer function for the destination color space. This will be applied + /// to encode linear RGB to non-linear RGB in the destination color space. + pub dst_transfer_function: ExternalTextureTransferFunction, + /// Transform to apply to [`ImageSample`] coordinates. /// /// This is a 3x2 column-major matrix representing an affine transform from @@ -6370,6 +6416,9 @@ impl ExternalTextureDescriptor { yuv_conversion_matrix: self.yuv_conversion_matrix, sample_transform: self.sample_transform, load_transform: self.load_transform, + gamut_conversion_matrix: self.gamut_conversion_matrix, + src_transfer_function: self.src_transfer_function, + dst_transfer_function: self.dst_transfer_function, } } diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 893d8101bb0..dcfc1933810 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -91,20 +91,21 @@ pub use wgt::{ CommandBufferDescriptor, CompareFunction, CompositeAlphaMode, CopyExternalImageDestInfo, CoreCounters, DepthBiasState, DepthStencilState, DeviceLostReason, DeviceType, DownlevelCapabilities, DownlevelFlags, DownlevelLimits, Dx12BackendOptions, Dx12Compiler, - DxcShaderModel, DynamicOffset, Extent3d, ExternalTextureFormat, Face, Features, FeaturesWGPU, - FeaturesWebGPU, FilterMode, FrontFace, GlBackendOptions, GlFenceBehavior, Gles3MinorVersion, - HalCounters, ImageSubresourceRange, IndexFormat, InstanceDescriptor, InstanceFlags, - InternalCounters, Limits, MemoryBudgetThresholds, MemoryHints, MultisampleState, - NoopBackendOptions, Origin2d, Origin3d, PipelineStatisticsTypes, PollError, PollStatus, - PolygonMode, PowerPreference, PredefinedColorSpace, PresentMode, PresentationTimestamp, - PrimitiveState, PrimitiveTopology, PushConstantRange, QueryType, RenderBundleDepthStencil, - RequestAdapterError, SamplerBindingType, SamplerBorderColor, ShaderLocation, ShaderModel, - ShaderRuntimeChecks, ShaderStages, StencilFaceState, StencilOperation, StencilState, - StorageTextureAccess, SurfaceCapabilities, SurfaceStatus, TexelCopyBufferLayout, TextureAspect, - TextureDimension, TextureFormat, TextureFormatFeatureFlags, TextureFormatFeatures, - TextureSampleType, TextureTransition, TextureUsages, TextureUses, TextureViewDimension, Trace, - VertexAttribute, VertexFormat, VertexStepMode, WasmNotSend, WasmNotSendSync, WasmNotSync, - COPY_BUFFER_ALIGNMENT, COPY_BYTES_PER_ROW_ALIGNMENT, MAP_ALIGNMENT, PUSH_CONSTANT_ALIGNMENT, + DxcShaderModel, DynamicOffset, Extent3d, ExternalTextureFormat, + ExternalTextureTransferFunction, Face, Features, FeaturesWGPU, FeaturesWebGPU, FilterMode, + FrontFace, GlBackendOptions, GlFenceBehavior, Gles3MinorVersion, HalCounters, + ImageSubresourceRange, IndexFormat, InstanceDescriptor, InstanceFlags, InternalCounters, + Limits, MemoryBudgetThresholds, MemoryHints, MultisampleState, NoopBackendOptions, Origin2d, + Origin3d, PipelineStatisticsTypes, PollError, PollStatus, PolygonMode, PowerPreference, + PredefinedColorSpace, PresentMode, PresentationTimestamp, PrimitiveState, PrimitiveTopology, + PushConstantRange, QueryType, RenderBundleDepthStencil, RequestAdapterError, + SamplerBindingType, SamplerBorderColor, ShaderLocation, ShaderModel, ShaderRuntimeChecks, + ShaderStages, StencilFaceState, StencilOperation, StencilState, StorageTextureAccess, + SurfaceCapabilities, SurfaceStatus, TexelCopyBufferLayout, TextureAspect, TextureDimension, + TextureFormat, TextureFormatFeatureFlags, TextureFormatFeatures, TextureSampleType, + TextureTransition, TextureUsages, TextureUses, TextureViewDimension, Trace, VertexAttribute, + VertexFormat, VertexStepMode, WasmNotSend, WasmNotSendSync, WasmNotSync, COPY_BUFFER_ALIGNMENT, + COPY_BYTES_PER_ROW_ALIGNMENT, MAP_ALIGNMENT, PUSH_CONSTANT_ALIGNMENT, QUERY_RESOLVE_BUFFER_ALIGNMENT, QUERY_SET_MAX_QUERIES, QUERY_SIZE, VERTEX_ALIGNMENT, }; From b5385225abdcf6d92dd6056bb3615ef735ec0949 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Wed, 6 Aug 2025 10:19:08 -0400 Subject: [PATCH 096/303] fix(core): validate effective buf. binding size is aligned to 4 (#8041) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The WebGPU spec. `createBindGroup` [states][spec-ref] (emphasis mine): > Device timeline initialization steps: > > … > > 2. If any of the following conditions are unsatisfied generate a > validation error, invalidate _bindGroup_ and return. > > … > > For each `GPUBindGroupEntry` _bindingDescriptor_ in > _descriptor_.`entries`: > > - … > > - If the defined binding member for _layoutBinding_ is: > > - … > > - `buffer` > > - … > > - If _layoutBinding_.`buffer`.`type` is > > - … > > - `"storage"` or `"read-only-storage"` > > - … > > - effective buffer binding size(_bufferBinding_) is a multiple of 4. [spec-ref]: https://www.w3.org/TR/webgpu/#dom-gpudevice-createbindgroup We were not implementing this check of effective buffer binding size. Check that it's a multiple of 4, including `webgpu:api,validation,createBindGroup:buffer,effective_buffer_binding_size:*` that this is now implemented as intended. --- CHANGELOG.md | 4 ++++ cts_runner/test.lst | 1 + wgpu-core/src/binding_model.rs | 3 +++ wgpu-core/src/device/resource.rs | 13 +++++++++++++ 4 files changed, 21 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4360ce16004..0de38979643 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,10 @@ Naga now requires that no type be larger than 1 GB. This limit may be lowered in ### Bug Fixes +#### General + +- Validate that effective buffer binding size is aligned to 4 when creating bind groups with buffer entries.. By @ErichDonGubler in [8041](https://github.com/gfx-rs/wgpu/pull/8041). + #### Vulkan Fix `STATUS_HEAP_CORRUPTION` crash when concurrently calling `create_sampler`. By @atlv24 in [#8043](https://github.com/gfx-rs/wgpu/pull/8043). diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 26c1db582eb..7282bef2cc1 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -19,6 +19,7 @@ webgpu:api,operation,render_pass,storeOp:render_pass_store_op,color_attachment_w webgpu:api,operation,render_pass,storeOp:render_pass_store_op,color_attachment_only:* webgpu:api,operation,render_pass,storeOp:render_pass_store_op,multiple_color_attachments:* webgpu:api,operation,render_pass,storeOp:render_pass_store_op,depth_stencil_attachment_only:* +webgpu:api,validation,createBindGroup:buffer,effective_buffer_binding_size:* webgpu:api,validation,encoding,beginComputePass:* webgpu:api,validation,encoding,beginRenderPass:* webgpu:api,validation,encoding,cmds,clearBuffer:* diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index 30d8a99a90b..2cbac7bfa6b 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -167,6 +167,8 @@ pub enum CreateBindGroupError { MissingTextureUsage(#[from] MissingTextureUsageError), #[error("Binding declared as a single item, but bind group is using it as an array")] SingleBindingExpected, + #[error("Effective buffer binding size {size} for storage buffers is expected to align to {alignment}, but size is {size}")] + UnalignedEffectiveBufferBindingSizeForStorage { alignment: u8, size: u64 }, #[error("Buffer offset {0} does not respect device's requested `{1}` limit {2}")] UnalignedBufferOffset(wgt::BufferAddress, &'static str, u32), #[error( @@ -275,6 +277,7 @@ impl WebGpuError for CreateBindGroupError { | Self::DuplicateBinding(_) | Self::MissingBindingDeclaration(_) | Self::SingleBindingExpected + | Self::UnalignedEffectiveBufferBindingSizeForStorage { .. } | Self::UnalignedBufferOffset(_, _, _) | Self::BufferRangeTooLarge { .. } | Self::WrongBindingType { .. } diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index b55676ea5be..eed295bdf29 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -2542,6 +2542,19 @@ impl Device { buffer.check_usage(pub_usage)?; let (bb, bind_size) = buffer.binding(bb.offset, bb.size, snatch_guard)?; + + if matches!(binding_ty, wgt::BufferBindingType::Storage { .. }) { + let storage_buf_size_alignment = 4; + + let aligned = bind_size % u64::from(storage_buf_size_alignment) == 0; + if !aligned { + return Err(Error::UnalignedEffectiveBufferBindingSizeForStorage { + alignment: storage_buf_size_alignment, + size: bind_size, + }); + } + } + let bind_end = bb.offset + bind_size; if bind_size > range_limit as u64 { From b3a3dc33b6e801d7409abf2fba3bef5d0bc4f802 Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Mon, 2 Jun 2025 17:21:23 +0100 Subject: [PATCH 097/303] [dx12] Support external textures on DX12 This implements the DX12 HAL part of external texture support, which is the final piece of the puzzle for external textures on DirectX 12. When creating a pipeline layout, HAL is responsible for mapping a single BindingType::ExternalTexture bind group entry to multiple descriptor ranges in the root signature it creates: 3 SRVs (one for each texture plane) and a CBV for the parameters buffer. Additionally we must expose the additional bindings to the Naga backend via the `external_texture_binding_map`. Lastly, when creating a bind group we write the descriptors for each of these bindings to the heap. And with that, we can finally enable the `EXTERNAL_TEXTURE` feature for the dx12 backend. --- wgpu-hal/src/dx12/adapter.rs | 3 +- wgpu-hal/src/dx12/conv.rs | 5 +- wgpu-hal/src/dx12/device.rs | 187 ++++++++++++++++++++++++----------- wgpu-types/src/features.rs | 2 +- 4 files changed, 139 insertions(+), 58 deletions(-) diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index 22d52be4d7e..3a0ece692ff 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -361,7 +361,8 @@ impl super::Adapter { | wgt::Features::DUAL_SOURCE_BLENDING | wgt::Features::TEXTURE_FORMAT_NV12 | wgt::Features::FLOAT32_FILTERABLE - | wgt::Features::TEXTURE_ATOMIC; + | wgt::Features::TEXTURE_ATOMIC + | wgt::Features::EXTERNAL_TEXTURE; //TODO: in order to expose this, we need to run a compute shader // that extract the necessary statistics out of the D3D12 result. diff --git a/wgpu-hal/src/dx12/conv.rs b/wgpu-hal/src/dx12/conv.rs index 2ccb96dd846..6005f43bf1a 100644 --- a/wgpu-hal/src/dx12/conv.rs +++ b/wgpu-hal/src/dx12/conv.rs @@ -135,7 +135,10 @@ pub fn map_binding_type(ty: &wgt::BindingType) -> Direct3D12::D3D12_DESCRIPTOR_R } | Bt::StorageTexture { .. } => Direct3D12::D3D12_DESCRIPTOR_RANGE_TYPE_UAV, Bt::AccelerationStructure { .. } => Direct3D12::D3D12_DESCRIPTOR_RANGE_TYPE_SRV, - Bt::ExternalTexture => unimplemented!(), + // External textures require multiple bindings and therefore cannot + // be mapped to a single descriptor range type. They must be handled + // separately by the caller. + Bt::ExternalTexture => unreachable!("External textures must be handled separately"), } } diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index d8bdd2b1d5f..8eb4bb8864f 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -807,7 +807,8 @@ impl crate::Device for super::Device { | wgt::BindingType::StorageTexture { .. } | wgt::BindingType::AccelerationStructure { .. } => num_views += count, wgt::BindingType::Sampler { .. } => has_sampler_in_group = true, - wgt::BindingType::ExternalTexture => unimplemented!(), + // Three texture planes and one params buffer + wgt::BindingType::ExternalTexture => num_views += 4 * count, } } @@ -880,6 +881,7 @@ impl crate::Device for super::Device { let mut binding_map = hlsl::BindingMap::default(); let mut sampler_buffer_binding_map = hlsl::SamplerIndexBufferBindingMap::default(); + let mut external_texture_binding_map = hlsl::ExternalTextureBindingMap::default(); let mut bind_cbv = hlsl::BindTarget::default(); let mut bind_srv = hlsl::BindTarget::default(); let mut bind_uav = hlsl::BindTarget::default(); @@ -939,6 +941,8 @@ impl crate::Device for super::Device { .. } => {} wgt::BindingType::Sampler(_) => sampler_in_bind_group = true, + // Three texture planes and one params buffer + wgt::BindingType::ExternalTexture => total_non_dynamic_entries += 4, _ => total_non_dynamic_entries += 1, } } @@ -993,61 +997,110 @@ impl crate::Device for super::Device { // SRV/CBV/UAV descriptor tables let range_base = ranges.len(); for entry in bgl.entries.iter() { - let (range_ty, has_dynamic_offset) = match entry.ty { - wgt::BindingType::Buffer { - ty, - has_dynamic_offset: true, - .. - } => match ty { - wgt::BufferBindingType::Uniform => continue, - wgt::BufferBindingType::Storage { .. } => { - (conv::map_binding_type(&entry.ty), true) - } - }, - ref other => (conv::map_binding_type(other), false), - }; - let bt = match range_ty { - Direct3D12::D3D12_DESCRIPTOR_RANGE_TYPE_CBV => &mut bind_cbv, - Direct3D12::D3D12_DESCRIPTOR_RANGE_TYPE_SRV => &mut bind_srv, - Direct3D12::D3D12_DESCRIPTOR_RANGE_TYPE_UAV => &mut bind_uav, - Direct3D12::D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER => continue, - _ => todo!(), - }; - - let binding_array_size = entry.count.map(NonZeroU32::get); - - let dynamic_storage_buffer_offsets_index = if has_dynamic_offset { - debug_assert!( - binding_array_size.is_none(), - "binding arrays and dynamic buffers are mutually exclusive" + let count = entry.count.map_or(1, NonZeroU32::get); + if let wgt::BindingType::ExternalTexture = entry.ty { + // External textures need 3 SRVs (a texture for each plane) + // and 1 CBV for the parameters buffer. + let bind_target = hlsl::ExternalTextureBindTarget { + planes: core::array::from_fn(|_| hlsl::BindTarget { + register: { + let register = bind_srv.register; + bind_srv.register += count; + register + }, + ..bind_srv + }), + params: hlsl::BindTarget { + register: { + let register = bind_cbv.register; + bind_cbv.register += count; + register + }, + ..bind_cbv + }, + }; + external_texture_binding_map.insert( + naga::ResourceBinding { + group: index as u32, + binding: entry.binding, + }, + bind_target, ); - let ret = Some(dynamic_storage_buffers); - dynamic_storage_buffers += 1; - ret + for bt in bind_target.planes { + ranges.push(Direct3D12::D3D12_DESCRIPTOR_RANGE { + RangeType: Direct3D12::D3D12_DESCRIPTOR_RANGE_TYPE_SRV, + NumDescriptors: count, + BaseShaderRegister: bt.register, + RegisterSpace: bt.space as u32, + OffsetInDescriptorsFromTableStart: + Direct3D12::D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND, + }); + } + ranges.push(Direct3D12::D3D12_DESCRIPTOR_RANGE { + RangeType: Direct3D12::D3D12_DESCRIPTOR_RANGE_TYPE_CBV, + NumDescriptors: count, + BaseShaderRegister: bind_target.params.register, + RegisterSpace: bind_target.params.space as u32, + OffsetInDescriptorsFromTableStart: + Direct3D12::D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND, + }); } else { - None - }; + let (range_ty, has_dynamic_offset) = match entry.ty { + wgt::BindingType::Buffer { + ty, + has_dynamic_offset: true, + .. + } => match ty { + wgt::BufferBindingType::Uniform => continue, + wgt::BufferBindingType::Storage { .. } => { + (conv::map_binding_type(&entry.ty), true) + } + }, + ref other => (conv::map_binding_type(other), false), + }; + let bt = match range_ty { + Direct3D12::D3D12_DESCRIPTOR_RANGE_TYPE_CBV => &mut bind_cbv, + Direct3D12::D3D12_DESCRIPTOR_RANGE_TYPE_SRV => &mut bind_srv, + Direct3D12::D3D12_DESCRIPTOR_RANGE_TYPE_UAV => &mut bind_uav, + Direct3D12::D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER => continue, + _ => todo!(), + }; - binding_map.insert( - naga::ResourceBinding { - group: index as u32, - binding: entry.binding, - }, - hlsl::BindTarget { - binding_array_size, - dynamic_storage_buffer_offsets_index, - ..*bt - }, - ); - ranges.push(Direct3D12::D3D12_DESCRIPTOR_RANGE { - RangeType: range_ty, - NumDescriptors: entry.count.map_or(1, |count| count.get()), - BaseShaderRegister: bt.register, - RegisterSpace: bt.space as u32, - OffsetInDescriptorsFromTableStart: - Direct3D12::D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND, - }); - bt.register += entry.count.map(NonZeroU32::get).unwrap_or(1); + let binding_array_size = entry.count.map(NonZeroU32::get); + + let dynamic_storage_buffer_offsets_index = if has_dynamic_offset { + debug_assert!( + binding_array_size.is_none(), + "binding arrays and dynamic buffers are mutually exclusive" + ); + let ret = Some(dynamic_storage_buffers); + dynamic_storage_buffers += 1; + ret + } else { + None + }; + + binding_map.insert( + naga::ResourceBinding { + group: index as u32, + binding: entry.binding, + }, + hlsl::BindTarget { + binding_array_size, + dynamic_storage_buffer_offsets_index, + ..*bt + }, + ); + ranges.push(Direct3D12::D3D12_DESCRIPTOR_RANGE { + RangeType: range_ty, + NumDescriptors: count, + BaseShaderRegister: bt.register, + RegisterSpace: bt.space as u32, + OffsetInDescriptorsFromTableStart: + Direct3D12::D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND, + }); + bt.register += count; + } } let mut sampler_index_within_bind_group = 0; @@ -1388,7 +1441,7 @@ impl crate::Device for super::Device { restrict_indexing: true, sampler_heap_target, sampler_buffer_binding_map, - external_texture_binding_map: hlsl::ExternalTextureBindingMap::default(), + external_texture_binding_map, force_loop_bounding: true, }, }) @@ -1574,7 +1627,31 @@ impl crate::Device for super::Device { inner.stage.push(handle); } } - wgt::BindingType::ExternalTexture => unimplemented!(), + wgt::BindingType::ExternalTexture => { + // We don't yet support binding arrays of external textures. + // https://github.com/gfx-rs/wgpu/issues/8027 + assert_eq!(entry.count, 1); + let external_texture = &desc.external_textures[entry.resource_index as usize]; + for plane in &external_texture.planes { + let plane_handle = plane.view.handle_srv.unwrap(); + cpu_views.as_mut().unwrap().stage.push(plane_handle.raw); + } + let gpu_address = external_texture.params.resolve_address(); + let size = external_texture.params.resolve_size() as u32; + let inner = cpu_views.as_mut().unwrap(); + let cpu_index = inner.stage.len() as u32; + let params_handle = desc.layout.cpu_heap_views.as_ref().unwrap().at(cpu_index); + let size_mask = Direct3D12::D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT - 1; + let raw_desc = Direct3D12::D3D12_CONSTANT_BUFFER_VIEW_DESC { + BufferLocation: gpu_address, + SizeInBytes: ((size - 1) | size_mask) + 1, + }; + unsafe { + self.raw + .CreateConstantBufferView(Some(&raw_desc), params_handle) + }; + inner.stage.push(params_handle); + } } } diff --git a/wgpu-types/src/features.rs b/wgpu-types/src/features.rs index 5880c6ff351..908d5bda203 100644 --- a/wgpu-types/src/features.rs +++ b/wgpu-types/src/features.rs @@ -997,7 +997,7 @@ bitflags_array! { /// all. /// /// Supported platforms: - /// - None + /// - DX12 const EXTERNAL_TEXTURE = 1 << 30; // Shader: From bd85c9a99a3fefedfa10d7c0cc2841a9f416af64 Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Thu, 19 Jun 2025 09:33:21 +0100 Subject: [PATCH 098/303] [test] Rename existing `external_texture` tests to `external_image_copy` These existing tests cover `Queue::copy_external_image_to_texture()` which, despite the similar name, is unrelated to the external texture binding resource. The following patch is going to add some tests for the latter, so we are taking this opportunity to rename the former to help avoid confusion. --- .../wgpu-gpu/{external_texture.rs => external_image_copy.rs} | 0 tests/tests/wgpu-gpu/main.rs | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/tests/wgpu-gpu/{external_texture.rs => external_image_copy.rs} (100%) diff --git a/tests/tests/wgpu-gpu/external_texture.rs b/tests/tests/wgpu-gpu/external_image_copy.rs similarity index 100% rename from tests/tests/wgpu-gpu/external_texture.rs rename to tests/tests/wgpu-gpu/external_image_copy.rs diff --git a/tests/tests/wgpu-gpu/main.rs b/tests/tests/wgpu-gpu/main.rs index a0785fe44e2..2698436ae48 100644 --- a/tests/tests/wgpu-gpu/main.rs +++ b/tests/tests/wgpu-gpu/main.rs @@ -28,7 +28,7 @@ mod dispatch_workgroups_indirect; mod draw_indirect; mod dual_source_blending; mod encoder; -mod external_texture; +mod external_image_copy; mod float32_filterable; mod image_atomics; mod instance; From 1bf1671ed877a6a9ccf5f1a349ec167cd28af3d7 Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Thu, 19 Jun 2025 17:22:24 +0100 Subject: [PATCH 099/303] [test] Add external texture GPU tests These tests cover the external texture binding resource. They ensure the WGSL functions `textureDimensions()`, `textureLoad()`, and `textureSampleBaseClampToEdge()` work as expected for both `TextureView`s and `ExternalTexture`s bound to external texture resource bindings. For external textures, they ensure multiplanar YUV formats work as expected including handling color space transformation. And that the provided sample and load transforms correctly handle cropping, flipping, and rotation. --- .../wgpu-gpu/external_texture/dimensions.wgsl | 10 + .../tests/wgpu-gpu/external_texture/load.wgsl | 12 + tests/tests/wgpu-gpu/external_texture/mod.rs | 1121 +++++++++++++++++ .../wgpu-gpu/external_texture/sample.wgsl | 14 + tests/tests/wgpu-gpu/main.rs | 2 + 5 files changed, 1159 insertions(+) create mode 100644 tests/tests/wgpu-gpu/external_texture/dimensions.wgsl create mode 100644 tests/tests/wgpu-gpu/external_texture/load.wgsl create mode 100644 tests/tests/wgpu-gpu/external_texture/mod.rs create mode 100644 tests/tests/wgpu-gpu/external_texture/sample.wgsl diff --git a/tests/tests/wgpu-gpu/external_texture/dimensions.wgsl b/tests/tests/wgpu-gpu/external_texture/dimensions.wgsl new file mode 100644 index 00000000000..422d676e3d5 --- /dev/null +++ b/tests/tests/wgpu-gpu/external_texture/dimensions.wgsl @@ -0,0 +1,10 @@ +@group(0) @binding(0) +var tex: texture_external; + +@group(0) @binding(1) +var output: vec2; + +@compute @workgroup_size(1) +fn main(@builtin(global_invocation_id) global_id: vec3) { + output = textureDimensions(tex); +} diff --git a/tests/tests/wgpu-gpu/external_texture/load.wgsl b/tests/tests/wgpu-gpu/external_texture/load.wgsl new file mode 100644 index 00000000000..b9f28d679fa --- /dev/null +++ b/tests/tests/wgpu-gpu/external_texture/load.wgsl @@ -0,0 +1,12 @@ +@group(0) @binding(0) +var tex: texture_external; + +@group(0) @binding(1) +var coords: array>; +@group(0) @binding(2) +var output: array>; + +@compute @workgroup_size(1) +fn main(@builtin(global_invocation_id) id: vec3) { + output[id.x] = textureLoad(tex, coords[id.x]); +} diff --git a/tests/tests/wgpu-gpu/external_texture/mod.rs b/tests/tests/wgpu-gpu/external_texture/mod.rs new file mode 100644 index 00000000000..4b22bdee15f --- /dev/null +++ b/tests/tests/wgpu-gpu/external_texture/mod.rs @@ -0,0 +1,1121 @@ +use approx::assert_abs_diff_eq; +use wgpu_test::{ + gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.extend([ + EXTERNAL_TEXTURE_DIMENSIONS, + EXTERNAL_TEXTURE_LOAD, + EXTERNAL_TEXTURE_LOAD_YUV, + EXTERNAL_TEXTURE_LOAD_TRANSFORM, + EXTERNAL_TEXTURE_LOAD_INVALID_ADDRESS, + EXTERNAL_TEXTURE_SAMPLE, + EXTERNAL_TEXTURE_SAMPLE_YUV, + EXTERNAL_TEXTURE_SAMPLE_TRANSFORM, + ]); +} + +// Input texture data +const RED_U8: [u8; 4] = [0xFF, 0x00, 0x00, 0xFF]; +const GREEN_U8: [u8; 4] = [0x00, 0xFF, 0x00, 0xFF]; +const BLUE_U8: [u8; 4] = [0x00, 0x00, 0xFF, 0xFF]; +const YELLOW_U8: [u8; 4] = [0xFF, 0xFF, 0x00, 0xFF]; +const BLACK_U8: [u8; 4] = [0x00, 0x00, 0x00, 0xFF]; + +// Data for a 2x2 or 4x1 texture with red, green, blue, and yellow pixels +const RGBA_TEXTURE_DATA: [[u8; 4]; 4] = [RED_U8, GREEN_U8, BLUE_U8, YELLOW_U8]; + +// Data for a 4x4 texture with red, green, blue, and yellow pixels in the +// centre, surrounded by a black border. +#[rustfmt::skip] +const RGBA_TEXTURE_DATA_WITH_BORDER: [[u8; 4]; 16] = [ + BLACK_U8, BLACK_U8, BLACK_U8, BLACK_U8, + BLACK_U8, RED_U8, GREEN_U8, BLACK_U8, + BLACK_U8, BLUE_U8, YELLOW_U8, BLACK_U8, + BLACK_U8, BLACK_U8, BLACK_U8, BLACK_U8, +]; + +// Red, green, blue, and yellow in BT601 limited range YUV. Values obtained by +// extracting raw frames from the WebGPU CTS' "four-colors" video [1], and +// inspecting the contents. +// [1] https://github.com/gpuweb/cts/blob/44dac855ba07b23c49d2cbc2c9d87bf8e6f38c47/src/resources/four-colors-vp8-bt601.webm +const RED_Y_U8: u8 = 0x51; +const RED_U_U8: u8 = 0x5A; +const RED_V_U8: u8 = 0xF0; +const GREEN_Y_U8: u8 = 0x91; +const GREEN_U_U8: u8 = 0x35; +const GREEN_V_U8: u8 = 0x22; +const BLUE_Y_U8: u8 = 0x29; +const BLUE_U_U8: u8 = 0xF0; +const BLUE_V_U8: u8 = 0x6E; +const YELLOW_Y_U8: u8 = 0xD2; +const YELLOW_U_U8: u8 = 0x10; +const YELLOW_V_U8: u8 = 0x92; + +// Data for a 4x4 texture with 4:2:0 chroma subsampling. The top-left quadrant +// is red, top-right green, bottom-left blue, and bottom-right yellow. +#[rustfmt::skip] +const Y_TEXTURE_DATA: [u8; 16] = [ + RED_Y_U8, RED_Y_U8, GREEN_Y_U8, GREEN_Y_U8, + RED_Y_U8, RED_Y_U8, GREEN_Y_U8, GREEN_Y_U8, + BLUE_Y_U8, BLUE_Y_U8, YELLOW_Y_U8, YELLOW_Y_U8, + BLUE_Y_U8, BLUE_Y_U8, YELLOW_Y_U8, YELLOW_Y_U8, +]; +const U_TEXTURE_DATA: [u8; 4] = [RED_U_U8, GREEN_U_U8, BLUE_U_U8, YELLOW_U_U8]; +const V_TEXTURE_DATA: [u8; 4] = [RED_V_U8, GREEN_V_U8, BLUE_V_U8, YELLOW_V_U8]; + +// Expected results after texture load/sample. +const RED_F32: [f32; 4] = [1.0, 0.0, 0.0, 1.0]; +const GREEN_F32: [f32; 4] = [0.0, 1.0, 0.0, 1.0]; +const BLUE_F32: [f32; 4] = [0.0, 0.0, 1.0, 1.0]; +const YELLOW_F32: [f32; 4] = [1.0, 1.0, 0.0, 1.0]; +const OPAQUE_BLACK_F32: [f32; 4] = [0.0, 0.0, 0.0, 1.0]; +const TRANSPARENT_BLACK_F32: [f32; 4] = [0.0, 0.0, 0.0, 0.0]; + +// Expected results after texture load/sample in sRGB color space. Values +// taken from the WebGPU CTS: +// https://github.com/gpuweb/cts/blob/44dac855ba07b23c49d2cbc2c9d87bf8e6f38c47/src/webgpu/web_platform/util.ts#L36-L43 +const RED_SRGB_F32: [f32; 4] = [0.9729456, 0.14179438, -0.020958992, 1.0]; +const GREEN_SRGB_F32: [f32; 4] = [0.24823427, 0.98481035, -0.056470133, 1.0]; +const BLUE_SRGB_F32: [f32; 4] = [0.10159736, 0.13545112, 1.0026299, 1.0]; +const YELLOW_SRGB_F32: [f32; 4] = [0.99547076, 0.9927421, -0.07742912, 1.0]; + +#[rustfmt::skip] +const IDENTITY_YUV_CONVERSION_MATRIX: [f32; 16] = [ + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0, +]; +#[rustfmt::skip] +const BT601_YUV_CONVERSION_MATRIX: [f32; 16] = [ + 1.1643835, 1.1643834, 1.1643835, 0.0, + 0.0, -0.39176223, 2.017232, 0.0, + 1.5960265, -0.81296754, 0.0, 0.0, + -0.8742022, 0.5316678, -1.0856307, 1.0 +]; + +const SRGB_TRANSFER_FUNCTION: wgpu::ExternalTextureTransferFunction = + wgpu::ExternalTextureTransferFunction { + a: 1.055, + b: 0.003130805, + g: 2.4, + k: 12.92, + }; + +const IDENTITY_GAMUT_CONVERSION_MATRIX: [f32; 9] = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]; +#[rustfmt::skip] +const BT601_TO_SRGB_GAMUT_CONVERSION_MATRIX: [f32; 9] = [ + 0.93954253, 0.017772198, -0.0016215984, + 0.050181333, 0.96579295, -0.0043697506, + 0.010276437, 0.016434949, 1.0059911, +]; + +const IDENTITY_SAMPLE_TRANSFORM: [f32; 6] = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]; +const IDENTITY_LOAD_TRANSFORM: [f32; 6] = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]; +// Flips a 2x2 texture horizontally +const HORIZONTAL_FLIP_2X2_SAMPLE_TRANSFORM: [f32; 6] = [-1.0, 0.0, 0.0, 1.0, 1.0, 0.0]; +const HORIZONTAL_FLIP_2X2_LOAD_TRANSFORM: [f32; 6] = [-1.0, 0.0, 0.0, 1.0, 1.0, 0.0]; +// Flips a 2x2 texture vertically +const VERTICAL_FLIP_2X2_SAMPLE_TRANSFORM: [f32; 6] = [1.0, 0.0, 0.0, -1.0, 0.0, 1.0]; +const VERTICAL_FLIP_2X2_LOAD_TRANSFORM: [f32; 6] = [1.0, 0.0, 0.0, -1.0, 0.0, 1.0]; +// Rotates a 4x1 texture 90 degrees +const ROTATE_90_4X1_SAMPLE_TRANSFORM: [f32; 6] = [0.0, -1.0, 1.0, 0.0, 0.0, 1.0]; +const ROTATE_90_4X1_LOAD_TRANSFORM: [f32; 6] = [0.0, 1.0, 1.0, 0.0, 0.0, 0.0]; +// Rotates a 4x1 texture 180 degrees +const ROTATE_180_4X1_SAMPLE_TRANSFORM: [f32; 6] = [-1.0, 0.0, 0.0, -1.0, 1.0, 1.0]; +const ROTATE_180_4X1_LOAD_TRANSFORM: [f32; 6] = [-1.0, 0.0, 0.0, 0.0, 3.0, 0.0]; +// Rotates a 4xx1 texture 270 degrees +const ROTATE_270_4X1_SAMPLE_TRANSFORM: [f32; 6] = [0.0, 1.0, -1.0, 0.0, 1.0, 0.0]; +const ROTATE_270_4X1_LOAD_TRANSFORM: [f32; 6] = [0.0, 0.0, -1.0, 0.0, 3.0, 0.0]; +// Crops the middle 2x2 pixels from a 4x4 texture +const CROP_4X4_SAMPLE_TRANSFORM: [f32; 6] = [0.5, 0.0, 0.0, 0.5, 0.25, 0.25]; +const CROP_4X4_LOAD_TRANSFORM: [f32; 6] = [0.5, 0.0, 0.0, 0.5, 1.0, 1.0]; + +/// Helper function to create a 2D texture and a view, optionally writing the +/// provided data to the texture, and returning the view. +fn create_texture_and_view( + ctx: &TestingContext, + size: wgpu::Extent3d, + format: wgpu::TextureFormat, + data: Option<&[u8]>, +) -> wgpu::TextureView { + let texture = ctx.device.create_texture(&wgpu::TextureDescriptor { + label: None, + size, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format, + usage: wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::TEXTURE_BINDING, + view_formats: &[], + }); + if let Some(data) = data { + ctx.queue.write_texture( + texture.as_image_copy(), + data, + wgpu::TexelCopyBufferLayout { + offset: 0, + bytes_per_row: Some(size.width * format.components() as u32), + rows_per_image: None, + }, + size, + ); + } + texture.create_view(&wgpu::TextureViewDescriptor::default()) +} + +/// Helper function to perform textureDimensions() and return the result. +fn get_dimensions(ctx: &TestingContext, texture_resource: wgpu::BindingResource) -> [u32; 2] { + let module = ctx + .device + .create_shader_module(wgpu::include_wgsl!("dimensions.wgsl")); + let pipeline = ctx + .device + .create_compute_pipeline(&wgpu::ComputePipelineDescriptor { + label: None, + layout: None, + module: &module, + entry_point: Some("main"), + compilation_options: wgpu::PipelineCompilationOptions::default(), + cache: None, + }); + + let output_buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: std::mem::size_of::<[u32; 2]>() as _, + usage: wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_SRC, + mapped_at_creation: false, + }); + let download_buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: output_buffer.size(), + usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ, + mapped_at_creation: false, + }); + + let bind_group = ctx.device.create_bind_group(&wgpu::BindGroupDescriptor { + label: None, + layout: &pipeline.get_bind_group_layout(0), + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: texture_resource, + }, + wgpu::BindGroupEntry { + binding: 1, + resource: output_buffer.as_entire_binding(), + }, + ], + }); + let mut encoder = ctx + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + { + let mut pass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor::default()); + pass.set_pipeline(&pipeline); + pass.set_bind_group(0, &bind_group, &[]); + pass.dispatch_workgroups(1, 1, 1); + } + + encoder.copy_buffer_to_buffer(&output_buffer, 0, &download_buffer, 0, output_buffer.size()); + ctx.queue.submit(Some(encoder.finish())); + let buffer_slice = download_buffer.slice(..); + buffer_slice.map_async(wgpu::MapMode::Read, |_| {}); + ctx.device.poll(wgpu::PollType::Wait).unwrap(); + + let data = buffer_slice.get_mapped_range(); + let size: &[u32] = bytemuck::cast_slice(&data); + size.try_into().unwrap() +} + +/// Helper function to perform `textureLoad()` for the specified coordinates and return +/// the loaded values. +fn get_loads( + ctx: &TestingContext, + coords: &[[u32; 2]], + texture_resource: wgpu::BindingResource, +) -> Vec<[f32; 4]> { + let module = ctx + .device + .create_shader_module(wgpu::include_wgsl!("load.wgsl")); + let pipeline = ctx + .device + .create_compute_pipeline(&wgpu::ComputePipelineDescriptor { + label: None, + layout: None, + module: &module, + entry_point: Some("main"), + compilation_options: wgpu::PipelineCompilationOptions::default(), + cache: None, + }); + + let coords_buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: std::mem::size_of_val(coords) as _, + usage: wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false, + }); + ctx.queue + .write_buffer(&coords_buffer, 0, bytemuck::cast_slice(coords)); + + let output_buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: (coords.len() * std::mem::size_of::<[f32; 4]>()) as _, + usage: wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_SRC, + mapped_at_creation: false, + }); + let download_buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: output_buffer.size(), + usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ, + mapped_at_creation: false, + }); + + let bind_group = ctx.device.create_bind_group(&wgpu::BindGroupDescriptor { + label: None, + layout: &pipeline.get_bind_group_layout(0), + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: texture_resource, + }, + wgpu::BindGroupEntry { + binding: 1, + resource: coords_buffer.as_entire_binding(), + }, + wgpu::BindGroupEntry { + binding: 2, + resource: output_buffer.as_entire_binding(), + }, + ], + }); + + let mut encoder = ctx + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + { + let mut pass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor::default()); + pass.set_pipeline(&pipeline); + pass.set_bind_group(0, &bind_group, &[]); + pass.dispatch_workgroups(coords.len() as _, 1, 1); + } + + encoder.copy_buffer_to_buffer(&output_buffer, 0, &download_buffer, 0, output_buffer.size()); + ctx.queue.submit(Some(encoder.finish())); + let buffer_slice = download_buffer.slice(..); + buffer_slice.map_async(wgpu::MapMode::Read, |_| {}); + ctx.device.poll(wgpu::PollType::Wait).unwrap(); + + let data = buffer_slice.get_mapped_range(); + let values: &[[f32; 4]] = bytemuck::cast_slice(&data); + values.to_vec() +} + +/// Helper function to perform `textureSampleBaseClampToEdge()` for the specified +/// coordinates and return the sampled values. +fn get_samples( + ctx: &TestingContext, + coords: &[[f32; 2]], + texture_resource: wgpu::BindingResource, +) -> Vec<[f32; 4]> { + let module = ctx + .device + .create_shader_module(wgpu::include_wgsl!("sample.wgsl")); + let pipeline = ctx + .device + .create_compute_pipeline(&wgpu::ComputePipelineDescriptor { + label: None, + layout: None, + module: &module, + entry_point: Some("main"), + compilation_options: wgpu::PipelineCompilationOptions::default(), + cache: None, + }); + + let coords_buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: std::mem::size_of_val(coords) as _, + usage: wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false, + }); + ctx.queue + .write_buffer(&coords_buffer, 0, bytemuck::cast_slice(coords)); + + let output_buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: (coords.len() * std::mem::size_of::<[f32; 4]>()) as _, + usage: wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_SRC, + mapped_at_creation: false, + }); + let download_buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: output_buffer.size(), + usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ, + mapped_at_creation: false, + }); + + let sampler = ctx + .device + .create_sampler(&wgpu::SamplerDescriptor::default()); + + let bind_group = ctx.device.create_bind_group(&wgpu::BindGroupDescriptor { + label: None, + layout: &pipeline.get_bind_group_layout(0), + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: texture_resource, + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::Sampler(&sampler), + }, + wgpu::BindGroupEntry { + binding: 2, + resource: coords_buffer.as_entire_binding(), + }, + wgpu::BindGroupEntry { + binding: 3, + resource: output_buffer.as_entire_binding(), + }, + ], + }); + + let mut encoder = ctx + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + { + let mut pass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor::default()); + pass.set_pipeline(&pipeline); + pass.set_bind_group(0, &bind_group, &[]); + pass.dispatch_workgroups(coords.len() as _, 1, 1); + } + + encoder.copy_buffer_to_buffer(&output_buffer, 0, &download_buffer, 0, output_buffer.size()); + ctx.queue.submit(Some(encoder.finish())); + let buffer_slice = download_buffer.slice(..); + buffer_slice.map_async(wgpu::MapMode::Read, |_| {}); + ctx.device.poll(wgpu::PollType::Wait).unwrap(); + + let data = buffer_slice.get_mapped_range(); + let values: &[[f32; 4]] = bytemuck::cast_slice(&data); + values.to_vec() +} + +/// Tests that `textureDimensions()` returns the correct value for both external textures +/// and texture views bound to an external texture binding. +#[gpu_test] +static EXTERNAL_TEXTURE_DIMENSIONS: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters( + TestParameters::default() + .test_features_limits() + .features(wgpu::Features::EXTERNAL_TEXTURE), + ) + .run_async(|ctx| async move { + const TEXTURE_WIDTH: u32 = 128; + const TEXTURE_HEIGHT: u32 = 64; + let view = create_texture_and_view( + &ctx, + wgpu::Extent3d { + width: TEXTURE_WIDTH, + height: TEXTURE_HEIGHT, + depth_or_array_layers: 1, + }, + wgpu::TextureFormat::Rgba8Unorm, + None, + ); + let dims = get_dimensions(&ctx, wgpu::BindingResource::TextureView(&view)); + assert_eq!(dims, [TEXTURE_WIDTH, TEXTURE_HEIGHT]); + + const EXTERNAL_TEXTURE_WIDTH: u32 = 32; + const EXTERNAL_TEXTURE_HEIGHT: u32 = 16; + let external_texture = ctx.device.create_external_texture( + &wgpu::ExternalTextureDescriptor { + label: None, + width: EXTERNAL_TEXTURE_WIDTH, + height: EXTERNAL_TEXTURE_HEIGHT, + format: wgpu::ExternalTextureFormat::Rgba, + yuv_conversion_matrix: IDENTITY_YUV_CONVERSION_MATRIX, + gamut_conversion_matrix: IDENTITY_GAMUT_CONVERSION_MATRIX, + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), + sample_transform: IDENTITY_SAMPLE_TRANSFORM, + load_transform: IDENTITY_LOAD_TRANSFORM, + }, + &[&view], + ); + let dims = get_dimensions( + &ctx, + wgpu::BindingResource::ExternalTexture(&external_texture), + ); + // This should return the dimensions provided in the ExternalTextureDescriptor, + // rather than the dimensions of the underlying texture. + assert_eq!(dims, [EXTERNAL_TEXTURE_WIDTH, EXTERNAL_TEXTURE_HEIGHT]) + }); + +/// Tests that `textureLoad()` returns the correct values for both RGBA format external +/// textures and texture views bound to an external texture binding. +#[gpu_test] +static EXTERNAL_TEXTURE_LOAD: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters( + TestParameters::default() + .test_features_limits() + .features(wgpu::Features::EXTERNAL_TEXTURE), + ) + .run_async(|ctx| async move { + let view = create_texture_and_view( + &ctx, + wgpu::Extent3d { + width: 2, + height: 2, + depth_or_array_layers: 1, + }, + wgpu::TextureFormat::Rgba8Unorm, + Some(RGBA_TEXTURE_DATA.as_flattened()), + ); + let loads = get_loads( + &ctx, + &[[0, 0], [1, 0], [0, 1], [1, 1]], + wgpu::BindingResource::TextureView(&view), + ); + assert_eq!(&loads, &[RED_F32, GREEN_F32, BLUE_F32, YELLOW_F32]); + + let external_texture = ctx.device.create_external_texture( + &wgpu::ExternalTextureDescriptor { + label: None, + width: 2, + height: 2, + format: wgpu::ExternalTextureFormat::Rgba, + yuv_conversion_matrix: IDENTITY_YUV_CONVERSION_MATRIX, + gamut_conversion_matrix: IDENTITY_GAMUT_CONVERSION_MATRIX, + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), + sample_transform: IDENTITY_SAMPLE_TRANSFORM, + load_transform: IDENTITY_LOAD_TRANSFORM, + }, + &[&view], + ); + + let loads = get_loads( + &ctx, + &[[0, 0], [1, 0], [0, 1], [1, 1]], + wgpu::BindingResource::ExternalTexture(&external_texture), + ); + assert_eq!(&loads, &[RED_F32, GREEN_F32, BLUE_F32, YELLOW_F32]); + }); + +/// Tests that `textureLoad()` returns the correct values for YUV format external +/// textures. +#[gpu_test] +static EXTERNAL_TEXTURE_LOAD_YUV: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters( + TestParameters::default() + .test_features_limits() + .features(wgpu::Features::EXTERNAL_TEXTURE), + ) + .run_async(|ctx| async move { + let y_view = create_texture_and_view( + &ctx, + wgpu::Extent3d { + width: 4, + height: 4, + depth_or_array_layers: 1, + }, + wgpu::TextureFormat::R8Unorm, + Some(&Y_TEXTURE_DATA), + ); + let u_view = create_texture_and_view( + &ctx, + wgpu::Extent3d { + width: 2, + height: 2, + depth_or_array_layers: 1, + }, + wgpu::TextureFormat::R8Unorm, + Some(&U_TEXTURE_DATA), + ); + let v_view = create_texture_and_view( + &ctx, + wgpu::Extent3d { + width: 2, + height: 2, + depth_or_array_layers: 1, + }, + wgpu::TextureFormat::R8Unorm, + Some(&V_TEXTURE_DATA), + ); + + let external_texture = ctx.device.create_external_texture( + &wgpu::ExternalTextureDescriptor { + label: None, + width: 4, + height: 4, + format: wgpu::ExternalTextureFormat::Yu12, + yuv_conversion_matrix: BT601_YUV_CONVERSION_MATRIX, + gamut_conversion_matrix: BT601_TO_SRGB_GAMUT_CONVERSION_MATRIX, + src_transfer_function: SRGB_TRANSFER_FUNCTION, + dst_transfer_function: SRGB_TRANSFER_FUNCTION, + sample_transform: IDENTITY_SAMPLE_TRANSFORM, + load_transform: IDENTITY_LOAD_TRANSFORM, + }, + &[&y_view, &u_view, &v_view], + ); + let loads = get_loads( + &ctx, + &[[1, 1], [2, 1], [1, 2], [2, 2]], + wgpu::BindingResource::ExternalTexture(&external_texture), + ); + + // `assert_abs_diff_eq!()` works for slices but not arrays, hence the + // following tomfoolery. + let loads = loads.iter().map(|arr| arr.as_slice()).collect::>(); + let expected = [RED_SRGB_F32, GREEN_SRGB_F32, BLUE_SRGB_F32, YELLOW_SRGB_F32]; + let expected = expected.each_ref().map(|arr| arr.as_slice()); + // We expect slight inaccuracies due to floating point maths. + assert_abs_diff_eq!(loads.as_slice(), expected.as_slice(), epsilon = 0.01); + }); + +/// Tests that `textureLoad()` returns the correct values for external textures with +/// various load transforms. +#[gpu_test] +static EXTERNAL_TEXTURE_LOAD_TRANSFORM: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters( + TestParameters::default() + .test_features_limits() + .features(wgpu::Features::EXTERNAL_TEXTURE), + ) + .run_async(|ctx| async move { + let view_2x2 = create_texture_and_view( + &ctx, + wgpu::Extent3d { + width: 2, + height: 2, + depth_or_array_layers: 1, + }, + wgpu::TextureFormat::Rgba8Unorm, + Some(RGBA_TEXTURE_DATA.as_flattened()), + ); + + let flip_h_external_texture = ctx.device.create_external_texture( + &wgpu::ExternalTextureDescriptor { + label: None, + width: 2, + height: 2, + format: wgpu::ExternalTextureFormat::Rgba, + yuv_conversion_matrix: IDENTITY_YUV_CONVERSION_MATRIX, + gamut_conversion_matrix: IDENTITY_GAMUT_CONVERSION_MATRIX, + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), + sample_transform: HORIZONTAL_FLIP_2X2_SAMPLE_TRANSFORM, + load_transform: HORIZONTAL_FLIP_2X2_LOAD_TRANSFORM, + }, + &[&view_2x2], + ); + let loads = get_loads( + &ctx, + &[[0, 0], [1, 0], [0, 1], [1, 1]], + wgpu::BindingResource::ExternalTexture(&flip_h_external_texture), + ); + assert_eq!(&loads, &[GREEN_F32, RED_F32, YELLOW_F32, BLUE_F32]); + + let flip_v_external_texture = ctx.device.create_external_texture( + &wgpu::ExternalTextureDescriptor { + label: None, + width: 2, + height: 2, + format: wgpu::ExternalTextureFormat::Rgba, + yuv_conversion_matrix: IDENTITY_YUV_CONVERSION_MATRIX, + gamut_conversion_matrix: IDENTITY_GAMUT_CONVERSION_MATRIX, + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), + sample_transform: VERTICAL_FLIP_2X2_SAMPLE_TRANSFORM, + load_transform: VERTICAL_FLIP_2X2_LOAD_TRANSFORM, + }, + &[&view_2x2], + ); + let loads = get_loads( + &ctx, + &[[0, 0], [1, 0], [0, 1], [1, 1]], + wgpu::BindingResource::ExternalTexture(&flip_v_external_texture), + ); + assert_eq!(&loads, &[BLUE_F32, YELLOW_F32, RED_F32, GREEN_F32]); + + // Use a non-square texture for the rotation cases as it's more + // interesting + let view_4x1 = create_texture_and_view( + &ctx, + wgpu::Extent3d { + width: 4, + height: 1, + depth_or_array_layers: 1, + }, + wgpu::TextureFormat::Rgba8Unorm, + Some(RGBA_TEXTURE_DATA.as_flattened()), + ); + + let rotate_90_external_texture = ctx.device.create_external_texture( + &wgpu::ExternalTextureDescriptor { + label: None, + width: 1, + height: 4, + format: wgpu::ExternalTextureFormat::Rgba, + yuv_conversion_matrix: IDENTITY_YUV_CONVERSION_MATRIX, + gamut_conversion_matrix: IDENTITY_GAMUT_CONVERSION_MATRIX, + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), + sample_transform: ROTATE_90_4X1_SAMPLE_TRANSFORM, + load_transform: ROTATE_90_4X1_LOAD_TRANSFORM, + }, + &[&view_4x1], + ); + let loads = get_loads( + &ctx, + &[[0, 0], [0, 1], [0, 2], [0, 3]], + wgpu::BindingResource::ExternalTexture(&rotate_90_external_texture), + ); + assert_eq!(&loads, &[RED_F32, GREEN_F32, BLUE_F32, YELLOW_F32]); + + let rotate_180_external_texture = ctx.device.create_external_texture( + &wgpu::ExternalTextureDescriptor { + label: None, + width: 4, + height: 1, + format: wgpu::ExternalTextureFormat::Rgba, + yuv_conversion_matrix: IDENTITY_YUV_CONVERSION_MATRIX, + gamut_conversion_matrix: IDENTITY_GAMUT_CONVERSION_MATRIX, + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), + sample_transform: ROTATE_180_4X1_SAMPLE_TRANSFORM, + load_transform: ROTATE_180_4X1_LOAD_TRANSFORM, + }, + &[&view_4x1], + ); + let loads = get_loads( + &ctx, + &[[0, 0], [1, 0], [2, 0], [3, 0]], + wgpu::BindingResource::ExternalTexture(&rotate_180_external_texture), + ); + assert_eq!(&loads, &[YELLOW_F32, BLUE_F32, GREEN_F32, RED_F32]); + + let rotate_270_external_texture = ctx.device.create_external_texture( + &wgpu::ExternalTextureDescriptor { + label: None, + width: 1, + height: 4, + format: wgpu::ExternalTextureFormat::Rgba, + yuv_conversion_matrix: IDENTITY_YUV_CONVERSION_MATRIX, + gamut_conversion_matrix: IDENTITY_GAMUT_CONVERSION_MATRIX, + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), + sample_transform: ROTATE_270_4X1_SAMPLE_TRANSFORM, + load_transform: ROTATE_270_4X1_LOAD_TRANSFORM, + }, + &[&view_4x1], + ); + let loads = get_loads( + &ctx, + &[[0, 0], [0, 1], [0, 2], [0, 3]], + wgpu::BindingResource::ExternalTexture(&rotate_270_external_texture), + ); + assert_eq!(&loads, &[YELLOW_F32, BLUE_F32, GREEN_F32, RED_F32]); + + let view_4x4 = create_texture_and_view( + &ctx, + wgpu::Extent3d { + width: 4, + height: 4, + depth_or_array_layers: 1, + }, + wgpu::TextureFormat::Rgba8Unorm, + Some(RGBA_TEXTURE_DATA_WITH_BORDER.as_flattened()), + ); + let crop_tex = ctx.device.create_external_texture( + &wgpu::ExternalTextureDescriptor { + label: None, + width: 2, + height: 2, + format: wgpu::ExternalTextureFormat::Rgba, + yuv_conversion_matrix: IDENTITY_YUV_CONVERSION_MATRIX, + gamut_conversion_matrix: IDENTITY_GAMUT_CONVERSION_MATRIX, + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), + sample_transform: CROP_4X4_SAMPLE_TRANSFORM, + load_transform: CROP_4X4_LOAD_TRANSFORM, + }, + &[&view_4x4], + ); + let loads = get_loads( + &ctx, + &[[0, 0], [1, 0], [0, 1], [1, 1]], + wgpu::BindingResource::ExternalTexture(&crop_tex), + ); + assert_eq!(&loads, &[RED_F32, GREEN_F32, BLUE_F32, YELLOW_F32]); + }); + +/// Tests that `textureLoad()` for an invalid address returns an allowed value. +#[gpu_test] +static EXTERNAL_TEXTURE_LOAD_INVALID_ADDRESS: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters( + TestParameters::default() + .test_features_limits() + .features(wgpu::Features::EXTERNAL_TEXTURE), + ) + .run_async(|ctx| async move { + // Create a 2x2 texture, but specify the width and height of the + // external texture to be 1x1. (0, 1), (1, 0), and (1, 1) will + // therefore be invalid addresses, despite falling within the bounds of + // the underlying texture. + let view = create_texture_and_view( + &ctx, + wgpu::Extent3d { + width: 2, + height: 2, + depth_or_array_layers: 1, + }, + wgpu::TextureFormat::Rgba8Unorm, + Some(RGBA_TEXTURE_DATA.as_flattened()), + ); + + let external_texture = ctx.device.create_external_texture( + &wgpu::ExternalTextureDescriptor { + label: None, + width: 1, + height: 1, + format: wgpu::ExternalTextureFormat::Rgba, + yuv_conversion_matrix: IDENTITY_YUV_CONVERSION_MATRIX, + gamut_conversion_matrix: IDENTITY_GAMUT_CONVERSION_MATRIX, + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), + sample_transform: IDENTITY_SAMPLE_TRANSFORM, + load_transform: IDENTITY_LOAD_TRANSFORM, + }, + &[&view], + ); + + let loads = get_loads( + &ctx, + &[[0, 0], [1, 0], [0, 1], [1, 1]], + wgpu::BindingResource::ExternalTexture(&external_texture), + ); + for load in &loads { + // From https://www.w3.org/TR/WGSL/#textureload: + // If the logical texel address is invalid, the built-in function returns one of: + // * The data for some texel within bounds of the texture + // * A vector (0,0,0,0) or (0,0,0,1) of the appropriate type for non-depth textures + // * 0.0 for depth textures + // We therefore expect the loaded values to be red, opaque black, + // or transparent black. They must not be green, blue, or yellow. + assert!([RED_F32, OPAQUE_BLACK_F32, TRANSPARENT_BLACK_F32].contains(load)); + } + }); + +/// Tests that `textureSampleBaseClampToEdge()` returns the correct values for both RGBA +/// format external textures and texture views bound to an external texture binding. +#[gpu_test] +static EXTERNAL_TEXTURE_SAMPLE: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters( + TestParameters::default() + .test_features_limits() + .features(wgpu::Features::EXTERNAL_TEXTURE), + ) + .run_async(|ctx| async move { + let view = create_texture_and_view( + &ctx, + wgpu::Extent3d { + width: 2, + height: 2, + depth_or_array_layers: 1, + }, + wgpu::TextureFormat::Rgba8Unorm, + Some(RGBA_TEXTURE_DATA.as_flattened()), + ); + let samples = get_samples( + &ctx, + &[[0.25, 0.25], [0.75, 0.25], [0.25, 0.75], [0.75, 0.75]], + wgpu::BindingResource::TextureView(&view), + ); + assert_eq!(&samples, &[RED_F32, GREEN_F32, BLUE_F32, YELLOW_F32]); + + let external_texture = ctx.device.create_external_texture( + &wgpu::ExternalTextureDescriptor { + label: None, + width: 2, + height: 2, + format: wgpu::ExternalTextureFormat::Rgba, + yuv_conversion_matrix: IDENTITY_YUV_CONVERSION_MATRIX, + gamut_conversion_matrix: IDENTITY_GAMUT_CONVERSION_MATRIX, + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), + sample_transform: IDENTITY_SAMPLE_TRANSFORM, + load_transform: IDENTITY_LOAD_TRANSFORM, + }, + &[&view], + ); + + let samples = get_samples( + &ctx, + &[[0.25, 0.25], [0.75, 0.25], [0.25, 0.75], [0.75, 0.75]], + wgpu::BindingResource::ExternalTexture(&external_texture), + ); + assert_eq!(&samples, &[RED_F32, GREEN_F32, BLUE_F32, YELLOW_F32]); + }); + +/// Tests that `textureSampleBaseClampToEdge()` returns the correct values for YUV +/// format external textures. +#[gpu_test] +static EXTERNAL_TEXTURE_SAMPLE_YUV: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters( + TestParameters::default() + .test_features_limits() + .features(wgpu::Features::EXTERNAL_TEXTURE), + ) + .run_async(|ctx| async move { + let y_view = create_texture_and_view( + &ctx, + wgpu::Extent3d { + width: 4, + height: 4, + depth_or_array_layers: 1, + }, + wgpu::TextureFormat::R8Unorm, + Some(&Y_TEXTURE_DATA), + ); + let u_view = create_texture_and_view( + &ctx, + wgpu::Extent3d { + width: 2, + height: 2, + depth_or_array_layers: 1, + }, + wgpu::TextureFormat::R8Unorm, + Some(&U_TEXTURE_DATA), + ); + let v_view = create_texture_and_view( + &ctx, + wgpu::Extent3d { + width: 2, + height: 2, + depth_or_array_layers: 1, + }, + wgpu::TextureFormat::R8Unorm, + Some(&V_TEXTURE_DATA), + ); + + let external_texture = ctx.device.create_external_texture( + &wgpu::ExternalTextureDescriptor { + label: None, + width: 4, + height: 4, + format: wgpu::ExternalTextureFormat::Yu12, + yuv_conversion_matrix: BT601_YUV_CONVERSION_MATRIX, + gamut_conversion_matrix: BT601_TO_SRGB_GAMUT_CONVERSION_MATRIX, + src_transfer_function: SRGB_TRANSFER_FUNCTION, + dst_transfer_function: SRGB_TRANSFER_FUNCTION, + sample_transform: IDENTITY_SAMPLE_TRANSFORM, + load_transform: IDENTITY_LOAD_TRANSFORM, + }, + &[&y_view, &u_view, &v_view], + ); + let samples = get_samples( + &ctx, + &[ + [0.375, 0.375], + [0.625, 0.375], + [0.375, 0.625], + [0.625, 0.625], + ], + wgpu::BindingResource::ExternalTexture(&external_texture), + ); + + // `assert_abs_diff_eq!()` works for slices but not arrays, hence the + // following tomfoolery. + let samples = samples.iter().map(|arr| arr.as_slice()).collect::>(); + let expected = [RED_SRGB_F32, GREEN_SRGB_F32, BLUE_SRGB_F32, YELLOW_SRGB_F32]; + let expected = expected.each_ref().map(|arr| arr.as_slice()); + // We expect slight inaccuracies due to floating point maths. + assert_abs_diff_eq!(samples.as_slice(), expected.as_slice(), epsilon = 0.01); + }); + +/// Tests that `textureSampleBaseClampToEdge()` returns the correct values for external +/// textures with various sample transforms. +#[gpu_test] +static EXTERNAL_TEXTURE_SAMPLE_TRANSFORM: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters( + TestParameters::default() + .test_features_limits() + .features(wgpu::Features::EXTERNAL_TEXTURE), + ) + .run_async(|ctx| async move { + let view_2x2 = create_texture_and_view( + &ctx, + wgpu::Extent3d { + width: 2, + height: 2, + depth_or_array_layers: 1, + }, + wgpu::TextureFormat::Rgba8Unorm, + Some(RGBA_TEXTURE_DATA.as_flattened()), + ); + + let flip_h_external_texture = ctx.device.create_external_texture( + &wgpu::ExternalTextureDescriptor { + label: None, + width: 2, + height: 2, + format: wgpu::ExternalTextureFormat::Rgba, + yuv_conversion_matrix: IDENTITY_YUV_CONVERSION_MATRIX, + gamut_conversion_matrix: IDENTITY_GAMUT_CONVERSION_MATRIX, + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), + sample_transform: HORIZONTAL_FLIP_2X2_SAMPLE_TRANSFORM, + load_transform: HORIZONTAL_FLIP_2X2_LOAD_TRANSFORM, + }, + &[&view_2x2], + ); + let samples = get_samples( + &ctx, + &[[0.25, 0.25], [0.75, 0.25], [0.25, 0.75], [0.75, 0.75]], + wgpu::BindingResource::ExternalTexture(&flip_h_external_texture), + ); + assert_eq!(&samples, &[GREEN_F32, RED_F32, YELLOW_F32, BLUE_F32]); + + let flip_v_external_texture = ctx.device.create_external_texture( + &wgpu::ExternalTextureDescriptor { + label: None, + width: 2, + height: 2, + format: wgpu::ExternalTextureFormat::Rgba, + yuv_conversion_matrix: IDENTITY_YUV_CONVERSION_MATRIX, + gamut_conversion_matrix: IDENTITY_GAMUT_CONVERSION_MATRIX, + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), + sample_transform: VERTICAL_FLIP_2X2_SAMPLE_TRANSFORM, + load_transform: VERTICAL_FLIP_2X2_LOAD_TRANSFORM, + }, + &[&view_2x2], + ); + let samples = get_samples( + &ctx, + &[[0.25, 0.25], [0.75, 0.25], [0.25, 0.75], [0.75, 0.75]], + wgpu::BindingResource::ExternalTexture(&flip_v_external_texture), + ); + assert_eq!(&samples, &[BLUE_F32, YELLOW_F32, RED_F32, GREEN_F32]); + + // Use a non-square texture for the rotation cases as it's more + // interesting + let view_4x1 = create_texture_and_view( + &ctx, + wgpu::Extent3d { + width: 4, + height: 1, + depth_or_array_layers: 1, + }, + wgpu::TextureFormat::Rgba8Unorm, + Some(RGBA_TEXTURE_DATA.as_flattened()), + ); + + let rotate_90_external_texture = ctx.device.create_external_texture( + &wgpu::ExternalTextureDescriptor { + label: None, + width: 1, + height: 4, + format: wgpu::ExternalTextureFormat::Rgba, + yuv_conversion_matrix: IDENTITY_YUV_CONVERSION_MATRIX, + gamut_conversion_matrix: IDENTITY_GAMUT_CONVERSION_MATRIX, + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), + sample_transform: ROTATE_90_4X1_SAMPLE_TRANSFORM, + load_transform: ROTATE_90_4X1_LOAD_TRANSFORM, + }, + &[&view_4x1], + ); + let samples = get_samples( + &ctx, + &[[0.5, 0.125], [0.5, 0.375], [0.5, 0.625], [0.5, 0.875]], + wgpu::BindingResource::ExternalTexture(&rotate_90_external_texture), + ); + assert_eq!(&samples, &[RED_F32, GREEN_F32, BLUE_F32, YELLOW_F32]); + + let rotate_180_external_texture = ctx.device.create_external_texture( + &wgpu::ExternalTextureDescriptor { + label: None, + width: 4, + height: 1, + format: wgpu::ExternalTextureFormat::Rgba, + yuv_conversion_matrix: IDENTITY_YUV_CONVERSION_MATRIX, + gamut_conversion_matrix: IDENTITY_GAMUT_CONVERSION_MATRIX, + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), + sample_transform: ROTATE_180_4X1_SAMPLE_TRANSFORM, + load_transform: ROTATE_180_4X1_LOAD_TRANSFORM, + }, + &[&view_4x1], + ); + let samples = get_samples( + &ctx, + &[[0.125, 0.5], [0.375, 0.5], [0.625, 0.5], [0.875, 0.5]], + wgpu::BindingResource::ExternalTexture(&rotate_180_external_texture), + ); + assert_eq!(&samples, &[YELLOW_F32, BLUE_F32, GREEN_F32, RED_F32]); + + let rotate_270_external_texture = ctx.device.create_external_texture( + &wgpu::ExternalTextureDescriptor { + label: None, + width: 1, + height: 4, + format: wgpu::ExternalTextureFormat::Rgba, + yuv_conversion_matrix: IDENTITY_YUV_CONVERSION_MATRIX, + gamut_conversion_matrix: IDENTITY_GAMUT_CONVERSION_MATRIX, + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), + sample_transform: ROTATE_270_4X1_SAMPLE_TRANSFORM, + load_transform: ROTATE_270_4X1_LOAD_TRANSFORM, + }, + &[&view_4x1], + ); + let samples = get_samples( + &ctx, + &[[0.5, 0.125], [0.5, 0.375], [0.5, 0.625], [0.5, 0.875]], + wgpu::BindingResource::ExternalTexture(&rotate_270_external_texture), + ); + assert_eq!(&samples, &[YELLOW_F32, BLUE_F32, GREEN_F32, RED_F32]); + + let view_4x4 = create_texture_and_view( + &ctx, + wgpu::Extent3d { + width: 4, + height: 4, + depth_or_array_layers: 1, + }, + wgpu::TextureFormat::Rgba8Unorm, + Some(RGBA_TEXTURE_DATA_WITH_BORDER.as_flattened()), + ); + let crop_tex = ctx.device.create_external_texture( + &wgpu::ExternalTextureDescriptor { + label: None, + width: 2, + height: 2, + format: wgpu::ExternalTextureFormat::Rgba, + yuv_conversion_matrix: IDENTITY_YUV_CONVERSION_MATRIX, + gamut_conversion_matrix: IDENTITY_GAMUT_CONVERSION_MATRIX, + src_transfer_function: Default::default(), + dst_transfer_function: Default::default(), + sample_transform: CROP_4X4_SAMPLE_TRANSFORM, + load_transform: CROP_4X4_LOAD_TRANSFORM, + }, + &[&view_4x4], + ); + // Deliberately sample from the edges of the external texture rather + // than the texel centres. This tests that clamping to a half-texel + // from the edge works as expected even when the external texture is + // cropped from a larger texture. If this weren't working, the black + // border would affect the sampled values. + let samples = get_samples( + &ctx, + &[[0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [1.0, 1.0]], + wgpu::BindingResource::ExternalTexture(&crop_tex), + ); + assert_eq!(&samples, &[RED_F32, GREEN_F32, BLUE_F32, YELLOW_F32]); + }); diff --git a/tests/tests/wgpu-gpu/external_texture/sample.wgsl b/tests/tests/wgpu-gpu/external_texture/sample.wgsl new file mode 100644 index 00000000000..ab6e862da99 --- /dev/null +++ b/tests/tests/wgpu-gpu/external_texture/sample.wgsl @@ -0,0 +1,14 @@ +@group(0) @binding(0) +var tex: texture_external; +@group(0) @binding(1) +var samp: sampler; + +@group(0) @binding(2) +var coords: array>; +@group(0) @binding(3) +var output: array>; + +@compute @workgroup_size(1) +fn main(@builtin(global_invocation_id) id: vec3) { + output[id.x] = textureSampleBaseClampToEdge(tex, samp, coords[id.x]); +} diff --git a/tests/tests/wgpu-gpu/main.rs b/tests/tests/wgpu-gpu/main.rs index 2698436ae48..98793419e15 100644 --- a/tests/tests/wgpu-gpu/main.rs +++ b/tests/tests/wgpu-gpu/main.rs @@ -29,6 +29,7 @@ mod draw_indirect; mod dual_source_blending; mod encoder; mod external_image_copy; +mod external_texture; mod float32_filterable; mod image_atomics; mod instance; @@ -88,6 +89,7 @@ fn all_tests() -> Vec { draw_indirect::all_tests(&mut tests); dual_source_blending::all_tests(&mut tests); encoder::all_tests(&mut tests); + external_texture::all_tests(&mut tests); float32_filterable::all_tests(&mut tests); image_atomics::all_tests(&mut tests); instance::all_tests(&mut tests); From 24a05fefdf20626ef7bf672ece804a4cf0ae2650 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Thu, 7 Aug 2025 18:01:45 -0700 Subject: [PATCH 100/303] Update CHANGELOG (#8050) --- CHANGELOG.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0de38979643..8a8a963cfc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,10 +58,22 @@ By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). #### General - Prevent resources for acceleration structures being created if acceleration structures are not enabled. By @Vecvec in [#8036](https://github.com/gfx-rs/wgpu/pull/8036). +- Validate that each `push_debug_group` pairs with exactly one `pop_debug_group`. By @andyleiserson in [#8048](https://github.com/gfx-rs/wgpu/pull/8048). +- `set_viewport` now requires that the supplied minimum depth value is less than the maximum depth value. By @andyleiserson in [#8040](https://github.com/gfx-rs/wgpu/pull/8040). +- Validation of `copy_texture_to_buffer`, `copy_buffer_to_texture`, and `copy_texture_to_texture` operations more closely follows the WebGPU specification. By @andyleiserson in various PRs. + - Copies within the same texture must not overlap. + - Copies of multisampled or depth/stencil formats must span an entire subresource (layer). + - Copies of depth/stencil formats must be 4B aligned. +- The offset for `set_vertex_buffer` and `set_index_buffer` must be 4B aligned. By @andyleiserson in [#7929](https://github.com/gfx-rs/wgpu/pull/7929). +- The offset and size of bindings are validated as fitting within the underlying buffer in more cases. By @andyleiserson in [#7911](https://github.com/gfx-rs/wgpu/pull/7911). #### Naga -Naga now requires that no type be larger than 1 GB. This limit may be lowered in the future; feedback on an appropriate value for the limit is welcome. By @andyleiserson in [#7950](https://github.com/gfx-rs/wgpu/pull/7950). +- Naga now requires that no type be larger than 1 GB. This limit may be lowered in the future; feedback on an appropriate value for the limit is welcome. By @andyleiserson in [#7950](https://github.com/gfx-rs/wgpu/pull/7950). + +#### DX12 + +- Fixed a bug where access to matrices with 2 rows would not work in some cases. By @andyleiserson in [#7438](https://github.com/gfx-rs/wgpu/pull/7438). ### Bug Fixes @@ -71,7 +83,7 @@ Naga now requires that no type be larger than 1 GB. This limit may be lowered in #### Vulkan -Fix `STATUS_HEAP_CORRUPTION` crash when concurrently calling `create_sampler`. By @atlv24 in [#8043](https://github.com/gfx-rs/wgpu/pull/8043). +- Fix `STATUS_HEAP_CORRUPTION` crash when concurrently calling `create_sampler`. By @atlv24 in [#8043](https://github.com/gfx-rs/wgpu/pull/8043). ## v26.0.2 (2025-07-23) From 0c30efe8574436a35222dae8d80ab2649f33b3ad Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Fri, 8 Aug 2025 18:50:26 -0400 Subject: [PATCH 101/303] docs(release-checklist): sync backporting label name with current one (#8062) --- docs/release-checklist.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/release-checklist.md b/docs/release-checklist.md index f533255ccaa..dcd4674fa51 100644 --- a/docs/release-checklist.md +++ b/docs/release-checklist.md @@ -13,6 +13,7 @@ Anyone in the @gfx-rs/wgpu team can perform these steps. ## Major Release Process Approx 1 Week Before: + - Determine if `glow` (@groves), `metal-rs` (@gfx-rs/wgpu) or any other dependant crates will need a release. If so, coordinate with their maintainers. - Go through the changelog: - Re-categorize miscategorized items. @@ -21,6 +22,7 @@ Approx 1 Week Before: - Copy-edit the changelog for clarity. Day of Release: + - Update the version number in the root `Cargo.toml` to the new version, this will update all crates to the new version. - Bump the wgpu dependency numbers in the following places: - `Cargo.toml` @@ -67,7 +69,8 @@ Day of Release: - [Rust Community Discord](https://discord.gg/rust-lang-community) in the #games-and-graphics channel ## Patch Release Process -- Enumerate all PRs that haven't been backported yet. These use the `needs-backport` label. [GH Link](https://github.com/gfx-rs/wgpu/pulls?q=sort%3Aupdated-desc+is%3Apr+label%3A%22PR%3A+needs+back-porting%22) + +- Enumerate all PRs that haven't been backported yet. These use the `PR: needs back-porting` label. [GH Link](https://github.com/gfx-rs/wgpu/pulls?q=sort%3Aupdated-desc+is%3Apr+label%3A%22PR%3A+needs+back-porting%22) - On _your own branch_ based on the latest release branch. Cherry-pick the PRs that need to be backported. When modifying the commits, use --append to retain their original authorship. - Remove the `needs-backport` label from the PRs. - Fix the changelogs items and add a new header for the patch release with the release version and date. From 78163905664e0771bb42aff62ad118928b72ffd6 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Fri, 8 Aug 2025 12:42:09 -0700 Subject: [PATCH 102/303] Make vendor-web-sys xtask accept a SHA Also, update wasm-bindgen URLs --- xtask/src/cts.rs | 118 +--------------------------------- xtask/src/util.rs | 123 ++++++++++++++++++++++++++++++++++++ xtask/src/vendor_web_sys.rs | 54 +++++++++------- 3 files changed, 157 insertions(+), 138 deletions(-) diff --git a/xtask/src/cts.rs b/xtask/src/cts.rs index 2dfbb2013f7..fdeae96c3cf 100644 --- a/xtask/src/cts.rs +++ b/xtask/src/cts.rs @@ -36,6 +36,8 @@ use regex_lite::{Regex, RegexBuilder}; use std::{ffi::OsString, sync::LazyLock}; use xshell::Shell; +use crate::util::git_version_at_least; + /// Path within the repository where the CTS will be checked out. const CTS_CHECKOUT_PATH: &str = "cts"; @@ -244,119 +246,3 @@ pub fn run_cts(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { Ok(()) } - -fn git_version_at_least(shell: &Shell, version: GitVersion) -> anyhow::Result { - let output = shell - .cmd("git") - .args(["--version"]) - .output() - .context("Failed to invoke `git --version`")?; - - let Some(code) = output.status.code() else { - anyhow::bail!("`git --version` failed to return an exit code; interrupt via signal, maybe?") - }; - - anyhow::ensure!(code == 0, "`git --version` returned a nonzero exit code"); - - let fmt_err_msg = "`git --version` did not have the expected structure"; - - let stdout = String::from_utf8(output.stdout).expect(fmt_err_msg); - - let parsed = parse_git_version_output(&stdout).expect(fmt_err_msg); - - Ok(parsed >= version) -} - -pub type GitVersion = [u8; 3]; - -fn parse_git_version_output(output: &str) -> anyhow::Result { - const PREFIX: &str = "git version "; - - let raw_version = output - .strip_prefix(PREFIX) - .with_context(|| format!("missing `{PREFIX}` prefix"))?; - - let raw_version = raw_version.trim_end(); // There should always be a newline at the end, but - // we don't care if it's missing. - - // Git for Windows suffixes the version with ".windows.". - // Strip it if present. - let raw_version = raw_version - .split_once(".windows") - .map_or(raw_version, |(before, _after)| before); - - let parsed = GitVersion::try_from( - raw_version - .splitn(3, '.') - .enumerate() - .map(|(idx, s)| { - s.parse().with_context(|| { - format!("failed to parse version number {idx} ({s:?}) as `u8`") - }) - }) - .collect::, _>>()?, - ) - .map_err(|vec| anyhow::Error::msg(format!("less than 3 version numbers found: {vec:?}")))?; - - log::debug!("detected Git version {raw_version}"); - - Ok(parsed) -} - -#[test] -fn test_git_version_parsing() { - macro_rules! test_ok { - ($input:expr, $expected:expr) => { - assert_eq!(parse_git_version_output($input).unwrap(), $expected); - }; - } - test_ok!("git version 2.3.0", [2, 3, 0]); - test_ok!("git version 0.255.0", [0, 255, 0]); - test_ok!("git version 4.5.6", [4, 5, 6]); - test_ok!("git version 2.3.0.windows.1", [2, 3, 0]); - - macro_rules! test_err { - ($input:expr, $msg:expr) => { - assert_eq!( - parse_git_version_output($input).unwrap_err().to_string(), - $msg - ) - }; - } - test_err!("2.3.0", "missing `git version ` prefix"); - test_err!("", "missing `git version ` prefix"); - - test_err!( - "git version 1.2", - "less than 3 version numbers found: [1, 2]" - ); - - test_err!( - "git version 9001", - "failed to parse version number 0 (\"9001\") as `u8`" - ); - test_err!( - "git version ", - "failed to parse version number 0 (\"\") as `u8`" - ); - test_err!( - "git version asdf", - "failed to parse version number 0 (\"asdf\") as `u8`" - ); - test_err!( - "git version 23.beta", - "failed to parse version number 1 (\"beta\") as `u8`" - ); - test_err!( - "git version 1.2.wat", - "failed to parse version number 2 (\"wat\") as `u8`" - ); - test_err!( - "git version 1.2.3.", - "failed to parse version number 2 (\"3.\") as `u8`" - ); - test_err!( - "git version 1.2.3.4", - "failed to parse version number 2 (\"3.4\") as `u8`" - ); -} diff --git a/xtask/src/util.rs b/xtask/src/util.rs index e38afde60d0..eb3e7819f56 100644 --- a/xtask/src/util.rs +++ b/xtask/src/util.rs @@ -1,10 +1,17 @@ use std::{io, process::Command}; +use anyhow::Context; +use xshell::Shell; + pub(crate) struct Program { pub crate_name: &'static str, pub binary_name: &'static str, } +pub(crate) fn looks_like_git_sha(input: &str) -> bool { + input.len() == 40 && input.chars().all(|c| c.is_ascii_hexdigit()) +} + pub(crate) fn check_all_programs(programs: &[Program]) -> anyhow::Result<()> { let mut failed_crates = Vec::new(); for &Program { @@ -41,3 +48,119 @@ pub(crate) fn check_all_programs(programs: &[Program]) -> anyhow::Result<()> { Ok(()) } + +pub(crate) fn git_version_at_least(shell: &Shell, version: GitVersion) -> anyhow::Result { + let output = shell + .cmd("git") + .args(["--version"]) + .output() + .context("Failed to invoke `git --version`")?; + + let Some(code) = output.status.code() else { + anyhow::bail!("`git --version` failed to return an exit code; interrupt via signal, maybe?") + }; + + anyhow::ensure!(code == 0, "`git --version` returned a nonzero exit code"); + + let fmt_err_msg = "`git --version` did not have the expected structure"; + + let stdout = String::from_utf8(output.stdout).expect(fmt_err_msg); + + let parsed = parse_git_version_output(&stdout).expect(fmt_err_msg); + + Ok(parsed >= version) +} + +pub(crate) type GitVersion = [u8; 3]; + +fn parse_git_version_output(output: &str) -> anyhow::Result { + const PREFIX: &str = "git version "; + + let raw_version = output + .strip_prefix(PREFIX) + .with_context(|| format!("missing `{PREFIX}` prefix"))?; + + let raw_version = raw_version.trim_end(); // There should always be a newline at the end, but + // we don't care if it's missing. + + // Git for Windows suffixes the version with ".windows.". + // Strip it if present. + let raw_version = raw_version + .split_once(".windows") + .map_or(raw_version, |(before, _after)| before); + + let parsed = GitVersion::try_from( + raw_version + .splitn(3, '.') + .enumerate() + .map(|(idx, s)| { + s.parse().with_context(|| { + format!("failed to parse version number {idx} ({s:?}) as `u8`") + }) + }) + .collect::, _>>()?, + ) + .map_err(|vec| anyhow::Error::msg(format!("less than 3 version numbers found: {vec:?}")))?; + + log::debug!("detected Git version {raw_version}"); + + Ok(parsed) +} + +#[test] +fn test_git_version_parsing() { + macro_rules! test_ok { + ($input:expr, $expected:expr) => { + assert_eq!(parse_git_version_output($input).unwrap(), $expected); + }; + } + test_ok!("git version 2.3.0", [2, 3, 0]); + test_ok!("git version 0.255.0", [0, 255, 0]); + test_ok!("git version 4.5.6", [4, 5, 6]); + test_ok!("git version 2.3.0.windows.1", [2, 3, 0]); + + macro_rules! test_err { + ($input:expr, $msg:expr) => { + assert_eq!( + parse_git_version_output($input).unwrap_err().to_string(), + $msg + ) + }; + } + test_err!("2.3.0", "missing `git version ` prefix"); + test_err!("", "missing `git version ` prefix"); + + test_err!( + "git version 1.2", + "less than 3 version numbers found: [1, 2]" + ); + + test_err!( + "git version 9001", + "failed to parse version number 0 (\"9001\") as `u8`" + ); + test_err!( + "git version ", + "failed to parse version number 0 (\"\") as `u8`" + ); + test_err!( + "git version asdf", + "failed to parse version number 0 (\"asdf\") as `u8`" + ); + test_err!( + "git version 23.beta", + "failed to parse version number 1 (\"beta\") as `u8`" + ); + test_err!( + "git version 1.2.wat", + "failed to parse version number 2 (\"wat\") as `u8`" + ); + test_err!( + "git version 1.2.3.", + "failed to parse version number 2 (\"3.\") as `u8`" + ); + test_err!( + "git version 1.2.3.4", + "failed to parse version number 2 (\"3.4\") as `u8`" + ); +} diff --git a/xtask/src/vendor_web_sys.rs b/xtask/src/vendor_web_sys.rs index f519ae78662..15f25f45260 100644 --- a/xtask/src/vendor_web_sys.rs +++ b/xtask/src/vendor_web_sys.rs @@ -3,7 +3,10 @@ use pico_args::Arguments; use std::fmt::Write; use xshell::Shell; -use crate::bad_arguments; +use crate::{ + bad_arguments, + util::{git_version_at_least, looks_like_git_sha}, +}; /// Path to the webgpu_sys folder relative to the root of the repository const WEBGPU_SYS_PATH: &str = "wgpu/src/backend/webgpu/webgpu_sys"; @@ -198,24 +201,31 @@ pub(crate) fn run_vendor_web_sys(shell: Shell, mut args: Arguments) -> anyhow::R .remove_path(WEBGPU_SYS_PATH) .context("could not remove webgpu_sys")?; - if let Some(ref version) = version { + if let Some(version) = version.as_deref() { eprintln!("# Cloning wasm-bindgen repository with version {version}"); - shell - .cmd("git") - .args([ - "clone", - "-b", - version, - "--depth", - "1", - git_url - .as_deref() - .unwrap_or("https://github.com/rustwasm/wasm-bindgen.git"), - WASM_BINDGEN_TEMP_CLONE_PATH, - ]) - .ignore_stderr() - .run() - .context("Could not clone wasm-bindgen repository")?; + let mut cmd = shell.cmd("git").args(["clone"]); + + if looks_like_git_sha(version) { + if git_version_at_least(&shell, [2, 49, 0])? { + cmd = cmd.args(["--revision", version]); + } else { + bad_arguments!("Must have git >= 2.49 to clone a SHA with --revision"); + } + } else { + cmd = cmd.args(["-b", version]); + } + + cmd.args([ + "--depth", + "1", + git_url + .as_deref() + .unwrap_or("https://github.com/wasm-bindgen/wasm-bindgen.git"), + WASM_BINDGEN_TEMP_CLONE_PATH, + ]) + .ignore_stderr() + .run() + .context("Could not clone wasm-bindgen repository")?; } if let Some(ref path) = path_to_checkout_arg { @@ -229,7 +239,7 @@ pub(crate) fn run_vendor_web_sys(shell: Shell, mut args: Arguments) -> anyhow::R // The indentation here does not matter, as rustfmt will normalize it. let file_prefix = format!("\ // DO NOT EDIT THIS FILE! - // + // // This module part of a subset of web-sys that is used by wgpu's webgpu backend. // // These bindings are vendored into wgpu for the sole purpose of letting @@ -246,8 +256,8 @@ pub(crate) fn run_vendor_web_sys(shell: Shell, mut args: Arguments) -> anyhow::R // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // - // If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. - // + // If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. + // // This file was generated by the `cargo xtask vendor-web-sys {argument_description}` command.\n" ); @@ -286,7 +296,7 @@ pub(crate) fn run_vendor_web_sys(shell: Shell, mut args: Arguments) -> anyhow::R let mut module_file_contents = format!( "\ //! Bindings to the WebGPU API. - //! + //! //! Internally vendored from the `web-sys` crate until the WebGPU binding are stabilized. {file_prefix} #![allow(unused_imports, non_snake_case)]\n" From 605f40d8664433eab25297b397527d59a802691f Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Fri, 8 Aug 2025 12:43:27 -0700 Subject: [PATCH 103/303] Vendor web-sys --- wgpu/src/backend/webgpu/webgpu_sys/gen_Gpu.rs | 14 +-- .../webgpu/webgpu_sys/gen_GpuAdapter.rs | 18 +-- .../webgpu/webgpu_sys/gen_GpuAdapterInfo.rs | 14 +-- .../webgpu/webgpu_sys/gen_GpuAddressMode.rs | 6 +- .../webgpu_sys/gen_GpuAutoLayoutMode.rs | 6 +- .../webgpu/webgpu_sys/gen_GpuBindGroup.rs | 10 +- .../webgpu_sys/gen_GpuBindGroupDescriptor.rs | 20 +-- .../webgpu_sys/gen_GpuBindGroupEntry.rs | 16 +-- .../webgpu_sys/gen_GpuBindGroupLayout.rs | 10 +- .../gen_GpuBindGroupLayoutDescriptor.rs | 16 +-- .../webgpu_sys/gen_GpuBindGroupLayoutEntry.rs | 36 +++--- .../webgpu_sys/gen_GpuBlendComponent.rs | 20 +-- .../webgpu/webgpu_sys/gen_GpuBlendFactor.rs | 6 +- .../webgpu_sys/gen_GpuBlendOperation.rs | 6 +- .../webgpu/webgpu_sys/gen_GpuBlendState.rs | 16 +-- .../webgpu/webgpu_sys/gen_GpuBuffer.rs | 48 ++++---- .../webgpu/webgpu_sys/gen_GpuBufferBinding.rs | 20 +-- .../webgpu_sys/gen_GpuBufferBindingLayout.rs | 20 +-- .../webgpu_sys/gen_GpuBufferBindingType.rs | 6 +- .../webgpu_sys/gen_GpuBufferDescriptor.rs | 24 ++-- .../webgpu_sys/gen_GpuBufferMapState.rs | 6 +- .../webgpu_sys/gen_GpuCanvasAlphaMode.rs | 6 +- .../webgpu_sys/gen_GpuCanvasConfiguration.rs | 32 ++--- .../webgpu/webgpu_sys/gen_GpuCanvasContext.rs | 16 +-- .../webgpu_sys/gen_GpuCanvasToneMapping.rs | 12 +- .../gen_GpuCanvasToneMappingMode.rs | 6 +- .../webgpu/webgpu_sys/gen_GpuColorDict.rs | 24 ++-- .../webgpu_sys/gen_GpuColorTargetState.rs | 20 +-- .../webgpu/webgpu_sys/gen_GpuCommandBuffer.rs | 10 +- .../gen_GpuCommandBufferDescriptor.rs | 12 +- .../webgpu_sys/gen_GpuCommandEncoder.rs | 80 ++++++------ .../gen_GpuCommandEncoderDescriptor.rs | 12 +- .../webgpu_sys/gen_GpuCompareFunction.rs | 6 +- .../webgpu_sys/gen_GpuCompilationInfo.rs | 8 +- .../webgpu_sys/gen_GpuCompilationMessage.rs | 18 +-- .../gen_GpuCompilationMessageType.rs | 6 +- .../gen_GpuComputePassDescriptor.rs | 16 +-- .../webgpu_sys/gen_GpuComputePassEncoder.rs | 42 +++---- .../gen_GpuComputePassTimestampWrites.rs | 20 +-- .../webgpu_sys/gen_GpuComputePipeline.rs | 12 +- .../gen_GpuComputePipelineDescriptor.rs | 20 +-- .../gen_GpuCopyExternalImageDestInfo.rs | 28 ++--- .../gen_GpuCopyExternalImageSourceInfo.rs | 20 +-- .../webgpu/webgpu_sys/gen_GpuCullMode.rs | 6 +- .../webgpu_sys/gen_GpuDepthStencilState.rs | 48 ++++---- .../webgpu/webgpu_sys/gen_GpuDevice.rs | 64 +++++----- .../webgpu_sys/gen_GpuDeviceDescriptor.rs | 24 ++-- .../webgpu_sys/gen_GpuDeviceLostInfo.rs | 10 +- .../webgpu_sys/gen_GpuDeviceLostReason.rs | 6 +- .../backend/webgpu/webgpu_sys/gen_GpuError.rs | 8 +- .../webgpu/webgpu_sys/gen_GpuErrorFilter.rs | 6 +- .../webgpu/webgpu_sys/gen_GpuExtent3dDict.rs | 20 +-- .../webgpu_sys/gen_GpuExternalTexture.rs | 10 +- .../gen_GpuExternalTextureBindingLayout.rs | 8 +- .../gen_GpuExternalTextureDescriptor.rs | 16 +-- .../webgpu/webgpu_sys/gen_GpuFeatureName.rs | 6 +- .../webgpu/webgpu_sys/gen_GpuFilterMode.rs | 6 +- .../webgpu/webgpu_sys/gen_GpuFragmentState.rs | 24 ++-- .../webgpu/webgpu_sys/gen_GpuFrontFace.rs | 6 +- .../webgpu/webgpu_sys/gen_GpuIndexFormat.rs | 6 +- .../webgpu/webgpu_sys/gen_GpuLoadOp.rs | 6 +- .../webgpu_sys/gen_GpuMipmapFilterMode.rs | 6 +- .../webgpu_sys/gen_GpuMultisampleState.rs | 20 +-- .../webgpu_sys/gen_GpuObjectDescriptorBase.rs | 12 +- .../webgpu/webgpu_sys/gen_GpuOrigin2dDict.rs | 16 +-- .../webgpu/webgpu_sys/gen_GpuOrigin3dDict.rs | 20 +-- .../webgpu_sys/gen_GpuOutOfMemoryError.rs | 8 +- .../gen_GpuPipelineDescriptorBase.rs | 16 +-- .../webgpu_sys/gen_GpuPipelineLayout.rs | 10 +- .../gen_GpuPipelineLayoutDescriptor.rs | 16 +-- .../webgpu_sys/gen_GpuPowerPreference.rs | 6 +- .../webgpu_sys/gen_GpuPrimitiveState.rs | 28 ++--- .../webgpu_sys/gen_GpuPrimitiveTopology.rs | 6 +- .../webgpu_sys/gen_GpuProgrammableStage.rs | 20 +-- .../webgpu/webgpu_sys/gen_GpuQuerySet.rs | 16 +-- .../webgpu_sys/gen_GpuQuerySetDescriptor.rs | 20 +-- .../webgpu/webgpu_sys/gen_GpuQueryType.rs | 6 +- .../backend/webgpu/webgpu_sys/gen_GpuQueue.rs | 114 +++++++++--------- .../webgpu_sys/gen_GpuQueueDescriptor.rs | 12 +- .../webgpu/webgpu_sys/gen_GpuRenderBundle.rs | 10 +- .../gen_GpuRenderBundleDescriptor.rs | 12 +- .../webgpu_sys/gen_GpuRenderBundleEncoder.rs | 88 +++++++------- .../gen_GpuRenderBundleEncoderDescriptor.rs | 32 ++--- .../gen_GpuRenderPassColorAttachment.rs | 32 ++--- ...gen_GpuRenderPassDepthStencilAttachment.rs | 44 +++---- .../webgpu_sys/gen_GpuRenderPassDescriptor.rs | 32 ++--- .../webgpu_sys/gen_GpuRenderPassEncoder.rs | 102 ++++++++-------- .../gen_GpuRenderPassTimestampWrites.rs | 20 +-- .../webgpu_sys/gen_GpuRenderPipeline.rs | 12 +- .../gen_GpuRenderPipelineDescriptor.rs | 36 +++--- .../gen_GpuRequestAdapterOptions.rs | 24 ++-- .../webgpu/webgpu_sys/gen_GpuSampler.rs | 10 +- .../webgpu_sys/gen_GpuSamplerBindingLayout.rs | 12 +- .../webgpu_sys/gen_GpuSamplerBindingType.rs | 6 +- .../webgpu_sys/gen_GpuSamplerDescriptor.rs | 52 ++++---- .../webgpu/webgpu_sys/gen_GpuShaderModule.rs | 12 +- .../gen_GpuShaderModuleDescriptor.rs | 20 +-- .../webgpu_sys/gen_GpuStencilFaceState.rs | 24 ++-- .../webgpu_sys/gen_GpuStencilOperation.rs | 6 +- .../webgpu_sys/gen_GpuStorageTextureAccess.rs | 6 +- .../gen_GpuStorageTextureBindingLayout.rs | 20 +-- .../webgpu/webgpu_sys/gen_GpuStoreOp.rs | 6 +- .../webgpu_sys/gen_GpuSupportedFeatures.rs | 18 +-- .../webgpu_sys/gen_GpuSupportedLimits.rs | 68 +++++------ .../webgpu_sys/gen_GpuTexelCopyBufferInfo.rs | 24 ++-- .../gen_GpuTexelCopyBufferLayout.rs | 20 +-- .../webgpu_sys/gen_GpuTexelCopyTextureInfo.rs | 24 ++-- .../webgpu/webgpu_sys/gen_GpuTexture.rs | 32 ++--- .../webgpu/webgpu_sys/gen_GpuTextureAspect.rs | 6 +- .../webgpu_sys/gen_GpuTextureBindingLayout.rs | 20 +-- .../webgpu_sys/gen_GpuTextureDescriptor.rs | 40 +++--- .../webgpu_sys/gen_GpuTextureDimension.rs | 6 +- .../webgpu/webgpu_sys/gen_GpuTextureFormat.rs | 6 +- .../webgpu_sys/gen_GpuTextureSampleType.rs | 6 +- .../webgpu/webgpu_sys/gen_GpuTextureView.rs | 10 +- .../gen_GpuTextureViewDescriptor.rs | 44 +++---- .../webgpu_sys/gen_GpuTextureViewDimension.rs | 6 +- .../webgpu_sys/gen_GpuUncapturedErrorEvent.rs | 10 +- .../gen_GpuUncapturedErrorEventInit.rs | 24 ++-- .../webgpu_sys/gen_GpuValidationError.rs | 8 +- .../webgpu_sys/gen_GpuVertexAttribute.rs | 20 +-- .../webgpu_sys/gen_GpuVertexBufferLayout.rs | 20 +-- .../webgpu/webgpu_sys/gen_GpuVertexFormat.rs | 6 +- .../webgpu/webgpu_sys/gen_GpuVertexState.rs | 24 ++-- .../webgpu_sys/gen_GpuVertexStepMode.rs | 6 +- .../webgpu_sys/gen_WgslLanguageFeatures.rs | 18 +-- .../webgpu/webgpu_sys/gen_gpu_map_mode.rs | 10 +- wgpu/src/backend/webgpu/webgpu_sys/mod.rs | 4 +- 128 files changed, 1247 insertions(+), 1247 deletions(-) diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_Gpu.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_Gpu.rs index 32f5bec31f1..3a70b0c2f6f 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_Gpu.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_Gpu.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `Gpu`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type Gpu; # [wasm_bindgen (structural , method , getter , js_class = "GPU" , js_name = wgslLanguageFeatures)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `Gpu`, `WgslLanguageFeatures`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn wgsl_language_features(this: &Gpu) -> WgslLanguageFeatures; # [wasm_bindgen (method , structural , js_class = "GPU" , js_name = getPreferredCanvasFormat)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `Gpu`, `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn get_preferred_canvas_format(this: &Gpu) -> GpuTextureFormat; # [wasm_bindgen (method , structural , js_class = "GPU" , js_name = requestAdapter)] @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `Gpu`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn request_adapter(this: &Gpu) -> ::js_sys::Promise; # [wasm_bindgen (method , structural , js_class = "GPU" , js_name = requestAdapter)] @@ -79,7 +79,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `Gpu`, `GpuRequestAdapterOptions`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn request_adapter_with_options( this: &Gpu, options: &GpuRequestAdapterOptions, diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuAdapter.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuAdapter.rs index 855a76bfdf3..c1bc6d46164 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuAdapter.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuAdapter.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuAdapter`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuAdapter; # [wasm_bindgen (structural , method , getter , js_class = "GPUAdapter" , js_name = features)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuAdapter`, `GpuSupportedFeatures`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn features(this: &GpuAdapter) -> GpuSupportedFeatures; # [wasm_bindgen (structural , method , getter , js_class = "GPUAdapter" , js_name = limits)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuAdapter`, `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn limits(this: &GpuAdapter) -> GpuSupportedLimits; # [wasm_bindgen (structural , method , getter , js_class = "GPUAdapter" , js_name = info)] @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuAdapter`, `GpuAdapterInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn info(this: &GpuAdapter) -> GpuAdapterInfo; # [wasm_bindgen (structural , method , getter , js_class = "GPUAdapter" , js_name = isFallbackAdapter)] @@ -79,7 +79,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuAdapter`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn is_fallback_adapter(this: &GpuAdapter) -> bool; # [wasm_bindgen (method , structural , js_class = "GPUAdapter" , js_name = requestDevice)] @@ -90,7 +90,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuAdapter`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn request_device(this: &GpuAdapter) -> ::js_sys::Promise; # [wasm_bindgen (method , structural , js_class = "GPUAdapter" , js_name = requestDevice)] @@ -101,7 +101,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuAdapter`, `GpuDeviceDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn request_device_with_descriptor( this: &GpuAdapter, descriptor: &GpuDeviceDescriptor, diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuAdapterInfo.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuAdapterInfo.rs index 06c251f1810..c99000fdaf6 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuAdapterInfo.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuAdapterInfo.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuAdapterInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuAdapterInfo; # [wasm_bindgen (structural , method , getter , js_class = "GPUAdapterInfo" , js_name = vendor)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuAdapterInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn vendor(this: &GpuAdapterInfo) -> ::alloc::string::String; # [wasm_bindgen (structural , method , getter , js_class = "GPUAdapterInfo" , js_name = architecture)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuAdapterInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn architecture(this: &GpuAdapterInfo) -> ::alloc::string::String; # [wasm_bindgen (structural , method , getter , js_class = "GPUAdapterInfo" , js_name = device)] @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuAdapterInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn device(this: &GpuAdapterInfo) -> ::alloc::string::String; # [wasm_bindgen (structural , method , getter , js_class = "GPUAdapterInfo" , js_name = description)] @@ -79,6 +79,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuAdapterInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn description(this: &GpuAdapterInfo) -> ::alloc::string::String; } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuAddressMode.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuAddressMode.rs index 2718d15ff51..11e70cff270 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuAddressMode.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuAddressMode.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuAddressMode`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuAddressMode { ClampToEdge = "clamp-to-edge", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuAutoLayoutMode.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuAutoLayoutMode.rs index 2bd43bc2de0..62d94465a68 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuAutoLayoutMode.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuAutoLayoutMode.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuAutoLayoutMode`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuAutoLayoutMode { Auto = "auto", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroup.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroup.rs index 02f61eafe8c..c056487adf8 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroup.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroup.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuBindGroup; # [wasm_bindgen (structural , method , getter , js_class = "GPUBindGroup" , js_name = label)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuBindGroup) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPUBindGroup" , js_name = label)] @@ -57,6 +57,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuBindGroup, value: &str); } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupDescriptor.rs index 691add6fc35..3c58c1c202f 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuBindGroupDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuBindGroupDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuBindGroupDescriptor, val: &str); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "entries")] pub fn get_entries(this: &GpuBindGroupDescriptor) -> ::js_sys::Array; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "entries")] pub fn set_entries(this: &GpuBindGroupDescriptor, val: &::wasm_bindgen::JsValue); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupDescriptor`, `GpuBindGroupLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "layout")] pub fn get_layout(this: &GpuBindGroupDescriptor) -> GpuBindGroupLayout; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupDescriptor`, `GpuBindGroupLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "layout")] pub fn set_layout(this: &GpuBindGroupDescriptor, val: &GpuBindGroupLayout); } @@ -97,7 +97,7 @@ impl GpuBindGroupDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupDescriptor`, `GpuBindGroupLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(entries: &::wasm_bindgen::JsValue, layout: &GpuBindGroupLayout) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupEntry.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupEntry.rs index c51e223a7cf..266fd1cbfde 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupEntry.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupEntry.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupEntry`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuBindGroupEntry; #[doc = "Get the `binding` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupEntry`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "binding")] pub fn get_binding(this: &GpuBindGroupEntry) -> u32; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupEntry`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "binding")] pub fn set_binding(this: &GpuBindGroupEntry, val: u32); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupEntry`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "resource")] pub fn get_resource(this: &GpuBindGroupEntry) -> ::wasm_bindgen::JsValue; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupEntry`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "resource")] pub fn set_resource(this: &GpuBindGroupEntry, val: &::wasm_bindgen::JsValue); } @@ -79,7 +79,7 @@ impl GpuBindGroupEntry { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupEntry`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(binding: u32, resource: &::wasm_bindgen::JsValue) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupLayout.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupLayout.rs index 4bade8fcd89..7c500ea0ffc 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupLayout.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupLayout.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuBindGroupLayout; # [wasm_bindgen (structural , method , getter , js_class = "GPUBindGroupLayout" , js_name = label)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuBindGroupLayout) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPUBindGroupLayout" , js_name = label)] @@ -57,6 +57,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuBindGroupLayout, value: &str); } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupLayoutDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupLayoutDescriptor.rs index 0bafe646339..5e11b9f8f24 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupLayoutDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupLayoutDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuBindGroupLayoutDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuBindGroupLayoutDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuBindGroupLayoutDescriptor, val: &str); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "entries")] pub fn get_entries(this: &GpuBindGroupLayoutDescriptor) -> ::js_sys::Array; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "entries")] pub fn set_entries(this: &GpuBindGroupLayoutDescriptor, val: &::wasm_bindgen::JsValue); } @@ -79,7 +79,7 @@ impl GpuBindGroupLayoutDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(entries: &::wasm_bindgen::JsValue) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupLayoutEntry.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupLayoutEntry.rs index 0a5f916d2b5..d641712e3e9 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupLayoutEntry.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBindGroupLayoutEntry.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutEntry`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuBindGroupLayoutEntry; #[doc = "Get the `binding` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutEntry`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "binding")] pub fn get_binding(this: &GpuBindGroupLayoutEntry) -> u32; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutEntry`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "binding")] pub fn set_binding(this: &GpuBindGroupLayoutEntry, val: u32); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutEntry`, `GpuBufferBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "buffer")] pub fn get_buffer(this: &GpuBindGroupLayoutEntry) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutEntry`, `GpuBufferBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "buffer")] pub fn set_buffer(this: &GpuBindGroupLayoutEntry, val: &GpuBufferBindingLayout); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutEntry`, `GpuExternalTextureBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "externalTexture")] pub fn get_external_texture( this: &GpuBindGroupLayoutEntry, @@ -88,7 +88,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutEntry`, `GpuExternalTextureBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "externalTexture")] pub fn set_external_texture( this: &GpuBindGroupLayoutEntry, @@ -100,7 +100,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutEntry`, `GpuSamplerBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "sampler")] pub fn get_sampler(this: &GpuBindGroupLayoutEntry) -> Option; @@ -109,7 +109,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutEntry`, `GpuSamplerBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "sampler")] pub fn set_sampler(this: &GpuBindGroupLayoutEntry, val: &GpuSamplerBindingLayout); @@ -118,7 +118,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutEntry`, `GpuStorageTextureBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "storageTexture")] pub fn get_storage_texture( this: &GpuBindGroupLayoutEntry, @@ -129,7 +129,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutEntry`, `GpuStorageTextureBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "storageTexture")] pub fn set_storage_texture( this: &GpuBindGroupLayoutEntry, @@ -141,7 +141,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutEntry`, `GpuTextureBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "texture")] pub fn get_texture(this: &GpuBindGroupLayoutEntry) -> Option; @@ -150,7 +150,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutEntry`, `GpuTextureBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "texture")] pub fn set_texture(this: &GpuBindGroupLayoutEntry, val: &GpuTextureBindingLayout); @@ -159,7 +159,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutEntry`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "visibility")] pub fn get_visibility(this: &GpuBindGroupLayoutEntry) -> u32; @@ -168,7 +168,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutEntry`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "visibility")] pub fn set_visibility(this: &GpuBindGroupLayoutEntry, val: u32); } @@ -179,7 +179,7 @@ impl GpuBindGroupLayoutEntry { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayoutEntry`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(binding: u32, visibility: u32) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBlendComponent.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBlendComponent.rs index 9c3c8403bd8..0f11495e371 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBlendComponent.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBlendComponent.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBlendComponent`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuBlendComponent; #[doc = "Get the `dstFactor` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBlendComponent`, `GpuBlendFactor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "dstFactor")] pub fn get_dst_factor(this: &GpuBlendComponent) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBlendComponent`, `GpuBlendFactor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "dstFactor")] pub fn set_dst_factor(this: &GpuBlendComponent, val: GpuBlendFactor); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBlendComponent`, `GpuBlendOperation`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "operation")] pub fn get_operation(this: &GpuBlendComponent) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBlendComponent`, `GpuBlendOperation`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "operation")] pub fn set_operation(this: &GpuBlendComponent, val: GpuBlendOperation); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBlendComponent`, `GpuBlendFactor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "srcFactor")] pub fn get_src_factor(this: &GpuBlendComponent) -> Option; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBlendComponent`, `GpuBlendFactor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "srcFactor")] pub fn set_src_factor(this: &GpuBlendComponent, val: GpuBlendFactor); } @@ -97,7 +97,7 @@ impl GpuBlendComponent { #[doc = "*This API requires the following crate features to be activated: `GpuBlendComponent`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBlendFactor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBlendFactor.rs index d8ea45d598b..0b1f7c3913f 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBlendFactor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBlendFactor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuBlendFactor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuBlendFactor { Zero = "zero", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBlendOperation.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBlendOperation.rs index 3d054b6afc1..13da1a1b7e1 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBlendOperation.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBlendOperation.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuBlendOperation`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuBlendOperation { Add = "add", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBlendState.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBlendState.rs index 5d01cc05f1b..8c54586f34d 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBlendState.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBlendState.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBlendState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuBlendState; #[doc = "Get the `alpha` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBlendComponent`, `GpuBlendState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "alpha")] pub fn get_alpha(this: &GpuBlendState) -> GpuBlendComponent; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBlendComponent`, `GpuBlendState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "alpha")] pub fn set_alpha(this: &GpuBlendState, val: &GpuBlendComponent); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBlendComponent`, `GpuBlendState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "color")] pub fn get_color(this: &GpuBlendState) -> GpuBlendComponent; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBlendComponent`, `GpuBlendState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "color")] pub fn set_color(this: &GpuBlendState, val: &GpuBlendComponent); } @@ -79,7 +79,7 @@ impl GpuBlendState { #[doc = "*This API requires the following crate features to be activated: `GpuBlendComponent`, `GpuBlendState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(alpha: &GpuBlendComponent, color: &GpuBlendComponent) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBuffer.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBuffer.rs index 1f161a2b79a..05f60aa54eb 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBuffer.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBuffer.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuBuffer; # [wasm_bindgen (structural , method , getter , js_class = "GPUBuffer" , js_name = size)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn size(this: &GpuBuffer) -> f64; # [wasm_bindgen (structural , method , getter , js_class = "GPUBuffer" , js_name = usage)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn usage(this: &GpuBuffer) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUBuffer" , js_name = mapState)] @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuBufferMapState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn map_state(this: &GpuBuffer) -> GpuBufferMapState; # [wasm_bindgen (structural , method , getter , js_class = "GPUBuffer" , js_name = label)] @@ -79,7 +79,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuBuffer) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPUBuffer" , js_name = label)] @@ -90,7 +90,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuBuffer, value: &str); # [wasm_bindgen (method , structural , js_class = "GPUBuffer" , js_name = destroy)] @@ -101,7 +101,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn destroy(this: &GpuBuffer); # [wasm_bindgen (catch , method , structural , js_class = "GPUBuffer" , js_name = getMappedRange)] @@ -112,7 +112,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn get_mapped_range(this: &GpuBuffer) -> Result<::js_sys::ArrayBuffer, JsValue>; # [wasm_bindgen (catch , method , structural , js_class = "GPUBuffer" , js_name = getMappedRange)] @@ -123,7 +123,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn get_mapped_range_with_u32( this: &GpuBuffer, offset: u32, @@ -137,7 +137,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn get_mapped_range_with_f64( this: &GpuBuffer, offset: f64, @@ -151,7 +151,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn get_mapped_range_with_u32_and_u32( this: &GpuBuffer, offset: u32, @@ -166,7 +166,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn get_mapped_range_with_f64_and_u32( this: &GpuBuffer, offset: f64, @@ -181,7 +181,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn get_mapped_range_with_u32_and_f64( this: &GpuBuffer, offset: u32, @@ -196,7 +196,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn get_mapped_range_with_f64_and_f64( this: &GpuBuffer, offset: f64, @@ -211,7 +211,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn map_async(this: &GpuBuffer, mode: u32) -> ::js_sys::Promise; # [wasm_bindgen (method , structural , js_class = "GPUBuffer" , js_name = mapAsync)] @@ -222,7 +222,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn map_async_with_u32(this: &GpuBuffer, mode: u32, offset: u32) -> ::js_sys::Promise; # [wasm_bindgen (method , structural , js_class = "GPUBuffer" , js_name = mapAsync)] @@ -233,7 +233,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn map_async_with_f64(this: &GpuBuffer, mode: u32, offset: f64) -> ::js_sys::Promise; # [wasm_bindgen (method , structural , js_class = "GPUBuffer" , js_name = mapAsync)] @@ -244,7 +244,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn map_async_with_u32_and_u32( this: &GpuBuffer, mode: u32, @@ -260,7 +260,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn map_async_with_f64_and_u32( this: &GpuBuffer, mode: u32, @@ -276,7 +276,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn map_async_with_u32_and_f64( this: &GpuBuffer, mode: u32, @@ -292,7 +292,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn map_async_with_f64_and_f64( this: &GpuBuffer, mode: u32, @@ -308,6 +308,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn unmap(this: &GpuBuffer); } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferBinding.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferBinding.rs index 95d81a228a9..5174557c60b 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferBinding.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferBinding.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferBinding`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuBufferBinding; #[doc = "Get the `buffer` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuBufferBinding`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "buffer")] pub fn get_buffer(this: &GpuBufferBinding) -> GpuBuffer; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuBufferBinding`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "buffer")] pub fn set_buffer(this: &GpuBufferBinding, val: &GpuBuffer); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferBinding`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "offset")] pub fn get_offset(this: &GpuBufferBinding) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferBinding`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "offset")] pub fn set_offset(this: &GpuBufferBinding, val: f64); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferBinding`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "size")] pub fn get_size(this: &GpuBufferBinding) -> Option; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferBinding`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "size")] pub fn set_size(this: &GpuBufferBinding, val: f64); } @@ -97,7 +97,7 @@ impl GpuBufferBinding { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuBufferBinding`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(buffer: &GpuBuffer) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferBindingLayout.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferBindingLayout.rs index 137291f0c64..311d42bc116 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferBindingLayout.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferBindingLayout.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuBufferBindingLayout; #[doc = "Get the `hasDynamicOffset` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "hasDynamicOffset")] pub fn get_has_dynamic_offset(this: &GpuBufferBindingLayout) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "hasDynamicOffset")] pub fn set_has_dynamic_offset(this: &GpuBufferBindingLayout, val: bool); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "minBindingSize")] pub fn get_min_binding_size(this: &GpuBufferBindingLayout) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "minBindingSize")] pub fn set_min_binding_size(this: &GpuBufferBindingLayout, val: f64); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferBindingLayout`, `GpuBufferBindingType`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "type")] pub fn get_type(this: &GpuBufferBindingLayout) -> Option; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferBindingLayout`, `GpuBufferBindingType`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "type")] pub fn set_type(this: &GpuBufferBindingLayout, val: GpuBufferBindingType); } @@ -97,7 +97,7 @@ impl GpuBufferBindingLayout { #[doc = "*This API requires the following crate features to be activated: `GpuBufferBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferBindingType.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferBindingType.rs index 24ded9e6339..7b1a6478d69 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferBindingType.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferBindingType.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuBufferBindingType`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuBufferBindingType { Uniform = "uniform", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferDescriptor.rs index f55a66bd299..0303470cf46 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuBufferDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuBufferDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuBufferDescriptor, val: &str); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "mappedAtCreation")] pub fn get_mapped_at_creation(this: &GpuBufferDescriptor) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "mappedAtCreation")] pub fn set_mapped_at_creation(this: &GpuBufferDescriptor, val: bool); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "size")] pub fn get_size(this: &GpuBufferDescriptor) -> f64; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "size")] pub fn set_size(this: &GpuBufferDescriptor, val: f64); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "usage")] pub fn get_usage(this: &GpuBufferDescriptor) -> u32; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBufferDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "usage")] pub fn set_usage(this: &GpuBufferDescriptor, val: u32); } @@ -115,7 +115,7 @@ impl GpuBufferDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuBufferDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(size: f64, usage: u32) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferMapState.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferMapState.rs index 95f5094a592..c44b6ec4501 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferMapState.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuBufferMapState.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuBufferMapState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuBufferMapState { Unmapped = "unmapped", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasAlphaMode.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasAlphaMode.rs index 9cf7d07b691..0ec4ac45feb 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasAlphaMode.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasAlphaMode.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuCanvasAlphaMode`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuCanvasAlphaMode { Opaque = "opaque", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasConfiguration.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasConfiguration.rs index 76c169a86de..469376affc2 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasConfiguration.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasConfiguration.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasConfiguration`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuCanvasConfiguration; #[doc = "Get the `alphaMode` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasAlphaMode`, `GpuCanvasConfiguration`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "alphaMode")] pub fn get_alpha_mode(this: &GpuCanvasConfiguration) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasAlphaMode`, `GpuCanvasConfiguration`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "alphaMode")] pub fn set_alpha_mode(this: &GpuCanvasConfiguration, val: GpuCanvasAlphaMode); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasConfiguration`, `GpuDevice`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "device")] pub fn get_device(this: &GpuCanvasConfiguration) -> GpuDevice; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasConfiguration`, `GpuDevice`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "device")] pub fn set_device(this: &GpuCanvasConfiguration, val: &GpuDevice); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasConfiguration`, `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "format")] pub fn get_format(this: &GpuCanvasConfiguration) -> GpuTextureFormat; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasConfiguration`, `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "format")] pub fn set_format(this: &GpuCanvasConfiguration, val: GpuTextureFormat); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasConfiguration`, `GpuCanvasToneMapping`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "toneMapping")] pub fn get_tone_mapping(this: &GpuCanvasConfiguration) -> Option; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasConfiguration`, `GpuCanvasToneMapping`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "toneMapping")] pub fn set_tone_mapping(this: &GpuCanvasConfiguration, val: &GpuCanvasToneMapping); @@ -113,7 +113,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasConfiguration`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "usage")] pub fn get_usage(this: &GpuCanvasConfiguration) -> Option; @@ -122,7 +122,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasConfiguration`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "usage")] pub fn set_usage(this: &GpuCanvasConfiguration, val: u32); @@ -131,7 +131,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasConfiguration`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "viewFormats")] pub fn get_view_formats(this: &GpuCanvasConfiguration) -> Option<::js_sys::Array>; @@ -140,7 +140,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasConfiguration`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "viewFormats")] pub fn set_view_formats(this: &GpuCanvasConfiguration, val: &::wasm_bindgen::JsValue); } @@ -151,7 +151,7 @@ impl GpuCanvasConfiguration { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasConfiguration`, `GpuDevice`, `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(device: &GpuDevice, format: GpuTextureFormat) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasContext.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasContext.rs index 843adba3180..5504b3bdf52 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasContext.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasContext.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasContext`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuCanvasContext; # [wasm_bindgen (structural , method , getter , js_class = "GPUCanvasContext" , js_name = canvas)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasContext`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn canvas(this: &GpuCanvasContext) -> ::js_sys::Object; # [wasm_bindgen (catch , method , structural , js_class = "GPUCanvasContext" , js_name = configure)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasConfiguration`, `GpuCanvasContext`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn configure( this: &GpuCanvasContext, configuration: &GpuCanvasConfiguration, @@ -71,7 +71,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasConfiguration`, `GpuCanvasContext`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn get_configuration(this: &GpuCanvasContext) -> Option; # [wasm_bindgen (catch , method , structural , js_class = "GPUCanvasContext" , js_name = getCurrentTexture)] @@ -82,7 +82,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasContext`, `GpuTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn get_current_texture(this: &GpuCanvasContext) -> Result; # [wasm_bindgen (method , structural , js_class = "GPUCanvasContext" , js_name = unconfigure)] @@ -93,6 +93,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasContext`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn unconfigure(this: &GpuCanvasContext); } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasToneMapping.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasToneMapping.rs index ebd0a84539f..8b528f73e18 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasToneMapping.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasToneMapping.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasToneMapping`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuCanvasToneMapping; #[doc = "Get the `mode` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasToneMapping`, `GpuCanvasToneMappingMode`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "mode")] pub fn get_mode(this: &GpuCanvasToneMapping) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasToneMapping`, `GpuCanvasToneMappingMode`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "mode")] pub fn set_mode(this: &GpuCanvasToneMapping, val: GpuCanvasToneMappingMode); } @@ -61,7 +61,7 @@ impl GpuCanvasToneMapping { #[doc = "*This API requires the following crate features to be activated: `GpuCanvasToneMapping`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasToneMappingMode.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasToneMappingMode.rs index 51d4c14c93f..e601a631eb4 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasToneMappingMode.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCanvasToneMappingMode.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuCanvasToneMappingMode`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuCanvasToneMappingMode { Standard = "standard", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuColorDict.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuColorDict.rs index 7ce76510666..eb02d96132b 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuColorDict.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuColorDict.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuColorDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuColorDict; #[doc = "Get the `a` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuColorDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "a")] pub fn get_a(this: &GpuColorDict) -> f64; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuColorDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "a")] pub fn set_a(this: &GpuColorDict, val: f64); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuColorDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "b")] pub fn get_b(this: &GpuColorDict) -> f64; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuColorDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "b")] pub fn set_b(this: &GpuColorDict, val: f64); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuColorDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "g")] pub fn get_g(this: &GpuColorDict) -> f64; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuColorDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "g")] pub fn set_g(this: &GpuColorDict, val: f64); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuColorDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "r")] pub fn get_r(this: &GpuColorDict) -> f64; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuColorDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "r")] pub fn set_r(this: &GpuColorDict, val: f64); } @@ -115,7 +115,7 @@ impl GpuColorDict { #[doc = "*This API requires the following crate features to be activated: `GpuColorDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(a: f64, b: f64, g: f64, r: f64) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuColorTargetState.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuColorTargetState.rs index 8f784505ce2..4f92ba301a7 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuColorTargetState.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuColorTargetState.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuColorTargetState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuColorTargetState; #[doc = "Get the `blend` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBlendState`, `GpuColorTargetState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "blend")] pub fn get_blend(this: &GpuColorTargetState) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBlendState`, `GpuColorTargetState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "blend")] pub fn set_blend(this: &GpuColorTargetState, val: &GpuBlendState); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuColorTargetState`, `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "format")] pub fn get_format(this: &GpuColorTargetState) -> GpuTextureFormat; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuColorTargetState`, `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "format")] pub fn set_format(this: &GpuColorTargetState, val: GpuTextureFormat); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuColorTargetState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "writeMask")] pub fn get_write_mask(this: &GpuColorTargetState) -> Option; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuColorTargetState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "writeMask")] pub fn set_write_mask(this: &GpuColorTargetState, val: u32); } @@ -97,7 +97,7 @@ impl GpuColorTargetState { #[doc = "*This API requires the following crate features to be activated: `GpuColorTargetState`, `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(format: GpuTextureFormat) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCommandBuffer.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCommandBuffer.rs index cf78b2e3cef..44e47a236e5 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCommandBuffer.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCommandBuffer.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuCommandBuffer; # [wasm_bindgen (structural , method , getter , js_class = "GPUCommandBuffer" , js_name = label)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuCommandBuffer) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPUCommandBuffer" , js_name = label)] @@ -57,6 +57,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandBuffer`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuCommandBuffer, value: &str); } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCommandBufferDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCommandBufferDescriptor.rs index d22076cf389..c571b408285 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCommandBufferDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCommandBufferDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandBufferDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuCommandBufferDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandBufferDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuCommandBufferDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandBufferDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuCommandBufferDescriptor, val: &str); } @@ -61,7 +61,7 @@ impl GpuCommandBufferDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuCommandBufferDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCommandEncoder.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCommandEncoder.rs index b5bc2cd1fd8..2116f8a1aad 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCommandEncoder.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCommandEncoder.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuCommandEncoder; # [wasm_bindgen (structural , method , getter , js_class = "GPUCommandEncoder" , js_name = label)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuCommandEncoder) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPUCommandEncoder" , js_name = label)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuCommandEncoder, value: &str); # [wasm_bindgen (method , structural , js_class = "GPUCommandEncoder" , js_name = beginComputePass)] @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoder`, `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn begin_compute_pass(this: &GpuCommandEncoder) -> GpuComputePassEncoder; # [wasm_bindgen (method , structural , js_class = "GPUCommandEncoder" , js_name = beginComputePass)] @@ -79,7 +79,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoder`, `GpuComputePassDescriptor`, `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn begin_compute_pass_with_descriptor( this: &GpuCommandEncoder, descriptor: &GpuComputePassDescriptor, @@ -93,7 +93,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoder`, `GpuRenderPassDescriptor`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn begin_render_pass( this: &GpuCommandEncoder, descriptor: &GpuRenderPassDescriptor, @@ -107,7 +107,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn clear_buffer(this: &GpuCommandEncoder, buffer: &GpuBuffer); # [wasm_bindgen (method , structural , js_class = "GPUCommandEncoder" , js_name = clearBuffer)] @@ -118,7 +118,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn clear_buffer_with_u32(this: &GpuCommandEncoder, buffer: &GpuBuffer, offset: u32); # [wasm_bindgen (method , structural , js_class = "GPUCommandEncoder" , js_name = clearBuffer)] @@ -129,7 +129,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn clear_buffer_with_f64(this: &GpuCommandEncoder, buffer: &GpuBuffer, offset: f64); # [wasm_bindgen (method , structural , js_class = "GPUCommandEncoder" , js_name = clearBuffer)] @@ -140,7 +140,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn clear_buffer_with_u32_and_u32( this: &GpuCommandEncoder, buffer: &GpuBuffer, @@ -156,7 +156,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn clear_buffer_with_f64_and_u32( this: &GpuCommandEncoder, buffer: &GpuBuffer, @@ -172,7 +172,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn clear_buffer_with_u32_and_f64( this: &GpuCommandEncoder, buffer: &GpuBuffer, @@ -188,7 +188,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn clear_buffer_with_f64_and_f64( this: &GpuCommandEncoder, buffer: &GpuBuffer, @@ -204,7 +204,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_buffer_to_buffer_with_u32_and_u32( this: &GpuCommandEncoder, source: &GpuBuffer, @@ -221,7 +221,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_buffer_to_buffer_with_f64_and_u32( this: &GpuCommandEncoder, source: &GpuBuffer, @@ -238,7 +238,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_buffer_to_buffer_with_u32_and_f64( this: &GpuCommandEncoder, source: &GpuBuffer, @@ -255,7 +255,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_buffer_to_buffer_with_f64_and_f64( this: &GpuCommandEncoder, source: &GpuBuffer, @@ -272,7 +272,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_buffer_to_buffer_with_u32_and_u32_and_u32( this: &GpuCommandEncoder, source: &GpuBuffer, @@ -290,7 +290,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_buffer_to_buffer_with_f64_and_u32_and_u32( this: &GpuCommandEncoder, source: &GpuBuffer, @@ -308,7 +308,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_buffer_to_buffer_with_u32_and_f64_and_u32( this: &GpuCommandEncoder, source: &GpuBuffer, @@ -326,7 +326,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_buffer_to_buffer_with_f64_and_f64_and_u32( this: &GpuCommandEncoder, source: &GpuBuffer, @@ -344,7 +344,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_buffer_to_buffer_with_u32_and_u32_and_f64( this: &GpuCommandEncoder, source: &GpuBuffer, @@ -362,7 +362,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_buffer_to_buffer_with_f64_and_u32_and_f64( this: &GpuCommandEncoder, source: &GpuBuffer, @@ -380,7 +380,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_buffer_to_buffer_with_u32_and_f64_and_f64( this: &GpuCommandEncoder, source: &GpuBuffer, @@ -398,7 +398,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_buffer_to_buffer_with_f64_and_f64_and_f64( this: &GpuCommandEncoder, source: &GpuBuffer, @@ -416,7 +416,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoder`, `GpuTexelCopyBufferInfo`, `GpuTexelCopyTextureInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_buffer_to_texture_with_u32_sequence( this: &GpuCommandEncoder, source: &GpuTexelCopyBufferInfo, @@ -432,7 +432,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoder`, `GpuExtent3dDict`, `GpuTexelCopyBufferInfo`, `GpuTexelCopyTextureInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_buffer_to_texture_with_gpu_extent_3d_dict( this: &GpuCommandEncoder, source: &GpuTexelCopyBufferInfo, @@ -448,7 +448,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoder`, `GpuTexelCopyBufferInfo`, `GpuTexelCopyTextureInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_texture_to_buffer_with_u32_sequence( this: &GpuCommandEncoder, source: &GpuTexelCopyTextureInfo, @@ -464,7 +464,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoder`, `GpuExtent3dDict`, `GpuTexelCopyBufferInfo`, `GpuTexelCopyTextureInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_texture_to_buffer_with_gpu_extent_3d_dict( this: &GpuCommandEncoder, source: &GpuTexelCopyTextureInfo, @@ -480,7 +480,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoder`, `GpuTexelCopyTextureInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_texture_to_texture_with_u32_sequence( this: &GpuCommandEncoder, source: &GpuTexelCopyTextureInfo, @@ -496,7 +496,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoder`, `GpuExtent3dDict`, `GpuTexelCopyTextureInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_texture_to_texture_with_gpu_extent_3d_dict( this: &GpuCommandEncoder, source: &GpuTexelCopyTextureInfo, @@ -512,7 +512,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandBuffer`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn finish(this: &GpuCommandEncoder) -> GpuCommandBuffer; # [wasm_bindgen (method , structural , js_class = "GPUCommandEncoder" , js_name = finish)] @@ -523,7 +523,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandBuffer`, `GpuCommandBufferDescriptor`, `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn finish_with_descriptor( this: &GpuCommandEncoder, descriptor: &GpuCommandBufferDescriptor, @@ -537,7 +537,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`, `GpuQuerySet`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn resolve_query_set_with_u32( this: &GpuCommandEncoder, query_set: &GpuQuerySet, @@ -555,7 +555,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuCommandEncoder`, `GpuQuerySet`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn resolve_query_set_with_f64( this: &GpuCommandEncoder, query_set: &GpuQuerySet, @@ -573,7 +573,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn insert_debug_marker(this: &GpuCommandEncoder, marker_label: &str); # [wasm_bindgen (method , structural , js_class = "GPUCommandEncoder" , js_name = popDebugGroup)] @@ -584,7 +584,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn pop_debug_group(this: &GpuCommandEncoder); # [wasm_bindgen (method , structural , js_class = "GPUCommandEncoder" , js_name = pushDebugGroup)] @@ -595,6 +595,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn push_debug_group(this: &GpuCommandEncoder, group_label: &str); } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCommandEncoderDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCommandEncoderDescriptor.rs index 62121b205f7..64d08c43d7d 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCommandEncoderDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCommandEncoderDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoderDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuCommandEncoderDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoderDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuCommandEncoderDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoderDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuCommandEncoderDescriptor, val: &str); } @@ -61,7 +61,7 @@ impl GpuCommandEncoderDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoderDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCompareFunction.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCompareFunction.rs index e07496f03b8..bd7008fe204 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCompareFunction.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCompareFunction.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuCompareFunction`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuCompareFunction { Never = "never", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCompilationInfo.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCompilationInfo.rs index 91617424e2f..029797d148a 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCompilationInfo.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCompilationInfo.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCompilationInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuCompilationInfo; # [wasm_bindgen (structural , method , getter , js_class = "GPUCompilationInfo" , js_name = messages)] @@ -46,6 +46,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCompilationInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn messages(this: &GpuCompilationInfo) -> ::js_sys::Array; } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCompilationMessage.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCompilationMessage.rs index bbf2422aca4..927af739107 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCompilationMessage.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCompilationMessage.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCompilationMessage`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuCompilationMessage; # [wasm_bindgen (structural , method , getter , js_class = "GPUCompilationMessage" , js_name = message)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCompilationMessage`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn message(this: &GpuCompilationMessage) -> ::alloc::string::String; # [wasm_bindgen (structural , method , getter , js_class = "GPUCompilationMessage" , js_name = type)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCompilationMessage`, `GpuCompilationMessageType`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn type_(this: &GpuCompilationMessage) -> GpuCompilationMessageType; # [wasm_bindgen (structural , method , getter , js_class = "GPUCompilationMessage" , js_name = lineNum)] @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCompilationMessage`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn line_num(this: &GpuCompilationMessage) -> f64; # [wasm_bindgen (structural , method , getter , js_class = "GPUCompilationMessage" , js_name = linePos)] @@ -79,7 +79,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCompilationMessage`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn line_pos(this: &GpuCompilationMessage) -> f64; # [wasm_bindgen (structural , method , getter , js_class = "GPUCompilationMessage" , js_name = offset)] @@ -90,7 +90,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCompilationMessage`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn offset(this: &GpuCompilationMessage) -> f64; # [wasm_bindgen (structural , method , getter , js_class = "GPUCompilationMessage" , js_name = length)] @@ -101,6 +101,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCompilationMessage`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn length(this: &GpuCompilationMessage) -> f64; } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCompilationMessageType.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCompilationMessageType.rs index c2f0629f88a..6b98eb784dc 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCompilationMessageType.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCompilationMessageType.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuCompilationMessageType`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuCompilationMessageType { Error = "error", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePassDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePassDescriptor.rs index 9de91497888..593a06f4488 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePassDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePassDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuComputePassDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuComputePassDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuComputePassDescriptor, val: &str); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassDescriptor`, `GpuComputePassTimestampWrites`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "timestampWrites")] pub fn get_timestamp_writes( this: &GpuComputePassDescriptor, @@ -70,7 +70,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassDescriptor`, `GpuComputePassTimestampWrites`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "timestampWrites")] pub fn set_timestamp_writes( this: &GpuComputePassDescriptor, @@ -84,7 +84,7 @@ impl GpuComputePassDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePassEncoder.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePassEncoder.rs index 8a2831b3d9c..1e57894e2d5 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePassEncoder.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePassEncoder.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuComputePassEncoder; # [wasm_bindgen (structural , method , getter , js_class = "GPUComputePassEncoder" , js_name = label)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuComputePassEncoder) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPUComputePassEncoder" , js_name = label)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuComputePassEncoder, value: &str); # [wasm_bindgen (method , structural , js_class = "GPUComputePassEncoder" , js_name = dispatchWorkgroups)] @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn dispatch_workgroups(this: &GpuComputePassEncoder, workgroup_count_x: u32); # [wasm_bindgen (method , structural , js_class = "GPUComputePassEncoder" , js_name = dispatchWorkgroups)] @@ -79,7 +79,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn dispatch_workgroups_with_workgroup_count_y( this: &GpuComputePassEncoder, workgroup_count_x: u32, @@ -94,7 +94,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn dispatch_workgroups_with_workgroup_count_y_and_workgroup_count_z( this: &GpuComputePassEncoder, workgroup_count_x: u32, @@ -110,7 +110,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn dispatch_workgroups_indirect_with_u32( this: &GpuComputePassEncoder, indirect_buffer: &GpuBuffer, @@ -125,7 +125,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn dispatch_workgroups_indirect_with_f64( this: &GpuComputePassEncoder, indirect_buffer: &GpuBuffer, @@ -140,7 +140,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn end(this: &GpuComputePassEncoder); # [wasm_bindgen (method , structural , js_class = "GPUComputePassEncoder" , js_name = setPipeline)] @@ -151,7 +151,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassEncoder`, `GpuComputePipeline`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_pipeline(this: &GpuComputePassEncoder, pipeline: &GpuComputePipeline); # [wasm_bindgen (method , structural , js_class = "GPUComputePassEncoder" , js_name = setBindGroup)] @@ -162,7 +162,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`, `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_bind_group( this: &GpuComputePassEncoder, index: u32, @@ -177,7 +177,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`, `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_bind_group_with_u32_sequence( this: &GpuComputePassEncoder, index: u32, @@ -193,7 +193,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`, `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_bind_group_with_u32_slice_and_u32_and_dynamic_offsets_data_length( this: &GpuComputePassEncoder, index: u32, @@ -211,7 +211,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`, `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_bind_group_with_u32_array_and_u32_and_dynamic_offsets_data_length( this: &GpuComputePassEncoder, index: u32, @@ -229,7 +229,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`, `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_bind_group_with_u32_slice_and_f64_and_dynamic_offsets_data_length( this: &GpuComputePassEncoder, index: u32, @@ -247,7 +247,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`, `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_bind_group_with_u32_array_and_f64_and_dynamic_offsets_data_length( this: &GpuComputePassEncoder, index: u32, @@ -265,7 +265,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn insert_debug_marker(this: &GpuComputePassEncoder, marker_label: &str); # [wasm_bindgen (method , structural , js_class = "GPUComputePassEncoder" , js_name = popDebugGroup)] @@ -276,7 +276,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn pop_debug_group(this: &GpuComputePassEncoder); # [wasm_bindgen (method , structural , js_class = "GPUComputePassEncoder" , js_name = pushDebugGroup)] @@ -287,6 +287,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn push_debug_group(this: &GpuComputePassEncoder, group_label: &str); } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePassTimestampWrites.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePassTimestampWrites.rs index 6d8fa439c11..7d91fd2abe5 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePassTimestampWrites.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePassTimestampWrites.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassTimestampWrites`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuComputePassTimestampWrites; #[doc = "Get the `beginningOfPassWriteIndex` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassTimestampWrites`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "beginningOfPassWriteIndex")] pub fn get_beginning_of_pass_write_index(this: &GpuComputePassTimestampWrites) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassTimestampWrites`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "beginningOfPassWriteIndex")] pub fn set_beginning_of_pass_write_index(this: &GpuComputePassTimestampWrites, val: u32); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassTimestampWrites`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "endOfPassWriteIndex")] pub fn get_end_of_pass_write_index(this: &GpuComputePassTimestampWrites) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassTimestampWrites`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "endOfPassWriteIndex")] pub fn set_end_of_pass_write_index(this: &GpuComputePassTimestampWrites, val: u32); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassTimestampWrites`, `GpuQuerySet`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "querySet")] pub fn get_query_set(this: &GpuComputePassTimestampWrites) -> GpuQuerySet; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassTimestampWrites`, `GpuQuerySet`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "querySet")] pub fn set_query_set(this: &GpuComputePassTimestampWrites, val: &GpuQuerySet); } @@ -97,7 +97,7 @@ impl GpuComputePassTimestampWrites { #[doc = "*This API requires the following crate features to be activated: `GpuComputePassTimestampWrites`, `GpuQuerySet`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(query_set: &GpuQuerySet) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePipeline.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePipeline.rs index 3bbe4820bb5..c022652a557 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePipeline.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePipeline.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePipeline`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuComputePipeline; # [wasm_bindgen (structural , method , getter , js_class = "GPUComputePipeline" , js_name = label)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePipeline`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuComputePipeline) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPUComputePipeline" , js_name = label)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePipeline`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuComputePipeline, value: &str); # [wasm_bindgen (method , structural , js_class = "GPUComputePipeline" , js_name = getBindGroupLayout)] @@ -68,6 +68,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayout`, `GpuComputePipeline`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn get_bind_group_layout(this: &GpuComputePipeline, index: u32) -> GpuBindGroupLayout; } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePipelineDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePipelineDescriptor.rs index d7ff8e671b3..2ca6458d1dd 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePipelineDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuComputePipelineDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuComputePipelineDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuComputePipelineDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuComputePipelineDescriptor, val: &str); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "layout")] pub fn get_layout(this: &GpuComputePipelineDescriptor) -> ::wasm_bindgen::JsValue; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "layout")] pub fn set_layout(this: &GpuComputePipelineDescriptor, val: &::wasm_bindgen::JsValue); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePipelineDescriptor`, `GpuProgrammableStage`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "compute")] pub fn get_compute(this: &GpuComputePipelineDescriptor) -> GpuProgrammableStage; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePipelineDescriptor`, `GpuProgrammableStage`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "compute")] pub fn set_compute(this: &GpuComputePipelineDescriptor, val: &GpuProgrammableStage); } @@ -97,7 +97,7 @@ impl GpuComputePipelineDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuComputePipelineDescriptor`, `GpuProgrammableStage`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(layout: &::wasm_bindgen::JsValue, compute: &GpuProgrammableStage) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCopyExternalImageDestInfo.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCopyExternalImageDestInfo.rs index 48f7cf74ea1..4b9eaa3f8df 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCopyExternalImageDestInfo.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCopyExternalImageDestInfo.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageDestInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuCopyExternalImageDestInfo; #[doc = "Get the `aspect` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageDestInfo`, `GpuTextureAspect`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "aspect")] pub fn get_aspect(this: &GpuCopyExternalImageDestInfo) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageDestInfo`, `GpuTextureAspect`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "aspect")] pub fn set_aspect(this: &GpuCopyExternalImageDestInfo, val: GpuTextureAspect); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageDestInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "mipLevel")] pub fn get_mip_level(this: &GpuCopyExternalImageDestInfo) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageDestInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "mipLevel")] pub fn set_mip_level(this: &GpuCopyExternalImageDestInfo, val: u32); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageDestInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "origin")] pub fn get_origin(this: &GpuCopyExternalImageDestInfo) -> ::wasm_bindgen::JsValue; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageDestInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "origin")] pub fn set_origin(this: &GpuCopyExternalImageDestInfo, val: &::wasm_bindgen::JsValue); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageDestInfo`, `GpuTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "texture")] pub fn get_texture(this: &GpuCopyExternalImageDestInfo) -> GpuTexture; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageDestInfo`, `GpuTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "texture")] pub fn set_texture(this: &GpuCopyExternalImageDestInfo, val: &GpuTexture); @@ -113,7 +113,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageDestInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "premultipliedAlpha")] pub fn get_premultiplied_alpha(this: &GpuCopyExternalImageDestInfo) -> Option; @@ -122,7 +122,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageDestInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "premultipliedAlpha")] pub fn set_premultiplied_alpha(this: &GpuCopyExternalImageDestInfo, val: bool); } @@ -133,7 +133,7 @@ impl GpuCopyExternalImageDestInfo { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageDestInfo`, `GpuTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(texture: &GpuTexture) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCopyExternalImageSourceInfo.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCopyExternalImageSourceInfo.rs index 24080faeb41..bd787899062 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCopyExternalImageSourceInfo.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCopyExternalImageSourceInfo.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageSourceInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuCopyExternalImageSourceInfo; #[doc = "Get the `flipY` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageSourceInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "flipY")] pub fn get_flip_y(this: &GpuCopyExternalImageSourceInfo) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageSourceInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "flipY")] pub fn set_flip_y(this: &GpuCopyExternalImageSourceInfo, val: bool); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageSourceInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "origin")] pub fn get_origin(this: &GpuCopyExternalImageSourceInfo) -> ::wasm_bindgen::JsValue; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageSourceInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "origin")] pub fn set_origin(this: &GpuCopyExternalImageSourceInfo, val: &::wasm_bindgen::JsValue); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageSourceInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "source")] pub fn get_source(this: &GpuCopyExternalImageSourceInfo) -> ::js_sys::Object; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageSourceInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "source")] pub fn set_source(this: &GpuCopyExternalImageSourceInfo, val: &::js_sys::Object); } @@ -97,7 +97,7 @@ impl GpuCopyExternalImageSourceInfo { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageSourceInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(source: &::js_sys::Object) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCullMode.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCullMode.rs index 2f46bd93a55..02e0a666a88 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCullMode.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuCullMode.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuCullMode`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuCullMode { None = "none", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDepthStencilState.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDepthStencilState.rs index bff7df8a66b..58de872ff91 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDepthStencilState.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDepthStencilState.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuDepthStencilState; #[doc = "Get the `depthBias` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "depthBias")] pub fn get_depth_bias(this: &GpuDepthStencilState) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "depthBias")] pub fn set_depth_bias(this: &GpuDepthStencilState, val: i32); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "depthBiasClamp")] pub fn get_depth_bias_clamp(this: &GpuDepthStencilState) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "depthBiasClamp")] pub fn set_depth_bias_clamp(this: &GpuDepthStencilState, val: f32); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "depthBiasSlopeScale")] pub fn get_depth_bias_slope_scale(this: &GpuDepthStencilState) -> Option; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "depthBiasSlopeScale")] pub fn set_depth_bias_slope_scale(this: &GpuDepthStencilState, val: f32); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCompareFunction`, `GpuDepthStencilState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "depthCompare")] pub fn get_depth_compare(this: &GpuDepthStencilState) -> Option; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCompareFunction`, `GpuDepthStencilState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "depthCompare")] pub fn set_depth_compare(this: &GpuDepthStencilState, val: GpuCompareFunction); @@ -113,7 +113,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "depthWriteEnabled")] pub fn get_depth_write_enabled(this: &GpuDepthStencilState) -> Option; @@ -122,7 +122,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "depthWriteEnabled")] pub fn set_depth_write_enabled(this: &GpuDepthStencilState, val: bool); @@ -131,7 +131,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`, `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "format")] pub fn get_format(this: &GpuDepthStencilState) -> GpuTextureFormat; @@ -140,7 +140,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`, `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "format")] pub fn set_format(this: &GpuDepthStencilState, val: GpuTextureFormat); @@ -149,7 +149,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`, `GpuStencilFaceState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "stencilBack")] pub fn get_stencil_back(this: &GpuDepthStencilState) -> Option; @@ -158,7 +158,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`, `GpuStencilFaceState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "stencilBack")] pub fn set_stencil_back(this: &GpuDepthStencilState, val: &GpuStencilFaceState); @@ -167,7 +167,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`, `GpuStencilFaceState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "stencilFront")] pub fn get_stencil_front(this: &GpuDepthStencilState) -> Option; @@ -176,7 +176,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`, `GpuStencilFaceState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "stencilFront")] pub fn set_stencil_front(this: &GpuDepthStencilState, val: &GpuStencilFaceState); @@ -185,7 +185,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "stencilReadMask")] pub fn get_stencil_read_mask(this: &GpuDepthStencilState) -> Option; @@ -194,7 +194,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "stencilReadMask")] pub fn set_stencil_read_mask(this: &GpuDepthStencilState, val: u32); @@ -203,7 +203,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "stencilWriteMask")] pub fn get_stencil_write_mask(this: &GpuDepthStencilState) -> Option; @@ -212,7 +212,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "stencilWriteMask")] pub fn set_stencil_write_mask(this: &GpuDepthStencilState, val: u32); } @@ -223,7 +223,7 @@ impl GpuDepthStencilState { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`, `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(format: GpuTextureFormat) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDevice.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDevice.rs index aa02361d77e..966c0bd5966 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDevice.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDevice.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuDevice; # [wasm_bindgen (structural , method , getter , js_class = "GPUDevice" , js_name = features)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`, `GpuSupportedFeatures`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn features(this: &GpuDevice) -> GpuSupportedFeatures; # [wasm_bindgen (structural , method , getter , js_class = "GPUDevice" , js_name = limits)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`, `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn limits(this: &GpuDevice) -> GpuSupportedLimits; # [wasm_bindgen (structural , method , getter , js_class = "GPUDevice" , js_name = adapterInfo)] @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuAdapterInfo`, `GpuDevice`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn adapter_info(this: &GpuDevice) -> GpuAdapterInfo; # [wasm_bindgen (structural , method , getter , js_class = "GPUDevice" , js_name = queue)] @@ -79,7 +79,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn queue(this: &GpuDevice) -> GpuQueue; # [wasm_bindgen (structural , method , getter , js_class = "GPUDevice" , js_name = lost)] @@ -90,7 +90,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn lost(this: &GpuDevice) -> ::js_sys::Promise; # [wasm_bindgen (structural , method , getter , js_class = "GPUDevice" , js_name = onuncapturederror)] @@ -101,7 +101,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn onuncapturederror(this: &GpuDevice) -> Option<::js_sys::Function>; # [wasm_bindgen (structural , method , setter , js_class = "GPUDevice" , js_name = onuncapturederror)] @@ -112,7 +112,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_onuncapturederror(this: &GpuDevice, value: Option<&::js_sys::Function>); # [wasm_bindgen (structural , method , getter , js_class = "GPUDevice" , js_name = label)] @@ -123,7 +123,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuDevice) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPUDevice" , js_name = label)] @@ -134,7 +134,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuDevice, value: &str); # [wasm_bindgen (method , structural , js_class = "GPUDevice" , js_name = createBindGroup)] @@ -145,7 +145,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`, `GpuBindGroupDescriptor`, `GpuDevice`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn create_bind_group(this: &GpuDevice, descriptor: &GpuBindGroupDescriptor) -> GpuBindGroup; @@ -157,7 +157,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayout`, `GpuBindGroupLayoutDescriptor`, `GpuDevice`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn create_bind_group_layout( this: &GpuDevice, descriptor: &GpuBindGroupLayoutDescriptor, @@ -171,7 +171,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuBufferDescriptor`, `GpuDevice`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn create_buffer( this: &GpuDevice, descriptor: &GpuBufferDescriptor, @@ -185,7 +185,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoder`, `GpuDevice`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn create_command_encoder(this: &GpuDevice) -> GpuCommandEncoder; # [wasm_bindgen (method , structural , js_class = "GPUDevice" , js_name = createCommandEncoder)] @@ -196,7 +196,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCommandEncoder`, `GpuCommandEncoderDescriptor`, `GpuDevice`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn create_command_encoder_with_descriptor( this: &GpuDevice, descriptor: &GpuCommandEncoderDescriptor, @@ -210,7 +210,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePipeline`, `GpuComputePipelineDescriptor`, `GpuDevice`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn create_compute_pipeline( this: &GpuDevice, descriptor: &GpuComputePipelineDescriptor, @@ -224,7 +224,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuComputePipelineDescriptor`, `GpuDevice`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn create_compute_pipeline_async( this: &GpuDevice, descriptor: &GpuComputePipelineDescriptor, @@ -238,7 +238,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`, `GpuPipelineLayout`, `GpuPipelineLayoutDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn create_pipeline_layout( this: &GpuDevice, descriptor: &GpuPipelineLayoutDescriptor, @@ -252,7 +252,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`, `GpuQuerySet`, `GpuQuerySetDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn create_query_set( this: &GpuDevice, descriptor: &GpuQuerySetDescriptor, @@ -266,7 +266,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`, `GpuRenderBundleEncoder`, `GpuRenderBundleEncoderDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn create_render_bundle_encoder( this: &GpuDevice, descriptor: &GpuRenderBundleEncoderDescriptor, @@ -280,7 +280,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`, `GpuRenderPipeline`, `GpuRenderPipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn create_render_pipeline( this: &GpuDevice, descriptor: &GpuRenderPipelineDescriptor, @@ -294,7 +294,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`, `GpuRenderPipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn create_render_pipeline_async( this: &GpuDevice, descriptor: &GpuRenderPipelineDescriptor, @@ -308,7 +308,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`, `GpuSampler`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn create_sampler(this: &GpuDevice) -> GpuSampler; # [wasm_bindgen (method , structural , js_class = "GPUDevice" , js_name = createSampler)] @@ -319,7 +319,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`, `GpuSampler`, `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn create_sampler_with_descriptor( this: &GpuDevice, descriptor: &GpuSamplerDescriptor, @@ -333,7 +333,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`, `GpuShaderModule`, `GpuShaderModuleDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn create_shader_module( this: &GpuDevice, descriptor: &GpuShaderModuleDescriptor, @@ -347,7 +347,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`, `GpuTexture`, `GpuTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn create_texture( this: &GpuDevice, descriptor: &GpuTextureDescriptor, @@ -361,7 +361,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn destroy(this: &GpuDevice); # [wasm_bindgen (catch , method , structural , js_class = "GPUDevice" , js_name = importExternalTexture)] @@ -372,7 +372,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`, `GpuExternalTexture`, `GpuExternalTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn import_external_texture( this: &GpuDevice, descriptor: &GpuExternalTextureDescriptor, @@ -386,7 +386,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn pop_error_scope(this: &GpuDevice) -> ::js_sys::Promise; # [wasm_bindgen (method , structural , js_class = "GPUDevice" , js_name = pushErrorScope)] @@ -397,6 +397,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDevice`, `GpuErrorFilter`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn push_error_scope(this: &GpuDevice, filter: GpuErrorFilter); } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDeviceDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDeviceDescriptor.rs index dc27743e06d..9a1bb4f2003 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDeviceDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDeviceDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDeviceDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuDeviceDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDeviceDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuDeviceDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDeviceDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuDeviceDescriptor, val: &str); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDeviceDescriptor`, `GpuQueueDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "defaultQueue")] pub fn get_default_queue(this: &GpuDeviceDescriptor) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDeviceDescriptor`, `GpuQueueDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "defaultQueue")] pub fn set_default_queue(this: &GpuDeviceDescriptor, val: &GpuQueueDescriptor); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDeviceDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "requiredFeatures")] pub fn get_required_features(this: &GpuDeviceDescriptor) -> Option<::js_sys::Array>; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDeviceDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "requiredFeatures")] pub fn set_required_features(this: &GpuDeviceDescriptor, val: &::wasm_bindgen::JsValue); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDeviceDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "requiredLimits")] pub fn get_required_limits(this: &GpuDeviceDescriptor) -> Option<::js_sys::Object>; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDeviceDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "requiredLimits")] pub fn set_required_limits(this: &GpuDeviceDescriptor, val: &::js_sys::Object); } @@ -115,7 +115,7 @@ impl GpuDeviceDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuDeviceDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDeviceLostInfo.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDeviceLostInfo.rs index b86f91bff33..898c45c62db 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDeviceLostInfo.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDeviceLostInfo.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDeviceLostInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuDeviceLostInfo; # [wasm_bindgen (structural , method , getter , js_class = "GPUDeviceLostInfo" , js_name = reason)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDeviceLostInfo`, `GpuDeviceLostReason`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn reason(this: &GpuDeviceLostInfo) -> GpuDeviceLostReason; # [wasm_bindgen (structural , method , getter , js_class = "GPUDeviceLostInfo" , js_name = message)] @@ -57,6 +57,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDeviceLostInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn message(this: &GpuDeviceLostInfo) -> ::alloc::string::String; } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDeviceLostReason.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDeviceLostReason.rs index 7362466a34a..31ed7b13eaf 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDeviceLostReason.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuDeviceLostReason.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuDeviceLostReason`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuDeviceLostReason { Unknown = "unknown", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuError.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuError.rs index d95fc59f814..6ce5b5fe98d 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuError.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuError.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuError`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuError; # [wasm_bindgen (structural , method , getter , js_class = "GPUError" , js_name = message)] @@ -46,6 +46,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuError`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn message(this: &GpuError) -> ::alloc::string::String; } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuErrorFilter.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuErrorFilter.rs index 21d3362470b..26a63aef19e 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuErrorFilter.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuErrorFilter.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuErrorFilter`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuErrorFilter { Validation = "validation", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuExtent3dDict.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuExtent3dDict.rs index 00a52d54545..0f81c38357b 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuExtent3dDict.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuExtent3dDict.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuExtent3dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuExtent3dDict; #[doc = "Get the `depthOrArrayLayers` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuExtent3dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "depthOrArrayLayers")] pub fn get_depth_or_array_layers(this: &GpuExtent3dDict) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuExtent3dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "depthOrArrayLayers")] pub fn set_depth_or_array_layers(this: &GpuExtent3dDict, val: u32); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuExtent3dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "height")] pub fn get_height(this: &GpuExtent3dDict) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuExtent3dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "height")] pub fn set_height(this: &GpuExtent3dDict, val: u32); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuExtent3dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "width")] pub fn get_width(this: &GpuExtent3dDict) -> u32; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuExtent3dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "width")] pub fn set_width(this: &GpuExtent3dDict, val: u32); } @@ -97,7 +97,7 @@ impl GpuExtent3dDict { #[doc = "*This API requires the following crate features to be activated: `GpuExtent3dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(width: u32) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuExternalTexture.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuExternalTexture.rs index 36a3faf0652..ea9a557b944 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuExternalTexture.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuExternalTexture.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuExternalTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuExternalTexture; # [wasm_bindgen (structural , method , getter , js_class = "GPUExternalTexture" , js_name = label)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuExternalTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuExternalTexture) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPUExternalTexture" , js_name = label)] @@ -57,6 +57,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuExternalTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuExternalTexture, value: &str); } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuExternalTextureBindingLayout.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuExternalTextureBindingLayout.rs index 869a4cc1072..c773de83dfb 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuExternalTextureBindingLayout.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuExternalTextureBindingLayout.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuExternalTextureBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuExternalTextureBindingLayout; } @@ -43,7 +43,7 @@ impl GpuExternalTextureBindingLayout { #[doc = "*This API requires the following crate features to be activated: `GpuExternalTextureBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuExternalTextureDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuExternalTextureDescriptor.rs index 209538a3cf9..b1c6cdc869c 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuExternalTextureDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuExternalTextureDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuExternalTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuExternalTextureDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuExternalTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuExternalTextureDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuExternalTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuExternalTextureDescriptor, val: &str); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuExternalTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "source")] pub fn get_source(this: &GpuExternalTextureDescriptor) -> ::js_sys::Object; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuExternalTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "source")] pub fn set_source(this: &GpuExternalTextureDescriptor, val: &::js_sys::Object); } @@ -79,7 +79,7 @@ impl GpuExternalTextureDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuExternalTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(source: &::js_sys::Object) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuFeatureName.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuFeatureName.rs index 8b454f07cfd..cf3a5e8537f 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuFeatureName.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuFeatureName.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuFeatureName`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuFeatureName { DepthClipControl = "depth-clip-control", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuFilterMode.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuFilterMode.rs index 1e5c94697a4..46fb0b642e0 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuFilterMode.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuFilterMode.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuFilterMode`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuFilterMode { Nearest = "nearest", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuFragmentState.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuFragmentState.rs index e8d961e8bbf..ba16aca0c77 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuFragmentState.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuFragmentState.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuFragmentState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuFragmentState; #[doc = "Get the `constants` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuFragmentState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "constants")] pub fn get_constants(this: &GpuFragmentState) -> Option<::js_sys::Object>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuFragmentState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "constants")] pub fn set_constants(this: &GpuFragmentState, val: &::js_sys::Object); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuFragmentState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "entryPoint")] pub fn get_entry_point(this: &GpuFragmentState) -> Option<::alloc::string::String>; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuFragmentState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "entryPoint")] pub fn set_entry_point(this: &GpuFragmentState, val: &str); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuFragmentState`, `GpuShaderModule`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "module")] pub fn get_module(this: &GpuFragmentState) -> GpuShaderModule; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuFragmentState`, `GpuShaderModule`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "module")] pub fn set_module(this: &GpuFragmentState, val: &GpuShaderModule); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuFragmentState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "targets")] pub fn get_targets(this: &GpuFragmentState) -> ::js_sys::Array; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuFragmentState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "targets")] pub fn set_targets(this: &GpuFragmentState, val: &::wasm_bindgen::JsValue); } @@ -115,7 +115,7 @@ impl GpuFragmentState { #[doc = "*This API requires the following crate features to be activated: `GpuFragmentState`, `GpuShaderModule`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(module: &GpuShaderModule, targets: &::wasm_bindgen::JsValue) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuFrontFace.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuFrontFace.rs index 89dec0e64b0..eb9eda7b580 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuFrontFace.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuFrontFace.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuFrontFace`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuFrontFace { Ccw = "ccw", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuIndexFormat.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuIndexFormat.rs index fd3a6a85ca6..7931e961c1a 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuIndexFormat.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuIndexFormat.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuIndexFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuIndexFormat { Uint16 = "uint16", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuLoadOp.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuLoadOp.rs index cb542321bd7..6717dc764d8 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuLoadOp.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuLoadOp.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuLoadOp`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuLoadOp { Load = "load", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuMipmapFilterMode.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuMipmapFilterMode.rs index 8dceae994a0..9d962297d30 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuMipmapFilterMode.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuMipmapFilterMode.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuMipmapFilterMode`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuMipmapFilterMode { Nearest = "nearest", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuMultisampleState.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuMultisampleState.rs index 2cbaaccd3b1..28cd36d2f67 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuMultisampleState.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuMultisampleState.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuMultisampleState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuMultisampleState; #[doc = "Get the `alphaToCoverageEnabled` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuMultisampleState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "alphaToCoverageEnabled")] pub fn get_alpha_to_coverage_enabled(this: &GpuMultisampleState) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuMultisampleState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "alphaToCoverageEnabled")] pub fn set_alpha_to_coverage_enabled(this: &GpuMultisampleState, val: bool); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuMultisampleState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "count")] pub fn get_count(this: &GpuMultisampleState) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuMultisampleState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "count")] pub fn set_count(this: &GpuMultisampleState, val: u32); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuMultisampleState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "mask")] pub fn get_mask(this: &GpuMultisampleState) -> Option; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuMultisampleState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "mask")] pub fn set_mask(this: &GpuMultisampleState, val: u32); } @@ -97,7 +97,7 @@ impl GpuMultisampleState { #[doc = "*This API requires the following crate features to be activated: `GpuMultisampleState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuObjectDescriptorBase.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuObjectDescriptorBase.rs index 284f643ec9b..f46278f77c6 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuObjectDescriptorBase.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuObjectDescriptorBase.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuObjectDescriptorBase`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuObjectDescriptorBase; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuObjectDescriptorBase`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuObjectDescriptorBase) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuObjectDescriptorBase`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuObjectDescriptorBase, val: &str); } @@ -61,7 +61,7 @@ impl GpuObjectDescriptorBase { #[doc = "*This API requires the following crate features to be activated: `GpuObjectDescriptorBase`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuOrigin2dDict.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuOrigin2dDict.rs index 13e1ab6bee7..c8b5210053d 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuOrigin2dDict.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuOrigin2dDict.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuOrigin2dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuOrigin2dDict; #[doc = "Get the `x` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuOrigin2dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "x")] pub fn get_x(this: &GpuOrigin2dDict) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuOrigin2dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "x")] pub fn set_x(this: &GpuOrigin2dDict, val: u32); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuOrigin2dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "y")] pub fn get_y(this: &GpuOrigin2dDict) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuOrigin2dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "y")] pub fn set_y(this: &GpuOrigin2dDict, val: u32); } @@ -79,7 +79,7 @@ impl GpuOrigin2dDict { #[doc = "*This API requires the following crate features to be activated: `GpuOrigin2dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuOrigin3dDict.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuOrigin3dDict.rs index 96f67f929d9..a6c77558cc6 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuOrigin3dDict.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuOrigin3dDict.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuOrigin3dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuOrigin3dDict; #[doc = "Get the `x` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuOrigin3dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "x")] pub fn get_x(this: &GpuOrigin3dDict) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuOrigin3dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "x")] pub fn set_x(this: &GpuOrigin3dDict, val: u32); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuOrigin3dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "y")] pub fn get_y(this: &GpuOrigin3dDict) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuOrigin3dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "y")] pub fn set_y(this: &GpuOrigin3dDict, val: u32); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuOrigin3dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "z")] pub fn get_z(this: &GpuOrigin3dDict) -> Option; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuOrigin3dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "z")] pub fn set_z(this: &GpuOrigin3dDict, val: u32); } @@ -97,7 +97,7 @@ impl GpuOrigin3dDict { #[doc = "*This API requires the following crate features to be activated: `GpuOrigin3dDict`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuOutOfMemoryError.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuOutOfMemoryError.rs index 4246b73c007..21f527deac9 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuOutOfMemoryError.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuOutOfMemoryError.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuOutOfMemoryError`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuOutOfMemoryError; #[wasm_bindgen(catch, constructor, js_class = "GPUOutOfMemoryError")] @@ -46,6 +46,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuOutOfMemoryError`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(message: &str) -> Result; } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPipelineDescriptorBase.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPipelineDescriptorBase.rs index 5e9a661c807..e0067ddcd04 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPipelineDescriptorBase.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPipelineDescriptorBase.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPipelineDescriptorBase`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuPipelineDescriptorBase; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPipelineDescriptorBase`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuPipelineDescriptorBase) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPipelineDescriptorBase`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuPipelineDescriptorBase, val: &str); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPipelineDescriptorBase`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "layout")] pub fn get_layout(this: &GpuPipelineDescriptorBase) -> ::wasm_bindgen::JsValue; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPipelineDescriptorBase`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "layout")] pub fn set_layout(this: &GpuPipelineDescriptorBase, val: &::wasm_bindgen::JsValue); } @@ -79,7 +79,7 @@ impl GpuPipelineDescriptorBase { #[doc = "*This API requires the following crate features to be activated: `GpuPipelineDescriptorBase`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(layout: &::wasm_bindgen::JsValue) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPipelineLayout.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPipelineLayout.rs index 58b55b53286..da21f62ef83 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPipelineLayout.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPipelineLayout.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPipelineLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuPipelineLayout; # [wasm_bindgen (structural , method , getter , js_class = "GPUPipelineLayout" , js_name = label)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPipelineLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuPipelineLayout) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPUPipelineLayout" , js_name = label)] @@ -57,6 +57,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPipelineLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuPipelineLayout, value: &str); } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPipelineLayoutDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPipelineLayoutDescriptor.rs index 7b3b8277a1e..7fc19056347 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPipelineLayoutDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPipelineLayoutDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPipelineLayoutDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuPipelineLayoutDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPipelineLayoutDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuPipelineLayoutDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPipelineLayoutDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuPipelineLayoutDescriptor, val: &str); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPipelineLayoutDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "bindGroupLayouts")] pub fn get_bind_group_layouts(this: &GpuPipelineLayoutDescriptor) -> ::js_sys::Array; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPipelineLayoutDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "bindGroupLayouts")] pub fn set_bind_group_layouts( this: &GpuPipelineLayoutDescriptor, @@ -82,7 +82,7 @@ impl GpuPipelineLayoutDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuPipelineLayoutDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(bind_group_layouts: &::wasm_bindgen::JsValue) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPowerPreference.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPowerPreference.rs index 483a533e7cb..d674f0efcec 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPowerPreference.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPowerPreference.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuPowerPreference`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuPowerPreference { LowPower = "low-power", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPrimitiveState.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPrimitiveState.rs index be0a1347a55..cf9cdb3e527 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPrimitiveState.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPrimitiveState.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPrimitiveState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuPrimitiveState; #[doc = "Get the `cullMode` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCullMode`, `GpuPrimitiveState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "cullMode")] pub fn get_cull_mode(this: &GpuPrimitiveState) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCullMode`, `GpuPrimitiveState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "cullMode")] pub fn set_cull_mode(this: &GpuPrimitiveState, val: GpuCullMode); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuFrontFace`, `GpuPrimitiveState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "frontFace")] pub fn get_front_face(this: &GpuPrimitiveState) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuFrontFace`, `GpuPrimitiveState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "frontFace")] pub fn set_front_face(this: &GpuPrimitiveState, val: GpuFrontFace); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuIndexFormat`, `GpuPrimitiveState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "stripIndexFormat")] pub fn get_strip_index_format(this: &GpuPrimitiveState) -> Option; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuIndexFormat`, `GpuPrimitiveState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "stripIndexFormat")] pub fn set_strip_index_format(this: &GpuPrimitiveState, val: GpuIndexFormat); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPrimitiveState`, `GpuPrimitiveTopology`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "topology")] pub fn get_topology(this: &GpuPrimitiveState) -> Option; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPrimitiveState`, `GpuPrimitiveTopology`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "topology")] pub fn set_topology(this: &GpuPrimitiveState, val: GpuPrimitiveTopology); @@ -113,7 +113,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPrimitiveState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "unclippedDepth")] pub fn get_unclipped_depth(this: &GpuPrimitiveState) -> Option; @@ -122,7 +122,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPrimitiveState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "unclippedDepth")] pub fn set_unclipped_depth(this: &GpuPrimitiveState, val: bool); } @@ -133,7 +133,7 @@ impl GpuPrimitiveState { #[doc = "*This API requires the following crate features to be activated: `GpuPrimitiveState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPrimitiveTopology.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPrimitiveTopology.rs index 1b869c2a921..6ec5b28172d 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPrimitiveTopology.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuPrimitiveTopology.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuPrimitiveTopology`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuPrimitiveTopology { PointList = "point-list", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuProgrammableStage.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuProgrammableStage.rs index d8e08bc4e15..03110080db5 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuProgrammableStage.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuProgrammableStage.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuProgrammableStage`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuProgrammableStage; #[doc = "Get the `constants` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuProgrammableStage`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "constants")] pub fn get_constants(this: &GpuProgrammableStage) -> Option<::js_sys::Object>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuProgrammableStage`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "constants")] pub fn set_constants(this: &GpuProgrammableStage, val: &::js_sys::Object); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuProgrammableStage`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "entryPoint")] pub fn get_entry_point(this: &GpuProgrammableStage) -> Option<::alloc::string::String>; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuProgrammableStage`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "entryPoint")] pub fn set_entry_point(this: &GpuProgrammableStage, val: &str); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuProgrammableStage`, `GpuShaderModule`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "module")] pub fn get_module(this: &GpuProgrammableStage) -> GpuShaderModule; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuProgrammableStage`, `GpuShaderModule`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "module")] pub fn set_module(this: &GpuProgrammableStage, val: &GpuShaderModule); } @@ -97,7 +97,7 @@ impl GpuProgrammableStage { #[doc = "*This API requires the following crate features to be activated: `GpuProgrammableStage`, `GpuShaderModule`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(module: &GpuShaderModule) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQuerySet.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQuerySet.rs index 55e3c8cf347..ddaf35ac7a8 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQuerySet.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQuerySet.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQuerySet`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuQuerySet; # [wasm_bindgen (structural , method , getter , js_class = "GPUQuerySet" , js_name = type)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQuerySet`, `GpuQueryType`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn type_(this: &GpuQuerySet) -> GpuQueryType; # [wasm_bindgen (structural , method , getter , js_class = "GPUQuerySet" , js_name = count)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQuerySet`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn count(this: &GpuQuerySet) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUQuerySet" , js_name = label)] @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQuerySet`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuQuerySet) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPUQuerySet" , js_name = label)] @@ -79,7 +79,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQuerySet`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuQuerySet, value: &str); # [wasm_bindgen (method , structural , js_class = "GPUQuerySet" , js_name = destroy)] @@ -90,6 +90,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQuerySet`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn destroy(this: &GpuQuerySet); } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQuerySetDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQuerySetDescriptor.rs index 0f79bef9f04..def89e147b0 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQuerySetDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQuerySetDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQuerySetDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuQuerySetDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQuerySetDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuQuerySetDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQuerySetDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuQuerySetDescriptor, val: &str); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQuerySetDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "count")] pub fn get_count(this: &GpuQuerySetDescriptor) -> u32; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQuerySetDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "count")] pub fn set_count(this: &GpuQuerySetDescriptor, val: u32); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQuerySetDescriptor`, `GpuQueryType`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "type")] pub fn get_type(this: &GpuQuerySetDescriptor) -> GpuQueryType; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQuerySetDescriptor`, `GpuQueryType`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "type")] pub fn set_type(this: &GpuQuerySetDescriptor, val: GpuQueryType); } @@ -97,7 +97,7 @@ impl GpuQuerySetDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuQuerySetDescriptor`, `GpuQueryType`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(count: u32, type_: GpuQueryType) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQueryType.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQueryType.rs index bf33f2eb639..58d693abe2d 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQueryType.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQueryType.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuQueryType`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuQueryType { Occlusion = "occlusion", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQueue.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQueue.rs index 46aea1996ec..4b65d7ad7af 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQueue.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQueue.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuQueue; # [wasm_bindgen (structural , method , getter , js_class = "GPUQueue" , js_name = label)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuQueue) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPUQueue" , js_name = label)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuQueue, value: &str); # [wasm_bindgen (catch , method , structural , js_class = "GPUQueue" , js_name = copyExternalImageToTexture)] @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageDestInfo`, `GpuCopyExternalImageSourceInfo`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_external_image_to_texture_with_u32_sequence( this: &GpuQueue, source: &GpuCopyExternalImageSourceInfo, @@ -84,7 +84,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCopyExternalImageDestInfo`, `GpuCopyExternalImageSourceInfo`, `GpuExtent3dDict`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn copy_external_image_to_texture_with_gpu_extent_3d_dict( this: &GpuQueue, source: &GpuCopyExternalImageSourceInfo, @@ -100,7 +100,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn on_submitted_work_done(this: &GpuQueue) -> ::js_sys::Promise; # [wasm_bindgen (method , structural , js_class = "GPUQueue" , js_name = submit)] @@ -111,7 +111,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn submit(this: &GpuQueue, command_buffers: &::wasm_bindgen::JsValue); # [wasm_bindgen (catch , method , structural , js_class = "GPUQueue" , js_name = writeBuffer)] @@ -122,7 +122,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_buffer_source( this: &GpuQueue, buffer: &GpuBuffer, @@ -138,7 +138,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_buffer_source( this: &GpuQueue, buffer: &GpuBuffer, @@ -154,7 +154,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_u8_slice( this: &GpuQueue, buffer: &GpuBuffer, @@ -170,7 +170,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_u8_slice( this: &GpuQueue, buffer: &GpuBuffer, @@ -186,7 +186,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_u8_array( this: &GpuQueue, buffer: &GpuBuffer, @@ -202,7 +202,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_u8_array( this: &GpuQueue, buffer: &GpuBuffer, @@ -218,7 +218,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_buffer_source_and_u32( this: &GpuQueue, buffer: &GpuBuffer, @@ -235,7 +235,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_buffer_source_and_u32( this: &GpuQueue, buffer: &GpuBuffer, @@ -252,7 +252,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_u8_slice_and_u32( this: &GpuQueue, buffer: &GpuBuffer, @@ -269,7 +269,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_u8_slice_and_u32( this: &GpuQueue, buffer: &GpuBuffer, @@ -286,7 +286,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_u8_array_and_u32( this: &GpuQueue, buffer: &GpuBuffer, @@ -303,7 +303,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_u8_array_and_u32( this: &GpuQueue, buffer: &GpuBuffer, @@ -320,7 +320,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_buffer_source_and_f64( this: &GpuQueue, buffer: &GpuBuffer, @@ -337,7 +337,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_buffer_source_and_f64( this: &GpuQueue, buffer: &GpuBuffer, @@ -354,7 +354,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_u8_slice_and_f64( this: &GpuQueue, buffer: &GpuBuffer, @@ -371,7 +371,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_u8_slice_and_f64( this: &GpuQueue, buffer: &GpuBuffer, @@ -388,7 +388,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_u8_array_and_f64( this: &GpuQueue, buffer: &GpuBuffer, @@ -405,7 +405,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_u8_array_and_f64( this: &GpuQueue, buffer: &GpuBuffer, @@ -422,7 +422,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_buffer_source_and_u32_and_u32( this: &GpuQueue, buffer: &GpuBuffer, @@ -440,7 +440,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_buffer_source_and_u32_and_u32( this: &GpuQueue, buffer: &GpuBuffer, @@ -458,7 +458,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_u8_slice_and_u32_and_u32( this: &GpuQueue, buffer: &GpuBuffer, @@ -476,7 +476,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_u8_slice_and_u32_and_u32( this: &GpuQueue, buffer: &GpuBuffer, @@ -494,7 +494,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_u8_array_and_u32_and_u32( this: &GpuQueue, buffer: &GpuBuffer, @@ -512,7 +512,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_u8_array_and_u32_and_u32( this: &GpuQueue, buffer: &GpuBuffer, @@ -530,7 +530,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_buffer_source_and_f64_and_u32( this: &GpuQueue, buffer: &GpuBuffer, @@ -548,7 +548,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_buffer_source_and_f64_and_u32( this: &GpuQueue, buffer: &GpuBuffer, @@ -566,7 +566,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_u8_slice_and_f64_and_u32( this: &GpuQueue, buffer: &GpuBuffer, @@ -584,7 +584,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_u8_slice_and_f64_and_u32( this: &GpuQueue, buffer: &GpuBuffer, @@ -602,7 +602,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_u8_array_and_f64_and_u32( this: &GpuQueue, buffer: &GpuBuffer, @@ -620,7 +620,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_u8_array_and_f64_and_u32( this: &GpuQueue, buffer: &GpuBuffer, @@ -638,7 +638,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_buffer_source_and_u32_and_f64( this: &GpuQueue, buffer: &GpuBuffer, @@ -656,7 +656,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_buffer_source_and_u32_and_f64( this: &GpuQueue, buffer: &GpuBuffer, @@ -674,7 +674,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_u8_slice_and_u32_and_f64( this: &GpuQueue, buffer: &GpuBuffer, @@ -692,7 +692,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_u8_slice_and_u32_and_f64( this: &GpuQueue, buffer: &GpuBuffer, @@ -710,7 +710,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_u8_array_and_u32_and_f64( this: &GpuQueue, buffer: &GpuBuffer, @@ -728,7 +728,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_u8_array_and_u32_and_f64( this: &GpuQueue, buffer: &GpuBuffer, @@ -746,7 +746,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_buffer_source_and_f64_and_f64( this: &GpuQueue, buffer: &GpuBuffer, @@ -764,7 +764,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_buffer_source_and_f64_and_f64( this: &GpuQueue, buffer: &GpuBuffer, @@ -782,7 +782,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_u8_slice_and_f64_and_f64( this: &GpuQueue, buffer: &GpuBuffer, @@ -800,7 +800,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_u8_slice_and_f64_and_f64( this: &GpuQueue, buffer: &GpuBuffer, @@ -818,7 +818,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_u32_and_u8_array_and_f64_and_f64( this: &GpuQueue, buffer: &GpuBuffer, @@ -836,7 +836,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuQueue`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_buffer_with_f64_and_u8_array_and_f64_and_f64( this: &GpuQueue, buffer: &GpuBuffer, @@ -854,7 +854,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQueue`, `GpuTexelCopyBufferLayout`, `GpuTexelCopyTextureInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_texture_with_buffer_source_and_u32_sequence( this: &GpuQueue, destination: &GpuTexelCopyTextureInfo, @@ -871,7 +871,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQueue`, `GpuTexelCopyBufferLayout`, `GpuTexelCopyTextureInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_texture_with_u8_slice_and_u32_sequence( this: &GpuQueue, destination: &GpuTexelCopyTextureInfo, @@ -888,7 +888,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQueue`, `GpuTexelCopyBufferLayout`, `GpuTexelCopyTextureInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_texture_with_u8_array_and_u32_sequence( this: &GpuQueue, destination: &GpuTexelCopyTextureInfo, @@ -905,7 +905,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuExtent3dDict`, `GpuQueue`, `GpuTexelCopyBufferLayout`, `GpuTexelCopyTextureInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_texture_with_buffer_source_and_gpu_extent_3d_dict( this: &GpuQueue, destination: &GpuTexelCopyTextureInfo, @@ -922,7 +922,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuExtent3dDict`, `GpuQueue`, `GpuTexelCopyBufferLayout`, `GpuTexelCopyTextureInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_texture_with_u8_slice_and_gpu_extent_3d_dict( this: &GpuQueue, destination: &GpuTexelCopyTextureInfo, @@ -939,7 +939,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuExtent3dDict`, `GpuQueue`, `GpuTexelCopyBufferLayout`, `GpuTexelCopyTextureInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn write_texture_with_u8_array_and_gpu_extent_3d_dict( this: &GpuQueue, destination: &GpuTexelCopyTextureInfo, diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQueueDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQueueDescriptor.rs index b70952ee574..822a6f069f6 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQueueDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuQueueDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQueueDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuQueueDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQueueDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuQueueDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQueueDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuQueueDescriptor, val: &str); } @@ -61,7 +61,7 @@ impl GpuQueueDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuQueueDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderBundle.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderBundle.rs index a51fc4bd484..36f85f3b2d4 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderBundle.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderBundle.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundle`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuRenderBundle; # [wasm_bindgen (structural , method , getter , js_class = "GPURenderBundle" , js_name = label)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundle`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuRenderBundle) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPURenderBundle" , js_name = label)] @@ -57,6 +57,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundle`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuRenderBundle, value: &str); } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderBundleDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderBundleDescriptor.rs index be10266d0f6..4f2c6c286d0 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderBundleDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderBundleDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuRenderBundleDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuRenderBundleDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuRenderBundleDescriptor, val: &str); } @@ -61,7 +61,7 @@ impl GpuRenderBundleDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderBundleEncoder.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderBundleEncoder.rs index 8809116bbac..36519cd3250 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderBundleEncoder.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderBundleEncoder.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuRenderBundleEncoder; # [wasm_bindgen (structural , method , getter , js_class = "GPURenderBundleEncoder" , js_name = label)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuRenderBundleEncoder) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPURenderBundleEncoder" , js_name = label)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuRenderBundleEncoder, value: &str); # [wasm_bindgen (method , structural , js_class = "GPURenderBundleEncoder" , js_name = finish)] @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundle`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn finish(this: &GpuRenderBundleEncoder) -> GpuRenderBundle; # [wasm_bindgen (method , structural , js_class = "GPURenderBundleEncoder" , js_name = finish)] @@ -79,7 +79,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundle`, `GpuRenderBundleDescriptor`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn finish_with_descriptor( this: &GpuRenderBundleEncoder, descriptor: &GpuRenderBundleDescriptor, @@ -93,7 +93,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_bind_group( this: &GpuRenderBundleEncoder, index: u32, @@ -108,7 +108,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_bind_group_with_u32_sequence( this: &GpuRenderBundleEncoder, index: u32, @@ -124,7 +124,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_bind_group_with_u32_slice_and_u32_and_dynamic_offsets_data_length( this: &GpuRenderBundleEncoder, index: u32, @@ -142,7 +142,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_bind_group_with_u32_array_and_u32_and_dynamic_offsets_data_length( this: &GpuRenderBundleEncoder, index: u32, @@ -160,7 +160,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_bind_group_with_u32_slice_and_f64_and_dynamic_offsets_data_length( this: &GpuRenderBundleEncoder, index: u32, @@ -178,7 +178,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_bind_group_with_u32_array_and_f64_and_dynamic_offsets_data_length( this: &GpuRenderBundleEncoder, index: u32, @@ -196,7 +196,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn insert_debug_marker(this: &GpuRenderBundleEncoder, marker_label: &str); # [wasm_bindgen (method , structural , js_class = "GPURenderBundleEncoder" , js_name = popDebugGroup)] @@ -207,7 +207,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn pop_debug_group(this: &GpuRenderBundleEncoder); # [wasm_bindgen (method , structural , js_class = "GPURenderBundleEncoder" , js_name = pushDebugGroup)] @@ -218,7 +218,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn push_debug_group(this: &GpuRenderBundleEncoder, group_label: &str); # [wasm_bindgen (method , structural , js_class = "GPURenderBundleEncoder" , js_name = draw)] @@ -229,7 +229,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw(this: &GpuRenderBundleEncoder, vertex_count: u32); # [wasm_bindgen (method , structural , js_class = "GPURenderBundleEncoder" , js_name = draw)] @@ -240,7 +240,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_with_instance_count( this: &GpuRenderBundleEncoder, vertex_count: u32, @@ -255,7 +255,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_with_instance_count_and_first_vertex( this: &GpuRenderBundleEncoder, vertex_count: u32, @@ -271,7 +271,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_with_instance_count_and_first_vertex_and_first_instance( this: &GpuRenderBundleEncoder, vertex_count: u32, @@ -288,7 +288,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_indexed(this: &GpuRenderBundleEncoder, index_count: u32); # [wasm_bindgen (method , structural , js_class = "GPURenderBundleEncoder" , js_name = drawIndexed)] @@ -299,7 +299,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_indexed_with_instance_count( this: &GpuRenderBundleEncoder, index_count: u32, @@ -314,7 +314,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_indexed_with_instance_count_and_first_index( this: &GpuRenderBundleEncoder, index_count: u32, @@ -330,7 +330,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_indexed_with_instance_count_and_first_index_and_base_vertex( this: &GpuRenderBundleEncoder, index_count: u32, @@ -347,7 +347,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_indexed_with_instance_count_and_first_index_and_base_vertex_and_first_instance( this: &GpuRenderBundleEncoder, index_count: u32, @@ -365,7 +365,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_indexed_indirect_with_u32( this: &GpuRenderBundleEncoder, indirect_buffer: &GpuBuffer, @@ -380,7 +380,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_indexed_indirect_with_f64( this: &GpuRenderBundleEncoder, indirect_buffer: &GpuBuffer, @@ -395,7 +395,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_indirect_with_u32( this: &GpuRenderBundleEncoder, indirect_buffer: &GpuBuffer, @@ -410,7 +410,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_indirect_with_f64( this: &GpuRenderBundleEncoder, indirect_buffer: &GpuBuffer, @@ -425,7 +425,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuIndexFormat`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_index_buffer( this: &GpuRenderBundleEncoder, buffer: &GpuBuffer, @@ -440,7 +440,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuIndexFormat`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_index_buffer_with_u32( this: &GpuRenderBundleEncoder, buffer: &GpuBuffer, @@ -456,7 +456,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuIndexFormat`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_index_buffer_with_f64( this: &GpuRenderBundleEncoder, buffer: &GpuBuffer, @@ -472,7 +472,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuIndexFormat`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_index_buffer_with_u32_and_u32( this: &GpuRenderBundleEncoder, buffer: &GpuBuffer, @@ -489,7 +489,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuIndexFormat`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_index_buffer_with_f64_and_u32( this: &GpuRenderBundleEncoder, buffer: &GpuBuffer, @@ -506,7 +506,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuIndexFormat`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_index_buffer_with_u32_and_f64( this: &GpuRenderBundleEncoder, buffer: &GpuBuffer, @@ -523,7 +523,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuIndexFormat`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_index_buffer_with_f64_and_f64( this: &GpuRenderBundleEncoder, buffer: &GpuBuffer, @@ -540,7 +540,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoder`, `GpuRenderPipeline`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_pipeline(this: &GpuRenderBundleEncoder, pipeline: &GpuRenderPipeline); # [wasm_bindgen (method , structural , js_class = "GPURenderBundleEncoder" , js_name = setVertexBuffer)] @@ -551,7 +551,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_vertex_buffer(this: &GpuRenderBundleEncoder, slot: u32, buffer: Option<&GpuBuffer>); # [wasm_bindgen (method , structural , js_class = "GPURenderBundleEncoder" , js_name = setVertexBuffer)] @@ -562,7 +562,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_vertex_buffer_with_u32( this: &GpuRenderBundleEncoder, slot: u32, @@ -578,7 +578,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_vertex_buffer_with_f64( this: &GpuRenderBundleEncoder, slot: u32, @@ -594,7 +594,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_vertex_buffer_with_u32_and_u32( this: &GpuRenderBundleEncoder, slot: u32, @@ -611,7 +611,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_vertex_buffer_with_f64_and_u32( this: &GpuRenderBundleEncoder, slot: u32, @@ -628,7 +628,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_vertex_buffer_with_u32_and_f64( this: &GpuRenderBundleEncoder, slot: u32, @@ -645,7 +645,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderBundleEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_vertex_buffer_with_f64_and_f64( this: &GpuRenderBundleEncoder, slot: u32, diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderBundleEncoderDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderBundleEncoderDescriptor.rs index 0b4d2888136..e4a7939aaa8 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderBundleEncoderDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderBundleEncoderDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoderDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuRenderBundleEncoderDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoderDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuRenderBundleEncoderDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoderDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuRenderBundleEncoderDescriptor, val: &str); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoderDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "colorFormats")] pub fn get_color_formats(this: &GpuRenderBundleEncoderDescriptor) -> ::js_sys::Array; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoderDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "colorFormats")] pub fn set_color_formats( this: &GpuRenderBundleEncoderDescriptor, @@ -80,7 +80,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoderDescriptor`, `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "depthStencilFormat")] pub fn get_depth_stencil_format( this: &GpuRenderBundleEncoderDescriptor, @@ -91,7 +91,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoderDescriptor`, `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "depthStencilFormat")] pub fn set_depth_stencil_format(this: &GpuRenderBundleEncoderDescriptor, val: GpuTextureFormat); @@ -100,7 +100,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoderDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "sampleCount")] pub fn get_sample_count(this: &GpuRenderBundleEncoderDescriptor) -> Option; @@ -109,7 +109,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoderDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "sampleCount")] pub fn set_sample_count(this: &GpuRenderBundleEncoderDescriptor, val: u32); @@ -118,7 +118,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoderDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "depthReadOnly")] pub fn get_depth_read_only(this: &GpuRenderBundleEncoderDescriptor) -> Option; @@ -127,7 +127,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoderDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "depthReadOnly")] pub fn set_depth_read_only(this: &GpuRenderBundleEncoderDescriptor, val: bool); @@ -136,7 +136,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoderDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "stencilReadOnly")] pub fn get_stencil_read_only(this: &GpuRenderBundleEncoderDescriptor) -> Option; @@ -145,7 +145,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoderDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "stencilReadOnly")] pub fn set_stencil_read_only(this: &GpuRenderBundleEncoderDescriptor, val: bool); } @@ -156,7 +156,7 @@ impl GpuRenderBundleEncoderDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuRenderBundleEncoderDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(color_formats: &::wasm_bindgen::JsValue) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassColorAttachment.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassColorAttachment.rs index 10c13f16723..7bba182b1ba 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassColorAttachment.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassColorAttachment.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassColorAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuRenderPassColorAttachment; #[doc = "Get the `clearValue` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassColorAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "clearValue")] pub fn get_clear_value(this: &GpuRenderPassColorAttachment) -> ::wasm_bindgen::JsValue; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassColorAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "clearValue")] pub fn set_clear_value(this: &GpuRenderPassColorAttachment, val: &::wasm_bindgen::JsValue); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassColorAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "depthSlice")] pub fn get_depth_slice(this: &GpuRenderPassColorAttachment) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassColorAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "depthSlice")] pub fn set_depth_slice(this: &GpuRenderPassColorAttachment, val: u32); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuLoadOp`, `GpuRenderPassColorAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "loadOp")] pub fn get_load_op(this: &GpuRenderPassColorAttachment) -> GpuLoadOp; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuLoadOp`, `GpuRenderPassColorAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "loadOp")] pub fn set_load_op(this: &GpuRenderPassColorAttachment, val: GpuLoadOp); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassColorAttachment`, `GpuTextureView`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "resolveTarget")] pub fn get_resolve_target(this: &GpuRenderPassColorAttachment) -> Option; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassColorAttachment`, `GpuTextureView`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "resolveTarget")] pub fn set_resolve_target(this: &GpuRenderPassColorAttachment, val: &GpuTextureView); @@ -113,7 +113,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassColorAttachment`, `GpuStoreOp`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "storeOp")] pub fn get_store_op(this: &GpuRenderPassColorAttachment) -> GpuStoreOp; @@ -122,7 +122,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassColorAttachment`, `GpuStoreOp`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "storeOp")] pub fn set_store_op(this: &GpuRenderPassColorAttachment, val: GpuStoreOp); @@ -131,7 +131,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassColorAttachment`, `GpuTextureView`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "view")] pub fn get_view(this: &GpuRenderPassColorAttachment) -> GpuTextureView; @@ -140,7 +140,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassColorAttachment`, `GpuTextureView`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "view")] pub fn set_view(this: &GpuRenderPassColorAttachment, val: &GpuTextureView); } @@ -151,7 +151,7 @@ impl GpuRenderPassColorAttachment { #[doc = "*This API requires the following crate features to be activated: `GpuLoadOp`, `GpuRenderPassColorAttachment`, `GpuStoreOp`, `GpuTextureView`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(load_op: GpuLoadOp, store_op: GpuStoreOp, view: &GpuTextureView) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassDepthStencilAttachment.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassDepthStencilAttachment.rs index 2388dc7346e..41135ecff02 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassDepthStencilAttachment.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassDepthStencilAttachment.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDepthStencilAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuRenderPassDepthStencilAttachment; #[doc = "Get the `depthClearValue` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDepthStencilAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "depthClearValue")] pub fn get_depth_clear_value(this: &GpuRenderPassDepthStencilAttachment) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDepthStencilAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "depthClearValue")] pub fn set_depth_clear_value(this: &GpuRenderPassDepthStencilAttachment, val: f32); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuLoadOp`, `GpuRenderPassDepthStencilAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "depthLoadOp")] pub fn get_depth_load_op(this: &GpuRenderPassDepthStencilAttachment) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuLoadOp`, `GpuRenderPassDepthStencilAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "depthLoadOp")] pub fn set_depth_load_op(this: &GpuRenderPassDepthStencilAttachment, val: GpuLoadOp); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDepthStencilAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "depthReadOnly")] pub fn get_depth_read_only(this: &GpuRenderPassDepthStencilAttachment) -> Option; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDepthStencilAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "depthReadOnly")] pub fn set_depth_read_only(this: &GpuRenderPassDepthStencilAttachment, val: bool); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDepthStencilAttachment`, `GpuStoreOp`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "depthStoreOp")] pub fn get_depth_store_op(this: &GpuRenderPassDepthStencilAttachment) -> Option; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDepthStencilAttachment`, `GpuStoreOp`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "depthStoreOp")] pub fn set_depth_store_op(this: &GpuRenderPassDepthStencilAttachment, val: GpuStoreOp); @@ -113,7 +113,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDepthStencilAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "stencilClearValue")] pub fn get_stencil_clear_value(this: &GpuRenderPassDepthStencilAttachment) -> Option; @@ -122,7 +122,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDepthStencilAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "stencilClearValue")] pub fn set_stencil_clear_value(this: &GpuRenderPassDepthStencilAttachment, val: u32); @@ -131,7 +131,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuLoadOp`, `GpuRenderPassDepthStencilAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "stencilLoadOp")] pub fn get_stencil_load_op(this: &GpuRenderPassDepthStencilAttachment) -> Option; @@ -140,7 +140,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuLoadOp`, `GpuRenderPassDepthStencilAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "stencilLoadOp")] pub fn set_stencil_load_op(this: &GpuRenderPassDepthStencilAttachment, val: GpuLoadOp); @@ -149,7 +149,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDepthStencilAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "stencilReadOnly")] pub fn get_stencil_read_only(this: &GpuRenderPassDepthStencilAttachment) -> Option; @@ -158,7 +158,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDepthStencilAttachment`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "stencilReadOnly")] pub fn set_stencil_read_only(this: &GpuRenderPassDepthStencilAttachment, val: bool); @@ -167,7 +167,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDepthStencilAttachment`, `GpuStoreOp`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "stencilStoreOp")] pub fn get_stencil_store_op(this: &GpuRenderPassDepthStencilAttachment) -> Option; @@ -176,7 +176,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDepthStencilAttachment`, `GpuStoreOp`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "stencilStoreOp")] pub fn set_stencil_store_op(this: &GpuRenderPassDepthStencilAttachment, val: GpuStoreOp); @@ -185,7 +185,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDepthStencilAttachment`, `GpuTextureView`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "view")] pub fn get_view(this: &GpuRenderPassDepthStencilAttachment) -> GpuTextureView; @@ -194,7 +194,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDepthStencilAttachment`, `GpuTextureView`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "view")] pub fn set_view(this: &GpuRenderPassDepthStencilAttachment, val: &GpuTextureView); } @@ -205,7 +205,7 @@ impl GpuRenderPassDepthStencilAttachment { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDepthStencilAttachment`, `GpuTextureView`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(view: &GpuTextureView) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassDescriptor.rs index dd468147591..97cefbe36b2 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuRenderPassDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuRenderPassDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuRenderPassDescriptor, val: &str); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "colorAttachments")] pub fn get_color_attachments(this: &GpuRenderPassDescriptor) -> ::js_sys::Array; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "colorAttachments")] pub fn set_color_attachments(this: &GpuRenderPassDescriptor, val: &::wasm_bindgen::JsValue); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDepthStencilAttachment`, `GpuRenderPassDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "depthStencilAttachment")] pub fn get_depth_stencil_attachment( this: &GpuRenderPassDescriptor, @@ -88,7 +88,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDepthStencilAttachment`, `GpuRenderPassDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "depthStencilAttachment")] pub fn set_depth_stencil_attachment( this: &GpuRenderPassDescriptor, @@ -100,7 +100,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "maxDrawCount")] pub fn get_max_draw_count(this: &GpuRenderPassDescriptor) -> Option; @@ -109,7 +109,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "maxDrawCount")] pub fn set_max_draw_count(this: &GpuRenderPassDescriptor, val: f64); @@ -118,7 +118,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQuerySet`, `GpuRenderPassDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "occlusionQuerySet")] pub fn get_occlusion_query_set(this: &GpuRenderPassDescriptor) -> Option; @@ -127,7 +127,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQuerySet`, `GpuRenderPassDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "occlusionQuerySet")] pub fn set_occlusion_query_set(this: &GpuRenderPassDescriptor, val: &GpuQuerySet); @@ -136,7 +136,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDescriptor`, `GpuRenderPassTimestampWrites`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "timestampWrites")] pub fn get_timestamp_writes( this: &GpuRenderPassDescriptor, @@ -147,7 +147,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDescriptor`, `GpuRenderPassTimestampWrites`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "timestampWrites")] pub fn set_timestamp_writes(this: &GpuRenderPassDescriptor, val: &GpuRenderPassTimestampWrites); } @@ -158,7 +158,7 @@ impl GpuRenderPassDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(color_attachments: &::wasm_bindgen::JsValue) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassEncoder.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassEncoder.rs index 85049d8b03b..7de607c6303 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassEncoder.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassEncoder.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuRenderPassEncoder; # [wasm_bindgen (structural , method , getter , js_class = "GPURenderPassEncoder" , js_name = label)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuRenderPassEncoder) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPURenderPassEncoder" , js_name = label)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuRenderPassEncoder, value: &str); # [wasm_bindgen (method , structural , js_class = "GPURenderPassEncoder" , js_name = beginOcclusionQuery)] @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn begin_occlusion_query(this: &GpuRenderPassEncoder, query_index: u32); # [wasm_bindgen (method , structural , js_class = "GPURenderPassEncoder" , js_name = end)] @@ -79,7 +79,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn end(this: &GpuRenderPassEncoder); # [wasm_bindgen (method , structural , js_class = "GPURenderPassEncoder" , js_name = endOcclusionQuery)] @@ -90,7 +90,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn end_occlusion_query(this: &GpuRenderPassEncoder); # [wasm_bindgen (method , structural , js_class = "GPURenderPassEncoder" , js_name = executeBundles)] @@ -101,7 +101,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn execute_bundles(this: &GpuRenderPassEncoder, bundles: &::wasm_bindgen::JsValue); # [wasm_bindgen (catch , method , structural , js_class = "GPURenderPassEncoder" , js_name = setBlendConstant)] @@ -112,7 +112,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_blend_constant_with_f64_sequence( this: &GpuRenderPassEncoder, color: &::wasm_bindgen::JsValue, @@ -126,7 +126,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuColorDict`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_blend_constant_with_gpu_color_dict( this: &GpuRenderPassEncoder, color: &GpuColorDict, @@ -140,7 +140,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_scissor_rect(this: &GpuRenderPassEncoder, x: u32, y: u32, width: u32, height: u32); # [wasm_bindgen (method , structural , js_class = "GPURenderPassEncoder" , js_name = setStencilReference)] @@ -151,7 +151,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_stencil_reference(this: &GpuRenderPassEncoder, reference: u32); # [wasm_bindgen (method , structural , js_class = "GPURenderPassEncoder" , js_name = setViewport)] @@ -162,7 +162,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_viewport( this: &GpuRenderPassEncoder, x: f32, @@ -181,7 +181,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_bind_group( this: &GpuRenderPassEncoder, index: u32, @@ -196,7 +196,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_bind_group_with_u32_sequence( this: &GpuRenderPassEncoder, index: u32, @@ -212,7 +212,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_bind_group_with_u32_slice_and_u32_and_dynamic_offsets_data_length( this: &GpuRenderPassEncoder, index: u32, @@ -230,7 +230,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_bind_group_with_u32_array_and_u32_and_dynamic_offsets_data_length( this: &GpuRenderPassEncoder, index: u32, @@ -248,7 +248,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_bind_group_with_u32_slice_and_f64_and_dynamic_offsets_data_length( this: &GpuRenderPassEncoder, index: u32, @@ -266,7 +266,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroup`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_bind_group_with_u32_array_and_f64_and_dynamic_offsets_data_length( this: &GpuRenderPassEncoder, index: u32, @@ -284,7 +284,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn insert_debug_marker(this: &GpuRenderPassEncoder, marker_label: &str); # [wasm_bindgen (method , structural , js_class = "GPURenderPassEncoder" , js_name = popDebugGroup)] @@ -295,7 +295,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn pop_debug_group(this: &GpuRenderPassEncoder); # [wasm_bindgen (method , structural , js_class = "GPURenderPassEncoder" , js_name = pushDebugGroup)] @@ -306,7 +306,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn push_debug_group(this: &GpuRenderPassEncoder, group_label: &str); # [wasm_bindgen (method , structural , js_class = "GPURenderPassEncoder" , js_name = draw)] @@ -317,7 +317,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw(this: &GpuRenderPassEncoder, vertex_count: u32); # [wasm_bindgen (method , structural , js_class = "GPURenderPassEncoder" , js_name = draw)] @@ -328,7 +328,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_with_instance_count( this: &GpuRenderPassEncoder, vertex_count: u32, @@ -343,7 +343,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_with_instance_count_and_first_vertex( this: &GpuRenderPassEncoder, vertex_count: u32, @@ -359,7 +359,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_with_instance_count_and_first_vertex_and_first_instance( this: &GpuRenderPassEncoder, vertex_count: u32, @@ -376,7 +376,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_indexed(this: &GpuRenderPassEncoder, index_count: u32); # [wasm_bindgen (method , structural , js_class = "GPURenderPassEncoder" , js_name = drawIndexed)] @@ -387,7 +387,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_indexed_with_instance_count( this: &GpuRenderPassEncoder, index_count: u32, @@ -402,7 +402,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_indexed_with_instance_count_and_first_index( this: &GpuRenderPassEncoder, index_count: u32, @@ -418,7 +418,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_indexed_with_instance_count_and_first_index_and_base_vertex( this: &GpuRenderPassEncoder, index_count: u32, @@ -435,7 +435,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_indexed_with_instance_count_and_first_index_and_base_vertex_and_first_instance( this: &GpuRenderPassEncoder, index_count: u32, @@ -453,7 +453,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_indexed_indirect_with_u32( this: &GpuRenderPassEncoder, indirect_buffer: &GpuBuffer, @@ -468,7 +468,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_indexed_indirect_with_f64( this: &GpuRenderPassEncoder, indirect_buffer: &GpuBuffer, @@ -483,7 +483,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_indirect_with_u32( this: &GpuRenderPassEncoder, indirect_buffer: &GpuBuffer, @@ -498,7 +498,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn draw_indirect_with_f64( this: &GpuRenderPassEncoder, indirect_buffer: &GpuBuffer, @@ -513,7 +513,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuIndexFormat`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_index_buffer( this: &GpuRenderPassEncoder, buffer: &GpuBuffer, @@ -528,7 +528,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuIndexFormat`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_index_buffer_with_u32( this: &GpuRenderPassEncoder, buffer: &GpuBuffer, @@ -544,7 +544,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuIndexFormat`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_index_buffer_with_f64( this: &GpuRenderPassEncoder, buffer: &GpuBuffer, @@ -560,7 +560,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuIndexFormat`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_index_buffer_with_u32_and_u32( this: &GpuRenderPassEncoder, buffer: &GpuBuffer, @@ -577,7 +577,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuIndexFormat`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_index_buffer_with_f64_and_u32( this: &GpuRenderPassEncoder, buffer: &GpuBuffer, @@ -594,7 +594,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuIndexFormat`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_index_buffer_with_u32_and_f64( this: &GpuRenderPassEncoder, buffer: &GpuBuffer, @@ -611,7 +611,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuIndexFormat`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_index_buffer_with_f64_and_f64( this: &GpuRenderPassEncoder, buffer: &GpuBuffer, @@ -628,7 +628,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassEncoder`, `GpuRenderPipeline`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_pipeline(this: &GpuRenderPassEncoder, pipeline: &GpuRenderPipeline); # [wasm_bindgen (method , structural , js_class = "GPURenderPassEncoder" , js_name = setVertexBuffer)] @@ -639,7 +639,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_vertex_buffer(this: &GpuRenderPassEncoder, slot: u32, buffer: Option<&GpuBuffer>); # [wasm_bindgen (method , structural , js_class = "GPURenderPassEncoder" , js_name = setVertexBuffer)] @@ -650,7 +650,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_vertex_buffer_with_u32( this: &GpuRenderPassEncoder, slot: u32, @@ -666,7 +666,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_vertex_buffer_with_f64( this: &GpuRenderPassEncoder, slot: u32, @@ -682,7 +682,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_vertex_buffer_with_u32_and_u32( this: &GpuRenderPassEncoder, slot: u32, @@ -699,7 +699,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_vertex_buffer_with_f64_and_u32( this: &GpuRenderPassEncoder, slot: u32, @@ -716,7 +716,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_vertex_buffer_with_u32_and_f64( this: &GpuRenderPassEncoder, slot: u32, @@ -733,7 +733,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuRenderPassEncoder`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_vertex_buffer_with_f64_and_f64( this: &GpuRenderPassEncoder, slot: u32, diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassTimestampWrites.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassTimestampWrites.rs index 1fcad87967d..3d6b4d1ede0 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassTimestampWrites.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPassTimestampWrites.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassTimestampWrites`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuRenderPassTimestampWrites; #[doc = "Get the `beginningOfPassWriteIndex` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassTimestampWrites`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "beginningOfPassWriteIndex")] pub fn get_beginning_of_pass_write_index(this: &GpuRenderPassTimestampWrites) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassTimestampWrites`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "beginningOfPassWriteIndex")] pub fn set_beginning_of_pass_write_index(this: &GpuRenderPassTimestampWrites, val: u32); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassTimestampWrites`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "endOfPassWriteIndex")] pub fn get_end_of_pass_write_index(this: &GpuRenderPassTimestampWrites) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPassTimestampWrites`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "endOfPassWriteIndex")] pub fn set_end_of_pass_write_index(this: &GpuRenderPassTimestampWrites, val: u32); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQuerySet`, `GpuRenderPassTimestampWrites`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "querySet")] pub fn get_query_set(this: &GpuRenderPassTimestampWrites) -> GpuQuerySet; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuQuerySet`, `GpuRenderPassTimestampWrites`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "querySet")] pub fn set_query_set(this: &GpuRenderPassTimestampWrites, val: &GpuQuerySet); } @@ -97,7 +97,7 @@ impl GpuRenderPassTimestampWrites { #[doc = "*This API requires the following crate features to be activated: `GpuQuerySet`, `GpuRenderPassTimestampWrites`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(query_set: &GpuQuerySet) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPipeline.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPipeline.rs index 41663dd5d87..795bc24d1bb 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPipeline.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPipeline.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPipeline`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuRenderPipeline; # [wasm_bindgen (structural , method , getter , js_class = "GPURenderPipeline" , js_name = label)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPipeline`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuRenderPipeline) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPURenderPipeline" , js_name = label)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPipeline`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuRenderPipeline, value: &str); # [wasm_bindgen (method , structural , js_class = "GPURenderPipeline" , js_name = getBindGroupLayout)] @@ -68,6 +68,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBindGroupLayout`, `GpuRenderPipeline`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn get_bind_group_layout(this: &GpuRenderPipeline, index: u32) -> GpuBindGroupLayout; } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPipelineDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPipelineDescriptor.rs index bbf92b31fde..a0f2875b689 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPipelineDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRenderPipelineDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuRenderPipelineDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuRenderPipelineDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuRenderPipelineDescriptor, val: &str); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "layout")] pub fn get_layout(this: &GpuRenderPipelineDescriptor) -> ::wasm_bindgen::JsValue; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "layout")] pub fn set_layout(this: &GpuRenderPipelineDescriptor, val: &::wasm_bindgen::JsValue); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`, `GpuRenderPipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "depthStencil")] pub fn get_depth_stencil(this: &GpuRenderPipelineDescriptor) -> Option; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuDepthStencilState`, `GpuRenderPipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "depthStencil")] pub fn set_depth_stencil(this: &GpuRenderPipelineDescriptor, val: &GpuDepthStencilState); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuFragmentState`, `GpuRenderPipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "fragment")] pub fn get_fragment(this: &GpuRenderPipelineDescriptor) -> Option; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuFragmentState`, `GpuRenderPipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "fragment")] pub fn set_fragment(this: &GpuRenderPipelineDescriptor, val: &GpuFragmentState); @@ -113,7 +113,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuMultisampleState`, `GpuRenderPipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "multisample")] pub fn get_multisample(this: &GpuRenderPipelineDescriptor) -> Option; @@ -122,7 +122,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuMultisampleState`, `GpuRenderPipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "multisample")] pub fn set_multisample(this: &GpuRenderPipelineDescriptor, val: &GpuMultisampleState); @@ -131,7 +131,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPrimitiveState`, `GpuRenderPipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "primitive")] pub fn get_primitive(this: &GpuRenderPipelineDescriptor) -> Option; @@ -140,7 +140,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPrimitiveState`, `GpuRenderPipelineDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "primitive")] pub fn set_primitive(this: &GpuRenderPipelineDescriptor, val: &GpuPrimitiveState); @@ -149,7 +149,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPipelineDescriptor`, `GpuVertexState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "vertex")] pub fn get_vertex(this: &GpuRenderPipelineDescriptor) -> GpuVertexState; @@ -158,7 +158,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPipelineDescriptor`, `GpuVertexState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "vertex")] pub fn set_vertex(this: &GpuRenderPipelineDescriptor, val: &GpuVertexState); } @@ -169,7 +169,7 @@ impl GpuRenderPipelineDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuRenderPipelineDescriptor`, `GpuVertexState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(layout: &::wasm_bindgen::JsValue, vertex: &GpuVertexState) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRequestAdapterOptions.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRequestAdapterOptions.rs index 8c85b39787a..3543ad8e1a1 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRequestAdapterOptions.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuRequestAdapterOptions.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRequestAdapterOptions`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuRequestAdapterOptions; #[doc = "Get the `featureLevel` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRequestAdapterOptions`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "featureLevel")] pub fn get_feature_level(this: &GpuRequestAdapterOptions) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRequestAdapterOptions`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "featureLevel")] pub fn set_feature_level(this: &GpuRequestAdapterOptions, val: &str); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRequestAdapterOptions`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "forceFallbackAdapter")] pub fn get_force_fallback_adapter(this: &GpuRequestAdapterOptions) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRequestAdapterOptions`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "forceFallbackAdapter")] pub fn set_force_fallback_adapter(this: &GpuRequestAdapterOptions, val: bool); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPowerPreference`, `GpuRequestAdapterOptions`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "powerPreference")] pub fn get_power_preference(this: &GpuRequestAdapterOptions) -> Option; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuPowerPreference`, `GpuRequestAdapterOptions`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "powerPreference")] pub fn set_power_preference(this: &GpuRequestAdapterOptions, val: GpuPowerPreference); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRequestAdapterOptions`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "xrCompatible")] pub fn get_xr_compatible(this: &GpuRequestAdapterOptions) -> Option; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuRequestAdapterOptions`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "xrCompatible")] pub fn set_xr_compatible(this: &GpuRequestAdapterOptions, val: bool); } @@ -115,7 +115,7 @@ impl GpuRequestAdapterOptions { #[doc = "*This API requires the following crate features to be activated: `GpuRequestAdapterOptions`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSampler.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSampler.rs index d5e454bde68..5f88d52447d 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSampler.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSampler.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSampler`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuSampler; # [wasm_bindgen (structural , method , getter , js_class = "GPUSampler" , js_name = label)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSampler`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuSampler) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPUSampler" , js_name = label)] @@ -57,6 +57,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSampler`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuSampler, value: &str); } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSamplerBindingLayout.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSamplerBindingLayout.rs index 9647be02b5d..b14f2901460 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSamplerBindingLayout.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSamplerBindingLayout.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSamplerBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuSamplerBindingLayout; #[doc = "Get the `type` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSamplerBindingLayout`, `GpuSamplerBindingType`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "type")] pub fn get_type(this: &GpuSamplerBindingLayout) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSamplerBindingLayout`, `GpuSamplerBindingType`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "type")] pub fn set_type(this: &GpuSamplerBindingLayout, val: GpuSamplerBindingType); } @@ -61,7 +61,7 @@ impl GpuSamplerBindingLayout { #[doc = "*This API requires the following crate features to be activated: `GpuSamplerBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSamplerBindingType.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSamplerBindingType.rs index e65aa1b7a62..6cebb038632 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSamplerBindingType.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSamplerBindingType.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuSamplerBindingType`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuSamplerBindingType { Filtering = "filtering", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSamplerDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSamplerDescriptor.rs index bd679b734f4..3cb3237dd03 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSamplerDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSamplerDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuSamplerDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuSamplerDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuSamplerDescriptor, val: &str); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuAddressMode`, `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "addressModeU")] pub fn get_address_mode_u(this: &GpuSamplerDescriptor) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuAddressMode`, `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "addressModeU")] pub fn set_address_mode_u(this: &GpuSamplerDescriptor, val: GpuAddressMode); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuAddressMode`, `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "addressModeV")] pub fn get_address_mode_v(this: &GpuSamplerDescriptor) -> Option; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuAddressMode`, `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "addressModeV")] pub fn set_address_mode_v(this: &GpuSamplerDescriptor, val: GpuAddressMode); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuAddressMode`, `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "addressModeW")] pub fn get_address_mode_w(this: &GpuSamplerDescriptor) -> Option; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuAddressMode`, `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "addressModeW")] pub fn set_address_mode_w(this: &GpuSamplerDescriptor, val: GpuAddressMode); @@ -113,7 +113,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCompareFunction`, `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "compare")] pub fn get_compare(this: &GpuSamplerDescriptor) -> Option; @@ -122,7 +122,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCompareFunction`, `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "compare")] pub fn set_compare(this: &GpuSamplerDescriptor, val: GpuCompareFunction); @@ -131,7 +131,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "lodMaxClamp")] pub fn get_lod_max_clamp(this: &GpuSamplerDescriptor) -> Option; @@ -140,7 +140,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "lodMaxClamp")] pub fn set_lod_max_clamp(this: &GpuSamplerDescriptor, val: f32); @@ -149,7 +149,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "lodMinClamp")] pub fn get_lod_min_clamp(this: &GpuSamplerDescriptor) -> Option; @@ -158,7 +158,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "lodMinClamp")] pub fn set_lod_min_clamp(this: &GpuSamplerDescriptor, val: f32); @@ -167,7 +167,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuFilterMode`, `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "magFilter")] pub fn get_mag_filter(this: &GpuSamplerDescriptor) -> Option; @@ -176,7 +176,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuFilterMode`, `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "magFilter")] pub fn set_mag_filter(this: &GpuSamplerDescriptor, val: GpuFilterMode); @@ -185,7 +185,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "maxAnisotropy")] pub fn get_max_anisotropy(this: &GpuSamplerDescriptor) -> Option; @@ -194,7 +194,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "maxAnisotropy")] pub fn set_max_anisotropy(this: &GpuSamplerDescriptor, val: u16); @@ -203,7 +203,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuFilterMode`, `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "minFilter")] pub fn get_min_filter(this: &GpuSamplerDescriptor) -> Option; @@ -212,7 +212,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuFilterMode`, `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "minFilter")] pub fn set_min_filter(this: &GpuSamplerDescriptor, val: GpuFilterMode); @@ -221,7 +221,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuMipmapFilterMode`, `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "mipmapFilter")] pub fn get_mipmap_filter(this: &GpuSamplerDescriptor) -> Option; @@ -230,7 +230,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuMipmapFilterMode`, `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "mipmapFilter")] pub fn set_mipmap_filter(this: &GpuSamplerDescriptor, val: GpuMipmapFilterMode); } @@ -241,7 +241,7 @@ impl GpuSamplerDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuSamplerDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuShaderModule.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuShaderModule.rs index 316a9b2fac4..bbebbb42615 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuShaderModule.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuShaderModule.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuShaderModule`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuShaderModule; # [wasm_bindgen (structural , method , getter , js_class = "GPUShaderModule" , js_name = label)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuShaderModule`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuShaderModule) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPUShaderModule" , js_name = label)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuShaderModule`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuShaderModule, value: &str); # [wasm_bindgen (method , structural , js_class = "GPUShaderModule" , js_name = getCompilationInfo)] @@ -68,6 +68,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuShaderModule`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn get_compilation_info(this: &GpuShaderModule) -> ::js_sys::Promise; } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuShaderModuleDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuShaderModuleDescriptor.rs index 89fac0382fa..e0d08610fa3 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuShaderModuleDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuShaderModuleDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuShaderModuleDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuShaderModuleDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuShaderModuleDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuShaderModuleDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuShaderModuleDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuShaderModuleDescriptor, val: &str); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuShaderModuleDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "code")] pub fn get_code(this: &GpuShaderModuleDescriptor) -> ::alloc::string::String; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuShaderModuleDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "code")] pub fn set_code(this: &GpuShaderModuleDescriptor, val: &str); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuShaderModuleDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "compilationHints")] pub fn get_compilation_hints(this: &GpuShaderModuleDescriptor) -> Option<::js_sys::Array>; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuShaderModuleDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "compilationHints")] pub fn set_compilation_hints(this: &GpuShaderModuleDescriptor, val: &::wasm_bindgen::JsValue); } @@ -97,7 +97,7 @@ impl GpuShaderModuleDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuShaderModuleDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(code: &str) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStencilFaceState.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStencilFaceState.rs index 709481e9052..96fedd785d6 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStencilFaceState.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStencilFaceState.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuStencilFaceState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuStencilFaceState; #[doc = "Get the `compare` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCompareFunction`, `GpuStencilFaceState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "compare")] pub fn get_compare(this: &GpuStencilFaceState) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuCompareFunction`, `GpuStencilFaceState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "compare")] pub fn set_compare(this: &GpuStencilFaceState, val: GpuCompareFunction); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuStencilFaceState`, `GpuStencilOperation`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "depthFailOp")] pub fn get_depth_fail_op(this: &GpuStencilFaceState) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuStencilFaceState`, `GpuStencilOperation`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "depthFailOp")] pub fn set_depth_fail_op(this: &GpuStencilFaceState, val: GpuStencilOperation); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuStencilFaceState`, `GpuStencilOperation`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "failOp")] pub fn get_fail_op(this: &GpuStencilFaceState) -> Option; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuStencilFaceState`, `GpuStencilOperation`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "failOp")] pub fn set_fail_op(this: &GpuStencilFaceState, val: GpuStencilOperation); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuStencilFaceState`, `GpuStencilOperation`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "passOp")] pub fn get_pass_op(this: &GpuStencilFaceState) -> Option; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuStencilFaceState`, `GpuStencilOperation`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "passOp")] pub fn set_pass_op(this: &GpuStencilFaceState, val: GpuStencilOperation); } @@ -115,7 +115,7 @@ impl GpuStencilFaceState { #[doc = "*This API requires the following crate features to be activated: `GpuStencilFaceState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStencilOperation.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStencilOperation.rs index 088478779de..f5137d89218 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStencilOperation.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStencilOperation.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuStencilOperation`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuStencilOperation { Keep = "keep", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStorageTextureAccess.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStorageTextureAccess.rs index 696c57751bb..43499d6df2f 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStorageTextureAccess.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStorageTextureAccess.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuStorageTextureAccess`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuStorageTextureAccess { WriteOnly = "write-only", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStorageTextureBindingLayout.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStorageTextureBindingLayout.rs index a65a5463531..f694316e112 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStorageTextureBindingLayout.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStorageTextureBindingLayout.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuStorageTextureBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuStorageTextureBindingLayout; #[doc = "Get the `access` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuStorageTextureAccess`, `GpuStorageTextureBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "access")] pub fn get_access(this: &GpuStorageTextureBindingLayout) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuStorageTextureAccess`, `GpuStorageTextureBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "access")] pub fn set_access(this: &GpuStorageTextureBindingLayout, val: GpuStorageTextureAccess); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuStorageTextureBindingLayout`, `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "format")] pub fn get_format(this: &GpuStorageTextureBindingLayout) -> GpuTextureFormat; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuStorageTextureBindingLayout`, `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "format")] pub fn set_format(this: &GpuStorageTextureBindingLayout, val: GpuTextureFormat); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuStorageTextureBindingLayout`, `GpuTextureViewDimension`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "viewDimension")] pub fn get_view_dimension( this: &GpuStorageTextureBindingLayout, @@ -88,7 +88,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuStorageTextureBindingLayout`, `GpuTextureViewDimension`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "viewDimension")] pub fn set_view_dimension(this: &GpuStorageTextureBindingLayout, val: GpuTextureViewDimension); } @@ -99,7 +99,7 @@ impl GpuStorageTextureBindingLayout { #[doc = "*This API requires the following crate features to be activated: `GpuStorageTextureBindingLayout`, `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(format: GpuTextureFormat) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStoreOp.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStoreOp.rs index 5271f6f253f..f32edb3f926 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStoreOp.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuStoreOp.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuStoreOp`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuStoreOp { Store = "store", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSupportedFeatures.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSupportedFeatures.rs index 78e155085ed..fc70e2f1709 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSupportedFeatures.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSupportedFeatures.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedFeatures`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuSupportedFeatures; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedFeatures" , js_name = size)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedFeatures`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn size(this: &GpuSupportedFeatures) -> u32; # [wasm_bindgen (method , structural , js_class = "GPUSupportedFeatures" , js_name = entries)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedFeatures`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn entries(this: &GpuSupportedFeatures) -> ::js_sys::Iterator; # [wasm_bindgen (catch , method , structural , js_class = "GPUSupportedFeatures" , js_name = forEach)] @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedFeatures`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn for_each( this: &GpuSupportedFeatures, callback: &::js_sys::Function, @@ -82,7 +82,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedFeatures`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn has(this: &GpuSupportedFeatures, value: &str) -> bool; # [wasm_bindgen (method , structural , js_class = "GPUSupportedFeatures" , js_name = keys)] @@ -93,7 +93,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedFeatures`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn keys(this: &GpuSupportedFeatures) -> ::js_sys::Iterator; # [wasm_bindgen (method , structural , js_class = "GPUSupportedFeatures" , js_name = values)] @@ -104,6 +104,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedFeatures`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn values(this: &GpuSupportedFeatures) -> ::js_sys::Iterator; } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSupportedLimits.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSupportedLimits.rs index b123896acb1..8323fe6e2fc 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSupportedLimits.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuSupportedLimits.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuSupportedLimits; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxTextureDimension1D)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_texture_dimension_1d(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxTextureDimension2D)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_texture_dimension_2d(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxTextureDimension3D)] @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_texture_dimension_3d(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxTextureArrayLayers)] @@ -79,7 +79,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_texture_array_layers(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxBindGroups)] @@ -90,7 +90,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_bind_groups(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxBindGroupsPlusVertexBuffers)] @@ -101,7 +101,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_bind_groups_plus_vertex_buffers(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxBindingsPerBindGroup)] @@ -112,7 +112,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_bindings_per_bind_group(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxDynamicUniformBuffersPerPipelineLayout)] @@ -123,7 +123,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_dynamic_uniform_buffers_per_pipeline_layout(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxDynamicStorageBuffersPerPipelineLayout)] @@ -134,7 +134,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_dynamic_storage_buffers_per_pipeline_layout(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxSampledTexturesPerShaderStage)] @@ -145,7 +145,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_sampled_textures_per_shader_stage(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxSamplersPerShaderStage)] @@ -156,7 +156,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_samplers_per_shader_stage(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxStorageBuffersPerShaderStage)] @@ -167,7 +167,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_storage_buffers_per_shader_stage(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxStorageTexturesPerShaderStage)] @@ -178,7 +178,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_storage_textures_per_shader_stage(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxUniformBuffersPerShaderStage)] @@ -189,7 +189,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_uniform_buffers_per_shader_stage(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxUniformBufferBindingSize)] @@ -200,7 +200,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_uniform_buffer_binding_size(this: &GpuSupportedLimits) -> f64; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxStorageBufferBindingSize)] @@ -211,7 +211,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_storage_buffer_binding_size(this: &GpuSupportedLimits) -> f64; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = minUniformBufferOffsetAlignment)] @@ -222,7 +222,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn min_uniform_buffer_offset_alignment(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = minStorageBufferOffsetAlignment)] @@ -233,7 +233,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn min_storage_buffer_offset_alignment(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxVertexBuffers)] @@ -244,7 +244,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_vertex_buffers(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxBufferSize)] @@ -255,7 +255,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_buffer_size(this: &GpuSupportedLimits) -> f64; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxVertexAttributes)] @@ -266,7 +266,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_vertex_attributes(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxVertexBufferArrayStride)] @@ -277,7 +277,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_vertex_buffer_array_stride(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxInterStageShaderVariables)] @@ -288,7 +288,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_inter_stage_shader_variables(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxColorAttachments)] @@ -299,7 +299,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_color_attachments(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxColorAttachmentBytesPerSample)] @@ -310,7 +310,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_color_attachment_bytes_per_sample(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxComputeWorkgroupStorageSize)] @@ -321,7 +321,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_compute_workgroup_storage_size(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxComputeInvocationsPerWorkgroup)] @@ -332,7 +332,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_compute_invocations_per_workgroup(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxComputeWorkgroupSizeX)] @@ -343,7 +343,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_compute_workgroup_size_x(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxComputeWorkgroupSizeY)] @@ -354,7 +354,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_compute_workgroup_size_y(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxComputeWorkgroupSizeZ)] @@ -365,7 +365,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_compute_workgroup_size_z(this: &GpuSupportedLimits) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUSupportedLimits" , js_name = maxComputeWorkgroupsPerDimension)] @@ -376,6 +376,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuSupportedLimits`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn max_compute_workgroups_per_dimension(this: &GpuSupportedLimits) -> u32; } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTexelCopyBufferInfo.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTexelCopyBufferInfo.rs index 64e2fb8ed68..dad3f24b2eb 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTexelCopyBufferInfo.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTexelCopyBufferInfo.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyBufferInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuTexelCopyBufferInfo; #[doc = "Get the `bytesPerRow` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyBufferInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "bytesPerRow")] pub fn get_bytes_per_row(this: &GpuTexelCopyBufferInfo) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyBufferInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "bytesPerRow")] pub fn set_bytes_per_row(this: &GpuTexelCopyBufferInfo, val: u32); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyBufferInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "offset")] pub fn get_offset(this: &GpuTexelCopyBufferInfo) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyBufferInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "offset")] pub fn set_offset(this: &GpuTexelCopyBufferInfo, val: f64); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyBufferInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "rowsPerImage")] pub fn get_rows_per_image(this: &GpuTexelCopyBufferInfo) -> Option; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyBufferInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "rowsPerImage")] pub fn set_rows_per_image(this: &GpuTexelCopyBufferInfo, val: u32); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuTexelCopyBufferInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "buffer")] pub fn get_buffer(this: &GpuTexelCopyBufferInfo) -> GpuBuffer; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuTexelCopyBufferInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "buffer")] pub fn set_buffer(this: &GpuTexelCopyBufferInfo, val: &GpuBuffer); } @@ -115,7 +115,7 @@ impl GpuTexelCopyBufferInfo { #[doc = "*This API requires the following crate features to be activated: `GpuBuffer`, `GpuTexelCopyBufferInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(buffer: &GpuBuffer) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTexelCopyBufferLayout.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTexelCopyBufferLayout.rs index d82a124e26a..26f9a4f3c3f 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTexelCopyBufferLayout.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTexelCopyBufferLayout.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyBufferLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuTexelCopyBufferLayout; #[doc = "Get the `bytesPerRow` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyBufferLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "bytesPerRow")] pub fn get_bytes_per_row(this: &GpuTexelCopyBufferLayout) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyBufferLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "bytesPerRow")] pub fn set_bytes_per_row(this: &GpuTexelCopyBufferLayout, val: u32); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyBufferLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "offset")] pub fn get_offset(this: &GpuTexelCopyBufferLayout) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyBufferLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "offset")] pub fn set_offset(this: &GpuTexelCopyBufferLayout, val: f64); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyBufferLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "rowsPerImage")] pub fn get_rows_per_image(this: &GpuTexelCopyBufferLayout) -> Option; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyBufferLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "rowsPerImage")] pub fn set_rows_per_image(this: &GpuTexelCopyBufferLayout, val: u32); } @@ -97,7 +97,7 @@ impl GpuTexelCopyBufferLayout { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyBufferLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTexelCopyTextureInfo.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTexelCopyTextureInfo.rs index 651ff52b523..e948503de50 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTexelCopyTextureInfo.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTexelCopyTextureInfo.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyTextureInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuTexelCopyTextureInfo; #[doc = "Get the `aspect` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyTextureInfo`, `GpuTextureAspect`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "aspect")] pub fn get_aspect(this: &GpuTexelCopyTextureInfo) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyTextureInfo`, `GpuTextureAspect`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "aspect")] pub fn set_aspect(this: &GpuTexelCopyTextureInfo, val: GpuTextureAspect); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyTextureInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "mipLevel")] pub fn get_mip_level(this: &GpuTexelCopyTextureInfo) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyTextureInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "mipLevel")] pub fn set_mip_level(this: &GpuTexelCopyTextureInfo, val: u32); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyTextureInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "origin")] pub fn get_origin(this: &GpuTexelCopyTextureInfo) -> ::wasm_bindgen::JsValue; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyTextureInfo`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "origin")] pub fn set_origin(this: &GpuTexelCopyTextureInfo, val: &::wasm_bindgen::JsValue); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyTextureInfo`, `GpuTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "texture")] pub fn get_texture(this: &GpuTexelCopyTextureInfo) -> GpuTexture; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyTextureInfo`, `GpuTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "texture")] pub fn set_texture(this: &GpuTexelCopyTextureInfo, val: &GpuTexture); } @@ -115,7 +115,7 @@ impl GpuTexelCopyTextureInfo { #[doc = "*This API requires the following crate features to be activated: `GpuTexelCopyTextureInfo`, `GpuTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(texture: &GpuTexture) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTexture.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTexture.rs index e8bb664ab08..20c3eb8cb66 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTexture.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTexture.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuTexture; # [wasm_bindgen (structural , method , getter , js_class = "GPUTexture" , js_name = width)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn width(this: &GpuTexture) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUTexture" , js_name = height)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn height(this: &GpuTexture) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUTexture" , js_name = depthOrArrayLayers)] @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn depth_or_array_layers(this: &GpuTexture) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUTexture" , js_name = mipLevelCount)] @@ -79,7 +79,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn mip_level_count(this: &GpuTexture) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUTexture" , js_name = sampleCount)] @@ -90,7 +90,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn sample_count(this: &GpuTexture) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUTexture" , js_name = dimension)] @@ -101,7 +101,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexture`, `GpuTextureDimension`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn dimension(this: &GpuTexture) -> GpuTextureDimension; # [wasm_bindgen (structural , method , getter , js_class = "GPUTexture" , js_name = format)] @@ -112,7 +112,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexture`, `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn format(this: &GpuTexture) -> GpuTextureFormat; # [wasm_bindgen (structural , method , getter , js_class = "GPUTexture" , js_name = usage)] @@ -123,7 +123,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn usage(this: &GpuTexture) -> u32; # [wasm_bindgen (structural , method , getter , js_class = "GPUTexture" , js_name = label)] @@ -134,7 +134,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuTexture) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPUTexture" , js_name = label)] @@ -145,7 +145,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuTexture, value: &str); # [wasm_bindgen (catch , method , structural , js_class = "GPUTexture" , js_name = createView)] @@ -156,7 +156,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexture`, `GpuTextureView`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn create_view(this: &GpuTexture) -> Result; # [wasm_bindgen (catch , method , structural , js_class = "GPUTexture" , js_name = createView)] @@ -167,7 +167,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexture`, `GpuTextureView`, `GpuTextureViewDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn create_view_with_descriptor( this: &GpuTexture, descriptor: &GpuTextureViewDescriptor, @@ -181,6 +181,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTexture`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn destroy(this: &GpuTexture); } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureAspect.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureAspect.rs index 99552772bfa..c8d7739b80a 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureAspect.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureAspect.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuTextureAspect`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuTextureAspect { All = "all", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureBindingLayout.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureBindingLayout.rs index 4030eeb2387..2a7bd017c37 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureBindingLayout.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureBindingLayout.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuTextureBindingLayout; #[doc = "Get the `multisampled` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "multisampled")] pub fn get_multisampled(this: &GpuTextureBindingLayout) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "multisampled")] pub fn set_multisampled(this: &GpuTextureBindingLayout, val: bool); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureBindingLayout`, `GpuTextureSampleType`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "sampleType")] pub fn get_sample_type(this: &GpuTextureBindingLayout) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureBindingLayout`, `GpuTextureSampleType`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "sampleType")] pub fn set_sample_type(this: &GpuTextureBindingLayout, val: GpuTextureSampleType); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureBindingLayout`, `GpuTextureViewDimension`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "viewDimension")] pub fn get_view_dimension(this: &GpuTextureBindingLayout) -> Option; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureBindingLayout`, `GpuTextureViewDimension`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "viewDimension")] pub fn set_view_dimension(this: &GpuTextureBindingLayout, val: GpuTextureViewDimension); } @@ -97,7 +97,7 @@ impl GpuTextureBindingLayout { #[doc = "*This API requires the following crate features to be activated: `GpuTextureBindingLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureDescriptor.rs index 92911d4c64f..dc6be01757b 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuTextureDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuTextureDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuTextureDescriptor, val: &str); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureDescriptor`, `GpuTextureDimension`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "dimension")] pub fn get_dimension(this: &GpuTextureDescriptor) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureDescriptor`, `GpuTextureDimension`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "dimension")] pub fn set_dimension(this: &GpuTextureDescriptor, val: GpuTextureDimension); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureDescriptor`, `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "format")] pub fn get_format(this: &GpuTextureDescriptor) -> GpuTextureFormat; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureDescriptor`, `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "format")] pub fn set_format(this: &GpuTextureDescriptor, val: GpuTextureFormat); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "mipLevelCount")] pub fn get_mip_level_count(this: &GpuTextureDescriptor) -> Option; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "mipLevelCount")] pub fn set_mip_level_count(this: &GpuTextureDescriptor, val: u32); @@ -113,7 +113,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "sampleCount")] pub fn get_sample_count(this: &GpuTextureDescriptor) -> Option; @@ -122,7 +122,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "sampleCount")] pub fn set_sample_count(this: &GpuTextureDescriptor, val: u32); @@ -131,7 +131,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "size")] pub fn get_size(this: &GpuTextureDescriptor) -> ::wasm_bindgen::JsValue; @@ -140,7 +140,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "size")] pub fn set_size(this: &GpuTextureDescriptor, val: &::wasm_bindgen::JsValue); @@ -149,7 +149,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "usage")] pub fn get_usage(this: &GpuTextureDescriptor) -> u32; @@ -158,7 +158,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "usage")] pub fn set_usage(this: &GpuTextureDescriptor, val: u32); @@ -167,7 +167,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "viewFormats")] pub fn get_view_formats(this: &GpuTextureDescriptor) -> Option<::js_sys::Array>; @@ -176,7 +176,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "viewFormats")] pub fn set_view_formats(this: &GpuTextureDescriptor, val: &::wasm_bindgen::JsValue); } @@ -187,7 +187,7 @@ impl GpuTextureDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuTextureDescriptor`, `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(format: GpuTextureFormat, size: &::wasm_bindgen::JsValue, usage: u32) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureDimension.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureDimension.rs index 752dafb0d87..d860c9d13ba 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureDimension.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureDimension.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuTextureDimension`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuTextureDimension { N1d = "1d", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureFormat.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureFormat.rs index 97f93dc97bc..c861a82fc39 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureFormat.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureFormat.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuTextureFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuTextureFormat { R8unorm = "r8unorm", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureSampleType.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureSampleType.rs index e36b12218d1..04fdb2e3bfe 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureSampleType.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureSampleType.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuTextureSampleType`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuTextureSampleType { Float = "float", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureView.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureView.rs index 3b2cd03b9d4..6ece2949867 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureView.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureView.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureView`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuTextureView; # [wasm_bindgen (structural , method , getter , js_class = "GPUTextureView" , js_name = label)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureView`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn label(this: &GpuTextureView) -> ::alloc::string::String; # [wasm_bindgen (structural , method , setter , js_class = "GPUTextureView" , js_name = label)] @@ -57,6 +57,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureView`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn set_label(this: &GpuTextureView, value: &str); } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureViewDescriptor.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureViewDescriptor.rs index 57d08f4ddc2..49c642d31e8 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureViewDescriptor.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureViewDescriptor.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureViewDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuTextureViewDescriptor; #[doc = "Get the `label` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureViewDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "label")] pub fn get_label(this: &GpuTextureViewDescriptor) -> Option<::alloc::string::String>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureViewDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "label")] pub fn set_label(this: &GpuTextureViewDescriptor, val: &str); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureViewDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "arrayLayerCount")] pub fn get_array_layer_count(this: &GpuTextureViewDescriptor) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureViewDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "arrayLayerCount")] pub fn set_array_layer_count(this: &GpuTextureViewDescriptor, val: u32); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureAspect`, `GpuTextureViewDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "aspect")] pub fn get_aspect(this: &GpuTextureViewDescriptor) -> Option; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureAspect`, `GpuTextureViewDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "aspect")] pub fn set_aspect(this: &GpuTextureViewDescriptor, val: GpuTextureAspect); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureViewDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "baseArrayLayer")] pub fn get_base_array_layer(this: &GpuTextureViewDescriptor) -> Option; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureViewDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "baseArrayLayer")] pub fn set_base_array_layer(this: &GpuTextureViewDescriptor, val: u32); @@ -113,7 +113,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureViewDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "baseMipLevel")] pub fn get_base_mip_level(this: &GpuTextureViewDescriptor) -> Option; @@ -122,7 +122,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureViewDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "baseMipLevel")] pub fn set_base_mip_level(this: &GpuTextureViewDescriptor, val: u32); @@ -131,7 +131,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureViewDescriptor`, `GpuTextureViewDimension`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "dimension")] pub fn get_dimension(this: &GpuTextureViewDescriptor) -> Option; @@ -140,7 +140,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureViewDescriptor`, `GpuTextureViewDimension`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "dimension")] pub fn set_dimension(this: &GpuTextureViewDescriptor, val: GpuTextureViewDimension); @@ -149,7 +149,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureFormat`, `GpuTextureViewDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "format")] pub fn get_format(this: &GpuTextureViewDescriptor) -> Option; @@ -158,7 +158,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureFormat`, `GpuTextureViewDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "format")] pub fn set_format(this: &GpuTextureViewDescriptor, val: GpuTextureFormat); @@ -167,7 +167,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureViewDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "mipLevelCount")] pub fn get_mip_level_count(this: &GpuTextureViewDescriptor) -> Option; @@ -176,7 +176,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureViewDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "mipLevelCount")] pub fn set_mip_level_count(this: &GpuTextureViewDescriptor, val: u32); @@ -185,7 +185,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureViewDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "usage")] pub fn get_usage(this: &GpuTextureViewDescriptor) -> Option; @@ -194,7 +194,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuTextureViewDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "usage")] pub fn set_usage(this: &GpuTextureViewDescriptor, val: u32); } @@ -205,7 +205,7 @@ impl GpuTextureViewDescriptor { #[doc = "*This API requires the following crate features to be activated: `GpuTextureViewDescriptor`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new() -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureViewDimension.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureViewDimension.rs index 4e0541a2536..57ccb0360a2 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureViewDimension.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuTextureViewDimension.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuTextureViewDimension`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuTextureViewDimension { N1d = "1d", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuUncapturedErrorEvent.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuUncapturedErrorEvent.rs index a07199e298e..a59f1dbe0a1 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuUncapturedErrorEvent.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuUncapturedErrorEvent.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuUncapturedErrorEvent`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuUncapturedErrorEvent; # [wasm_bindgen (structural , method , getter , js_class = "GPUUncapturedErrorEvent" , js_name = error)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuError`, `GpuUncapturedErrorEvent`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn error(this: &GpuUncapturedErrorEvent) -> GpuError; #[wasm_bindgen(catch, constructor, js_class = "GPUUncapturedErrorEvent")] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuUncapturedErrorEvent`, `GpuUncapturedErrorEventInit`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new( type_: &str, gpu_uncaptured_error_event_init_dict: &GpuUncapturedErrorEventInit, diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuUncapturedErrorEventInit.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuUncapturedErrorEventInit.rs index 8b6814dab23..32597521eac 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuUncapturedErrorEventInit.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuUncapturedErrorEventInit.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuUncapturedErrorEventInit`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuUncapturedErrorEventInit; #[doc = "Get the `bubbles` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuUncapturedErrorEventInit`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "bubbles")] pub fn get_bubbles(this: &GpuUncapturedErrorEventInit) -> Option; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuUncapturedErrorEventInit`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "bubbles")] pub fn set_bubbles(this: &GpuUncapturedErrorEventInit, val: bool); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuUncapturedErrorEventInit`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "cancelable")] pub fn get_cancelable(this: &GpuUncapturedErrorEventInit) -> Option; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuUncapturedErrorEventInit`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "cancelable")] pub fn set_cancelable(this: &GpuUncapturedErrorEventInit, val: bool); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuUncapturedErrorEventInit`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "composed")] pub fn get_composed(this: &GpuUncapturedErrorEventInit) -> Option; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuUncapturedErrorEventInit`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "composed")] pub fn set_composed(this: &GpuUncapturedErrorEventInit, val: bool); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuError`, `GpuUncapturedErrorEventInit`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "error")] pub fn get_error(this: &GpuUncapturedErrorEventInit) -> GpuError; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuError`, `GpuUncapturedErrorEventInit`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "error")] pub fn set_error(this: &GpuUncapturedErrorEventInit, val: &GpuError); } @@ -115,7 +115,7 @@ impl GpuUncapturedErrorEventInit { #[doc = "*This API requires the following crate features to be activated: `GpuError`, `GpuUncapturedErrorEventInit`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(error: &GpuError) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuValidationError.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuValidationError.rs index 8ffde5cc523..f29b3b86171 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuValidationError.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuValidationError.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuValidationError`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuValidationError; #[wasm_bindgen(catch, constructor, js_class = "GPUValidationError")] @@ -46,6 +46,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuValidationError`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(message: &str) -> Result; } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexAttribute.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexAttribute.rs index 8fba1994b53..298b213401e 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexAttribute.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexAttribute.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexAttribute`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuVertexAttribute; #[doc = "Get the `format` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexAttribute`, `GpuVertexFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "format")] pub fn get_format(this: &GpuVertexAttribute) -> GpuVertexFormat; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexAttribute`, `GpuVertexFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "format")] pub fn set_format(this: &GpuVertexAttribute, val: GpuVertexFormat); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexAttribute`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "offset")] pub fn get_offset(this: &GpuVertexAttribute) -> f64; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexAttribute`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "offset")] pub fn set_offset(this: &GpuVertexAttribute, val: f64); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexAttribute`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "shaderLocation")] pub fn get_shader_location(this: &GpuVertexAttribute) -> u32; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexAttribute`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "shaderLocation")] pub fn set_shader_location(this: &GpuVertexAttribute, val: u32); } @@ -97,7 +97,7 @@ impl GpuVertexAttribute { #[doc = "*This API requires the following crate features to be activated: `GpuVertexAttribute`, `GpuVertexFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(format: GpuVertexFormat, offset: f64, shader_location: u32) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexBufferLayout.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexBufferLayout.rs index bfde1500141..9ebf3e6ecb1 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexBufferLayout.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexBufferLayout.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexBufferLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuVertexBufferLayout; #[doc = "Get the `arrayStride` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexBufferLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "arrayStride")] pub fn get_array_stride(this: &GpuVertexBufferLayout) -> f64; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexBufferLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "arrayStride")] pub fn set_array_stride(this: &GpuVertexBufferLayout, val: f64); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexBufferLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "attributes")] pub fn get_attributes(this: &GpuVertexBufferLayout) -> ::js_sys::Array; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexBufferLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "attributes")] pub fn set_attributes(this: &GpuVertexBufferLayout, val: &::wasm_bindgen::JsValue); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexBufferLayout`, `GpuVertexStepMode`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "stepMode")] pub fn get_step_mode(this: &GpuVertexBufferLayout) -> Option; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexBufferLayout`, `GpuVertexStepMode`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "stepMode")] pub fn set_step_mode(this: &GpuVertexBufferLayout, val: GpuVertexStepMode); } @@ -97,7 +97,7 @@ impl GpuVertexBufferLayout { #[doc = "*This API requires the following crate features to be activated: `GpuVertexBufferLayout`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(array_stride: f64, attributes: &::wasm_bindgen::JsValue) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexFormat.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexFormat.rs index baf6b50daae..167c67a6062 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexFormat.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexFormat.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuVertexFormat`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuVertexFormat { Uint8 = "uint8", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexState.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexState.rs index 5c2e76dd365..a60ef9e6bb4 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexState.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexState.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -33,7 +33,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type GpuVertexState; #[doc = "Get the `constants` field of this object."] @@ -41,7 +41,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "constants")] pub fn get_constants(this: &GpuVertexState) -> Option<::js_sys::Object>; @@ -50,7 +50,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "constants")] pub fn set_constants(this: &GpuVertexState, val: &::js_sys::Object); @@ -59,7 +59,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "entryPoint")] pub fn get_entry_point(this: &GpuVertexState) -> Option<::alloc::string::String>; @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "entryPoint")] pub fn set_entry_point(this: &GpuVertexState, val: &str); @@ -77,7 +77,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuShaderModule`, `GpuVertexState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "module")] pub fn get_module(this: &GpuVertexState) -> GpuShaderModule; @@ -86,7 +86,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuShaderModule`, `GpuVertexState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "module")] pub fn set_module(this: &GpuVertexState, val: &GpuShaderModule); @@ -95,7 +95,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, getter = "buffers")] pub fn get_buffers(this: &GpuVertexState) -> Option<::js_sys::Array>; @@ -104,7 +104,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `GpuVertexState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[wasm_bindgen(method, setter = "buffers")] pub fn set_buffers(this: &GpuVertexState, val: &::wasm_bindgen::JsValue); } @@ -115,7 +115,7 @@ impl GpuVertexState { #[doc = "*This API requires the following crate features to be activated: `GpuShaderModule`, `GpuVertexState`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn new(module: &GpuShaderModule) -> Self { #[allow(unused_mut)] let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(::js_sys::Object::new()); diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexStepMode.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexStepMode.rs index a3c9c8a42b0..29a0b857b23 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexStepMode.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_GpuVertexStepMode.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use wasm_bindgen::prelude::*; @@ -29,7 +29,7 @@ use wasm_bindgen::prelude::*; #[doc = "*This API requires the following crate features to be activated: `GpuVertexStepMode`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GpuVertexStepMode { Vertex = "vertex", diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_WgslLanguageFeatures.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_WgslLanguageFeatures.rs index 7aa26f7daaa..d6fe55d0c7b 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_WgslLanguageFeatures.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_WgslLanguageFeatures.rs @@ -16,9 +16,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports)] #![allow(clippy::all)] use super::*; @@ -35,7 +35,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `WgslLanguageFeatures`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub type WgslLanguageFeatures; # [wasm_bindgen (structural , method , getter , js_class = "WGSLLanguageFeatures" , js_name = size)] @@ -46,7 +46,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `WgslLanguageFeatures`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn size(this: &WgslLanguageFeatures) -> u32; # [wasm_bindgen (method , structural , js_class = "WGSLLanguageFeatures" , js_name = entries)] @@ -57,7 +57,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `WgslLanguageFeatures`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn entries(this: &WgslLanguageFeatures) -> ::js_sys::Iterator; # [wasm_bindgen (catch , method , structural , js_class = "WGSLLanguageFeatures" , js_name = forEach)] @@ -68,7 +68,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `WgslLanguageFeatures`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn for_each( this: &WgslLanguageFeatures, callback: &::js_sys::Function, @@ -82,7 +82,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `WgslLanguageFeatures`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn has(this: &WgslLanguageFeatures, value: &str) -> bool; # [wasm_bindgen (method , structural , js_class = "WGSLLanguageFeatures" , js_name = keys)] @@ -93,7 +93,7 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `WgslLanguageFeatures`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn keys(this: &WgslLanguageFeatures) -> ::js_sys::Iterator; # [wasm_bindgen (method , structural , js_class = "WGSLLanguageFeatures" , js_name = values)] @@ -104,6 +104,6 @@ extern "C" { #[doc = "*This API requires the following crate features to be activated: `WgslLanguageFeatures`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub fn values(this: &WgslLanguageFeatures) -> ::js_sys::Iterator; } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/gen_gpu_map_mode.rs b/wgpu/src/backend/webgpu/webgpu_sys/gen_gpu_map_mode.rs index 959a4a7a1e0..4b620cb07a5 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/gen_gpu_map_mode.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/gen_gpu_map_mode.rs @@ -16,13 +16,13 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] -#[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] +#[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub mod gpu_map_mode { #![allow(unused_imports)] #![allow(clippy::all)] @@ -34,7 +34,7 @@ pub mod gpu_map_mode { #[doc = "*This API requires the following crate features to be activated: `gpu_map_mode`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub const READ: u32 = 1u64 as u32; #[doc = "The `GPUMapMode.WRITE` const."] @@ -42,6 +42,6 @@ pub mod gpu_map_mode { #[doc = "*This API requires the following crate features to be activated: `gpu_map_mode`*"] #[doc = ""] #[doc = "*This API is unstable and requires `--cfg=web_sys_unstable_apis` to be activated, as"] - #[doc = "[described in the `wasm-bindgen` guide](https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html)*"] + #[doc = "[described in the `wasm-bindgen` guide](https://wasm-bindgen.github.io/wasm-bindgen/web-sys/unstable-apis.html)*"] pub const WRITE: u32 = 2u64 as u32; } diff --git a/wgpu/src/backend/webgpu/webgpu_sys/mod.rs b/wgpu/src/backend/webgpu/webgpu_sys/mod.rs index 02e0e0a5db2..49bcd32fd44 100644 --- a/wgpu/src/backend/webgpu/webgpu_sys/mod.rs +++ b/wgpu/src/backend/webgpu/webgpu_sys/mod.rs @@ -19,9 +19,9 @@ // Vendoring also allows us to avoid building `web-sys` with // `--cfg=web_sys_unstable_apis`, needed to get the WebGPU bindings. // -// If you want to improve the generated code, please submit a PR to the https://github.com/rustwasm/wasm-bindgen repository. +// If you want to improve the generated code, please submit a PR to the https://github.com/wasm-bindgen/wasm-bindgen repository. // -// This file was generated by the `cargo xtask vendor-web-sys --version buf-to-buf-copy-size --git-url https://github.com/andyleiserson/wasm-bindgen.git` command. +// This file was generated by the `cargo xtask vendor-web-sys --version f7e0467c4b4d88303eb79fba485320cfb4dfdd58` command. #![allow(unused_imports, non_snake_case)] use web_sys::{Event, EventTarget}; From e990388af98e4b4dff9f7fcc09a4eb5d2f71d227 Mon Sep 17 00:00:00 2001 From: Bot-Kerem <72509655+Bot-Kerem@users.noreply.github.com> Date: Fri, 8 Aug 2025 22:58:57 +0000 Subject: [PATCH 104/303] Update README.md (#8069) --- examples/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/README.md b/examples/README.md index a303eb52920..2de633e6997 100644 --- a/examples/README.md +++ b/examples/README.md @@ -43,7 +43,7 @@ These examples use a common framework to handle wgpu init, window creation, and - `ray_cube_fragment` - Demonstrates using ray queries with a fragment shader. - `ray_scene` - Demonstrates using ray queries and model loading - `ray_shadows` - Demonstrates a simple use of ray queries - high quality shadows - uses a light set with push constants to raytrace through an untransformed scene and detect whether there is something obstructing the light. -- `mesh_shader` - Rrenders a triangle to a window with mesh shaders, while showcasing most mesh shader related features(task shaders, payloads, per primitive data). +- `mesh_shader` - Renders a triangle to a window with mesh shaders, while showcasing most mesh shader related features(task shaders, payloads, per primitive data). #### Compute From 1241bb03843f86d863bf4cba438460c27348f62c Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Tue, 5 Aug 2025 17:08:56 -0400 Subject: [PATCH 105/303] fix(deno_webgpu): expose `GPUInternalError` in `bootstrap.js` --- cts_runner/src/bootstrap.js | 1 + 1 file changed, 1 insertion(+) diff --git a/cts_runner/src/bootstrap.js b/cts_runner/src/bootstrap.js index 6f3a2dc3a30..e652b35aad2 100644 --- a/cts_runner/src/bootstrap.js +++ b/cts_runner/src/bootstrap.js @@ -220,6 +220,7 @@ const windowOrWorkerGlobalScope = { GPURenderBundle: util.nonEnumerable(webgpu.GPURenderBundle), GPUQuerySet: util.nonEnumerable(webgpu.GPUQuerySet), GPUError: util.nonEnumerable(webgpu.GPUError), + GPUInternalError: util.nonEnumerable(webgpu.GPUInternalError), GPUValidationError: util.nonEnumerable(webgpu.GPUValidationError), GPUOutOfMemoryError: util.nonEnumerable(webgpu.GPUOutOfMemoryError), }; From 495df81f145799ba0dab078887d5107900cfcab0 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Tue, 5 Aug 2025 17:08:56 -0400 Subject: [PATCH 106/303] fix(deno_webgpu): expose `GPUUncapturedErrorEvent` in `bootstrap.js` --- cts_runner/src/bootstrap.js | 1 + 1 file changed, 1 insertion(+) diff --git a/cts_runner/src/bootstrap.js b/cts_runner/src/bootstrap.js index e652b35aad2..e322a6d62dc 100644 --- a/cts_runner/src/bootstrap.js +++ b/cts_runner/src/bootstrap.js @@ -223,6 +223,7 @@ const windowOrWorkerGlobalScope = { GPUInternalError: util.nonEnumerable(webgpu.GPUInternalError), GPUValidationError: util.nonEnumerable(webgpu.GPUValidationError), GPUOutOfMemoryError: util.nonEnumerable(webgpu.GPUOutOfMemoryError), + GPUUncapturedErrorEvent: util.nonEnumerable(webgpu.GPUUncapturedErrorEvent), }; windowOrWorkerGlobalScope.console.enumerable = false; From f6a3af1f1deca12f6bed96f1533b7b25fcd0256d Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Tue, 5 Aug 2025 17:08:56 -0400 Subject: [PATCH 107/303] refactor(deno_webgpu): remove unused `allow(dead_code)` on `GPUError::Internal` --- deno_webgpu/error.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/deno_webgpu/error.rs b/deno_webgpu/error.rs index 066b2a4e810..7047d19f9b6 100644 --- a/deno_webgpu/error.rs +++ b/deno_webgpu/error.rs @@ -166,7 +166,6 @@ pub enum GPUError { Validation(String), #[class("GPUOutOfMemoryError")] OutOfMemory, - #[allow(dead_code)] #[class("GPUInternalError")] Internal, } From b1bf444b7a331353cc4703c474c3ce6fd1ecdae8 Mon Sep 17 00:00:00 2001 From: Lisitsa Nikita Date: Sat, 9 Aug 2025 18:48:11 +0300 Subject: [PATCH 108/303] Fix error message when render pipeline vertex attribute location is greater or equal to the maximum number of vertex attributes (fixes #8064) (#8065) --- wgpu-core/src/device/resource.rs | 2 +- wgpu-core/src/pipeline.rs | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index eed295bdf29..a7cacea5945 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -3697,7 +3697,7 @@ impl Device { if attribute.shader_location >= self.limits.max_vertex_attributes { return Err( - pipeline::CreateRenderPipelineError::TooManyVertexAttributes { + pipeline::CreateRenderPipelineError::VertexAttributeLocationTooLarge { given: attribute.shader_location, limit: self.limits.max_vertex_attributes, }, diff --git a/wgpu-core/src/pipeline.rs b/wgpu-core/src/pipeline.rs index f67cc65e2af..580fdc4d94e 100644 --- a/wgpu-core/src/pipeline.rs +++ b/wgpu-core/src/pipeline.rs @@ -624,6 +624,8 @@ pub enum CreateRenderPipelineError { TooManyVertexBuffers { given: u32, limit: u32 }, #[error("The total number of vertex attributes {given} exceeds the limit {limit}")] TooManyVertexAttributes { given: u32, limit: u32 }, + #[error("Vertex attribute location {given} must be less than limit {limit}")] + VertexAttributeLocationTooLarge { given: u32, limit: u32 }, #[error("Vertex buffer {index} stride {given} exceeds the limit {limit}")] VertexStrideTooLarge { index: u32, given: u32, limit: u32 }, #[error("Vertex attribute at location {location} stride {given} exceeds the limit {limit}")] @@ -708,6 +710,7 @@ impl WebGpuError for CreateRenderPipelineError { | Self::InvalidSampleCount(_) | Self::TooManyVertexBuffers { .. } | Self::TooManyVertexAttributes { .. } + | Self::VertexAttributeLocationTooLarge { .. } | Self::VertexStrideTooLarge { .. } | Self::UnalignedVertexStride { .. } | Self::InvalidVertexAttributeOffset { .. } From 1b948fbf4264a4378bb9bf3702347fcf1393a576 Mon Sep 17 00:00:00 2001 From: Lisitsa Nikita Date: Sat, 9 Aug 2025 18:58:32 +0300 Subject: [PATCH 109/303] Fix 'Read-only attachment with load' error message (#8068) --- wgpu-core/src/command/render.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index abc8163c63a..6546b71c324 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -638,9 +638,9 @@ impl WebGpuError for ColorAttachmentError { pub enum AttachmentError { #[error("The format of the depth-stencil attachment ({0:?}) is not a depth-or-stencil format")] InvalidDepthStencilAttachmentFormat(wgt::TextureFormat), - #[error("Read-only attachment with load")] + #[error("LoadOp must be None for read-only attachments")] ReadOnlyWithLoad, - #[error("Read-only attachment with store")] + #[error("StoreOp must be None for read-only attachments")] ReadOnlyWithStore, #[error("Attachment without load")] NoLoad, From b9f66e77e548e60ed6d0513e0b8d18131ab8d57e Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Sun, 10 Aug 2025 05:10:10 -0400 Subject: [PATCH 110/303] =?UTF-8?q?docs(release-checklist):=20include=20`T?= =?UTF-8?q?his=20release=20includes=20`crate`,=20=E2=80=A6`=20in=20the=20`?= =?UTF-8?q?CHANGELOG`,=20too=20(#8063)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/release-checklist.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/release-checklist.md b/docs/release-checklist.md index dcd4674fa51..ad678930120 100644 --- a/docs/release-checklist.md +++ b/docs/release-checklist.md @@ -74,6 +74,10 @@ Day of Release: - On _your own branch_ based on the latest release branch. Cherry-pick the PRs that need to be backported. When modifying the commits, use --append to retain their original authorship. - Remove the `needs-backport` label from the PRs. - Fix the changelogs items and add a new header for the patch release with the release version and date. + - The release section should start with a header saying the following (for example) + ```markdown + This release includes `crate1`, `crate2` and `crate3` version `X.Y.Z`. All other crates remain at their previous versions. + ``` - Once all the PRs are cherry-picked, look at the diff between HEAD and the previous patch release. See what crates changed. - Bump all the versions of the crates that changed. - Create a PR with all of the version changes and changelog updates into the release branch. @@ -81,10 +85,6 @@ Day of Release: - Checkout the release branch with the merged PR. - Publish all relevant crates (see list above). - Create a new release on the `wgpu` repo with the changelog and a tag called `vX.Y.Z` on the release branch. - - The release should start with a header saying the following (for example) - ```markdown - This release includes `crate1`, `crate2` and `crate3` version `X.Y.Z`. All other crates remain at their previous versions. - ``` - Backport the changelog and version bumps to the `trunk` branch. - Ensure that any items in the newly-released changelog don't appear in the "unreleased" section of the trunk changelog. - Update the release checklist with any needed changes. From f04b3b020f09ab066fde6bf46d6198ff41ee41c7 Mon Sep 17 00:00:00 2001 From: sagudev <16504129+sagudev@users.noreply.github.com> Date: Sun, 10 Aug 2025 11:15:36 +0200 Subject: [PATCH 111/303] Remove lifetime from BufferSlice, BufferView, BufferViewMut (#8046) --- .../wgpu-gpu/timestamp_normalization/utils.rs | 4 +- wgpu/src/api/buffer.rs | 59 ++++++++++--------- wgpu/src/util/belt.rs | 2 +- 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/tests/tests/wgpu-gpu/timestamp_normalization/utils.rs b/tests/tests/wgpu-gpu/timestamp_normalization/utils.rs index e0cadc58327..1ce11ad775a 100644 --- a/tests/tests/wgpu-gpu/timestamp_normalization/utils.rs +++ b/tests/tests/wgpu-gpu/timestamp_normalization/utils.rs @@ -282,7 +282,5 @@ fn process_shader(ctx: TestingContext, inputs: &[u8], entry_point_src: &str) -> ctx.device.poll(wgpu::PollType::Wait).unwrap(); - let value = pulldown_buffer.get_mapped_range(..).to_vec(); - - value + pulldown_buffer.get_mapped_range(..).to_vec() } diff --git a/wgpu/src/api/buffer.rs b/wgpu/src/api/buffer.rs index da7e4aca873..6e4d65c7d20 100644 --- a/wgpu/src/api/buffer.rs +++ b/wgpu/src/api/buffer.rs @@ -354,7 +354,7 @@ impl Buffer { /// - If you try to create overlapping views of a buffer, mutable or otherwise. /// /// [mapped]: Buffer#mapping-buffers - pub fn get_mapped_range>(&self, bounds: S) -> BufferView<'_> { + pub fn get_mapped_range>(&self, bounds: S) -> BufferView { self.slice(bounds).get_mapped_range() } @@ -377,10 +377,7 @@ impl Buffer { /// - If you try to create overlapping views of a buffer, mutable or otherwise. /// /// [mapped]: Buffer#mapping-buffers - pub fn get_mapped_range_mut>( - &self, - bounds: S, - ) -> BufferViewMut<'_> { + pub fn get_mapped_range_mut>(&self, bounds: S) -> BufferViewMut { self.slice(bounds).get_mapped_range_mut() } @@ -518,11 +515,13 @@ impl<'a> BufferSlice<'a> { /// - If you try to create overlapping views of a buffer, mutable or otherwise. /// /// [mapped]: Buffer#mapping-buffers - pub fn get_mapped_range(&self) -> BufferView<'a> { + pub fn get_mapped_range(&self) -> BufferView { let end = self.buffer.map_context.lock().add(self.offset, self.size); let range = self.buffer.inner.get_mapped_range(self.offset..end); BufferView { - slice: *self, + buffer: self.buffer.clone(), + size: self.size, + offset: self.offset, inner: range, } } @@ -544,11 +543,13 @@ impl<'a> BufferSlice<'a> { /// - If you try to create overlapping views of a buffer, mutable or otherwise. /// /// [mapped]: Buffer#mapping-buffers - pub fn get_mapped_range_mut(&self) -> BufferViewMut<'a> { + pub fn get_mapped_range_mut(&self) -> BufferViewMut { let end = self.buffer.map_context.lock().add(self.offset, self.size); let range = self.buffer.inner.get_mapped_range(self.offset..end); BufferViewMut { - slice: *self, + buffer: self.buffer.clone(), + size: self.size, + offset: self.offset, inner: range, readable: self.buffer.usage.contains(BufferUsages::MAP_READ), } @@ -725,13 +726,16 @@ static_assertions::assert_impl_all!(MapMode: Send, Sync); /// [map]: Buffer#mapping-buffers /// [`map_async`]: BufferSlice::map_async #[derive(Debug)] -pub struct BufferView<'a> { - slice: BufferSlice<'a>, +pub struct BufferView { + // `buffer, offset, size` are similar to `BufferSlice`, except that they own the buffer. + buffer: Buffer, + offset: BufferAddress, + size: BufferSize, inner: dispatch::DispatchBufferMappedRange, } #[cfg(webgpu)] -impl BufferView<'_> { +impl BufferView { /// Provides the same data as dereferencing the view, but as a `Uint8Array` in js. /// This can be MUCH faster than dereferencing the view which copies the data into /// the Rust / wasm heap. @@ -740,7 +744,7 @@ impl BufferView<'_> { } } -impl core::ops::Deref for BufferView<'_> { +impl core::ops::Deref for BufferView { type Target = [u8]; #[inline] @@ -749,7 +753,7 @@ impl core::ops::Deref for BufferView<'_> { } } -impl AsRef<[u8]> for BufferView<'_> { +impl AsRef<[u8]> for BufferView { #[inline] fn as_ref(&self) -> &[u8] { self.inner.slice() @@ -775,20 +779,23 @@ impl AsRef<[u8]> for BufferView<'_> { /// /// [map]: Buffer#mapping-buffers #[derive(Debug)] -pub struct BufferViewMut<'a> { - slice: BufferSlice<'a>, +pub struct BufferViewMut { + // `buffer, offset, size` are similar to `BufferSlice`, except that they own the buffer. + buffer: Buffer, + offset: BufferAddress, + size: BufferSize, inner: dispatch::DispatchBufferMappedRange, readable: bool, } -impl AsMut<[u8]> for BufferViewMut<'_> { +impl AsMut<[u8]> for BufferViewMut { #[inline] fn as_mut(&mut self) -> &mut [u8] { self.inner.slice_mut() } } -impl Deref for BufferViewMut<'_> { +impl Deref for BufferViewMut { type Target = [u8]; fn deref(&self) -> &Self::Target { @@ -800,29 +807,27 @@ impl Deref for BufferViewMut<'_> { } } -impl DerefMut for BufferViewMut<'_> { +impl DerefMut for BufferViewMut { fn deref_mut(&mut self) -> &mut Self::Target { self.inner.slice_mut() } } -impl Drop for BufferView<'_> { +impl Drop for BufferView { fn drop(&mut self) { - self.slice - .buffer + self.buffer .map_context .lock() - .remove(self.slice.offset, self.slice.size); + .remove(self.offset, self.size); } } -impl Drop for BufferViewMut<'_> { +impl Drop for BufferViewMut { fn drop(&mut self) { - self.slice - .buffer + self.buffer .map_context .lock() - .remove(self.slice.offset, self.slice.size); + .remove(self.offset, self.size); } } diff --git a/wgpu/src/util/belt.rs b/wgpu/src/util/belt.rs index 222a49f4c46..2662f72b545 100644 --- a/wgpu/src/util/belt.rs +++ b/wgpu/src/util/belt.rs @@ -77,7 +77,7 @@ impl StagingBelt { offset: BufferAddress, size: BufferSize, device: &Device, - ) -> BufferViewMut<'_> { + ) -> BufferViewMut { let slice_of_belt = self.allocate( size, const { BufferSize::new(crate::COPY_BUFFER_ALIGNMENT).unwrap() }, From e7cdfc436a6980e5a1ae3844767dd435ca902b46 Mon Sep 17 00:00:00 2001 From: Marc Pabst <2624210+marcpabst@users.noreply.github.com> Date: Sun, 10 Aug 2025 11:01:25 +0100 Subject: [PATCH 112/303] Allow disabling waiting for latency waitable object (#7400) --- CHANGELOG.md | 7 ++- deno_webgpu/lib.rs | 1 + tests/src/init.rs | 1 + wgpu-hal/examples/ray-traced-triangle/main.rs | 1 + wgpu-hal/src/dx12/adapter.rs | 3 + wgpu-hal/src/dx12/device.rs | 2 + wgpu-hal/src/dx12/instance.rs | 3 + wgpu-hal/src/dx12/mod.rs | 57 ++++++++++++++---- wgpu-types/src/instance.rs | 60 ++++++++++++++++++- 9 files changed, 122 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a8a963cfc6..d04d74205fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,7 +73,7 @@ By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). #### DX12 -- Fixed a bug where access to matrices with 2 rows would not work in some cases. By @andyleiserson in [#7438](https://github.com/gfx-rs/wgpu/pull/7438). +- Allow disabling waiting for latency waitable object. By @marcpabst in [#7400](https://github.com/gfx-rs/wgpu/pull/7400) ### Bug Fixes @@ -85,6 +85,11 @@ By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). - Fix `STATUS_HEAP_CORRUPTION` crash when concurrently calling `create_sampler`. By @atlv24 in [#8043](https://github.com/gfx-rs/wgpu/pull/8043). +##### DX12 + +- Fixed a bug where access to matrices with 2 rows would not work in some cases. By @andyleiserson in [#7438](https://github.com/gfx-rs/wgpu/pull/7438). + + ## v26.0.2 (2025-07-23) ### Bug Fixes diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index 6ce31a29c52..8b39160b264 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -158,6 +158,7 @@ impl GPU { backend_options: wgpu_types::BackendOptions { dx12: wgpu_types::Dx12BackendOptions { shader_compiler: wgpu_types::Dx12Compiler::Fxc, + ..Default::default() }, gl: wgpu_types::GlBackendOptions::default(), noop: wgpu_types::NoopBackendOptions::default(), diff --git a/tests/src/init.rs b/tests/src/init.rs index bee5af689c7..0a33f969f25 100644 --- a/tests/src/init.rs +++ b/tests/src/init.rs @@ -50,6 +50,7 @@ pub fn initialize_instance(backends: wgpu::Backends, params: &TestParameters) -> backend_options: wgpu::BackendOptions { dx12: wgpu::Dx12BackendOptions { shader_compiler: dx12_shader_compiler, + ..Default::default() }, gl: wgpu::GlBackendOptions { fence_behavior: if cfg!(target_family = "wasm") { diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index 2947d1a6014..43cb405ef14 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -242,6 +242,7 @@ impl Example { backend_options: wgpu_types::BackendOptions { dx12: Dx12BackendOptions { shader_compiler: wgpu_types::Dx12Compiler::default_dynamic_dxc(), + ..Default::default() }, ..Default::default() }, diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index 3a0ece692ff..b8b908279e0 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -58,6 +58,7 @@ impl super::Adapter { instance_flags: wgt::InstanceFlags, memory_budget_thresholds: wgt::MemoryBudgetThresholds, compiler_container: Arc, + backend_options: wgt::Dx12BackendOptions, ) -> Option> { // Create the device so that we can get the capabilities. let device = { @@ -534,6 +535,7 @@ impl super::Adapter { workarounds, memory_budget_thresholds, compiler_container, + options: backend_options, }, info, features, @@ -697,6 +699,7 @@ impl crate::Adapter for super::Adapter { &self.library, self.memory_budget_thresholds, self.compiler_container.clone(), + self.options.clone(), )?; Ok(crate::OpenDevice { device, diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 8eb4bb8864f..d62fc5c6751 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -48,6 +48,7 @@ impl super::Device { library: &Arc, memory_budget_thresholds: wgt::MemoryBudgetThresholds, compiler_container: Arc, + backend_options: wgt::Dx12BackendOptions, ) -> Result { if private_caps .instance_flags @@ -198,6 +199,7 @@ impl super::Device { raw.clone(), Direct3D12::D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, )), + options: backend_options, library: Arc::clone(library), #[cfg(feature = "renderdoc")] render_doc: Default::default(), diff --git a/wgpu-hal/src/dx12/instance.rs b/wgpu-hal/src/dx12/instance.rs index 9055b5407f2..69bfa77d8e8 100644 --- a/wgpu-hal/src/dx12/instance.rs +++ b/wgpu-hal/src/dx12/instance.rs @@ -109,6 +109,7 @@ impl crate::Instance for super::Instance { flags: desc.flags, memory_budget_thresholds: desc.memory_budget_thresholds, compiler_container: Arc::new(compiler_container), + options: desc.backend_options.dx12.clone(), }) } @@ -125,6 +126,7 @@ impl crate::Instance for super::Instance { target: SurfaceTarget::WndHandle(Foundation::HWND(handle.hwnd.get() as *mut _)), supports_allow_tearing: self.supports_allow_tearing, swap_chain: RwLock::new(None), + options: self.options.clone(), }), _ => Err(crate::InstanceError::new(format!( "window handle {window_handle:?} is not a Win32 handle" @@ -147,6 +149,7 @@ impl crate::Instance for super::Instance { self.flags, self.memory_budget_thresholds, self.compiler_container.clone(), + self.options.clone(), ) }) .collect() diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index a102006acb0..c15f3b81e4e 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -464,6 +464,7 @@ pub struct Instance { flags: wgt::InstanceFlags, memory_budget_thresholds: wgt::MemoryBudgetThresholds, compiler_container: Arc, + options: wgt::Dx12BackendOptions, } impl Instance { @@ -481,6 +482,7 @@ impl Instance { target: SurfaceTarget::Visual(visual.to_owned()), supports_allow_tearing: self.supports_allow_tearing, swap_chain: RwLock::new(None), + options: self.options.clone(), } } @@ -498,6 +500,7 @@ impl Instance { target: SurfaceTarget::SurfaceHandle(surface_handle), supports_allow_tearing: self.supports_allow_tearing, swap_chain: RwLock::new(None), + options: self.options.clone(), } } @@ -514,6 +517,7 @@ impl Instance { target: SurfaceTarget::SwapChainPanel(swap_chain_panel.to_owned()), supports_allow_tearing: self.supports_allow_tearing, swap_chain: RwLock::new(None), + options: self.options.clone(), } } } @@ -528,7 +532,7 @@ struct SwapChain { // when the swapchain is destroyed resources: Vec, /// Handle is freed in [`Self::release_resources()`] - waitable: Foundation::HANDLE, + waitable: Option, acquired_count: usize, present_mode: wgt::PresentMode, format: wgt::TextureFormat, @@ -550,6 +554,7 @@ pub struct Surface { target: SurfaceTarget, supports_allow_tearing: bool, swap_chain: RwLock>, + options: wgt::Dx12BackendOptions, } unsafe impl Send for Surface {} @@ -559,6 +564,12 @@ impl Surface { pub fn swap_chain(&self) -> Option { Some(self.swap_chain.read().as_ref()?.raw.clone()) } + + /// Returns the waitable handle associated with this swap chain, if any. + /// Handle is only valid while the swap chain is alive. + pub unsafe fn waitable_handle(&self) -> Option { + self.swap_chain.read().as_ref()?.waitable + } } #[derive(Debug, Clone, Copy)] @@ -601,6 +612,7 @@ pub struct Adapter { workarounds: Workarounds, memory_budget_thresholds: wgt::MemoryBudgetThresholds, compiler_container: Arc, + options: wgt::Dx12BackendOptions, } unsafe impl Send for Adapter {} @@ -659,6 +671,7 @@ pub struct Device { idler: Idler, features: wgt::Features, shared: Arc, + options: wgt::Dx12BackendOptions, // CPU only pools rtv_pool: Arc>, dsv_pool: Mutex, @@ -1178,7 +1191,9 @@ impl crate::DynAccelerationStructure for AccelerationStructure {} impl SwapChain { unsafe fn release_resources(mut self) -> Dxgi::IDXGISwapChain3 { - unsafe { Foundation::HANDLE::free(&mut self.waitable) }; + if let Some(mut waitable) = self.waitable.take() { + unsafe { Foundation::HANDLE::free(&mut waitable) }; + } self.raw } @@ -1190,14 +1205,21 @@ impl SwapChain { Some(duration) => duration.as_millis() as u32, None => Threading::INFINITE, }; - match unsafe { Threading::WaitForSingleObject(self.waitable, timeout_ms) } { - Foundation::WAIT_ABANDONED | Foundation::WAIT_FAILED => Err(crate::SurfaceError::Lost), - Foundation::WAIT_OBJECT_0 => Ok(true), - Foundation::WAIT_TIMEOUT => Ok(false), - other => { - log::error!("Unexpected wait status: 0x{other:x?}"); - Err(crate::SurfaceError::Lost) + + if let Some(waitable) = self.waitable { + match unsafe { Threading::WaitForSingleObject(waitable, timeout_ms) } { + Foundation::WAIT_ABANDONED | Foundation::WAIT_FAILED => { + Err(crate::SurfaceError::Lost) + } + Foundation::WAIT_OBJECT_0 => Ok(true), + Foundation::WAIT_TIMEOUT => Ok(false), + other => { + log::error!("Unexpected wait status: 0x{other:x?}"); + Err(crate::SurfaceError::Lost) + } } + } else { + Ok(true) } } } @@ -1365,7 +1387,14 @@ impl crate::Surface for Surface { unsafe { swap_chain.SetMaximumFrameLatency(config.maximum_frame_latency) } .into_device_result("SetMaximumFrameLatency")?; - let waitable = unsafe { swap_chain.GetFrameLatencyWaitableObject() }; + + let waitable = match device.options.latency_waitable_object { + wgt::Dx12UseFrameLatencyWaitableObject::None => None, + wgt::Dx12UseFrameLatencyWaitableObject::Wait + | wgt::Dx12UseFrameLatencyWaitableObject::DontWait => { + Some(unsafe { swap_chain.GetFrameLatencyWaitableObject() }) + } + }; let mut resources = Vec::with_capacity(swap_chain_buffer as usize); for i in 0..swap_chain_buffer { @@ -1412,7 +1441,13 @@ impl crate::Surface for Surface { let mut swapchain = self.swap_chain.write(); let sc = swapchain.as_mut().unwrap(); - unsafe { sc.wait(timeout) }?; + match self.options.latency_waitable_object { + wgt::Dx12UseFrameLatencyWaitableObject::None + | wgt::Dx12UseFrameLatencyWaitableObject::DontWait => {} + wgt::Dx12UseFrameLatencyWaitableObject::Wait => { + unsafe { sc.wait(timeout) }?; + } + } let base_index = unsafe { sc.raw.GetCurrentBackBufferIndex() } as usize; let index = (base_index + sc.acquired_count) % sc.resources.len(); diff --git a/wgpu-types/src/instance.rs b/wgpu-types/src/instance.rs index 79e3f7b2526..c78fccdb665 100644 --- a/wgpu-types/src/instance.rs +++ b/wgpu-types/src/instance.rs @@ -359,6 +359,8 @@ impl GlBackendOptions { pub struct Dx12BackendOptions { /// Which DX12 shader compiler to use. pub shader_compiler: Dx12Compiler, + /// Whether to wait for the latency waitable object before acquiring the next swapchain image. + pub latency_waitable_object: Dx12UseFrameLatencyWaitableObject, } impl Dx12BackendOptions { @@ -368,8 +370,11 @@ impl Dx12BackendOptions { #[must_use] pub fn from_env_or_default() -> Self { let compiler = Dx12Compiler::from_env().unwrap_or_default(); + let latency_waitable_object = + Dx12UseFrameLatencyWaitableObject::from_env().unwrap_or_default(); Self { shader_compiler: compiler, + latency_waitable_object, } } @@ -379,7 +384,12 @@ impl Dx12BackendOptions { #[must_use] pub fn with_env(self) -> Self { let shader_compiler = self.shader_compiler.with_env(); - Self { shader_compiler } + let latency_waitable_object = self.latency_waitable_object.with_env(); + + Self { + shader_compiler, + latency_waitable_object, + } } } @@ -515,6 +525,54 @@ impl Dx12Compiler { } } +/// Whether and how to use a waitable handle obtained from `GetFrameLatencyWaitableObject`. +#[derive(Clone, Debug, Default)] +pub enum Dx12UseFrameLatencyWaitableObject { + /// Do not obtain a waitable handle and do not wait for it. The swapchain will + /// be created without the `DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT` flag. + None, + /// Obtain a waitable handle and wait for it before acquiring the next swapchain image. + #[default] + Wait, + /// Create the swapchain with the `DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT` flag and + /// obtain a waitable handle, but do not wait for it before acquiring the next swapchain image. + /// This is useful if the application wants to wait for the waitable object itself. + DontWait, +} + +impl Dx12UseFrameLatencyWaitableObject { + /// Choose whether to use a frame latency waitable object from the environment variable `WGPU_DX12_USE_FRAME_LATENCY_WAITABLE_OBJECT`. + /// + /// Valid values, case insensitive: + /// - `None` + /// - `Wait` + /// - `DontWait` + #[must_use] + pub fn from_env() -> Option { + let value = crate::env::var("WGPU_DX12_USE_FRAME_LATENCY_WAITABLE_OBJECT") + .as_deref()? + .to_lowercase(); + match value.as_str() { + "none" => Some(Self::None), + "wait" => Some(Self::Wait), + "dontwait" => Some(Self::DontWait), + _ => None, + } + } + + /// Takes the given setting, modifies it based on the `WGPU_DX12_USE_FRAME_LATENCY_WAITABLE_OBJECT` environment variable, and returns the result. + /// + /// See `from_env` for more information. + #[must_use] + pub fn with_env(self) -> Self { + if let Some(compiler) = Self::from_env() { + compiler + } else { + self + } + } +} + /// Selects which OpenGL ES 3 minor version to request. /// /// When using ANGLE as an OpenGL ES/EGL implementation, explicitly requesting `Version1` can provide a non-conformant ES 3.1 on APIs like D3D11. From 0990ecd57427c49f0e20e432dc2656a5cbc2190d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Aug 2025 11:16:35 +0200 Subject: [PATCH 113/303] chore(deps): update crate-ci/typos action to v1.35.3 (#8077) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4fca15ea6a8..84453f0c793 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -725,7 +725,7 @@ jobs: run: taplo format --check --diff - name: Check for typos - uses: crate-ci/typos@v1.34.0 + uses: crate-ci/typos@v1.35.3 check-cts-runner: # runtime is normally 2 minutes From 505d7216748bb6a2759b6bfb4619c02d9bed285d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Aug 2025 11:20:14 +0200 Subject: [PATCH 114/303] chore(deps): update rust crate ctor to 0.5 (#8078) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f7175cce623..90e59c7d793 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -998,9 +998,9 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "ctor" -version = "0.4.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec09e802f5081de6157da9a75701d6c713d8dc3ba52571fd4bd25f412644e8a6" +checksum = "67773048316103656a637612c4a62477603b777d91d9c62ff2290f9cde178fdb" dependencies = [ "ctor-proc-macro", "dtor", @@ -1326,18 +1326,18 @@ checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" [[package]] name = "dtor" -version = "0.0.6" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97cbdf2ad6846025e8e25df05171abfb30e3ababa12ee0a0e44b9bbe570633a8" +checksum = "e58a0764cddb55ab28955347b45be00ade43d4d6f3ba4bf3dc354e4ec9432934" dependencies = [ "dtor-proc-macro", ] [[package]] name = "dtor-proc-macro" -version = "0.0.5" +version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7454e41ff9012c00d53cf7f475c5e3afa3b91b7c90568495495e8d9bf47a1055" +checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5" [[package]] name = "either" diff --git a/Cargo.toml b/Cargo.toml index 529a0e92035..672e24a14d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -108,7 +108,7 @@ cfg_aliases = "0.2.1" cfg-if = "1" criterion = "0.7" codespan-reporting = { version = "0.12", default-features = false } -ctor = "0.4" +ctor = "0.5" diff = "0.1" document-features = "0.2.10" encase = "0.11" From 02636cd940eb630448e882885ef1e7deea493acd Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Thu, 7 Aug 2025 11:34:57 -0400 Subject: [PATCH 115/303] style(CHANGELOG): trim extra whitespace --- CHANGELOG.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d04d74205fd..23f43e1e9a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -166,9 +166,9 @@ let (device, queue) = adapter .unwrap(); ``` -More examples of this +More examples of this -By @Vecvec in [#7829](https://github.com/gfx-rs/wgpu/pull/7829). +By @Vecvec in [#7829](https://github.com/gfx-rs/wgpu/pull/7829). ### Naga @@ -252,7 +252,6 @@ By @Vecvec in [#7829](https://github.com/gfx-rs/wgpu/pull/7829). - The definition of `enum CommandEncoderError` has changed significantly, to reflect which errors can be raised by `CommandEncoder.finish()`. There are also some errors that no longer appear directly in `CommandEncoderError`, and instead appear nested within the `RenderPass` or `ComputePass` variants. - `CopyError` has been removed. Errors that were previously a `CopyError` are now a `CommandEncoderError` returned by `finish()`. (The detailed reasons for copies to fail were and still are described by `TransferError`, which was previously a variant of `CopyError`, and is now a variant of `CommandEncoderError`). - #### Naga - Mark `readonly_and_readwrite_storage_textures` & `packed_4x8_integer_dot_product` language extensions as implemented. By @teoxoy in [#7543](https://github.com/gfx-rs/wgpu/pull/7543) From d17228fda80af490ca2ba1ecd4b06928c2d6e2bd Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Thu, 7 Aug 2025 11:34:57 -0400 Subject: [PATCH 116/303] docs(CHANGELOG): port 26.0.{3,4} release notes --- CHANGELOG.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23f43e1e9a2..bde223b1714 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -81,14 +81,23 @@ By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). - Validate that effective buffer binding size is aligned to 4 when creating bind groups with buffer entries.. By @ErichDonGubler in [8041](https://github.com/gfx-rs/wgpu/pull/8041). +#### DX12 + +- Fixed a bug where access to matrices with 2 rows would not work in some cases. By @andyleiserson in [#7438](https://github.com/gfx-rs/wgpu/pull/7438). + +## v26.0.4 (2025-08-07) + +### Bug Fixes + #### Vulkan -- Fix `STATUS_HEAP_CORRUPTION` crash when concurrently calling `create_sampler`. By @atlv24 in [#8043](https://github.com/gfx-rs/wgpu/pull/8043). +- Fix `STATUS_HEAP_CORRUPTION` crash when concurrently calling `create_sampler`. By @atlv24 in [#8043](https://github.com/gfx-rs/wgpu/pull/8043), [#8056](https://github.com/gfx-rs/wgpu/pull/8056). -##### DX12 +## v26.0.3 (2025-07-30) -- Fixed a bug where access to matrices with 2 rows would not work in some cases. By @andyleiserson in [#7438](https://github.com/gfx-rs/wgpu/pull/7438). +### Bug Fixes +- Fixed memory leak in vulkan backend. By @cwfitzgerald in [#8031](https://github.com/gfx-rs/wgpu/pull/8031). ## v26.0.2 (2025-07-23) @@ -96,6 +105,7 @@ By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). - Fixed vulkan validation error regarding the swapchain in latest SDK. By @cwfitzgerald in [#7971](https://github.com/gfx-rs/wgpu/pull/7971). - Fixed flickering on AMD devices and crashes inside Renderdoc due to incorrect caching of `VkFramebuffer`s when the driver re-used image view handles. By @cwfitzgerald in [#7972](https://github.com/gfx-rs/wgpu/pull/7972). + > [!WARNING] > There is formally a breaking change in `wgpu_hal::vulkan::Device::texture_from_raw` as there is now a `&self` receiver where > there previously wasn't one. This will not affect you unless you explicitly use this api. We have gone ahead with the release From f9df2b5442d30b7d19ebcd679a8e9e70204fa966 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Thu, 7 Aug 2025 12:30:28 -0400 Subject: [PATCH 117/303] docs(CHANGELOG): move #7345's entry to `Unreleased` --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bde223b1714..a1cb2650a6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,12 @@ We have merged the acceleration structure feature into the `RayQuery` feature. T By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). +### New Features + +#### General + +- Added mesh shader support to `wgpu`, with examples. Requires passthrough. By @SupaMaggie70Incorporated in [#7345](https://github.com/gfx-rs/wgpu/pull/7345). + ### Changes #### General @@ -198,7 +204,6 @@ By @Vecvec in [#7829](https://github.com/gfx-rs/wgpu/pull/7829). - Add acceleration structure limits. By @Vecvec in [#7845](https://github.com/gfx-rs/wgpu/pull/7845). - Add support for clip-distances feature for Vulkan and GL backends. By @dzamkov in [#7730](https://github.com/gfx-rs/wgpu/pull/7730) - Added `wgpu_types::error::{ErrorType, WebGpuError}` for classification of errors according to WebGPU's [`GPUError`]'s classification scheme, and implement `WebGpuError` for existing errors. This allows users of `wgpu-core` to offload error classification onto the WGPU ecosystem, rather than having to do it themselves without sufficient information. By @ErichDonGubler in [#6547](https://github.com/gfx-rs/wgpu/pull/6547). -- Added mesh shader support to `wgpu`, with examples. Requires passthrough. By @SupaMaggie70Incorporated in [#7345](https://github.com/gfx-rs/wgpu/pull/7345). [`GPUError`]: https://www.w3.org/TR/webgpu/#gpuerror From 0cc8c11afef2c87e8f02d34fdf6c78201542a0ea Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Mon, 11 Aug 2025 12:16:46 -0700 Subject: [PATCH 118/303] Escape control chars in source when printing diagnostics (#8049) --- CHANGELOG.md | 3 +-- naga/src/error.rs | 33 +++++++++++++++++++++++++++++++-- naga/src/front/glsl/error.rs | 4 ++-- naga/src/front/spv/error.rs | 8 ++++++-- naga/src/front/wgsl/error.rs | 5 +++-- naga/src/span.rs | 6 +++--- naga/tests/naga/wgsl_errors.rs | 15 +++++++++++++++ 7 files changed, 61 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1cb2650a6c..64973330bcc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -76,6 +76,7 @@ By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). #### Naga - Naga now requires that no type be larger than 1 GB. This limit may be lowered in the future; feedback on an appropriate value for the limit is welcome. By @andyleiserson in [#7950](https://github.com/gfx-rs/wgpu/pull/7950). +- If the shader source contains control characters, Naga now replaces them with U+FFFD ("replacement character") in diagnostic output. By @andyleiserson in [#8049](https://github.com/gfx-rs/wgpu/pull/8049). #### DX12 @@ -182,8 +183,6 @@ let (device, queue) = adapter .unwrap(); ``` -More examples of this - By @Vecvec in [#7829](https://github.com/gfx-rs/wgpu/pull/7829). ### Naga diff --git a/naga/src/error.rs b/naga/src/error.rs index 3c2f476c9b1..a4855606731 100644 --- a/naga/src/error.rs +++ b/naga/src/error.rs @@ -1,4 +1,4 @@ -use alloc::{boxed::Box, string::String}; +use alloc::{borrow::Cow, boxed::Box, string::String}; use core::{error::Error, fmt}; #[derive(Clone, Debug)] @@ -41,7 +41,7 @@ impl fmt::Display for ShaderError use codespan_reporting::{files::SimpleFile, term}; let label = self.label.as_deref().unwrap_or_default(); - let files = SimpleFile::new(label, &self.source); + let files = SimpleFile::new(label, replace_control_chars(&self.source)); let config = term::Config::default(); let writer = { @@ -137,3 +137,32 @@ where Some(&self.inner) } } + +pub(crate) fn replace_control_chars(s: &str) -> Cow<'_, str> { + const REPLACEMENT_CHAR: &str = "\u{FFFD}"; + debug_assert_eq!( + REPLACEMENT_CHAR.chars().next().unwrap(), + char::REPLACEMENT_CHARACTER + ); + + let mut res = Cow::Borrowed(s); + let mut offset = 0; + + while let Some(found_pos) = res[offset..].find(|c: char| c.is_control() && !c.is_whitespace()) { + offset += found_pos; + let found_len = res[offset..].chars().next().unwrap().len_utf8(); + res.to_mut() + .replace_range(offset..offset + found_len, REPLACEMENT_CHAR); + offset += REPLACEMENT_CHAR.len(); + } + + res +} + +#[test] +fn test_replace_control_chars() { + // The UTF-8 encoding of \u{0080} is multiple bytes. + let input = "Foo\u{0080}Bar\u{0001}Baz\n"; + let expected = "Foo\u{FFFD}Bar\u{FFFD}Baz\n"; + assert_eq!(replace_control_chars(input), expected); +} diff --git a/naga/src/front/glsl/error.rs b/naga/src/front/glsl/error.rs index 900ad52359d..1fb15ef0390 100644 --- a/naga/src/front/glsl/error.rs +++ b/naga/src/front/glsl/error.rs @@ -12,7 +12,7 @@ use pp_rs::token::PreprocessorError; use thiserror::Error; use super::token::TokenValue; -use crate::SourceLocation; +use crate::{error::replace_control_chars, SourceLocation}; use crate::{error::ErrorWrite, proc::ConstantEvaluatorError, Span}; fn join_with_comma(list: &[ExpectedToken]) -> String { @@ -171,7 +171,7 @@ impl ParseErrors { pub fn emit_to_writer_with_path(&self, writer: &mut impl ErrorWrite, source: &str, path: &str) { let path = path.to_string(); - let files = SimpleFile::new(path, source); + let files = SimpleFile::new(path, replace_control_chars(source)); let config = term::Config::default(); for err in &self.errors { diff --git a/naga/src/front/spv/error.rs b/naga/src/front/spv/error.rs index acfda0a22fa..cf456a9db90 100644 --- a/naga/src/front/spv/error.rs +++ b/naga/src/front/spv/error.rs @@ -8,7 +8,11 @@ use codespan_reporting::files::SimpleFile; use codespan_reporting::term; use super::ModuleState; -use crate::{arena::Handle, error::ErrorWrite, front::atomic_upgrade}; +use crate::{ + arena::Handle, + error::{replace_control_chars, ErrorWrite}, + front::atomic_upgrade, +}; #[derive(Clone, Debug, thiserror::Error)] pub enum Error { @@ -157,7 +161,7 @@ impl Error { pub fn emit_to_writer_with_path(&self, writer: &mut impl ErrorWrite, source: &str, path: &str) { let path = path.to_string(); - let files = SimpleFile::new(path, source); + let files = SimpleFile::new(path, replace_control_chars(source)); let config = term::Config::default(); let diagnostic = Diagnostic::error().with_message(format!("{self:?}")); diff --git a/naga/src/front/wgsl/error.rs b/naga/src/front/wgsl/error.rs index 7101eb6fc9c..1cdf53f37dc 100644 --- a/naga/src/front/wgsl/error.rs +++ b/naga/src/front/wgsl/error.rs @@ -2,6 +2,7 @@ use crate::common::wgsl::TryToWgsl; use crate::diagnostic_filter::ConflictingDiagnosticRuleError; +use crate::error::replace_control_chars; use crate::proc::{Alignment, ConstantEvaluatorError, ResolveError}; use crate::{Scalar, SourceLocation, Span}; @@ -79,7 +80,7 @@ impl ParseError { P: AsRef, { let path = path.as_ref().display().to_string(); - let files = SimpleFile::new(path, source); + let files = SimpleFile::new(path, replace_control_chars(source)); let config = term::Config::default(); cfg_if::cfg_if! { @@ -105,7 +106,7 @@ impl ParseError { P: AsRef, { let path = path.as_ref().display().to_string(); - let files = SimpleFile::new(path, source); + let files = SimpleFile::new(path, replace_control_chars(source)); let config = term::Config::default(); let mut writer = crate::error::DiagnosticBuffer::new(); diff --git a/naga/src/span.rs b/naga/src/span.rs index 942846e46b5..357c2379f29 100644 --- a/naga/src/span.rs +++ b/naga/src/span.rs @@ -6,7 +6,7 @@ use alloc::{ }; use core::{error::Error, fmt, ops::Range}; -use crate::{path_like::PathLike, Arena, Handle, UniqueArena}; +use crate::{error::replace_control_chars, path_like::PathLike, Arena, Handle, UniqueArena}; /// A source code span, used for error reporting. #[derive(Clone, Copy, Debug, PartialEq, Default)] @@ -291,7 +291,7 @@ impl WithSpan { use codespan_reporting::{files, term}; let path = path.to_string_lossy(); - let files = files::SimpleFile::new(path, source); + let files = files::SimpleFile::new(path, replace_control_chars(source)); let config = term::Config::default(); cfg_if::cfg_if! { @@ -323,7 +323,7 @@ impl WithSpan { use codespan_reporting::{files, term}; let path = path.to_string_lossy(); - let files = files::SimpleFile::new(path, source); + let files = files::SimpleFile::new(path, replace_control_chars(source)); let config = term::Config::default(); let mut writer = crate::error::DiagnosticBuffer::new(); diff --git a/naga/tests/naga/wgsl_errors.rs b/naga/tests/naga/wgsl_errors.rs index 79ffe2a49fa..adb60a18485 100644 --- a/naga/tests/naga/wgsl_errors.rs +++ b/naga/tests/naga/wgsl_errors.rs @@ -3887,3 +3887,18 @@ fn max_type_size_array_of_structs() { )) } } + +#[cfg(feature = "wgsl-in")] +#[test] +fn source_with_control_char() { + check( + "\x07", + "error: expected global item (`struct`, `const`, `var`, `alias`, `fn`, `diagnostic`, `enable`, `requires`, `;`) or the end of the file, found \"\\u{7}\" + ┌─ wgsl:1:1 + │ +1 │ � + │ ^ expected global item (`struct`, `const`, `var`, `alias`, `fn`, `diagnostic`, `enable`, `requires`, `;`) or the end of the file + +", + ); +} From e7dad314ed613c2f17765d33a8e548af40a92869 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Mon, 11 Aug 2025 13:04:53 -0700 Subject: [PATCH 119/303] Accept configuration from the environment for the trace player (#8083) --- player/src/bin/play.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/player/src/bin/play.rs b/player/src/bin/play.rs index c94e57875c1..a053e932f04 100644 --- a/player/src/bin/play.rs +++ b/player/src/bin/play.rs @@ -68,7 +68,8 @@ fn main() { .build(&event_loop) .unwrap(); - let global = wgc::global::Global::new("player", &wgt::InstanceDescriptor::default()); + let global = + wgc::global::Global::new("player", &wgt::InstanceDescriptor::from_env_or_default()); let mut command_encoder_id_manager = IdentityManager::new(); let mut command_buffer_id_manager = IdentityManager::new(); From 445ecb3fee060e02e5e3d2989e254926e053c836 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Mon, 11 Aug 2025 17:10:26 -0400 Subject: [PATCH 120/303] Update backport label ref. in `release-checklist.md` & style fixes (#8081) * docs(release-checklist): sync backporting label name with current one * style(release-checklist): run `prettier` From a96a6cd63b0d12a8fe8ac192d1f3b8f2ec4071f5 Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Tue, 12 Aug 2025 09:49:16 -0700 Subject: [PATCH 121/303] Update to slab 0.4.11. (#8088) --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 90e59c7d793..7b889e07420 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3836,9 +3836,9 @@ checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "slab" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] name = "slotmap" From 01b3204e7f911256deb2263194e54770c5a9999e Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Tue, 12 Aug 2025 09:54:04 -0700 Subject: [PATCH 122/303] [hal] Minor doc clarification. (#8087) Don't use the term "single-threaded", since it's confusing. Just say what you mean. --- wgpu-hal/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index e6b4e0b0f89..331af72baf7 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -1053,9 +1053,9 @@ pub trait Queue: WasmNotSendSync { /// Update `fence` to `value` when the operation is complete. See /// [`Fence`] for details. /// - /// A `wgpu_hal` queue is "single threaded": all command buffers are - /// executed in the order they're submitted, with each buffer able to see - /// previous buffers' results. Specifically: + /// All command buffers submitted to a `wgpu_hal` queue are executed in the + /// order they're submitted, with each buffer able to observe the effects of + /// previous buffers' execution. Specifically: /// /// - If two calls to `submit` on a single `Queue` occur in a particular /// order (that is, they happen on the same thread, or on two threads that From 486c15177268805e4952ba635fb358423e8eb00a Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Wed, 13 Aug 2025 14:35:20 +0100 Subject: [PATCH 123/303] [dx12,vulkan] Add support for P010 texture format (#8086) P010 is a 4:2:0 chroma subsampled planar format, similar to NV12. Each component uses 16 bits of storage, of which only the high 10 bits are used. On DX12 this maps to DXGI_FORMAT_P010, and on Vulkan this maps to G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16. The existing "nv12" gpu test module has been renamed to "planar_texture", and a new test P010_TEXTURE_CREATION_SAMPLING has been added similar to the existing NV12_TEXTURE_CREATION_SAMPLING. The remaining tests in this module have been converted to validation tests, and now test both NV12 and P010 formats. --- tests/src/lib.rs | 2 +- tests/tests/wgpu-gpu/main.rs | 4 +- tests/tests/wgpu-gpu/nv12_texture/mod.rs | 277 ------------------ tests/tests/wgpu-gpu/planar_texture/mod.rs | 189 ++++++++++++ .../planar_texture.wgsl} | 0 tests/tests/wgpu-validation/api/texture.rs | 244 +++++++++++++++ wgpu-core/src/command/clear.rs | 6 +- wgpu-core/src/validation.rs | 1 + wgpu-hal/src/auxil/dxgi/conv.rs | 1 + wgpu-hal/src/dx12/adapter.rs | 29 ++ wgpu-hal/src/gles/adapter.rs | 1 + wgpu-hal/src/gles/conv.rs | 1 + wgpu-hal/src/lib.rs | 2 +- wgpu-hal/src/metal/adapter.rs | 2 + wgpu-hal/src/vulkan/adapter.rs | 18 ++ wgpu-hal/src/vulkan/conv.rs | 1 + wgpu-info/src/texture.rs | 3 +- wgpu-types/src/features.rs | 54 ++-- wgpu-types/src/lib.rs | 45 ++- 19 files changed, 570 insertions(+), 310 deletions(-) delete mode 100644 tests/tests/wgpu-gpu/nv12_texture/mod.rs create mode 100644 tests/tests/wgpu-gpu/planar_texture/mod.rs rename tests/tests/wgpu-gpu/{nv12_texture/nv12_texture.wgsl => planar_texture/planar_texture.wgsl} (100%) diff --git a/tests/src/lib.rs b/tests/src/lib.rs index b3f65351e4a..22afd7ecf77 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -37,7 +37,7 @@ pub use wgpu_macros::gpu_test; pub fn fail( device: &wgpu::Device, callback: impl FnOnce() -> T, - expected_msg_substring: Option<&'static str>, + expected_msg_substring: Option<&str>, ) -> T { device.push_error_scope(wgpu::ErrorFilter::Validation); let result = callback(); diff --git a/tests/tests/wgpu-gpu/main.rs b/tests/tests/wgpu-gpu/main.rs index 98793419e15..d461845e92b 100644 --- a/tests/tests/wgpu-gpu/main.rs +++ b/tests/tests/wgpu-gpu/main.rs @@ -36,12 +36,12 @@ mod instance; mod life_cycle; mod mem_leaks; mod mesh_shader; -mod nv12_texture; mod occlusion_query; mod oob_indexing; mod oom; mod pipeline; mod pipeline_cache; +mod planar_texture; mod poll; mod push_constants; mod query_set; @@ -96,12 +96,12 @@ fn all_tests() -> Vec { life_cycle::all_tests(&mut tests); mem_leaks::all_tests(&mut tests); mesh_shader::all_tests(&mut tests); - nv12_texture::all_tests(&mut tests); occlusion_query::all_tests(&mut tests); oob_indexing::all_tests(&mut tests); oom::all_tests(&mut tests); pipeline_cache::all_tests(&mut tests); pipeline::all_tests(&mut tests); + planar_texture::all_tests(&mut tests); poll::all_tests(&mut tests); push_constants::all_tests(&mut tests); query_set::all_tests(&mut tests); diff --git a/tests/tests/wgpu-gpu/nv12_texture/mod.rs b/tests/tests/wgpu-gpu/nv12_texture/mod.rs deleted file mode 100644 index ced957ca382..00000000000 --- a/tests/tests/wgpu-gpu/nv12_texture/mod.rs +++ /dev/null @@ -1,277 +0,0 @@ -//! Tests for nv12 texture creation and sampling. - -use wgpu_test::{fail, gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; - -pub fn all_tests(tests: &mut Vec) { - tests.extend([ - NV12_TEXTURE_CREATION_SAMPLING, - NV12_TEXTURE_VIEW_PLANE_ON_NON_PLANAR_FORMAT, - NV12_TEXTURE_VIEW_PLANE_OUT_OF_BOUNDS, - NV12_TEXTURE_BAD_FORMAT_VIEW_PLANE, - NV12_TEXTURE_BAD_SIZE, - ]); -} - -#[gpu_test] -static NV12_TEXTURE_CREATION_SAMPLING: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters( - TestParameters::default() - .features(wgpu::Features::TEXTURE_FORMAT_NV12) - .enable_noop(), - ) - .run_sync(|ctx| { - let size = wgpu::Extent3d { - width: 256, - height: 256, - depth_or_array_layers: 1, - }; - let target_format = wgpu::TextureFormat::Bgra8UnormSrgb; - - let shader = ctx - .device - .create_shader_module(wgpu::include_wgsl!("nv12_texture.wgsl")); - let pipeline = ctx - .device - .create_render_pipeline(&wgpu::RenderPipelineDescriptor { - label: Some("nv12 pipeline"), - layout: None, - vertex: wgpu::VertexState { - module: &shader, - entry_point: Some("vs_main"), - compilation_options: Default::default(), - buffers: &[], - }, - fragment: Some(wgpu::FragmentState { - module: &shader, - entry_point: Some("fs_main"), - compilation_options: Default::default(), - targets: &[Some(target_format.into())], - }), - primitive: wgpu::PrimitiveState { - topology: wgpu::PrimitiveTopology::TriangleStrip, - strip_index_format: Some(wgpu::IndexFormat::Uint32), - ..Default::default() - }, - depth_stencil: None, - multisample: wgpu::MultisampleState::default(), - multiview: None, - cache: None, - }); - - let tex = ctx.device.create_texture(&wgpu::TextureDescriptor { - label: None, - dimension: wgpu::TextureDimension::D2, - size, - format: wgpu::TextureFormat::NV12, - usage: wgpu::TextureUsages::TEXTURE_BINDING, - mip_level_count: 1, - sample_count: 1, - view_formats: &[], - }); - let y_view = tex.create_view(&wgpu::TextureViewDescriptor { - format: Some(wgpu::TextureFormat::R8Unorm), - aspect: wgpu::TextureAspect::Plane0, - ..Default::default() - }); - let uv_view = tex.create_view(&wgpu::TextureViewDescriptor { - format: Some(wgpu::TextureFormat::Rg8Unorm), - aspect: wgpu::TextureAspect::Plane1, - ..Default::default() - }); - let sampler = ctx.device.create_sampler(&wgpu::SamplerDescriptor { - min_filter: wgpu::FilterMode::Linear, - mag_filter: wgpu::FilterMode::Linear, - ..Default::default() - }); - let bind_group = ctx.device.create_bind_group(&wgpu::BindGroupDescriptor { - label: None, - layout: &pipeline.get_bind_group_layout(0), - entries: &[ - wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::Sampler(&sampler), - }, - wgpu::BindGroupEntry { - binding: 1, - resource: wgpu::BindingResource::TextureView(&y_view), - }, - wgpu::BindGroupEntry { - binding: 2, - resource: wgpu::BindingResource::TextureView(&uv_view), - }, - ], - }); - - let target_tex = ctx.device.create_texture(&wgpu::TextureDescriptor { - label: None, - size, - mip_level_count: 1, - sample_count: 1, - dimension: wgpu::TextureDimension::D2, - format: target_format, - usage: wgpu::TextureUsages::RENDER_ATTACHMENT, - view_formats: &[], - }); - let target_view = target_tex.create_view(&wgpu::TextureViewDescriptor::default()); - - let mut encoder = ctx - .device - .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); - let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: None, - color_attachments: &[Some(wgpu::RenderPassColorAttachment { - ops: wgpu::Operations::default(), - resolve_target: None, - view: &target_view, - depth_slice: None, - })], - depth_stencil_attachment: None, - timestamp_writes: None, - occlusion_query_set: None, - }); - rpass.set_pipeline(&pipeline); - rpass.set_bind_group(0, &bind_group, &[]); - rpass.draw(0..4, 0..1); - drop(rpass); - ctx.queue.submit(Some(encoder.finish())); - }); - -#[gpu_test] -static NV12_TEXTURE_VIEW_PLANE_ON_NON_PLANAR_FORMAT: GpuTestConfiguration = - GpuTestConfiguration::new() - .parameters( - TestParameters::default() - .features(wgpu::Features::TEXTURE_FORMAT_NV12) - .enable_noop(), - ) - .run_sync(|ctx| { - let size = wgpu::Extent3d { - width: 256, - height: 256, - depth_or_array_layers: 1, - }; - let tex = ctx.device.create_texture(&wgpu::TextureDescriptor { - label: None, - dimension: wgpu::TextureDimension::D2, - size, - format: wgpu::TextureFormat::R8Unorm, - usage: wgpu::TextureUsages::TEXTURE_BINDING, - mip_level_count: 1, - sample_count: 1, - view_formats: &[], - }); - fail( - &ctx.device, - || { - let _ = tex.create_view(&wgpu::TextureViewDescriptor { - aspect: wgpu::TextureAspect::Plane0, - ..Default::default() - }); - }, - Some("aspect plane0 is not in the source texture format r8unorm"), - ); - }); - -#[gpu_test] -static NV12_TEXTURE_VIEW_PLANE_OUT_OF_BOUNDS: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters( - TestParameters::default() - .features(wgpu::Features::TEXTURE_FORMAT_NV12) - .enable_noop(), - ) - .run_sync(|ctx| { - let size = wgpu::Extent3d { - width: 256, - height: 256, - depth_or_array_layers: 1, - }; - let tex = ctx.device.create_texture(&wgpu::TextureDescriptor { - label: None, - dimension: wgpu::TextureDimension::D2, - size, - format: wgpu::TextureFormat::NV12, - usage: wgpu::TextureUsages::TEXTURE_BINDING, - mip_level_count: 1, - sample_count: 1, - view_formats: &[], - }); - fail( - &ctx.device, - || { - let _ = tex.create_view(&wgpu::TextureViewDescriptor { - format: Some(wgpu::TextureFormat::R8Unorm), - aspect: wgpu::TextureAspect::Plane2, - ..Default::default() - }); - }, - Some("aspect plane2 is not in the source texture format nv12"), - ); - }); - -#[gpu_test] -static NV12_TEXTURE_BAD_FORMAT_VIEW_PLANE: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters( - TestParameters::default() - .features(wgpu::Features::TEXTURE_FORMAT_NV12) - .enable_noop(), - ) - .run_sync(|ctx| { - let size = wgpu::Extent3d { - width: 256, - height: 256, - depth_or_array_layers: 1, - }; - let tex = ctx.device.create_texture(&wgpu::TextureDescriptor { - label: None, - dimension: wgpu::TextureDimension::D2, - size, - format: wgpu::TextureFormat::NV12, - usage: wgpu::TextureUsages::TEXTURE_BINDING, - mip_level_count: 1, - sample_count: 1, - view_formats: &[], - }); - fail( - &ctx.device, - || { - let _ = tex.create_view(&wgpu::TextureViewDescriptor { - format: Some(wgpu::TextureFormat::Rg8Unorm), - aspect: wgpu::TextureAspect::Plane0, - ..Default::default() - }); - }, - Some("unable to view texture nv12 as rg8unorm"), - ); - }); - -#[gpu_test] -static NV12_TEXTURE_BAD_SIZE: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters( - TestParameters::default() - .features(wgpu::Features::TEXTURE_FORMAT_NV12) - .enable_noop(), - ) - .run_sync(|ctx| { - let size = wgpu::Extent3d { - width: 255, - height: 255, - depth_or_array_layers: 1, - }; - - fail( - &ctx.device, - || { - let _ = ctx.device.create_texture(&wgpu::TextureDescriptor { - label: None, - dimension: wgpu::TextureDimension::D2, - size, - format: wgpu::TextureFormat::NV12, - usage: wgpu::TextureUsages::TEXTURE_BINDING, - mip_level_count: 1, - sample_count: 1, - view_formats: &[], - }); - }, - Some("width 255 is not a multiple of nv12's width multiple requirement"), - ); - }); diff --git a/tests/tests/wgpu-gpu/planar_texture/mod.rs b/tests/tests/wgpu-gpu/planar_texture/mod.rs new file mode 100644 index 00000000000..961d4b43f64 --- /dev/null +++ b/tests/tests/wgpu-gpu/planar_texture/mod.rs @@ -0,0 +1,189 @@ +//! Tests for nv12 texture creation and sampling. + +use wgpu_test::{ + gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(tests: &mut Vec) { + tests.extend([ + NV12_TEXTURE_CREATION_SAMPLING, + P010_TEXTURE_CREATION_SAMPLING, + ]); +} + +// Helper function to test planar texture creation and sampling. +fn test_planar_texture_creation_sampling( + ctx: &TestingContext, + y_view: &wgpu::TextureView, + uv_view: &wgpu::TextureView, +) { + let target_format = wgpu::TextureFormat::Bgra8UnormSrgb; + + let shader = ctx + .device + .create_shader_module(wgpu::include_wgsl!("planar_texture.wgsl")); + let pipeline = ctx + .device + .create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("planar texture pipeline"), + layout: None, + vertex: wgpu::VertexState { + module: &shader, + entry_point: Some("vs_main"), + compilation_options: Default::default(), + buffers: &[], + }, + fragment: Some(wgpu::FragmentState { + module: &shader, + entry_point: Some("fs_main"), + compilation_options: Default::default(), + targets: &[Some(target_format.into())], + }), + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::TriangleStrip, + strip_index_format: Some(wgpu::IndexFormat::Uint32), + ..Default::default() + }, + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), + multiview: None, + cache: None, + }); + + let sampler = ctx.device.create_sampler(&wgpu::SamplerDescriptor { + min_filter: wgpu::FilterMode::Linear, + mag_filter: wgpu::FilterMode::Linear, + ..Default::default() + }); + let bind_group = ctx.device.create_bind_group(&wgpu::BindGroupDescriptor { + label: None, + layout: &pipeline.get_bind_group_layout(0), + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::Sampler(&sampler), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::TextureView(y_view), + }, + wgpu::BindGroupEntry { + binding: 2, + resource: wgpu::BindingResource::TextureView(uv_view), + }, + ], + }); + + let target_tex = ctx.device.create_texture(&wgpu::TextureDescriptor { + label: None, + size: y_view.texture().size(), + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: target_format, + usage: wgpu::TextureUsages::RENDER_ATTACHMENT, + view_formats: &[], + }); + let target_view = target_tex.create_view(&wgpu::TextureViewDescriptor::default()); + + let mut encoder = ctx + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); + let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: None, + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + ops: wgpu::Operations::default(), + resolve_target: None, + view: &target_view, + depth_slice: None, + })], + depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, + }); + rpass.set_pipeline(&pipeline); + rpass.set_bind_group(0, &bind_group, &[]); + rpass.draw(0..4, 0..1); + drop(rpass); + ctx.queue.submit(Some(encoder.finish())); +} + +/// Ensures that creation and sampling of an NV12 format texture works as +/// expected. +#[gpu_test] +static NV12_TEXTURE_CREATION_SAMPLING: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters( + TestParameters::default() + .features(wgpu::Features::TEXTURE_FORMAT_NV12) + .enable_noop(), + ) + .run_sync(|ctx| { + let size = wgpu::Extent3d { + width: 256, + height: 256, + depth_or_array_layers: 1, + }; + let tex = ctx.device.create_texture(&wgpu::TextureDescriptor { + label: None, + dimension: wgpu::TextureDimension::D2, + size, + format: wgpu::TextureFormat::NV12, + usage: wgpu::TextureUsages::TEXTURE_BINDING, + mip_level_count: 1, + sample_count: 1, + view_formats: &[], + }); + let y_view = tex.create_view(&wgpu::TextureViewDescriptor { + format: Some(wgpu::TextureFormat::R8Unorm), + aspect: wgpu::TextureAspect::Plane0, + ..Default::default() + }); + let uv_view = tex.create_view(&wgpu::TextureViewDescriptor { + format: Some(wgpu::TextureFormat::Rg8Unorm), + aspect: wgpu::TextureAspect::Plane1, + ..Default::default() + }); + + test_planar_texture_creation_sampling(&ctx, &y_view, &uv_view); + }); + +/// Ensures that creation and sampling of a P010 format texture works as +/// expected. +#[gpu_test] +static P010_TEXTURE_CREATION_SAMPLING: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters( + TestParameters::default() + .features( + wgpu::Features::TEXTURE_FORMAT_P010 | wgpu::Features::TEXTURE_FORMAT_16BIT_NORM, + ) + .enable_noop(), + ) + .run_sync(|ctx| { + let size = wgpu::Extent3d { + width: 256, + height: 256, + depth_or_array_layers: 1, + }; + let tex = ctx.device.create_texture(&wgpu::TextureDescriptor { + label: None, + dimension: wgpu::TextureDimension::D2, + size, + format: wgpu::TextureFormat::P010, + usage: wgpu::TextureUsages::TEXTURE_BINDING, + mip_level_count: 1, + sample_count: 1, + view_formats: &[], + }); + let y_view = tex.create_view(&wgpu::TextureViewDescriptor { + format: Some(wgpu::TextureFormat::R16Unorm), + aspect: wgpu::TextureAspect::Plane0, + ..Default::default() + }); + let uv_view = tex.create_view(&wgpu::TextureViewDescriptor { + format: Some(wgpu::TextureFormat::Rg16Unorm), + aspect: wgpu::TextureAspect::Plane1, + ..Default::default() + }); + + test_planar_texture_creation_sampling(&ctx, &y_view, &uv_view); + }); diff --git a/tests/tests/wgpu-gpu/nv12_texture/nv12_texture.wgsl b/tests/tests/wgpu-gpu/planar_texture/planar_texture.wgsl similarity index 100% rename from tests/tests/wgpu-gpu/nv12_texture/nv12_texture.wgsl rename to tests/tests/wgpu-gpu/planar_texture/planar_texture.wgsl diff --git a/tests/tests/wgpu-validation/api/texture.rs b/tests/tests/wgpu-validation/api/texture.rs index 2b079cc3a78..4b1e93ebb16 100644 --- a/tests/tests/wgpu-validation/api/texture.rs +++ b/tests/tests/wgpu-validation/api/texture.rs @@ -1,5 +1,7 @@ //! Tests of [`wgpu::Texture`] and related. +use wgpu_test::{fail, valid}; + /// Ensures that submitting a command buffer referencing an already destroyed texture /// results in an error. #[test] @@ -54,3 +56,245 @@ fn destroyed_texture() { queue.submit([encoder.finish()]); } + +/// Ensures that creating a texture view from a specific plane of a planar +/// texture works as expected. +#[test] +fn planar_texture_view_plane() { + let required_features = wgpu::Features::TEXTURE_FORMAT_NV12 + | wgpu::Features::TEXTURE_FORMAT_P010 + | wgpu::Features::TEXTURE_FORMAT_16BIT_NORM; + let device_desc = wgpu::DeviceDescriptor { + required_features, + ..Default::default() + }; + let (device, _queue) = wgpu::Device::noop(&device_desc); + let size = wgpu::Extent3d { + width: 256, + height: 256, + depth_or_array_layers: 1, + }; + + for (tex_format, view_format, view_aspect) in [ + ( + wgpu::TextureFormat::NV12, + wgpu::TextureFormat::R8Unorm, + wgpu::TextureAspect::Plane0, + ), + ( + wgpu::TextureFormat::NV12, + wgpu::TextureFormat::Rg8Unorm, + wgpu::TextureAspect::Plane1, + ), + ( + wgpu::TextureFormat::P010, + wgpu::TextureFormat::R16Unorm, + wgpu::TextureAspect::Plane0, + ), + ( + wgpu::TextureFormat::P010, + wgpu::TextureFormat::Rg16Unorm, + wgpu::TextureAspect::Plane1, + ), + ] { + let tex = device.create_texture(&wgpu::TextureDescriptor { + label: None, + dimension: wgpu::TextureDimension::D2, + size, + format: tex_format, + usage: wgpu::TextureUsages::TEXTURE_BINDING, + mip_level_count: 1, + sample_count: 1, + view_formats: &[], + }); + valid(&device, || { + let _ = tex.create_view(&wgpu::TextureViewDescriptor { + format: Some(view_format), + aspect: view_aspect, + ..Default::default() + }); + }); + } +} + +/// Ensures that attempting to create a texture view from a specific plane of a +/// non-planar texture fails validation. +#[test] +fn non_planar_texture_view_plane() { + let (device, _queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + let size = wgpu::Extent3d { + width: 256, + height: 256, + depth_or_array_layers: 1, + }; + let tex = device.create_texture(&wgpu::TextureDescriptor { + label: None, + dimension: wgpu::TextureDimension::D2, + size, + format: wgpu::TextureFormat::R8Unorm, + usage: wgpu::TextureUsages::TEXTURE_BINDING, + mip_level_count: 1, + sample_count: 1, + view_formats: &[], + }); + fail( + &device, + || { + let _ = tex.create_view(&wgpu::TextureViewDescriptor { + aspect: wgpu::TextureAspect::Plane0, + ..Default::default() + }); + }, + Some("Aspect Plane0 is not in the source texture format R8Unorm"), + ); +} + +/// Ensures that attempting to create a texture view from an invalid plane of a +/// planar texture fails validation. +#[test] +fn planar_texture_view_plane_out_of_bounds() { + let required_features = wgpu::Features::TEXTURE_FORMAT_NV12 + | wgpu::Features::TEXTURE_FORMAT_P010 + | wgpu::Features::TEXTURE_FORMAT_16BIT_NORM; + let device_desc = wgpu::DeviceDescriptor { + required_features, + ..Default::default() + }; + let (device, _queue) = wgpu::Device::noop(&device_desc); + let size = wgpu::Extent3d { + width: 256, + height: 256, + depth_or_array_layers: 1, + }; + + for (tex_format, view_format, view_aspect) in [ + ( + wgpu::TextureFormat::NV12, + wgpu::TextureFormat::R8Unorm, + wgpu::TextureAspect::Plane2, + ), + ( + wgpu::TextureFormat::P010, + wgpu::TextureFormat::R16Unorm, + wgpu::TextureAspect::Plane2, + ), + ] { + let tex = device.create_texture(&wgpu::TextureDescriptor { + label: None, + dimension: wgpu::TextureDimension::D2, + size, + format: tex_format, + usage: wgpu::TextureUsages::TEXTURE_BINDING, + mip_level_count: 1, + sample_count: 1, + view_formats: &[], + }); + fail( + &device, + || { + let _ = tex.create_view(&wgpu::TextureViewDescriptor { + format: Some(view_format), + aspect: view_aspect, + ..Default::default() + }); + }, + Some(&format!( + "Aspect {view_aspect:?} is not in the source texture format {tex_format:?}" + )), + ); + } +} + +/// Ensures that attempting to create a texture view from a specific plane of a +/// planar texture with an invalid format fails validation. +#[test] +fn planar_texture_view_plane_bad_format() { + let required_features = wgpu::Features::TEXTURE_FORMAT_NV12 + | wgpu::Features::TEXTURE_FORMAT_P010 + | wgpu::Features::TEXTURE_FORMAT_16BIT_NORM; + let device_desc = wgpu::DeviceDescriptor { + required_features, + ..Default::default() + }; + let (device, _queue) = wgpu::Device::noop(&device_desc); + let size = wgpu::Extent3d { + width: 256, + height: 256, + depth_or_array_layers: 1, + }; + for (tex_format, view_format, view_aspect) in [ + ( + wgpu::TextureFormat::NV12, + wgpu::TextureFormat::Rg8Unorm, + wgpu::TextureAspect::Plane0, + ), + ( + wgpu::TextureFormat::P010, + wgpu::TextureFormat::Rg16Unorm, + wgpu::TextureAspect::Plane0, + ), + ] { + let tex = device.create_texture(&wgpu::TextureDescriptor { + label: None, + dimension: wgpu::TextureDimension::D2, + size, + format: tex_format, + usage: wgpu::TextureUsages::TEXTURE_BINDING, + mip_level_count: 1, + sample_count: 1, + view_formats: &[], + }); + fail( + &device, + || { + let _ = tex.create_view(&wgpu::TextureViewDescriptor { + format: Some(view_format), + aspect: view_aspect, + ..Default::default() + }); + }, + Some(&format!( + "unable to view texture {tex_format:?} as {view_format:?}" + )), + ); + } +} + +/// Ensures that attempting to create a planar texture with an invalid size +/// fails validation. +#[test] +fn planar_texture_bad_size() { + let required_features = + wgpu::Features::TEXTURE_FORMAT_NV12 | wgpu::Features::TEXTURE_FORMAT_P010; + let device_desc = wgpu::DeviceDescriptor { + required_features, + ..Default::default() + }; + let (device, _queue) = wgpu::Device::noop(&device_desc); + let size = wgpu::Extent3d { + width: 255, + height: 255, + depth_or_array_layers: 1, + }; + for format in [wgpu::TextureFormat::NV12, wgpu::TextureFormat::P010] { + fail( + &device, + || { + let _ = device.create_texture(&wgpu::TextureDescriptor { + label: None, + dimension: wgpu::TextureDimension::D2, + size, + format, + usage: wgpu::TextureUsages::TEXTURE_BINDING, + mip_level_count: 1, + sample_count: 1, + view_formats: &[], + }); + }, + Some(&format!( + "width {} is not a multiple of {format:?}'s width multiple requirement", + size.width + )), + ); + } +} diff --git a/wgpu-core/src/command/clear.rs b/wgpu-core/src/command/clear.rs index 593382aa931..840e9068125 100644 --- a/wgpu-core/src/command/clear.rs +++ b/wgpu-core/src/command/clear.rs @@ -373,8 +373,10 @@ fn clear_texture_via_buffer_copies( ) { assert!(!texture_desc.format.is_depth_stencil_format()); - if texture_desc.format == wgt::TextureFormat::NV12 { - // TODO: Currently COPY_DST for NV12 textures is unsupported. + if texture_desc.format == wgt::TextureFormat::NV12 + || texture_desc.format == wgt::TextureFormat::P010 + { + // TODO: Currently COPY_DST for NV12 and P010 textures is unsupported. return; } diff --git a/wgpu-core/src/validation.rs b/wgpu-core/src/validation.rs index 2127604064d..2c2f4b36c44 100644 --- a/wgpu-core/src/validation.rs +++ b/wgpu-core/src/validation.rs @@ -817,6 +817,7 @@ impl NumericType { panic!("Unexpected depth format") } Tf::NV12 => panic!("Unexpected nv12 format"), + Tf::P010 => panic!("Unexpected p010 format"), Tf::Rgb9e5Ufloat => (NumericDimension::Vector(Vs::Tri), Scalar::F32), Tf::Bc1RgbaUnorm | Tf::Bc1RgbaUnormSrgb diff --git a/wgpu-hal/src/auxil/dxgi/conv.rs b/wgpu-hal/src/auxil/dxgi/conv.rs index a53934258dc..6e27081aac4 100644 --- a/wgpu-hal/src/auxil/dxgi/conv.rs +++ b/wgpu-hal/src/auxil/dxgi/conv.rs @@ -68,6 +68,7 @@ pub fn map_texture_format_failable( Tf::Depth32Float => DXGI_FORMAT_D32_FLOAT, Tf::Depth32FloatStencil8 => DXGI_FORMAT_D32_FLOAT_S8X24_UINT, Tf::NV12 => DXGI_FORMAT_NV12, + Tf::P010 => DXGI_FORMAT_P010, Tf::Bc1RgbaUnorm => DXGI_FORMAT_BC1_UNORM, Tf::Bc1RgbaUnormSrgb => DXGI_FORMAT_BC1_UNORM_SRGB, Tf::Bc2RgbaUnorm => DXGI_FORMAT_BC2_UNORM, diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index b8b908279e0..fd045ea03d9 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -414,6 +414,35 @@ impl super::Adapter { bgra8unorm_storage_supported, ); + let p010_format_supported = { + let mut p010_info = Direct3D12::D3D12_FEATURE_DATA_FORMAT_SUPPORT { + Format: Dxgi::Common::DXGI_FORMAT_P010, + ..Default::default() + }; + let hr = unsafe { + device.CheckFeatureSupport( + Direct3D12::D3D12_FEATURE_FORMAT_SUPPORT, + <*mut _>::cast(&mut p010_info), + size_of_val(&p010_info) as u32, + ) + }; + if hr.is_ok() { + let supports_texture2d = p010_info + .Support1 + .contains(Direct3D12::D3D12_FORMAT_SUPPORT1_TEXTURE2D); + let supports_shader_load = p010_info + .Support1 + .contains(Direct3D12::D3D12_FORMAT_SUPPORT1_SHADER_LOAD); + let supports_shader_sample = p010_info + .Support1 + .contains(Direct3D12::D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE); + supports_texture2d && supports_shader_load && supports_shader_sample + } else { + false + } + }; + features.set(wgt::Features::TEXTURE_FORMAT_P010, p010_format_supported); + let mut features1 = Direct3D12::D3D12_FEATURE_DATA_D3D12_OPTIONS1::default(); let hr = unsafe { device.CheckFeatureSupport( diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index 865f35013c7..87e8caff667 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -1165,6 +1165,7 @@ impl crate::Adapter for super::Adapter { | Tf::Depth24Plus | Tf::Depth24PlusStencil8 => depth, Tf::NV12 => empty, + Tf::P010 => empty, Tf::Rgb9e5Ufloat => filterable, Tf::Bc1RgbaUnorm | Tf::Bc1RgbaUnormSrgb diff --git a/wgpu-hal/src/gles/conv.rs b/wgpu-hal/src/gles/conv.rs index 7348f2f19ee..b9dd545d562 100644 --- a/wgpu-hal/src/gles/conv.rs +++ b/wgpu-hal/src/gles/conv.rs @@ -89,6 +89,7 @@ impl super::AdapterShared { glow::UNSIGNED_INT_24_8, ), Tf::NV12 => unreachable!(), + Tf::P010 => unreachable!(), Tf::Rgb9e5Ufloat => (glow::RGB9_E5, glow::RGB, glow::UNSIGNED_INT_5_9_9_9_REV), Tf::Bc1RgbaUnorm => (glow::COMPRESSED_RGBA_S3TC_DXT1_EXT, glow::RGBA, 0), Tf::Bc1RgbaUnormSrgb => (glow::COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, glow::RGBA, 0), diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 331af72baf7..e60b07e9a6a 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -1734,7 +1734,7 @@ impl From for FormatAspects { wgt::TextureFormat::Depth32FloatStencil8 | wgt::TextureFormat::Depth24PlusStencil8 => { Self::DEPTH_STENCIL } - wgt::TextureFormat::NV12 => Self::PLANE_0 | Self::PLANE_1, + wgt::TextureFormat::NV12 | wgt::TextureFormat::P010 => Self::PLANE_0 | Self::PLANE_1, _ => Self::COLOR, } } diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index 7ab14ca76d2..d02e38980ac 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -290,6 +290,7 @@ impl crate::Adapter for super::Adapter { flags } Tf::NV12 => return Tfc::empty(), + Tf::P010 => return Tfc::empty(), Tf::Rgb9e5Ufloat => { if pc.msaa_apple3 { all_caps @@ -1175,6 +1176,7 @@ impl super::PrivateCapabilities { } } Tf::NV12 => unreachable!(), + Tf::P010 => unreachable!(), Tf::Rgb9e5Ufloat => MTL::RGB9E5Float, Tf::Bc1RgbaUnorm => MTL::BC1_RGBA, Tf::Bc1RgbaUnormSrgb => MTL::BC1_RGBA_sRGB, diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 19c1ffe4ca7..bb4e2a9d4ae 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -850,6 +850,24 @@ impl PhysicalDeviceFeatures { ); } + if let Some(ref _sampler_ycbcr_conversion) = self.sampler_ycbcr_conversion { + features.set( + F::TEXTURE_FORMAT_P010, + supports_format( + instance, + phd, + vk::Format::G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16, + vk::ImageTiling::OPTIMAL, + vk::FormatFeatureFlags::SAMPLED_IMAGE + | vk::FormatFeatureFlags::TRANSFER_SRC + | vk::FormatFeatureFlags::TRANSFER_DST, + ) && !caps + .driver + .map(|driver| driver.driver_id == vk::DriverId::MOLTENVK) + .unwrap_or_default(), + ); + } + features.set( F::VULKAN_GOOGLE_DISPLAY_TIMING, caps.supports_extension(google::display_timing::NAME), diff --git a/wgpu-hal/src/vulkan/conv.rs b/wgpu-hal/src/vulkan/conv.rs index 5d067c0ef0f..e6bcb20ca75 100644 --- a/wgpu-hal/src/vulkan/conv.rs +++ b/wgpu-hal/src/vulkan/conv.rs @@ -78,6 +78,7 @@ impl super::PrivateCapabilities { } Tf::Depth16Unorm => F::D16_UNORM, Tf::NV12 => F::G8_B8R8_2PLANE_420_UNORM, + Tf::P010 => F::G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16, Tf::Rgb9e5Ufloat => F::E5B9G9R9_UFLOAT_PACK32, Tf::Bc1RgbaUnorm => F::BC1_RGBA_UNORM_BLOCK, Tf::Bc1RgbaUnormSrgb => F::BC1_RGBA_SRGB_BLOCK, diff --git a/wgpu-info/src/texture.rs b/wgpu-info/src/texture.rs index 64325f0e5bc..5c9c385fab3 100644 --- a/wgpu-info/src/texture.rs +++ b/wgpu-info/src/texture.rs @@ -1,6 +1,6 @@ // Lets keep these on one line #[rustfmt::skip] -pub const TEXTURE_FORMAT_LIST: [wgpu::TextureFormat; 117] = [ +pub const TEXTURE_FORMAT_LIST: [wgpu::TextureFormat; 118] = [ wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Snorm, wgpu::TextureFormat::R8Uint, @@ -52,6 +52,7 @@ pub const TEXTURE_FORMAT_LIST: [wgpu::TextureFormat; 117] = [ wgpu::TextureFormat::Depth32Float, wgpu::TextureFormat::Depth32FloatStencil8, wgpu::TextureFormat::NV12, + wgpu::TextureFormat::P010, wgpu::TextureFormat::Bc1RgbaUnorm, wgpu::TextureFormat::Bc1RgbaUnormSrgb, wgpu::TextureFormat::Bc2RgbaUnorm, diff --git a/wgpu-types/src/features.rs b/wgpu-types/src/features.rs index 908d5bda203..af3a920cd61 100644 --- a/wgpu-types/src/features.rs +++ b/wgpu-types/src/features.rs @@ -984,6 +984,16 @@ bitflags_array! { /// /// [`TextureFormat::NV12`]: super::TextureFormat::NV12 const TEXTURE_FORMAT_NV12 = 1 << 29; + /// Allows for creation of textures of format [`TextureFormat::P010`] + /// + /// Supported platforms: + /// - DX12 + /// - Vulkan + /// + /// This is a native only feature. + /// + /// [`TextureFormat::P010`]: super::TextureFormat::P010 + const TEXTURE_FORMAT_P010 = 1 << 30; /// Allows for the creation and usage of `ExternalTexture`s, and bind /// group layouts containing external texture `BindingType`s. @@ -998,7 +1008,7 @@ bitflags_array! { /// /// Supported platforms: /// - DX12 - const EXTERNAL_TEXTURE = 1 << 30; + const EXTERNAL_TEXTURE = 1 << 31; // Shader: @@ -1012,7 +1022,7 @@ bitflags_array! { /// - Vulkan /// /// This is a native-only feature. - const EXPERIMENTAL_RAY_QUERY = 1 << 31; + const EXPERIMENTAL_RAY_QUERY = 1 << 32; /// Enables 64-bit floating point types in SPIR-V shaders. /// /// Note: even when supported by GPU hardware, 64-bit floating point operations are @@ -1022,14 +1032,14 @@ bitflags_array! { /// - Vulkan /// /// This is a native only feature. - const SHADER_F64 = 1 << 32; + const SHADER_F64 = 1 << 33; /// Allows shaders to use i16. Not currently supported in `naga`, only available through `spirv-passthrough`. /// /// Supported platforms: /// - Vulkan /// /// This is a native only feature. - const SHADER_I16 = 1 << 33; + const SHADER_I16 = 1 << 34; /// Enables `builtin(primitive_index)` in fragment shaders. /// /// Note: enables geometry processing for pipelines using the builtin. @@ -1043,7 +1053,7 @@ bitflags_array! { /// - OpenGL (some) /// /// This is a native only feature. - const SHADER_PRIMITIVE_INDEX = 1 << 34; + const SHADER_PRIMITIVE_INDEX = 1 << 35; /// Allows shaders to use the `early_depth_test` attribute. /// /// The attribute is applied to the fragment shader entry point. It can be used in two @@ -1071,7 +1081,7 @@ bitflags_array! { /// This is a native only feature. /// /// [`EarlyDepthTest`]: https://docs.rs/naga/latest/naga/ir/enum.EarlyDepthTest.html - const SHADER_EARLY_DEPTH_TEST = 1 << 35; + const SHADER_EARLY_DEPTH_TEST = 1 << 36; /// Allows shaders to use i64 and u64. /// /// Supported platforms: @@ -1080,7 +1090,7 @@ bitflags_array! { /// - Metal (with MSL 2.3+) /// /// This is a native only feature. - const SHADER_INT64 = 1 << 36; + const SHADER_INT64 = 1 << 37; /// Allows compute and fragment shaders to use the subgroup operation built-ins /// /// Supported Platforms: @@ -1089,14 +1099,14 @@ bitflags_array! { /// - Metal /// /// This is a native only feature. - const SUBGROUP = 1 << 37; + const SUBGROUP = 1 << 38; /// Allows vertex shaders to use the subgroup operation built-ins /// /// Supported Platforms: /// - Vulkan /// /// This is a native only feature. - const SUBGROUP_VERTEX = 1 << 38; + const SUBGROUP_VERTEX = 1 << 39; /// Allows shaders to use the subgroup barrier /// /// Supported Platforms: @@ -1104,7 +1114,7 @@ bitflags_array! { /// - Metal /// /// This is a native only feature. - const SUBGROUP_BARRIER = 1 << 39; + const SUBGROUP_BARRIER = 1 << 40; /// Allows the use of pipeline cache objects /// /// Supported platforms: @@ -1113,7 +1123,7 @@ bitflags_array! { /// Unimplemented Platforms: /// - DX12 /// - Metal - const PIPELINE_CACHE = 1 << 40; + const PIPELINE_CACHE = 1 << 41; /// Allows shaders to use i64 and u64 atomic min and max. /// /// Supported platforms: @@ -1122,7 +1132,7 @@ bitflags_array! { /// - Metal (with MSL 2.4+) /// /// This is a native only feature. - const SHADER_INT64_ATOMIC_MIN_MAX = 1 << 41; + const SHADER_INT64_ATOMIC_MIN_MAX = 1 << 42; /// Allows shaders to use all i64 and u64 atomic operations. /// /// Supported platforms: @@ -1130,7 +1140,7 @@ bitflags_array! { /// - DX12 (with SM 6.6+) /// /// This is a native only feature. - const SHADER_INT64_ATOMIC_ALL_OPS = 1 << 42; + const SHADER_INT64_ATOMIC_ALL_OPS = 1 << 43; /// Allows using the [VK_GOOGLE_display_timing] Vulkan extension. /// /// This is used for frame pacing to reduce latency, and is generally only available on Android. @@ -1146,7 +1156,7 @@ bitflags_array! { /// /// [VK_GOOGLE_display_timing]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_GOOGLE_display_timing.html /// [`Surface::as_hal()`]: https://docs.rs/wgpu/latest/wgpu/struct.Surface.html#method.as_hal - const VULKAN_GOOGLE_DISPLAY_TIMING = 1 << 43; + const VULKAN_GOOGLE_DISPLAY_TIMING = 1 << 44; /// Allows using the [VK_KHR_external_memory_win32] Vulkan extension. /// @@ -1156,7 +1166,7 @@ bitflags_array! { /// This is a native only feature. /// /// [VK_KHR_external_memory_win32]: https://registry.khronos.org/vulkan/specs/latest/man/html/VK_KHR_external_memory_win32.html - const VULKAN_EXTERNAL_MEMORY_WIN32 = 1 << 44; + const VULKAN_EXTERNAL_MEMORY_WIN32 = 1 << 45; /// Enables R64Uint image atomic min and max. /// @@ -1166,7 +1176,7 @@ bitflags_array! { /// - Metal (with MSL 3.1+) /// /// This is a native only feature. - const TEXTURE_INT64_ATOMIC = 1 << 45; + const TEXTURE_INT64_ATOMIC = 1 << 46; /// Allows uniform buffers to be bound as binding arrays. /// @@ -1183,7 +1193,7 @@ bitflags_array! { /// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s `shaderUniformBufferArrayNonUniformIndexing` feature) /// /// This is a native only feature. - const UNIFORM_BUFFER_BINDING_ARRAYS = 1 << 46; + const UNIFORM_BUFFER_BINDING_ARRAYS = 1 << 47; /// Enables mesh shaders and task shaders in mesh shader pipelines. /// @@ -1195,7 +1205,7 @@ bitflags_array! { /// - Metal /// /// This is a native only feature. - const EXPERIMENTAL_MESH_SHADER = 1 << 47; + const EXPERIMENTAL_MESH_SHADER = 1 << 48; /// ***THIS IS EXPERIMENTAL:*** Features enabled by this may have /// major bugs in them and are expected to be subject to breaking changes, suggestions @@ -1210,7 +1220,7 @@ bitflags_array! { /// This is a native only feature /// /// [`AccelerationStructureFlags::ALLOW_RAY_HIT_VERTEX_RETURN`]: super::AccelerationStructureFlags::ALLOW_RAY_HIT_VERTEX_RETURN - const EXPERIMENTAL_RAY_HIT_VERTEX_RETURN = 1 << 48; + const EXPERIMENTAL_RAY_HIT_VERTEX_RETURN = 1 << 49; /// Enables multiview in mesh shader pipelines /// @@ -1222,7 +1232,7 @@ bitflags_array! { /// - Metal /// /// This is a native only feature. - const EXPERIMENTAL_MESH_SHADER_MULTIVIEW = 1 << 49; + const EXPERIMENTAL_MESH_SHADER_MULTIVIEW = 1 << 50; /// Allows usage of additional vertex formats in [BlasTriangleGeometrySizeDescriptor::vertex_format] /// @@ -1231,7 +1241,7 @@ bitflags_array! { /// - DX12 /// /// [BlasTriangleGeometrySizeDescriptor::vertex_format]: super::BlasTriangleGeometrySizeDescriptor - const EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS = 1 << 50; + const EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS = 1 << 51; /// Enables creating shader modules from DirectX HLSL or DXIL shaders (unsafe) /// @@ -1241,7 +1251,7 @@ bitflags_array! { /// - DX12 /// /// This is a native only feature. - const HLSL_DXIL_SHADER_PASSTHROUGH = 1 << 51; + const HLSL_DXIL_SHADER_PASSTHROUGH = 1 << 52; } /// Features that are not guaranteed to be supported. diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 2e21cb904af..fb71e420262 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -2230,6 +2230,23 @@ pub enum TextureFormat { /// [`Features::TEXTURE_FORMAT_NV12`] must be enabled to use this texture format. NV12, + /// YUV 4:2:0 chroma subsampled format. + /// + /// Contains two planes: + /// - 0: Single 16 bit channel luminance, of which only the high 10 bits + /// are used. + /// - 1: Dual 16 bit channel chrominance at half width and half height, of + /// which only the high 10 bits are used. + /// + /// Valid view formats for luminance are [`TextureFormat::R16Unorm`]. + /// + /// Valid view formats for chrominance are [`TextureFormat::Rg16Unorm`]. + /// + /// Width and height must be even. + /// + /// [`Features::TEXTURE_FORMAT_P010`] must be enabled to use this texture format. + P010, + // Compressed textures usable with `TEXTURE_COMPRESSION_BC` feature. `TEXTURE_COMPRESSION_SLICED_3D` is required to use with 3D textures. /// 4x4 block compressed texture. 8 bytes per block (4 bit/px). 4 color + alpha pallet. 5 bit R + 6 bit G + 5 bit B + 1 bit alpha. /// [0, 63] ([0, 1] for alpha) converted to/from float [0, 1] in shader. @@ -2475,6 +2492,7 @@ impl<'de> Deserialize<'de> for TextureFormat { "depth24plus" => TextureFormat::Depth24Plus, "depth24plus-stencil8" => TextureFormat::Depth24PlusStencil8, "nv12" => TextureFormat::NV12, + "p010" => TextureFormat::P010, "rgb9e5ufloat" => TextureFormat::Rgb9e5Ufloat, "bc1-rgba-unorm" => TextureFormat::Bc1RgbaUnorm, "bc1-rgba-unorm-srgb" => TextureFormat::Bc1RgbaUnormSrgb, @@ -2604,6 +2622,7 @@ impl Serialize for TextureFormat { TextureFormat::Depth24Plus => "depth24plus", TextureFormat::Depth24PlusStencil8 => "depth24plus-stencil8", TextureFormat::NV12 => "nv12", + TextureFormat::P010 => "p010", TextureFormat::Rgb9e5Ufloat => "rgb9e5ufloat", TextureFormat::Bc1RgbaUnorm => "bc1-rgba-unorm", TextureFormat::Bc1RgbaUnormSrgb => "bc1-rgba-unorm-srgb", @@ -2696,6 +2715,8 @@ impl TextureFormat { (Self::Depth32FloatStencil8, TextureAspect::DepthOnly) => Some(Self::Depth32Float), (Self::NV12, TextureAspect::Plane0) => Some(Self::R8Unorm), (Self::NV12, TextureAspect::Plane1) => Some(Self::Rg8Unorm), + (Self::P010, TextureAspect::Plane0) => Some(Self::R16Unorm), + (Self::P010, TextureAspect::Plane1) => Some(Self::Rg16Unorm), // views to multi-planar formats must specify the plane (format, TextureAspect::All) if !format.is_multi_planar_format() => Some(format), _ => None, @@ -2751,6 +2772,7 @@ impl TextureFormat { pub fn planes(&self) -> Option { match *self { Self::NV12 => Some(2), + Self::P010 => Some(2), _ => None, } } @@ -2788,6 +2810,7 @@ impl TextureFormat { pub fn size_multiple_requirement(&self) -> (u32, u32) { match *self { Self::NV12 => (2, 2), + Self::P010 => (2, 2), _ => self.block_dimensions(), } } @@ -2848,7 +2871,8 @@ impl TextureFormat { | Self::Depth24PlusStencil8 | Self::Depth32Float | Self::Depth32FloatStencil8 - | Self::NV12 => (1, 1), + | Self::NV12 + | Self::P010 => (1, 1), Self::Bc1RgbaUnorm | Self::Bc1RgbaUnormSrgb @@ -2966,6 +2990,7 @@ impl TextureFormat { Self::Depth32FloatStencil8 => Features::DEPTH32FLOAT_STENCIL8, Self::NV12 => Features::TEXTURE_FORMAT_NV12, + Self::P010 => Features::TEXTURE_FORMAT_P010, Self::R16Unorm | Self::R16Snorm @@ -3099,8 +3124,10 @@ impl TextureFormat { Self::Depth32Float => ( msaa, attachment), Self::Depth32FloatStencil8 => ( msaa, attachment), - // We only support sampling nv12 textures until we implement transfer plane data. + // We only support sampling nv12 and p010 textures until we + // implement transfer plane data. Self::NV12 => ( none, binding), + Self::P010 => ( none, binding), Self::R16Unorm => ( msaa | s_ro_wo, storage), Self::R16Snorm => ( msaa | s_ro_wo, storage), @@ -3230,7 +3257,7 @@ impl TextureFormat { _ => None, }, - Self::NV12 => match aspect { + Self::NV12 | Self::P010 => match aspect { Some(TextureAspect::Plane0) | Some(TextureAspect::Plane1) => { Some(unfilterable_float) } @@ -3363,6 +3390,12 @@ impl TextureFormat { _ => None, }, + Self::P010 => match aspect { + Some(TextureAspect::Plane0) => Some(2), + Some(TextureAspect::Plane1) => Some(4), + _ => None, + }, + Self::Bc1RgbaUnorm | Self::Bc1RgbaUnormSrgb | Self::Bc4RUnorm | Self::Bc4RSnorm => { Some(8) } @@ -3448,6 +3481,7 @@ impl TextureFormat { | Self::Depth32Float | Self::Depth32FloatStencil8 | Self::NV12 + | Self::P010 | Self::Rgb9e5Ufloat | Self::Bc1RgbaUnorm | Self::Bc1RgbaUnormSrgb @@ -3531,6 +3565,7 @@ impl TextureFormat { | Self::Depth32Float | Self::Depth32FloatStencil8 | Self::NV12 + | Self::P010 | Self::Rgb9e5Ufloat | Self::Bc1RgbaUnorm | Self::Bc1RgbaUnormSrgb @@ -3625,7 +3660,7 @@ impl TextureFormat { _ => 2, }, - Self::NV12 => match aspect { + Self::NV12 | Self::P010 => match aspect { TextureAspect::Plane0 => 1, TextureAspect::Plane1 => 2, _ => 3, @@ -3735,6 +3770,8 @@ impl TextureFormat { Self::Stencil8 => 1, // Two chroma bytes per block, one luma byte per block Self::NV12 => 3, + // Two chroma u16s and one luma u16 per block + Self::P010 => 6, f => { log::warn!("Memory footprint for format {f:?} is not implemented"); 0 From 2e8a600e353cde43ec3c68fa75680ca80d4f7434 Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Sat, 26 Jul 2025 08:50:58 -0700 Subject: [PATCH 124/303] Add `Sync` bound to uncaptured error handler. It makes sense for a function to be `FnMut + Send`, or `Fn + Send + Sync`, but not `Fn + Send` because that is overly restrictive for the caller and the callee. --- CHANGELOG.md | 2 ++ wgpu/src/api/device.rs | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64973330bcc..1c0a30a7408 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,6 +72,8 @@ By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). - Copies of depth/stencil formats must be 4B aligned. - The offset for `set_vertex_buffer` and `set_index_buffer` must be 4B aligned. By @andyleiserson in [#7929](https://github.com/gfx-rs/wgpu/pull/7929). - The offset and size of bindings are validated as fitting within the underlying buffer in more cases. By @andyleiserson in [#7911](https://github.com/gfx-rs/wgpu/pull/7911). +- The function you pass to `Device::on_uncaptured_error()` must now implement `Sync` in addition to `Send`. + By @kpreid in [#8011](https://github.com/gfx-rs/wgpu/pull/8011). #### Naga diff --git a/wgpu/src/api/device.rs b/wgpu/src/api/device.rs index 401431bcbda..8e0e372ddc1 100644 --- a/wgpu/src/api/device.rs +++ b/wgpu/src/api/device.rs @@ -714,9 +714,11 @@ impl From for RequestDeviceError { } } -/// Type for the callback of uncaptured error handler -pub trait UncapturedErrorHandler: Fn(Error) + Send + 'static {} -impl UncapturedErrorHandler for T where T: Fn(Error) + Send + 'static {} +/// The callback of [`Device::on_uncaptured_error()`]. +/// +/// It must be a function with this signature. +pub trait UncapturedErrorHandler: Fn(Error) + Send + Sync + 'static {} +impl UncapturedErrorHandler for T where T: Fn(Error) + Send + Sync + 'static {} /// Kinds of [`Error`]s a [`Device::push_error_scope()`] may be configured to catch. #[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd)] From ea8315e28e05c14da2a502a8a55376dd9eac8bca Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Sat, 26 Jul 2025 09:35:31 -0700 Subject: [PATCH 125/303] Change uncaptured error handler pointer type from `Box` to `Arc`. This will be necessary for the next change. --- CHANGELOG.md | 2 +- examples/standalone/custom_backend/src/custom.rs | 2 +- wgpu/src/api/device.rs | 4 ++-- wgpu/src/backend/webgpu.rs | 3 ++- wgpu/src/backend/wgpu_core.rs | 4 ++-- wgpu/src/dispatch.rs | 2 +- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c0a30a7408..7d193794ccb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,7 +72,7 @@ By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). - Copies of depth/stencil formats must be 4B aligned. - The offset for `set_vertex_buffer` and `set_index_buffer` must be 4B aligned. By @andyleiserson in [#7929](https://github.com/gfx-rs/wgpu/pull/7929). - The offset and size of bindings are validated as fitting within the underlying buffer in more cases. By @andyleiserson in [#7911](https://github.com/gfx-rs/wgpu/pull/7911). -- The function you pass to `Device::on_uncaptured_error()` must now implement `Sync` in addition to `Send`. +- The function you pass to `Device::on_uncaptured_error()` must now implement `Sync` in addition to `Send`, and be wrapped in `Arc` instead of `Box`. By @kpreid in [#8011](https://github.com/gfx-rs/wgpu/pull/8011). #### Naga diff --git a/examples/standalone/custom_backend/src/custom.rs b/examples/standalone/custom_backend/src/custom.rs index 6381c48d1d4..3082be20b5f 100644 --- a/examples/standalone/custom_backend/src/custom.rs +++ b/examples/standalone/custom_backend/src/custom.rs @@ -240,7 +240,7 @@ impl DeviceInterface for CustomDevice { unimplemented!() } - fn on_uncaptured_error(&self, _handler: Box) { + fn on_uncaptured_error(&self, _handler: Arc) { unimplemented!() } diff --git a/wgpu/src/api/device.rs b/wgpu/src/api/device.rs index 8e0e372ddc1..a0b51c4be7b 100644 --- a/wgpu/src/api/device.rs +++ b/wgpu/src/api/device.rs @@ -407,8 +407,8 @@ impl Device { QuerySet { inner: query_set } } - /// Set a callback for errors that are not handled in error scopes. - pub fn on_uncaptured_error(&self, handler: Box) { + /// Set a callback which will be called for all errors that are not handled in error scopes. + pub fn on_uncaptured_error(&self, handler: Arc) { self.inner.on_uncaptured_error(handler) } diff --git a/wgpu/src/backend/webgpu.rs b/wgpu/src/backend/webgpu.rs index 28fcc99b848..0bd973cdb63 100644 --- a/wgpu/src/backend/webgpu.rs +++ b/wgpu/src/backend/webgpu.rs @@ -10,6 +10,7 @@ use alloc::{ format, rc::Rc, string::{String, ToString as _}, + sync::Arc, vec, vec::Vec, }; @@ -2409,7 +2410,7 @@ impl dispatch::DeviceInterface for WebDevice { closure.forget(); } - fn on_uncaptured_error(&self, handler: Box) { + fn on_uncaptured_error(&self, handler: Arc) { let f = Closure::wrap(Box::new(move |event: webgpu_sys::GpuUncapturedErrorEvent| { let error = crate::Error::from_js(event.error().value_of()); handler(error); diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index b97f20870cd..7cc1a9ecd19 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -617,7 +617,7 @@ struct ErrorScope { struct ErrorSinkRaw { scopes: Vec, - uncaptured_handler: Option>, + uncaptured_handler: Option>, } impl ErrorSinkRaw { @@ -1757,7 +1757,7 @@ impl dispatch::DeviceInterface for CoreDevice { .device_set_device_lost_closure(self.id, device_lost_callback); } - fn on_uncaptured_error(&self, handler: Box) { + fn on_uncaptured_error(&self, handler: Arc) { let mut error_sink = self.error_sink.lock(); error_sink.uncaptured_handler = Some(handler); } diff --git a/wgpu/src/dispatch.rs b/wgpu/src/dispatch.rs index 3b549a659ee..0ec87fadddb 100644 --- a/wgpu/src/dispatch.rs +++ b/wgpu/src/dispatch.rs @@ -185,7 +185,7 @@ pub trait DeviceInterface: CommonTraits { fn set_device_lost_callback(&self, device_lost_callback: BoxDeviceLostCallback); - fn on_uncaptured_error(&self, handler: Box); + fn on_uncaptured_error(&self, handler: Arc); fn push_error_scope(&self, filter: crate::ErrorFilter); fn pop_error_scope(&self) -> Pin>; From 2d835bf3b41ead3758b4a32e97e80dc252fe648a Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Sat, 26 Jul 2025 08:59:04 -0700 Subject: [PATCH 126/303] Call uncaptured error handler without the lock held. This prevents a possible deadlock if the callback itself calls wgpu operations. --- CHANGELOG.md | 1 + tests/tests/wgpu-validation/api/device.rs | 44 +++++++++++++++ tests/tests/wgpu-validation/api/mod.rs | 1 + wgpu/src/backend/wgpu_core.rs | 67 +++++++++++++++-------- 4 files changed, 90 insertions(+), 23 deletions(-) create mode 100644 tests/tests/wgpu-validation/api/device.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d193794ccb..4146352c8ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,7 @@ By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). - The offset for `set_vertex_buffer` and `set_index_buffer` must be 4B aligned. By @andyleiserson in [#7929](https://github.com/gfx-rs/wgpu/pull/7929). - The offset and size of bindings are validated as fitting within the underlying buffer in more cases. By @andyleiserson in [#7911](https://github.com/gfx-rs/wgpu/pull/7911). - The function you pass to `Device::on_uncaptured_error()` must now implement `Sync` in addition to `Send`, and be wrapped in `Arc` instead of `Box`. + In exchange for this, it is no longer possible for calling `wgpu` functions while in that callback to cause a deadlock (not that we encourage you to actually do that). By @kpreid in [#8011](https://github.com/gfx-rs/wgpu/pull/8011). #### Naga diff --git a/tests/tests/wgpu-validation/api/device.rs b/tests/tests/wgpu-validation/api/device.rs new file mode 100644 index 00000000000..aec013db767 --- /dev/null +++ b/tests/tests/wgpu-validation/api/device.rs @@ -0,0 +1,44 @@ +/// Test that if another error occurs reentrantly in the [`wgpu::Device::on_uncaptured_error`] +/// handler, this does not result in a deadlock (as a previous implementation would have had). +#[cfg(not(target_family = "wasm"))] // test needs wgpu::Device: Send + Sync to achieve reentrance +#[test] +fn recursive_uncaptured_error() { + use std::sync::atomic::{AtomicU32, Ordering::Relaxed}; + use std::sync::Arc; + + const ERRONEOUS_TEXTURE_DESC: wgpu::TextureDescriptor = wgpu::TextureDescriptor { + label: None, + size: wgpu::Extent3d { + width: 1, + height: 1, + depth_or_array_layers: 10, + }, + mip_level_count: 0, + sample_count: 0, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rgba8UnormSrgb, + usage: wgpu::TextureUsages::COPY_SRC, + view_formats: &[], + }; + + let (device, _queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + + let errors_seen: Arc = Arc::default(); + let handler = Arc::new({ + let errors_seen = errors_seen.clone(); + let device = device.clone(); + move |_error| { + let previous_count = errors_seen.fetch_add(1, Relaxed); + if previous_count == 0 { + // Trigger another error recursively + _ = device.create_texture(&ERRONEOUS_TEXTURE_DESC); + } + } + }); + + // Trigger one error which will call the handler + device.on_uncaptured_error(handler); + _ = device.create_texture(&ERRONEOUS_TEXTURE_DESC); + + assert_eq!(errors_seen.load(Relaxed), 2); +} diff --git a/tests/tests/wgpu-validation/api/mod.rs b/tests/tests/wgpu-validation/api/mod.rs index 9ea34327b47..383e86d3008 100644 --- a/tests/tests/wgpu-validation/api/mod.rs +++ b/tests/tests/wgpu-validation/api/mod.rs @@ -1,6 +1,7 @@ mod binding_arrays; mod buffer; mod buffer_slice; +mod device; mod external_texture; mod instance; mod texture; diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index 7cc1a9ecd19..5b96225cdcb 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -281,27 +281,36 @@ impl ContextWgpuCore { source, label: label.unwrap_or_default().to_string(), }); - let mut sink = sink_mutex.lock(); - let description = || self.format_error(&*source); - let error = match error_type { - ErrorType::Internal => { - let description = description(); - crate::Error::Internal { - source, - description, + let final_error_handling = { + let mut sink = sink_mutex.lock(); + let description = || self.format_error(&*source); + let error = match error_type { + ErrorType::Internal => { + let description = description(); + crate::Error::Internal { + source, + description, + } } - } - ErrorType::OutOfMemory => crate::Error::OutOfMemory { source }, - ErrorType::Validation => { - let description = description(); - crate::Error::Validation { - source, - description, + ErrorType::OutOfMemory => crate::Error::OutOfMemory { source }, + ErrorType::Validation => { + let description = description(); + crate::Error::Validation { + source, + description, + } } - } - ErrorType::DeviceLost => return, // will be surfaced via callback + ErrorType::DeviceLost => return, // will be surfaced via callback + }; + sink.handle_error_or_return_handler(error) }; - sink.handle_error(error); + + if let Some(f) = final_error_handling { + // If the user has provided their own `uncaptured_handler` callback, invoke it now, + // having released our lock on `sink_mutex`. See the comments on + // `handle_error_or_return_handler` for details. + f(); + } } #[inline] @@ -628,8 +637,18 @@ impl ErrorSinkRaw { } } + /// Deliver the error to + /// + /// * the innermost error scope, if any, or + /// * the uncaptured error handler, if there is one, or + /// * [`default_error_handler()`]. + /// + /// If a closure is returned, the caller should call it immediately after dropping the + /// [`ErrorSink`] mutex guard. This makes sure that the user callback is not called with + /// a wgpu mutex held. #[track_caller] - fn handle_error(&mut self, err: crate::Error) { + #[must_use] + fn handle_error_or_return_handler(&mut self, err: crate::Error) -> Option { let filter = match err { crate::Error::OutOfMemory { .. } => crate::ErrorFilter::OutOfMemory, crate::Error::Validation { .. } => crate::ErrorFilter::Validation, @@ -645,13 +664,15 @@ impl ErrorSinkRaw { if scope.error.is_none() { scope.error = Some(err); } + None } None => { - if let Some(custom_handler) = self.uncaptured_handler.as_ref() { - (custom_handler)(err); + if let Some(custom_handler) = &self.uncaptured_handler { + let custom_handler = Arc::clone(custom_handler); + Some(move || (custom_handler)(err)) } else { // direct call preserves #[track_caller] where dyn can't - default_error_handler(err); + default_error_handler(err) } } } @@ -665,7 +686,7 @@ impl fmt::Debug for ErrorSinkRaw { } #[track_caller] -fn default_error_handler(err: crate::Error) { +fn default_error_handler(err: crate::Error) -> ! { log::error!("Handling wgpu errors as fatal by default"); panic!("wgpu error: {err}\n"); } From 54be6a2b5b780e356976ef7e30d00244f2bad651 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Thu, 14 Aug 2025 03:27:51 +1200 Subject: [PATCH 127/303] Fix empty `if`s causing errors on spirv 1.6 (#7883) --- CHANGELOG.md | 6 + naga/src/back/spv/block.rs | 109 ++++--- naga/tests/in/wgsl/empty-if.toml | 2 + naga/tests/in/wgsl/empty-if.wgsl | 9 + .../out/glsl/wgsl-empty-if.comp.Compute.glsl | 15 + naga/tests/out/hlsl/wgsl-empty-if.hlsl | 7 + naga/tests/out/hlsl/wgsl-empty-if.ron | 12 + naga/tests/out/msl/wgsl-empty-if.msl | 16 + naga/tests/out/spv/wgsl-access.spvasm | 304 +++++++++--------- naga/tests/out/spv/wgsl-empty-if.spvasm | 29 ++ naga/tests/out/wgsl/wgsl-empty-if.wgsl | 6 + 11 files changed, 309 insertions(+), 206 deletions(-) create mode 100644 naga/tests/in/wgsl/empty-if.toml create mode 100644 naga/tests/in/wgsl/empty-if.wgsl create mode 100644 naga/tests/out/glsl/wgsl-empty-if.comp.Compute.glsl create mode 100644 naga/tests/out/hlsl/wgsl-empty-if.hlsl create mode 100644 naga/tests/out/hlsl/wgsl-empty-if.ron create mode 100644 naga/tests/out/msl/wgsl-empty-if.msl create mode 100644 naga/tests/out/spv/wgsl-empty-if.spvasm create mode 100644 naga/tests/out/wgsl/wgsl-empty-if.wgsl diff --git a/CHANGELOG.md b/CHANGELOG.md index 4146352c8ac..78871071b2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -109,6 +109,12 @@ By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). - Fixed memory leak in vulkan backend. By @cwfitzgerald in [#8031](https://github.com/gfx-rs/wgpu/pull/8031). +### Bug Fixes + +#### Naga + +- Fix empty `if` statements causing errors on spirv 1.6+. By @Vecvec in [#7883](https://github.com/gfx-rs/wgpu/pull/7883). + ## v26.0.2 (2025-07-23) ### Bug Fixes diff --git a/naga/src/back/spv/block.rs b/naga/src/back/spv/block.rs index 71487c69758..0cd414bfbeb 100644 --- a/naga/src/back/spv/block.rs +++ b/naga/src/back/spv/block.rs @@ -2979,62 +2979,69 @@ impl BlockContext<'_> { ref accept, ref reject, } => { - let condition_id = self.cached[condition]; + // In spirv 1.6, in a conditional branch the two block ids + // of the branches can't have the same label. If `accept` + // and `reject` are both empty (e.g. in `if (condition) {}`) + // merge id will be both labels. Because both branches are + // empty, we can skip the if statement. + if !(accept.is_empty() && reject.is_empty()) { + let condition_id = self.cached[condition]; + + let merge_id = self.gen_id(); + block.body.push(Instruction::selection_merge( + merge_id, + spirv::SelectionControl::NONE, + )); - let merge_id = self.gen_id(); - block.body.push(Instruction::selection_merge( - merge_id, - spirv::SelectionControl::NONE, - )); + let accept_id = if accept.is_empty() { + None + } else { + Some(self.gen_id()) + }; + let reject_id = if reject.is_empty() { + None + } else { + Some(self.gen_id()) + }; - let accept_id = if accept.is_empty() { - None - } else { - Some(self.gen_id()) - }; - let reject_id = if reject.is_empty() { - None - } else { - Some(self.gen_id()) - }; + self.function.consume( + block, + Instruction::branch_conditional( + condition_id, + accept_id.unwrap_or(merge_id), + reject_id.unwrap_or(merge_id), + ), + ); - self.function.consume( - block, - Instruction::branch_conditional( - condition_id, - accept_id.unwrap_or(merge_id), - reject_id.unwrap_or(merge_id), - ), - ); + if let Some(block_id) = accept_id { + // We can ignore the `BlockExitDisposition` returned here because, + // even if `merge_id` is not actually reachable, it is always + // referred to by the `OpSelectionMerge` instruction we emitted + // earlier. + let _ = self.write_block( + block_id, + accept, + BlockExit::Branch { target: merge_id }, + loop_context, + debug_info, + )?; + } + if let Some(block_id) = reject_id { + // We can ignore the `BlockExitDisposition` returned here because, + // even if `merge_id` is not actually reachable, it is always + // referred to by the `OpSelectionMerge` instruction we emitted + // earlier. + let _ = self.write_block( + block_id, + reject, + BlockExit::Branch { target: merge_id }, + loop_context, + debug_info, + )?; + } - if let Some(block_id) = accept_id { - // We can ignore the `BlockExitDisposition` returned here because, - // even if `merge_id` is not actually reachable, it is always - // referred to by the `OpSelectionMerge` instruction we emitted - // earlier. - let _ = self.write_block( - block_id, - accept, - BlockExit::Branch { target: merge_id }, - loop_context, - debug_info, - )?; - } - if let Some(block_id) = reject_id { - // We can ignore the `BlockExitDisposition` returned here because, - // even if `merge_id` is not actually reachable, it is always - // referred to by the `OpSelectionMerge` instruction we emitted - // earlier. - let _ = self.write_block( - block_id, - reject, - BlockExit::Branch { target: merge_id }, - loop_context, - debug_info, - )?; + block = Block::new(merge_id); } - - block = Block::new(merge_id); } Statement::Switch { selector, diff --git a/naga/tests/in/wgsl/empty-if.toml b/naga/tests/in/wgsl/empty-if.toml new file mode 100644 index 00000000000..b7d70bcf51f --- /dev/null +++ b/naga/tests/in/wgsl/empty-if.toml @@ -0,0 +1,2 @@ +[spv] +version = [1, 6] diff --git a/naga/tests/in/wgsl/empty-if.wgsl b/naga/tests/in/wgsl/empty-if.wgsl new file mode 100644 index 00000000000..c72eb7a0128 --- /dev/null +++ b/naga/tests/in/wgsl/empty-if.wgsl @@ -0,0 +1,9 @@ +@workgroup_size(1) +@compute +fn comp(@builtin(global_invocation_id) id: vec3) { + if (id.x == 0) { + + } + _ = 1+1; // otherwise, naga generates returns in the if statement. + return; +} \ No newline at end of file diff --git a/naga/tests/out/glsl/wgsl-empty-if.comp.Compute.glsl b/naga/tests/out/glsl/wgsl-empty-if.comp.Compute.glsl new file mode 100644 index 00000000000..9300c2802e6 --- /dev/null +++ b/naga/tests/out/glsl/wgsl-empty-if.comp.Compute.glsl @@ -0,0 +1,15 @@ +#version 310 es + +precision highp float; +precision highp int; + +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; + + +void main() { + uvec3 id = gl_GlobalInvocationID; + if ((id.x == 0u)) { + } + return; +} + diff --git a/naga/tests/out/hlsl/wgsl-empty-if.hlsl b/naga/tests/out/hlsl/wgsl-empty-if.hlsl new file mode 100644 index 00000000000..6fd5db5e928 --- /dev/null +++ b/naga/tests/out/hlsl/wgsl-empty-if.hlsl @@ -0,0 +1,7 @@ +[numthreads(1, 1, 1)] +void comp(uint3 id : SV_DispatchThreadID) +{ + if ((id.x == 0u)) { + } + return; +} diff --git a/naga/tests/out/hlsl/wgsl-empty-if.ron b/naga/tests/out/hlsl/wgsl-empty-if.ron new file mode 100644 index 00000000000..03fe98f84cd --- /dev/null +++ b/naga/tests/out/hlsl/wgsl-empty-if.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ], + compute:[ + ( + entry_point:"comp", + target_profile:"cs_5_1", + ), + ], +) diff --git a/naga/tests/out/msl/wgsl-empty-if.msl b/naga/tests/out/msl/wgsl-empty-if.msl new file mode 100644 index 00000000000..d9ce803d617 --- /dev/null +++ b/naga/tests/out/msl/wgsl-empty-if.msl @@ -0,0 +1,16 @@ +// language: metal1.0 +#include +#include + +using metal::uint; + + +struct compInput { +}; +kernel void comp( + metal::uint3 id [[thread_position_in_grid]] +) { + if (id.x == 0u) { + } + return; +} diff --git a/naga/tests/out/spv/wgsl-access.spvasm b/naga/tests/out/spv/wgsl-access.spvasm index 78d263d5fc6..31e8e5d4c0b 100644 --- a/naga/tests/out/spv/wgsl-access.spvasm +++ b/naga/tests/out/spv/wgsl-access.spvasm @@ -1,16 +1,16 @@ ; SPIR-V ; Version: 1.1 ; Generator: rspirv -; Bound: 416 +; Bound: 414 OpCapability Shader OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint Vertex %333 "foo_vert" %328 %331 -OpEntryPoint Fragment %389 "foo_frag" %388 -OpEntryPoint GLCompute %407 "foo_compute" -OpExecutionMode %389 OriginUpperLeft -OpExecutionMode %407 LocalSize 1 1 1 +OpEntryPoint Vertex %331 "foo_vert" %326 %329 +OpEntryPoint Fragment %387 "foo_frag" %386 +OpEntryPoint GLCompute %405 "foo_compute" +OpExecutionMode %387 OriginUpperLeft +OpExecutionMode %405 LocalSize 1 1 1 %3 = OpString "access.wgsl" OpSource Unknown 0 %3 "// This snapshot tests accessing various containers, dereferencing pointers. @@ -334,16 +334,16 @@ OpName %275 "a" OpName %284 "member_ptr" OpName %288 "s" OpName %294 "let_members_of_members" -OpName %306 "var_members_of_members" -OpName %307 "thing" -OpName %309 "inner" -OpName %312 "delishus" -OpName %328 "vi" -OpName %333 "foo_vert" -OpName %344 "foo" -OpName %345 "c2" -OpName %389 "foo_frag" -OpName %407 "foo_compute" +OpName %305 "var_members_of_members" +OpName %306 "thing" +OpName %308 "inner" +OpName %311 "delishus" +OpName %326 "vi" +OpName %331 "foo_vert" +OpName %342 "foo" +OpName %343 "c2" +OpName %387 "foo_frag" +OpName %405 "foo_compute" OpMemberDecorate %7 0 Offset 0 OpMemberDecorate %7 1 Offset 16 OpMemberDecorate %7 2 Offset 28 @@ -395,9 +395,9 @@ OpDecorate %62 DescriptorSet 0 OpDecorate %62 Binding 3 OpDecorate %63 Block OpMemberDecorate %63 0 Offset 0 -OpDecorate %328 BuiltIn VertexIndex -OpDecorate %331 BuiltIn Position -OpDecorate %388 Location 0 +OpDecorate %326 BuiltIn VertexIndex +OpDecorate %329 BuiltIn Position +OpDecorate %386 Location 0 %2 = OpTypeVoid %4 = OpTypeInt 32 0 %5 = OpTypeVector %4 3 @@ -533,45 +533,45 @@ OpDecorate %388 Location 0 %287 = OpConstantComposite %45 %286 %289 = OpTypePointer Function %45 %295 = OpConstantNull %47 -%308 = OpTypePointer Function %47 -%310 = OpTypePointer Function %46 -%311 = OpConstantNull %46 -%313 = OpConstantNull %6 -%329 = OpTypePointer Input %4 -%328 = OpVariable %329 Input -%332 = OpTypePointer Output %32 -%331 = OpVariable %332 Output -%335 = OpTypePointer StorageBuffer %24 -%338 = OpConstant %9 0 -%339 = OpConstant %4 3 -%340 = OpConstant %6 3 -%341 = OpConstant %6 4 -%342 = OpConstant %6 5 -%343 = OpConstantNull %30 -%346 = OpTypePointer Function %33 -%347 = OpConstantNull %33 -%353 = OpTypePointer StorageBuffer %10 -%356 = OpTypePointer StorageBuffer %19 -%359 = OpTypePointer StorageBuffer %11 -%360 = OpTypePointer StorageBuffer %9 -%363 = OpTypePointer StorageBuffer %20 -%366 = OpTypePointer StorageBuffer %8 -%367 = OpTypePointer StorageBuffer %6 -%372 = OpConstant %9 -2147483600 -%373 = OpConstant %9 2147483500 -%382 = OpTypeVector %6 4 -%388 = OpVariable %332 Output -%391 = OpConstantComposite %11 %338 %338 %338 -%392 = OpConstantComposite %11 %71 %71 %71 -%393 = OpConstantComposite %11 %73 %73 %73 -%394 = OpConstantComposite %11 %75 %75 %75 -%395 = OpConstantComposite %10 %391 %392 %393 %394 -%396 = OpConstantComposite %18 %48 %48 -%397 = OpConstantComposite %18 %44 %44 -%398 = OpConstantComposite %19 %396 %397 -%399 = OpConstantNull %24 -%400 = OpConstantComposite %32 %338 %338 %338 %338 -%408 = OpConstantTrue %42 +%307 = OpTypePointer Function %47 +%309 = OpTypePointer Function %46 +%310 = OpConstantNull %46 +%312 = OpConstantNull %6 +%327 = OpTypePointer Input %4 +%326 = OpVariable %327 Input +%330 = OpTypePointer Output %32 +%329 = OpVariable %330 Output +%333 = OpTypePointer StorageBuffer %24 +%336 = OpConstant %9 0 +%337 = OpConstant %4 3 +%338 = OpConstant %6 3 +%339 = OpConstant %6 4 +%340 = OpConstant %6 5 +%341 = OpConstantNull %30 +%344 = OpTypePointer Function %33 +%345 = OpConstantNull %33 +%351 = OpTypePointer StorageBuffer %10 +%354 = OpTypePointer StorageBuffer %19 +%357 = OpTypePointer StorageBuffer %11 +%358 = OpTypePointer StorageBuffer %9 +%361 = OpTypePointer StorageBuffer %20 +%364 = OpTypePointer StorageBuffer %8 +%365 = OpTypePointer StorageBuffer %6 +%370 = OpConstant %9 -2147483600 +%371 = OpConstant %9 2147483500 +%380 = OpTypeVector %6 4 +%386 = OpVariable %330 Output +%389 = OpConstantComposite %11 %336 %336 %336 +%390 = OpConstantComposite %11 %71 %71 %71 +%391 = OpConstantComposite %11 %73 %73 %73 +%392 = OpConstantComposite %11 %75 %75 %75 +%393 = OpConstantComposite %10 %389 %390 %391 %392 +%394 = OpConstantComposite %18 %48 %48 +%395 = OpConstantComposite %18 %44 %44 +%396 = OpConstantComposite %19 %394 %395 +%397 = OpConstantNull %24 +%398 = OpConstantComposite %32 %336 %336 %336 %336 +%406 = OpConstantTrue %42 %66 = OpFunction %2 None %67 %65 = OpLabel %94 = OpVariable %95 Function %70 @@ -939,164 +939,158 @@ OpLine %3 228 9 %300 = OpBitcast %4 %298 %301 = OpINotEqual %42 %299 %300 OpLine %3 228 5 -OpSelectionMerge %302 None -OpBranchConditional %301 %302 %302 -%302 = OpLabel OpLine %3 232 12 -%303 = OpCompositeExtract %46 %295 0 -%304 = OpCompositeExtract %6 %303 0 -OpReturnValue %304 +%302 = OpCompositeExtract %46 %295 0 +%303 = OpCompositeExtract %6 %302 0 +OpReturnValue %303 OpFunctionEnd -%306 = OpFunction %6 None %285 -%305 = OpLabel -%307 = OpVariable %308 Function %295 -%309 = OpVariable %310 Function %311 -%312 = OpVariable %95 Function %313 -OpBranch %314 -%314 = OpLabel +%305 = OpFunction %6 None %285 +%304 = OpLabel +%306 = OpVariable %307 Function %295 +%308 = OpVariable %309 Function %310 +%311 = OpVariable %95 Function %312 +OpBranch %313 +%313 = OpLabel OpLine %3 238 17 -%315 = OpAccessChain %310 %307 %48 -%316 = OpLoad %46 %315 +%314 = OpAccessChain %309 %306 %48 +%315 = OpLoad %46 %314 OpLine %3 238 5 -OpStore %309 %316 +OpStore %308 %315 OpLine %3 239 20 -%317 = OpAccessChain %95 %309 %48 -%318 = OpLoad %6 %317 +%316 = OpAccessChain %95 %308 %48 +%317 = OpLoad %6 %316 OpLine %3 239 5 -OpStore %312 %318 +OpStore %311 %317 OpLine %3 241 9 -%319 = OpAccessChain %34 %307 %44 -%320 = OpLoad %4 %319 -%321 = OpLoad %6 %312 -%322 = OpBitcast %4 %321 -%323 = OpINotEqual %42 %320 %322 +%318 = OpAccessChain %34 %306 %44 +%319 = OpLoad %4 %318 +%320 = OpLoad %6 %311 +%321 = OpBitcast %4 %320 +%322 = OpINotEqual %42 %319 %321 OpLine %3 241 5 -OpSelectionMerge %324 None -OpBranchConditional %323 %324 %324 -%324 = OpLabel OpLine %3 245 12 -%325 = OpAccessChain %95 %307 %48 %48 -%326 = OpLoad %6 %325 -OpReturnValue %326 +%323 = OpAccessChain %95 %306 %48 %48 +%324 = OpLoad %6 %323 +OpReturnValue %324 OpFunctionEnd -%333 = OpFunction %2 None %67 -%327 = OpLabel -%344 = OpVariable %28 Function %338 -%345 = OpVariable %346 Function %347 -%330 = OpLoad %4 %328 -%334 = OpAccessChain %68 %56 %48 -%336 = OpAccessChain %335 %59 %48 -%337 = OpAccessChain %141 %62 %48 -OpBranch %348 -%348 = OpLabel +%331 = OpFunction %2 None %67 +%325 = OpLabel +%342 = OpVariable %28 Function %336 +%343 = OpVariable %344 Function %345 +%328 = OpLoad %4 %326 +%332 = OpAccessChain %68 %56 %48 +%334 = OpAccessChain %333 %59 %48 +%335 = OpAccessChain %141 %62 %48 +OpBranch %346 +%346 = OpLabel OpLine %3 1 1 -%349 = OpLoad %9 %344 +%347 = OpLoad %9 %342 OpLine %3 118 5 -OpStore %344 %71 +OpStore %342 %71 OpLine %3 120 9 -%350 = OpLoad %7 %52 +%348 = OpLoad %7 %52 OpLine %3 121 5 -%351 = OpFunctionCall %2 %66 +%349 = OpFunctionCall %2 %66 OpLine %3 122 5 -%352 = OpFunctionCall %2 %140 +%350 = OpFunctionCall %2 %140 OpLine %3 125 19 -%354 = OpAccessChain %353 %54 %48 -%355 = OpLoad %10 %354 +%352 = OpAccessChain %351 %54 %48 +%353 = OpLoad %10 %352 OpLine %3 126 15 -%357 = OpAccessChain %356 %54 %40 -%358 = OpLoad %19 %357 +%355 = OpAccessChain %354 %54 %40 +%356 = OpLoad %19 %355 OpLine %3 128 13 -%361 = OpAccessChain %360 %54 %48 %339 %48 -%362 = OpLoad %9 %361 +%359 = OpAccessChain %358 %54 %48 %337 %48 +%360 = OpLoad %9 %359 OpLine %3 129 13 OpLine %3 129 22 -%364 = OpArrayLength %4 %54 5 +%362 = OpArrayLength %4 %54 5 OpLine %3 129 13 -%365 = OpISub %4 %364 %15 -%368 = OpAccessChain %367 %54 %31 %365 %48 -%369 = OpLoad %6 %368 +%363 = OpISub %4 %362 %15 +%366 = OpAccessChain %365 %54 %31 %363 %48 +%367 = OpLoad %6 %366 OpLine %3 130 13 -%370 = OpLoad %24 %336 +%368 = OpLoad %24 %334 OpLine %3 133 56 OpLine %3 133 56 OpLine %3 134 21 -%371 = OpFunctionCall %9 %198 %344 +%369 = OpFunctionCall %9 %198 %342 OpLine %3 137 31 -%374 = OpExtInst %9 %1 FClamp %362 %372 %373 -%375 = OpConvertFToS %6 %374 +%372 = OpExtInst %9 %1 FClamp %360 %370 %371 +%373 = OpConvertFToS %6 %372 OpLine %3 137 14 -%376 = OpCompositeConstruct %33 %369 %375 %340 %341 %342 +%374 = OpCompositeConstruct %33 %367 %373 %338 %339 %340 OpLine %3 137 5 -OpStore %345 %376 +OpStore %343 %374 OpLine %3 138 5 -%377 = OpIAdd %4 %330 %44 +%375 = OpIAdd %4 %328 %44 OpLine %3 138 5 -%378 = OpAccessChain %95 %345 %377 -OpStore %378 %286 +%376 = OpAccessChain %95 %343 %375 +OpStore %376 %286 OpLine %3 139 17 -%379 = OpAccessChain %95 %345 %330 -%380 = OpLoad %6 %379 +%377 = OpAccessChain %95 %343 %328 +%378 = OpLoad %6 %377 OpLine %3 141 5 -%381 = OpFunctionCall %9 %204 %343 +%379 = OpFunctionCall %9 %204 %341 OpLine %3 143 22 -%383 = OpCompositeConstruct %382 %380 %380 %380 %380 -%384 = OpConvertSToF %32 %383 -%385 = OpMatrixTimesVector %11 %355 %384 +%381 = OpCompositeConstruct %380 %378 %378 %378 %378 +%382 = OpConvertSToF %32 %381 +%383 = OpMatrixTimesVector %11 %353 %382 OpLine %3 143 12 -%386 = OpCompositeConstruct %32 %385 %73 -OpStore %331 %386 +%384 = OpCompositeConstruct %32 %383 %73 +OpStore %329 %384 OpReturn OpFunctionEnd -%389 = OpFunction %2 None %67 -%387 = OpLabel -%390 = OpAccessChain %335 %59 %48 -OpBranch %401 -%401 = OpLabel +%387 = OpFunction %2 None %67 +%385 = OpLabel +%388 = OpAccessChain %333 %59 %48 +OpBranch %399 +%399 = OpLabel OpLine %3 149 5 OpLine %3 149 5 OpLine %3 149 5 -%402 = OpAccessChain %360 %54 %48 %44 %15 -OpStore %402 %71 +%400 = OpAccessChain %358 %54 %48 %44 %15 +OpStore %400 %71 OpLine %3 150 5 OpLine %3 150 31 OpLine %3 150 47 OpLine %3 150 63 OpLine %3 150 19 OpLine %3 150 5 -%403 = OpAccessChain %353 %54 %48 -OpStore %403 %395 +%401 = OpAccessChain %351 %54 %48 +OpStore %401 %393 OpLine %3 151 5 OpLine %3 151 35 OpLine %3 151 15 OpLine %3 151 5 -%404 = OpAccessChain %356 %54 %40 -OpStore %404 %398 +%402 = OpAccessChain %354 %54 %40 +OpStore %402 %396 OpLine %3 152 5 OpLine %3 152 5 OpLine %3 152 5 -%405 = OpAccessChain %367 %54 %31 %44 %48 -OpStore %405 %70 +%403 = OpAccessChain %365 %54 %31 %44 %48 +OpStore %403 %70 OpLine %3 153 5 -OpStore %390 %399 +OpStore %388 %397 OpLine %3 155 12 -OpStore %388 %400 +OpStore %386 %398 OpReturn OpFunctionEnd -%407 = OpFunction %2 None %67 -%406 = OpLabel -OpBranch %409 -%409 = OpLabel +%405 = OpFunction %2 None %67 +%404 = OpLabel +OpBranch %407 +%407 = OpLabel OpLine %3 250 5 -%410 = OpFunctionCall %2 %224 +%408 = OpFunctionCall %2 %224 OpLine %3 251 5 -%411 = OpFunctionCall %2 %261 +%409 = OpFunctionCall %2 %261 OpLine %3 252 5 -%412 = OpFunctionCall %42 %273 %408 +%410 = OpFunctionCall %42 %273 %406 OpLine %3 253 5 -%413 = OpFunctionCall %6 %284 +%411 = OpFunctionCall %6 %284 OpLine %3 254 5 -%414 = OpFunctionCall %6 %294 +%412 = OpFunctionCall %6 %294 OpLine %3 255 5 -%415 = OpFunctionCall %6 %306 +%413 = OpFunctionCall %6 %305 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/naga/tests/out/spv/wgsl-empty-if.spvasm b/naga/tests/out/spv/wgsl-empty-if.spvasm new file mode 100644 index 00000000000..3845afcede7 --- /dev/null +++ b/naga/tests/out/spv/wgsl-empty-if.spvasm @@ -0,0 +1,29 @@ +; SPIR-V +; Version: 1.6 +; Generator: rspirv +; Bound: 18 +OpCapability Shader +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %9 "comp" %6 +OpExecutionMode %9 LocalSize 1 1 1 +OpDecorate %6 BuiltIn GlobalInvocationId +%2 = OpTypeVoid +%4 = OpTypeInt 32 0 +%3 = OpTypeVector %4 3 +%7 = OpTypePointer Input %3 +%6 = OpVariable %7 Input +%10 = OpTypeFunction %2 +%11 = OpConstant %4 0 +%12 = OpTypeInt 32 1 +%13 = OpConstant %12 2 +%16 = OpTypeBool +%9 = OpFunction %2 None %10 +%5 = OpLabel +%8 = OpLoad %3 %6 +OpBranch %14 +%14 = OpLabel +%15 = OpCompositeExtract %4 %8 0 +%17 = OpIEqual %16 %15 %11 +OpReturn +OpFunctionEnd \ No newline at end of file diff --git a/naga/tests/out/wgsl/wgsl-empty-if.wgsl b/naga/tests/out/wgsl/wgsl-empty-if.wgsl new file mode 100644 index 00000000000..5435020695d --- /dev/null +++ b/naga/tests/out/wgsl/wgsl-empty-if.wgsl @@ -0,0 +1,6 @@ +@compute @workgroup_size(1, 1, 1) +fn comp(@builtin(global_invocation_id) id: vec3) { + if (id.x == 0u) { + } + return; +} From dd93ed5975861a24bb64ac215394b1d5ce998f89 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 13 Aug 2025 23:07:26 +0000 Subject: [PATCH 128/303] chore(deps): update cargo.lock (#8079) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 + Cargo.lock | 163 +++++++++++++++++++++------------------ 2 files changed, 88 insertions(+), 77 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 84453f0c793..4e3422e62bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -401,6 +401,8 @@ jobs: run: | set -e + # 1.23.2 requires bytemuck_derive 1.10.1 + cargo update -p bytemuck --precise 1.23.1 # 1.9.0 requires MSRV 1.84 cargo update -p bytemuck_derive --precise 1.8.1 diff --git a/Cargo.lock b/Cargo.lock index 7b889e07420..1f0c5b5ab22 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,9 +14,9 @@ dependencies = [ [[package]] name = "ab_glyph_rasterizer" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2187590a23ab1e3df8681afdf0987c48504d80291f002fcdb651f0ef5e25169" +checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" [[package]] name = "addr2line" @@ -132,9 +132,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.19" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" +checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" dependencies = [ "anstyle", "anstyle-parse", @@ -162,29 +162,29 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.9" +version = "3.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "anyhow" -version = "1.0.98" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" [[package]] name = "approx" @@ -484,18 +484,18 @@ checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "bytemuck" -version = "1.23.1" +version = "1.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" +checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "441473f2b4b0459a68628c744bc61d23e730fb00128b841d30fa4bb3972257e4" +checksum = "4f154e572231cb6ba2bd1176980827e3d5dc04cc183a75dea38109fbdd672d29" dependencies = [ "proc-macro2", "quote", @@ -568,9 +568,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.10" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0da45bc31171d8d6960122e222a67740df867c1dd53b4d51caa297084c185cab" +checksum = "5d07aa9a93b00c76f71bc35d598bed923f6d4f3a9ca5c24b7737ae1a292841c0" dependencies = [ "serde", ] @@ -623,7 +623,7 @@ dependencies = [ "serde", "serde-untagged", "serde-value", - "thiserror 2.0.12", + "thiserror 2.0.14", "toml 0.8.23", "unicode-xid", "url", @@ -641,7 +641,7 @@ dependencies = [ "semver 1.0.26", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.14", ] [[package]] @@ -652,9 +652,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.31" +version = "1.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2" +checksum = "2352e5597e9c544d5e6d9c95190d5d27738ade584fa8db0a16e130e5c2b5296e" dependencies = [ "jobserver", "libc", @@ -743,9 +743,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.42" +version = "4.5.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed87a9d530bb41a67537289bafcac159cb3ee28460e0a4571123d2a778a6a882" +checksum = "1fc0e74a703892159f5ae7d3aac52c8e6c392f5ae5f359c70b5881d60aaac318" dependencies = [ "clap_builder", "clap_derive", @@ -753,9 +753,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.42" +version = "4.5.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64f4f3f3c77c94aff3c7e9aac9a2ca1974a5adf392a8bb751e827d6d127ab966" +checksum = "b3e7f4214277f3c7aa526a59dd3fbe306a370daee1f8b7b8c987069cd8e888a8" dependencies = [ "anstream", "anstyle", @@ -765,9 +765,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.41" +version = "4.5.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" +checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -852,9 +852,12 @@ dependencies = [ [[package]] name = "const_panic" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98d1483e98c9d67f341ab4b3915cfdc54740bd6f5cccc9226ee0535d86aa8fb" +checksum = "bb8a602185c3c95b52f86dc78e55a6df9a287a7a93ddbcf012509930880cf879" +dependencies = [ + "typewit", +] [[package]] name = "cooked-waker" @@ -1090,7 +1093,7 @@ dependencies = [ "smallvec", "sourcemap", "static_assertions", - "thiserror 2.0.12", + "thiserror 2.0.14", "tokio", "url", "v8", @@ -1142,7 +1145,7 @@ dependencies = [ "strum 0.25.0", "strum_macros 0.25.3", "syn", - "thiserror 2.0.12", + "thiserror 2.0.14", ] [[package]] @@ -1154,7 +1157,7 @@ dependencies = [ "deno_error", "percent-encoding", "sys_traits", - "thiserror 2.0.12", + "thiserror 2.0.14", "url", ] @@ -1175,7 +1178,7 @@ dependencies = [ "once_cell", "percent-encoding", "serde", - "thiserror 2.0.12", + "thiserror 2.0.14", "which 6.0.3", "winapi", ] @@ -1209,7 +1212,7 @@ checksum = "36a705094c7fbbb01338e89c12367da939cf831dd5b202e3a521f75a614a6082" dependencies = [ "deno_core", "deno_error", - "thiserror 2.0.12", + "thiserror 2.0.14", "urlpattern", ] @@ -1229,7 +1232,7 @@ dependencies = [ "flate2", "futures", "serde", - "thiserror 2.0.12", + "thiserror 2.0.14", "tokio", "uuid", ] @@ -1245,7 +1248,7 @@ dependencies = [ "raw-window-handle 0.6.2", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.14", "tokio", "wgpu-core", "wgpu-types", @@ -1354,7 +1357,7 @@ dependencies = [ "const_panic", "encase_derive", "glam", - "thiserror 2.0.12", + "thiserror 2.0.14", ] [[package]] @@ -1625,9 +1628,9 @@ checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" dependencies = [ "fastrand", "futures-core", @@ -1754,9 +1757,9 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "glow" @@ -1909,9 +1912,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.4" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", "equivalent", @@ -2262,9 +2265,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.174" +version = "0.2.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" [[package]] name = "libfuzzer-sys" @@ -2518,8 +2521,8 @@ dependencies = [ "serde", "spirv", "strum 0.27.2", - "thiserror 2.0.12", - "toml 0.9.4", + "thiserror 2.0.14", + "toml 0.9.5", "unicode-ident", "walkdir", ] @@ -3356,9 +3359,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "d61789d7719defeb74ea5fe81f2fdfdbd28a803847077cecce2ff14e1472f6f1" dependencies = [ "unicode-ident", ] @@ -3443,9 +3446,9 @@ checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "rayon" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ "either", "rayon-core", @@ -3453,9 +3456,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -3622,9 +3625,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" @@ -3714,9 +3717,9 @@ dependencies = [ [[package]] name = "serde-untagged" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "299d9c19d7d466db4ab10addd5703e4c615dec2a5a16dbbafe191045e87ee66e" +checksum = "34836a629bcbc6f1afdf0907a744870039b1e14c0561cb26094fa683b158eff3" dependencies = [ "erased-serde", "serde", @@ -3785,7 +3788,7 @@ dependencies = [ "num-bigint", "serde", "smallvec", - "thiserror 2.0.12", + "thiserror 2.0.14", "v8", ] @@ -4109,11 +4112,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "0b0949c3a6c842cbde3f1686d6eea5a010516deb7085f79db747562d4102f41e" dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl 2.0.14", ] [[package]] @@ -4129,9 +4132,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "cc5b44b4ab9c2fdd0e0512e6bece8388e214c0749f5862b114cc5b7a25daf227" dependencies = [ "proc-macro2", "quote", @@ -4247,9 +4250,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ae868b5a0f67631c14589f7e250c1ea2c574ee5ba21c6c8dd4b1485705a5a1" +checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8" dependencies = [ "indexmap", "serde", @@ -4294,9 +4297,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97200572db069e74c512a14117b296ba0a80a30123fbbb5aa1f4a348f639ca30" +checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10" dependencies = [ "winnow", ] @@ -4395,7 +4398,7 @@ dependencies = [ "serde_json", "target-triple", "termcolor", - "toml 0.9.4", + "toml 0.9.5", ] [[package]] @@ -4410,6 +4413,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" +[[package]] +name = "typewit" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97e72ba082eeb9da9dc68ff5a2bf727ef6ce362556e8d29ec1aed3bd05e7d86a" + [[package]] name = "unic-char-property" version = "0.9.0" @@ -4531,9 +4540,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" +checksum = "f33196643e165781c20a5ead5582283a7dacbb87855d867fbc2df3f81eddc1be" dependencies = [ "getrandom 0.3.3", "js-sys", @@ -4709,7 +4718,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eeee3bdea6257cc36d756fa745a70f9d393571e47d69e0ed97581676a5369ca" dependencies = [ "deno_error", - "thiserror 2.0.12", + "thiserror 2.0.14", ] [[package]] @@ -4957,7 +4966,7 @@ dependencies = [ "rustc-hash", "serde", "smallvec", - "thiserror 2.0.12", + "thiserror 2.0.14", "wgpu-core-deps-apple", "wgpu-core-deps-emscripten", "wgpu-core-deps-wasm", @@ -5098,7 +5107,7 @@ dependencies = [ "renderdoc-sys", "rustc-hash", "smallvec", - "thiserror 2.0.12", + "thiserror 2.0.14", "wasm-bindgen", "web-sys", "wgpu-types", @@ -5181,7 +5190,7 @@ dependencies = [ "log", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.14", "web-sys", ] @@ -6010,9 +6019,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.2" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" dependencies = [ "yoke", "zerofrom", From 0c0df249cf4fd860f42194575824b838f212c531 Mon Sep 17 00:00:00 2001 From: SupaMaggie70Incorporated <85136135+SupaMaggie70Incorporated@users.noreply.github.com> Date: Thu, 14 Aug 2025 08:03:06 -0500 Subject: [PATCH 129/303] Only commit hopefully (#8101) --- wgpu-hal/src/dx12/adapter.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index fd045ea03d9..1f57fa69010 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -363,7 +363,8 @@ impl super::Adapter { | wgt::Features::TEXTURE_FORMAT_NV12 | wgt::Features::FLOAT32_FILTERABLE | wgt::Features::TEXTURE_ATOMIC - | wgt::Features::EXTERNAL_TEXTURE; + | wgt::Features::EXTERNAL_TEXTURE + | wgt::Features::HLSL_DXIL_SHADER_PASSTHROUGH; //TODO: in order to expose this, we need to run a compute shader // that extract the necessary statistics out of the D3D12 result. From 576210214d5f697977fd801e3016942387311546 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Sun, 17 Aug 2025 13:23:08 -0700 Subject: [PATCH 130/303] Fix minimal versions CI failure (#8112) --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1f0c5b5ab22..567d3614fd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -197,9 +197,9 @@ dependencies = [ [[package]] name = "arbitrary" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" dependencies = [ "derive_arbitrary", ] diff --git a/Cargo.toml b/Cargo.toml index 672e24a14d1..c07c3986f24 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -92,7 +92,7 @@ wgpu-core-deps-emscripten = { version = "26.0.0", path = "./wgpu-core/platform-d anyhow = { version = "1.0.87", default-features = false } approx = "0.5" -arbitrary = "1.4" +arbitrary = "1.4.2" argh = "0.1.13" arrayvec = { version = "0.7.1", default-features = false } bincode = "2" From 21497a53223a7c364646c9b8f694436978c2f0b0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 10:18:46 -0700 Subject: [PATCH 131/303] chore(deps): update cts digest to 94f4ce1 (#8113) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- cts_runner/revision.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cts_runner/revision.txt b/cts_runner/revision.txt index f5b9ec29ac0..1b89eb0da00 100644 --- a/cts_runner/revision.txt +++ b/cts_runner/revision.txt @@ -1 +1 @@ -a46bb820fc62687ca8c4bfec1657e65c327458fd +94f4ce1d37ff6410bfcf95a8963f5fee853cfc15 From 7bd005531eeba09b7c3cfd22f5c8c4b17ec14e26 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 20:30:21 -0400 Subject: [PATCH 132/303] chore(deps): update actions/checkout action to v5 (#8115) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 20 ++++++++++---------- .github/workflows/cts.yml | 2 +- .github/workflows/docs.yml | 2 +- .github/workflows/generate.yml | 2 +- .github/workflows/lazy.yml | 6 +++--- .github/workflows/publish.yml | 2 +- .github/workflows/shaders.yml | 6 +++--- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e3422e62bd..21e8bce509e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -194,7 +194,7 @@ jobs: steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install toolchain (repo MSRV - tier 1 or 2) if: matrix.tier == 1 || matrix.tier == 2 @@ -373,7 +373,7 @@ jobs: steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install core MSRV toolchain run: | @@ -430,7 +430,7 @@ jobs: steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install toolchain run: | @@ -471,7 +471,7 @@ jobs: steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install repo MSRV toolchain run: | @@ -514,7 +514,7 @@ jobs: steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install repo MSRV toolchain run: | @@ -678,7 +678,7 @@ jobs: steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install repo MSRV toolchain run: | @@ -706,7 +706,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install repo MSRV toolchain run: | @@ -737,7 +737,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install MSRV toolchain run: | @@ -775,7 +775,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Run `cargo deny check` uses: EmbarkStudios/cargo-deny-action@v2 @@ -792,7 +792,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Run `cargo deny check` uses: EmbarkStudios/cargo-deny-action@v2 diff --git a/.github/workflows/cts.yml b/.github/workflows/cts.yml index 4fd5511d210..cc794f7b7ac 100644 --- a/.github/workflows/cts.yml +++ b/.github/workflows/cts.yml @@ -55,7 +55,7 @@ jobs: steps: - name: checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Install Repo MSRV toolchain run: | diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a8634bccd88..83adc7629ec 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false diff --git a/.github/workflows/generate.yml b/.github/workflows/generate.yml index db614ebc095..cd2d4af901e 100644 --- a/.github/workflows/generate.yml +++ b/.github/workflows/generate.yml @@ -49,7 +49,7 @@ jobs: name: "${{ matrix.name }}" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 # We can't rely on an override here, as that would only set # the toolchain for the current directory, not the newly generated project. diff --git a/.github/workflows/lazy.yml b/.github/workflows/lazy.yml index 46f666136c7..d0e526799b1 100644 --- a/.github/workflows/lazy.yml +++ b/.github/workflows/lazy.yml @@ -24,7 +24,7 @@ jobs: name: "Validate Shaders: Dota2" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: mkdir naga/data @@ -50,7 +50,7 @@ jobs: name: "Validate Shaders: Sascha Willems Vulkan Tutorial" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Download shaders run: cd naga && git clone https://github.com/SaschaWillems/Vulkan.git @@ -85,7 +85,7 @@ jobs: name: "Validate Shaders: dneto0 spirv-samples" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Download shaders run: | diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 5967d20e863..1a4385da0ac 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: persist-credentials: false diff --git a/.github/workflows/shaders.yml b/.github/workflows/shaders.yml index 3844d2b9625..084602ff118 100644 --- a/.github/workflows/shaders.yml +++ b/.github/workflows/shaders.yml @@ -31,7 +31,7 @@ jobs: name: "Validate: HLSL" runs-on: windows-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Debug symbols to `line-tables-only` shell: bash @@ -75,7 +75,7 @@ jobs: name: "Validate: MSL" runs-on: macos-14 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Debug symbols to line-tables-only shell: bash @@ -97,7 +97,7 @@ jobs: name: "Validate: SPIR-V/GLSL/DOT/WGSL" runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Install Vulkan SDK shell: bash From 875250348c5bca0d578fc0b308755ead0ade8f1c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Aug 2025 20:30:42 -0400 Subject: [PATCH 133/303] chore(deps): update crate-ci/typos action to v1.35.5 (#8114) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 21e8bce509e..92c45fa7ae0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -727,7 +727,7 @@ jobs: run: taplo format --check --diff - name: Check for typos - uses: crate-ci/typos@v1.35.3 + uses: crate-ci/typos@v1.35.5 check-cts-runner: # runtime is normally 2 minutes From 9aaed2c0cc3c5faf2f3aaba95fafa3b13ac74c93 Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Wed, 20 Aug 2025 08:30:54 +0100 Subject: [PATCH 134/303] [naga] Ensure validation rejects invalid sample operations of `ImageClass::External` images. (#8121) textureSampleBaseClampToEdge() is valid when called on a `texture_external` texture, but all other sample operations are invalid. Previously validation was succeeding for these operations on an external texture in cases where the same operation on a `texture_2d` would be allowed. We must therefore explicitly check for ImageClass::External and disallow invalid sample operations. --- naga/src/valid/expression.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/naga/src/valid/expression.rs b/naga/src/valid/expression.rs index a34f3aa9ecc..5661094f33b 100644 --- a/naga/src/valid/expression.rs +++ b/naga/src/valid/expression.rs @@ -590,6 +590,11 @@ impl super::Validator { } } + // External textures can only be sampled using clamp_to_edge. + if matches!(class, crate::ImageClass::External) && !clamp_to_edge { + return Err(ExpressionError::InvalidImageClass(class)); + } + // check level properties match level { crate::SampleLevel::Auto => ShaderStages::FRAGMENT, From 57d89b4a4f942fdedc2e88a9ce795491d29ac326 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Wed, 20 Aug 2025 11:22:35 -0400 Subject: [PATCH 135/303] docs(vulkan): clarify safety contract for `DeviceShared::set_object_name` (#8055) * docs(vulkan): clarify safety contract for `DeviceShared::set_object_name` --- wgpu-hal/src/vulkan/device.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 1d229635317..48be11a124d 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -27,7 +27,17 @@ impl super::DeviceShared { /// /// # Safety /// - /// It must be valid to set `object`'s debug name + /// This method inherits the safety contract from [`vkSetDebugUtilsObjectName`]. In particular: + /// + /// - `object` must be a valid handle for one of the following: + /// - An instance-level object from the same instance as this device. + /// - A physical-device-level object that descends from the same physical device as this + /// device. + /// - A device-level object that descends from this device. + /// - `object` must be externally synchronized—only the calling thread should access it during + /// this call. + /// + /// [`vkSetDebugUtilsObjectName`]: https://registry.khronos.org/vulkan/specs/latest/man/html/vkSetDebugUtilsObjectNameEXT.html pub(super) unsafe fn set_object_name(&self, object: impl vk::Handle, name: &str) { let Some(extension) = self.extension_fns.debug_utils.as_ref() else { return; From 6a4eaa92934f0c8e159c3566dff5e474471d199a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Aug 2025 11:32:22 -0400 Subject: [PATCH 136/303] chore(deps): update cargo.lock (#8116) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Cargo.lock | 188 ++++++++++++++++++++++++++--------------------------- 1 file changed, 94 insertions(+), 94 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 567d3614fd4..56128ca6616 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,7 +74,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee91c0c2905bae44f84bfa4e044536541df26b7703fd0888deeb9060fcc44289" dependencies = [ "android-properties", - "bitflags 2.9.1", + "bitflags 2.9.2", "cc", "cesu8", "jni", @@ -95,7 +95,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" dependencies = [ "android-properties", - "bitflags 2.9.1", + "bitflags 2.9.2", "cc", "cesu8", "jni", @@ -268,9 +268,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.88" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", @@ -370,7 +370,7 @@ version = "0.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "cexpr", "clang-sys", "itertools 0.13.0", @@ -422,9 +422,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "6a65b545ab31d687cff52899d4890855fec459eb6afe0da6417b8a18da87aa29" dependencies = [ "arbitrary", "serde", @@ -520,7 +520,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "log", "polling", "rustix 0.38.44", @@ -534,7 +534,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "log", "polling", "rustix 0.38.44", @@ -623,7 +623,7 @@ dependencies = [ "serde", "serde-untagged", "serde-value", - "thiserror 2.0.14", + "thiserror 2.0.16", "toml 0.8.23", "unicode-xid", "url", @@ -641,7 +641,7 @@ dependencies = [ "semver 1.0.26", "serde", "serde_json", - "thiserror 2.0.14", + "thiserror 2.0.16", ] [[package]] @@ -652,9 +652,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.32" +version = "1.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2352e5597e9c544d5e6d9c95190d5d27738ade584fa8db0a16e130e5c2b5296e" +checksum = "3ee0f8803222ba5a7e2777dd72ca451868909b1ac410621b676adf07280e9b5f" dependencies = [ "jobserver", "libc", @@ -678,9 +678,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" [[package]] name = "cfg_aliases" @@ -921,7 +921,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "core-foundation 0.10.1", "libc", ] @@ -1093,7 +1093,7 @@ dependencies = [ "smallvec", "sourcemap", "static_assertions", - "thiserror 2.0.14", + "thiserror 2.0.16", "tokio", "url", "v8", @@ -1145,7 +1145,7 @@ dependencies = [ "strum 0.25.0", "strum_macros 0.25.3", "syn", - "thiserror 2.0.14", + "thiserror 2.0.16", ] [[package]] @@ -1157,7 +1157,7 @@ dependencies = [ "deno_error", "percent-encoding", "sys_traits", - "thiserror 2.0.14", + "thiserror 2.0.16", "url", ] @@ -1178,7 +1178,7 @@ dependencies = [ "once_cell", "percent-encoding", "serde", - "thiserror 2.0.14", + "thiserror 2.0.16", "which 6.0.3", "winapi", ] @@ -1212,7 +1212,7 @@ checksum = "36a705094c7fbbb01338e89c12367da939cf831dd5b202e3a521f75a614a6082" dependencies = [ "deno_core", "deno_error", - "thiserror 2.0.14", + "thiserror 2.0.16", "urlpattern", ] @@ -1232,7 +1232,7 @@ dependencies = [ "flate2", "futures", "serde", - "thiserror 2.0.14", + "thiserror 2.0.16", "tokio", "uuid", ] @@ -1248,7 +1248,7 @@ dependencies = [ "raw-window-handle 0.6.2", "serde", "serde_json", - "thiserror 2.0.14", + "thiserror 2.0.16", "tokio", "wgpu-core", "wgpu-types", @@ -1265,9 +1265,9 @@ dependencies = [ [[package]] name = "derive_arbitrary" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", @@ -1357,7 +1357,7 @@ dependencies = [ "const_panic", "encase_derive", "glam", - "thiserror 2.0.14", + "thiserror 2.0.16", ] [[package]] @@ -1779,7 +1779,7 @@ version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18fcd4ae4e86d991ad1300b8f57166e5be0c95ef1f63f3f5b827f8a164548746" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "cfg_aliases 0.1.1", "cgl", "core-foundation 0.9.4", @@ -1842,7 +1842,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "gpu-alloc-types", ] @@ -1852,7 +1852,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", ] [[package]] @@ -1873,7 +1873,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "gpu-descriptor-types", "hashbrown", ] @@ -1884,7 +1884,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", ] [[package]] @@ -2130,7 +2130,7 @@ version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "cfg-if", "libc", ] @@ -2254,7 +2254,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff7f53bdf698e7aa7ec916411bbdc8078135da11b66db5182675b2227f6c0d07" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", ] [[package]] @@ -2302,7 +2302,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "libc", "redox_syscall 0.5.17", ] @@ -2435,7 +2435,7 @@ version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00c15a6f673ff72ddcc22394663290f870fb224c1bfce55734a75c414150e605" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "block", "core-graphics-types 0.2.0", "foreign-types", @@ -2497,7 +2497,7 @@ dependencies = [ "arbitrary", "arrayvec", "bit-set 0.8.0", - "bitflags 2.9.1", + "bitflags 2.9.2", "cfg-if", "cfg_aliases 0.2.1", "codespan-reporting", @@ -2521,7 +2521,7 @@ dependencies = [ "serde", "spirv", "strum 0.27.2", - "thiserror 2.0.14", + "thiserror 2.0.16", "toml 0.9.5", "unicode-ident", "walkdir", @@ -2603,7 +2603,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "jni-sys", "log", "ndk-sys 0.5.0+25.2.9519653", @@ -2619,7 +2619,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "jni-sys", "log", "ndk-sys 0.6.0+11769913", @@ -2810,7 +2810,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "block2 0.5.1", "libc", "objc2 0.5.2", @@ -2826,7 +2826,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "block2 0.5.1", "objc2 0.5.2", "objc2-core-location", @@ -2850,7 +2850,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation", @@ -2898,7 +2898,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "block2 0.5.1", "dispatch", "libc", @@ -2923,7 +2923,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation", @@ -2935,7 +2935,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation", @@ -2958,7 +2958,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "block2 0.5.1", "objc2 0.5.2", "objc2-cloud-kit", @@ -2990,7 +2990,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "block2 0.5.1", "objc2 0.5.2", "objc2-core-location", @@ -3317,9 +3317,9 @@ checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" [[package]] name = "prettyplease" -version = "0.2.36" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", "syn", @@ -3359,9 +3359,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.97" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61789d7719defeb74ea5fe81f2fdfdbd28a803847077cecce2ff14e1472f6f1" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] @@ -3488,7 +3488,7 @@ version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", ] [[package]] @@ -3554,7 +3554,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f" dependencies = [ "base64", - "bitflags 2.9.1", + "bitflags 2.9.2", "serde", "serde_derive", "unicode-ident", @@ -3603,7 +3603,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "errno", "libc", "linux-raw-sys 0.4.15", @@ -3616,7 +3616,7 @@ version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "errno", "libc", "linux-raw-sys 0.9.4", @@ -3749,9 +3749,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.142" +version = "1.0.143" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" +checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" dependencies = [ "indexmap", "itoa", @@ -3788,7 +3788,7 @@ dependencies = [ "num-bigint", "serde", "smallvec", - "thiserror 2.0.14", + "thiserror 2.0.16", "v8", ] @@ -3864,7 +3864,7 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "calloop 0.12.4", "calloop-wayland-source 0.2.0", "cursor-icon", @@ -3889,7 +3889,7 @@ version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "calloop 0.13.0", "calloop-wayland-source 0.3.0", "cursor-icon", @@ -3961,7 +3961,7 @@ version = "0.3.0+sdk-1.3.268.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "serde", ] @@ -4040,9 +4040,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.104" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", @@ -4112,11 +4112,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.14" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b0949c3a6c842cbde3f1686d6eea5a010516deb7085f79db747562d4102f41e" +checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" dependencies = [ - "thiserror-impl 2.0.14", + "thiserror-impl 2.0.16", ] [[package]] @@ -4132,9 +4132,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.14" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc5b44b4ab9c2fdd0e0512e6bece8388e214c0749f5862b114cc5b7a25daf227" +checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" dependencies = [ "proc-macro2", "quote", @@ -4557,7 +4557,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21c7a224a7eaf3f98c1bad772fbaee56394dce185ef7b19a2e0ca5e3d274165d" dependencies = [ "bindgen", - "bitflags 2.9.1", + "bitflags 2.9.2", "fslock", "gzip-header", "home", @@ -4718,7 +4718,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eeee3bdea6257cc36d756fa745a70f9d393571e47d69e0ed97581676a5369ca" dependencies = [ "deno_error", - "thiserror 2.0.14", + "thiserror 2.0.16", ] [[package]] @@ -4741,7 +4741,7 @@ version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "rustix 1.0.8", "wayland-backend", "wayland-scanner", @@ -4753,7 +4753,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "cursor-icon", "wayland-backend", ] @@ -4775,7 +4775,7 @@ version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "wayland-backend", "wayland-client", "wayland-scanner", @@ -4787,7 +4787,7 @@ version = "0.32.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "wayland-backend", "wayland-client", "wayland-scanner", @@ -4799,7 +4799,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "wayland-backend", "wayland-client", "wayland-protocols 0.31.2", @@ -4812,7 +4812,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a07a14257c077ab3279987c4f8bb987851bf57081b93710381daea94f2c2c032" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "wayland-backend", "wayland-client", "wayland-protocols 0.32.9", @@ -4825,7 +4825,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "wayland-backend", "wayland-client", "wayland-protocols 0.31.2", @@ -4838,7 +4838,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efd94963ed43cf9938a090ca4f7da58eb55325ec8200c3848963e98dc25b78ec" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "wayland-backend", "wayland-client", "wayland-protocols 0.32.9", @@ -4903,7 +4903,7 @@ name = "wgpu" version = "26.0.0" dependencies = [ "arrayvec", - "bitflags 2.9.1", + "bitflags 2.9.2", "bytemuck", "cfg-if", "cfg_aliases 0.2.1", @@ -4949,7 +4949,7 @@ dependencies = [ "arrayvec", "bit-set 0.8.0", "bit-vec 0.8.0", - "bitflags 2.9.1", + "bitflags 2.9.2", "bytemuck", "cfg_aliases 0.2.1", "document-features", @@ -4966,7 +4966,7 @@ dependencies = [ "rustc-hash", "serde", "smallvec", - "thiserror 2.0.14", + "thiserror 2.0.16", "wgpu-core-deps-apple", "wgpu-core-deps-emscripten", "wgpu-core-deps-wasm", @@ -5070,7 +5070,7 @@ dependencies = [ "arrayvec", "ash", "bit-set 0.8.0", - "bitflags 2.9.1", + "bitflags 2.9.2", "block", "bytemuck", "cfg-if", @@ -5107,7 +5107,7 @@ dependencies = [ "renderdoc-sys", "rustc-hash", "smallvec", - "thiserror 2.0.14", + "thiserror 2.0.16", "wasm-bindgen", "web-sys", "wgpu-types", @@ -5121,7 +5121,7 @@ name = "wgpu-info" version = "26.0.0" dependencies = [ "anyhow", - "bitflags 2.9.1", + "bitflags 2.9.2", "env_logger", "hashbrown", "pico-args", @@ -5146,7 +5146,7 @@ dependencies = [ "anyhow", "approx", "arrayvec", - "bitflags 2.9.1", + "bitflags 2.9.2", "bytemuck", "cargo_metadata", "cfg-if", @@ -5184,13 +5184,13 @@ dependencies = [ name = "wgpu-types" version = "26.0.0" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "bytemuck", "js-sys", "log", "serde", "serde_json", - "thiserror 2.0.14", + "thiserror 2.0.16", "web-sys", ] @@ -5247,11 +5247,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -5732,7 +5732,7 @@ dependencies = [ "ahash", "android-activity 0.5.2", "atomic-waker", - "bitflags 2.9.1", + "bitflags 2.9.2", "bytemuck", "calloop 0.12.4", "cfg_aliases 0.1.1", @@ -5781,7 +5781,7 @@ dependencies = [ "ahash", "android-activity 0.6.0", "atomic-waker", - "bitflags 2.9.1", + "bitflags 2.9.2", "block2 0.5.1", "bytemuck", "calloop 0.13.0", @@ -5845,7 +5845,7 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", ] [[package]] @@ -5907,7 +5907,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.2", "dlib", "log", "once_cell", From eb9b2e9c9bf7270c55391330ac4476c07f1320df Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Wed, 20 Aug 2025 16:35:47 +0100 Subject: [PATCH 137/303] Add changelog entry for external texture support (#8123) --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78871071b2d..5e9bc2d0f63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,8 @@ By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). - Added mesh shader support to `wgpu`, with examples. Requires passthrough. By @SupaMaggie70Incorporated in [#7345](https://github.com/gfx-rs/wgpu/pull/7345). +- Added support for external textures based on WebGPU's [`GPUExternalTexture`](https://www.w3.org/TR/webgpu/#gpuexternaltexture). These allow shaders to transparently operate on potentially multiplanar source texture data in either RGB or YCbCr formats via WGSL's `texture_external` type. This is gated behind the `Features::EXTERNAL_TEXTURE` feature, which is currently only supported on DX12. By @jamienicol in [#4386](https://github.com/gfx-rs/wgpu/issues/4386). + ### Changes #### General From 17a17f716a9e09d054e791ffd91f5e2e2b1c8cff Mon Sep 17 00:00:00 2001 From: Magnus <85136135+SupaMaggie70Incorporated@users.noreply.github.com> Date: Wed, 20 Aug 2025 15:20:59 -0500 Subject: [PATCH 138/303] Initial precompiled shaders implementation (#7834) Co-authored-by: Connor Fitzgerald --- CHANGELOG.md | 21 +++ Cargo.lock | 1 + deno_webgpu/webidl.rs | 15 +- examples/features/src/mesh_shader/mod.rs | 14 +- player/Cargo.toml | 1 + player/src/lib.rs | 78 +++++++++ tests/tests/wgpu-gpu/mesh_shader/mod.rs | 14 +- wgpu-core/src/device/global.rs | 51 +++--- wgpu-core/src/device/resource.rs | 76 +++++---- wgpu-core/src/device/trace.rs | 9 + wgpu-core/src/pipeline.rs | 3 + wgpu-hal/src/dx12/adapter.rs | 4 +- wgpu-hal/src/dx12/device.rs | 11 +- wgpu-hal/src/gles/device.rs | 23 ++- wgpu-hal/src/gles/mod.rs | 2 +- wgpu-hal/src/lib.rs | 7 +- wgpu-hal/src/metal/adapter.rs | 4 +- wgpu-hal/src/metal/device.rs | 12 +- wgpu-hal/src/vulkan/adapter.rs | 4 +- wgpu-hal/src/vulkan/device.rs | 12 +- wgpu-types/src/features.rs | 41 ++--- wgpu-types/src/lib.rs | 202 ++++++++--------------- wgpu/src/api/shader_module.rs | 28 +--- wgpu/src/backend/webgpu.rs | 38 ++++- wgpu/src/backend/wgpu_core.rs | 2 +- wgpu/src/macros.rs | 25 ++- 26 files changed, 383 insertions(+), 315 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e9bc2d0f63..4d9a84a7341 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,27 @@ We have merged the acceleration structure feature into the `RayQuery` feature. T By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). +#### New `EXPERIMENTAL_PRECOMPILED_SHADERS` API +We have added `Features::EXPERIMENTAL_PRECOMPILED_SHADERS`, replacing existing passthrough types with a unified `CreateShaderModuleDescriptorPassthrough` which allows passing multiple shader codes for different backends. By @SupaMaggie70Incorporated in [#7834](https://github.com/gfx-rs/wgpu/pull/7834) + +Difference for SPIR-V passthrough: +```diff +- device.create_shader_module_passthrough(wgpu::ShaderModuleDescriptorPassthrough::SpirV( +- wgpu::ShaderModuleDescriptorSpirV { +- label: None, +- source: spirv_code, +- }, +- )) ++ device.create_shader_module_passthrough(wgpu::ShaderModuleDescriptorPassthrough { ++ entry_point: "main".into(), ++ label: None, ++ spirv: Some(spirv_code), ++ ..Default::default() +}) +``` +This allows using precompiled shaders without manually checking which backend's code to pass, for example if you have shaders precompiled for both DXIL and SPIR-V. + + ### New Features #### General diff --git a/Cargo.lock b/Cargo.lock index 56128ca6616..2d3f7dcd13d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3191,6 +3191,7 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" name = "player" version = "26.0.0" dependencies = [ + "bytemuck", "env_logger", "log", "raw-window-handle 0.6.2", diff --git a/deno_webgpu/webidl.rs b/deno_webgpu/webidl.rs index 533da00c830..75a19d372c3 100644 --- a/deno_webgpu/webidl.rs +++ b/deno_webgpu/webidl.rs @@ -419,10 +419,6 @@ pub enum GPUFeatureName { VertexWritableStorage, #[webidl(rename = "clear-texture")] ClearTexture, - #[webidl(rename = "msl-shader-passthrough")] - MslShaderPassthrough, - #[webidl(rename = "spirv-shader-passthrough")] - SpirvShaderPassthrough, #[webidl(rename = "multiview")] Multiview, #[webidl(rename = "vertex-attribute-64-bit")] @@ -435,6 +431,8 @@ pub enum GPUFeatureName { ShaderPrimitiveIndex, #[webidl(rename = "shader-early-depth-test")] ShaderEarlyDepthTest, + #[webidl(rename = "passthrough-shaders")] + PassthroughShaders, } pub fn feature_names_to_features(names: Vec) -> wgpu_types::Features { @@ -482,14 +480,13 @@ pub fn feature_names_to_features(names: Vec) -> wgpu_types::Feat GPUFeatureName::ConservativeRasterization => Features::CONSERVATIVE_RASTERIZATION, GPUFeatureName::VertexWritableStorage => Features::VERTEX_WRITABLE_STORAGE, GPUFeatureName::ClearTexture => Features::CLEAR_TEXTURE, - GPUFeatureName::MslShaderPassthrough => Features::MSL_SHADER_PASSTHROUGH, - GPUFeatureName::SpirvShaderPassthrough => Features::SPIRV_SHADER_PASSTHROUGH, GPUFeatureName::Multiview => Features::MULTIVIEW, GPUFeatureName::VertexAttribute64Bit => Features::VERTEX_ATTRIBUTE_64BIT, GPUFeatureName::ShaderF64 => Features::SHADER_F64, GPUFeatureName::ShaderI16 => Features::SHADER_I16, GPUFeatureName::ShaderPrimitiveIndex => Features::SHADER_PRIMITIVE_INDEX, GPUFeatureName::ShaderEarlyDepthTest => Features::SHADER_EARLY_DEPTH_TEST, + GPUFeatureName::PassthroughShaders => Features::EXPERIMENTAL_PASSTHROUGH_SHADERS, }; features.set(feature, true); } @@ -626,9 +623,6 @@ pub fn features_to_feature_names(features: wgpu_types::Features) -> HashSet HashSet wgpu::Features { - wgpu::Features::EXPERIMENTAL_MESH_SHADER | wgpu::Features::SPIRV_SHADER_PASSTHROUGH + wgpu::Features::EXPERIMENTAL_MESH_SHADER | wgpu::Features::EXPERIMENTAL_PASSTHROUGH_SHADERS } fn required_limits() -> wgpu::Limits { wgpu::Limits::defaults().using_recommended_minimum_mesh_shader_values() diff --git a/player/Cargo.toml b/player/Cargo.toml index aadf4e5e8ff..f29aacf0e94 100644 --- a/player/Cargo.toml +++ b/player/Cargo.toml @@ -26,6 +26,7 @@ log.workspace = true raw-window-handle.workspace = true ron.workspace = true winit = { workspace = true, optional = true } +bytemuck.workspace = true # Non-Webassembly # diff --git a/player/src/lib.rs b/player/src/lib.rs index 5076db0267d..8ba7e13ce1b 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -315,6 +315,84 @@ impl GlobalPlay for wgc::global::Global { println!("shader compilation error:\n---{code}\n---\n{e}"); } } + Action::CreateShaderModulePassthrough { + id, + data, + entry_point, + label, + num_workgroups, + runtime_checks, + } => { + let spirv = data.iter().find_map(|a| { + if a.ends_with(".spv") { + let data = fs::read(dir.join(a)).unwrap(); + assert!(data.len() % 4 == 0); + + Some(Cow::Owned(bytemuck::pod_collect_to_vec(&data))) + } else { + None + } + }); + let dxil = data.iter().find_map(|a| { + if a.ends_with(".dxil") { + let vec = std::fs::read(dir.join(a)).unwrap(); + Some(Cow::Owned(vec)) + } else { + None + } + }); + let hlsl = data.iter().find_map(|a| { + if a.ends_with(".hlsl") { + let code = fs::read_to_string(dir.join(a)).unwrap(); + Some(Cow::Owned(code)) + } else { + None + } + }); + let msl = data.iter().find_map(|a| { + if a.ends_with(".msl") { + let code = fs::read_to_string(dir.join(a)).unwrap(); + Some(Cow::Owned(code)) + } else { + None + } + }); + let glsl = data.iter().find_map(|a| { + if a.ends_with(".glsl") { + let code = fs::read_to_string(dir.join(a)).unwrap(); + Some(Cow::Owned(code)) + } else { + None + } + }); + let wgsl = data.iter().find_map(|a| { + if a.ends_with(".wgsl") { + let code = fs::read_to_string(dir.join(a)).unwrap(); + Some(Cow::Owned(code)) + } else { + None + } + }); + let desc = wgt::CreateShaderModuleDescriptorPassthrough { + entry_point, + label, + num_workgroups, + runtime_checks, + + spirv, + dxil, + hlsl, + msl, + glsl, + wgsl, + }; + let (_, error) = unsafe { + self.device_create_shader_module_passthrough(device, &desc, Some(id)) + }; + if let Some(e) = error { + println!("shader compilation error: {e}"); + } + } Action::DestroyShaderModule(id) => { self.shader_module_drop(id); } diff --git a/tests/tests/wgpu-gpu/mesh_shader/mod.rs b/tests/tests/wgpu-gpu/mesh_shader/mod.rs index 8a0bdf4b80f..4dd897129f6 100644 --- a/tests/tests/wgpu-gpu/mesh_shader/mod.rs +++ b/tests/tests/wgpu-gpu/mesh_shader/mod.rs @@ -41,12 +41,12 @@ fn compile_glsl( let output = cmd.wait_with_output().expect("Error waiting for glslc"); assert!(output.status.success()); unsafe { - device.create_shader_module_passthrough(wgpu::ShaderModuleDescriptorPassthrough::SpirV( - wgpu::ShaderModuleDescriptorSpirV { - label: None, - source: wgpu::util::make_spirv_raw(&output.stdout), - }, - )) + device.create_shader_module_passthrough(wgpu::ShaderModuleDescriptorPassthrough { + entry_point: "main".into(), + label: None, + spirv: Some(wgpu::util::make_spirv_raw(&output.stdout)), + ..Default::default() + }) } } @@ -267,7 +267,7 @@ fn default_gpu_test_config(draw_type: DrawType) -> GpuTestConfiguration { .test_features_limits() .features( wgpu::Features::EXPERIMENTAL_MESH_SHADER - | wgpu::Features::SPIRV_SHADER_PASSTHROUGH + | wgpu::Features::EXPERIMENTAL_PASSTHROUGH_SHADERS | match draw_type { DrawType::Standard | DrawType::Indirect => wgpu::Features::empty(), DrawType::MultiIndirect => wgpu::Features::MULTI_DRAW_INDIRECT, diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index 92f10fc07fc..4b35638c48f 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -1094,36 +1094,27 @@ impl Global { #[cfg(feature = "trace")] if let Some(ref mut trace) = *device.trace.lock() { - let data = trace.make_binary(desc.trace_binary_ext(), desc.trace_data()); - trace.add(trace::Action::CreateShaderModule { + let mut file_names = Vec::new(); + for (data, ext) in [ + (desc.spirv.as_ref().map(|a| bytemuck::cast_slice(a)), "spv"), + (desc.dxil.as_deref(), "dxil"), + (desc.hlsl.as_ref().map(|a| a.as_bytes()), "hlsl"), + (desc.msl.as_ref().map(|a| a.as_bytes()), "msl"), + (desc.glsl.as_ref().map(|a| a.as_bytes()), "glsl"), + (desc.wgsl.as_ref().map(|a| a.as_bytes()), "wgsl"), + ] { + if let Some(data) = data { + file_names.push(trace.make_binary(ext, data)); + } + } + trace.add(trace::Action::CreateShaderModulePassthrough { id: fid.id(), - desc: match desc { - pipeline::ShaderModuleDescriptorPassthrough::SpirV(inner) => { - pipeline::ShaderModuleDescriptor { - label: inner.label.clone(), - runtime_checks: wgt::ShaderRuntimeChecks::unchecked(), - } - } - pipeline::ShaderModuleDescriptorPassthrough::Msl(inner) => { - pipeline::ShaderModuleDescriptor { - label: inner.label.clone(), - runtime_checks: wgt::ShaderRuntimeChecks::unchecked(), - } - } - pipeline::ShaderModuleDescriptorPassthrough::Dxil(inner) => { - pipeline::ShaderModuleDescriptor { - label: inner.label.clone(), - runtime_checks: wgt::ShaderRuntimeChecks::unchecked(), - } - } - pipeline::ShaderModuleDescriptorPassthrough::Hlsl(inner) => { - pipeline::ShaderModuleDescriptor { - label: inner.label.clone(), - runtime_checks: wgt::ShaderRuntimeChecks::unchecked(), - } - } - }, - data, + data: file_names, + + entry_point: desc.entry_point.clone(), + label: desc.label.clone(), + num_workgroups: desc.num_workgroups, + runtime_checks: desc.runtime_checks, }); }; @@ -1138,7 +1129,7 @@ impl Global { return (id, None); }; - let id = fid.assign(Fallible::Invalid(Arc::new(desc.label().to_string()))); + let id = fid.assign(Fallible::Invalid(Arc::new(desc.label.to_string()))); (id, Some(error)) } diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index a7cacea5945..ba894a977aa 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -2125,39 +2125,59 @@ impl Device { descriptor: &pipeline::ShaderModuleDescriptorPassthrough<'a>, ) -> Result, pipeline::CreateShaderModuleError> { self.check_is_valid()?; - let hal_shader = match descriptor { - pipeline::ShaderModuleDescriptorPassthrough::SpirV(inner) => { - self.require_features(wgt::Features::SPIRV_SHADER_PASSTHROUGH)?; - hal::ShaderInput::SpirV(&inner.source) - } - pipeline::ShaderModuleDescriptorPassthrough::Msl(inner) => { - self.require_features(wgt::Features::MSL_SHADER_PASSTHROUGH)?; - hal::ShaderInput::Msl { - shader: inner.source.to_string(), - entry_point: inner.entry_point.to_string(), - num_workgroups: inner.num_workgroups, - } - } - pipeline::ShaderModuleDescriptorPassthrough::Dxil(inner) => { - self.require_features(wgt::Features::HLSL_DXIL_SHADER_PASSTHROUGH)?; - hal::ShaderInput::Dxil { - shader: inner.source, - entry_point: inner.entry_point.clone(), - num_workgroups: inner.num_workgroups, + self.require_features(wgt::Features::EXPERIMENTAL_PASSTHROUGH_SHADERS)?; + + // TODO: when we get to use if-let chains, this will be a little nicer! + + log::info!("Backend: {}", self.backend()); + let hal_shader = match self.backend() { + wgt::Backend::Vulkan => hal::ShaderInput::SpirV( + descriptor + .spirv + .as_ref() + .ok_or(pipeline::CreateShaderModuleError::NotCompiledForBackend)?, + ), + wgt::Backend::Dx12 => { + if let Some(dxil) = &descriptor.dxil { + hal::ShaderInput::Dxil { + shader: dxil, + entry_point: descriptor.entry_point.clone(), + num_workgroups: descriptor.num_workgroups, + } + } else if let Some(hlsl) = &descriptor.hlsl { + hal::ShaderInput::Hlsl { + shader: hlsl, + entry_point: descriptor.entry_point.clone(), + num_workgroups: descriptor.num_workgroups, + } + } else { + return Err(pipeline::CreateShaderModuleError::NotCompiledForBackend); } } - pipeline::ShaderModuleDescriptorPassthrough::Hlsl(inner) => { - self.require_features(wgt::Features::HLSL_DXIL_SHADER_PASSTHROUGH)?; - hal::ShaderInput::Hlsl { - shader: inner.source, - entry_point: inner.entry_point.clone(), - num_workgroups: inner.num_workgroups, - } + wgt::Backend::Metal => hal::ShaderInput::Msl { + shader: descriptor + .msl + .as_ref() + .ok_or(pipeline::CreateShaderModuleError::NotCompiledForBackend)?, + entry_point: descriptor.entry_point.clone(), + num_workgroups: descriptor.num_workgroups, + }, + wgt::Backend::Gl => hal::ShaderInput::Glsl { + shader: descriptor + .glsl + .as_ref() + .ok_or(pipeline::CreateShaderModuleError::NotCompiledForBackend)?, + entry_point: descriptor.entry_point.clone(), + num_workgroups: descriptor.num_workgroups, + }, + wgt::Backend::Noop => { + return Err(pipeline::CreateShaderModuleError::NotCompiledForBackend) } + wgt::Backend::BrowserWebGpu => unreachable!(), }; let hal_desc = hal::ShaderModuleDescriptor { - label: descriptor.label().to_hal(self.instance_flags), + label: descriptor.label.to_hal(self.instance_flags), runtime_checks: wgt::ShaderRuntimeChecks::unchecked(), }; @@ -2180,7 +2200,7 @@ impl Device { raw: ManuallyDrop::new(raw), device: self.clone(), interface: None, - label: descriptor.label().to_string(), + label: descriptor.label.to_string(), }; Ok(Arc::new(module)) diff --git a/wgpu-core/src/device/trace.rs b/wgpu-core/src/device/trace.rs index 58d26e4b079..80432d5e938 100644 --- a/wgpu-core/src/device/trace.rs +++ b/wgpu-core/src/device/trace.rs @@ -93,6 +93,15 @@ pub enum Action<'a> { desc: crate::pipeline::ShaderModuleDescriptor<'a>, data: FileName, }, + CreateShaderModulePassthrough { + id: id::ShaderModuleId, + data: Vec, + + entry_point: String, + label: crate::Label<'a>, + num_workgroups: (u32, u32, u32), + runtime_checks: wgt::ShaderRuntimeChecks, + }, DestroyShaderModule(id::ShaderModuleId), CreateComputePipeline { id: id::ComputePipelineId, diff --git a/wgpu-core/src/pipeline.rs b/wgpu-core/src/pipeline.rs index 580fdc4d94e..753518f67ad 100644 --- a/wgpu-core/src/pipeline.rs +++ b/wgpu-core/src/pipeline.rs @@ -130,6 +130,8 @@ pub enum CreateShaderModuleError { group: u32, limit: u32, }, + #[error("Generic shader passthrough does not contain any code compatible with this backend.")] + NotCompiledForBackend, } impl WebGpuError for CreateShaderModuleError { @@ -147,6 +149,7 @@ impl WebGpuError for CreateShaderModuleError { Self::ParsingGlsl(..) => return ErrorType::Validation, #[cfg(feature = "spirv")] Self::ParsingSpirV(..) => return ErrorType::Validation, + Self::NotCompiledForBackend => return ErrorType::Validation, }; e.webgpu_error_type() } diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index 1f57fa69010..88d01103629 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -363,8 +363,8 @@ impl super::Adapter { | wgt::Features::TEXTURE_FORMAT_NV12 | wgt::Features::FLOAT32_FILTERABLE | wgt::Features::TEXTURE_ATOMIC - | wgt::Features::EXTERNAL_TEXTURE - | wgt::Features::HLSL_DXIL_SHADER_PASSTHROUGH; + | wgt::Features::EXPERIMENTAL_PASSTHROUGH_SHADERS + | wgt::Features::EXTERNAL_TEXTURE; //TODO: in order to expose this, we need to run a compute shader // that extract the necessary statistics out of the D3D12 result. diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index d62fc5c6751..34454c9f963 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -1777,12 +1777,6 @@ impl crate::Device for super::Device { raw_name, runtime_checks: desc.runtime_checks, }), - crate::ShaderInput::SpirV(_) => { - panic!("SPIRV_SHADER_PASSTHROUGH is not enabled for this backend") - } - crate::ShaderInput::Msl { .. } => { - panic!("MSL_SHADER_PASSTHROUGH is not enabled for this backend") - } crate::ShaderInput::Dxil { shader, entry_point, @@ -1809,6 +1803,11 @@ impl crate::Device for super::Device { raw_name, runtime_checks: desc.runtime_checks, }), + crate::ShaderInput::SpirV(_) + | crate::ShaderInput::Msl { .. } + | crate::ShaderInput::Glsl { .. } => { + unreachable!() + } } } unsafe fn destroy_shader_module(&self, _module: super::ShaderModule) { diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index 0b1b77e11bc..dda5525c61c 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -222,8 +222,8 @@ impl super::Device { }; let (module, info) = naga::back::pipeline_constants::process_overrides( - &stage.module.naga.module, - &stage.module.naga.info, + &stage.module.source.module, + &stage.module.source.info, Some((naga_stage, stage.entry_point)), stage.constants, ) @@ -463,7 +463,7 @@ impl super::Device { for (stage_idx, stage_items) in push_constant_items.into_iter().enumerate() { for item in stage_items { - let naga_module = &shaders[stage_idx].1.module.naga.module; + let naga_module = &shaders[stage_idx].1.module.source.module; let type_inner = &naga_module.types[item.ty].inner; let location = unsafe { gl.get_uniform_location(program, &item.access_path) }; @@ -1334,16 +1334,15 @@ impl crate::Device for super::Device { self.counters.shader_modules.add(1); Ok(super::ShaderModule { - naga: match shader { - crate::ShaderInput::SpirV(_) => { - panic!("`Features::SPIRV_SHADER_PASSTHROUGH` is not enabled") - } - crate::ShaderInput::Msl { .. } => { - panic!("`Features::MSL_SHADER_PASSTHROUGH` is not enabled") - } + source: match shader { crate::ShaderInput::Naga(naga) => naga, - crate::ShaderInput::Dxil { .. } | crate::ShaderInput::Hlsl { .. } => { - panic!("`Features::HLSL_DXIL_SHADER_PASSTHROUGH` is not enabled") + // The backend doesn't yet expose this feature so it should be fine + crate::ShaderInput::Glsl { .. } => unimplemented!(), + crate::ShaderInput::SpirV(_) + | crate::ShaderInput::Msl { .. } + | crate::ShaderInput::Dxil { .. } + | crate::ShaderInput::Hlsl { .. } => { + unreachable!() } }, label: desc.label.map(|str| str.to_string()), diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 94416086d2e..b56a851e395 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -605,7 +605,7 @@ type ShaderId = u32; #[derive(Debug)] pub struct ShaderModule { - naga: crate::NagaShader, + source: crate::NagaShader, label: Option, id: ShaderId, } diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index e60b07e9a6a..b4255a6c811 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -2219,7 +2219,7 @@ impl fmt::Debug for NagaShader { pub enum ShaderInput<'a> { Naga(NagaShader), Msl { - shader: String, + shader: &'a str, entry_point: String, num_workgroups: (u32, u32, u32), }, @@ -2234,6 +2234,11 @@ pub enum ShaderInput<'a> { entry_point: String, num_workgroups: (u32, u32, u32), }, + Glsl { + shader: &'a str, + entry_point: String, + num_workgroups: (u32, u32, u32), + }, } pub struct ShaderModuleDescriptor<'a> { diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index d02e38980ac..02dfc0fe601 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -917,7 +917,6 @@ impl super::PrivateCapabilities { use wgt::Features as F; let mut features = F::empty() - | F::MSL_SHADER_PASSTHROUGH | F::MAPPABLE_PRIMARY_BUFFERS | F::VERTEX_WRITABLE_STORAGE | F::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES @@ -927,7 +926,8 @@ impl super::PrivateCapabilities { | F::TEXTURE_FORMAT_16BIT_NORM | F::SHADER_F16 | F::DEPTH32FLOAT_STENCIL8 - | F::BGRA8UNORM_STORAGE; + | F::BGRA8UNORM_STORAGE + | F::EXPERIMENTAL_PASSTHROUGH_SHADERS; features.set(F::FLOAT32_FILTERABLE, self.supports_float_filtering); features.set( diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index fbb166c2723..6af8ad3062d 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -1017,7 +1017,7 @@ impl crate::Device for super::Device { // Obtain the locked device from shared let device = self.shared.device.lock(); let library = device - .new_library_with_source(&source, &options) + .new_library_with_source(source, &options) .map_err(|e| crate::ShaderError::Compilation(format!("MSL: {e:?}")))?; let function = library.get_function(&entry_point, None).map_err(|_| { crate::ShaderError::Compilation(format!( @@ -1035,12 +1035,10 @@ impl crate::Device for super::Device { bounds_checks: desc.runtime_checks, }) } - crate::ShaderInput::SpirV(_) => { - panic!("SPIRV_SHADER_PASSTHROUGH is not enabled for this backend") - } - crate::ShaderInput::Dxil { .. } | crate::ShaderInput::Hlsl { .. } => { - panic!("`Features::HLSL_DXIL_SHADER_PASSTHROUGH` is not enabled for this backend") - } + crate::ShaderInput::SpirV(_) + | crate::ShaderInput::Dxil { .. } + | crate::ShaderInput::Hlsl { .. } + | crate::ShaderInput::Glsl { .. } => unreachable!(), } } diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index bb4e2a9d4ae..f94e1ac3272 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -543,7 +543,6 @@ impl PhysicalDeviceFeatures { ) -> (wgt::Features, wgt::DownlevelFlags) { use wgt::{DownlevelFlags as Df, Features as F}; let mut features = F::empty() - | F::SPIRV_SHADER_PASSTHROUGH | F::MAPPABLE_PRIMARY_BUFFERS | F::PUSH_CONSTANTS | F::ADDRESS_MODE_CLAMP_TO_BORDER @@ -555,7 +554,8 @@ impl PhysicalDeviceFeatures { | F::CLEAR_TEXTURE | F::PIPELINE_CACHE | F::SHADER_EARLY_DEPTH_TEST - | F::TEXTURE_ATOMIC; + | F::TEXTURE_ATOMIC + | F::EXPERIMENTAL_PASSTHROUGH_SHADERS; let mut dl_flags = Df::COMPUTE_SHADERS | Df::BASE_VERTEX diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 48be11a124d..42771f5c597 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -1940,13 +1940,11 @@ impl crate::Device for super::Device { .map_err(|e| crate::ShaderError::Compilation(format!("{e}")))?, ) } - crate::ShaderInput::Msl { .. } => { - panic!("MSL_SHADER_PASSTHROUGH is not enabled for this backend") - } - crate::ShaderInput::Dxil { .. } | crate::ShaderInput::Hlsl { .. } => { - panic!("`Features::HLSL_DXIL_SHADER_PASSTHROUGH` is not enabled") - } - crate::ShaderInput::SpirV(spv) => Cow::Borrowed(spv), + crate::ShaderInput::SpirV(data) => Cow::Borrowed(data), + crate::ShaderInput::Msl { .. } + | crate::ShaderInput::Dxil { .. } + | crate::ShaderInput::Hlsl { .. } + | crate::ShaderInput::Glsl { .. } => unreachable!(), }; let raw = self.create_shader_module_impl(&spv)?; diff --git a/wgpu-types/src/features.rs b/wgpu-types/src/features.rs index af3a920cd61..8f7418b018d 100644 --- a/wgpu-types/src/features.rs +++ b/wgpu-types/src/features.rs @@ -926,29 +926,6 @@ bitflags_array! { /// /// This is a native only feature. const CLEAR_TEXTURE = 1 << 23; - /// Enables creating shader modules from Metal MSL computer shaders (unsafe). - /// - /// Metal data is not parsed or interpreted in any way - /// - /// Supported platforms: - /// - Metal - /// - /// This is a native only feature. - const MSL_SHADER_PASSTHROUGH = 1 << 24; - /// Enables creating shader modules from SPIR-V binary data (unsafe). - /// - /// SPIR-V data is not parsed or interpreted in any way; you can use - /// [`wgpu::make_spirv_raw!`] to check for alignment and magic number when converting from - /// raw bytes. - /// - /// Supported platforms: - /// - Vulkan, in case shader's requested capabilities and extensions agree with - /// Vulkan implementation. - /// - /// This is a native only feature. - /// - /// [`wgpu::make_spirv_raw!`]: https://docs.rs/wgpu/latest/wgpu/macro.include_spirv_raw.html - const SPIRV_SHADER_PASSTHROUGH = 1 << 25; /// Enables multiview render passes and `builtin(view_index)` in vertex shaders. /// /// Supported platforms: @@ -1243,15 +1220,23 @@ bitflags_array! { /// [BlasTriangleGeometrySizeDescriptor::vertex_format]: super::BlasTriangleGeometrySizeDescriptor const EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS = 1 << 51; - /// Enables creating shader modules from DirectX HLSL or DXIL shaders (unsafe) + /// Enables creating shaders from passthrough with reflection info (unsafe) /// - /// HLSL/DXIL data is not parsed or interpreted in any way + /// Allows using [`Device::create_shader_module_passthrough`]. + /// Shader code isn't parsed or interpreted in any way. It is the user's + /// responsibility to ensure the code and reflection (if passed) are correct. /// - /// Supported platforms: + /// Supported platforms + /// - Vulkan /// - DX12 + /// - Metal + /// - WebGPU /// - /// This is a native only feature. - const HLSL_DXIL_SHADER_PASSTHROUGH = 1 << 52; + /// Ideally, in the future, all platforms will be supported. For more info, see + /// [this comment](https://github.com/gfx-rs/wgpu/issues/3103#issuecomment-2833058367). + /// + /// [`Device::create_shader_module_passthrough`]: https://docs.rs/wgpu/latest/wgpu/struct.Device.html#method.create_shader_module_passthrough + const EXPERIMENTAL_PASSTHROUGH_SHADERS = 1 << 52; } /// Features that are not guaranteed to be supported. diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index fb71e420262..ea2a09eb62a 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -8032,20 +8032,52 @@ pub enum DeviceLostReason { Destroyed = 1, } -/// Descriptor for creating a shader module. -/// -/// This type is unique to the Rust API of `wgpu`. In the WebGPU specification, -/// only WGSL source code strings are accepted. +/// Descriptor for a shader module given by any of several sources. +/// These shaders are passed through directly to the underlying api. +/// At least one shader type that may be used by the backend must be `Some` or a panic is raised. #[derive(Debug, Clone)] -pub enum CreateShaderModuleDescriptorPassthrough<'a, L> { - /// Passthrough for SPIR-V binaries. - SpirV(ShaderModuleDescriptorSpirV<'a, L>), - /// Passthrough for MSL source code. - Msl(ShaderModuleDescriptorMsl<'a, L>), - /// Passthrough for DXIL compiled with DXC - Dxil(ShaderModuleDescriptorDxil<'a, L>), - /// Passthrough for HLSL - Hlsl(ShaderModuleDescriptorHlsl<'a, L>), +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct CreateShaderModuleDescriptorPassthrough<'a, L> { + /// Entrypoint. Unused for Spir-V. + pub entry_point: String, + /// Debug label of the shader module. This will show up in graphics debuggers for easy identification. + pub label: L, + /// Number of workgroups in each dimension x, y and z. Unused for Spir-V. + pub num_workgroups: (u32, u32, u32), + /// Runtime checks that should be enabled. + pub runtime_checks: ShaderRuntimeChecks, + + /// Binary SPIR-V data, in 4-byte words. + pub spirv: Option>, + /// Shader DXIL source. + pub dxil: Option>, + /// Shader MSL source. + pub msl: Option>, + /// Shader HLSL source. + pub hlsl: Option>, + /// Shader GLSL source (currently unused). + pub glsl: Option>, + /// Shader WGSL source. + pub wgsl: Option>, +} + +// This is so people don't have to fill in fields they don't use, like num_workgroups, +// entry_point, or other shader languages they didn't compile for +impl<'a, L: Default> Default for CreateShaderModuleDescriptorPassthrough<'a, L> { + fn default() -> Self { + Self { + entry_point: "".into(), + label: Default::default(), + num_workgroups: (0, 0, 0), + runtime_checks: ShaderRuntimeChecks::unchecked(), + spirv: None, + dxil: None, + msl: None, + hlsl: None, + glsl: None, + wgsl: None, + } + } } impl<'a, L> CreateShaderModuleDescriptorPassthrough<'a, L> { @@ -8053,134 +8085,46 @@ impl<'a, L> CreateShaderModuleDescriptorPassthrough<'a, L> { pub fn map_label( &self, fun: impl FnOnce(&L) -> K, - ) -> CreateShaderModuleDescriptorPassthrough<'_, K> { - match self { - CreateShaderModuleDescriptorPassthrough::SpirV(inner) => { - CreateShaderModuleDescriptorPassthrough::<'_, K>::SpirV( - ShaderModuleDescriptorSpirV { - label: fun(&inner.label), - source: inner.source.clone(), - }, - ) - } - CreateShaderModuleDescriptorPassthrough::Msl(inner) => { - CreateShaderModuleDescriptorPassthrough::<'_, K>::Msl(ShaderModuleDescriptorMsl { - entry_point: inner.entry_point.clone(), - label: fun(&inner.label), - num_workgroups: inner.num_workgroups, - source: inner.source.clone(), - }) - } - CreateShaderModuleDescriptorPassthrough::Dxil(inner) => { - CreateShaderModuleDescriptorPassthrough::<'_, K>::Dxil(ShaderModuleDescriptorDxil { - entry_point: inner.entry_point.clone(), - label: fun(&inner.label), - num_workgroups: inner.num_workgroups, - source: inner.source, - }) - } - CreateShaderModuleDescriptorPassthrough::Hlsl(inner) => { - CreateShaderModuleDescriptorPassthrough::<'_, K>::Hlsl(ShaderModuleDescriptorHlsl { - entry_point: inner.entry_point.clone(), - label: fun(&inner.label), - num_workgroups: inner.num_workgroups, - source: inner.source, - }) - } - } - } - - /// Returns the label of shader module passthrough descriptor. - pub fn label(&'a self) -> &'a L { - match self { - CreateShaderModuleDescriptorPassthrough::SpirV(inner) => &inner.label, - CreateShaderModuleDescriptorPassthrough::Msl(inner) => &inner.label, - CreateShaderModuleDescriptorPassthrough::Dxil(inner) => &inner.label, - CreateShaderModuleDescriptorPassthrough::Hlsl(inner) => &inner.label, + ) -> CreateShaderModuleDescriptorPassthrough<'a, K> { + CreateShaderModuleDescriptorPassthrough { + entry_point: self.entry_point.clone(), + label: fun(&self.label), + num_workgroups: self.num_workgroups, + runtime_checks: self.runtime_checks, + spirv: self.spirv.clone(), + dxil: self.dxil.clone(), + msl: self.msl.clone(), + hlsl: self.hlsl.clone(), + glsl: self.glsl.clone(), + wgsl: self.wgsl.clone(), } } #[cfg(feature = "trace")] /// Returns the source data for tracing purpose. pub fn trace_data(&self) -> &[u8] { - match self { - CreateShaderModuleDescriptorPassthrough::SpirV(inner) => { - bytemuck::cast_slice(&inner.source) - } - CreateShaderModuleDescriptorPassthrough::Msl(inner) => inner.source.as_bytes(), - CreateShaderModuleDescriptorPassthrough::Dxil(inner) => inner.source, - CreateShaderModuleDescriptorPassthrough::Hlsl(inner) => inner.source.as_bytes(), + if let Some(spirv) = &self.spirv { + bytemuck::cast_slice(spirv) + } else if let Some(msl) = &self.msl { + msl.as_bytes() + } else if let Some(dxil) = &self.dxil { + dxil + } else { + panic!("No binary data provided to `ShaderModuleDescriptorGeneric`") } } #[cfg(feature = "trace")] /// Returns the binary file extension for tracing purpose. pub fn trace_binary_ext(&self) -> &'static str { - match self { - CreateShaderModuleDescriptorPassthrough::SpirV(..) => "spv", - CreateShaderModuleDescriptorPassthrough::Msl(..) => "msl", - CreateShaderModuleDescriptorPassthrough::Dxil(..) => "dxil", - CreateShaderModuleDescriptorPassthrough::Hlsl(..) => "hlsl", + if self.spirv.is_some() { + "spv" + } else if self.msl.is_some() { + "msl" + } else if self.dxil.is_some() { + "dxil" + } else { + panic!("No binary data provided to `ShaderModuleDescriptorGeneric`") } } } - -/// Descriptor for a shader module given by Metal MSL source. -/// -/// This type is unique to the Rust API of `wgpu`. In the WebGPU specification, -/// only WGSL source code strings are accepted. -#[derive(Debug, Clone)] -pub struct ShaderModuleDescriptorMsl<'a, L> { - /// Entrypoint. - pub entry_point: String, - /// Debug label of the shader module. This will show up in graphics debuggers for easy identification. - pub label: L, - /// Number of workgroups in each dimension x, y and z. - pub num_workgroups: (u32, u32, u32), - /// Shader MSL source. - pub source: Cow<'a, str>, -} - -/// Descriptor for a shader module given by DirectX DXIL source. -/// -/// This type is unique to the Rust API of `wgpu`. In the WebGPU specification, -/// only WGSL source code strings are accepted. -#[derive(Debug, Clone)] -pub struct ShaderModuleDescriptorDxil<'a, L> { - /// Entrypoint. - pub entry_point: String, - /// Debug label of the shader module. This will show up in graphics debuggers for easy identification. - pub label: L, - /// Number of workgroups in each dimension x, y and z. - pub num_workgroups: (u32, u32, u32), - /// Shader DXIL source. - pub source: &'a [u8], -} - -/// Descriptor for a shader module given by DirectX HLSL source. -/// -/// This type is unique to the Rust API of `wgpu`. In the WebGPU specification, -/// only WGSL source code strings are accepted. -#[derive(Debug, Clone)] -pub struct ShaderModuleDescriptorHlsl<'a, L> { - /// Entrypoint. - pub entry_point: String, - /// Debug label of the shader module. This will show up in graphics debuggers for easy identification. - pub label: L, - /// Number of workgroups in each dimension x, y and z. - pub num_workgroups: (u32, u32, u32), - /// Shader HLSL source. - pub source: &'a str, -} - -/// Descriptor for a shader module given by SPIR-V binary. -/// -/// This type is unique to the Rust API of `wgpu`. In the WebGPU specification, -/// only WGSL source code strings are accepted. -#[derive(Debug, Clone)] -pub struct ShaderModuleDescriptorSpirV<'a, L> { - /// Debug label of the shader module. This will show up in graphics debuggers for easy identification. - pub label: L, - /// Binary SPIR-V data, in 4-byte words. - pub source: Cow<'a, [u32]>, -} diff --git a/wgpu/src/api/shader_module.rs b/wgpu/src/api/shader_module.rs index c481de6218a..b2aad03ab02 100644 --- a/wgpu/src/api/shader_module.rs +++ b/wgpu/src/api/shader_module.rs @@ -228,34 +228,10 @@ pub struct ShaderModuleDescriptor<'a> { } static_assertions::assert_impl_all!(ShaderModuleDescriptor<'_>: Send, Sync); -/// Descriptor for a shader module that will bypass wgpu's shader tooling, for use with -/// [`Device::create_shader_module_passthrough`]. +/// Descriptor for a shader module given by any of several sources. +/// At least one of the shader types that may be used by the backend must be `Some` /// /// This type is unique to the Rust API of `wgpu`. In the WebGPU specification, /// only WGSL source code strings are accepted. pub type ShaderModuleDescriptorPassthrough<'a> = wgt::CreateShaderModuleDescriptorPassthrough<'a, Label<'a>>; - -/// Descriptor for a shader module given by Metal MSL source. -/// -/// This type is unique to the Rust API of `wgpu`. In the WebGPU specification, -/// only WGSL source code strings are accepted. -pub type ShaderModuleDescriptorMsl<'a> = wgt::ShaderModuleDescriptorMsl<'a, Label<'a>>; - -/// Descriptor for a shader module given by SPIR-V binary. -/// -/// This type is unique to the Rust API of `wgpu`. In the WebGPU specification, -/// only WGSL source code strings are accepted. -pub type ShaderModuleDescriptorSpirV<'a> = wgt::ShaderModuleDescriptorSpirV<'a, Label<'a>>; - -/// Descriptor for a shader module given by DirectX HLSL source. -/// -/// This type is unique to the Rust API of `wgpu`. In the WebGPU specification, -/// only WGSL source code strings are accepted. -pub type ShaderModuleDescriptorHlsl<'a> = wgt::ShaderModuleDescriptorHlsl<'a, Label<'a>>; - -/// Descriptor for a shader module given by DirectX DXIL source. -/// -/// This type is unique to the Rust API of `wgpu`. In the WebGPU specification, -/// only WGSL source code strings are accepted. -pub type ShaderModuleDescriptorDxil<'a> = wgt::ShaderModuleDescriptorDxil<'a, Label<'a>>; diff --git a/wgpu/src/backend/webgpu.rs b/wgpu/src/backend/webgpu.rs index 0bd973cdb63..603922f86a8 100644 --- a/wgpu/src/backend/webgpu.rs +++ b/wgpu/src/backend/webgpu.rs @@ -1862,9 +1862,43 @@ impl dispatch::DeviceInterface for WebDevice { unsafe fn create_shader_module_passthrough( &self, - _desc: &crate::ShaderModuleDescriptorPassthrough<'_>, + desc: &crate::ShaderModuleDescriptorPassthrough<'_>, ) -> dispatch::DispatchShaderModule { - unreachable!("No XXX_SHADER_PASSTHROUGH feature enabled for this backend") + let shader_module_result = if let Some(ref code) = desc.wgsl { + let shader_module = webgpu_sys::GpuShaderModuleDescriptor::new(code); + Ok(( + shader_module, + WebShaderCompilationInfo::Wgsl { + source: code.to_string(), + }, + )) + } else { + Err(crate::CompilationInfo { + messages: vec![crate::CompilationMessage { + message: + "Passthrough shader not compiled for WGSL on WebGPU backend (WGPU error)" + .to_string(), + location: None, + message_type: crate::CompilationMessageType::Error, + }], + }) + }; + let (descriptor, compilation_info) = match shader_module_result { + Ok(v) => v, + Err(compilation_info) => ( + webgpu_sys::GpuShaderModuleDescriptor::new(""), + WebShaderCompilationInfo::Transformed { compilation_info }, + ), + }; + if let Some(label) = desc.label { + descriptor.set_label(label); + } + WebShaderModule { + module: self.inner.create_shader_module(&descriptor), + compilation_info, + ident: crate::cmp::Identifier::create(), + } + .into() } fn create_bind_group_layout( diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index 5b96225cdcb..812cd5276a4 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -1088,7 +1088,7 @@ impl dispatch::DeviceInterface for CoreDevice { self.context.handle_error( &self.error_sink, cause.clone(), - desc.label().as_deref(), + desc.label.as_deref(), "Device::create_shader_module_passthrough", ); CompilationInfo::from(cause) diff --git a/wgpu/src/macros.rs b/wgpu/src/macros.rs index c766dfb2178..537756adb92 100644 --- a/wgpu/src/macros.rs +++ b/wgpu/src/macros.rs @@ -96,22 +96,31 @@ macro_rules! include_spirv { }; } -/// Macro to load raw SPIR-V data statically, for use with [`Features::SPIRV_SHADER_PASSTHROUGH`]. +/// Macro to load raw SPIR-V data statically, for use with [`Features::EXPERIMENTAL_PASSTHROUGH_SHADERS`]. /// /// It ensures the word alignment as well as the magic number. /// -/// [`Features::SPIRV_SHADER_PASSTHROUGH`]: crate::Features::SPIRV_SHADER_PASSTHROUGH +/// [`Features::EXPERIMENTAL_PASSTHROUGH_SHADERS`]: crate::Features::EXPERIMENTAL_PASSTHROUGH_SHADERS #[macro_export] macro_rules! include_spirv_raw { ($($token:tt)*) => { { //log::info!("including '{}'", $($token)*); - $crate::ShaderModuleDescriptorPassthrough::SpirV( - $crate::ShaderModuleDescriptorSpirV { - label: $crate::__macro_helpers::Some($($token)*), - source: $crate::util::make_spirv_raw($crate::__macro_helpers::include_bytes!($($token)*)), - } - ) + $crate::ShaderModuleDescriptorPassthrough { + label: $crate::__macro_helpers::Some($($token)*), + spirv: Some($crate::util::make_spirv_raw($crate::__macro_helpers::include_bytes!($($token)*))), + + entry_point: "".to_owned(), + // This is unused for SPIR-V + num_workgroups: (0, 0, 0), + reflection: None, + shader_runtime_checks: $crate::ShaderRuntimeChecks::unchecked(), + dxil: None, + msl: None, + hlsl: None, + glsl: None, + wgsl: None, + } } }; } From fe86710af73ddb949ddb32830449fb8d3a72c23f Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Wed, 20 Aug 2025 17:16:58 -0400 Subject: [PATCH 139/303] Properly enable getrandom in nanorand (#8098) --- .cargo/config.toml | 4 ++++ .github/workflows/ci.yml | 5 +++++ Cargo.lock | 6 ++++++ Cargo.toml | 1 + examples/features/Cargo.toml | 3 ++- examples/features/src/repeated_compute/mod.rs | 4 +++- 6 files changed, 21 insertions(+), 2 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index b97153d60ad..16bb815038f 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,2 +1,6 @@ [alias] xtask = "run -p wgpu-xtask --" + +# Needed until https://github.com/rust-random/getrandom/issues/675 is resolved. +[target.wasm32-unknown-unknown] +rustflags = ["--cfg", "getrandom_backend=\"wasm_js\""] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 92c45fa7ae0..cc913c35f5c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -261,6 +261,8 @@ jobs: run: | set -e + export RUSTFLAGS="$RUSTFLAGS --cfg getrandom_backend=\"wasm_js\"" + # build for WebGPU cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} --tests --features glsl,spirv,fragile-send-sync-non-atomic-wasm cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} --tests --features glsl,spirv @@ -487,6 +489,9 @@ jobs: - name: Execute tests run: | cd wgpu + + export RUSTFLAGS="$RUSTFLAGS --cfg getrandom_backend=\"wasm_js\"" + wasm-pack test --headless --chrome --no-default-features --features wgsl,webgl,web --workspace gpu-test: diff --git a/Cargo.lock b/Cargo.lock index 2d3f7dcd13d..f4812d64f28 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1724,9 +1724,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi", "wasi 0.14.2+wasi-0.2.4", + "wasm-bindgen", ] [[package]] @@ -2581,6 +2583,9 @@ name = "nanorand" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e3d189da485332e96ba8a5ef646a311871abd7915bf06ac848a9117f19cf6e4" +dependencies = [ + "getrandom 0.3.3", +] [[package]] name = "nanoserde" @@ -5044,6 +5049,7 @@ dependencies = [ "env_logger", "fern", "flume", + "getrandom 0.3.3", "glam", "ktx2", "log", diff --git a/Cargo.toml b/Cargo.toml index c07c3986f24..ceea21bb873 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -116,6 +116,7 @@ env_logger = { version = "0.11", default-features = false } fern = "0.7" flume = "0.11" futures-lite = "2" +getrandom = "0.3" glam = "0.30" glob = "0.3" half = { version = "2.5", default-features = false } # We require 2.5 to have `Arbitrary` support. diff --git a/examples/features/Cargo.toml b/examples/features/Cargo.toml index b11ba7fc8a7..85c777f48b7 100644 --- a/examples/features/Cargo.toml +++ b/examples/features/Cargo.toml @@ -35,10 +35,11 @@ bytemuck.workspace = true cfg-if.workspace = true encase = { workspace = true, features = ["glam"] } flume.workspace = true +getrandom = { workspace = true, features = ["wasm_js"] } glam = { workspace = true, features = ["bytemuck"] } ktx2.workspace = true log.workspace = true -nanorand = { workspace = true, features = ["tls"] } +nanorand = { workspace = true, features = ["getrandom"] } noise.workspace = true obj.workspace = true png.workspace = true diff --git a/examples/features/src/repeated_compute/mod.rs b/examples/features/src/repeated_compute/mod.rs index 2b9b19995a8..f6104d948b5 100644 --- a/examples/features/src/repeated_compute/mod.rs +++ b/examples/features/src/repeated_compute/mod.rs @@ -13,9 +13,11 @@ async fn run() { let mut numbers = [0u32; 256]; let context = WgpuContext::new(size_of_val(&numbers)).await; + let mut rand = nanorand::WyRand::new(); + for _ in 0..10 { for p in numbers.iter_mut() { - *p = nanorand::tls_rng().generate::() as u32; + *p = rand.generate::() as u32; } compute(&mut numbers, &context).await; From e7a99be0584fc9a8517c3e22f34eb732b7524920 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 20 Aug 2025 14:58:56 -0700 Subject: [PATCH 140/303] [deno] Fix some problems in the handling of device limits (#8085) * Correct error type when a requested limit is too high * Clamp requested limits to the WebGPU defaults Fixes #8084 --- CHANGELOG.md | 1 + cts_runner/test.lst | 1 + deno_webgpu/adapter.rs | 14 +++- wgpu-types/src/lib.rs | 167 ++++++++++++++++++++++++++++------------- 4 files changed, 126 insertions(+), 57 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d9a84a7341..ed056032c2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -98,6 +98,7 @@ This allows using precompiled shaders without manually checking which backend's - The function you pass to `Device::on_uncaptured_error()` must now implement `Sync` in addition to `Send`, and be wrapped in `Arc` instead of `Box`. In exchange for this, it is no longer possible for calling `wgpu` functions while in that callback to cause a deadlock (not that we encourage you to actually do that). By @kpreid in [#8011](https://github.com/gfx-rs/wgpu/pull/8011). +- The limits requested for a device must now satisfy `min_subgroup_size <= max_subgroup_size`. By @andyleiserson in [#8085](https://github.com/gfx-rs/wgpu/pull/8085). #### Naga diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 7282bef2cc1..082d348a2b7 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -19,6 +19,7 @@ webgpu:api,operation,render_pass,storeOp:render_pass_store_op,color_attachment_w webgpu:api,operation,render_pass,storeOp:render_pass_store_op,color_attachment_only:* webgpu:api,operation,render_pass,storeOp:render_pass_store_op,multiple_color_attachments:* webgpu:api,operation,render_pass,storeOp:render_pass_store_op,depth_stencil_attachment_only:* +fails-if(dx12) webgpu:api,validation,capability_checks,limits,maxBindGroups:setBindGroup,* webgpu:api,validation,createBindGroup:buffer,effective_buffer_binding_size:* webgpu:api,validation,encoding,beginComputePass:* webgpu:api,validation,encoding,beginRenderPass:* diff --git a/deno_webgpu/adapter.rs b/deno_webgpu/adapter.rs index d5916fb0677..a97f7ddb3ff 100644 --- a/deno_webgpu/adapter.rs +++ b/deno_webgpu/adapter.rs @@ -125,8 +125,16 @@ impl GPUAdapter { return Err(CreateDeviceError::RequiredFeaturesNotASubset); } - let required_limits = - serde_json::from_value(serde_json::to_value(descriptor.required_limits)?)?; + // When support for compatibility mode is added, this will need to look + // at whether the adapter is "compatibility-defaulting" or + // "core-defaulting", and choose the appropriate set of defaults. + // + // Support for compatibility mode is tracked in + // https://github.com/gfx-rs/wgpu/issues/8124. + let required_limits = serde_json::from_value::(serde_json::to_value( + descriptor.required_limits, + )?)? + .or_better_values_from(&wgpu_types::Limits::default()); let trace = std::env::var_os("DENO_WEBGPU_TRACE") .map(|path| wgpu_types::Trace::Directory(std::path::PathBuf::from(path))) @@ -196,7 +204,7 @@ pub enum CreateDeviceError { #[class(inherit)] #[error(transparent)] Serde(#[from] serde_json::Error), - #[class(type)] + #[class("DOMExceptionOperationError")] #[error(transparent)] Device(#[from] wgpu_core::instance::RequestDeviceError), } diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index ea2a09eb62a..5fe93a1888f 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -16,6 +16,7 @@ extern crate alloc; use alloc::borrow::Cow; use alloc::{string::String, vec, vec::Vec}; +use core::cmp::Ordering; use core::{ fmt, hash::{Hash, Hasher}, @@ -459,6 +460,71 @@ impl fmt::Display for RequestAdapterError { } } +/// Invoke a macro for each of the limits. +/// +/// The supplied macro should take two arguments. The first is a limit name, as +/// an identifier, typically used to access a member of `struct Limits`. The +/// second is `Ordering::Less` if valid values are less than the limit (the +/// common case), or `Ordering::Greater` if valid values are more than the limit +/// (for limits like alignments, which are minima instead of maxima). +macro_rules! with_limits { + ($macro_name:ident) => { + $macro_name!(max_texture_dimension_1d, Ordering::Less); + $macro_name!(max_texture_dimension_1d, Ordering::Less); + $macro_name!(max_texture_dimension_2d, Ordering::Less); + $macro_name!(max_texture_dimension_3d, Ordering::Less); + $macro_name!(max_texture_array_layers, Ordering::Less); + $macro_name!(max_bind_groups, Ordering::Less); + $macro_name!(max_bindings_per_bind_group, Ordering::Less); + $macro_name!( + max_dynamic_uniform_buffers_per_pipeline_layout, + Ordering::Less + ); + $macro_name!( + max_dynamic_storage_buffers_per_pipeline_layout, + Ordering::Less + ); + $macro_name!(max_sampled_textures_per_shader_stage, Ordering::Less); + $macro_name!(max_samplers_per_shader_stage, Ordering::Less); + $macro_name!(max_storage_buffers_per_shader_stage, Ordering::Less); + $macro_name!(max_storage_textures_per_shader_stage, Ordering::Less); + $macro_name!(max_uniform_buffers_per_shader_stage, Ordering::Less); + $macro_name!(max_binding_array_elements_per_shader_stage, Ordering::Less); + $macro_name!(max_uniform_buffer_binding_size, Ordering::Less); + $macro_name!(max_storage_buffer_binding_size, Ordering::Less); + $macro_name!(max_vertex_buffers, Ordering::Less); + $macro_name!(max_buffer_size, Ordering::Less); + $macro_name!(max_vertex_attributes, Ordering::Less); + $macro_name!(max_vertex_buffer_array_stride, Ordering::Less); + $macro_name!(min_uniform_buffer_offset_alignment, Ordering::Greater); + $macro_name!(min_storage_buffer_offset_alignment, Ordering::Greater); + $macro_name!(max_inter_stage_shader_components, Ordering::Less); + $macro_name!(max_color_attachments, Ordering::Less); + $macro_name!(max_color_attachment_bytes_per_sample, Ordering::Less); + $macro_name!(max_compute_workgroup_storage_size, Ordering::Less); + $macro_name!(max_compute_invocations_per_workgroup, Ordering::Less); + $macro_name!(max_compute_workgroup_size_x, Ordering::Less); + $macro_name!(max_compute_workgroup_size_y, Ordering::Less); + $macro_name!(max_compute_workgroup_size_z, Ordering::Less); + $macro_name!(max_compute_workgroups_per_dimension, Ordering::Less); + + $macro_name!(min_subgroup_size, Ordering::Greater); + $macro_name!(max_subgroup_size, Ordering::Less); + + $macro_name!(max_push_constant_size, Ordering::Less); + $macro_name!(max_non_sampler_bindings, Ordering::Less); + + $macro_name!(max_task_workgroup_total_count, Ordering::Less); + $macro_name!(max_task_workgroups_per_dimension, Ordering::Less); + $macro_name!(max_mesh_multiview_count, Ordering::Less); + $macro_name!(max_mesh_output_layers, Ordering::Less); + + $macro_name!(max_blas_primitive_count, Ordering::Less); + $macro_name!(max_blas_geometry_count, Ordering::Less); + $macro_name!(max_tlas_instance_count, Ordering::Less); + }; +} + /// Represents the sets of limits an adapter/device supports. /// /// We provide three different defaults. @@ -1015,68 +1081,61 @@ impl Limits { fatal: bool, mut fail_fn: impl FnMut(&'static str, u64, u64), ) { - use core::cmp::Ordering; - - macro_rules! compare { - ($name:ident, $ordering:ident) => { - match self.$name.cmp(&allowed.$name) { - Ordering::$ordering | Ordering::Equal => (), - _ => { - fail_fn(stringify!($name), self.$name as u64, allowed.$name as u64); - if fatal { - return; - } + macro_rules! check_with_fail_fn { + ($name:ident, $ordering:expr) => { + let invalid_ord = $ordering.reverse(); + // In the case of `min_subgroup_size`, requesting a value of + // zero means "I'm not going to use subgroups", so we have to + // special case that. If any of our minimum limits could + // meaningfully go all the way to zero, that would conflict with + // this. + if self.$name != 0 && self.$name.cmp(&allowed.$name) == invalid_ord { + fail_fn(stringify!($name), self.$name as u64, allowed.$name as u64); + if fatal { + return; } } }; } - compare!(max_texture_dimension_1d, Less); - compare!(max_texture_dimension_2d, Less); - compare!(max_texture_dimension_3d, Less); - compare!(max_texture_array_layers, Less); - compare!(max_bind_groups, Less); - compare!(max_bindings_per_bind_group, Less); - compare!(max_dynamic_uniform_buffers_per_pipeline_layout, Less); - compare!(max_dynamic_storage_buffers_per_pipeline_layout, Less); - compare!(max_sampled_textures_per_shader_stage, Less); - compare!(max_samplers_per_shader_stage, Less); - compare!(max_storage_buffers_per_shader_stage, Less); - compare!(max_storage_textures_per_shader_stage, Less); - compare!(max_uniform_buffers_per_shader_stage, Less); - compare!(max_binding_array_elements_per_shader_stage, Less); - compare!(max_uniform_buffer_binding_size, Less); - compare!(max_storage_buffer_binding_size, Less); - compare!(max_vertex_buffers, Less); - compare!(max_buffer_size, Less); - compare!(max_vertex_attributes, Less); - compare!(max_vertex_buffer_array_stride, Less); - compare!(min_uniform_buffer_offset_alignment, Greater); - compare!(min_storage_buffer_offset_alignment, Greater); - compare!(max_inter_stage_shader_components, Less); - compare!(max_color_attachments, Less); - compare!(max_color_attachment_bytes_per_sample, Less); - compare!(max_compute_workgroup_storage_size, Less); - compare!(max_compute_invocations_per_workgroup, Less); - compare!(max_compute_workgroup_size_x, Less); - compare!(max_compute_workgroup_size_y, Less); - compare!(max_compute_workgroup_size_z, Less); - compare!(max_compute_workgroups_per_dimension, Less); - if self.min_subgroup_size > 0 && self.max_subgroup_size > 0 { - compare!(min_subgroup_size, Greater); - compare!(max_subgroup_size, Less); + if self.min_subgroup_size > self.max_subgroup_size { + fail_fn( + "max_subgroup_size", + self.min_subgroup_size as u64, + allowed.min_subgroup_size as u64, + ); + } + with_limits!(check_with_fail_fn); + } + + /// For each limit in `other` that is better than the value in `self`, + /// replace the value in `self` with the value from `other`. + /// + /// A request for a limit value less than the WebGPU-specified default must + /// be ignored. This function is used to clamp such requests to the default + /// value. + /// + /// This function is not for clamping requests for values beyond the + /// supported limits. For that purpose the desired function would be + /// `or_worse_values_from` (which doesn't exist, but could be added if + /// needed). + #[must_use] + pub fn or_better_values_from(mut self, other: &Self) -> Self { + macro_rules! or_better_value_from { + ($name:ident, $ordering:expr) => { + match $ordering { + // Limits that are maximum values (most of them) + Ordering::Less => self.$name = self.$name.max(other.$name), + // Limits that are minimum values + Ordering::Greater => self.$name = self.$name.min(other.$name), + Ordering::Equal => unreachable!(), + } + }; } - compare!(max_push_constant_size, Less); - compare!(max_non_sampler_bindings, Less); - compare!(max_task_workgroup_total_count, Less); - compare!(max_task_workgroups_per_dimension, Less); - compare!(max_mesh_multiview_count, Less); - compare!(max_mesh_output_layers, Less); + with_limits!(or_better_value_from); - compare!(max_blas_primitive_count, Less); - compare!(max_blas_geometry_count, Less); - compare!(max_tlas_instance_count, Less); + self } } From 8897c9e93f1e9073f32c05b7ff01ca47260c137e Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 20 Aug 2025 15:35:42 -0700 Subject: [PATCH 141/303] [deno] Enable additional vertex formats (#8095) --- deno_webgpu/render_pipeline.rs | 60 +++++++++++++++++----------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/deno_webgpu/render_pipeline.rs b/deno_webgpu/render_pipeline.rs index fcd9d786df5..1088b95ff47 100644 --- a/deno_webgpu/render_pipeline.rs +++ b/deno_webgpu/render_pipeline.rs @@ -417,56 +417,56 @@ pub(crate) struct GPUVertexAttribute { #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUVertexFormat { - // #[webidl(rename = "uint8")] - // Uint8, + #[webidl(rename = "uint8")] + Uint8, #[webidl(rename = "uint8x2")] Uint8x2, #[webidl(rename = "uint8x4")] Uint8x4, - // #[webidl(rename = "sint8")] - // Sint8, + #[webidl(rename = "sint8")] + Sint8, #[webidl(rename = "sint8x2")] Sint8x2, #[webidl(rename = "sint8x4")] Sint8x4, - // #[webidl(rename = "unorm8")] - // Unorm8, + #[webidl(rename = "unorm8")] + Unorm8, #[webidl(rename = "unorm8x2")] Unorm8x2, #[webidl(rename = "unorm8x4")] Unorm8x4, - // #[webidl(rename = "snorm8")] - // Snorm8, + #[webidl(rename = "snorm8")] + Snorm8, #[webidl(rename = "snorm8x2")] Snorm8x2, #[webidl(rename = "snorm8x4")] Snorm8x4, - // #[webidl(rename = "uint16")] - // Uint16, + #[webidl(rename = "uint16")] + Uint16, #[webidl(rename = "uint16x2")] Uint16x2, #[webidl(rename = "uint16x4")] Uint16x4, - // #[webidl(rename = "sint16")] - // Sint16, + #[webidl(rename = "sint16")] + Sint16, #[webidl(rename = "sint16x2")] Sint16x2, #[webidl(rename = "sint16x4")] Sint16x4, - // #[webidl(rename = "unorm16")] - // Unorm16, + #[webidl(rename = "unorm16")] + Unorm16, #[webidl(rename = "unorm16x2")] Unorm16x2, #[webidl(rename = "unorm16x4")] Unorm16x4, - // #[webidl(rename = "snorm16")] - // Snorm16, + #[webidl(rename = "snorm16")] + Snorm16, #[webidl(rename = "snorm16x2")] Snorm16x2, #[webidl(rename = "snorm16x4")] Snorm16x4, - // #[webidl(rename = "float16")] - // Float16, + #[webidl(rename = "float16")] + Float16, #[webidl(rename = "float16x2")] Float16x2, #[webidl(rename = "float16x4")] @@ -497,38 +497,38 @@ pub(crate) enum GPUVertexFormat { Sint32x4, #[webidl(rename = "unorm10-10-10-2")] Unorm1010102, - // #[webidl(rename = "unorm8x4-bgra")] - // Unorm8x4Bgra, + #[webidl(rename = "unorm8x4-bgra")] + Unorm8x4Bgra, } impl From for wgpu_types::VertexFormat { fn from(value: GPUVertexFormat) -> Self { match value { - //GPUVertexFormat::Uint8 => Self::Uint8, + GPUVertexFormat::Uint8 => Self::Uint8, GPUVertexFormat::Uint8x2 => Self::Uint8x2, GPUVertexFormat::Uint8x4 => Self::Uint8x4, - //GPUVertexFormat::Sint8 => Self::Sint8, + GPUVertexFormat::Sint8 => Self::Sint8, GPUVertexFormat::Sint8x2 => Self::Sint8x2, GPUVertexFormat::Sint8x4 => Self::Sint8x4, - //GPUVertexFormat::Unorm8 => Self::Unorm8, + GPUVertexFormat::Unorm8 => Self::Unorm8, GPUVertexFormat::Unorm8x2 => Self::Unorm8x2, GPUVertexFormat::Unorm8x4 => Self::Unorm8x4, - //GPUVertexFormat::Snorm8 => Self::Snorm8, + GPUVertexFormat::Snorm8 => Self::Snorm8, GPUVertexFormat::Snorm8x2 => Self::Snorm8x2, GPUVertexFormat::Snorm8x4 => Self::Snorm8x4, - //GPUVertexFormat::Uint16 => Self::Uint16, + GPUVertexFormat::Uint16 => Self::Uint16, GPUVertexFormat::Uint16x2 => Self::Uint16x2, GPUVertexFormat::Uint16x4 => Self::Uint16x4, - //GPUVertexFormat::Sint16 => Self::Sint16, + GPUVertexFormat::Sint16 => Self::Sint16, GPUVertexFormat::Sint16x2 => Self::Sint16x2, GPUVertexFormat::Sint16x4 => Self::Sint16x4, - //GPUVertexFormat::Unorm16 => Self::Unorm16, + GPUVertexFormat::Unorm16 => Self::Unorm16, GPUVertexFormat::Unorm16x2 => Self::Unorm16x2, GPUVertexFormat::Unorm16x4 => Self::Unorm16x4, - //GPUVertexFormat::Snorm16 => Self::Snorm16, + GPUVertexFormat::Snorm16 => Self::Snorm16, GPUVertexFormat::Snorm16x2 => Self::Snorm16x2, GPUVertexFormat::Snorm16x4 => Self::Snorm16x4, - //GPUVertexFormat::Float16 => Self::Float16, + GPUVertexFormat::Float16 => Self::Float16, GPUVertexFormat::Float16x2 => Self::Float16x2, GPUVertexFormat::Float16x4 => Self::Float16x4, GPUVertexFormat::Float32 => Self::Float32, @@ -544,7 +544,7 @@ impl From for wgpu_types::VertexFormat { GPUVertexFormat::Sint32x3 => Self::Sint32x3, GPUVertexFormat::Sint32x4 => Self::Sint32x4, GPUVertexFormat::Unorm1010102 => Self::Unorm10_10_10_2, - //GPUVertexFormat::Unorm8x4Bgra => Self::Unorm8x4Bgra, + GPUVertexFormat::Unorm8x4Bgra => Self::Unorm8x4Bgra, } } } From 2996c926d481c57813a06452e964fbc84e18f43d Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 20 Aug 2025 19:20:22 -0700 Subject: [PATCH 142/303] [docs] Security policy (#8006) --------- Co-authored-by: Kevin Reid --- .github/ISSUE_TEMPLATE/config.yml | 7 ++- SECURITY.md | 84 +++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 SECURITY.md diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index dc45ceff329..7cfcd54472b 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1,10 @@ blank_issues_enabled: false contact_links: - name: Question about wgpu - url: https://github.com/gfx-rs/wgpu/discussions/new + url: https://github.com/gfx-rs/wgpu/discussions/new/choose about: Any questions about how to use wgpu should go here. + - name: Security concerns + url: https://github.com/gfx-rs/wgpu/security + about: > + If you have found a possible vulnerability in wgpu, please read this + security policy for information about reporting it confidentially. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000000..1f7cf02121e --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,84 @@ +# WGPU Security Policy + +This document describes what is considered a security vulnerability in WGPU and +how vulnerabilities should be reported. + + +## Vulnerability Definition + +WebGPU introduces a different threat model than is sometimes applied to +GPU-related software. Unlike typical gaming or high-performance computing +applications, where the software accessing GPU APIs is proprietary or +obtained from a trusted developer, WebGPU makes GPU APIs available to +arbitrary web applications. In the threat model of the web, malicious +content should not be able to use the GPU APIs to access data or interfaces +outside the intended scope for interaction with web content. Therefore, `wgpu` +seeks to prevent undefined behavior and data leaks even when its API is +misused, and failures to do so may be considered vulnerabilities. (This is +also in accordance with the Rust principle of safe vs. unsafe code, since the +`wgpu` library exposes a safe API.) + +The WGPU maintainers have discretion in assigning a severity to individual +vulnerabilities. It is generally considered a high-severity vulnerability in +WGPU if JavaScript or WebAssembly code, running with privileges of ordinary web +content in a browser that is using WGPU to provide the WebGPU API to that +content, is able to: + +- Access data associated with native applications other than the user agent, + or associated with other web origins. +- Escape the applicable sandbox and run arbitrary code or call arbitrary system + APIs on the user agent host. +- Consume system resources to the point that it is difficult to recover + (e.g. by closing the web page). + +The WGPU Rust API offers some functionality, both supported and experimental, +that is not part of the WebGPU standard and is not made available in JavaScript +environments using WGPU. Associated vulnerabilities may be assigned lower +severity than vulnerabilities that apply to a WGPU-based WebGPU implementation +exposed to JavaScript. + + +## Supported Versions + +The WGPU project maintains security support for serious vulnerabilities in the +[most recent major release](https://github.com/gfx-rs/wgpu/releases). Fixes for +security vulnerabilities found shortly after the initial release of a major +version may also be provided for the previous major release. + +Mozilla provides security support for versions of WGPU used in [current +versions of Firefox](https://whattrainisitnow.com/). + +The version of WGPU that is active can be found in the Firefox repositories: + +- [release](https://github.com/mozilla-firefox/firefox/blob/release/gfx/wgpu_bindings/Cargo.toml), +- [beta](https://github.com/mozilla-firefox/firefox/blob/beta/gfx/wgpu_bindings/Cargo.toml), and +- [nightly](https://github.com/mozilla-firefox/firefox/blob/main/gfx/wgpu_bindings/Cargo.toml), + +We welcome reports of security vulnerabilities in any of these released +versions or in the latest code on the `trunk` branch. + + +## Reporting a Vulnerability + +Although not all vulnerabilities in WGPU will affect Firefox, Mozilla accepts +all vulnerability reports for WGPU and directs them appropriately. Additionally, +Mozilla serves as the CVE numbering authority for the WGPU project. + +To report a security problem with WGPU, create a bug in Mozilla's Bugzilla +instance in the +[Core :: Graphics :: WebGPU](https://bugzilla.mozilla.org/enter_bug.cgi?product=Core&component=Graphics%3A+WebGPU&groups=core-security&groups=gfx-core-security) +component. + +**IMPORTANT: For security issues, please make sure that you check the box +labelled "Many users could be harmed by this security problem".** We advise +that you check this option for anything that is potentially +security-relevant, including memory safety, crashes, race conditions, and +handling of confidential information. + +Review Mozilla's [guides on bug +reporting](https://bugzilla.mozilla.org/page.cgi?id=bug-writing.html) before +you open a bug. + +Mozilla operates a [bug bounty +program](https://www.mozilla.org/en-US/security/bug-bounty/). Some +vulnerabilities in this project may be eligible. From 4b5e38ab49eaa6efd1dead93eaa99bccb73f5016 Mon Sep 17 00:00:00 2001 From: cryvosh Date: Thu, 21 Aug 2025 04:50:32 -0400 Subject: [PATCH 143/303] [naga spv-out] Add f16 io polyfill (#7884) --- CHANGELOG.md | 1 + naga/src/back/spv/block.rs | 2 +- naga/src/back/spv/f16_polyfill.rs | 104 +++ naga/src/back/spv/mod.rs | 11 + naga/src/back/spv/writer.rs | 99 ++- naga/tests/in/wgsl/f16-native.toml | 13 + naga/tests/in/wgsl/f16-native.wgsl | 79 ++ naga/tests/in/wgsl/f16-polyfill.toml | 13 + naga/tests/in/wgsl/f16-polyfill.wgsl | 79 ++ naga/tests/naga/snapshots.rs | 21 +- naga/tests/naga/spirv_capabilities.rs | 135 ++++ naga/tests/out/spv/wgsl-f16-native.spvasm | 761 +++++++++++++++++++ naga/tests/out/spv/wgsl-f16-polyfill.spvasm | 789 ++++++++++++++++++++ wgpu-hal/src/vulkan/adapter.rs | 18 +- 14 files changed, 2106 insertions(+), 19 deletions(-) create mode 100644 naga/src/back/spv/f16_polyfill.rs create mode 100644 naga/tests/in/wgsl/f16-native.toml create mode 100644 naga/tests/in/wgsl/f16-native.wgsl create mode 100644 naga/tests/in/wgsl/f16-polyfill.toml create mode 100644 naga/tests/in/wgsl/f16-polyfill.wgsl create mode 100644 naga/tests/out/spv/wgsl-f16-native.spvasm create mode 100644 naga/tests/out/spv/wgsl-f16-polyfill.spvasm diff --git a/CHANGELOG.md b/CHANGELOG.md index ed056032c2f..11fb072dcab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -104,6 +104,7 @@ This allows using precompiled shaders without manually checking which backend's - Naga now requires that no type be larger than 1 GB. This limit may be lowered in the future; feedback on an appropriate value for the limit is welcome. By @andyleiserson in [#7950](https://github.com/gfx-rs/wgpu/pull/7950). - If the shader source contains control characters, Naga now replaces them with U+FFFD ("replacement character") in diagnostic output. By @andyleiserson in [#8049](https://github.com/gfx-rs/wgpu/pull/8049). +- Add f16 IO polyfill on Vulkan backend to enable SHADER_F16 use without requiring `storageInputOutput16`. By @cryvosh in [#7884](https://github.com/gfx-rs/wgpu/pull/7884). #### DX12 diff --git a/naga/src/back/spv/block.rs b/naga/src/back/spv/block.rs index 0cd414bfbeb..7758d86c414 100644 --- a/naga/src/back/spv/block.rs +++ b/naga/src/back/spv/block.rs @@ -237,7 +237,7 @@ impl Writer { } }; - body.push(Instruction::store(res_member.id, member_value_id, None)); + self.store_io_with_f16_polyfill(body, res_member.id, member_value_id); match res_member.built_in { Some(crate::BuiltIn::Position { .. }) diff --git a/naga/src/back/spv/f16_polyfill.rs b/naga/src/back/spv/f16_polyfill.rs new file mode 100644 index 00000000000..824490265af --- /dev/null +++ b/naga/src/back/spv/f16_polyfill.rs @@ -0,0 +1,104 @@ +/*! +This module provides functionality for polyfilling `f16` input/output variables +when the `StorageInputOutput16` capability is not available or disabled. + +It works by: + +1. Declaring `f16` I/O variables as `f32` in SPIR-V +2. Converting between `f16` and `f32` at runtime using `OpFConvert` +3. Maintaining mappings to track which variables need conversion +*/ + +use crate::back::spv::{Instruction, LocalType, NumericType, Word}; +use alloc::vec::Vec; + +/// Manages `f16` I/O polyfill state and operations. +#[derive(Default)] +pub(in crate::back::spv) struct F16IoPolyfill { + use_native: bool, + io_var_to_f32_type: crate::FastHashMap, +} + +impl F16IoPolyfill { + pub fn new(use_storage_input_output_16: bool) -> Self { + Self { + use_native: use_storage_input_output_16, + io_var_to_f32_type: crate::FastHashMap::default(), + } + } + + pub fn needs_polyfill(&self, ty_inner: &crate::TypeInner) -> bool { + use crate::{ScalarKind as Sk, TypeInner}; + + !self.use_native + && match *ty_inner { + TypeInner::Scalar(ref s) if s.kind == Sk::Float && s.width == 2 => true, + TypeInner::Vector { scalar, .. } + if scalar.kind == Sk::Float && scalar.width == 2 => + { + true + } + _ => false, + } + } + + pub fn register_io_var(&mut self, variable_id: Word, f32_type_id: Word) { + self.io_var_to_f32_type.insert(variable_id, f32_type_id); + } + + pub fn get_f32_io_type(&self, variable_id: Word) -> Option { + self.io_var_to_f32_type.get(&variable_id).copied() + } + + pub fn emit_f16_to_f32_conversion( + f16_value_id: Word, + f32_type_id: Word, + converted_id: Word, + body: &mut Vec, + ) { + body.push(Instruction::unary( + spirv::Op::FConvert, + f32_type_id, + converted_id, + f16_value_id, + )); + } + + pub fn emit_f32_to_f16_conversion( + f32_value_id: Word, + f16_type_id: Word, + converted_id: Word, + body: &mut Vec, + ) { + body.push(Instruction::unary( + spirv::Op::FConvert, + f16_type_id, + converted_id, + f32_value_id, + )); + } + + pub fn create_polyfill_type(ty_inner: &crate::TypeInner) -> Option { + use crate::{ScalarKind as Sk, TypeInner}; + + match *ty_inner { + TypeInner::Scalar(ref s) if s.kind == Sk::Float && s.width == 2 => { + Some(LocalType::Numeric(NumericType::Scalar(crate::Scalar::F32))) + } + TypeInner::Vector { size, scalar } if scalar.kind == Sk::Float && scalar.width == 2 => { + Some(LocalType::Numeric(NumericType::Vector { + size, + scalar: crate::Scalar::F32, + })) + } + _ => None, + } + } +} + +impl crate::back::spv::recyclable::Recyclable for F16IoPolyfill { + fn recycle(mut self) -> Self { + self.io_var_to_f32_type = self.io_var_to_f32_type.recycle(); + self + } +} diff --git a/naga/src/back/spv/mod.rs b/naga/src/back/spv/mod.rs index 21c00015478..ab3abe95515 100644 --- a/naga/src/back/spv/mod.rs +++ b/naga/src/back/spv/mod.rs @@ -5,6 +5,7 @@ Backend for [SPIR-V][spv] (Standard Portable Intermediate Representation). */ mod block; +mod f16_polyfill; mod helpers; mod image; mod index; @@ -745,6 +746,7 @@ pub struct Writer { bounds_check_policies: BoundsCheckPolicies, zero_initialize_workgroup_memory: ZeroInitializeWorkgroupMemoryMode, force_loop_bounding: bool, + use_storage_input_output_16: bool, void_type: Word, //TODO: convert most of these into vectors, addressable by handle indices lookup_type: crate::FastHashMap, @@ -771,6 +773,10 @@ pub struct Writer { ray_get_committed_intersection_function: Option, ray_get_candidate_intersection_function: Option, + + /// F16 I/O polyfill manager for handling `f16` input/output variables + /// when `StorageInputOutput16` capability is not available. + io_f16_polyfills: f16_polyfill::F16IoPolyfill, } bitflags::bitflags! { @@ -853,6 +859,10 @@ pub struct Options<'a> { /// to think the number of iterations is bounded. pub force_loop_bounding: bool, + /// Whether to use the `StorageInputOutput16` capability for `f16` shader I/O. + /// When false, `f16` I/O is polyfilled using `f32` types with conversions. + pub use_storage_input_output_16: bool, + pub debug_info: Option>, } @@ -872,6 +882,7 @@ impl Default for Options<'_> { bounds_check_policies: BoundsCheckPolicies::default(), zero_initialize_workgroup_memory: ZeroInitializeWorkgroupMemoryMode::Polyfill, force_loop_bounding: true, + use_storage_input_output_16: true, debug_info: None, } } diff --git a/naga/src/back/spv/writer.rs b/naga/src/back/spv/writer.rs index 0688eb6c975..48d13f03c25 100644 --- a/naga/src/back/spv/writer.rs +++ b/naga/src/back/spv/writer.rs @@ -78,6 +78,7 @@ impl Writer { bounds_check_policies: options.bounds_check_policies, zero_initialize_workgroup_memory: options.zero_initialize_workgroup_memory, force_loop_bounding: options.force_loop_bounding, + use_storage_input_output_16: options.use_storage_input_output_16, void_type, lookup_type: crate::FastHashMap::default(), lookup_function: crate::FastHashMap::default(), @@ -92,6 +93,9 @@ impl Writer { temp_list: Vec::new(), ray_get_committed_intersection_function: None, ray_get_candidate_intersection_function: None, + io_f16_polyfills: super::f16_polyfill::F16IoPolyfill::new( + options.use_storage_input_output_16, + ), }) } @@ -125,6 +129,7 @@ impl Writer { bounds_check_policies: self.bounds_check_policies, zero_initialize_workgroup_memory: self.zero_initialize_workgroup_memory, force_loop_bounding: self.force_loop_bounding, + use_storage_input_output_16: self.use_storage_input_output_16, capabilities_available: take(&mut self.capabilities_available), binding_map: take(&mut self.binding_map), @@ -151,6 +156,7 @@ impl Writer { temp_list: take(&mut self.temp_list).recycle(), ray_get_candidate_intersection_function: None, ray_get_committed_intersection_function: None, + io_f16_polyfills: take(&mut self.io_f16_polyfills).recycle(), }; *self = fresh; @@ -726,10 +732,11 @@ impl Writer { binding, )?; iface.varying_ids.push(varying_id); - let id = self.id_gen.next(); - prelude - .body - .push(Instruction::load(argument_type_id, id, varying_id, None)); + let id = self.load_io_with_f16_polyfill( + &mut prelude.body, + varying_id, + argument_type_id, + ); if binding == &crate::Binding::BuiltIn(crate::BuiltIn::LocalInvocationId) { local_invocation_id = Some(id); @@ -754,10 +761,8 @@ impl Writer { binding, )?; iface.varying_ids.push(varying_id); - let id = self.id_gen.next(); - prelude - .body - .push(Instruction::load(type_id, id, varying_id, None)); + let id = + self.load_io_with_f16_polyfill(&mut prelude.body, varying_id, type_id); constituent_ids.push(id); if binding == &crate::Binding::BuiltIn(crate::BuiltIn::LocalInvocationId) { @@ -1220,8 +1225,10 @@ impl Writer { .insert(spirv::Capability::StorageBuffer16BitAccess); self.capabilities_used .insert(spirv::Capability::UniformAndStorageBuffer16BitAccess); - self.capabilities_used - .insert(spirv::Capability::StorageInputOutput16); + if self.use_storage_input_output_16 { + self.capabilities_used + .insert(spirv::Capability::StorageInputOutput16); + } } Instruction::type_float(id, bits) } @@ -1905,8 +1912,26 @@ impl Writer { ty: Handle, binding: &crate::Binding, ) -> Result { + use crate::TypeInner; + let id = self.id_gen.next(); - let pointer_type_id = self.get_handle_pointer_type_id(ty, class); + let ty_inner = &ir_module.types[ty].inner; + let needs_polyfill = self.needs_f16_polyfill(ty_inner); + + let pointer_type_id = if needs_polyfill { + let f32_value_local = + super::f16_polyfill::F16IoPolyfill::create_polyfill_type(ty_inner) + .expect("needs_polyfill returned true but create_polyfill_type returned None"); + + let f32_type_id = self.get_localtype_id(f32_value_local); + let ptr_id = self.get_pointer_type_id(f32_type_id, class); + self.io_f16_polyfills.register_io_var(id, f32_type_id); + + ptr_id + } else { + self.get_handle_pointer_type_id(ty, class) + }; + Instruction::variable(pointer_type_id, id, class, None) .to_words(&mut self.logical_layout.declarations); @@ -2089,8 +2114,9 @@ impl Writer { // > shader, must be decorated Flat if class == spirv::StorageClass::Input && stage == crate::ShaderStage::Fragment { let is_flat = match ir_module.types[ty].inner { - crate::TypeInner::Scalar(scalar) - | crate::TypeInner::Vector { scalar, .. } => match scalar.kind { + TypeInner::Scalar(scalar) | TypeInner::Vector { scalar, .. } => match scalar + .kind + { Sk::Uint | Sk::Sint | Sk::Bool => true, Sk::Float => false, Sk::AbstractInt | Sk::AbstractFloat => { @@ -2112,6 +2138,49 @@ impl Writer { Ok(id) } + /// Load an IO variable, converting from `f32` to `f16` if polyfill is active. + /// Returns the id of the loaded value matching `target_type_id`. + pub(super) fn load_io_with_f16_polyfill( + &mut self, + body: &mut Vec, + varying_id: Word, + target_type_id: Word, + ) -> Word { + let tmp = self.id_gen.next(); + if let Some(f32_ty) = self.io_f16_polyfills.get_f32_io_type(varying_id) { + body.push(Instruction::load(f32_ty, tmp, varying_id, None)); + let converted = self.id_gen.next(); + super::f16_polyfill::F16IoPolyfill::emit_f32_to_f16_conversion( + tmp, + target_type_id, + converted, + body, + ); + converted + } else { + body.push(Instruction::load(target_type_id, tmp, varying_id, None)); + tmp + } + } + + /// Store an IO variable, converting from `f16` to `f32` if polyfill is active. + pub(super) fn store_io_with_f16_polyfill( + &mut self, + body: &mut Vec, + varying_id: Word, + value_id: Word, + ) { + if let Some(f32_ty) = self.io_f16_polyfills.get_f32_io_type(varying_id) { + let converted = self.id_gen.next(); + super::f16_polyfill::F16IoPolyfill::emit_f16_to_f32_conversion( + value_id, f32_ty, converted, body, + ); + body.push(Instruction::store(varying_id, converted, None)); + } else { + body.push(Instruction::store(varying_id, value_id, None)); + } + } + fn write_global_variable( &mut self, ir_module: &crate::Module, @@ -2585,6 +2654,10 @@ impl Writer { self.decorate(id, spirv::Decoration::NonUniform, &[]); Ok(()) } + + pub(super) fn needs_f16_polyfill(&self, ty_inner: &crate::TypeInner) -> bool { + self.io_f16_polyfills.needs_polyfill(ty_inner) + } } #[test] diff --git a/naga/tests/in/wgsl/f16-native.toml b/naga/tests/in/wgsl/f16-native.toml new file mode 100644 index 00000000000..529d34f80da --- /dev/null +++ b/naga/tests/in/wgsl/f16-native.toml @@ -0,0 +1,13 @@ +targets = "SPIRV" +god_mode = true + +[spv] +debug = true +version = [1, 1] +use_storage_input_output_16 = true +capabilities = ["Float16"] + +[bounds_check_policies] +index = "ReadZeroSkipWrite" +buffer = "ReadZeroSkipWrite" +image = "ReadZeroSkipWrite" diff --git a/naga/tests/in/wgsl/f16-native.wgsl b/naga/tests/in/wgsl/f16-native.wgsl new file mode 100644 index 00000000000..fda726df765 --- /dev/null +++ b/naga/tests/in/wgsl/f16-native.wgsl @@ -0,0 +1,79 @@ +enable f16; + +@fragment +fn test_direct( + @location(0) scalar_f16: f16, + @location(1) scalar_f32: f32, + @location(2) vec2_f16: vec2, + @location(3) vec2_f32: vec2, + @location(4) vec3_f16: vec3, + @location(5) vec3_f32: vec3, + @location(6) vec4_f16: vec4, + @location(7) vec4_f32: vec4, +) -> F16IO { + var output: F16IO; + output.scalar_f16 = scalar_f16 + 1.0h; + output.scalar_f32 = scalar_f32 + 1.0; + output.vec2_f16 = vec2_f16 + vec2(1.0h); + output.vec2_f32 = vec2_f32 + vec2(1.0); + output.vec3_f16 = vec3_f16 + vec3(1.0h); + output.vec3_f32 = vec3_f32 + vec3(1.0); + output.vec4_f16 = vec4_f16 + vec4(1.0h); + output.vec4_f32 = vec4_f32 + vec4(1.0); + return output; +} + +struct F16IO { + @location(0) scalar_f16: f16, + @location(1) scalar_f32: f32, + @location(2) vec2_f16: vec2, + @location(3) vec2_f32: vec2, + @location(4) vec3_f16: vec3, + @location(5) vec3_f32: vec3, + @location(6) vec4_f16: vec4, + @location(7) vec4_f32: vec4, +} + +@fragment +fn test_struct(input: F16IO) -> F16IO { + var output: F16IO; + output.scalar_f16 = input.scalar_f16 + 1.0h; + output.scalar_f32 = input.scalar_f32 + 1.0; + output.vec2_f16 = input.vec2_f16 + vec2(1.0h); + output.vec2_f32 = input.vec2_f32 + vec2(1.0); + output.vec3_f16 = input.vec3_f16 + vec3(1.0h); + output.vec3_f32 = input.vec3_f32 + vec3(1.0); + output.vec4_f16 = input.vec4_f16 + vec4(1.0h); + output.vec4_f32 = input.vec4_f32 + vec4(1.0); + return output; +} + +@fragment +fn test_copy_input(input_original: F16IO) -> F16IO { + var input = input_original; + var output: F16IO; + output.scalar_f16 = input.scalar_f16 + 1.0h; + output.scalar_f32 = input.scalar_f32 + 1.0; + output.vec2_f16 = input.vec2_f16 + vec2(1.0h); + output.vec2_f32 = input.vec2_f32 + vec2(1.0); + output.vec3_f16 = input.vec3_f16 + vec3(1.0h); + output.vec3_f32 = input.vec3_f32 + vec3(1.0); + output.vec4_f16 = input.vec4_f16 + vec4(1.0h); + output.vec4_f32 = input.vec4_f32 + vec4(1.0); + return output; +} + +@fragment +fn test_return_partial(input_original: F16IO) -> @location(0) f16 { + var input = input_original; + input.scalar_f16 = 0.0h; + return input.scalar_f16; +} + +@fragment +fn test_component_access(input: F16IO) -> F16IO { + var output: F16IO; + output.vec2_f16.x = input.vec2_f16.y; + output.vec2_f16.y = input.vec2_f16.x; + return output; +} \ No newline at end of file diff --git a/naga/tests/in/wgsl/f16-polyfill.toml b/naga/tests/in/wgsl/f16-polyfill.toml new file mode 100644 index 00000000000..96160063e05 --- /dev/null +++ b/naga/tests/in/wgsl/f16-polyfill.toml @@ -0,0 +1,13 @@ +targets = "SPIRV" +god_mode = true + +[spv] +debug = true +version = [1, 1] +use_storage_input_output_16 = false +capabilities = ["Float16"] + +[bounds_check_policies] +index = "ReadZeroSkipWrite" +buffer = "ReadZeroSkipWrite" +image = "ReadZeroSkipWrite" diff --git a/naga/tests/in/wgsl/f16-polyfill.wgsl b/naga/tests/in/wgsl/f16-polyfill.wgsl new file mode 100644 index 00000000000..fda726df765 --- /dev/null +++ b/naga/tests/in/wgsl/f16-polyfill.wgsl @@ -0,0 +1,79 @@ +enable f16; + +@fragment +fn test_direct( + @location(0) scalar_f16: f16, + @location(1) scalar_f32: f32, + @location(2) vec2_f16: vec2, + @location(3) vec2_f32: vec2, + @location(4) vec3_f16: vec3, + @location(5) vec3_f32: vec3, + @location(6) vec4_f16: vec4, + @location(7) vec4_f32: vec4, +) -> F16IO { + var output: F16IO; + output.scalar_f16 = scalar_f16 + 1.0h; + output.scalar_f32 = scalar_f32 + 1.0; + output.vec2_f16 = vec2_f16 + vec2(1.0h); + output.vec2_f32 = vec2_f32 + vec2(1.0); + output.vec3_f16 = vec3_f16 + vec3(1.0h); + output.vec3_f32 = vec3_f32 + vec3(1.0); + output.vec4_f16 = vec4_f16 + vec4(1.0h); + output.vec4_f32 = vec4_f32 + vec4(1.0); + return output; +} + +struct F16IO { + @location(0) scalar_f16: f16, + @location(1) scalar_f32: f32, + @location(2) vec2_f16: vec2, + @location(3) vec2_f32: vec2, + @location(4) vec3_f16: vec3, + @location(5) vec3_f32: vec3, + @location(6) vec4_f16: vec4, + @location(7) vec4_f32: vec4, +} + +@fragment +fn test_struct(input: F16IO) -> F16IO { + var output: F16IO; + output.scalar_f16 = input.scalar_f16 + 1.0h; + output.scalar_f32 = input.scalar_f32 + 1.0; + output.vec2_f16 = input.vec2_f16 + vec2(1.0h); + output.vec2_f32 = input.vec2_f32 + vec2(1.0); + output.vec3_f16 = input.vec3_f16 + vec3(1.0h); + output.vec3_f32 = input.vec3_f32 + vec3(1.0); + output.vec4_f16 = input.vec4_f16 + vec4(1.0h); + output.vec4_f32 = input.vec4_f32 + vec4(1.0); + return output; +} + +@fragment +fn test_copy_input(input_original: F16IO) -> F16IO { + var input = input_original; + var output: F16IO; + output.scalar_f16 = input.scalar_f16 + 1.0h; + output.scalar_f32 = input.scalar_f32 + 1.0; + output.vec2_f16 = input.vec2_f16 + vec2(1.0h); + output.vec2_f32 = input.vec2_f32 + vec2(1.0); + output.vec3_f16 = input.vec3_f16 + vec3(1.0h); + output.vec3_f32 = input.vec3_f32 + vec3(1.0); + output.vec4_f16 = input.vec4_f16 + vec4(1.0h); + output.vec4_f32 = input.vec4_f32 + vec4(1.0); + return output; +} + +@fragment +fn test_return_partial(input_original: F16IO) -> @location(0) f16 { + var input = input_original; + input.scalar_f16 = 0.0h; + return input.scalar_f16; +} + +@fragment +fn test_component_access(input: F16IO) -> F16IO { + var output: F16IO; + output.vec2_f16.x = input.vec2_f16.y; + output.vec2_f16.y = input.vec2_f16.x; + return output; +} \ No newline at end of file diff --git a/naga/tests/naga/snapshots.rs b/naga/tests/naga/snapshots.rs index e2288eee918..f08ca3b0f65 100644 --- a/naga/tests/naga/snapshots.rs +++ b/naga/tests/naga/snapshots.rs @@ -91,7 +91,7 @@ struct SpirvInParameters { adjust_coordinate_space: bool, } -#[derive(Default, serde::Deserialize)] +#[derive(serde::Deserialize)] #[serde(default)] struct SpirvOutParameters { version: SpvOutVersion, @@ -101,11 +101,29 @@ struct SpirvOutParameters { force_point_size: bool, clamp_frag_depth: bool, separate_entry_points: bool, + use_storage_input_output_16: bool, #[cfg(all(feature = "deserialize", spv_out))] #[serde(deserialize_with = "deserialize_binding_map")] binding_map: naga::back::spv::BindingMap, } +impl Default for SpirvOutParameters { + fn default() -> Self { + Self { + version: SpvOutVersion::default(), + capabilities: naga::FastHashSet::default(), + debug: false, + adjust_coordinate_space: false, + force_point_size: false, + clamp_frag_depth: false, + separate_entry_points: false, + use_storage_input_output_16: true, + #[cfg(all(feature = "deserialize", spv_out))] + binding_map: naga::back::spv::BindingMap::default(), + } + } +} + #[derive(Default, serde::Deserialize)] #[serde(default)] struct WgslOutParameters { @@ -617,6 +635,7 @@ fn write_output_spv( binding_map: params.binding_map.clone(), zero_initialize_workgroup_memory: spv::ZeroInitializeWorkgroupMemoryMode::Polyfill, force_loop_bounding: true, + use_storage_input_output_16: params.use_storage_input_output_16, debug_info, }; diff --git a/naga/tests/naga/spirv_capabilities.rs b/naga/tests/naga/spirv_capabilities.rs index 2d46e37f72d..6d0e8153b81 100644 --- a/naga/tests/naga/spirv_capabilities.rs +++ b/naga/tests/naga/spirv_capabilities.rs @@ -6,6 +6,9 @@ Test SPIR-V backend capability checks. use spirv::Capability as Ca; +#[cfg(spv_out)] +use rspirv::binary::Disassemble; + fn capabilities_used(source: &str) -> naga::FastIndexSet { use naga::back::spv; use naga::valid; @@ -213,3 +216,135 @@ fn int64() { fn float16() { require(&[Ca::Float16], "enable f16; fn f(x: f16) { }"); } + +#[test] +fn f16_io_capabilities() { + let source = r#" + enable f16; + + struct VertexOutput { + @location(0) color: vec3, + } + + @fragment + fn main(input: VertexOutput) -> @location(0) vec4 { + return vec4(input.color, f16(1.0)); + } + "#; + + use naga::back::spv; + use naga::valid; + + let module = naga::front::wgsl::parse_str(source).unwrap(); + let info = valid::Validator::new(valid::ValidationFlags::all(), valid::Capabilities::all()) + .validate(&module) + .unwrap(); + + // Test native path: use_storage_input_output_16 = true + let options_native = spv::Options { + use_storage_input_output_16: true, + ..Default::default() + }; + + let mut words_native = vec![]; + let mut writer_native = spv::Writer::new(&options_native).unwrap(); + writer_native + .write(&module, &info, None, &None, &mut words_native) + .unwrap(); + let caps_native = writer_native.get_capabilities_used(); + + // Should include `StorageInputOutput16` for native `f16` I/O + assert!(caps_native.contains(&Ca::StorageInputOutput16)); + + // Test polyfill path: use_storage_input_output_16 = false + let options_polyfill = spv::Options { + use_storage_input_output_16: false, + ..Default::default() + }; + + let mut words_polyfill = vec![]; + let mut writer_polyfill = spv::Writer::new(&options_polyfill).unwrap(); + writer_polyfill + .write(&module, &info, None, &None, &mut words_polyfill) + .unwrap(); + let caps_polyfill = writer_polyfill.get_capabilities_used(); + + // Should not include `StorageInputOutput16` when polyfilled + assert!(!caps_polyfill.contains(&Ca::StorageInputOutput16)); + + // But should still include the basic `f16` capabilities + assert!(caps_polyfill.contains(&Ca::Float16)); +} + +#[cfg(spv_out)] +#[test] +fn f16_io_polyfill_codegen() { + let source = r#" + enable f16; + + struct F16IO { + @location(0) scalar_f16: f16, + @location(1) scalar_f32: f32, + @location(2) vec2_f16: vec2, + @location(3) vec2_f32: vec2, + } + + @fragment + fn main(input: F16IO) -> F16IO { + var output = input; + output.scalar_f16 = input.scalar_f16 + 1.0h; + output.vec2_f16.x = input.vec2_f16.y; + return output; + } + "#; + + use naga::{back::spv, valid}; + + let module = naga::front::wgsl::parse_str(source).unwrap(); + let info = valid::Validator::new(valid::ValidationFlags::all(), valid::Capabilities::all()) + .validate(&module) + .unwrap(); + + // Test Native Path + let options_native = spv::Options { + use_storage_input_output_16: true, + ..Default::default() + }; + let mut words_native = vec![]; + let mut writer_native = spv::Writer::new(&options_native).unwrap(); + writer_native + .write(&module, &info, None, &None, &mut words_native) + .unwrap(); + let caps_native = writer_native.get_capabilities_used(); + let dis_native = rspirv::dr::load_words(words_native).unwrap().disassemble(); + + // Native path must request the capability and must NOT have conversions. + assert!(caps_native.contains(&Ca::StorageInputOutput16)); + assert!(!dis_native.contains("OpFConvert")); + + // Test Polyfill Path + let options_polyfill = spv::Options { + use_storage_input_output_16: false, + ..Default::default() + }; + let mut words_polyfill = vec![]; + let mut writer_polyfill = spv::Writer::new(&options_polyfill).unwrap(); + writer_polyfill + .write(&module, &info, None, &None, &mut words_polyfill) + .unwrap(); + let caps_polyfill = writer_polyfill.get_capabilities_used(); + let dis_polyfill = rspirv::dr::load_words(words_polyfill) + .unwrap() + .disassemble(); + + // Polyfill path should request the capability but not have conversions. + assert!(!caps_polyfill.contains(&Ca::StorageInputOutput16)); + assert!(dis_polyfill.contains("OpFConvert")); + + // Should have 2 input conversions, and 2 output conversions + let fconvert_count = dis_polyfill.matches("OpFConvert").count(); + assert_eq!( + fconvert_count, 4, + "Expected 4 OpFConvert instructions for polyfilled I/O" + ); +} diff --git a/naga/tests/out/spv/wgsl-f16-native.spvasm b/naga/tests/out/spv/wgsl-f16-native.spvasm new file mode 100644 index 00000000000..43210270933 --- /dev/null +++ b/naga/tests/out/spv/wgsl-f16-native.spvasm @@ -0,0 +1,761 @@ +; SPIR-V +; Version: 1.1 +; Generator: rspirv +; Bound: 318 +OpCapability Shader +OpCapability Float16 +OpCapability StorageBuffer16BitAccess +OpCapability UniformAndStorageBuffer16BitAccess +OpCapability StorageInputOutput16 +OpExtension "SPV_KHR_16bit_storage" +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint Fragment %54 "test_direct" %14 %17 %20 %23 %26 %29 %32 %35 %38 %40 %42 %44 %46 %48 %50 %52 +OpEntryPoint Fragment %136 "test_struct" %112 %114 %116 %118 %120 %122 %124 %126 %128 %129 %130 %131 %132 %133 %134 %135 +OpEntryPoint Fragment %199 "test_copy_input" %175 %177 %179 %181 %183 %185 %187 %189 %191 %192 %193 %194 %195 %196 %197 %198 +OpEntryPoint Fragment %265 "test_return_partial" %248 %250 %252 %254 %256 %258 %260 %262 %264 +OpEntryPoint Fragment %299 "test_component_access" %275 %277 %279 %281 %283 %285 %287 %289 %291 %292 %293 %294 %295 %296 %297 %298 +OpExecutionMode %54 OriginUpperLeft +OpExecutionMode %136 OriginUpperLeft +OpExecutionMode %199 OriginUpperLeft +OpExecutionMode %265 OriginUpperLeft +OpExecutionMode %299 OriginUpperLeft +%3 = OpString "f16-native.wgsl" +OpSource Unknown 0 %3 "enable f16; + +@fragment +fn test_direct( + @location(0) scalar_f16: f16, + @location(1) scalar_f32: f32, + @location(2) vec2_f16: vec2, + @location(3) vec2_f32: vec2, + @location(4) vec3_f16: vec3, + @location(5) vec3_f32: vec3, + @location(6) vec4_f16: vec4, + @location(7) vec4_f32: vec4, +) -> F16IO { + var output: F16IO; + output.scalar_f16 = scalar_f16 + 1.0h; + output.scalar_f32 = scalar_f32 + 1.0; + output.vec2_f16 = vec2_f16 + vec2(1.0h); + output.vec2_f32 = vec2_f32 + vec2(1.0); + output.vec3_f16 = vec3_f16 + vec3(1.0h); + output.vec3_f32 = vec3_f32 + vec3(1.0); + output.vec4_f16 = vec4_f16 + vec4(1.0h); + output.vec4_f32 = vec4_f32 + vec4(1.0); + return output; +} + +struct F16IO { + @location(0) scalar_f16: f16, + @location(1) scalar_f32: f32, + @location(2) vec2_f16: vec2, + @location(3) vec2_f32: vec2, + @location(4) vec3_f16: vec3, + @location(5) vec3_f32: vec3, + @location(6) vec4_f16: vec4, + @location(7) vec4_f32: vec4, +} + +@fragment +fn test_struct(input: F16IO) -> F16IO { + var output: F16IO; + output.scalar_f16 = input.scalar_f16 + 1.0h; + output.scalar_f32 = input.scalar_f32 + 1.0; + output.vec2_f16 = input.vec2_f16 + vec2(1.0h); + output.vec2_f32 = input.vec2_f32 + vec2(1.0); + output.vec3_f16 = input.vec3_f16 + vec3(1.0h); + output.vec3_f32 = input.vec3_f32 + vec3(1.0); + output.vec4_f16 = input.vec4_f16 + vec4(1.0h); + output.vec4_f32 = input.vec4_f32 + vec4(1.0); + return output; +} + +@fragment +fn test_copy_input(input_original: F16IO) -> F16IO { + var input = input_original; + var output: F16IO; + output.scalar_f16 = input.scalar_f16 + 1.0h; + output.scalar_f32 = input.scalar_f32 + 1.0; + output.vec2_f16 = input.vec2_f16 + vec2(1.0h); + output.vec2_f32 = input.vec2_f32 + vec2(1.0); + output.vec3_f16 = input.vec3_f16 + vec3(1.0h); + output.vec3_f32 = input.vec3_f32 + vec3(1.0); + output.vec4_f16 = input.vec4_f16 + vec4(1.0h); + output.vec4_f32 = input.vec4_f32 + vec4(1.0); + return output; +} + +@fragment +fn test_return_partial(input_original: F16IO) -> @location(0) f16 { + var input = input_original; + input.scalar_f16 = 0.0h; + return input.scalar_f16; +} + +@fragment +fn test_component_access(input: F16IO) -> F16IO { + var output: F16IO; + output.vec2_f16.x = input.vec2_f16.y; + output.vec2_f16.y = input.vec2_f16.x; + return output; +}" +OpMemberName %12 0 "scalar_f16" +OpMemberName %12 1 "scalar_f32" +OpMemberName %12 2 "vec2_f16" +OpMemberName %12 3 "vec2_f32" +OpMemberName %12 4 "vec3_f16" +OpMemberName %12 5 "vec3_f32" +OpMemberName %12 6 "vec4_f16" +OpMemberName %12 7 "vec4_f32" +OpName %12 "F16IO" +OpName %14 "scalar_f16" +OpName %17 "scalar_f32" +OpName %20 "vec2_f16" +OpName %23 "vec2_f32" +OpName %26 "vec3_f16" +OpName %29 "vec3_f32" +OpName %32 "vec4_f16" +OpName %35 "vec4_f32" +OpName %38 "scalar_f16" +OpName %40 "scalar_f32" +OpName %42 "vec2_f16" +OpName %44 "vec2_f32" +OpName %46 "vec3_f16" +OpName %48 "vec3_f32" +OpName %50 "vec4_f16" +OpName %52 "vec4_f32" +OpName %54 "test_direct" +OpName %64 "output" +OpName %112 "scalar_f16" +OpName %114 "scalar_f32" +OpName %116 "vec2_f16" +OpName %118 "vec2_f32" +OpName %120 "vec3_f16" +OpName %122 "vec3_f32" +OpName %124 "vec4_f16" +OpName %126 "vec4_f32" +OpName %128 "scalar_f16" +OpName %129 "scalar_f32" +OpName %130 "vec2_f16" +OpName %131 "vec2_f32" +OpName %132 "vec3_f16" +OpName %133 "vec3_f32" +OpName %134 "vec4_f16" +OpName %135 "vec4_f32" +OpName %136 "test_struct" +OpName %137 "output" +OpName %175 "scalar_f16" +OpName %177 "scalar_f32" +OpName %179 "vec2_f16" +OpName %181 "vec2_f32" +OpName %183 "vec3_f16" +OpName %185 "vec3_f32" +OpName %187 "vec4_f16" +OpName %189 "vec4_f32" +OpName %191 "scalar_f16" +OpName %192 "scalar_f32" +OpName %193 "vec2_f16" +OpName %194 "vec2_f32" +OpName %195 "vec3_f16" +OpName %196 "vec3_f32" +OpName %197 "vec4_f16" +OpName %198 "vec4_f32" +OpName %199 "test_copy_input" +OpName %200 "input" +OpName %202 "output" +OpName %248 "scalar_f16" +OpName %250 "scalar_f32" +OpName %252 "vec2_f16" +OpName %254 "vec2_f32" +OpName %256 "vec3_f16" +OpName %258 "vec3_f32" +OpName %260 "vec4_f16" +OpName %262 "vec4_f32" +OpName %265 "test_return_partial" +OpName %267 "input" +OpName %275 "scalar_f16" +OpName %277 "scalar_f32" +OpName %279 "vec2_f16" +OpName %281 "vec2_f32" +OpName %283 "vec3_f16" +OpName %285 "vec3_f32" +OpName %287 "vec4_f16" +OpName %289 "vec4_f32" +OpName %291 "scalar_f16" +OpName %292 "scalar_f32" +OpName %293 "vec2_f16" +OpName %294 "vec2_f32" +OpName %295 "vec3_f16" +OpName %296 "vec3_f32" +OpName %297 "vec4_f16" +OpName %298 "vec4_f32" +OpName %299 "test_component_access" +OpName %300 "output" +OpMemberDecorate %12 0 Offset 0 +OpMemberDecorate %12 1 Offset 4 +OpMemberDecorate %12 2 Offset 8 +OpMemberDecorate %12 3 Offset 16 +OpMemberDecorate %12 4 Offset 24 +OpMemberDecorate %12 5 Offset 32 +OpMemberDecorate %12 6 Offset 48 +OpMemberDecorate %12 7 Offset 64 +OpDecorate %14 Location 0 +OpDecorate %17 Location 1 +OpDecorate %20 Location 2 +OpDecorate %23 Location 3 +OpDecorate %26 Location 4 +OpDecorate %29 Location 5 +OpDecorate %32 Location 6 +OpDecorate %35 Location 7 +OpDecorate %38 Location 0 +OpDecorate %40 Location 1 +OpDecorate %42 Location 2 +OpDecorate %44 Location 3 +OpDecorate %46 Location 4 +OpDecorate %48 Location 5 +OpDecorate %50 Location 6 +OpDecorate %52 Location 7 +OpDecorate %112 Location 0 +OpDecorate %114 Location 1 +OpDecorate %116 Location 2 +OpDecorate %118 Location 3 +OpDecorate %120 Location 4 +OpDecorate %122 Location 5 +OpDecorate %124 Location 6 +OpDecorate %126 Location 7 +OpDecorate %128 Location 0 +OpDecorate %129 Location 1 +OpDecorate %130 Location 2 +OpDecorate %131 Location 3 +OpDecorate %132 Location 4 +OpDecorate %133 Location 5 +OpDecorate %134 Location 6 +OpDecorate %135 Location 7 +OpDecorate %175 Location 0 +OpDecorate %177 Location 1 +OpDecorate %179 Location 2 +OpDecorate %181 Location 3 +OpDecorate %183 Location 4 +OpDecorate %185 Location 5 +OpDecorate %187 Location 6 +OpDecorate %189 Location 7 +OpDecorate %191 Location 0 +OpDecorate %192 Location 1 +OpDecorate %193 Location 2 +OpDecorate %194 Location 3 +OpDecorate %195 Location 4 +OpDecorate %196 Location 5 +OpDecorate %197 Location 6 +OpDecorate %198 Location 7 +OpDecorate %248 Location 0 +OpDecorate %250 Location 1 +OpDecorate %252 Location 2 +OpDecorate %254 Location 3 +OpDecorate %256 Location 4 +OpDecorate %258 Location 5 +OpDecorate %260 Location 6 +OpDecorate %262 Location 7 +OpDecorate %264 Location 0 +OpDecorate %275 Location 0 +OpDecorate %277 Location 1 +OpDecorate %279 Location 2 +OpDecorate %281 Location 3 +OpDecorate %283 Location 4 +OpDecorate %285 Location 5 +OpDecorate %287 Location 6 +OpDecorate %289 Location 7 +OpDecorate %291 Location 0 +OpDecorate %292 Location 1 +OpDecorate %293 Location 2 +OpDecorate %294 Location 3 +OpDecorate %295 Location 4 +OpDecorate %296 Location 5 +OpDecorate %297 Location 6 +OpDecorate %298 Location 7 +%2 = OpTypeVoid +%4 = OpTypeFloat 16 +%5 = OpTypeFloat 32 +%6 = OpTypeVector %4 2 +%7 = OpTypeVector %5 2 +%8 = OpTypeVector %4 3 +%9 = OpTypeVector %5 3 +%10 = OpTypeVector %4 4 +%11 = OpTypeVector %5 4 +%12 = OpTypeStruct %4 %5 %6 %7 %8 %9 %10 %11 +%15 = OpTypePointer Input %4 +%14 = OpVariable %15 Input +%18 = OpTypePointer Input %5 +%17 = OpVariable %18 Input +%21 = OpTypePointer Input %6 +%20 = OpVariable %21 Input +%24 = OpTypePointer Input %7 +%23 = OpVariable %24 Input +%27 = OpTypePointer Input %8 +%26 = OpVariable %27 Input +%30 = OpTypePointer Input %9 +%29 = OpVariable %30 Input +%33 = OpTypePointer Input %10 +%32 = OpVariable %33 Input +%36 = OpTypePointer Input %11 +%35 = OpVariable %36 Input +%39 = OpTypePointer Output %4 +%38 = OpVariable %39 Output +%41 = OpTypePointer Output %5 +%40 = OpVariable %41 Output +%43 = OpTypePointer Output %6 +%42 = OpVariable %43 Output +%45 = OpTypePointer Output %7 +%44 = OpVariable %45 Output +%47 = OpTypePointer Output %8 +%46 = OpVariable %47 Output +%49 = OpTypePointer Output %9 +%48 = OpVariable %49 Output +%51 = OpTypePointer Output %10 +%50 = OpVariable %51 Output +%53 = OpTypePointer Output %11 +%52 = OpVariable %53 Output +%55 = OpTypeFunction %2 +%56 = OpConstant %4 0.000000000000000000000000000000000000000021524 +%57 = OpConstant %5 1 +%58 = OpConstantComposite %6 %56 %56 +%59 = OpConstantComposite %7 %57 %57 +%60 = OpConstantComposite %8 %56 %56 %56 +%61 = OpConstantComposite %9 %57 %57 %57 +%62 = OpConstantComposite %10 %56 %56 %56 %56 +%63 = OpConstantComposite %11 %57 %57 %57 %57 +%65 = OpTypePointer Function %12 +%66 = OpConstantNull %12 +%68 = OpTypePointer Function %4 +%71 = OpTypeInt 32 0 +%70 = OpConstant %71 0 +%73 = OpTypePointer Function %5 +%75 = OpConstant %71 1 +%77 = OpTypePointer Function %6 +%79 = OpConstant %71 2 +%81 = OpTypePointer Function %7 +%83 = OpConstant %71 3 +%85 = OpTypePointer Function %8 +%87 = OpConstant %71 4 +%89 = OpTypePointer Function %9 +%91 = OpConstant %71 5 +%93 = OpTypePointer Function %10 +%95 = OpConstant %71 6 +%97 = OpTypePointer Function %11 +%99 = OpConstant %71 7 +%112 = OpVariable %15 Input +%114 = OpVariable %18 Input +%116 = OpVariable %21 Input +%118 = OpVariable %24 Input +%120 = OpVariable %27 Input +%122 = OpVariable %30 Input +%124 = OpVariable %33 Input +%126 = OpVariable %36 Input +%128 = OpVariable %39 Output +%129 = OpVariable %41 Output +%130 = OpVariable %43 Output +%131 = OpVariable %45 Output +%132 = OpVariable %47 Output +%133 = OpVariable %49 Output +%134 = OpVariable %51 Output +%135 = OpVariable %53 Output +%138 = OpConstantNull %12 +%175 = OpVariable %15 Input +%177 = OpVariable %18 Input +%179 = OpVariable %21 Input +%181 = OpVariable %24 Input +%183 = OpVariable %27 Input +%185 = OpVariable %30 Input +%187 = OpVariable %33 Input +%189 = OpVariable %36 Input +%191 = OpVariable %39 Output +%192 = OpVariable %41 Output +%193 = OpVariable %43 Output +%194 = OpVariable %45 Output +%195 = OpVariable %47 Output +%196 = OpVariable %49 Output +%197 = OpVariable %51 Output +%198 = OpVariable %53 Output +%201 = OpConstantNull %12 +%203 = OpConstantNull %12 +%248 = OpVariable %15 Input +%250 = OpVariable %18 Input +%252 = OpVariable %21 Input +%254 = OpVariable %24 Input +%256 = OpVariable %27 Input +%258 = OpVariable %30 Input +%260 = OpVariable %33 Input +%262 = OpVariable %36 Input +%264 = OpVariable %39 Output +%266 = OpConstant %4 0 +%268 = OpConstantNull %12 +%275 = OpVariable %15 Input +%277 = OpVariable %18 Input +%279 = OpVariable %21 Input +%281 = OpVariable %24 Input +%283 = OpVariable %27 Input +%285 = OpVariable %30 Input +%287 = OpVariable %33 Input +%289 = OpVariable %36 Input +%291 = OpVariable %39 Output +%292 = OpVariable %41 Output +%293 = OpVariable %43 Output +%294 = OpVariable %45 Output +%295 = OpVariable %47 Output +%296 = OpVariable %49 Output +%297 = OpVariable %51 Output +%298 = OpVariable %53 Output +%301 = OpConstantNull %12 +%54 = OpFunction %2 None %55 +%13 = OpLabel +%64 = OpVariable %65 Function %66 +%16 = OpLoad %4 %14 +%19 = OpLoad %5 %17 +%22 = OpLoad %6 %20 +%25 = OpLoad %7 %23 +%28 = OpLoad %8 %26 +%31 = OpLoad %9 %29 +%34 = OpLoad %10 %32 +%37 = OpLoad %11 %35 +OpBranch %67 +%67 = OpLabel +OpLine %3 15 5 +OpLine %3 15 25 +%69 = OpFAdd %4 %16 %56 +OpLine %3 15 5 +%72 = OpAccessChain %68 %64 %70 +OpStore %72 %69 +OpLine %3 16 5 +OpLine %3 16 25 +%74 = OpFAdd %5 %19 %57 +OpLine %3 16 5 +%76 = OpAccessChain %73 %64 %75 +OpStore %76 %74 +OpLine %3 17 5 +OpLine %3 17 23 +%78 = OpFAdd %6 %22 %58 +OpLine %3 17 5 +%80 = OpAccessChain %77 %64 %79 +OpStore %80 %78 +OpLine %3 18 5 +OpLine %3 18 34 +OpLine %3 18 23 +%82 = OpFAdd %7 %25 %59 +OpLine %3 18 5 +%84 = OpAccessChain %81 %64 %83 +OpStore %84 %82 +OpLine %3 19 5 +OpLine %3 19 23 +%86 = OpFAdd %8 %28 %60 +OpLine %3 19 5 +%88 = OpAccessChain %85 %64 %87 +OpStore %88 %86 +OpLine %3 20 5 +OpLine %3 20 34 +OpLine %3 20 23 +%90 = OpFAdd %9 %31 %61 +OpLine %3 20 5 +%92 = OpAccessChain %89 %64 %91 +OpStore %92 %90 +OpLine %3 21 5 +OpLine %3 21 23 +%94 = OpFAdd %10 %34 %62 +OpLine %3 21 5 +%96 = OpAccessChain %93 %64 %95 +OpStore %96 %94 +OpLine %3 22 5 +OpLine %3 22 34 +OpLine %3 22 23 +%98 = OpFAdd %11 %37 %63 +OpLine %3 22 5 +%100 = OpAccessChain %97 %64 %99 +OpStore %100 %98 +OpLine %3 1 1 +%101 = OpLoad %12 %64 +%102 = OpCompositeExtract %4 %101 0 +OpStore %38 %102 +%103 = OpCompositeExtract %5 %101 1 +OpStore %40 %103 +%104 = OpCompositeExtract %6 %101 2 +OpStore %42 %104 +%105 = OpCompositeExtract %7 %101 3 +OpStore %44 %105 +%106 = OpCompositeExtract %8 %101 4 +OpStore %46 %106 +%107 = OpCompositeExtract %9 %101 5 +OpStore %48 %107 +%108 = OpCompositeExtract %10 %101 6 +OpStore %50 %108 +%109 = OpCompositeExtract %11 %101 7 +OpStore %52 %109 +OpReturn +OpFunctionEnd +%136 = OpFunction %2 None %55 +%110 = OpLabel +%137 = OpVariable %65 Function %138 +%113 = OpLoad %4 %112 +%115 = OpLoad %5 %114 +%117 = OpLoad %6 %116 +%119 = OpLoad %7 %118 +%121 = OpLoad %8 %120 +%123 = OpLoad %9 %122 +%125 = OpLoad %10 %124 +%127 = OpLoad %11 %126 +%111 = OpCompositeConstruct %12 %113 %115 %117 %119 %121 %123 %125 %127 +OpBranch %139 +%139 = OpLabel +OpLine %3 40 5 +%140 = OpCompositeExtract %4 %111 0 +OpLine %3 40 25 +%141 = OpFAdd %4 %140 %56 +OpLine %3 40 5 +%142 = OpAccessChain %68 %137 %70 +OpStore %142 %141 +OpLine %3 41 5 +%143 = OpCompositeExtract %5 %111 1 +OpLine %3 41 25 +%144 = OpFAdd %5 %143 %57 +OpLine %3 41 5 +%145 = OpAccessChain %73 %137 %75 +OpStore %145 %144 +OpLine %3 42 5 +%146 = OpCompositeExtract %6 %111 2 +OpLine %3 42 23 +%147 = OpFAdd %6 %146 %58 +OpLine %3 42 5 +%148 = OpAccessChain %77 %137 %79 +OpStore %148 %147 +OpLine %3 43 5 +%149 = OpCompositeExtract %7 %111 3 +OpLine %3 43 40 +OpLine %3 43 23 +%150 = OpFAdd %7 %149 %59 +OpLine %3 43 5 +%151 = OpAccessChain %81 %137 %83 +OpStore %151 %150 +OpLine %3 44 5 +%152 = OpCompositeExtract %8 %111 4 +OpLine %3 44 23 +%153 = OpFAdd %8 %152 %60 +OpLine %3 44 5 +%154 = OpAccessChain %85 %137 %87 +OpStore %154 %153 +OpLine %3 45 5 +%155 = OpCompositeExtract %9 %111 5 +OpLine %3 45 40 +OpLine %3 45 23 +%156 = OpFAdd %9 %155 %61 +OpLine %3 45 5 +%157 = OpAccessChain %89 %137 %91 +OpStore %157 %156 +OpLine %3 46 5 +%158 = OpCompositeExtract %10 %111 6 +OpLine %3 46 23 +%159 = OpFAdd %10 %158 %62 +OpLine %3 46 5 +%160 = OpAccessChain %93 %137 %95 +OpStore %160 %159 +OpLine %3 47 5 +%161 = OpCompositeExtract %11 %111 7 +OpLine %3 47 40 +OpLine %3 47 23 +%162 = OpFAdd %11 %161 %63 +OpLine %3 47 5 +%163 = OpAccessChain %97 %137 %99 +OpStore %163 %162 +OpLine %3 1 1 +%164 = OpLoad %12 %137 +%165 = OpCompositeExtract %4 %164 0 +OpStore %128 %165 +%166 = OpCompositeExtract %5 %164 1 +OpStore %129 %166 +%167 = OpCompositeExtract %6 %164 2 +OpStore %130 %167 +%168 = OpCompositeExtract %7 %164 3 +OpStore %131 %168 +%169 = OpCompositeExtract %8 %164 4 +OpStore %132 %169 +%170 = OpCompositeExtract %9 %164 5 +OpStore %133 %170 +%171 = OpCompositeExtract %10 %164 6 +OpStore %134 %171 +%172 = OpCompositeExtract %11 %164 7 +OpStore %135 %172 +OpReturn +OpFunctionEnd +%199 = OpFunction %2 None %55 +%173 = OpLabel +%200 = OpVariable %65 Function %201 +%202 = OpVariable %65 Function %203 +%176 = OpLoad %4 %175 +%178 = OpLoad %5 %177 +%180 = OpLoad %6 %179 +%182 = OpLoad %7 %181 +%184 = OpLoad %8 %183 +%186 = OpLoad %9 %185 +%188 = OpLoad %10 %187 +%190 = OpLoad %11 %189 +%174 = OpCompositeConstruct %12 %176 %178 %180 %182 %184 %186 %188 %190 +OpBranch %204 +%204 = OpLabel +OpLine %3 53 5 +OpStore %200 %174 +OpLine %3 55 5 +%205 = OpAccessChain %68 %200 %70 +%206 = OpLoad %4 %205 +OpLine %3 55 25 +%207 = OpFAdd %4 %206 %56 +OpLine %3 55 5 +%208 = OpAccessChain %68 %202 %70 +OpStore %208 %207 +OpLine %3 56 5 +%209 = OpAccessChain %73 %200 %75 +%210 = OpLoad %5 %209 +OpLine %3 56 25 +%211 = OpFAdd %5 %210 %57 +OpLine %3 56 5 +%212 = OpAccessChain %73 %202 %75 +OpStore %212 %211 +OpLine %3 57 5 +%213 = OpAccessChain %77 %200 %79 +%214 = OpLoad %6 %213 +OpLine %3 57 23 +%215 = OpFAdd %6 %214 %58 +OpLine %3 57 5 +%216 = OpAccessChain %77 %202 %79 +OpStore %216 %215 +OpLine %3 58 5 +%217 = OpAccessChain %81 %200 %83 +%218 = OpLoad %7 %217 +OpLine %3 58 40 +OpLine %3 58 23 +%219 = OpFAdd %7 %218 %59 +OpLine %3 58 5 +%220 = OpAccessChain %81 %202 %83 +OpStore %220 %219 +OpLine %3 59 5 +%221 = OpAccessChain %85 %200 %87 +%222 = OpLoad %8 %221 +OpLine %3 59 23 +%223 = OpFAdd %8 %222 %60 +OpLine %3 59 5 +%224 = OpAccessChain %85 %202 %87 +OpStore %224 %223 +OpLine %3 60 5 +%225 = OpAccessChain %89 %200 %91 +%226 = OpLoad %9 %225 +OpLine %3 60 40 +OpLine %3 60 23 +%227 = OpFAdd %9 %226 %61 +OpLine %3 60 5 +%228 = OpAccessChain %89 %202 %91 +OpStore %228 %227 +OpLine %3 61 5 +%229 = OpAccessChain %93 %200 %95 +%230 = OpLoad %10 %229 +OpLine %3 61 23 +%231 = OpFAdd %10 %230 %62 +OpLine %3 61 5 +%232 = OpAccessChain %93 %202 %95 +OpStore %232 %231 +OpLine %3 62 5 +%233 = OpAccessChain %97 %200 %99 +%234 = OpLoad %11 %233 +OpLine %3 62 40 +OpLine %3 62 23 +%235 = OpFAdd %11 %234 %63 +OpLine %3 62 5 +%236 = OpAccessChain %97 %202 %99 +OpStore %236 %235 +OpLine %3 1 1 +%237 = OpLoad %12 %202 +%238 = OpCompositeExtract %4 %237 0 +OpStore %191 %238 +%239 = OpCompositeExtract %5 %237 1 +OpStore %192 %239 +%240 = OpCompositeExtract %6 %237 2 +OpStore %193 %240 +%241 = OpCompositeExtract %7 %237 3 +OpStore %194 %241 +%242 = OpCompositeExtract %8 %237 4 +OpStore %195 %242 +%243 = OpCompositeExtract %9 %237 5 +OpStore %196 %243 +%244 = OpCompositeExtract %10 %237 6 +OpStore %197 %244 +%245 = OpCompositeExtract %11 %237 7 +OpStore %198 %245 +OpReturn +OpFunctionEnd +%265 = OpFunction %2 None %55 +%246 = OpLabel +%267 = OpVariable %65 Function %268 +%249 = OpLoad %4 %248 +%251 = OpLoad %5 %250 +%253 = OpLoad %6 %252 +%255 = OpLoad %7 %254 +%257 = OpLoad %8 %256 +%259 = OpLoad %9 %258 +%261 = OpLoad %10 %260 +%263 = OpLoad %11 %262 +%247 = OpCompositeConstruct %12 %249 %251 %253 %255 %257 %259 %261 %263 +OpBranch %269 +%269 = OpLabel +OpLine %3 68 5 +OpStore %267 %247 +OpLine %3 69 5 +OpLine %3 69 5 +%270 = OpAccessChain %68 %267 %70 +OpStore %270 %266 +OpLine %3 70 12 +%271 = OpAccessChain %68 %267 %70 +%272 = OpLoad %4 %271 +OpStore %264 %272 +OpReturn +OpFunctionEnd +%299 = OpFunction %2 None %55 +%273 = OpLabel +%300 = OpVariable %65 Function %301 +%276 = OpLoad %4 %275 +%278 = OpLoad %5 %277 +%280 = OpLoad %6 %279 +%282 = OpLoad %7 %281 +%284 = OpLoad %8 %283 +%286 = OpLoad %9 %285 +%288 = OpLoad %10 %287 +%290 = OpLoad %11 %289 +%274 = OpCompositeConstruct %12 %276 %278 %280 %282 %284 %286 %288 %290 +OpBranch %302 +%302 = OpLabel +OpLine %3 76 5 +%303 = OpCompositeExtract %6 %274 2 +%304 = OpCompositeExtract %4 %303 1 +OpLine %3 76 5 +%305 = OpAccessChain %68 %300 %79 %70 +OpStore %305 %304 +OpLine %3 77 5 +%306 = OpCompositeExtract %6 %274 2 +%307 = OpCompositeExtract %4 %306 0 +OpLine %3 77 5 +%308 = OpAccessChain %68 %300 %79 %75 +OpStore %308 %307 +OpLine %3 1 1 +%309 = OpLoad %12 %300 +%310 = OpCompositeExtract %4 %309 0 +OpStore %291 %310 +%311 = OpCompositeExtract %5 %309 1 +OpStore %292 %311 +%312 = OpCompositeExtract %6 %309 2 +OpStore %293 %312 +%313 = OpCompositeExtract %7 %309 3 +OpStore %294 %313 +%314 = OpCompositeExtract %8 %309 4 +OpStore %295 %314 +%315 = OpCompositeExtract %9 %309 5 +OpStore %296 %315 +%316 = OpCompositeExtract %10 %309 6 +OpStore %297 %316 +%317 = OpCompositeExtract %11 %309 7 +OpStore %298 %317 +OpReturn +OpFunctionEnd \ No newline at end of file diff --git a/naga/tests/out/spv/wgsl-f16-polyfill.spvasm b/naga/tests/out/spv/wgsl-f16-polyfill.spvasm new file mode 100644 index 00000000000..d673816a486 --- /dev/null +++ b/naga/tests/out/spv/wgsl-f16-polyfill.spvasm @@ -0,0 +1,789 @@ +; SPIR-V +; Version: 1.1 +; Generator: rspirv +; Bound: 347 +OpCapability Shader +OpCapability Float16 +OpCapability StorageBuffer16BitAccess +OpCapability UniformAndStorageBuffer16BitAccess +OpExtension "SPV_KHR_16bit_storage" +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint Fragment %50 "test_direct" %14 %18 %20 %24 %26 %30 %32 %36 %38 %40 %41 %43 %44 %46 %47 %49 +OpEntryPoint Fragment %140 "test_struct" %112 %115 %117 %120 %122 %125 %127 %130 %132 %133 %134 %135 %136 %137 %138 %139 +OpEntryPoint Fragment %211 "test_copy_input" %183 %186 %188 %191 %193 %196 %198 %201 %203 %204 %205 %206 %207 %208 %209 %210 +OpEntryPoint Fragment %285 "test_return_partial" %264 %267 %269 %272 %274 %277 %279 %282 %284 +OpEntryPoint Fragment %324 "test_component_access" %296 %299 %301 %304 %306 %309 %311 %314 %316 %317 %318 %319 %320 %321 %322 %323 +OpExecutionMode %50 OriginUpperLeft +OpExecutionMode %140 OriginUpperLeft +OpExecutionMode %211 OriginUpperLeft +OpExecutionMode %285 OriginUpperLeft +OpExecutionMode %324 OriginUpperLeft +%3 = OpString "f16-polyfill.wgsl" +OpSource Unknown 0 %3 "enable f16; + +@fragment +fn test_direct( + @location(0) scalar_f16: f16, + @location(1) scalar_f32: f32, + @location(2) vec2_f16: vec2, + @location(3) vec2_f32: vec2, + @location(4) vec3_f16: vec3, + @location(5) vec3_f32: vec3, + @location(6) vec4_f16: vec4, + @location(7) vec4_f32: vec4, +) -> F16IO { + var output: F16IO; + output.scalar_f16 = scalar_f16 + 1.0h; + output.scalar_f32 = scalar_f32 + 1.0; + output.vec2_f16 = vec2_f16 + vec2(1.0h); + output.vec2_f32 = vec2_f32 + vec2(1.0); + output.vec3_f16 = vec3_f16 + vec3(1.0h); + output.vec3_f32 = vec3_f32 + vec3(1.0); + output.vec4_f16 = vec4_f16 + vec4(1.0h); + output.vec4_f32 = vec4_f32 + vec4(1.0); + return output; +} + +struct F16IO { + @location(0) scalar_f16: f16, + @location(1) scalar_f32: f32, + @location(2) vec2_f16: vec2, + @location(3) vec2_f32: vec2, + @location(4) vec3_f16: vec3, + @location(5) vec3_f32: vec3, + @location(6) vec4_f16: vec4, + @location(7) vec4_f32: vec4, +} + +@fragment +fn test_struct(input: F16IO) -> F16IO { + var output: F16IO; + output.scalar_f16 = input.scalar_f16 + 1.0h; + output.scalar_f32 = input.scalar_f32 + 1.0; + output.vec2_f16 = input.vec2_f16 + vec2(1.0h); + output.vec2_f32 = input.vec2_f32 + vec2(1.0); + output.vec3_f16 = input.vec3_f16 + vec3(1.0h); + output.vec3_f32 = input.vec3_f32 + vec3(1.0); + output.vec4_f16 = input.vec4_f16 + vec4(1.0h); + output.vec4_f32 = input.vec4_f32 + vec4(1.0); + return output; +} + +@fragment +fn test_copy_input(input_original: F16IO) -> F16IO { + var input = input_original; + var output: F16IO; + output.scalar_f16 = input.scalar_f16 + 1.0h; + output.scalar_f32 = input.scalar_f32 + 1.0; + output.vec2_f16 = input.vec2_f16 + vec2(1.0h); + output.vec2_f32 = input.vec2_f32 + vec2(1.0); + output.vec3_f16 = input.vec3_f16 + vec3(1.0h); + output.vec3_f32 = input.vec3_f32 + vec3(1.0); + output.vec4_f16 = input.vec4_f16 + vec4(1.0h); + output.vec4_f32 = input.vec4_f32 + vec4(1.0); + return output; +} + +@fragment +fn test_return_partial(input_original: F16IO) -> @location(0) f16 { + var input = input_original; + input.scalar_f16 = 0.0h; + return input.scalar_f16; +} + +@fragment +fn test_component_access(input: F16IO) -> F16IO { + var output: F16IO; + output.vec2_f16.x = input.vec2_f16.y; + output.vec2_f16.y = input.vec2_f16.x; + return output; +}" +OpMemberName %12 0 "scalar_f16" +OpMemberName %12 1 "scalar_f32" +OpMemberName %12 2 "vec2_f16" +OpMemberName %12 3 "vec2_f32" +OpMemberName %12 4 "vec3_f16" +OpMemberName %12 5 "vec3_f32" +OpMemberName %12 6 "vec4_f16" +OpMemberName %12 7 "vec4_f32" +OpName %12 "F16IO" +OpName %14 "scalar_f16" +OpName %18 "scalar_f32" +OpName %20 "vec2_f16" +OpName %24 "vec2_f32" +OpName %26 "vec3_f16" +OpName %30 "vec3_f32" +OpName %32 "vec4_f16" +OpName %36 "vec4_f32" +OpName %38 "scalar_f16" +OpName %40 "scalar_f32" +OpName %41 "vec2_f16" +OpName %43 "vec2_f32" +OpName %44 "vec3_f16" +OpName %46 "vec3_f32" +OpName %47 "vec4_f16" +OpName %49 "vec4_f32" +OpName %50 "test_direct" +OpName %60 "output" +OpName %112 "scalar_f16" +OpName %115 "scalar_f32" +OpName %117 "vec2_f16" +OpName %120 "vec2_f32" +OpName %122 "vec3_f16" +OpName %125 "vec3_f32" +OpName %127 "vec4_f16" +OpName %130 "vec4_f32" +OpName %132 "scalar_f16" +OpName %133 "scalar_f32" +OpName %134 "vec2_f16" +OpName %135 "vec2_f32" +OpName %136 "vec3_f16" +OpName %137 "vec3_f32" +OpName %138 "vec4_f16" +OpName %139 "vec4_f32" +OpName %140 "test_struct" +OpName %141 "output" +OpName %183 "scalar_f16" +OpName %186 "scalar_f32" +OpName %188 "vec2_f16" +OpName %191 "vec2_f32" +OpName %193 "vec3_f16" +OpName %196 "vec3_f32" +OpName %198 "vec4_f16" +OpName %201 "vec4_f32" +OpName %203 "scalar_f16" +OpName %204 "scalar_f32" +OpName %205 "vec2_f16" +OpName %206 "vec2_f32" +OpName %207 "vec3_f16" +OpName %208 "vec3_f32" +OpName %209 "vec4_f16" +OpName %210 "vec4_f32" +OpName %211 "test_copy_input" +OpName %212 "input" +OpName %214 "output" +OpName %264 "scalar_f16" +OpName %267 "scalar_f32" +OpName %269 "vec2_f16" +OpName %272 "vec2_f32" +OpName %274 "vec3_f16" +OpName %277 "vec3_f32" +OpName %279 "vec4_f16" +OpName %282 "vec4_f32" +OpName %285 "test_return_partial" +OpName %287 "input" +OpName %296 "scalar_f16" +OpName %299 "scalar_f32" +OpName %301 "vec2_f16" +OpName %304 "vec2_f32" +OpName %306 "vec3_f16" +OpName %309 "vec3_f32" +OpName %311 "vec4_f16" +OpName %314 "vec4_f32" +OpName %316 "scalar_f16" +OpName %317 "scalar_f32" +OpName %318 "vec2_f16" +OpName %319 "vec2_f32" +OpName %320 "vec3_f16" +OpName %321 "vec3_f32" +OpName %322 "vec4_f16" +OpName %323 "vec4_f32" +OpName %324 "test_component_access" +OpName %325 "output" +OpMemberDecorate %12 0 Offset 0 +OpMemberDecorate %12 1 Offset 4 +OpMemberDecorate %12 2 Offset 8 +OpMemberDecorate %12 3 Offset 16 +OpMemberDecorate %12 4 Offset 24 +OpMemberDecorate %12 5 Offset 32 +OpMemberDecorate %12 6 Offset 48 +OpMemberDecorate %12 7 Offset 64 +OpDecorate %14 Location 0 +OpDecorate %18 Location 1 +OpDecorate %20 Location 2 +OpDecorate %24 Location 3 +OpDecorate %26 Location 4 +OpDecorate %30 Location 5 +OpDecorate %32 Location 6 +OpDecorate %36 Location 7 +OpDecorate %38 Location 0 +OpDecorate %40 Location 1 +OpDecorate %41 Location 2 +OpDecorate %43 Location 3 +OpDecorate %44 Location 4 +OpDecorate %46 Location 5 +OpDecorate %47 Location 6 +OpDecorate %49 Location 7 +OpDecorate %112 Location 0 +OpDecorate %115 Location 1 +OpDecorate %117 Location 2 +OpDecorate %120 Location 3 +OpDecorate %122 Location 4 +OpDecorate %125 Location 5 +OpDecorate %127 Location 6 +OpDecorate %130 Location 7 +OpDecorate %132 Location 0 +OpDecorate %133 Location 1 +OpDecorate %134 Location 2 +OpDecorate %135 Location 3 +OpDecorate %136 Location 4 +OpDecorate %137 Location 5 +OpDecorate %138 Location 6 +OpDecorate %139 Location 7 +OpDecorate %183 Location 0 +OpDecorate %186 Location 1 +OpDecorate %188 Location 2 +OpDecorate %191 Location 3 +OpDecorate %193 Location 4 +OpDecorate %196 Location 5 +OpDecorate %198 Location 6 +OpDecorate %201 Location 7 +OpDecorate %203 Location 0 +OpDecorate %204 Location 1 +OpDecorate %205 Location 2 +OpDecorate %206 Location 3 +OpDecorate %207 Location 4 +OpDecorate %208 Location 5 +OpDecorate %209 Location 6 +OpDecorate %210 Location 7 +OpDecorate %264 Location 0 +OpDecorate %267 Location 1 +OpDecorate %269 Location 2 +OpDecorate %272 Location 3 +OpDecorate %274 Location 4 +OpDecorate %277 Location 5 +OpDecorate %279 Location 6 +OpDecorate %282 Location 7 +OpDecorate %284 Location 0 +OpDecorate %296 Location 0 +OpDecorate %299 Location 1 +OpDecorate %301 Location 2 +OpDecorate %304 Location 3 +OpDecorate %306 Location 4 +OpDecorate %309 Location 5 +OpDecorate %311 Location 6 +OpDecorate %314 Location 7 +OpDecorate %316 Location 0 +OpDecorate %317 Location 1 +OpDecorate %318 Location 2 +OpDecorate %319 Location 3 +OpDecorate %320 Location 4 +OpDecorate %321 Location 5 +OpDecorate %322 Location 6 +OpDecorate %323 Location 7 +%2 = OpTypeVoid +%4 = OpTypeFloat 16 +%5 = OpTypeFloat 32 +%6 = OpTypeVector %4 2 +%7 = OpTypeVector %5 2 +%8 = OpTypeVector %4 3 +%9 = OpTypeVector %5 3 +%10 = OpTypeVector %4 4 +%11 = OpTypeVector %5 4 +%12 = OpTypeStruct %4 %5 %6 %7 %8 %9 %10 %11 +%15 = OpTypePointer Input %5 +%14 = OpVariable %15 Input +%18 = OpVariable %15 Input +%21 = OpTypePointer Input %7 +%20 = OpVariable %21 Input +%24 = OpVariable %21 Input +%27 = OpTypePointer Input %9 +%26 = OpVariable %27 Input +%30 = OpVariable %27 Input +%33 = OpTypePointer Input %11 +%32 = OpVariable %33 Input +%36 = OpVariable %33 Input +%39 = OpTypePointer Output %5 +%38 = OpVariable %39 Output +%40 = OpVariable %39 Output +%42 = OpTypePointer Output %7 +%41 = OpVariable %42 Output +%43 = OpVariable %42 Output +%45 = OpTypePointer Output %9 +%44 = OpVariable %45 Output +%46 = OpVariable %45 Output +%48 = OpTypePointer Output %11 +%47 = OpVariable %48 Output +%49 = OpVariable %48 Output +%51 = OpTypeFunction %2 +%52 = OpConstant %4 0.000000000000000000000000000000000000000021524 +%53 = OpConstant %5 1 +%54 = OpConstantComposite %6 %52 %52 +%55 = OpConstantComposite %7 %53 %53 +%56 = OpConstantComposite %8 %52 %52 %52 +%57 = OpConstantComposite %9 %53 %53 %53 +%58 = OpConstantComposite %10 %52 %52 %52 %52 +%59 = OpConstantComposite %11 %53 %53 %53 %53 +%61 = OpTypePointer Function %12 +%62 = OpConstantNull %12 +%64 = OpTypePointer Function %4 +%67 = OpTypeInt 32 0 +%66 = OpConstant %67 0 +%69 = OpTypePointer Function %5 +%71 = OpConstant %67 1 +%73 = OpTypePointer Function %6 +%75 = OpConstant %67 2 +%77 = OpTypePointer Function %7 +%79 = OpConstant %67 3 +%81 = OpTypePointer Function %8 +%83 = OpConstant %67 4 +%85 = OpTypePointer Function %9 +%87 = OpConstant %67 5 +%89 = OpTypePointer Function %10 +%91 = OpConstant %67 6 +%93 = OpTypePointer Function %11 +%95 = OpConstant %67 7 +%112 = OpVariable %15 Input +%115 = OpVariable %15 Input +%117 = OpVariable %21 Input +%120 = OpVariable %21 Input +%122 = OpVariable %27 Input +%125 = OpVariable %27 Input +%127 = OpVariable %33 Input +%130 = OpVariable %33 Input +%132 = OpVariable %39 Output +%133 = OpVariable %39 Output +%134 = OpVariable %42 Output +%135 = OpVariable %42 Output +%136 = OpVariable %45 Output +%137 = OpVariable %45 Output +%138 = OpVariable %48 Output +%139 = OpVariable %48 Output +%142 = OpConstantNull %12 +%183 = OpVariable %15 Input +%186 = OpVariable %15 Input +%188 = OpVariable %21 Input +%191 = OpVariable %21 Input +%193 = OpVariable %27 Input +%196 = OpVariable %27 Input +%198 = OpVariable %33 Input +%201 = OpVariable %33 Input +%203 = OpVariable %39 Output +%204 = OpVariable %39 Output +%205 = OpVariable %42 Output +%206 = OpVariable %42 Output +%207 = OpVariable %45 Output +%208 = OpVariable %45 Output +%209 = OpVariable %48 Output +%210 = OpVariable %48 Output +%213 = OpConstantNull %12 +%215 = OpConstantNull %12 +%264 = OpVariable %15 Input +%267 = OpVariable %15 Input +%269 = OpVariable %21 Input +%272 = OpVariable %21 Input +%274 = OpVariable %27 Input +%277 = OpVariable %27 Input +%279 = OpVariable %33 Input +%282 = OpVariable %33 Input +%284 = OpVariable %39 Output +%286 = OpConstant %4 0 +%288 = OpConstantNull %12 +%296 = OpVariable %15 Input +%299 = OpVariable %15 Input +%301 = OpVariable %21 Input +%304 = OpVariable %21 Input +%306 = OpVariable %27 Input +%309 = OpVariable %27 Input +%311 = OpVariable %33 Input +%314 = OpVariable %33 Input +%316 = OpVariable %39 Output +%317 = OpVariable %39 Output +%318 = OpVariable %42 Output +%319 = OpVariable %42 Output +%320 = OpVariable %45 Output +%321 = OpVariable %45 Output +%322 = OpVariable %48 Output +%323 = OpVariable %48 Output +%326 = OpConstantNull %12 +%50 = OpFunction %2 None %51 +%13 = OpLabel +%60 = OpVariable %61 Function %62 +%16 = OpLoad %5 %14 +%17 = OpFConvert %4 %16 +%19 = OpLoad %5 %18 +%22 = OpLoad %7 %20 +%23 = OpFConvert %6 %22 +%25 = OpLoad %7 %24 +%28 = OpLoad %9 %26 +%29 = OpFConvert %8 %28 +%31 = OpLoad %9 %30 +%34 = OpLoad %11 %32 +%35 = OpFConvert %10 %34 +%37 = OpLoad %11 %36 +OpBranch %63 +%63 = OpLabel +OpLine %3 15 5 +OpLine %3 15 25 +%65 = OpFAdd %4 %17 %52 +OpLine %3 15 5 +%68 = OpAccessChain %64 %60 %66 +OpStore %68 %65 +OpLine %3 16 5 +OpLine %3 16 25 +%70 = OpFAdd %5 %19 %53 +OpLine %3 16 5 +%72 = OpAccessChain %69 %60 %71 +OpStore %72 %70 +OpLine %3 17 5 +OpLine %3 17 23 +%74 = OpFAdd %6 %23 %54 +OpLine %3 17 5 +%76 = OpAccessChain %73 %60 %75 +OpStore %76 %74 +OpLine %3 18 5 +OpLine %3 18 34 +OpLine %3 18 23 +%78 = OpFAdd %7 %25 %55 +OpLine %3 18 5 +%80 = OpAccessChain %77 %60 %79 +OpStore %80 %78 +OpLine %3 19 5 +OpLine %3 19 23 +%82 = OpFAdd %8 %29 %56 +OpLine %3 19 5 +%84 = OpAccessChain %81 %60 %83 +OpStore %84 %82 +OpLine %3 20 5 +OpLine %3 20 34 +OpLine %3 20 23 +%86 = OpFAdd %9 %31 %57 +OpLine %3 20 5 +%88 = OpAccessChain %85 %60 %87 +OpStore %88 %86 +OpLine %3 21 5 +OpLine %3 21 23 +%90 = OpFAdd %10 %35 %58 +OpLine %3 21 5 +%92 = OpAccessChain %89 %60 %91 +OpStore %92 %90 +OpLine %3 22 5 +OpLine %3 22 34 +OpLine %3 22 23 +%94 = OpFAdd %11 %37 %59 +OpLine %3 22 5 +%96 = OpAccessChain %93 %60 %95 +OpStore %96 %94 +OpLine %3 1 1 +%97 = OpLoad %12 %60 +%98 = OpCompositeExtract %4 %97 0 +%99 = OpFConvert %5 %98 +OpStore %38 %99 +%100 = OpCompositeExtract %5 %97 1 +OpStore %40 %100 +%101 = OpCompositeExtract %6 %97 2 +%102 = OpFConvert %7 %101 +OpStore %41 %102 +%103 = OpCompositeExtract %7 %97 3 +OpStore %43 %103 +%104 = OpCompositeExtract %8 %97 4 +%105 = OpFConvert %9 %104 +OpStore %44 %105 +%106 = OpCompositeExtract %9 %97 5 +OpStore %46 %106 +%107 = OpCompositeExtract %10 %97 6 +%108 = OpFConvert %11 %107 +OpStore %47 %108 +%109 = OpCompositeExtract %11 %97 7 +OpStore %49 %109 +OpReturn +OpFunctionEnd +%140 = OpFunction %2 None %51 +%110 = OpLabel +%141 = OpVariable %61 Function %142 +%113 = OpLoad %5 %112 +%114 = OpFConvert %4 %113 +%116 = OpLoad %5 %115 +%118 = OpLoad %7 %117 +%119 = OpFConvert %6 %118 +%121 = OpLoad %7 %120 +%123 = OpLoad %9 %122 +%124 = OpFConvert %8 %123 +%126 = OpLoad %9 %125 +%128 = OpLoad %11 %127 +%129 = OpFConvert %10 %128 +%131 = OpLoad %11 %130 +%111 = OpCompositeConstruct %12 %114 %116 %119 %121 %124 %126 %129 %131 +OpBranch %143 +%143 = OpLabel +OpLine %3 40 5 +%144 = OpCompositeExtract %4 %111 0 +OpLine %3 40 25 +%145 = OpFAdd %4 %144 %52 +OpLine %3 40 5 +%146 = OpAccessChain %64 %141 %66 +OpStore %146 %145 +OpLine %3 41 5 +%147 = OpCompositeExtract %5 %111 1 +OpLine %3 41 25 +%148 = OpFAdd %5 %147 %53 +OpLine %3 41 5 +%149 = OpAccessChain %69 %141 %71 +OpStore %149 %148 +OpLine %3 42 5 +%150 = OpCompositeExtract %6 %111 2 +OpLine %3 42 23 +%151 = OpFAdd %6 %150 %54 +OpLine %3 42 5 +%152 = OpAccessChain %73 %141 %75 +OpStore %152 %151 +OpLine %3 43 5 +%153 = OpCompositeExtract %7 %111 3 +OpLine %3 43 40 +OpLine %3 43 23 +%154 = OpFAdd %7 %153 %55 +OpLine %3 43 5 +%155 = OpAccessChain %77 %141 %79 +OpStore %155 %154 +OpLine %3 44 5 +%156 = OpCompositeExtract %8 %111 4 +OpLine %3 44 23 +%157 = OpFAdd %8 %156 %56 +OpLine %3 44 5 +%158 = OpAccessChain %81 %141 %83 +OpStore %158 %157 +OpLine %3 45 5 +%159 = OpCompositeExtract %9 %111 5 +OpLine %3 45 40 +OpLine %3 45 23 +%160 = OpFAdd %9 %159 %57 +OpLine %3 45 5 +%161 = OpAccessChain %85 %141 %87 +OpStore %161 %160 +OpLine %3 46 5 +%162 = OpCompositeExtract %10 %111 6 +OpLine %3 46 23 +%163 = OpFAdd %10 %162 %58 +OpLine %3 46 5 +%164 = OpAccessChain %89 %141 %91 +OpStore %164 %163 +OpLine %3 47 5 +%165 = OpCompositeExtract %11 %111 7 +OpLine %3 47 40 +OpLine %3 47 23 +%166 = OpFAdd %11 %165 %59 +OpLine %3 47 5 +%167 = OpAccessChain %93 %141 %95 +OpStore %167 %166 +OpLine %3 1 1 +%168 = OpLoad %12 %141 +%169 = OpCompositeExtract %4 %168 0 +%170 = OpFConvert %5 %169 +OpStore %132 %170 +%171 = OpCompositeExtract %5 %168 1 +OpStore %133 %171 +%172 = OpCompositeExtract %6 %168 2 +%173 = OpFConvert %7 %172 +OpStore %134 %173 +%174 = OpCompositeExtract %7 %168 3 +OpStore %135 %174 +%175 = OpCompositeExtract %8 %168 4 +%176 = OpFConvert %9 %175 +OpStore %136 %176 +%177 = OpCompositeExtract %9 %168 5 +OpStore %137 %177 +%178 = OpCompositeExtract %10 %168 6 +%179 = OpFConvert %11 %178 +OpStore %138 %179 +%180 = OpCompositeExtract %11 %168 7 +OpStore %139 %180 +OpReturn +OpFunctionEnd +%211 = OpFunction %2 None %51 +%181 = OpLabel +%212 = OpVariable %61 Function %213 +%214 = OpVariable %61 Function %215 +%184 = OpLoad %5 %183 +%185 = OpFConvert %4 %184 +%187 = OpLoad %5 %186 +%189 = OpLoad %7 %188 +%190 = OpFConvert %6 %189 +%192 = OpLoad %7 %191 +%194 = OpLoad %9 %193 +%195 = OpFConvert %8 %194 +%197 = OpLoad %9 %196 +%199 = OpLoad %11 %198 +%200 = OpFConvert %10 %199 +%202 = OpLoad %11 %201 +%182 = OpCompositeConstruct %12 %185 %187 %190 %192 %195 %197 %200 %202 +OpBranch %216 +%216 = OpLabel +OpLine %3 53 5 +OpStore %212 %182 +OpLine %3 55 5 +%217 = OpAccessChain %64 %212 %66 +%218 = OpLoad %4 %217 +OpLine %3 55 25 +%219 = OpFAdd %4 %218 %52 +OpLine %3 55 5 +%220 = OpAccessChain %64 %214 %66 +OpStore %220 %219 +OpLine %3 56 5 +%221 = OpAccessChain %69 %212 %71 +%222 = OpLoad %5 %221 +OpLine %3 56 25 +%223 = OpFAdd %5 %222 %53 +OpLine %3 56 5 +%224 = OpAccessChain %69 %214 %71 +OpStore %224 %223 +OpLine %3 57 5 +%225 = OpAccessChain %73 %212 %75 +%226 = OpLoad %6 %225 +OpLine %3 57 23 +%227 = OpFAdd %6 %226 %54 +OpLine %3 57 5 +%228 = OpAccessChain %73 %214 %75 +OpStore %228 %227 +OpLine %3 58 5 +%229 = OpAccessChain %77 %212 %79 +%230 = OpLoad %7 %229 +OpLine %3 58 40 +OpLine %3 58 23 +%231 = OpFAdd %7 %230 %55 +OpLine %3 58 5 +%232 = OpAccessChain %77 %214 %79 +OpStore %232 %231 +OpLine %3 59 5 +%233 = OpAccessChain %81 %212 %83 +%234 = OpLoad %8 %233 +OpLine %3 59 23 +%235 = OpFAdd %8 %234 %56 +OpLine %3 59 5 +%236 = OpAccessChain %81 %214 %83 +OpStore %236 %235 +OpLine %3 60 5 +%237 = OpAccessChain %85 %212 %87 +%238 = OpLoad %9 %237 +OpLine %3 60 40 +OpLine %3 60 23 +%239 = OpFAdd %9 %238 %57 +OpLine %3 60 5 +%240 = OpAccessChain %85 %214 %87 +OpStore %240 %239 +OpLine %3 61 5 +%241 = OpAccessChain %89 %212 %91 +%242 = OpLoad %10 %241 +OpLine %3 61 23 +%243 = OpFAdd %10 %242 %58 +OpLine %3 61 5 +%244 = OpAccessChain %89 %214 %91 +OpStore %244 %243 +OpLine %3 62 5 +%245 = OpAccessChain %93 %212 %95 +%246 = OpLoad %11 %245 +OpLine %3 62 40 +OpLine %3 62 23 +%247 = OpFAdd %11 %246 %59 +OpLine %3 62 5 +%248 = OpAccessChain %93 %214 %95 +OpStore %248 %247 +OpLine %3 1 1 +%249 = OpLoad %12 %214 +%250 = OpCompositeExtract %4 %249 0 +%251 = OpFConvert %5 %250 +OpStore %203 %251 +%252 = OpCompositeExtract %5 %249 1 +OpStore %204 %252 +%253 = OpCompositeExtract %6 %249 2 +%254 = OpFConvert %7 %253 +OpStore %205 %254 +%255 = OpCompositeExtract %7 %249 3 +OpStore %206 %255 +%256 = OpCompositeExtract %8 %249 4 +%257 = OpFConvert %9 %256 +OpStore %207 %257 +%258 = OpCompositeExtract %9 %249 5 +OpStore %208 %258 +%259 = OpCompositeExtract %10 %249 6 +%260 = OpFConvert %11 %259 +OpStore %209 %260 +%261 = OpCompositeExtract %11 %249 7 +OpStore %210 %261 +OpReturn +OpFunctionEnd +%285 = OpFunction %2 None %51 +%262 = OpLabel +%287 = OpVariable %61 Function %288 +%265 = OpLoad %5 %264 +%266 = OpFConvert %4 %265 +%268 = OpLoad %5 %267 +%270 = OpLoad %7 %269 +%271 = OpFConvert %6 %270 +%273 = OpLoad %7 %272 +%275 = OpLoad %9 %274 +%276 = OpFConvert %8 %275 +%278 = OpLoad %9 %277 +%280 = OpLoad %11 %279 +%281 = OpFConvert %10 %280 +%283 = OpLoad %11 %282 +%263 = OpCompositeConstruct %12 %266 %268 %271 %273 %276 %278 %281 %283 +OpBranch %289 +%289 = OpLabel +OpLine %3 68 5 +OpStore %287 %263 +OpLine %3 69 5 +OpLine %3 69 5 +%290 = OpAccessChain %64 %287 %66 +OpStore %290 %286 +OpLine %3 70 12 +%291 = OpAccessChain %64 %287 %66 +%292 = OpLoad %4 %291 +%293 = OpFConvert %5 %292 +OpStore %284 %293 +OpReturn +OpFunctionEnd +%324 = OpFunction %2 None %51 +%294 = OpLabel +%325 = OpVariable %61 Function %326 +%297 = OpLoad %5 %296 +%298 = OpFConvert %4 %297 +%300 = OpLoad %5 %299 +%302 = OpLoad %7 %301 +%303 = OpFConvert %6 %302 +%305 = OpLoad %7 %304 +%307 = OpLoad %9 %306 +%308 = OpFConvert %8 %307 +%310 = OpLoad %9 %309 +%312 = OpLoad %11 %311 +%313 = OpFConvert %10 %312 +%315 = OpLoad %11 %314 +%295 = OpCompositeConstruct %12 %298 %300 %303 %305 %308 %310 %313 %315 +OpBranch %327 +%327 = OpLabel +OpLine %3 76 5 +%328 = OpCompositeExtract %6 %295 2 +%329 = OpCompositeExtract %4 %328 1 +OpLine %3 76 5 +%330 = OpAccessChain %64 %325 %75 %66 +OpStore %330 %329 +OpLine %3 77 5 +%331 = OpCompositeExtract %6 %295 2 +%332 = OpCompositeExtract %4 %331 0 +OpLine %3 77 5 +%333 = OpAccessChain %64 %325 %75 %71 +OpStore %333 %332 +OpLine %3 1 1 +%334 = OpLoad %12 %325 +%335 = OpCompositeExtract %4 %334 0 +%336 = OpFConvert %5 %335 +OpStore %316 %336 +%337 = OpCompositeExtract %5 %334 1 +OpStore %317 %337 +%338 = OpCompositeExtract %6 %334 2 +%339 = OpFConvert %7 %338 +OpStore %318 %339 +%340 = OpCompositeExtract %7 %334 3 +OpStore %319 %340 +%341 = OpCompositeExtract %8 %334 4 +%342 = OpFConvert %9 %341 +OpStore %320 %342 +%343 = OpCompositeExtract %9 %334 5 +OpStore %321 %343 +%344 = OpCompositeExtract %10 %334 6 +%345 = OpFConvert %11 %344 +OpStore %322 %345 +%346 = OpCompositeExtract %11 %334 7 +OpStore %323 %346 +OpReturn +OpFunctionEnd \ No newline at end of file diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index f94e1ac3272..71c469806e0 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -198,6 +198,13 @@ impl PhysicalDeviceFeatures { info } + fn supports_storage_input_output_16(&self) -> bool { + self._16bit_storage + .as_ref() + .map(|features| features.storage_input_output16 != 0) + .unwrap_or(false) + } + /// Create a `PhysicalDeviceFeatures` that can be used to create a logical /// device. /// @@ -226,7 +233,7 @@ impl PhysicalDeviceFeatures { /// [`Adapter::required_device_extensions`]: super::Adapter::required_device_extensions fn from_extensions_and_requested_features( phd_capabilities: &PhysicalDeviceProperties, - _phd_features: &PhysicalDeviceFeatures, + phd_features: &PhysicalDeviceFeatures, enabled_extensions: &[&'static CStr], requested_features: wgt::Features, downlevel_flags: wgt::DownlevelFlags, @@ -399,7 +406,7 @@ impl PhysicalDeviceFeatures { Some( vk::PhysicalDevice16BitStorageFeatures::default() .storage_buffer16_bit_access(true) - .storage_input_output16(true) + .storage_input_output16(phd_features.supports_storage_input_output_16()) .uniform_and_storage_buffer16_bit_access(true), ) } else { @@ -736,12 +743,13 @@ impl PhysicalDeviceFeatures { if let (Some(ref f16_i8), Some(ref bit16)) = (self.shader_float16_int8, self._16bit_storage) { + // Note `storage_input_output16` is not required, we polyfill `f16` I/O using `f32` + // types when this capability is not available features.set( F::SHADER_F16, f16_i8.shader_float16 != 0 && bit16.storage_buffer16_bit_access != 0 - && bit16.uniform_and_storage_buffer16_bit_access != 0 - && bit16.storage_input_output16 != 0, + && bit16.uniform_and_storage_buffer16_bit_access != 0, ); } @@ -2148,6 +2156,8 @@ impl super::Adapter { spv::ZeroInitializeWorkgroupMemoryMode::Polyfill }, force_loop_bounding: true, + use_storage_input_output_16: features.contains(wgt::Features::SHADER_F16) + && self.phd_features.supports_storage_input_output_16(), // We need to build this separately for each invocation, so just default it out here binding_map: BTreeMap::default(), debug_info: None, From bb21da3014bed3346fb463d989a2d88e239eb9e6 Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Thu, 14 Aug 2025 11:11:56 +0100 Subject: [PATCH 144/303] [naga msl-out] Split up write_wrapped_functions() It was getting unwieldy, and upcoming commits are going to add additional functions that will be wrapped. --- naga/src/back/msl/writer.rs | 765 ++++++++++++++++++++---------------- 1 file changed, 423 insertions(+), 342 deletions(-) diff --git a/naga/src/back/msl/writer.rs b/naga/src/back/msl/writer.rs index 2525855cd70..e5e5526d7ea 100644 --- a/naga/src/back/msl/writer.rs +++ b/naga/src/back/msl/writer.rs @@ -5513,375 +5513,456 @@ template } } - pub(super) fn write_wrapped_functions( + fn write_wrapped_unary_op( &mut self, module: &crate::Module, func_ctx: &back::FunctionCtx, + op: crate::UnaryOperator, + operand: Handle, ) -> BackendResult { - for (expr_handle, expr) in func_ctx.expressions.iter() { - match *expr { - crate::Expression::Unary { op, expr: operand } => { - let operand_ty = func_ctx.resolve_type(operand, &module.types); - match op { - // Negating the TYPE_MIN of a two's complement signed integer - // type causes overflow, which is undefined behaviour in MSL. To - // avoid this we bitcast the value to unsigned and negate it, - // then bitcast back to signed. - // This adheres to the WGSL spec in that the negative of the - // type's minimum value should equal to the minimum value. - crate::UnaryOperator::Negate - if operand_ty.scalar_kind() == Some(crate::ScalarKind::Sint) => - { - let Some((vector_size, scalar)) = operand_ty.vector_size_and_scalar() - else { - continue; - }; - let wrapped = WrappedFunction::UnaryOp { - op, - ty: (vector_size, scalar), - }; - if !self.wrapped_functions.insert(wrapped) { - continue; - } - - let unsigned_scalar = crate::Scalar { - kind: crate::ScalarKind::Uint, - ..scalar - }; - let mut type_name = String::new(); - let mut unsigned_type_name = String::new(); - match vector_size { - None => { - put_numeric_type(&mut type_name, scalar, &[])?; - put_numeric_type(&mut unsigned_type_name, unsigned_scalar, &[])? - } - Some(size) => { - put_numeric_type(&mut type_name, scalar, &[size])?; - put_numeric_type( - &mut unsigned_type_name, - unsigned_scalar, - &[size], - )?; - } - }; + let operand_ty = func_ctx.resolve_type(operand, &module.types); + match op { + // Negating the TYPE_MIN of a two's complement signed integer + // type causes overflow, which is undefined behaviour in MSL. To + // avoid this we bitcast the value to unsigned and negate it, + // then bitcast back to signed. + // This adheres to the WGSL spec in that the negative of the + // type's minimum value should equal to the minimum value. + crate::UnaryOperator::Negate + if operand_ty.scalar_kind() == Some(crate::ScalarKind::Sint) => + { + let Some((vector_size, scalar)) = operand_ty.vector_size_and_scalar() else { + return Ok(()); + }; + let wrapped = WrappedFunction::UnaryOp { + op, + ty: (vector_size, scalar), + }; + if !self.wrapped_functions.insert(wrapped) { + return Ok(()); + } - writeln!(self.out, "{type_name} {NEG_FUNCTION}({type_name} val) {{")?; - let level = back::Level(1); - writeln!(self.out, "{level}return as_type<{type_name}>(-as_type<{unsigned_type_name}>(val));")?; - writeln!(self.out, "}}")?; - writeln!(self.out)?; - } - _ => {} + let unsigned_scalar = crate::Scalar { + kind: crate::ScalarKind::Uint, + ..scalar + }; + let mut type_name = String::new(); + let mut unsigned_type_name = String::new(); + match vector_size { + None => { + put_numeric_type(&mut type_name, scalar, &[])?; + put_numeric_type(&mut unsigned_type_name, unsigned_scalar, &[])? + } + Some(size) => { + put_numeric_type(&mut type_name, scalar, &[size])?; + put_numeric_type(&mut unsigned_type_name, unsigned_scalar, &[size])?; } + }; + + writeln!(self.out, "{type_name} {NEG_FUNCTION}({type_name} val) {{")?; + let level = back::Level(1); + writeln!( + self.out, + "{level}return as_type<{type_name}>(-as_type<{unsigned_type_name}>(val));" + )?; + writeln!(self.out, "}}")?; + writeln!(self.out)?; + } + _ => {} + } + Ok(()) + } + + fn write_wrapped_binary_op( + &mut self, + module: &crate::Module, + func_ctx: &back::FunctionCtx, + expr: Handle, + op: crate::BinaryOperator, + left: Handle, + right: Handle, + ) -> BackendResult { + let expr_ty = func_ctx.resolve_type(expr, &module.types); + let left_ty = func_ctx.resolve_type(left, &module.types); + let right_ty = func_ctx.resolve_type(right, &module.types); + match (op, expr_ty.scalar_kind()) { + // Signed integer division of TYPE_MIN / -1, or signed or + // unsigned division by zero, gives an unspecified value in MSL. + // We override the divisor to 1 in these cases. + // This adheres to the WGSL spec in that: + // * TYPE_MIN / -1 == TYPE_MIN + // * x / 0 == x + ( + crate::BinaryOperator::Divide, + Some(crate::ScalarKind::Sint | crate::ScalarKind::Uint), + ) => { + let Some(left_wrapped_ty) = left_ty.vector_size_and_scalar() else { + return Ok(()); + }; + let Some(right_wrapped_ty) = right_ty.vector_size_and_scalar() else { + return Ok(()); + }; + let wrapped = WrappedFunction::BinaryOp { + op, + left_ty: left_wrapped_ty, + right_ty: right_wrapped_ty, + }; + if !self.wrapped_functions.insert(wrapped) { + return Ok(()); } - crate::Expression::Binary { op, left, right } => { - let expr_ty = func_ctx.resolve_type(expr_handle, &module.types); - let left_ty = func_ctx.resolve_type(left, &module.types); - let right_ty = func_ctx.resolve_type(right, &module.types); - match (op, expr_ty.scalar_kind()) { - // Signed integer division of TYPE_MIN / -1, or signed or - // unsigned division by zero, gives an unspecified value in MSL. - // We override the divisor to 1 in these cases. - // This adheres to the WGSL spec in that: - // * TYPE_MIN / -1 == TYPE_MIN - // * x / 0 == x - ( - crate::BinaryOperator::Divide, - Some(crate::ScalarKind::Sint | crate::ScalarKind::Uint), - ) => { - let Some(left_wrapped_ty) = left_ty.vector_size_and_scalar() else { - continue; - }; - let Some(right_wrapped_ty) = right_ty.vector_size_and_scalar() else { - continue; - }; - let wrapped = WrappedFunction::BinaryOp { - op, - left_ty: left_wrapped_ty, - right_ty: right_wrapped_ty, - }; - if !self.wrapped_functions.insert(wrapped) { - continue; - } - let Some((vector_size, scalar)) = expr_ty.vector_size_and_scalar() - else { - continue; - }; - let mut type_name = String::new(); - match vector_size { - None => put_numeric_type(&mut type_name, scalar, &[])?, - Some(size) => put_numeric_type(&mut type_name, scalar, &[size])?, - }; - writeln!( - self.out, - "{type_name} {DIV_FUNCTION}({type_name} lhs, {type_name} rhs) {{" - )?; - let level = back::Level(1); - match scalar.kind { - crate::ScalarKind::Sint => { - let min_val = match scalar.width { - 4 => crate::Literal::I32(i32::MIN), - 8 => crate::Literal::I64(i64::MIN), - _ => { - return Err(Error::GenericValidation(format!( - "Unexpected width for scalar {scalar:?}" - ))); - } - }; - write!( - self.out, - "{level}return lhs / metal::select(rhs, 1, (lhs == " - )?; - self.put_literal(min_val)?; - writeln!(self.out, " & rhs == -1) | (rhs == 0));")? - } - crate::ScalarKind::Uint => writeln!( - self.out, - "{level}return lhs / metal::select(rhs, 1u, rhs == 0u);" - )?, - _ => unreachable!(), - } - writeln!(self.out, "}}")?; - writeln!(self.out)?; - } - // Integer modulo where one or both operands are negative, or the - // divisor is zero, is undefined behaviour in MSL. To avoid this - // we use the following equation: - // - // dividend - (dividend / divisor) * divisor - // - // overriding the divisor to 1 if either it is 0, or it is -1 - // and the dividend is TYPE_MIN. - // - // This adheres to the WGSL spec in that: - // * TYPE_MIN % -1 == 0 - // * x % 0 == 0 - ( - crate::BinaryOperator::Modulo, - Some(crate::ScalarKind::Sint | crate::ScalarKind::Uint), - ) => { - let Some(left_wrapped_ty) = left_ty.vector_size_and_scalar() else { - continue; - }; - let Some((right_vector_size, right_scalar)) = - right_ty.vector_size_and_scalar() - else { - continue; - }; - let wrapped = WrappedFunction::BinaryOp { - op, - left_ty: left_wrapped_ty, - right_ty: (right_vector_size, right_scalar), - }; - if !self.wrapped_functions.insert(wrapped) { - continue; + let Some((vector_size, scalar)) = expr_ty.vector_size_and_scalar() else { + return Ok(()); + }; + let mut type_name = String::new(); + match vector_size { + None => put_numeric_type(&mut type_name, scalar, &[])?, + Some(size) => put_numeric_type(&mut type_name, scalar, &[size])?, + }; + writeln!( + self.out, + "{type_name} {DIV_FUNCTION}({type_name} lhs, {type_name} rhs) {{" + )?; + let level = back::Level(1); + match scalar.kind { + crate::ScalarKind::Sint => { + let min_val = match scalar.width { + 4 => crate::Literal::I32(i32::MIN), + 8 => crate::Literal::I64(i64::MIN), + _ => { + return Err(Error::GenericValidation(format!( + "Unexpected width for scalar {scalar:?}" + ))); } + }; + write!( + self.out, + "{level}return lhs / metal::select(rhs, 1, (lhs == " + )?; + self.put_literal(min_val)?; + writeln!(self.out, " & rhs == -1) | (rhs == 0));")? + } + crate::ScalarKind::Uint => writeln!( + self.out, + "{level}return lhs / metal::select(rhs, 1u, rhs == 0u);" + )?, + _ => unreachable!(), + } + writeln!(self.out, "}}")?; + writeln!(self.out)?; + } + // Integer modulo where one or both operands are negative, or the + // divisor is zero, is undefined behaviour in MSL. To avoid this + // we use the following equation: + // + // dividend - (dividend / divisor) * divisor + // + // overriding the divisor to 1 if either it is 0, or it is -1 + // and the dividend is TYPE_MIN. + // + // This adheres to the WGSL spec in that: + // * TYPE_MIN % -1 == 0 + // * x % 0 == 0 + ( + crate::BinaryOperator::Modulo, + Some(crate::ScalarKind::Sint | crate::ScalarKind::Uint), + ) => { + let Some(left_wrapped_ty) = left_ty.vector_size_and_scalar() else { + return Ok(()); + }; + let Some((right_vector_size, right_scalar)) = right_ty.vector_size_and_scalar() + else { + return Ok(()); + }; + let wrapped = WrappedFunction::BinaryOp { + op, + left_ty: left_wrapped_ty, + right_ty: (right_vector_size, right_scalar), + }; + if !self.wrapped_functions.insert(wrapped) { + return Ok(()); + } - let Some((vector_size, scalar)) = expr_ty.vector_size_and_scalar() - else { - continue; - }; - let mut type_name = String::new(); - match vector_size { - None => put_numeric_type(&mut type_name, scalar, &[])?, - Some(size) => put_numeric_type(&mut type_name, scalar, &[size])?, - }; - let mut rhs_type_name = String::new(); - match right_vector_size { - None => put_numeric_type(&mut rhs_type_name, right_scalar, &[])?, - Some(size) => { - put_numeric_type(&mut rhs_type_name, right_scalar, &[size])? - } - }; + let Some((vector_size, scalar)) = expr_ty.vector_size_and_scalar() else { + return Ok(()); + }; + let mut type_name = String::new(); + match vector_size { + None => put_numeric_type(&mut type_name, scalar, &[])?, + Some(size) => put_numeric_type(&mut type_name, scalar, &[size])?, + }; + let mut rhs_type_name = String::new(); + match right_vector_size { + None => put_numeric_type(&mut rhs_type_name, right_scalar, &[])?, + Some(size) => put_numeric_type(&mut rhs_type_name, right_scalar, &[size])?, + }; - writeln!( - self.out, - "{type_name} {MOD_FUNCTION}({type_name} lhs, {type_name} rhs) {{" - )?; - let level = back::Level(1); - match scalar.kind { - crate::ScalarKind::Sint => { - let min_val = match scalar.width { - 4 => crate::Literal::I32(i32::MIN), - 8 => crate::Literal::I64(i64::MIN), - _ => { - return Err(Error::GenericValidation(format!( - "Unexpected width for scalar {scalar:?}" - ))); - } - }; - write!(self.out, "{level}{rhs_type_name} divisor = metal::select(rhs, 1, (lhs == ")?; - self.put_literal(min_val)?; - writeln!(self.out, " & rhs == -1) | (rhs == 0));")?; - writeln!( - self.out, - "{level}return lhs - (lhs / divisor) * divisor;" - )? - } - crate::ScalarKind::Uint => writeln!( - self.out, - "{level}return lhs % metal::select(rhs, 1u, rhs == 0u);" - )?, - _ => unreachable!(), + writeln!( + self.out, + "{type_name} {MOD_FUNCTION}({type_name} lhs, {type_name} rhs) {{" + )?; + let level = back::Level(1); + match scalar.kind { + crate::ScalarKind::Sint => { + let min_val = match scalar.width { + 4 => crate::Literal::I32(i32::MIN), + 8 => crate::Literal::I64(i64::MIN), + _ => { + return Err(Error::GenericValidation(format!( + "Unexpected width for scalar {scalar:?}" + ))); } - writeln!(self.out, "}}")?; - writeln!(self.out)?; - } - _ => {} + }; + write!( + self.out, + "{level}{rhs_type_name} divisor = metal::select(rhs, 1, (lhs == " + )?; + self.put_literal(min_val)?; + writeln!(self.out, " & rhs == -1) | (rhs == 0));")?; + writeln!(self.out, "{level}return lhs - (lhs / divisor) * divisor;")? } + crate::ScalarKind::Uint => writeln!( + self.out, + "{level}return lhs % metal::select(rhs, 1u, rhs == 0u);" + )?, + _ => unreachable!(), + } + writeln!(self.out, "}}")?; + writeln!(self.out)?; + } + _ => {} + } + Ok(()) + } + + #[allow(clippy::too_many_arguments)] + fn write_wrapped_math_function( + &mut self, + module: &crate::Module, + func_ctx: &back::FunctionCtx, + fun: crate::MathFunction, + arg: Handle, + _arg1: Option>, + _arg2: Option>, + _arg3: Option>, + ) -> BackendResult { + let arg_ty = func_ctx.resolve_type(arg, &module.types); + match fun { + // Taking the absolute value of the TYPE_MIN of a two's + // complement signed integer type causes overflow, which is + // undefined behaviour in MSL. To avoid this, when the value is + // negative we bitcast the value to unsigned and negate it, then + // bitcast back to signed. + // This adheres to the WGSL spec in that the absolute of the + // type's minimum value should equal to the minimum value. + crate::MathFunction::Abs if arg_ty.scalar_kind() == Some(crate::ScalarKind::Sint) => { + let Some((vector_size, scalar)) = arg_ty.vector_size_and_scalar() else { + return Ok(()); + }; + let wrapped = WrappedFunction::Math { + fun, + arg_ty: (vector_size, scalar), + }; + if !self.wrapped_functions.insert(wrapped) { + return Ok(()); + } + + let unsigned_scalar = crate::Scalar { + kind: crate::ScalarKind::Uint, + ..scalar + }; + let mut type_name = String::new(); + let mut unsigned_type_name = String::new(); + match vector_size { + None => { + put_numeric_type(&mut type_name, scalar, &[])?; + put_numeric_type(&mut unsigned_type_name, unsigned_scalar, &[])? + } + Some(size) => { + put_numeric_type(&mut type_name, scalar, &[size])?; + put_numeric_type(&mut unsigned_type_name, unsigned_scalar, &[size])?; + } + }; + + writeln!(self.out, "{type_name} {ABS_FUNCTION}({type_name} val) {{")?; + let level = back::Level(1); + writeln!(self.out, "{level}return metal::select(as_type<{type_name}>(-as_type<{unsigned_type_name}>(val)), val, val >= 0);")?; + writeln!(self.out, "}}")?; + writeln!(self.out)?; + } + _ => {} + } + Ok(()) + } + + fn write_wrapped_cast( + &mut self, + module: &crate::Module, + func_ctx: &back::FunctionCtx, + expr: Handle, + kind: crate::ScalarKind, + convert: Option, + ) -> BackendResult { + // Avoid undefined behaviour when casting from a float to integer + // when the value is out of range for the target type. Additionally + // ensure we clamp to the correct value as per the WGSL spec. + // + // https://www.w3.org/TR/WGSL/#floating-point-conversion: + // * If X is exactly representable in the target type T, then the + // result is that value. + // * Otherwise, the result is the value in T closest to + // truncate(X) and also exactly representable in the original + // floating point type. + let src_ty = func_ctx.resolve_type(expr, &module.types); + let Some(width) = convert else { + return Ok(()); + }; + let Some((vector_size, src_scalar)) = src_ty.vector_size_and_scalar() else { + return Ok(()); + }; + let dst_scalar = crate::Scalar { kind, width }; + if src_scalar.kind != crate::ScalarKind::Float + || (dst_scalar.kind != crate::ScalarKind::Sint + && dst_scalar.kind != crate::ScalarKind::Uint) + { + return Ok(()); + } + let wrapped = WrappedFunction::Cast { + src_scalar, + vector_size, + dst_scalar, + }; + if !self.wrapped_functions.insert(wrapped) { + return Ok(()); + } + let (min, max) = proc::min_max_float_representable_by(src_scalar, dst_scalar); + + let mut src_type_name = String::new(); + match vector_size { + None => put_numeric_type(&mut src_type_name, src_scalar, &[])?, + Some(size) => put_numeric_type(&mut src_type_name, src_scalar, &[size])?, + }; + let mut dst_type_name = String::new(); + match vector_size { + None => put_numeric_type(&mut dst_type_name, dst_scalar, &[])?, + Some(size) => put_numeric_type(&mut dst_type_name, dst_scalar, &[size])?, + }; + let fun_name = match dst_scalar { + crate::Scalar::I32 => F2I32_FUNCTION, + crate::Scalar::U32 => F2U32_FUNCTION, + crate::Scalar::I64 => F2I64_FUNCTION, + crate::Scalar::U64 => F2U64_FUNCTION, + _ => unreachable!(), + }; + + writeln!( + self.out, + "{dst_type_name} {fun_name}({src_type_name} value) {{" + )?; + let level = back::Level(1); + write!( + self.out, + "{level}return static_cast<{dst_type_name}>({NAMESPACE}::clamp(value, " + )?; + self.put_literal(min)?; + write!(self.out, ", ")?; + self.put_literal(max)?; + writeln!(self.out, "));")?; + writeln!(self.out, "}}")?; + writeln!(self.out)?; + Ok(()) + } + + #[allow(clippy::too_many_arguments)] + fn write_wrapped_image_sample( + &mut self, + _module: &crate::Module, + _func_ctx: &back::FunctionCtx, + _image: Handle, + _sampler: Handle, + _gather: Option, + _coordinate: Handle, + _array_index: Option>, + _offset: Option>, + _level: crate::SampleLevel, + _depth_ref: Option>, + clamp_to_edge: bool, + ) -> BackendResult { + if !clamp_to_edge { + return Ok(()); + } + let wrapped = WrappedFunction::ImageSample { + clamp_to_edge: true, + }; + if !self.wrapped_functions.insert(wrapped) { + return Ok(()); + } + + writeln!(self.out, "{NAMESPACE}::float4 {IMAGE_SAMPLE_BASE_CLAMP_TO_EDGE_FUNCTION}({NAMESPACE}::texture2d tex, {NAMESPACE}::sampler samp, {NAMESPACE}::float2 coords) {{")?; + let l1 = back::Level(1); + writeln!(self.out, "{l1}{NAMESPACE}::float2 half_texel = 0.5 / {NAMESPACE}::float2(tex.get_width(0u), tex.get_height(0u));")?; + writeln!( + self.out, + "{l1}return tex.sample(samp, {NAMESPACE}::clamp(coords, half_texel, 1.0 - half_texel), {NAMESPACE}::level(0.0));" + )?; + writeln!(self.out, "}}")?; + writeln!(self.out)?; + Ok(()) + } + + pub(super) fn write_wrapped_functions( + &mut self, + module: &crate::Module, + func_ctx: &back::FunctionCtx, + ) -> BackendResult { + for (expr_handle, expr) in func_ctx.expressions.iter() { + match *expr { + crate::Expression::Unary { op, expr: operand } => { + self.write_wrapped_unary_op(module, func_ctx, op, operand)?; + } + crate::Expression::Binary { op, left, right } => { + self.write_wrapped_binary_op(module, func_ctx, expr_handle, op, left, right)?; } crate::Expression::Math { fun, arg, - arg1: _, - arg2: _, - arg3: _, + arg1, + arg2, + arg3, } => { - let arg_ty = func_ctx.resolve_type(arg, &module.types); - match fun { - // Taking the absolute value of the TYPE_MIN of a two's - // complement signed integer type causes overflow, which is - // undefined behaviour in MSL. To avoid this, when the value is - // negative we bitcast the value to unsigned and negate it, then - // bitcast back to signed. - // This adheres to the WGSL spec in that the absolute of the - // type's minimum value should equal to the minimum value. - crate::MathFunction::Abs - if arg_ty.scalar_kind() == Some(crate::ScalarKind::Sint) => - { - let Some((vector_size, scalar)) = arg_ty.vector_size_and_scalar() - else { - continue; - }; - let wrapped = WrappedFunction::Math { - fun, - arg_ty: (vector_size, scalar), - }; - if !self.wrapped_functions.insert(wrapped) { - continue; - } - - let unsigned_scalar = crate::Scalar { - kind: crate::ScalarKind::Uint, - ..scalar - }; - let mut type_name = String::new(); - let mut unsigned_type_name = String::new(); - match vector_size { - None => { - put_numeric_type(&mut type_name, scalar, &[])?; - put_numeric_type(&mut unsigned_type_name, unsigned_scalar, &[])? - } - Some(size) => { - put_numeric_type(&mut type_name, scalar, &[size])?; - put_numeric_type( - &mut unsigned_type_name, - unsigned_scalar, - &[size], - )?; - } - }; - - writeln!(self.out, "{type_name} {ABS_FUNCTION}({type_name} val) {{")?; - let level = back::Level(1); - writeln!(self.out, "{level}return metal::select(as_type<{type_name}>(-as_type<{unsigned_type_name}>(val)), val, val >= 0);")?; - writeln!(self.out, "}}")?; - writeln!(self.out)?; - } - _ => {} - } + self.write_wrapped_math_function(module, func_ctx, fun, arg, arg1, arg2, arg3)?; } crate::Expression::As { expr, kind, - convert: Some(width), + convert, } => { - // Avoid undefined behaviour when casting from a float to integer - // when the value is out of range for the target type. Additionally - // ensure we clamp to the correct value as per the WGSL spec. - // - // https://www.w3.org/TR/WGSL/#floating-point-conversion: - // * If X is exactly representable in the target type T, then the - // result is that value. - // * Otherwise, the result is the value in T closest to - // truncate(X) and also exactly representable in the original - // floating point type. - let src_ty = func_ctx.resolve_type(expr, &module.types); - let Some((vector_size, src_scalar)) = src_ty.vector_size_and_scalar() else { - continue; - }; - let dst_scalar = crate::Scalar { kind, width }; - if src_scalar.kind != crate::ScalarKind::Float - || (dst_scalar.kind != crate::ScalarKind::Sint - && dst_scalar.kind != crate::ScalarKind::Uint) - { - continue; - } - let wrapped = WrappedFunction::Cast { - src_scalar, - vector_size, - dst_scalar, - }; - if !self.wrapped_functions.insert(wrapped) { - continue; - } - let (min, max) = proc::min_max_float_representable_by(src_scalar, dst_scalar); - - let mut src_type_name = String::new(); - match vector_size { - None => put_numeric_type(&mut src_type_name, src_scalar, &[])?, - Some(size) => put_numeric_type(&mut src_type_name, src_scalar, &[size])?, - }; - let mut dst_type_name = String::new(); - match vector_size { - None => put_numeric_type(&mut dst_type_name, dst_scalar, &[])?, - Some(size) => put_numeric_type(&mut dst_type_name, dst_scalar, &[size])?, - }; - let fun_name = match dst_scalar { - crate::Scalar::I32 => F2I32_FUNCTION, - crate::Scalar::U32 => F2U32_FUNCTION, - crate::Scalar::I64 => F2I64_FUNCTION, - crate::Scalar::U64 => F2U64_FUNCTION, - _ => unreachable!(), - }; - - writeln!( - self.out, - "{dst_type_name} {fun_name}({src_type_name} value) {{" - )?; - let level = back::Level(1); - write!( - self.out, - "{level}return static_cast<{dst_type_name}>({NAMESPACE}::clamp(value, " - )?; - self.put_literal(min)?; - write!(self.out, ", ")?; - self.put_literal(max)?; - writeln!(self.out, "));")?; - writeln!(self.out, "}}")?; - writeln!(self.out)?; + self.write_wrapped_cast(module, func_ctx, expr, kind, convert)?; } crate::Expression::ImageSample { - clamp_to_edge: true, - .. + image, + sampler, + gather, + coordinate, + array_index, + offset, + level, + depth_ref, + clamp_to_edge, } => { - let wrapped = WrappedFunction::ImageSample { - clamp_to_edge: true, - }; - if !self.wrapped_functions.insert(wrapped) { - continue; - } - - writeln!(self.out, "{NAMESPACE}::float4 {IMAGE_SAMPLE_BASE_CLAMP_TO_EDGE_FUNCTION}({NAMESPACE}::texture2d tex, {NAMESPACE}::sampler samp, {NAMESPACE}::float2 coords) {{")?; - let l1 = back::Level(1); - writeln!(self.out, "{l1}{NAMESPACE}::float2 half_texel = 0.5 / {NAMESPACE}::float2(tex.get_width(0u), tex.get_height(0u));")?; - writeln!( - self.out, - "{l1}return tex.sample(samp, {NAMESPACE}::clamp(coords, half_texel, 1.0 - half_texel), {NAMESPACE}::level(0.0));" + self.write_wrapped_image_sample( + module, + func_ctx, + image, + sampler, + gather, + coordinate, + array_index, + offset, + level, + depth_ref, + clamp_to_edge, )?; - writeln!(self.out, "}}")?; - writeln!(self.out)?; } _ => {} } From 2cada72dfb955a4aeada1b2652202ade26825f58 Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Thu, 14 Aug 2025 19:47:55 +0100 Subject: [PATCH 145/303] [naga] Make external texture snapshot test call textureLoad() with both vec2 and vec2 coordinates The HLSL external texture implementation didn't have to do anything in particular to handle both coordinate types, as int2 automatically gets promoted to uint2. But in MSL this is not the case, and it is therefore important to test that we correctly handle both coordinate types. --- naga/tests/in/wgsl/texture-external.wgsl | 7 +- .../tests/out/hlsl/wgsl-texture-external.hlsl | 18 +++-- .../out/ir/wgsl-texture-external.compact.ron | 66 ++++++++++++++----- naga/tests/out/ir/wgsl-texture-external.ron | 66 ++++++++++++++----- .../tests/out/wgsl/wgsl-texture-external.wgsl | 20 +++--- 5 files changed, 127 insertions(+), 50 deletions(-) diff --git a/naga/tests/in/wgsl/texture-external.wgsl b/naga/tests/in/wgsl/texture-external.wgsl index 086551ab440..3bc0a44acb6 100644 --- a/naga/tests/in/wgsl/texture-external.wgsl +++ b/naga/tests/in/wgsl/texture-external.wgsl @@ -5,10 +5,11 @@ var samp: sampler; fn test(t: texture_external) -> vec4 { var a = textureSampleBaseClampToEdge(t, samp, vec2(0.0f)); - var b = textureLoad(t, vec2(0u)); - var c = textureDimensions(t); + var b = textureLoad(t, vec2(0i)); + var c = textureLoad(t, vec2(0u)); + var d = textureDimensions(t); - return a + b + vec2f(c).xyxy; + return a + b + c + vec2f(d).xyxy; } @fragment diff --git a/naga/tests/out/hlsl/wgsl-texture-external.hlsl b/naga/tests/out/hlsl/wgsl-texture-external.hlsl index dbf57609d8b..59e8e62cd72 100644 --- a/naga/tests/out/hlsl/wgsl-texture-external.hlsl +++ b/naga/tests/out/hlsl/wgsl-texture-external.hlsl @@ -137,17 +137,21 @@ float4 test(Texture2D t_plane0_, Texture2D t_plane1_, Texture2D< { float4 a = (float4)0; float4 b = (float4)0; - uint2 c = (uint2)0; + float4 c = (float4)0; + uint2 d = (uint2)0; float4 _e4 = nagaTextureSampleBaseClampToEdge(t_plane0_, t_plane1_, t_plane2_, t_params, samp, (0.0).xx); a = _e4; - float4 _e8 = nagaTextureLoadExternal(t_plane0_, t_plane1_, t_plane2_, t_params, (0u).xx); + float4 _e8 = nagaTextureLoadExternal(t_plane0_, t_plane1_, t_plane2_, t_params, (int(0)).xx); b = _e8; - c = NagaExternalDimensions2D(t_plane0_, t_plane1_, t_plane2_, t_params); - float4 _e12 = a; - float4 _e13 = b; - uint2 _e15 = c; - return ((_e12 + _e13) + float2(_e15).xyxy); + float4 _e12 = nagaTextureLoadExternal(t_plane0_, t_plane1_, t_plane2_, t_params, (0u).xx); + c = _e12; + d = NagaExternalDimensions2D(t_plane0_, t_plane1_, t_plane2_, t_params); + float4 _e16 = a; + float4 _e17 = b; + float4 _e19 = c; + uint2 _e21 = d; + return (((_e16 + _e17) + _e19) + float2(_e21).xyxy); } float4 fragment_main() : SV_Target0 diff --git a/naga/tests/out/ir/wgsl-texture-external.compact.ron b/naga/tests/out/ir/wgsl-texture-external.compact.ron index dbffbddcdc7..2b9e1c8d5e4 100644 --- a/naga/tests/out/ir/wgsl-texture-external.compact.ron +++ b/naga/tests/out/ir/wgsl-texture-external.compact.ron @@ -230,6 +230,11 @@ ), ( name: Some("c"), + ty: 10, + init: None, + ), + ( + name: Some("d"), ty: 2, init: None, ), @@ -254,7 +259,7 @@ clamp_to_edge: true, ), LocalVariable(0), - Literal(U32(0)), + Literal(I32(0)), Splat( size: Bi, value: 6, @@ -267,13 +272,26 @@ level: None, ), LocalVariable(1), + Literal(U32(0)), + Splat( + size: Bi, + value: 10, + ), + ImageLoad( + image: 0, + coordinate: 11, + array_index: None, + sample: None, + level: None, + ), + LocalVariable(2), ImageQuery( image: 0, query: Size( level: None, ), ), - LocalVariable(2), + LocalVariable(3), Load( pointer: 5, ), @@ -282,26 +300,34 @@ ), Binary( op: Add, - left: 12, - right: 13, + left: 16, + right: 17, ), Load( - pointer: 11, + pointer: 13, + ), + Binary( + op: Add, + left: 18, + right: 19, + ), + Load( + pointer: 15, ), As( - expr: 15, + expr: 21, kind: Float, convert: Some(4), ), Swizzle( size: Quad, - vector: 16, + vector: 22, pattern: (X, Y, X, Y), ), Binary( op: Add, - left: 14, - right: 17, + left: 20, + right: 23, ), ], named_expressions: { @@ -325,19 +351,27 @@ value: 8, ), Emit(( - start: 10, - end: 11, + start: 11, + end: 13, )), Store( - pointer: 11, - value: 10, + pointer: 13, + value: 12, + ), + Emit(( + start: 14, + end: 15, + )), + Store( + pointer: 15, + value: 14, ), Emit(( - start: 12, - end: 19, + start: 16, + end: 25, )), Return( - value: Some(18), + value: Some(24), ), ], diagnostic_filter_leaf: None, diff --git a/naga/tests/out/ir/wgsl-texture-external.ron b/naga/tests/out/ir/wgsl-texture-external.ron index dbffbddcdc7..2b9e1c8d5e4 100644 --- a/naga/tests/out/ir/wgsl-texture-external.ron +++ b/naga/tests/out/ir/wgsl-texture-external.ron @@ -230,6 +230,11 @@ ), ( name: Some("c"), + ty: 10, + init: None, + ), + ( + name: Some("d"), ty: 2, init: None, ), @@ -254,7 +259,7 @@ clamp_to_edge: true, ), LocalVariable(0), - Literal(U32(0)), + Literal(I32(0)), Splat( size: Bi, value: 6, @@ -267,13 +272,26 @@ level: None, ), LocalVariable(1), + Literal(U32(0)), + Splat( + size: Bi, + value: 10, + ), + ImageLoad( + image: 0, + coordinate: 11, + array_index: None, + sample: None, + level: None, + ), + LocalVariable(2), ImageQuery( image: 0, query: Size( level: None, ), ), - LocalVariable(2), + LocalVariable(3), Load( pointer: 5, ), @@ -282,26 +300,34 @@ ), Binary( op: Add, - left: 12, - right: 13, + left: 16, + right: 17, ), Load( - pointer: 11, + pointer: 13, + ), + Binary( + op: Add, + left: 18, + right: 19, + ), + Load( + pointer: 15, ), As( - expr: 15, + expr: 21, kind: Float, convert: Some(4), ), Swizzle( size: Quad, - vector: 16, + vector: 22, pattern: (X, Y, X, Y), ), Binary( op: Add, - left: 14, - right: 17, + left: 20, + right: 23, ), ], named_expressions: { @@ -325,19 +351,27 @@ value: 8, ), Emit(( - start: 10, - end: 11, + start: 11, + end: 13, )), Store( - pointer: 11, - value: 10, + pointer: 13, + value: 12, + ), + Emit(( + start: 14, + end: 15, + )), + Store( + pointer: 15, + value: 14, ), Emit(( - start: 12, - end: 19, + start: 16, + end: 25, )), Return( - value: Some(18), + value: Some(24), ), ], diagnostic_filter_leaf: None, diff --git a/naga/tests/out/wgsl/wgsl-texture-external.wgsl b/naga/tests/out/wgsl/wgsl-texture-external.wgsl index d165fa25905..329895ec88e 100644 --- a/naga/tests/out/wgsl/wgsl-texture-external.wgsl +++ b/naga/tests/out/wgsl/wgsl-texture-external.wgsl @@ -6,18 +6,22 @@ var samp: sampler; fn test(t: texture_external) -> vec4 { var a: vec4; var b: vec4; - var c: vec2; + var c: vec4; + var d: vec2; let _e4 = textureSampleBaseClampToEdge(t, samp, vec2(0f)); a = _e4; - let _e8 = textureLoad(t, vec2(0u)); + let _e8 = textureLoad(t, vec2(0i)); b = _e8; - let _e10 = textureDimensions(t); - c = _e10; - let _e12 = a; - let _e13 = b; - let _e15 = c; - return ((_e12 + _e13) + vec2(_e15).xyxy); + let _e12 = textureLoad(t, vec2(0u)); + c = _e12; + let _e14 = textureDimensions(t); + d = _e14; + let _e16 = a; + let _e17 = b; + let _e19 = c; + let _e21 = d; + return (((_e16 + _e17) + _e19) + vec2(_e21).xyxy); } @fragment From 2c6f06a82b9a90df6d6988b86a5df67a36b1f406 Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Mon, 9 Jun 2025 16:14:02 +0100 Subject: [PATCH 146/303] [naga msl-out] Implement support for external textures This adds MSL backend support for `ImageClass::External`. (ie WGSL's `external_texture` texture type). This is implemented very similarily to the HLSL implementation in #7826. Each external texture global variable is lowered to 3 `texture2d`s and a buffer of type NagaExternalTextureParams. As usual in Naga's MSL backend, these are passed as arguments to the entry point. The bindings for each of these arguments are provided via the usual binding map, using a new `BindExternalTextureTarget` variant of `BindTarget`. Unlike HLSL, MSL allows textures to be used as fields in structs. We therefore immediately wrap these variables in a `NagaExternalTextureWrapper` struct. This wrapper can then conveniently be passed to either user-defined functions or builtin implementations that accept an external texture. The WGSL builtins `textureDimensions()`, `textureLoad()`, and `textureSampleBaseClampToEdge()` are implemented using wrapper functions using the regular `write_wrapped_functions()` machinery. --- naga-cli/src/bin/naga.rs | 2 +- naga/src/back/msl/keywords.rs | 3 + naga/src/back/msl/mod.rs | 37 ++ naga/src/back/msl/writer.rs | 518 +++++++++++++++++-- naga/tests/in/wgsl/texture-external.toml | 32 +- naga/tests/out/msl/wgsl-texture-external.msl | 190 +++++++ 6 files changed, 748 insertions(+), 34 deletions(-) create mode 100644 naga/tests/out/msl/wgsl-texture-external.msl diff --git a/naga-cli/src/bin/naga.rs b/naga-cli/src/bin/naga.rs index 44369e9df7d..bbdc63fad5b 100644 --- a/naga-cli/src/bin/naga.rs +++ b/naga-cli/src/bin/naga.rs @@ -538,7 +538,7 @@ fn run() -> anyhow::Result<()> { use naga::valid::Capabilities as C; let missing = match Path::new(path).extension().and_then(|ex| ex.to_str()) { Some("wgsl") => C::CLIP_DISTANCE | C::CULL_DISTANCE, - Some("metal") => C::CULL_DISTANCE | C::TEXTURE_EXTERNAL, + Some("metal") => C::CULL_DISTANCE, Some("hlsl") => C::empty(), _ => C::TEXTURE_EXTERNAL, }; diff --git a/naga/src/back/msl/keywords.rs b/naga/src/back/msl/keywords.rs index 512ccd91235..e4f89bdc002 100644 --- a/naga/src/back/msl/keywords.rs +++ b/naga/src/back/msl/keywords.rs @@ -353,8 +353,11 @@ pub const RESERVED: &[&str] = &[ super::writer::F2U32_FUNCTION, super::writer::F2I64_FUNCTION, super::writer::F2U64_FUNCTION, + super::writer::IMAGE_LOAD_EXTERNAL_FUNCTION, super::writer::IMAGE_SAMPLE_BASE_CLAMP_TO_EDGE_FUNCTION, + super::writer::IMAGE_SIZE_EXTERNAL_FUNCTION, super::writer::ARGUMENT_BUFFER_WRAPPER_STRUCT, + super::writer::EXTERNAL_TEXTURE_WRAPPER_STRUCT, ]; /// The above set of reserved keywords, turned into a cached HashSet. This saves diff --git a/naga/src/back/msl/mod.rs b/naga/src/back/msl/mod.rs index 7bc8289b9b8..7e9180e0c25 100644 --- a/naga/src/back/msl/mod.rs +++ b/naga/src/back/msl/mod.rs @@ -43,6 +43,29 @@ additional effort and the difference is unlikely to matter.) [`BoundsCheckPolicy`]: crate::proc::BoundsCheckPolicy +## External textures + +Support for [`crate::ImageClass::External`] textures is implemented by lowering +each external texture global variable to 3 `texture2d`s, and a +constant buffer of type `NagaExternalTextureParams`. This provides up to 3 +planes of texture data (for example single planar RGBA, or separate Y, Cb, and +Cr planes), and the parameters buffer containing information describing how to +handle these correctly. The bind target to use for each of these globals is +specified via the [`BindTarget::external_texture`] field of the relevant +entries in [`EntryPointResources::resources`]. + +External textures are supported by WGSL's `textureDimensions()`, +`textureLoad()`, and `textureSampleBaseClampToEdge()` built-in functions. These +are implemented using helper functions. See the following functions for how +these are generated: + * `Writer::write_wrapped_image_query` + * `Writer::write_wrapped_image_load` + * `Writer::write_wrapped_image_sample` + +The lowered global variables for each external texture global are passed to the +entry point as separate arguments (see "Entry points" above). However, they are +then wrapped in a struct to allow them to be conveniently passed to user +defined and helper functions. See `writer::EXTERNAL_TEXTURE_WRAPPER_STRUCT`. */ use alloc::{ @@ -71,6 +94,19 @@ pub enum BindSamplerTarget { Inline(InlineSamplerIndex), } +/// Binding information for a Naga [`External`] image global variable. +/// +/// See the module documentation's section on external textures for details. +/// +/// [`External`]: crate::ir::ImageClass::External +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serialize", derive(serde::Serialize))] +#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] +pub struct BindExternalTextureTarget { + pub planes: [Slot; 3], + pub params: Slot, +} + #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serialize", derive(serde::Serialize))] #[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] @@ -79,6 +115,7 @@ pub struct BindTarget { pub buffer: Option, pub texture: Option, pub sampler: Option, + pub external_texture: Option, pub mutable: bool, } diff --git a/naga/src/back/msl/writer.rs b/naga/src/back/msl/writer.rs index e5e5526d7ea..9c0ac10d160 100644 --- a/naga/src/back/msl/writer.rs +++ b/naga/src/back/msl/writer.rs @@ -21,7 +21,7 @@ use crate::{ proc::{ self, index::{self, BoundsCheck}, - NameKey, TypeResolution, + ExternalTextureNameKey, NameKey, TypeResolution, }, valid, FastHashMap, FastHashSet, }; @@ -61,6 +61,8 @@ pub(crate) const F2I32_FUNCTION: &str = "naga_f2i32"; pub(crate) const F2U32_FUNCTION: &str = "naga_f2u32"; pub(crate) const F2I64_FUNCTION: &str = "naga_f2i64"; pub(crate) const F2U64_FUNCTION: &str = "naga_f2u64"; +pub(crate) const IMAGE_LOAD_EXTERNAL_FUNCTION: &str = "nagaTextureLoadExternal"; +pub(crate) const IMAGE_SIZE_EXTERNAL_FUNCTION: &str = "nagaTextureDimensionsExternal"; pub(crate) const IMAGE_SAMPLE_BASE_CLAMP_TO_EDGE_FUNCTION: &str = "nagaTextureSampleBaseClampToEdge"; /// For some reason, Metal does not let you have `metal::texture<..>*` as a buffer argument. @@ -71,6 +73,11 @@ pub(crate) const IMAGE_SAMPLE_BASE_CLAMP_TO_EDGE_FUNCTION: &str = /// This allows `NagaArgumentBufferWrapper>*` to work. The astute among /// you have noticed that this should be exactly the same to the compiler, and you're correct. pub(crate) const ARGUMENT_BUFFER_WRAPPER_STRUCT: &str = "NagaArgumentBufferWrapper"; +/// Name of the struct that is declared to wrap the 3 textures and parameters +/// buffer that [`crate::ImageClass::External`] variables are lowered to, +/// allowing them to be conveniently passed to user-defined or wrapper +/// functions. The struct is declared in [`Writer::write_type_defs`]. +pub(crate) const EXTERNAL_TEXTURE_WRAPPER_STRUCT: &str = "NagaExternalTextureWrapper"; /// Write the Metal name for a Naga numeric type: scalar, vector, or matrix. /// @@ -321,7 +328,9 @@ impl Display for TypeContext<'_> { }; ("texture", "", format.into(), access) } - crate::ImageClass::External => unimplemented!(), + crate::ImageClass::External => { + return write!(out, "{EXTERNAL_TEXTURE_WRAPPER_STRUCT}"); + } }; let base_name = scalar.to_msl_name(); let array_str = if arrayed { "_array" } else { "" }; @@ -449,9 +458,16 @@ enum WrappedFunction { vector_size: Option, dst_scalar: crate::Scalar, }, + ImageLoad { + class: crate::ImageClass, + }, ImageSample { + class: crate::ImageClass, clamp_to_edge: bool, }, + ImageQuerySize { + class: crate::ImageClass, + }, } pub struct Writer { @@ -1064,6 +1080,17 @@ impl Writer { kind: crate::ScalarKind, context: &ExpressionContext, ) -> BackendResult { + if let crate::TypeInner::Image { + class: crate::ImageClass::External, + .. + } = *context.resolve_type(image) + { + write!(self.out, "{IMAGE_SIZE_EXTERNAL_FUNCTION}(")?; + self.put_expression(image, context, true)?; + write!(self.out, ")")?; + return Ok(()); + } + //Note: MSL only has separate width/height/depth queries, // so compose the result of them. let dim = match *context.resolve_type(image) { @@ -1321,6 +1348,19 @@ impl Writer { mut address: TexelAddress, context: &ExpressionContext, ) -> BackendResult { + if let crate::TypeInner::Image { + class: crate::ImageClass::External, + .. + } = *context.resolve_type(image) + { + write!(self.out, "{IMAGE_LOAD_EXTERNAL_FUNCTION}(")?; + self.put_expression(image, context, true)?; + write!(self.out, ", ")?; + self.put_cast_to_uint_scalar_or_vector(address.coordinate, context)?; + write!(self.out, ")")?; + return Ok(()); + } + match context.policies.image_load { proc::BoundsCheckPolicy::Restrict => { // Use the cached restricted level of detail, if any. Omit the @@ -4387,15 +4427,43 @@ impl Writer { fn write_type_defs(&mut self, module: &crate::Module) -> BackendResult { let mut generated_argument_buffer_wrapper = false; + let mut generated_external_texture_wrapper = false; for (handle, ty) in module.types.iter() { - if let crate::TypeInner::BindingArray { .. } = ty.inner { - if !generated_argument_buffer_wrapper { + match ty.inner { + crate::TypeInner::BindingArray { .. } if !generated_argument_buffer_wrapper => { writeln!(self.out, "template ")?; writeln!(self.out, "struct {ARGUMENT_BUFFER_WRAPPER_STRUCT} {{")?; writeln!(self.out, "{}T {WRAPPED_ARRAY_FIELD};", back::INDENT)?; writeln!(self.out, "}};")?; generated_argument_buffer_wrapper = true; } + crate::TypeInner::Image { + class: crate::ImageClass::External, + .. + } if !generated_external_texture_wrapper => { + let params_ty_name = &self.names + [&NameKey::Type(module.special_types.external_texture_params.unwrap())]; + writeln!(self.out, "struct {EXTERNAL_TEXTURE_WRAPPER_STRUCT} {{")?; + writeln!( + self.out, + "{}{NAMESPACE}::texture2d plane0;", + back::INDENT + )?; + writeln!( + self.out, + "{}{NAMESPACE}::texture2d plane1;", + back::INDENT + )?; + writeln!( + self.out, + "{}{NAMESPACE}::texture2d plane2;", + back::INDENT + )?; + writeln!(self.out, "{}{params_ty_name} params;", back::INDENT)?; + writeln!(self.out, "}};")?; + generated_external_texture_wrapper = true; + } + _ => {} } if !ty.needs_alias() { @@ -5873,12 +5941,149 @@ template Ok(()) } + /// Helper function used by [`Self::write_wrapped_image_load`] and + /// [`Self::write_wrapped_image_sample`] to write the shared YUV to RGB + /// conversion code for external textures. Expects the preceding code to + /// declare the Y component as a `float` variable of name `y`, the UV + /// components as a `float2` variable of name `uv`, and the external + /// texture params as a variable of name `params`. The emitted code will + /// return the result. + fn write_convert_yuv_to_rgb_and_return( + &mut self, + level: back::Level, + y: &str, + uv: &str, + params: &str, + ) -> BackendResult { + let l1 = level; + let l2 = l1.next(); + + // Convert from YUV to non-linear RGB in the source color space. + writeln!( + self.out, + "{l1}float3 srcGammaRgb = ({params}.yuv_conversion_matrix * float4({y}, {uv}, 1.0)).rgb;" + )?; + + // Apply the inverse of the source transfer function to convert to + // linear RGB in the source color space. + writeln!(self.out, "{l1}float3 srcLinearRgb = {NAMESPACE}::select(")?; + writeln!(self.out, "{l2}{NAMESPACE}::pow((srcGammaRgb + {params}.src_tf.a - 1.0) / {params}.src_tf.a, {params}.src_tf.g),")?; + writeln!(self.out, "{l2}srcGammaRgb / {params}.src_tf.k,")?; + writeln!( + self.out, + "{l2}srcGammaRgb < {params}.src_tf.k * {params}.src_tf.b);" + )?; + + // Multiply by the gamut conversion matrix to convert to linear RGB in + // the destination color space. + writeln!( + self.out, + "{l1}float3 dstLinearRgb = {params}.gamut_conversion_matrix * srcLinearRgb;" + )?; + + // Finally, apply the dest transfer function to convert to non-linear + // RGB in the destination color space, and return the result. + writeln!(self.out, "{l1}float3 dstGammaRgb = {NAMESPACE}::select(")?; + writeln!(self.out, "{l2}{params}.dst_tf.a * {NAMESPACE}::pow(dstLinearRgb, 1.0 / {params}.dst_tf.g) - ({params}.dst_tf.a - 1),")?; + writeln!(self.out, "{l2}{params}.dst_tf.k * dstLinearRgb,")?; + writeln!(self.out, "{l2}dstLinearRgb < {params}.dst_tf.b);")?; + + writeln!(self.out, "{l1}return float4(dstGammaRgb, 1.0);")?; + Ok(()) + } + + #[allow(clippy::too_many_arguments)] + fn write_wrapped_image_load( + &mut self, + module: &crate::Module, + func_ctx: &back::FunctionCtx, + image: Handle, + _coordinate: Handle, + _array_index: Option>, + _sample: Option>, + _level: Option>, + ) -> BackendResult { + // We currently only need to wrap image loads for external textures + let class = match *func_ctx.resolve_type(image, &module.types) { + crate::TypeInner::Image { class, .. } => class, + _ => unreachable!(), + }; + if class != crate::ImageClass::External { + return Ok(()); + } + let wrapped = WrappedFunction::ImageLoad { class }; + if !self.wrapped_functions.insert(wrapped) { + return Ok(()); + } + + writeln!(self.out, "float4 {IMAGE_LOAD_EXTERNAL_FUNCTION}({EXTERNAL_TEXTURE_WRAPPER_STRUCT} tex, uint2 coords) {{")?; + let l1 = back::Level(1); + let l2 = l1.next(); + let l3 = l2.next(); + writeln!( + self.out, + "{l1}uint2 plane0_size = uint2(tex.plane0.get_width(), tex.plane0.get_height());" + )?; + // Clamp coords to provided size of external texture to prevent OOB + // read. If params.size is zero then clamp to the actual size of the + // texture. + writeln!( + self.out, + "{l1}uint2 cropped_size = {NAMESPACE}::any(tex.params.size != 0) ? tex.params.size : plane0_size;" + )?; + writeln!( + self.out, + "{l1}coords = {NAMESPACE}::min(coords, cropped_size - 1);" + )?; + + // Apply load transformation + writeln!(self.out, "{l1}uint2 plane0_coords = uint2({NAMESPACE}::round(tex.params.load_transform * float3(float2(coords), 1.0)));")?; + writeln!(self.out, "{l1}if (tex.params.num_planes == 1u) {{")?; + // For single plane, simply read from plane0 + writeln!(self.out, "{l2}return tex.plane0.read(plane0_coords);")?; + writeln!(self.out, "{l1}}} else {{")?; + + // Chroma planes may be subsampled so we must scale the coords accordingly. + writeln!( + self.out, + "{l2}uint2 plane1_size = uint2(tex.plane1.get_width(), tex.plane1.get_height());" + )?; + writeln!(self.out, "{l2}uint2 plane1_coords = uint2({NAMESPACE}::floor(float2(plane0_coords) * float2(plane1_size) / float2(plane0_size)));")?; + + // For multi-plane, read the Y value from plane 0 + writeln!(self.out, "{l2}float y = tex.plane0.read(plane0_coords).x;")?; + + writeln!(self.out, "{l2}float2 uv;")?; + writeln!(self.out, "{l2}if (tex.params.num_planes == 2u) {{")?; + // For 2 planes, read UV from interleaved plane 1 + writeln!(self.out, "{l3}uv = tex.plane1.read(plane1_coords).xy;")?; + writeln!(self.out, "{l2}}} else {{")?; + // For 3 planes, read U and V from planes 1 and 2 respectively + writeln!( + self.out, + "{l2}uint2 plane2_size = uint2(tex.plane2.get_width(), tex.plane2.get_height());" + )?; + writeln!(self.out, "{l2}uint2 plane2_coords = uint2({NAMESPACE}::floor(float2(plane0_coords) * float2(plane2_size) / float2(plane0_size)));")?; + writeln!( + self.out, + "{l3}uv = float2(tex.plane1.read(plane1_coords).x, tex.plane2.read(plane2_coords).x);" + )?; + writeln!(self.out, "{l2}}}")?; + + self.write_convert_yuv_to_rgb_and_return(l2, "y", "uv", "tex.params")?; + + writeln!(self.out, "{l1}}}")?; + writeln!(self.out, "}}")?; + writeln!(self.out)?; + Ok(()) + } + #[allow(clippy::too_many_arguments)] fn write_wrapped_image_sample( &mut self, - _module: &crate::Module, - _func_ctx: &back::FunctionCtx, - _image: Handle, + module: &crate::Module, + func_ctx: &back::FunctionCtx, + image: Handle, _sampler: Handle, _gather: Option, _coordinate: Handle, @@ -5888,23 +6093,163 @@ template _depth_ref: Option>, clamp_to_edge: bool, ) -> BackendResult { + // We currently only need to wrap textureSampleBaseClampToEdge, for + // both sampled and external textures. if !clamp_to_edge { return Ok(()); } + let class = match *func_ctx.resolve_type(image, &module.types) { + crate::TypeInner::Image { class, .. } => class, + _ => unreachable!(), + }; let wrapped = WrappedFunction::ImageSample { + class, clamp_to_edge: true, }; if !self.wrapped_functions.insert(wrapped) { return Ok(()); } + match class { + crate::ImageClass::External => { + writeln!(self.out, "float4 {IMAGE_SAMPLE_BASE_CLAMP_TO_EDGE_FUNCTION}({EXTERNAL_TEXTURE_WRAPPER_STRUCT} tex, {NAMESPACE}::sampler samp, float2 coords) {{")?; + let l1 = back::Level(1); + let l2 = l1.next(); + let l3 = l2.next(); + writeln!(self.out, "{l1}uint2 plane0_size = uint2(tex.plane0.get_width(), tex.plane0.get_height());")?; + writeln!( + self.out, + "{l1}coords = tex.params.sample_transform * float3(coords, 1.0);" + )?; + + // Calculate the sample bounds. The purported size of the texture + // (params.size) is irrelevant here as we are dealing with normalized + // coordinates. Usually we would clamp to (0,0)..(1,1). However, we must + // apply the sample transformation to that, also bearing in mind that it + // may contain a flip on either axis. We calculate and adjust for the + // half-texel separately for each plane as it depends on the actual + // texture size which may vary between planes. + writeln!( + self.out, + "{l1}float2 bounds_min = tex.params.sample_transform * float3(0.0, 0.0, 1.0);" + )?; + writeln!( + self.out, + "{l1}float2 bounds_max = tex.params.sample_transform * float3(1.0, 1.0, 1.0);" + )?; + writeln!(self.out, "{l1}float4 bounds = float4({NAMESPACE}::min(bounds_min, bounds_max), {NAMESPACE}::max(bounds_min, bounds_max));")?; + writeln!( + self.out, + "{l1}float2 plane0_half_texel = float2(0.5, 0.5) / float2(plane0_size);" + )?; + writeln!( + self.out, + "{l1}float2 plane0_coords = {NAMESPACE}::clamp(coords, bounds.xy + plane0_half_texel, bounds.zw - plane0_half_texel);" + )?; + writeln!(self.out, "{l1}if (tex.params.num_planes == 1u) {{")?; + // For single plane, simply sample from plane0 + writeln!( + self.out, + "{l2}return tex.plane0.sample(samp, plane0_coords, {NAMESPACE}::level(0.0f));" + )?; + writeln!(self.out, "{l1}}} else {{")?; + writeln!(self.out, "{l2}uint2 plane1_size = uint2(tex.plane1.get_width(), tex.plane1.get_height());")?; + writeln!( + self.out, + "{l2}float2 plane1_half_texel = float2(0.5, 0.5) / float2(plane1_size);" + )?; + writeln!( + self.out, + "{l2}float2 plane1_coords = {NAMESPACE}::clamp(coords, bounds.xy + plane1_half_texel, bounds.zw - plane1_half_texel);" + )?; + + // For multi-plane, sample the Y value from plane 0 + writeln!( + self.out, + "{l2}float y = tex.plane0.sample(samp, plane0_coords, {NAMESPACE}::level(0.0f)).r;" + )?; + writeln!(self.out, "{l2}float2 uv = float2(0.0, 0.0);")?; + writeln!(self.out, "{l2}if (tex.params.num_planes == 2u) {{")?; + // For 2 planes, sample UV from interleaved plane 1 + writeln!( + self.out, + "{l3}uv = tex.plane1.sample(samp, plane1_coords, {NAMESPACE}::level(0.0f)).xy;" + )?; + writeln!(self.out, "{l2}}} else {{")?; + // For 3 planes, sample U and V from planes 1 and 2 respectively + writeln!(self.out, "{l3}uint2 plane2_size = uint2(tex.plane2.get_width(), tex.plane2.get_height());")?; + writeln!( + self.out, + "{l3}float2 plane2_half_texel = float2(0.5, 0.5) / float2(plane2_size);" + )?; + writeln!( + self.out, + "{l3}float2 plane2_coords = {NAMESPACE}::clamp(coords, bounds.xy + plane2_half_texel, bounds.zw - plane1_half_texel);" + )?; + writeln!(self.out, "{l3}uv.x = tex.plane1.sample(samp, plane1_coords, {NAMESPACE}::level(0.0f)).x;")?; + writeln!(self.out, "{l3}uv.y = tex.plane2.sample(samp, plane2_coords, {NAMESPACE}::level(0.0f)).x;")?; + writeln!(self.out, "{l2}}}")?; + + self.write_convert_yuv_to_rgb_and_return(l2, "y", "uv", "tex.params")?; + + writeln!(self.out, "{l1}}}")?; + writeln!(self.out, "}}")?; + writeln!(self.out)?; + } + _ => { + writeln!(self.out, "{NAMESPACE}::float4 {IMAGE_SAMPLE_BASE_CLAMP_TO_EDGE_FUNCTION}({NAMESPACE}::texture2d tex, {NAMESPACE}::sampler samp, {NAMESPACE}::float2 coords) {{")?; + let l1 = back::Level(1); + writeln!(self.out, "{l1}{NAMESPACE}::float2 half_texel = 0.5 / {NAMESPACE}::float2(tex.get_width(0u), tex.get_height(0u));")?; + writeln!( + self.out, + "{l1}return tex.sample(samp, {NAMESPACE}::clamp(coords, half_texel, 1.0 - half_texel), {NAMESPACE}::level(0.0));" + )?; + writeln!(self.out, "}}")?; + writeln!(self.out)?; + } + } + Ok(()) + } - writeln!(self.out, "{NAMESPACE}::float4 {IMAGE_SAMPLE_BASE_CLAMP_TO_EDGE_FUNCTION}({NAMESPACE}::texture2d tex, {NAMESPACE}::sampler samp, {NAMESPACE}::float2 coords) {{")?; + fn write_wrapped_image_query( + &mut self, + module: &crate::Module, + func_ctx: &back::FunctionCtx, + image: Handle, + query: crate::ImageQuery, + ) -> BackendResult { + // We currently only need to wrap size image queries for external textures + if !matches!(query, crate::ImageQuery::Size { .. }) { + return Ok(()); + } + let class = match *func_ctx.resolve_type(image, &module.types) { + crate::TypeInner::Image { class, .. } => class, + _ => unreachable!(), + }; + if class != crate::ImageClass::External { + return Ok(()); + } + let wrapped = WrappedFunction::ImageQuerySize { class }; + if !self.wrapped_functions.insert(wrapped) { + return Ok(()); + } + writeln!( + self.out, + "uint2 {IMAGE_SIZE_EXTERNAL_FUNCTION}({EXTERNAL_TEXTURE_WRAPPER_STRUCT} tex) {{" + )?; let l1 = back::Level(1); - writeln!(self.out, "{l1}{NAMESPACE}::float2 half_texel = 0.5 / {NAMESPACE}::float2(tex.get_width(0u), tex.get_height(0u));")?; + let l2 = l1.next(); writeln!( self.out, - "{l1}return tex.sample(samp, {NAMESPACE}::clamp(coords, half_texel, 1.0 - half_texel), {NAMESPACE}::level(0.0));" + "{l1}if ({NAMESPACE}::any(tex.params.size != uint2(0u))) {{" )?; + writeln!(self.out, "{l2}return tex.params.size;")?; + writeln!(self.out, "{l1}}} else {{")?; + // params.size == (0, 0) indicates to query and return plane 0's actual size + writeln!( + self.out, + "{l2}return uint2(tex.plane0.get_width(), tex.plane0.get_height());" + )?; + writeln!(self.out, "{l1}}}")?; writeln!(self.out, "}}")?; writeln!(self.out)?; Ok(()) @@ -5939,6 +6284,23 @@ template } => { self.write_wrapped_cast(module, func_ctx, expr, kind, convert)?; } + crate::Expression::ImageLoad { + image, + coordinate, + array_index, + sample, + level, + } => { + self.write_wrapped_image_load( + module, + func_ctx, + image, + coordinate, + array_index, + sample, + level, + )?; + } crate::Expression::ImageSample { image, sampler, @@ -5964,6 +6326,9 @@ template clamp_to_edge, )?; } + crate::Expression::ImageQuery { image, query } => { + self.write_wrapped_image_query(module, func_ctx, image, query)?; + } _ => {} } } @@ -6293,6 +6658,10 @@ template // so that binding arrays fall to the buffer location. match module.types[var.ty].inner { + crate::TypeInner::Image { + class: crate::ImageClass::External, + .. + } => target.external_texture.is_some(), crate::TypeInner::Image { .. } => target.texture.is_some(), crate::TypeInner::Sampler { .. } => { target.sampler.is_some() @@ -6719,7 +7088,11 @@ template "read-write textures".to_string(), )); } - crate::ImageClass::External => unimplemented!(), + crate::ImageClass::External => { + return Err(Error::UnsupportedArrayOf( + "external textures".to_string(), + )); + } }, _ => { return Err(Error::UnsupportedArrayOfType(base)); @@ -6746,27 +7119,81 @@ template } } - let tyvar = TypedGlobalVariable { - module, - names: &self.names, - handle, - usage, - reference: true, - }; - let separator = if is_first_argument { - is_first_argument = false; - ' ' - } else { - ',' + let mut separator = || { + if is_first_argument { + is_first_argument = false; + ' ' + } else { + ',' + } }; - write!(self.out, "{separator} ")?; - tyvar.try_fmt(&mut self.out)?; - if let Some(resolved) = resolved { - resolved.try_fmt(&mut self.out)?; - } - if let Some(value) = var.init { - write!(self.out, " = ")?; - self.put_const_expression(value, module, mod_info, &module.global_expressions)?; + + match module.types[var.ty].inner { + crate::TypeInner::Image { + class: crate::ImageClass::External, + .. + } => { + // External texture global variables get lowered to 3 textures + // and a constant buffer. We must emit a separate argument for + // each of these. + let target = match resolved { + Some(back::msl::ResolvedBinding::Resource(target)) => { + target.external_texture + } + _ => None, + }; + + for i in 0..3 { + write!(self.out, "{} ", separator())?; + + let plane_name = &self.names[&NameKey::ExternalTextureGlobalVariable( + handle, + ExternalTextureNameKey::Plane(i), + )]; + write!( + self.out, + "{NAMESPACE}::texture2d {plane_name}" + )?; + if let Some(ref target) = target { + write!(self.out, " [[texture({})]]", target.planes[i])?; + } + writeln!(self.out)?; + } + let params_ty_name = &self.names + [&NameKey::Type(module.special_types.external_texture_params.unwrap())]; + let params_name = &self.names[&NameKey::ExternalTextureGlobalVariable( + handle, + ExternalTextureNameKey::Params, + )]; + write!(self.out, "{} ", separator())?; + write!(self.out, "constant {params_ty_name}& {params_name}")?; + if let Some(ref target) = target { + write!(self.out, " [[buffer({})]]", target.params)?; + } + } + _ => { + let tyvar = TypedGlobalVariable { + module, + names: &self.names, + handle, + usage, + reference: true, + }; + write!(self.out, "{} ", separator())?; + tyvar.try_fmt(&mut self.out)?; + if let Some(resolved) = resolved { + resolved.try_fmt(&mut self.out)?; + } + if let Some(value) = var.init { + write!(self.out, " = ")?; + self.put_const_expression( + value, + module, + mod_info, + &module.global_expressions, + )?; + } + } } writeln!(self.out)?; } @@ -7008,9 +7435,9 @@ template } }; } else if let Some(ref binding) = var.binding { - // write an inline sampler let resolved = options.resolve_resource_binding(ep, binding).unwrap(); if let Some(sampler) = resolved.as_inline_sampler(options) { + // write an inline sampler let name = &self.names[&NameKey::GlobalVariable(handle)]; writeln!( self.out, @@ -7021,6 +7448,33 @@ template )?; self.put_inline_sampler_properties(back::Level(2), sampler)?; writeln!(self.out, "{});", back::INDENT)?; + } else if let crate::TypeInner::Image { + class: crate::ImageClass::External, + .. + } = module.types[var.ty].inner + { + // Wrap the individual arguments for each external texture global + // in a struct which can be easily passed around. + let wrapper_name = &self.names[&NameKey::GlobalVariable(handle)]; + let l1 = back::Level(1); + let l2 = l1.next(); + writeln!( + self.out, + "{l1}const {EXTERNAL_TEXTURE_WRAPPER_STRUCT} {wrapper_name} {{" + )?; + for i in 0..3 { + let plane_name = &self.names[&NameKey::ExternalTextureGlobalVariable( + handle, + ExternalTextureNameKey::Plane(i), + )]; + writeln!(self.out, "{l2}.plane{i} = {plane_name},")?; + } + let params_name = &self.names[&NameKey::ExternalTextureGlobalVariable( + handle, + ExternalTextureNameKey::Params, + )]; + writeln!(self.out, "{l2}.params = {params_name},")?; + writeln!(self.out, "{l1}}};")?; } } } diff --git a/naga/tests/in/wgsl/texture-external.toml b/naga/tests/in/wgsl/texture-external.toml index 3ea75be88d2..3a44f0265ab 100644 --- a/naga/tests/in/wgsl/texture-external.toml +++ b/naga/tests/in/wgsl/texture-external.toml @@ -1,5 +1,35 @@ god_mode = true -targets = "HLSL | IR | WGSL" +targets = "HLSL | IR | METAL | WGSL" + +[msl.per_entry_point_map.compute_main] +resources = [ + { bind_target = { external_texture = { planes = [ + 0, + 1, + 2, + ], params = 0 } }, resource_binding = { group = 0, binding = 0 } }, + { bind_target = { sampler.Resource = 0 }, resource_binding = { group = 0, binding = 1 } }, +] + +[msl.per_entry_point_map.fragment_main] +resources = [ + { bind_target = { external_texture = { planes = [ + 0, + 1, + 2, + ], params = 0 } }, resource_binding = { group = 0, binding = 0 } }, + { bind_target = { sampler.Resource = 0 }, resource_binding = { group = 0, binding = 1 } }, +] + +[msl.per_entry_point_map.vertex_main] +resources = [ + { bind_target = { external_texture = { planes = [ + 0, + 1, + 2, + ], params = 0 } }, resource_binding = { group = 0, binding = 0 } }, + { bind_target = { sampler.Resource = 0 }, resource_binding = { group = 0, binding = 1 } }, +] [[hlsl.binding_map]] resource_binding = { group = 0, binding = 1 } diff --git a/naga/tests/out/msl/wgsl-texture-external.msl b/naga/tests/out/msl/wgsl-texture-external.msl new file mode 100644 index 00000000000..3dade424fb3 --- /dev/null +++ b/naga/tests/out/msl/wgsl-texture-external.msl @@ -0,0 +1,190 @@ +// language: metal1.0 +#include +#include + +using metal::uint; + +struct NagaExternalTextureTransferFn { + float a; + float b; + float g; + float k; +}; +struct NagaExternalTextureParams { + metal::float4x4 yuv_conversion_matrix; + metal::float3x3 gamut_conversion_matrix; + NagaExternalTextureTransferFn src_tf; + NagaExternalTextureTransferFn dst_tf; + metal::float3x2 sample_transform; + metal::float3x2 load_transform; + metal::uint2 size; + uint num_planes; + char _pad8[4]; +}; +struct NagaExternalTextureWrapper { + metal::texture2d plane0; + metal::texture2d plane1; + metal::texture2d plane2; + NagaExternalTextureParams params; +}; + +float4 nagaTextureSampleBaseClampToEdge(NagaExternalTextureWrapper tex, metal::sampler samp, float2 coords) { + uint2 plane0_size = uint2(tex.plane0.get_width(), tex.plane0.get_height()); + coords = tex.params.sample_transform * float3(coords, 1.0); + float2 bounds_min = tex.params.sample_transform * float3(0.0, 0.0, 1.0); + float2 bounds_max = tex.params.sample_transform * float3(1.0, 1.0, 1.0); + float4 bounds = float4(metal::min(bounds_min, bounds_max), metal::max(bounds_min, bounds_max)); + float2 plane0_half_texel = float2(0.5, 0.5) / float2(plane0_size); + float2 plane0_coords = metal::clamp(coords, bounds.xy + plane0_half_texel, bounds.zw - plane0_half_texel); + if (tex.params.num_planes == 1u) { + return tex.plane0.sample(samp, plane0_coords, metal::level(0.0f)); + } else { + uint2 plane1_size = uint2(tex.plane1.get_width(), tex.plane1.get_height()); + float2 plane1_half_texel = float2(0.5, 0.5) / float2(plane1_size); + float2 plane1_coords = metal::clamp(coords, bounds.xy + plane1_half_texel, bounds.zw - plane1_half_texel); + float y = tex.plane0.sample(samp, plane0_coords, metal::level(0.0f)).r; + float2 uv = float2(0.0, 0.0); + if (tex.params.num_planes == 2u) { + uv = tex.plane1.sample(samp, plane1_coords, metal::level(0.0f)).xy; + } else { + uint2 plane2_size = uint2(tex.plane2.get_width(), tex.plane2.get_height()); + float2 plane2_half_texel = float2(0.5, 0.5) / float2(plane2_size); + float2 plane2_coords = metal::clamp(coords, bounds.xy + plane2_half_texel, bounds.zw - plane1_half_texel); + uv.x = tex.plane1.sample(samp, plane1_coords, metal::level(0.0f)).x; + uv.y = tex.plane2.sample(samp, plane2_coords, metal::level(0.0f)).x; + } + float3 srcGammaRgb = (tex.params.yuv_conversion_matrix * float4(y, uv, 1.0)).rgb; + float3 srcLinearRgb = metal::select( + metal::pow((srcGammaRgb + tex.params.src_tf.a - 1.0) / tex.params.src_tf.a, tex.params.src_tf.g), + srcGammaRgb / tex.params.src_tf.k, + srcGammaRgb < tex.params.src_tf.k * tex.params.src_tf.b); + float3 dstLinearRgb = tex.params.gamut_conversion_matrix * srcLinearRgb; + float3 dstGammaRgb = metal::select( + tex.params.dst_tf.a * metal::pow(dstLinearRgb, 1.0 / tex.params.dst_tf.g) - (tex.params.dst_tf.a - 1), + tex.params.dst_tf.k * dstLinearRgb, + dstLinearRgb < tex.params.dst_tf.b); + return float4(dstGammaRgb, 1.0); + } +} + +float4 nagaTextureLoadExternal(NagaExternalTextureWrapper tex, uint2 coords) { + uint2 plane0_size = uint2(tex.plane0.get_width(), tex.plane0.get_height()); + uint2 cropped_size = metal::any(tex.params.size != 0) ? tex.params.size : plane0_size; + coords = metal::min(coords, cropped_size - 1); + uint2 plane0_coords = uint2(metal::round(tex.params.load_transform * float3(float2(coords), 1.0))); + if (tex.params.num_planes == 1u) { + return tex.plane0.read(plane0_coords); + } else { + uint2 plane1_size = uint2(tex.plane1.get_width(), tex.plane1.get_height()); + uint2 plane1_coords = uint2(metal::floor(float2(plane0_coords) * float2(plane1_size) / float2(plane0_size))); + float y = tex.plane0.read(plane0_coords).x; + float2 uv; + if (tex.params.num_planes == 2u) { + uv = tex.plane1.read(plane1_coords).xy; + } else { + uint2 plane2_size = uint2(tex.plane2.get_width(), tex.plane2.get_height()); + uint2 plane2_coords = uint2(metal::floor(float2(plane0_coords) * float2(plane2_size) / float2(plane0_size))); + uv = float2(tex.plane1.read(plane1_coords).x, tex.plane2.read(plane2_coords).x); + } + float3 srcGammaRgb = (tex.params.yuv_conversion_matrix * float4(y, uv, 1.0)).rgb; + float3 srcLinearRgb = metal::select( + metal::pow((srcGammaRgb + tex.params.src_tf.a - 1.0) / tex.params.src_tf.a, tex.params.src_tf.g), + srcGammaRgb / tex.params.src_tf.k, + srcGammaRgb < tex.params.src_tf.k * tex.params.src_tf.b); + float3 dstLinearRgb = tex.params.gamut_conversion_matrix * srcLinearRgb; + float3 dstGammaRgb = metal::select( + tex.params.dst_tf.a * metal::pow(dstLinearRgb, 1.0 / tex.params.dst_tf.g) - (tex.params.dst_tf.a - 1), + tex.params.dst_tf.k * dstLinearRgb, + dstLinearRgb < tex.params.dst_tf.b); + return float4(dstGammaRgb, 1.0); + } +} + +uint2 nagaTextureDimensionsExternal(NagaExternalTextureWrapper tex) { + if (metal::any(tex.params.size != uint2(0u))) { + return tex.params.size; + } else { + return uint2(tex.plane0.get_width(), tex.plane0.get_height()); + } +} + +metal::float4 test( + NagaExternalTextureWrapper t, + metal::sampler samp +) { + metal::float4 a = {}; + metal::float4 b = {}; + metal::float4 c = {}; + metal::uint2 d = {}; + metal::float4 _e4 = nagaTextureSampleBaseClampToEdge(t, samp, metal::float2(0.0)); + a = _e4; + metal::float4 _e8 = nagaTextureLoadExternal(t, metal::uint2(metal::int2(0))); + b = _e8; + metal::float4 _e12 = nagaTextureLoadExternal(t, metal::uint2(metal::uint2(0u))); + c = _e12; + d = nagaTextureDimensionsExternal(t); + metal::float4 _e16 = a; + metal::float4 _e17 = b; + metal::float4 _e19 = c; + metal::uint2 _e21 = d; + return ((_e16 + _e17) + _e19) + static_cast(_e21).xyxy; +} + +struct fragment_mainOutput { + metal::float4 member [[color(0)]]; +}; +fragment fragment_mainOutput fragment_main( + metal::texture2d tex_plane0_ [[texture(0)]] +, metal::texture2d tex_plane1_ [[texture(1)]] +, metal::texture2d tex_plane2_ [[texture(2)]] +, constant NagaExternalTextureParams& tex_params [[buffer(0)]] +, metal::sampler samp [[sampler(0)]] +) { + const NagaExternalTextureWrapper tex { + .plane0 = tex_plane0_, + .plane1 = tex_plane1_, + .plane2 = tex_plane2_, + .params = tex_params, + }; + metal::float4 _e1 = test(tex, samp); + return fragment_mainOutput { _e1 }; +} + + +struct vertex_mainOutput { + metal::float4 member_1 [[position]]; +}; +vertex vertex_mainOutput vertex_main( + metal::texture2d tex_plane0_ [[texture(0)]] +, metal::texture2d tex_plane1_ [[texture(1)]] +, metal::texture2d tex_plane2_ [[texture(2)]] +, constant NagaExternalTextureParams& tex_params [[buffer(0)]] +, metal::sampler samp [[sampler(0)]] +) { + const NagaExternalTextureWrapper tex { + .plane0 = tex_plane0_, + .plane1 = tex_plane1_, + .plane2 = tex_plane2_, + .params = tex_params, + }; + metal::float4 _e1 = test(tex, samp); + return vertex_mainOutput { _e1 }; +} + + +kernel void compute_main( + metal::texture2d tex_plane0_ [[texture(0)]] +, metal::texture2d tex_plane1_ [[texture(1)]] +, metal::texture2d tex_plane2_ [[texture(2)]] +, constant NagaExternalTextureParams& tex_params [[buffer(0)]] +, metal::sampler samp [[sampler(0)]] +) { + const NagaExternalTextureWrapper tex { + .plane0 = tex_plane0_, + .plane1 = tex_plane1_, + .plane2 = tex_plane2_, + .params = tex_params, + }; + metal::float4 _e1 = test(tex, samp); + return; +} From 167ff7b9529e690c291b158b9ea6f4232ddcb738 Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Mon, 9 Jun 2025 16:14:02 +0100 Subject: [PATCH 147/303] [metal] Implement support for external textures This contains the Metal HAL changes required to support external textures. When creating a bind group we create resource bindings for each of the 3 textures and parameters buffer that the external texture has been lowered to. When creating the pipeline layout we fill the `BindTarget` accordingly, so that the Naga MSL backend can bind each of the global variables to which the the external texture has been lowered to each of these resources. We must also ensure the size of the buffer bound to the parameters global matches the size of the MSL type, else metal validation complains. We do this by adding a padding field to the rust-side ExternalTextureParams struct, the size of which is used as the size of the buffer to allocate. Lastly we enable `Features::EXTERNAL_TEXTURE` on the Metal backend. --- wgpu-core/src/device/resource.rs | 4 ++++ wgpu-hal/src/metal/adapter.rs | 3 ++- wgpu-hal/src/metal/device.rs | 37 ++++++++++++++++++++++++++++++-- wgpu-types/src/features.rs | 1 + 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index ba894a977aa..7d5898ecc2d 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -163,6 +163,8 @@ pub struct ExternalTextureParams { /// plane and an interleaved CbCr plane. 3 indicates separate Y, Cb, and Cr /// planes. pub num_planes: u32, + // Ensure the size of this struct matches the type generated by Naga. + pub _padding: [u8; 4], } impl ExternalTextureParams { @@ -191,6 +193,7 @@ impl ExternalTextureParams { sample_transform: desc.sample_transform, load_transform: desc.load_transform, num_planes: desc.num_planes() as u32, + _padding: Default::default(), } } } @@ -512,6 +515,7 @@ impl Device { 0.0, 0.0 ], num_planes: 1, + _padding: Default::default(), }; let mut staging_buffer = StagingBuffer::new(self, wgt::BufferSize::new(size_of_val(&data) as _).unwrap())?; diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index 02dfc0fe601..44e2c3010a6 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -927,7 +927,8 @@ impl super::PrivateCapabilities { | F::SHADER_F16 | F::DEPTH32FLOAT_STENCIL8 | F::BGRA8UNORM_STORAGE - | F::EXPERIMENTAL_PASSTHROUGH_SHADERS; + | F::EXPERIMENTAL_PASSTHROUGH_SHADERS + | F::EXTERNAL_TEXTURE; features.set(F::FLOAT32_FILTERABLE, self.supports_float_filtering); features.set( diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index 6af8ad3062d..d034be31f37 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -747,7 +747,19 @@ impl crate::Device for super::Device { }; } wgt::BindingType::AccelerationStructure { .. } => unimplemented!(), - wgt::BindingType::ExternalTexture => unimplemented!(), + wgt::BindingType::ExternalTexture => { + target.external_texture = + Some(naga::back::msl::BindExternalTextureTarget { + planes: [ + info.counters.textures as _, + (info.counters.textures + 1) as _, + (info.counters.textures + 2) as _, + ], + params: info.counters.buffers as _, + }); + info.counters.textures += 3; + info.counters.buffers += 1; + } } } @@ -980,7 +992,28 @@ impl crate::Device for super::Device { counter.textures += 1; } wgt::BindingType::AccelerationStructure { .. } => unimplemented!(), - wgt::BindingType::ExternalTexture => unimplemented!(), + wgt::BindingType::ExternalTexture => { + // We don't yet support binding arrays of external textures. + // https://github.com/gfx-rs/wgpu/issues/8027 + assert_eq!(entry.count, 1); + let external_texture = + &desc.external_textures[entry.resource_index as usize]; + bg.textures.extend( + external_texture + .planes + .iter() + .map(|plane| plane.view.as_raw()), + ); + bg.buffers.push(super::BufferResource { + ptr: external_texture.params.buffer.as_raw(), + offset: external_texture.params.offset, + dynamic_index: None, + binding_size: None, + binding_location: layout.binding, + }); + counter.textures += 3; + counter.buffers += 1; + } } } } diff --git a/wgpu-types/src/features.rs b/wgpu-types/src/features.rs index 8f7418b018d..2c4bd7245b3 100644 --- a/wgpu-types/src/features.rs +++ b/wgpu-types/src/features.rs @@ -985,6 +985,7 @@ bitflags_array! { /// /// Supported platforms: /// - DX12 + /// - Metal const EXTERNAL_TEXTURE = 1 << 31; // Shader: From 37c4c881382643e2a84a654fc0c572ff8381ee55 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Sat, 23 Aug 2025 15:09:25 -0400 Subject: [PATCH 148/303] Fix RT validation error (#8132) --- wgpu-hal/src/vulkan/command.rs | 2 +- wgpu-hal/src/vulkan/device.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index ec9e44f2ee6..93c6b652a62 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -630,7 +630,7 @@ impl crate::CommandEncoder for super::CommandEncoder { .first_vertex(triangles.first_vertex); } else { range = range - .primitive_count(triangles.vertex_count) + .primitive_count(triangles.vertex_count / 3) .first_vertex(triangles.first_vertex); } diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 42771f5c597..580c1cb19cf 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -2557,7 +2557,7 @@ impl crate::Device for super::Device { triangle_data.index_type(conv::map_index_format(indices.format)); indices.count / 3 } else { - triangles.vertex_count + triangles.vertex_count / 3 }; let geometry = vk::AccelerationStructureGeometryKHR::default() From 7394d4351b91e7406269595d9ab9530ca3ba0e2d Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Sat, 23 Aug 2025 23:13:40 -0700 Subject: [PATCH 149/303] Remove copy-pasted mention of acceleration structures from mesh docs. (#8135) --- docs/api-specs/mesh_shading.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/api-specs/mesh_shading.md b/docs/api-specs/mesh_shading.md index 8c979890b78..46d7948d55e 100644 --- a/docs/api-specs/mesh_shading.md +++ b/docs/api-specs/mesh_shading.md @@ -2,8 +2,7 @@ 🧪Experimental🧪 -`wgpu` supports an experimental version of mesh shading. The extensions allow for acceleration structures to be created and built (with -`Features::EXPERIMENTAL_MESH_SHADER` enabled) and interacted with in shaders. Currently `naga` has no support for mesh shaders beyond recognizing the additional shader stages. +`wgpu` supports an experimental version of mesh shading. Currently `naga` has no support for mesh shaders beyond recognizing the additional shader stages. For this reason, all shaders must be created with `Device::create_shader_module_passthrough`. **Note**: The features documented here may have major bugs in them and are expected to be subject From c4a834e4f98d97b3966d7fee4ad92935f9adffe9 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Sun, 24 Aug 2025 21:11:13 +1200 Subject: [PATCH 150/303] Make the compacted hal acceleration structure inherit a label from the base BLAS. #8103 --- CHANGELOG.md | 1 + wgpu-core/src/device/queue.rs | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11fb072dcab..d4dc1187488 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -98,6 +98,7 @@ This allows using precompiled shaders without manually checking which backend's - The function you pass to `Device::on_uncaptured_error()` must now implement `Sync` in addition to `Send`, and be wrapped in `Arc` instead of `Box`. In exchange for this, it is no longer possible for calling `wgpu` functions while in that callback to cause a deadlock (not that we encourage you to actually do that). By @kpreid in [#8011](https://github.com/gfx-rs/wgpu/pull/8011). +- Make a compacted hal acceleration structure inherit a label from the base BLAS. By @Vecvec in [#8103](https://github.com/gfx-rs/wgpu/pull/8103). - The limits requested for a device must now satisfy `min_subgroup_size <= max_subgroup_size`. By @andyleiserson in [#8085](https://github.com/gfx-rs/wgpu/pull/8085). #### Naga diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index d946ec35a0b..a58c076d83c 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -1465,6 +1465,8 @@ impl Queue { profiling::scope!("Queue::compact_blas"); api_log!("Queue::compact_blas"); + let new_label = blas.label.clone() + " (compacted)"; + self.device.check_is_valid()?; self.same_device_as(blas.as_ref())?; @@ -1486,7 +1488,7 @@ impl Queue { device .raw() .create_acceleration_structure(&hal::AccelerationStructureDescriptor { - label: None, + label: hal_label(Some(&new_label), device.instance_flags), size: size_info.acceleration_structure_size, format: hal::AccelerationStructureFormat::BottomLevel, allow_compaction: false, @@ -1528,7 +1530,7 @@ impl Queue { // Bypass the submit checks which update this because we don't submit this normally. built_index: RwLock::new(rank::BLAS_BUILT_INDEX, Some(built_index)), handle, - label: blas.label.clone() + " compacted", + label: new_label, tracking_data: TrackingData::new(blas.device.tracker_indices.blas_s.clone()), compaction_buffer: None, compacted_state: Mutex::new(rank::BLAS_COMPACTION_STATE, BlasCompactState::Compacted), From dd73743e784e05a52d545ea9061e0acbbb0e0f13 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Sun, 24 Aug 2025 14:37:19 -0400 Subject: [PATCH 151/303] =?UTF-8?q?fix(wgsl-in):=20accept=20trailing=20com?= =?UTF-8?q?ma=20in=20`@blend=5Fsrc(=E2=80=A6)`=20attr.=20(#8137)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 ++++ cts_runner/test.lst | 1 + naga/src/front/wgsl/parse/mod.rs | 1 + 3 files changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4dc1187488..be4e1630a83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -121,6 +121,10 @@ This allows using precompiled shaders without manually checking which backend's - Fixed a bug where access to matrices with 2 rows would not work in some cases. By @andyleiserson in [#7438](https://github.com/gfx-rs/wgpu/pull/7438). +#### Naga + +- [wgsl-in] Allow a trailing comma in `@blend_src(…)` attributes. By @ErichDonGubler in [#8137](https://github.com/gfx-rs/wgpu/pull/8137). + ## v26.0.4 (2025-08-07) ### Bug Fixes diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 082d348a2b7..e681322a584 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -58,6 +58,7 @@ webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bind_grou webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:buffer_binding,render_pipeline:* webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:sampler_binding,render_pipeline:* webgpu:api,validation,encoding,queries,general:occlusion_query,query_index:* +webgpu:shader,validation,extension,dual_source_blending:blend_src_syntax_validation:* webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_usage_and_aspect:* webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_buffer_size:* fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_buffer_offset:format="depth32float";aspect="depth-only";copyType="CopyT2B" diff --git a/naga/src/front/wgsl/parse/mod.rs b/naga/src/front/wgsl/parse/mod.rs index cf4dd4d4bb6..c7f81005e97 100644 --- a/naga/src/front/wgsl/parse/mod.rs +++ b/naga/src/front/wgsl/parse/mod.rs @@ -235,6 +235,7 @@ impl<'a> BindingParser<'a> { lexer.expect(Token::Paren('('))?; self.blend_src .set(parser.general_expression(lexer, ctx)?, name_span)?; + lexer.skip(Token::Separator(',')); lexer.expect(Token::Paren(')'))?; } _ => return Err(Box::new(Error::UnknownAttribute(name_span))), From 779249fa92847a8b33ee6343cd674ce3d8a2b008 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Sun, 24 Aug 2025 14:20:33 -0700 Subject: [PATCH 152/303] Remove security issue type; github adds it automatically (#8142) --- .github/ISSUE_TEMPLATE/config.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 7cfcd54472b..29ab84ed12c 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -3,8 +3,3 @@ contact_links: - name: Question about wgpu url: https://github.com/gfx-rs/wgpu/discussions/new/choose about: Any questions about how to use wgpu should go here. - - name: Security concerns - url: https://github.com/gfx-rs/wgpu/security - about: > - If you have found a possible vulnerability in wgpu, please read this - security policy for information about reporting it confidentially. From 57368b374f67cfca39ca432ae9005abbef1d5780 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Sun, 24 Aug 2025 14:21:12 -0700 Subject: [PATCH 153/303] Disable `copy_ranges` on dx12 due to intermittent failures (#8141) --- cts_runner/test.lst | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/cts_runner/test.lst b/cts_runner/test.lst index e681322a584..b0a08098f84 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -26,7 +26,19 @@ webgpu:api,validation,encoding,beginRenderPass:* webgpu:api,validation,encoding,cmds,clearBuffer:* webgpu:api,validation,encoding,cmds,compute_pass:set_pipeline:* webgpu:api,validation,encoding,cmds,compute_pass:dispatch_sizes:* -webgpu:api,validation,encoding,cmds,copyTextureToTexture:* +webgpu:api,validation,encoding,cmds,copyTextureToTexture:copy_with_invalid_or_destroyed_texture:* +webgpu:api,validation,encoding,cmds,copyTextureToTexture:texture,device_mismatch:* +webgpu:api,validation,encoding,cmds,copyTextureToTexture:mipmap_level:* +webgpu:api,validation,encoding,cmds,copyTextureToTexture:texture_usage:* +webgpu:api,validation,encoding,cmds,copyTextureToTexture:sample_count:* +webgpu:api,validation,encoding,cmds,copyTextureToTexture:multisampled_copy_restrictions:* +webgpu:api,validation,encoding,cmds,copyTextureToTexture:texture_format_compatibility:* +webgpu:api,validation,encoding,cmds,copyTextureToTexture:depth_stencil_copy_restrictions:* +// Intermittently fails on dx12, https://github.com/gfx-rs/wgpu/issues/8118 +fails-if(dx12) webgpu:api,validation,encoding,cmds,copyTextureToTexture:copy_ranges:* +webgpu:api,validation,encoding,cmds,copyTextureToTexture:copy_within_same_texture:* +webgpu:api,validation,encoding,cmds,copyTextureToTexture:copy_aspects:* +webgpu:api,validation,encoding,cmds,copyTextureToTexture:copy_ranges_with_compressed_texture_formats:* webgpu:api,validation,encoding,cmds,debug:debug_group_balanced:encoderType="non-pass" webgpu:api,validation,encoding,cmds,debug:debug_group_balanced:encoderType="compute%20pass" webgpu:api,validation,encoding,cmds,debug:debug_group_balanced:encoderType="render%20pass" From 24a31c494af1a00cdc565168f6d43ca433677680 Mon Sep 17 00:00:00 2001 From: Magnus <85136135+SupaMaggie70Incorporated@users.noreply.github.com> Date: Sun, 24 Aug 2025 16:23:21 -0500 Subject: [PATCH 154/303] Only commit hopefully (#8140) --- wgpu-hal/src/metal/device.rs | 326 ++++++++++++++++++----------------- 1 file changed, 172 insertions(+), 154 deletions(-) diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index d034be31f37..dd5d05b6d50 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -128,176 +128,194 @@ impl super::Device { primitive_class: MTLPrimitiveTopologyClass, naga_stage: naga::ShaderStage, ) -> Result { - let naga_shader = if let ShaderModuleSource::Naga(naga) = &stage.module.source { - naga - } else { - panic!("load_shader required a naga shader"); - }; - let stage_bit = map_naga_stage(naga_stage); - let (module, module_info) = naga::back::pipeline_constants::process_overrides( - &naga_shader.module, - &naga_shader.info, - Some((naga_stage, stage.entry_point)), - stage.constants, - ) - .map_err(|e| crate::PipelineError::PipelineConstants(stage_bit, format!("MSL: {e:?}")))?; - - let ep_resources = &layout.per_stage_map[naga_stage]; - - let bounds_check_policy = if stage.module.bounds_checks.bounds_checks { - naga::proc::BoundsCheckPolicy::Restrict - } else { - naga::proc::BoundsCheckPolicy::Unchecked - }; + match stage.module.source { + ShaderModuleSource::Naga(ref naga_shader) => { + let stage_bit = map_naga_stage(naga_stage); + let (module, module_info) = naga::back::pipeline_constants::process_overrides( + &naga_shader.module, + &naga_shader.info, + Some((naga_stage, stage.entry_point)), + stage.constants, + ) + .map_err(|e| { + crate::PipelineError::PipelineConstants(stage_bit, format!("MSL: {e:?}")) + })?; - let options = naga::back::msl::Options { - lang_version: match self.shared.private_caps.msl_version { - MTLLanguageVersion::V1_0 => (1, 0), - MTLLanguageVersion::V1_1 => (1, 1), - MTLLanguageVersion::V1_2 => (1, 2), - MTLLanguageVersion::V2_0 => (2, 0), - MTLLanguageVersion::V2_1 => (2, 1), - MTLLanguageVersion::V2_2 => (2, 2), - MTLLanguageVersion::V2_3 => (2, 3), - MTLLanguageVersion::V2_4 => (2, 4), - MTLLanguageVersion::V3_0 => (3, 0), - MTLLanguageVersion::V3_1 => (3, 1), - }, - inline_samplers: Default::default(), - spirv_cross_compatibility: false, - fake_missing_bindings: false, - per_entry_point_map: naga::back::msl::EntryPointResourceMap::from([( - stage.entry_point.to_owned(), - ep_resources.clone(), - )]), - bounds_check_policies: naga::proc::BoundsCheckPolicies { - index: bounds_check_policy, - buffer: bounds_check_policy, - image_load: bounds_check_policy, - // TODO: support bounds checks on binding arrays - binding_array: naga::proc::BoundsCheckPolicy::Unchecked, - }, - zero_initialize_workgroup_memory: stage.zero_initialize_workgroup_memory, - force_loop_bounding: stage.module.bounds_checks.force_loop_bounding, - }; + let ep_resources = &layout.per_stage_map[naga_stage]; - let pipeline_options = naga::back::msl::PipelineOptions { - entry_point: Some((naga_stage, stage.entry_point.to_owned())), - allow_and_force_point_size: match primitive_class { - MTLPrimitiveTopologyClass::Point => true, - _ => false, - }, - vertex_pulling_transform: true, - vertex_buffer_mappings: vertex_buffer_mappings.to_vec(), - }; + let bounds_check_policy = if stage.module.bounds_checks.bounds_checks { + naga::proc::BoundsCheckPolicy::Restrict + } else { + naga::proc::BoundsCheckPolicy::Unchecked + }; - let (source, info) = - naga::back::msl::write_string(&module, &module_info, &options, &pipeline_options) - .map_err(|e| crate::PipelineError::Linkage(stage_bit, format!("MSL: {e:?}")))?; + let options = naga::back::msl::Options { + lang_version: match self.shared.private_caps.msl_version { + MTLLanguageVersion::V1_0 => (1, 0), + MTLLanguageVersion::V1_1 => (1, 1), + MTLLanguageVersion::V1_2 => (1, 2), + MTLLanguageVersion::V2_0 => (2, 0), + MTLLanguageVersion::V2_1 => (2, 1), + MTLLanguageVersion::V2_2 => (2, 2), + MTLLanguageVersion::V2_3 => (2, 3), + MTLLanguageVersion::V2_4 => (2, 4), + MTLLanguageVersion::V3_0 => (3, 0), + MTLLanguageVersion::V3_1 => (3, 1), + }, + inline_samplers: Default::default(), + spirv_cross_compatibility: false, + fake_missing_bindings: false, + per_entry_point_map: naga::back::msl::EntryPointResourceMap::from([( + stage.entry_point.to_owned(), + ep_resources.clone(), + )]), + bounds_check_policies: naga::proc::BoundsCheckPolicies { + index: bounds_check_policy, + buffer: bounds_check_policy, + image_load: bounds_check_policy, + // TODO: support bounds checks on binding arrays + binding_array: naga::proc::BoundsCheckPolicy::Unchecked, + }, + zero_initialize_workgroup_memory: stage.zero_initialize_workgroup_memory, + force_loop_bounding: stage.module.bounds_checks.force_loop_bounding, + }; - log::debug!( - "Naga generated shader for entry point '{}' and stage {:?}\n{}", - stage.entry_point, - naga_stage, - &source - ); + let pipeline_options = naga::back::msl::PipelineOptions { + entry_point: Some((naga_stage, stage.entry_point.to_owned())), + allow_and_force_point_size: match primitive_class { + MTLPrimitiveTopologyClass::Point => true, + _ => false, + }, + vertex_pulling_transform: true, + vertex_buffer_mappings: vertex_buffer_mappings.to_vec(), + }; - let options = metal::CompileOptions::new(); - options.set_language_version(self.shared.private_caps.msl_version); + let (source, info) = naga::back::msl::write_string( + &module, + &module_info, + &options, + &pipeline_options, + ) + .map_err(|e| crate::PipelineError::Linkage(stage_bit, format!("MSL: {e:?}")))?; - if self.shared.private_caps.supports_preserve_invariance { - options.set_preserve_invariance(true); - } + log::debug!( + "Naga generated shader for entry point '{}' and stage {:?}\n{}", + stage.entry_point, + naga_stage, + &source + ); - let library = self - .shared - .device - .lock() - .new_library_with_source(source.as_ref(), &options) - .map_err(|err| { - log::warn!("Naga generated shader:\n{source}"); - crate::PipelineError::Linkage(stage_bit, format!("Metal: {err}")) - })?; - - let ep_index = module - .entry_points - .iter() - .position(|ep| ep.stage == naga_stage && ep.name == stage.entry_point) - .ok_or(crate::PipelineError::EntryPoint(naga_stage))?; - let ep = &module.entry_points[ep_index]; - let translated_ep_name = info.entry_point_names[0] - .as_ref() - .map_err(|e| crate::PipelineError::Linkage(stage_bit, format!("{e}")))?; - - let wg_size = MTLSize { - width: ep.workgroup_size[0] as _, - height: ep.workgroup_size[1] as _, - depth: ep.workgroup_size[2] as _, - }; + let options = metal::CompileOptions::new(); + options.set_language_version(self.shared.private_caps.msl_version); - let function = library - .get_function(translated_ep_name, None) - .map_err(|e| { - log::error!("get_function: {e:?}"); - crate::PipelineError::EntryPoint(naga_stage) - })?; - - // collect sizes indices, immutable buffers, and work group memory sizes - let ep_info = &module_info.get_entry_point(ep_index); - let mut wg_memory_sizes = Vec::new(); - let mut sized_bindings = Vec::new(); - let mut immutable_buffer_mask = 0; - for (var_handle, var) in module.global_variables.iter() { - match var.space { - naga::AddressSpace::WorkGroup => { - if !ep_info[var_handle].is_empty() { - let size = module.types[var.ty].inner.size(module.to_ctx()); - wg_memory_sizes.push(size); - } + if self.shared.private_caps.supports_preserve_invariance { + options.set_preserve_invariance(true); } - naga::AddressSpace::Uniform | naga::AddressSpace::Storage { .. } => { - let br = match var.binding { - Some(br) => br, - None => continue, - }; - let storage_access_store = match var.space { - naga::AddressSpace::Storage { access } => { - access.contains(naga::StorageAccess::STORE) + + let library = self + .shared + .device + .lock() + .new_library_with_source(source.as_ref(), &options) + .map_err(|err| { + log::warn!("Naga generated shader:\n{source}"); + crate::PipelineError::Linkage(stage_bit, format!("Metal: {err}")) + })?; + + let ep_index = module + .entry_points + .iter() + .position(|ep| ep.stage == naga_stage && ep.name == stage.entry_point) + .ok_or(crate::PipelineError::EntryPoint(naga_stage))?; + let ep = &module.entry_points[ep_index]; + let translated_ep_name = info.entry_point_names[0] + .as_ref() + .map_err(|e| crate::PipelineError::Linkage(stage_bit, format!("{e}")))?; + + let wg_size = MTLSize { + width: ep.workgroup_size[0] as _, + height: ep.workgroup_size[1] as _, + depth: ep.workgroup_size[2] as _, + }; + + let function = library + .get_function(translated_ep_name, None) + .map_err(|e| { + log::error!("get_function: {e:?}"); + crate::PipelineError::EntryPoint(naga_stage) + })?; + + // collect sizes indices, immutable buffers, and work group memory sizes + let ep_info = &module_info.get_entry_point(ep_index); + let mut wg_memory_sizes = Vec::new(); + let mut sized_bindings = Vec::new(); + let mut immutable_buffer_mask = 0; + for (var_handle, var) in module.global_variables.iter() { + match var.space { + naga::AddressSpace::WorkGroup => { + if !ep_info[var_handle].is_empty() { + let size = module.types[var.ty].inner.size(module.to_ctx()); + wg_memory_sizes.push(size); + } } - _ => false, - }; + naga::AddressSpace::Uniform | naga::AddressSpace::Storage { .. } => { + let br = match var.binding { + Some(br) => br, + None => continue, + }; + let storage_access_store = match var.space { + naga::AddressSpace::Storage { access } => { + access.contains(naga::StorageAccess::STORE) + } + _ => false, + }; - // check for an immutable buffer - if !ep_info[var_handle].is_empty() && !storage_access_store { - let slot = ep_resources.resources[&br].buffer.unwrap(); - immutable_buffer_mask |= 1 << slot; - } + // check for an immutable buffer + if !ep_info[var_handle].is_empty() && !storage_access_store { + let slot = ep_resources.resources[&br].buffer.unwrap(); + immutable_buffer_mask |= 1 << slot; + } - let mut dynamic_array_container_ty = var.ty; - if let naga::TypeInner::Struct { ref members, .. } = module.types[var.ty].inner - { - dynamic_array_container_ty = members.last().unwrap().ty; - } - if let naga::TypeInner::Array { - size: naga::ArraySize::Dynamic, - .. - } = module.types[dynamic_array_container_ty].inner - { - sized_bindings.push(br); + let mut dynamic_array_container_ty = var.ty; + if let naga::TypeInner::Struct { ref members, .. } = + module.types[var.ty].inner + { + dynamic_array_container_ty = members.last().unwrap().ty; + } + if let naga::TypeInner::Array { + size: naga::ArraySize::Dynamic, + .. + } = module.types[dynamic_array_container_ty].inner + { + sized_bindings.push(br); + } + } + _ => {} } } - _ => {} + + Ok(CompiledShader { + library, + function, + wg_size, + wg_memory_sizes, + sized_bindings, + immutable_buffer_mask, + }) } + ShaderModuleSource::Passthrough(ref shader) => Ok(CompiledShader { + library: shader.library.clone(), + function: shader.function.clone(), + wg_size: MTLSize { + width: shader.num_workgroups.0 as u64, + height: shader.num_workgroups.1 as u64, + depth: shader.num_workgroups.2 as u64, + }, + wg_memory_sizes: vec![], + sized_bindings: vec![], + immutable_buffer_mask: 0, + }), } - - Ok(CompiledShader { - library, - function, - wg_size, - wg_memory_sizes, - sized_bindings, - immutable_buffer_mask, - }) } fn set_buffers_mutability( From c1254b4c8098a251ab9c21723141f0698daafc1b Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Sun, 10 Aug 2025 15:06:33 -0700 Subject: [PATCH 155/303] Add more overview documentation to `Buffer` and usages. --- wgpu-types/src/lib.rs | 8 +++++++ wgpu/src/api/buffer.rs | 53 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 5fe93a1888f..768658a5bf0 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -5247,6 +5247,10 @@ bitflags::bitflags! { /// The usages determine what kind of memory the buffer is allocated from and what /// actions the buffer can partake in. /// + /// Specifying only usages the application will actually perform may increase performance. + /// Additionally, on the WebGL backend, there are restrictions on [`BufferUsages::INDEX`]; + /// see [`DownlevelFlags::UNRESTRICTED_INDEX_BUFFER`] for more information. + /// /// Corresponds to [WebGPU `GPUBufferUsageFlags`]( /// https://gpuweb.github.io/gpuweb/#typedefdef-gpubufferusageflags). #[repr(transparent)] @@ -5365,6 +5369,10 @@ pub struct BufferDescriptor { pub size: BufferAddress, /// Usages of a buffer. If the buffer is used in any way that isn't specified here, the operation /// will panic. + /// + /// Specifying only usages the application will actually perform may increase performance. + /// Additionally, on the WebGL backend, there are restrictions on [`BufferUsages::INDEX`]; + /// see [`DownlevelFlags::UNRESTRICTED_INDEX_BUFFER`] for more information. pub usage: BufferUsages, /// Allows a buffer to be mapped immediately after they are made. It does not have to be [`BufferUsages::MAP_READ`] or /// [`BufferUsages::MAP_WRITE`], all buffers are allowed to be mapped at creation. diff --git a/wgpu/src/api/buffer.rs b/wgpu/src/api/buffer.rs index 6e4d65c7d20..28b43b76b0d 100644 --- a/wgpu/src/api/buffer.rs +++ b/wgpu/src/api/buffer.rs @@ -9,10 +9,13 @@ use crate::*; /// Handle to a GPU-accessible buffer. /// -/// Created with [`Device::create_buffer`] or -/// [`DeviceExt::create_buffer_init`](util::DeviceExt::create_buffer_init). -/// -/// Corresponds to [WebGPU `GPUBuffer`](https://gpuweb.github.io/gpuweb/#buffer-interface). +/// A `Buffer` is a memory allocation for use by the GPU, somewhat analogous to +/// [Box]<[\[u8\]][primitive@slice]> in Rust. +/// The contents of buffers are untyped bytes; it is up to the application to +/// specify the interpretation of the bytes when the buffer is used, in ways +/// such as [`VertexBufferLayout`]. +/// A single buffer can be used to hold multiple independent pieces of data at +/// different offsets (e.g. both vertices and indices for one or more meshes). /// /// A `Buffer`'s bytes have "interior mutability": functions like /// [`Queue::write_buffer`] or [mapping] a buffer for writing only require a @@ -20,8 +23,49 @@ use crate::*; /// prevents simultaneous reads and writes of buffer contents using run-time /// checks. /// +/// Created with [`Device::create_buffer()`] or +/// [`DeviceExt::create_buffer_init()`]. +/// +/// Corresponds to [WebGPU `GPUBuffer`](https://gpuweb.github.io/gpuweb/#buffer-interface). +/// /// [mapping]: Buffer#mapping-buffers /// +/// # How to get your data into a buffer +/// +/// Every `Buffer` starts with all bytes zeroed. +/// There are many ways to load data into a `Buffer`: +/// +/// - When creating a buffer, you may set the [`mapped_at_creation`][mac] flag, +/// then write to its [`get_mapped_range_mut()`][Buffer::get_mapped_range_mut]. +/// This only works when the buffer is created and has not yet been used by +/// the GPU, but it is all you need for buffers whose contents do not change +/// after creation. +/// - You may use [`DeviceExt::create_buffer_init()`] as a convenient way to +/// do that and copy data from a `&[u8]` you provide. +/// - After creation, you may use [`Buffer::map_async()`] to map it again; +/// however, you then need to wait until the GPU is no longer using the buffer +/// before you begin writing. +/// - You may use [`CommandEncoder::copy_buffer_to_buffer()`] to copy data into +/// this buffer from another buffer. +/// - You may use [`Queue::write_buffer()`] to copy data into the buffer from a +/// `&[u8]`. This uses a temporary “staging” buffer managed by `wgpu` to hold +/// the data. +/// - [`Queue::write_buffer_with()`] allows you to write directly into temporary +/// storage instead of providing a slice you already prepared, which may +/// allow *your* code to save the allocation of a [`Vec`] or such. +/// - You may use [`util::StagingBelt`] to manage a set of temporary buffers. +/// This may be more efficient than [`Queue::write_buffer_with()`] when you +/// have many small copies to perform, but requires more steps to use, and +/// tuning of the belt buffer size. +/// - You may write your own staging buffer management customized to your +/// application, based on mapped buffers and +/// [`CommandEncoder::copy_buffer_to_buffer()`]. +/// - A GPU computation’s results can be stored in a buffer: +/// - A [compute shader][ComputePipeline] may write to a buffer bound as a +/// [storage buffer][BufferBindingType::Storage]. +/// - A render pass may render to a texture which is then copied to a buffer +/// using [`CommandEncoder::copy_texture_to_buffer()`]. +/// /// # Mapping buffers /// /// If a `Buffer` is created with the appropriate [`usage`], it can be *mapped*: @@ -172,6 +216,7 @@ use crate::*; /// [mac]: BufferDescriptor::mapped_at_creation /// [`MAP_READ`]: BufferUsages::MAP_READ /// [`MAP_WRITE`]: BufferUsages::MAP_WRITE +/// [`DeviceExt::create_buffer_init()`]: util::DeviceExt::create_buffer_init #[derive(Debug, Clone)] pub struct Buffer { pub(crate) inner: dispatch::DispatchBuffer, From 03d419d0942ae3dd8572147ee2c48bc5909376bc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 25 Aug 2025 09:28:37 +0200 Subject: [PATCH 156/303] Update Cargo.lock (#8145) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Cargo.lock | 178 ++++++++++++++++++++++++++--------------------------- 1 file changed, 89 insertions(+), 89 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f4812d64f28..506c1209bcb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,7 +74,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee91c0c2905bae44f84bfa4e044536541df26b7703fd0888deeb9060fcc44289" dependencies = [ "android-properties", - "bitflags 2.9.2", + "bitflags 2.9.3", "cc", "cesu8", "jni", @@ -95,7 +95,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" dependencies = [ "android-properties", - "bitflags 2.9.2", + "bitflags 2.9.3", "cc", "cesu8", "jni", @@ -370,7 +370,7 @@ version = "0.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "cexpr", "clang-sys", "itertools 0.13.0", @@ -422,9 +422,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.2" +version = "2.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a65b545ab31d687cff52899d4890855fec459eb6afe0da6417b8a18da87aa29" +checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d" dependencies = [ "arbitrary", "serde", @@ -520,7 +520,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "log", "polling", "rustix 0.38.44", @@ -534,7 +534,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "log", "polling", "rustix 0.38.44", @@ -652,9 +652,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.33" +version = "1.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee0f8803222ba5a7e2777dd72ca451868909b1ac410621b676adf07280e9b5f" +checksum = "42bc4aea80032b7bf409b0bc7ccad88853858911b7713a8062fdc0623867bedc" dependencies = [ "jobserver", "libc", @@ -921,7 +921,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "core-foundation 0.10.1", "libc", ] @@ -1549,9 +1549,9 @@ checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -1682,9 +1682,9 @@ dependencies = [ [[package]] name = "generator" -version = "0.8.5" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d18470a76cb7f8ff746cf1f7470914f900252ec36bbc40b569d74b1258446827" +checksum = "605183a538e3e2a9c1038635cc5c2d194e2ee8fd0d1b66b8349fad7dbacce5a2" dependencies = [ "cc", "cfg-if", @@ -1781,7 +1781,7 @@ version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18fcd4ae4e86d991ad1300b8f57166e5be0c95ef1f63f3f5b827f8a164548746" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "cfg_aliases 0.1.1", "cgl", "core-foundation 0.9.4", @@ -1844,7 +1844,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "gpu-alloc-types", ] @@ -1854,7 +1854,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", ] [[package]] @@ -1875,7 +1875,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "gpu-descriptor-types", "hashbrown", ] @@ -1886,7 +1886,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", ] [[package]] @@ -2064,9 +2064,9 @@ dependencies = [ [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -2103,9 +2103,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" dependencies = [ "arbitrary", "equivalent", @@ -2128,11 +2128,11 @@ dependencies = [ [[package]] name = "io-uring" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" +checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "cfg-if", "libc", ] @@ -2215,9 +2215,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ "getrandom 0.3.3", "libc", @@ -2256,7 +2256,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff7f53bdf698e7aa7ec916411bbdc8078135da11b66db5182675b2227f6c0d07" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", ] [[package]] @@ -2304,7 +2304,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "libc", "redox_syscall 0.5.17", ] @@ -2415,9 +2415,9 @@ checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "memmap2" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "483758ad303d734cec05e5c12b41d7e93e6a6390c5e9dae6bdeb7c1259012d28" +checksum = "843a98750cd611cc2965a8213b53b43e715f13c37a9e096c6408e69990961db7" dependencies = [ "libc", ] @@ -2437,7 +2437,7 @@ version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00c15a6f673ff72ddcc22394663290f870fb224c1bfce55734a75c414150e605" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "block", "core-graphics-types 0.2.0", "foreign-types", @@ -2499,7 +2499,7 @@ dependencies = [ "arbitrary", "arrayvec", "bit-set 0.8.0", - "bitflags 2.9.2", + "bitflags 2.9.3", "cfg-if", "cfg_aliases 0.2.1", "codespan-reporting", @@ -2608,7 +2608,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "jni-sys", "log", "ndk-sys 0.5.0+25.2.9519653", @@ -2624,7 +2624,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "jni-sys", "log", "ndk-sys 0.6.0+11769913", @@ -2815,7 +2815,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "block2 0.5.1", "libc", "objc2 0.5.2", @@ -2831,7 +2831,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "block2 0.5.1", "objc2 0.5.2", "objc2-core-location", @@ -2855,7 +2855,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation", @@ -2903,7 +2903,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "block2 0.5.1", "dispatch", "libc", @@ -2928,7 +2928,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation", @@ -2940,7 +2940,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation", @@ -2963,7 +2963,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "block2 0.5.1", "objc2 0.5.2", "objc2-cloud-kit", @@ -2995,7 +2995,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "block2 0.5.1", "objc2 0.5.2", "objc2-core-location", @@ -3123,9 +3123,9 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "petgraph" @@ -3494,19 +3494,19 @@ version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", ] [[package]] name = "regex" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", + "regex-automata 0.4.10", + "regex-syntax 0.8.6", ] [[package]] @@ -3520,20 +3520,20 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.5", + "regex-syntax 0.8.6", ] [[package]] name = "regex-lite" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" +checksum = "943f41321c63ef1c92fd763bfe054d2668f7f225a5c29f0105903dc2fc04ba30" [[package]] name = "regex-syntax" @@ -3543,9 +3543,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" [[package]] name = "renderdoc-sys" @@ -3560,7 +3560,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f" dependencies = [ "base64", - "bitflags 2.9.2", + "bitflags 2.9.3", "serde", "serde_derive", "unicode-ident", @@ -3609,7 +3609,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "errno", "libc", "linux-raw-sys 0.4.15", @@ -3622,7 +3622,7 @@ version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "errno", "libc", "linux-raw-sys 0.9.4", @@ -3870,7 +3870,7 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "calloop 0.12.4", "calloop-wayland-source 0.2.0", "cursor-icon", @@ -3895,7 +3895,7 @@ version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "calloop 0.13.0", "calloop-wayland-source 0.3.0", "cursor-icon", @@ -3967,7 +3967,7 @@ version = "0.3.0+sdk-1.3.268.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "serde", ] @@ -4421,9 +4421,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typewit" -version = "1.12.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97e72ba082eeb9da9dc68ff5a2bf727ef6ce362556e8d29ec1aed3bd05e7d86a" +checksum = "4dd91acc53c592cb800c11c83e8e7ee1d48378d05cfa33b5474f5f80c5b236bf" [[package]] name = "unic-char-property" @@ -4510,9 +4510,9 @@ checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" [[package]] name = "url" -version = "2.5.4" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", @@ -4563,7 +4563,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21c7a224a7eaf3f98c1bad772fbaee56394dce185ef7b19a2e0ca5e3d274165d" dependencies = [ "bindgen", - "bitflags 2.9.2", + "bitflags 2.9.3", "fslock", "gzip-header", "home", @@ -4747,7 +4747,7 @@ version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "rustix 1.0.8", "wayland-backend", "wayland-scanner", @@ -4759,7 +4759,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "cursor-icon", "wayland-backend", ] @@ -4781,7 +4781,7 @@ version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "wayland-backend", "wayland-client", "wayland-scanner", @@ -4793,7 +4793,7 @@ version = "0.32.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "wayland-backend", "wayland-client", "wayland-scanner", @@ -4805,7 +4805,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "wayland-backend", "wayland-client", "wayland-protocols 0.31.2", @@ -4818,7 +4818,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a07a14257c077ab3279987c4f8bb987851bf57081b93710381daea94f2c2c032" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "wayland-backend", "wayland-client", "wayland-protocols 0.32.9", @@ -4831,7 +4831,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "wayland-backend", "wayland-client", "wayland-protocols 0.31.2", @@ -4844,7 +4844,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efd94963ed43cf9938a090ca4f7da58eb55325ec8200c3848963e98dc25b78ec" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "wayland-backend", "wayland-client", "wayland-protocols 0.32.9", @@ -4909,7 +4909,7 @@ name = "wgpu" version = "26.0.0" dependencies = [ "arrayvec", - "bitflags 2.9.2", + "bitflags 2.9.3", "bytemuck", "cfg-if", "cfg_aliases 0.2.1", @@ -4955,7 +4955,7 @@ dependencies = [ "arrayvec", "bit-set 0.8.0", "bit-vec 0.8.0", - "bitflags 2.9.2", + "bitflags 2.9.3", "bytemuck", "cfg_aliases 0.2.1", "document-features", @@ -5077,7 +5077,7 @@ dependencies = [ "arrayvec", "ash", "bit-set 0.8.0", - "bitflags 2.9.2", + "bitflags 2.9.3", "block", "bytemuck", "cfg-if", @@ -5128,7 +5128,7 @@ name = "wgpu-info" version = "26.0.0" dependencies = [ "anyhow", - "bitflags 2.9.2", + "bitflags 2.9.3", "env_logger", "hashbrown", "pico-args", @@ -5153,7 +5153,7 @@ dependencies = [ "anyhow", "approx", "arrayvec", - "bitflags 2.9.2", + "bitflags 2.9.3", "bytemuck", "cargo_metadata", "cfg-if", @@ -5191,7 +5191,7 @@ dependencies = [ name = "wgpu-types" version = "26.0.0" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "bytemuck", "js-sys", "log", @@ -5739,7 +5739,7 @@ dependencies = [ "ahash", "android-activity 0.5.2", "atomic-waker", - "bitflags 2.9.2", + "bitflags 2.9.3", "bytemuck", "calloop 0.12.4", "cfg_aliases 0.1.1", @@ -5788,7 +5788,7 @@ dependencies = [ "ahash", "android-activity 0.6.0", "atomic-waker", - "bitflags 2.9.2", + "bitflags 2.9.3", "block2 0.5.1", "bytemuck", "calloop 0.13.0", @@ -5833,9 +5833,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" dependencies = [ "memchr", ] @@ -5852,7 +5852,7 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", ] [[package]] @@ -5914,7 +5914,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.9.2", + "bitflags 2.9.3", "dlib", "log", "once_cell", From fdde05c7c0b8d5c0ea06a1ec04554a981d59ccef Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 25 Aug 2025 04:22:26 -0400 Subject: [PATCH 157/303] Update cts digest to f164473 (#8143) --- cts_runner/revision.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cts_runner/revision.txt b/cts_runner/revision.txt index 1b89eb0da00..782dc437bf3 100644 --- a/cts_runner/revision.txt +++ b/cts_runner/revision.txt @@ -1 +1 @@ -94f4ce1d37ff6410bfcf95a8963f5fee853cfc15 +f164473e801f80c0e560e67a9abb356b09e06506 From 1301f80688cca5add83d9d12af00c9d5510a9d24 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 25 Aug 2025 14:10:50 +0000 Subject: [PATCH 158/303] Update Rust crate cargo_metadata to 0.22 (#8144) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 506c1209bcb..b51813cbaf9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -606,9 +606,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84982c6c0ae343635a3a4ee6dedef965513735c8b183caa7289fa6e27399ebd4" +checksum = "8abf5d501fd757c2d2ee78d0cc40f606e92e3a63544420316565556ed28485e2" dependencies = [ "serde", ] @@ -631,9 +631,9 @@ dependencies = [ [[package]] name = "cargo_metadata" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cfca2aaa699835ba88faf58a06342a314a950d2b9686165e038286c30316868" +checksum = "0c3f56c207c76c07652489840ff98687dcf213de178ac0974660d6fefeaf5ec6" dependencies = [ "camino", "cargo-platform", diff --git a/Cargo.toml b/Cargo.toml index ceea21bb873..e039de4d896 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -103,7 +103,7 @@ bytemuck = { version = "1.22", features = [ "extern_crate_alloc", "min_const_generics", ] } -cargo_metadata = "0.21" +cargo_metadata = "0.22" cfg_aliases = "0.2.1" cfg-if = "1" criterion = "0.7" @@ -176,7 +176,7 @@ ron = "0.10" # see discussion here (including with some other alternatives): https://github.com/gfx-rs/wgpu/issues/6999 # (using default-features = false to support no-std build, avoiding any extra features that may require std::collections) rustc-hash = { version = "1.1", default-features = false } -serde_json = "1.0.118" +serde_json = "1.0.143" serde = { version = "1.0.219", default-features = false } shell-words = "1" smallvec = "1.13.1" From 884cea5ad913ba5fc44d336ed30b940f25b75c0e Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Mon, 25 Aug 2025 11:54:30 -0400 Subject: [PATCH 159/303] Narrow locks in queue::write_buffer (#8146) --- wgpu-core/src/device/queue.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index a58c076d83c..63f9130b61e 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -542,13 +542,10 @@ impl Queue { return Ok(()); }; - let snatch_guard = self.device.snatchable_lock.read(); - // Platform validation requires that the staging buffer always be // freed, even if an error occurs. All paths from here must call // `device.pending_writes.consume`. let mut staging_buffer = StagingBuffer::new(&self.device, data_size)?; - let mut pending_writes = self.pending_writes.lock(); let staging_buffer = { profiling::scope!("copy"); @@ -556,6 +553,9 @@ impl Queue { staging_buffer.flush() }; + let snatch_guard = self.device.snatchable_lock.read(); + let mut pending_writes = self.pending_writes.lock(); + let result = self.write_staging_buffer_impl( &snatch_guard, &mut pending_writes, @@ -564,7 +564,12 @@ impl Queue { buffer_offset, ); + drop(snatch_guard); + pending_writes.consume(staging_buffer); + + drop(pending_writes); + result } @@ -595,15 +600,15 @@ impl Queue { let buffer = buffer.get()?; - let snatch_guard = self.device.snatchable_lock.read(); - let mut pending_writes = self.pending_writes.lock(); - // At this point, we have taken ownership of the staging_buffer from the // user. Platform validation requires that the staging buffer always // be freed, even if an error occurs. All paths from here must call // `device.pending_writes.consume`. let staging_buffer = staging_buffer.flush(); + let snatch_guard = self.device.snatchable_lock.read(); + let mut pending_writes = self.pending_writes.lock(); + let result = self.write_staging_buffer_impl( &snatch_guard, &mut pending_writes, @@ -612,7 +617,12 @@ impl Queue { buffer_offset, ); + drop(snatch_guard); + pending_writes.consume(staging_buffer); + + drop(pending_writes); + result } From 6adb058c5088eb8262be6c1326100849be418d98 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Mon, 25 Aug 2025 12:42:19 -0400 Subject: [PATCH 160/303] [ci] Fix minimal version job (#8147) --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index e039de4d896..b28edfcf10d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -187,7 +187,7 @@ syn = "2.0.98" toml = "0.9.0" trybuild = "1" tracy-client = "0.18" -thiserror = { version = "2.0.11", default-features = false } +thiserror = { version = "2.0.12", default-features = false } unicode-ident = "1.0.5" walkdir = "2.3" winit = { version = "0.29", features = ["android-native-activity"] } From 9a8dbfb85cc01d3ede7a94fe248f4e9c28b580eb Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Mon, 25 Aug 2025 10:43:17 -0700 Subject: [PATCH 161/303] Link image_copy depth/stencil dx12 failures to #8133 (#8148) --- cts_runner/test.lst | 1 + 1 file changed, 1 insertion(+) diff --git a/cts_runner/test.lst b/cts_runner/test.lst index b0a08098f84..918b37e06d2 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -73,6 +73,7 @@ webgpu:api,validation,encoding,queries,general:occlusion_query,query_index:* webgpu:shader,validation,extension,dual_source_blending:blend_src_syntax_validation:* webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_usage_and_aspect:* webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_buffer_size:* +// image_copy depth/stencil failures on dx12: https://github.com/gfx-rs/wgpu/issues/8133 fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_buffer_offset:format="depth32float";aspect="depth-only";copyType="CopyT2B" fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_buffer_offset:format="depth24plus-stencil8";aspect="stencil-only";copyType="CopyB2T" fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_buffer_offset:format="depth24plus-stencil8";aspect="stencil-only";copyType="CopyT2B" From 0372d318caab9bc0fcb2c43a7da14738d9133a74 Mon Sep 17 00:00:00 2001 From: David Duarte Date: Wed, 27 Aug 2025 16:16:20 +0200 Subject: [PATCH 162/303] ci: Update vulkan sdk to 1.4.321.0 (#8157) --- .github/workflows/ci.yml | 18 ++++++++++-------- .github/workflows/shaders.yml | 18 +++++++++--------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cc913c35f5c..029de381c13 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,8 +19,8 @@ env: # # Sourced from https://vulkan.lunarg.com/sdk/home#linux - VULKAN_SDK_VERSION: "1.4.313" - VULKAN_FULL_SDK_VERSION: "1.4.313.0" + VULKAN_SDK_VERSION: "1.4.321" + VULKAN_FULL_SDK_VERSION: "1.4.321.0" # These Mesa version definition is duplicated in the install-mesa action. MESA_VERSION: "24.3.4" @@ -608,14 +608,16 @@ jobs: run: | set -e - sudo apt-get update -y -qq + curl -L --retry 5 https://sdk.lunarg.com/sdk/download/${{ env.VULKAN_FULL_SDK_VERSION }}/linux/vulkansdk-linux-x86_64-${{ env.VULKAN_FULL_SDK_VERSION }}.tar.xz -o vulkan-sdk.tar.xz + mkdir vulkan-sdk + tar xpf vulkan-sdk.tar.xz -C vulkan-sdk + + mv ./vulkan-sdk/${{ env.VULKAN_FULL_SDK_VERSION }} $HOME/VulkanSDK - # vulkan sdk - wget -qO - https://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo apt-key add - - sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-${{ env.VULKAN_SDK_VERSION }}-noble.list https://packages.lunarg.com/vulkan/${{ env.VULKAN_SDK_VERSION }}/lunarg-vulkan-$VULKAN_SDK_VERSION-noble.list + echo "$HOME/VulkanSDK/x86_64/bin" >> "$GITHUB_PATH" + echo "LD_LIBRARY_PATH=$HOME/VulkanSDK/x86_64/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" >> "$GITHUB_ENV" + echo "VK_ADD_LAYER_PATH=$HOME/VulkanSDK/x86_64/share/vulkan/explicit_layer.d" >> "$GITHUB_ENV" - sudo apt-get update - sudo apt install -y vulkan-sdk - name: (Linux) Install Mesa if: matrix.os == 'ubuntu-24.04' diff --git a/.github/workflows/shaders.yml b/.github/workflows/shaders.yml index 084602ff118..9bd57478987 100644 --- a/.github/workflows/shaders.yml +++ b/.github/workflows/shaders.yml @@ -15,9 +15,8 @@ on: env: # Sourced from https://vulkan.lunarg.com/sdk/home#linux - # - # We don't include the 4th version number, as it's not used in any URL. - VULKAN_SDK_VERSION: "1.4.313" + VULKAN_SDK_VERSION: "1.4.321" + VULKAN_FULL_SDK_VERSION: "1.4.321.0" # Every time a PR is pushed to, cancel any previous jobs. This # makes us behave nicer to github and get faster turnaround times @@ -104,14 +103,15 @@ jobs: run: | set -e - sudo apt-get update -y -qq + curl -L --retry 5 https://sdk.lunarg.com/sdk/download/${{ env.VULKAN_FULL_SDK_VERSION }}/linux/vulkansdk-linux-x86_64-${{ env.VULKAN_FULL_SDK_VERSION }}.tar.xz -o vulkan-sdk.tar.xz + mkdir vulkan-sdk + tar xpf vulkan-sdk.tar.xz -C vulkan-sdk - # vulkan sdk - wget -qO - https://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo apt-key add - - sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-$VULKAN_SDK_VERSION-noble.list https://packages.lunarg.com/vulkan/$VULKAN_SDK_VERSION/lunarg-vulkan-$VULKAN_SDK_VERSION-noble.list + mv ./vulkan-sdk/${{ env.VULKAN_FULL_SDK_VERSION }} $HOME/VulkanSDK - sudo apt-get update - sudo apt install -y vulkan-sdk + echo "$HOME/VulkanSDK/x86_64/bin" >> "$GITHUB_PATH" + echo "LD_LIBRARY_PATH=$HOME/VulkanSDK/x86_64/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" >> "$GITHUB_ENV" + echo "VK_ADD_LAYER_PATH=$HOME/VulkanSDK/x86_64/share/vulkan/explicit_layer.d" >> "$GITHUB_ENV" - name: Install Graphviz run: sudo apt-get install graphviz From 780bdfc9091af12ed462b30f83205ce451ebf9fe Mon Sep 17 00:00:00 2001 From: David Duarte Date: Wed, 27 Aug 2025 22:26:18 +0200 Subject: [PATCH 163/303] hal/vulkan: Increment counter for intermediate shaders (#8066) --- wgpu-hal/src/vulkan/device.rs | 60 ++++++++++++++++------------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 580c1cb19cf..1297e57f09b 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -1,10 +1,4 @@ -use alloc::{ - borrow::{Cow, ToOwned as _}, - collections::BTreeMap, - ffi::CString, - sync::Arc, - vec::Vec, -}; +use alloc::{borrow::ToOwned as _, collections::BTreeMap, ffi::CString, sync::Arc, vec::Vec}; use core::{ ffi::CStr, mem::{self, MaybeUninit}, @@ -832,6 +826,7 @@ impl super::Device { fn create_shader_module_impl( &self, spv: &[u32], + label: &crate::Label<'_>, ) -> Result { let vk_info = vk::ShaderModuleCreateInfo::default() .flags(vk::ShaderModuleCreateFlags::empty()) @@ -849,6 +844,11 @@ impl super::Device { // VK_ERROR_INVALID_SHADER_NV super::map_host_device_oom_err(err) } + + if let Some(label) = label { + unsafe { self.shared.set_object_name(raw, label) }; + } + Ok(raw) } @@ -924,7 +924,7 @@ impl super::Device { naga::back::spv::write_vec(&module, &info, options, Some(&pipeline_options)) } .map_err(|e| crate::PipelineError::Linkage(stage_flags, format!("{e}")))?; - self.create_shader_module_impl(&spv)? + self.create_shader_module_impl(&spv, &None)? } }; @@ -1899,19 +1899,20 @@ impl crate::Device for super::Device { desc: &crate::ShaderModuleDescriptor, shader: crate::ShaderInput, ) -> Result { - let spv = match shader { - crate::ShaderInput::Naga(naga_shader) => { + let shader_module = match shader { + crate::ShaderInput::Naga(naga_shader) if self .shared .workarounds .contains(super::Workarounds::SEPARATE_ENTRY_POINTS) - || !naga_shader.module.overrides.is_empty() - { - return Ok(super::ShaderModule::Intermediate { - naga_shader, - runtime_checks: desc.runtime_checks, - }); + || !naga_shader.module.overrides.is_empty() => + { + super::ShaderModule::Intermediate { + naga_shader, + runtime_checks: desc.runtime_checks, } + } + crate::ShaderInput::Naga(naga_shader) => { let mut naga_options = self.naga_options.clone(); naga_options.debug_info = naga_shader @@ -1930,32 +1931,27 @@ impl crate::Device for super::Device { binding_array: naga::proc::BoundsCheckPolicy::Unchecked, }; } - Cow::Owned( - naga::back::spv::write_vec( - &naga_shader.module, - &naga_shader.info, - &naga_options, - None, - ) - .map_err(|e| crate::ShaderError::Compilation(format!("{e}")))?, + let spv = naga::back::spv::write_vec( + &naga_shader.module, + &naga_shader.info, + &naga_options, + None, ) + .map_err(|e| crate::ShaderError::Compilation(format!("{e}")))?; + super::ShaderModule::Raw(self.create_shader_module_impl(&spv, &desc.label)?) + } + crate::ShaderInput::SpirV(data) => { + super::ShaderModule::Raw(self.create_shader_module_impl(data, &desc.label)?) } - crate::ShaderInput::SpirV(data) => Cow::Borrowed(data), crate::ShaderInput::Msl { .. } | crate::ShaderInput::Dxil { .. } | crate::ShaderInput::Hlsl { .. } | crate::ShaderInput::Glsl { .. } => unreachable!(), }; - let raw = self.create_shader_module_impl(&spv)?; - - if let Some(label) = desc.label { - unsafe { self.shared.set_object_name(raw, label) }; - } - self.counters.shader_modules.add(1); - Ok(super::ShaderModule::Raw(raw)) + Ok(shader_module) } unsafe fn destroy_shader_module(&self, module: super::ShaderModule) { From ca3f7f89897abf5e1c80d45bd3ae89be21375371 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Wed, 27 Aug 2025 17:45:50 -0400 Subject: [PATCH 164/303] [tests] Add test priorities so that heavy tests run first (#8152) --- .config/nextest.toml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.config/nextest.toml b/.config/nextest.toml index 32c8d09d91d..574ad1b3789 100644 --- a/.config/nextest.toml +++ b/.config/nextest.toml @@ -42,3 +42,12 @@ slow-timeout = { period = "3m", terminate-after = 2 } [[profile.default.overrides]] filter = 'test(~oom_test)' threads-required = "num-test-threads" + +# +# Priorities for slow tests so that they run first, increasing overall test suite speed. +# On software renderers, they can take 10-60 seconds. Compile fail can easily take 30+ +# seconds as it has to compile wgpu. +# +[[profile.default.overrides]] +priority = 1 +filter = 'test(clear_texture) | test(clear_buffer_range_respected) | test(compile_fail) | test(test_api)' From 1c8d769b670533ef93bebfc5261ef4b3031903af Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Wed, 27 Aug 2025 20:42:02 -0700 Subject: [PATCH 165/303] [naga] Introduce `KeywordSet` and `CaseInsensitiveKeywordSet`. (#8136) --- CHANGELOG.md | 1 + naga/src/back/glsl/keywords.rs | 13 +-- naga/src/back/glsl/mod.rs | 2 +- naga/src/back/hlsl/keywords.rs | 19 ++-- naga/src/back/hlsl/writer.rs | 2 +- naga/src/back/msl/keywords.rs | 12 +-- naga/src/back/msl/writer.rs | 2 +- naga/src/back/wgsl/writer.rs | 2 +- naga/src/keywords/wgsl.rs | 12 +-- naga/src/proc/keyword_set.rs | 178 +++++++++++++++++++++++++++++++++ naga/src/proc/mod.rs | 2 + naga/src/proc/namer.rs | 77 +++----------- naga/src/racy_lock.rs | 16 +-- 13 files changed, 213 insertions(+), 125 deletions(-) create mode 100644 naga/src/proc/keyword_set.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index be4e1630a83..56053f637e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -106,6 +106,7 @@ This allows using precompiled shaders without manually checking which backend's - Naga now requires that no type be larger than 1 GB. This limit may be lowered in the future; feedback on an appropriate value for the limit is welcome. By @andyleiserson in [#7950](https://github.com/gfx-rs/wgpu/pull/7950). - If the shader source contains control characters, Naga now replaces them with U+FFFD ("replacement character") in diagnostic output. By @andyleiserson in [#8049](https://github.com/gfx-rs/wgpu/pull/8049). - Add f16 IO polyfill on Vulkan backend to enable SHADER_F16 use without requiring `storageInputOutput16`. By @cryvosh in [#7884](https://github.com/gfx-rs/wgpu/pull/7884). +- For custom Naga backend authors: `naga::proc::Namer` now accepts reserved keywords using two new dedicated types, `proc::{KeywordSet, CaseInsensitiveKeywordSet}`. By @kpreid in [#8136](https://github.com/gfx-rs/wgpu/pull/8136). #### DX12 diff --git a/naga/src/back/glsl/keywords.rs b/naga/src/back/glsl/keywords.rs index ed217d9e60b..aeaec5b03c0 100644 --- a/naga/src/back/glsl/keywords.rs +++ b/naga/src/back/glsl/keywords.rs @@ -1,7 +1,6 @@ +use crate::proc::KeywordSet; use crate::racy_lock::RacyLock; -use hashbrown::HashSet; - pub const RESERVED_KEYWORDS: &[&str] = &[ // // GLSL 4.6 keywords, from https://github.com/KhronosGroup/OpenGL-Registry/blob/d00e11dc1a1ffba581d633f21f70202051248d5c/specs/gl/GLSLangSpec.4.60.html#L2004-L2322 @@ -499,11 +498,5 @@ pub const RESERVED_KEYWORDS: &[&str] = &[ /// significant time during [`Namer::reset`](crate::proc::Namer::reset). /// /// See for benchmarks. -pub static RESERVED_KEYWORD_SET: RacyLock> = RacyLock::new(|| { - let mut set = HashSet::default(); - set.reserve(RESERVED_KEYWORDS.len()); - for &word in RESERVED_KEYWORDS { - set.insert(word); - } - set -}); +pub static RESERVED_KEYWORD_SET: RacyLock = + RacyLock::new(|| KeywordSet::from_iter(RESERVED_KEYWORDS)); diff --git a/naga/src/back/glsl/mod.rs b/naga/src/back/glsl/mod.rs index e78af74c844..4c5a9d8cbcb 100644 --- a/naga/src/back/glsl/mod.rs +++ b/naga/src/back/glsl/mod.rs @@ -663,7 +663,7 @@ impl<'a, W: Write> Writer<'a, W> { namer.reset( module, &keywords::RESERVED_KEYWORD_SET, - &[], + proc::CaseInsensitiveKeywordSet::empty(), &[ "gl_", // all GL built-in variables "_group", // all normal bindings diff --git a/naga/src/back/hlsl/keywords.rs b/naga/src/back/hlsl/keywords.rs index 7b2ab839d4c..13f48cef8b5 100644 --- a/naga/src/back/hlsl/keywords.rs +++ b/naga/src/back/hlsl/keywords.rs @@ -1,7 +1,6 @@ +use crate::proc::{CaseInsensitiveKeywordSet, KeywordSet}; use crate::racy_lock::RacyLock; -use hashbrown::HashSet; - // When compiling with FXC without strict mode, these keywords are actually case insensitive. // If you compile with strict mode and specify a different casing like "Pass" instead in an identifier, FXC will give this error: // "error X3086: alternate cases for 'pass' are deprecated in strict mode" @@ -927,17 +926,11 @@ pub const TYPES: &[&str] = &{ /// significant time during [`Namer::reset`](crate::proc::Namer::reset). /// /// See for benchmarks. -pub static RESERVED_SET: RacyLock> = RacyLock::new(|| { - let mut set = HashSet::default(); - set.reserve(RESERVED.len() + TYPES.len()); - for &word in RESERVED { - set.insert(word); - } - for &word in TYPES { - set.insert(word); - } - set -}); +pub static RESERVED_SET: RacyLock = + RacyLock::new(|| KeywordSet::from_iter(RESERVED.iter().chain(TYPES))); + +pub static RESERVED_CASE_INSENSITIVE_SET: RacyLock = + RacyLock::new(|| CaseInsensitiveKeywordSet::from_iter(RESERVED_CASE_INSENSITIVE)); pub const RESERVED_PREFIXES: &[&str] = &[ "__dynamic_buffer_offsets", diff --git a/naga/src/back/hlsl/writer.rs b/naga/src/back/hlsl/writer.rs index 357b8597521..ab95b9327f9 100644 --- a/naga/src/back/hlsl/writer.rs +++ b/naga/src/back/hlsl/writer.rs @@ -155,7 +155,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { self.namer.reset( module, &super::keywords::RESERVED_SET, - super::keywords::RESERVED_CASE_INSENSITIVE, + &super::keywords::RESERVED_CASE_INSENSITIVE_SET, super::keywords::RESERVED_PREFIXES, &mut self.names, ); diff --git a/naga/src/back/msl/keywords.rs b/naga/src/back/msl/keywords.rs index e4f89bdc002..315af754e6c 100644 --- a/naga/src/back/msl/keywords.rs +++ b/naga/src/back/msl/keywords.rs @@ -1,7 +1,6 @@ +use crate::proc::KeywordSet; use crate::racy_lock::RacyLock; -use hashbrown::HashSet; - // MSLS - Metal Shading Language Specification: // https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf // @@ -364,11 +363,4 @@ pub const RESERVED: &[&str] = &[ /// significant time during [`Namer::reset`](crate::proc::Namer::reset). /// /// See for benchmarks. -pub static RESERVED_SET: RacyLock> = RacyLock::new(|| { - let mut set = HashSet::default(); - set.reserve(RESERVED.len()); - for &word in RESERVED { - set.insert(word); - } - set -}); +pub static RESERVED_SET: RacyLock = RacyLock::new(|| KeywordSet::from_iter(RESERVED)); diff --git a/naga/src/back/msl/writer.rs b/naga/src/back/msl/writer.rs index 9c0ac10d160..6fa5c135e34 100644 --- a/naga/src/back/msl/writer.rs +++ b/naga/src/back/msl/writer.rs @@ -4279,7 +4279,7 @@ impl Writer { self.namer.reset( module, &super::keywords::RESERVED_SET, - &[], + proc::CaseInsensitiveKeywordSet::empty(), &[CLAMPED_LOD_LOAD_PREFIX], &mut self.names, ); diff --git a/naga/src/back/wgsl/writer.rs b/naga/src/back/wgsl/writer.rs index 8982242daca..225a63343bf 100644 --- a/naga/src/back/wgsl/writer.rs +++ b/naga/src/back/wgsl/writer.rs @@ -101,7 +101,7 @@ impl Writer { module, &crate::keywords::wgsl::RESERVED_SET, // an identifier must not start with two underscore - &[], + proc::CaseInsensitiveKeywordSet::empty(), &["__", "_naga"], &mut self.names, ); diff --git a/naga/src/keywords/wgsl.rs b/naga/src/keywords/wgsl.rs index df464a10ff4..9bfce05d2f9 100644 --- a/naga/src/keywords/wgsl.rs +++ b/naga/src/keywords/wgsl.rs @@ -4,10 +4,9 @@ Keywords for [WGSL][wgsl] (WebGPU Shading Language). [wgsl]: https://gpuweb.github.io/gpuweb/wgsl.html */ +use crate::proc::KeywordSet; use crate::racy_lock::RacyLock; -use hashbrown::HashSet; - // https://gpuweb.github.io/gpuweb/wgsl/#keyword-summary // last sync: https://github.com/gpuweb/gpuweb/blob/39f2321f547c8f0b7f473cf1d47fba30b1691303/wgsl/index.bs pub const RESERVED: &[&str] = &[ @@ -238,11 +237,4 @@ pub const RESERVED: &[&str] = &[ /// significant time during [`Namer::reset`](crate::proc::Namer::reset). /// /// See for benchmarks. -pub static RESERVED_SET: RacyLock> = RacyLock::new(|| { - let mut set = HashSet::default(); - set.reserve(RESERVED.len()); - for &word in RESERVED { - set.insert(word); - } - set -}); +pub static RESERVED_SET: RacyLock = RacyLock::new(|| KeywordSet::from_iter(RESERVED)); diff --git a/naga/src/proc/keyword_set.rs b/naga/src/proc/keyword_set.rs new file mode 100644 index 00000000000..c2ad5dd5516 --- /dev/null +++ b/naga/src/proc/keyword_set.rs @@ -0,0 +1,178 @@ +use core::{fmt, hash}; + +use crate::racy_lock::RacyLock; +use crate::FastHashSet; + +/// A case-sensitive set of strings, +/// for use with [`Namer`][crate::proc::Namer] to avoid collisions with keywords and other reserved +/// identifiers. +/// +/// This is currently implemented as a hash table. +/// Future versions of Naga may change the implementation based on speed and code size +/// considerations. +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct KeywordSet(FastHashSet<&'static str>); + +impl KeywordSet { + /// Returns a new mutable empty set. + pub fn new() -> Self { + Self::default() + } + + /// Returns a reference to the empty set. + pub fn empty() -> &'static Self { + static EMPTY: RacyLock = RacyLock::new(Default::default); + &EMPTY + } + + /// Returns whether the set contains the given string. + #[inline] + pub fn contains(&self, identifier: &str) -> bool { + self.0.contains(identifier) + } +} + +impl Default for &'static KeywordSet { + fn default() -> Self { + KeywordSet::empty() + } +} + +impl FromIterator<&'static str> for KeywordSet { + fn from_iter>(iter: T) -> Self { + Self(iter.into_iter().collect()) + } +} + +/// Accepts double references so that `KeywordSet::from_iter(&["foo"])` works. +impl<'a> FromIterator<&'a &'static str> for KeywordSet { + fn from_iter>(iter: T) -> Self { + Self::from_iter(iter.into_iter().copied()) + } +} + +impl Extend<&'static str> for KeywordSet { + #[expect( + clippy::useless_conversion, + reason = "doing .into_iter() sooner reduces distinct monomorphizations" + )] + fn extend>(&mut self, iter: T) { + self.0.extend(iter.into_iter()) + } +} + +/// Accepts double references so that `.extend(&["foo"])` works. +impl<'a> Extend<&'a &'static str> for KeywordSet { + fn extend>(&mut self, iter: T) { + self.extend(iter.into_iter().copied()) + } +} + +/// A case-insensitive, ASCII-only set of strings, +/// for use with [`Namer`][crate::proc::Namer] to avoid collisions with keywords and other reserved +/// identifiers. +/// +/// This is currently implemented as a hash table. +/// Future versions of Naga may change the implementation based on speed and code size +/// considerations. +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct CaseInsensitiveKeywordSet(FastHashSet>); + +impl CaseInsensitiveKeywordSet { + /// Returns a new mutable empty set. + pub fn new() -> Self { + Self::default() + } + + /// Returns a reference to the empty set. + pub fn empty() -> &'static Self { + static EMPTY: RacyLock = RacyLock::new(Default::default); + &EMPTY + } + + /// Returns whether the set contains the given string, with comparison + /// by [`str::eq_ignore_ascii_case()`]. + #[inline] + pub fn contains(&self, identifier: &str) -> bool { + self.0.contains(&AsciiUniCase(identifier)) + } +} + +impl Default for &'static CaseInsensitiveKeywordSet { + fn default() -> Self { + CaseInsensitiveKeywordSet::empty() + } +} + +impl FromIterator<&'static str> for CaseInsensitiveKeywordSet { + fn from_iter>(iter: T) -> Self { + Self( + iter.into_iter() + .inspect(debug_assert_ascii) + .map(AsciiUniCase) + .collect(), + ) + } +} + +/// Accepts double references so that `CaseInsensitiveKeywordSet::from_iter(&["foo"])` works. +impl<'a> FromIterator<&'a &'static str> for CaseInsensitiveKeywordSet { + fn from_iter>(iter: T) -> Self { + Self::from_iter(iter.into_iter().copied()) + } +} + +impl Extend<&'static str> for CaseInsensitiveKeywordSet { + fn extend>(&mut self, iter: T) { + self.0.extend( + iter.into_iter() + .inspect(debug_assert_ascii) + .map(AsciiUniCase), + ) + } +} + +/// Accepts double references so that `.extend(&["foo"])` works. +impl<'a> Extend<&'a &'static str> for CaseInsensitiveKeywordSet { + fn extend>(&mut self, iter: T) { + self.extend(iter.into_iter().copied()) + } +} + +/// A string wrapper type with an ascii case insensitive Eq and Hash impl +#[derive(Clone, Copy)] +struct AsciiUniCase + ?Sized>(S); + +impl> fmt::Debug for AsciiUniCase { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.as_ref().fmt(f) + } +} + +impl> PartialEq for AsciiUniCase { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.0.as_ref().eq_ignore_ascii_case(other.0.as_ref()) + } +} + +impl> Eq for AsciiUniCase {} + +impl> hash::Hash for AsciiUniCase { + #[inline] + fn hash(&self, hasher: &mut H) { + for byte in self + .0 + .as_ref() + .as_bytes() + .iter() + .map(|b| b.to_ascii_lowercase()) + { + hasher.write_u8(byte); + } + } +} + +fn debug_assert_ascii(s: &&'static str) { + debug_assert!(s.is_ascii(), "{s:?} not ASCII") +} diff --git a/naga/src/proc/mod.rs b/naga/src/proc/mod.rs index 413e49c1eed..26f873a9435 100644 --- a/naga/src/proc/mod.rs +++ b/naga/src/proc/mod.rs @@ -5,6 +5,7 @@ mod constant_evaluator; mod emitter; pub mod index; +mod keyword_set; mod layouter; mod namer; mod overloads; @@ -17,6 +18,7 @@ pub use constant_evaluator::{ }; pub use emitter::Emitter; pub use index::{BoundsCheckPolicies, BoundsCheckPolicy, IndexableLength, IndexableLengthError}; +pub use keyword_set::{CaseInsensitiveKeywordSet, KeywordSet}; pub use layouter::{Alignment, LayoutError, LayoutErrorInner, Layouter, TypeLayout}; pub use namer::{EntryPointIndex, ExternalTextureNameKey, NameKey, Namer}; pub use overloads::{Conclusion, MissingSpecialType, OverloadSet, Rule}; diff --git a/naga/src/proc/namer.rs b/naga/src/proc/namer.rs index 0b812ff036a..38c1713567e 100644 --- a/naga/src/proc/namer.rs +++ b/naga/src/proc/namer.rs @@ -1,16 +1,15 @@ use alloc::{ borrow::Cow, - boxed::Box, format, string::{String, ToString}, vec::Vec, }; -use core::hash::{Hash, Hasher}; -use hashbrown::HashSet; -use once_cell::race::OnceBox; - -use crate::{arena::Handle, FastHashMap, FastHashSet}; +use crate::{ + arena::Handle, + proc::{keyword_set::CaseInsensitiveKeywordSet, KeywordSet}, + FastHashMap, +}; pub type EntryPointIndex = u16; const SEPARATOR: char = '_'; @@ -86,27 +85,15 @@ pub enum NameKey { /// This processor assigns names to all the things in a module /// that may need identifiers in a textual backend. +#[derive(Default)] pub struct Namer { /// The last numeric suffix used for each base name. Zero means "no suffix". unique: FastHashMap, - keywords: &'static HashSet<&'static str>, - keywords_case_insensitive: FastHashSet>, + keywords: &'static KeywordSet, + keywords_case_insensitive: &'static CaseInsensitiveKeywordSet, reserved_prefixes: Vec<&'static str>, } -impl Default for Namer { - fn default() -> Self { - static DEFAULT_KEYWORDS: OnceBox> = OnceBox::new(); - - Self { - unique: Default::default(), - keywords: DEFAULT_KEYWORDS.get_or_init(|| Box::new(HashSet::default())), - keywords_case_insensitive: Default::default(), - reserved_prefixes: Default::default(), - } - } -} - impl Namer { /// Return a form of `string` suitable for use as the base of an identifier. /// @@ -191,13 +178,11 @@ impl Namer { let mut suffixed = base.to_string(); if base.ends_with(char::is_numeric) || self.keywords.contains(base.as_ref()) - || self - .keywords_case_insensitive - .contains(&AsciiUniCase(base.as_ref())) + || self.keywords_case_insensitive.contains(base.as_ref()) { suffixed.push(SEPARATOR); } - debug_assert!(!self.keywords.contains::(&suffixed)); + debug_assert!(!self.keywords.contains(&suffixed)); // `self.unique` wants to own its keys. This allocates only if we haven't // already done so earlier. self.unique.insert(base.into_owned(), 0); @@ -228,8 +213,8 @@ impl Namer { pub fn reset( &mut self, module: &crate::Module, - reserved_keywords: &'static HashSet<&'static str>, - reserved_keywords_case_insensitive: &[&'static str], + reserved_keywords: &'static KeywordSet, + reserved_keywords_case_insensitive: &'static CaseInsensitiveKeywordSet, reserved_prefixes: &[&'static str], output: &mut FastHashMap, ) { @@ -238,16 +223,7 @@ impl Namer { self.unique.clear(); self.keywords = reserved_keywords; - - debug_assert!(reserved_keywords_case_insensitive - .iter() - .all(|s| s.is_ascii())); - self.keywords_case_insensitive.clear(); - self.keywords_case_insensitive.extend( - reserved_keywords_case_insensitive - .iter() - .map(|string| AsciiUniCase(*string)), - ); + self.keywords_case_insensitive = reserved_keywords_case_insensitive; // Choose fallback names for anonymous entry point return types. let mut entrypoint_type_fallbacks = FastHashMap::default(); @@ -384,33 +360,6 @@ impl Namer { } } -/// A string wrapper type with an ascii case insensitive Eq and Hash impl -struct AsciiUniCase + ?Sized>(S); - -impl> PartialEq for AsciiUniCase { - #[inline] - fn eq(&self, other: &Self) -> bool { - self.0.as_ref().eq_ignore_ascii_case(other.0.as_ref()) - } -} - -impl> Eq for AsciiUniCase {} - -impl> Hash for AsciiUniCase { - #[inline] - fn hash(&self, hasher: &mut H) { - for byte in self - .0 - .as_ref() - .as_bytes() - .iter() - .map(|b| b.to_ascii_lowercase()) - { - hasher.write_u8(byte); - } - } -} - #[test] fn test() { let mut namer = Namer::default(); diff --git a/naga/src/racy_lock.rs b/naga/src/racy_lock.rs index 116808055a6..fcb70b7926b 100644 --- a/naga/src/racy_lock.rs +++ b/naga/src/racy_lock.rs @@ -1,11 +1,3 @@ -#![cfg_attr( - not(any(glsl_out, hlsl_out, msl_out, feature = "wgsl-in", wgsl_out)), - expect( - dead_code, - reason = "RacyLock is only required for the above configurations" - ) -)] - use alloc::boxed::Box; use once_cell::race::OnceBox; @@ -25,17 +17,13 @@ impl RacyLock { init, } } - - /// Loads the internal value, initializing it if required. - pub fn get(&self) -> &T { - self.inner.get_or_init(|| Box::new((self.init)())) - } } impl core::ops::Deref for RacyLock { type Target = T; + /// Loads the internal value, initializing it if required. fn deref(&self) -> &Self::Target { - self.get() + self.inner.get_or_init(|| Box::new((self.init)())) } } From e59cdb55e57f986543234fcc0fba7ce7e87d7d14 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 28 Aug 2025 11:08:47 -0400 Subject: [PATCH 166/303] Remove CODEOWNERS file (#8159) --- .github/CODEOWNERS | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 1cae09787e1..00000000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1,17 +0,0 @@ -* @gfx-rs/wgpu - -/cts_runner/ @crowlkats @gfx-rs/wgpu -/deno_webgpu/ @crowlkats @gfx-rs/wgpu -/naga/ @gfx-rs/naga -/naga-cli/ @gfx-rs/naga - -# Both wgpu and naga teams are owners of naga infrastructure so -# either team can review changes to deps and docs. -naga/Cargo.toml @gfx-rs/wgpu @gfx-rs/naga -naga/README.md @gfx-rs/wgpu @gfx-rs/naga -naga/CHANGELOG.md @gfx-rs/wgpu @gfx-rs/naga -naga-cli/Cargo.toml @gfx-rs/wgpu @gfx-rs/naga - -# We leave the codeowners empty for the changelog, so naga changes -# don't trigger wgpu reviews and vise versa. -/CHANGELOG.md From 97ba77d668d12f77dc5d5f9c4f88c6f5ab1a6f44 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 28 Aug 2025 11:09:07 -0400 Subject: [PATCH 167/303] We're just lowercase bro (#8160) --- .gitignore | 2 +- CHANGELOG.md | 152 +++++++++---------- CONTRIBUTING.md | 52 +++---- GOVERNANCE.md | 22 +-- SECURITY.md | 30 ++-- examples/README.md | 6 +- examples/features/src/storage_texture/mod.rs | 2 +- examples/features/src/uniform_values/mod.rs | 2 +- wgpu-hal/examples/raw-gles.rs | 6 +- wgpu-types/src/lib.rs | 2 +- wgpu/Cargo.toml | 2 +- wgpu/src/backend/webgpu.rs | 2 +- 12 files changed, 140 insertions(+), 140 deletions(-) diff --git a/.gitignore b/.gitignore index f92fb07f943..a23fffc26db 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ # Jujutsu # -# When using the WGPU repository through [Jujutsu](https://github.com/martinvonz/jj), `.jj/` dirs. +# When using the wgpu repository through [Jujutsu](https://github.com/martinvonz/jj), `.jj/` dirs. # are ignored because Jujutsu writes a `.jj/.gitignore` file containing `/*`. Some tools, like # `prettier`, don't handle nested `.gitgnore` properly, but they _do_ handle top-level `.gitignore` # patterns properly. So, include it here, even though we shouldn't need it. :cry: diff --git a/CHANGELOG.md b/CHANGELOG.md index 56053f637e8..c195abde1d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,7 @@ Top level categories: Bottom level categories: -- Naga +- naga - General - DX12 - Vulkan @@ -101,10 +101,10 @@ This allows using precompiled shaders without manually checking which backend's - Make a compacted hal acceleration structure inherit a label from the base BLAS. By @Vecvec in [#8103](https://github.com/gfx-rs/wgpu/pull/8103). - The limits requested for a device must now satisfy `min_subgroup_size <= max_subgroup_size`. By @andyleiserson in [#8085](https://github.com/gfx-rs/wgpu/pull/8085). -#### Naga +#### naga -- Naga now requires that no type be larger than 1 GB. This limit may be lowered in the future; feedback on an appropriate value for the limit is welcome. By @andyleiserson in [#7950](https://github.com/gfx-rs/wgpu/pull/7950). -- If the shader source contains control characters, Naga now replaces them with U+FFFD ("replacement character") in diagnostic output. By @andyleiserson in [#8049](https://github.com/gfx-rs/wgpu/pull/8049). +- naga now requires that no type be larger than 1 GB. This limit may be lowered in the future; feedback on an appropriate value for the limit is welcome. By @andyleiserson in [#7950](https://github.com/gfx-rs/wgpu/pull/7950). +- If the shader source contains control characters, naga now replaces them with U+FFFD ("replacement character") in diagnostic output. By @andyleiserson in [#8049](https://github.com/gfx-rs/wgpu/pull/8049). - Add f16 IO polyfill on Vulkan backend to enable SHADER_F16 use without requiring `storageInputOutput16`. By @cryvosh in [#7884](https://github.com/gfx-rs/wgpu/pull/7884). - For custom Naga backend authors: `naga::proc::Namer` now accepts reserved keywords using two new dedicated types, `proc::{KeywordSet, CaseInsensitiveKeywordSet}`. By @kpreid in [#8136](https://github.com/gfx-rs/wgpu/pull/8136). @@ -122,7 +122,7 @@ This allows using precompiled shaders without manually checking which backend's - Fixed a bug where access to matrices with 2 rows would not work in some cases. By @andyleiserson in [#7438](https://github.com/gfx-rs/wgpu/pull/7438). -#### Naga +#### naga - [wgsl-in] Allow a trailing comma in `@blend_src(…)` attributes. By @ErichDonGubler in [#8137](https://github.com/gfx-rs/wgpu/pull/8137). @@ -142,7 +142,7 @@ This allows using precompiled shaders without manually checking which backend's ### Bug Fixes -#### Naga +#### naga - Fix empty `if` statements causing errors on spirv 1.6+. By @Vecvec in [#7883](https://github.com/gfx-rs/wgpu/pull/7883). @@ -225,7 +225,7 @@ let (device, queue) = adapter By @Vecvec in [#7829](https://github.com/gfx-rs/wgpu/pull/7829). -### Naga +### naga - Added `no_std` support with default features disabled. By @Bushrat011899 in [#7585](https://github.com/gfx-rs/wgpu/pull/7585). - [wgsl-in,ir] Add support for parsing rust-style doc comments via `naga::front::glsl::Frontend::new_with_options`. By @Vrixyz in [#6364](https://github.com/gfx-rs/wgpu/pull/6364). @@ -242,7 +242,7 @@ By @Vecvec in [#7829](https://github.com/gfx-rs/wgpu/pull/7829). - Add extra acceleration structure vertex formats. By @Vecvec in [#7580](https://github.com/gfx-rs/wgpu/pull/7580). - Add acceleration structure limits. By @Vecvec in [#7845](https://github.com/gfx-rs/wgpu/pull/7845). - Add support for clip-distances feature for Vulkan and GL backends. By @dzamkov in [#7730](https://github.com/gfx-rs/wgpu/pull/7730) -- Added `wgpu_types::error::{ErrorType, WebGpuError}` for classification of errors according to WebGPU's [`GPUError`]'s classification scheme, and implement `WebGpuError` for existing errors. This allows users of `wgpu-core` to offload error classification onto the WGPU ecosystem, rather than having to do it themselves without sufficient information. By @ErichDonGubler in [#6547](https://github.com/gfx-rs/wgpu/pull/6547). +- Added `wgpu_types::error::{ErrorType, WebGpuError}` for classification of errors according to WebGPU's [`GPUError`]'s classification scheme, and implement `WebGpuError` for existing errors. This allows users of `wgpu-core` to offload error classification onto the wgpu ecosystem, rather than having to do it themselves without sufficient information. By @ErichDonGubler in [#6547](https://github.com/gfx-rs/wgpu/pull/6547). [`GPUError`]: https://www.w3.org/TR/webgpu/#gpuerror @@ -253,9 +253,9 @@ By @Vecvec in [#7829](https://github.com/gfx-rs/wgpu/pull/7829). - Fix error message for sampler array limit. By @LPGhatguy in [#7704](https://github.com/gfx-rs/wgpu/pull/7704). - Fix bug where using `BufferSlice::get_mapped_range_as_array_buffer()` on a buffer would prevent you from ever unmapping it. Note that this API has changed and is now `BufferView::as_uint8array()`. -#### Naga +#### naga -- Naga now infers the correct binding layout when a resource appears only in an assignment to `_`. By @andyleiserson in [#7540](https://github.com/gfx-rs/wgpu/pull/7540). +- naga now infers the correct binding layout when a resource appears only in an assignment to `_`. By @andyleiserson in [#7540](https://github.com/gfx-rs/wgpu/pull/7540). - Implement `dot4U8Packed` and `dot4I8Packed` for all backends, using specialized intrinsics on SPIR-V, HSLS, and Metal if available, and polyfills everywhere else. By @robamler in [#7494](https://github.com/gfx-rs/wgpu/pull/7494), [#7574](https://github.com/gfx-rs/wgpu/pull/7574), and [#7653](https://github.com/gfx-rs/wgpu/pull/7653). - Add polyfilled `pack4x{I,U}8Clamped` built-ins to all backends and WGSL frontend. By @ErichDonGubler in [#7546](https://github.com/gfx-rs/wgpu/pull/7546). - Allow textureLoad's sample index arg to be unsigned. By @jimblandy in [#7625](https://github.com/gfx-rs/wgpu/pull/7625). @@ -306,7 +306,7 @@ By @Vecvec in [#7829](https://github.com/gfx-rs/wgpu/pull/7829). - The definition of `enum CommandEncoderError` has changed significantly, to reflect which errors can be raised by `CommandEncoder.finish()`. There are also some errors that no longer appear directly in `CommandEncoderError`, and instead appear nested within the `RenderPass` or `ComputePass` variants. - `CopyError` has been removed. Errors that were previously a `CopyError` are now a `CommandEncoderError` returned by `finish()`. (The detailed reasons for copies to fail were and still are described by `TransferError`, which was previously a variant of `CopyError`, and is now a variant of `CommandEncoderError`). -#### Naga +#### naga - Mark `readonly_and_readwrite_storage_textures` & `packed_4x8_integer_dot_product` language extensions as implemented. By @teoxoy in [#7543](https://github.com/gfx-rs/wgpu/pull/7543) - `naga::back::hlsl::Writer::new` has a new `pipeline_options` argument. `hlsl::PipelineOptions::default()` can be passed as a default. The `shader_stage` and `entry_point` members of `pipeline_options` can be used to write only a single entry point when using the HLSL and MSL backends (GLSL and SPIR-V already had this functionality). The Metal and DX12 HALs now write only a single entry point when loading shaders. By @andyleiserson in [#7626](https://github.com/gfx-rs/wgpu/pull/7626). @@ -461,7 +461,7 @@ There is now documentation to describe how this maps to the various debuggers' a By @cwfitzgerald in [#7470](https://github.com/gfx-rs/wgpu/pull/7470) -##### Ensure loops generated by SPIR-V and HLSL Naga backends are bounded +##### Ensure loops generated by SPIR-V and HLSL naga backends are bounded Make sure that all loops in shaders generated by these naga backends are bounded to avoid undefined behaviour due to infinite loops. Note that this may have a @@ -588,7 +588,7 @@ By @cwfitzgerald in [#6811](https://github.com/gfx-rs/wgpu/pull/6811), [#6815](h - new `Features::MSL_SHADER_PASSTHROUGH` run-time feature allows providing pass-through MSL Metal shaders. By @syl20bnr in [#7326](https://github.com/gfx-rs/wgpu/pull/7326). - Added mesh shader support to `wgpu_hal`. By @SupaMaggie70Incorporated in [#7089](https://github.com/gfx-rs/wgpu/pull/7089) -#### Naga +#### naga - Add support for unsigned types when calling textureLoad with the level parameter. By @ygdrasil-io in [#7058](https://github.com/gfx-rs/wgpu/pull/7058). - Support @must_use attribute on function declarations. By @turbocrime in [#6801](https://github.com/gfx-rs/wgpu/pull/6801). @@ -613,15 +613,15 @@ By @cwfitzgerald in [#6811](https://github.com/gfx-rs/wgpu/pull/6811), [#6815](h - Rename `instance_id` and `instance_custom_index` to `instance_index` and `instance_custom_data` by @Vecvec in [#6780](https://github.com/gfx-rs/wgpu/pull/6780) -#### Naga +#### naga -- Naga IR types are now available in the module `naga::ir` (e.g. `naga::ir::Module`). +- naga IR types are now available in the module `naga::ir` (e.g. `naga::ir::Module`). The original names (e.g. `naga::Module`) remain present for compatibility. By @kpreid in [#7365](https://github.com/gfx-rs/wgpu/pull/7365). - Refactored `use` statements to simplify future `no_std` support. By @bushrat011899 in [#7256](https://github.com/gfx-rs/wgpu/pull/7256) -- Naga's WGSL frontend no longer allows using the `&` operator to take the address of a component of a vector, +- naga's WGSL frontend no longer allows using the `&` operator to take the address of a component of a vector, which is not permitted by the WGSL specification. By @andyleiserson in [#7284](https://github.com/gfx-rs/wgpu/pull/7284) -- Naga's use of `termcolor` and `stderr` are now optional behind features of the same names. By @bushrat011899 in [#7482](https://github.com/gfx-rs/wgpu/pull/7482) +- naga's use of `termcolor` and `stderr` are now optional behind features of the same names. By @bushrat011899 in [#7482](https://github.com/gfx-rs/wgpu/pull/7482) #### Vulkan @@ -631,7 +631,7 @@ By @cwfitzgerald in [#6811](https://github.com/gfx-rs/wgpu/pull/6811), [#6815](h ### Bug Fixes -#### Naga +#### naga - Fix some instances of functions which have a return type but don't return a value being incorrectly validated. By @jamienicol in [#7013](https://github.com/gfx-rs/wgpu/pull/7013). - Allow abstract expressions to be used in WGSL function return statements. By @jamienicol in [#7035](https://github.com/gfx-rs/wgpu/pull/7035). @@ -663,7 +663,7 @@ By @cwfitzgerald in [#6811](https://github.com/gfx-rs/wgpu/pull/6811), [#6815](h #### Vulkan - Stop naga causing undefined behavior when a ray query misses. By @Vecvec in [#6752](https://github.com/gfx-rs/wgpu/pull/6752). -- In Naga's SPIR-V backend, avoid duplicating SPIR-V OpTypePointer instructions. By @jimblandy in [#7246](https://github.com/gfx-rs/wgpu/pull/7246). +- In naga's SPIR-V backend, avoid duplicating SPIR-V OpTypePointer instructions. By @jimblandy in [#7246](https://github.com/gfx-rs/wgpu/pull/7246). #### Gles @@ -683,7 +683,7 @@ By @cwfitzgerald in [#6811](https://github.com/gfx-rs/wgpu/pull/6811), [#6815](h ### Performance -#### Naga +#### naga - Replace `unicode-xid` with `unicode-ident`. By @CrazyboyQCD in [#7135](https://github.com/gfx-rs/wgpu/pull/7135) @@ -856,7 +856,7 @@ By @cwfitzgerald in [#6895](https://github.com/gfx-rs/wgpu/pull/6895) #### The `diagnostic(…);` directive is now supported in WGSL -Naga now parses `diagnostic(…);` directives according to the WGSL spec. This allows users to control certain lints, similar to Rust's `allow`, `warn`, and `deny` attributes. For example, in standard WGSL (but, notably, not Naga yet—see ) this snippet would emit a uniformity error: +naga now parses `diagnostic(…);` directives according to the WGSL spec. This allows users to control certain lints, similar to Rust's `allow`, `warn`, and `deny` attributes. For example, in standard WGSL (but, notably, not naga yet—see ) this snippet would emit a uniformity error: ```wgsl @group(0) @binding(0) var s : sampler; @@ -898,15 +898,15 @@ fn main(@builtin(position) p : vec4f) -> @location(0) vec4f { There are some limitations to keep in mind with this new functionality: - We support `@diagnostic(…)` rules as `fn` attributes, but prioritization for rules in statement positions (i.e., `if (…) @diagnostic(…) { … }` is unclear. If you are blocked by not being able to parse `diagnostic(…)` rules in statement positions, please let us know in , so we can determine how to prioritize it! -- Standard WGSL specifies `error`, `warning`, `info`, and `off` severity levels. These are all technically usable now! A caveat, though: warning- and info-level are only emitted to `stderr` via the `log` façade, rather than being reported through a `Result::Err` in Naga or the `CompilationInfo` interface in `wgpu{,-core}`. This will require breaking changes in Naga to fix, and is being tracked by . -- Not all lints can be controlled with `diagnostic(…)` rules. In fact, only the `derivative_uniformity` triggering rule exists in the WGSL standard. That said, Naga contributors are excited to see how this level of control unlocks a new ecosystem of configurable diagnostics. +- Standard WGSL specifies `error`, `warning`, `info`, and `off` severity levels. These are all technically usable now! A caveat, though: warning- and info-level are only emitted to `stderr` via the `log` façade, rather than being reported through a `Result::Err` in naga or the `CompilationInfo` interface in `wgpu{,-core}`. This will require breaking changes in naga to fix, and is being tracked by . +- Not all lints can be controlled with `diagnostic(…)` rules. In fact, only the `derivative_uniformity` triggering rule exists in the WGSL standard. That said, naga contributors are excited to see how this level of control unlocks a new ecosystem of configurable diagnostics. - Finally, `diagnostic(…)` rules are not yet emitted in WGSL output. This means that `wgsl-in` → `wgsl-out` is currently a lossy process. We felt that it was important to unblock users who needed `diagnostic(…)` rules (i.e., ) before we took significant effort to fix this (tracked in ). By @ErichDonGubler in [#6456](https://github.com/gfx-rs/wgpu/pull/6456), [#6148](https://github.com/gfx-rs/wgpu/pull/6148), [#6533](https://github.com/gfx-rs/wgpu/pull/6533), [#6353](https://github.com/gfx-rs/wgpu/pull/6353), [#6537](https://github.com/gfx-rs/wgpu/pull/6537). #### New Features -##### Naga +##### naga - Support atomic operations on fields of global structs in the SPIR-V frontend. By @schell in [#6693](https://github.com/gfx-rs/wgpu/pull/6693). - Clean up tests for atomic operations support in SPIR-V frontend. By @schell in [#6692](https://github.com/gfx-rs/wgpu/pull/6692) @@ -952,7 +952,7 @@ By @ErichDonGubler in [#6456](https://github.com/gfx-rs/wgpu/pull/6456), [#6148] #### Changes -##### Naga +##### naga - Show types of LHS and RHS in binary operation type mismatch errors. By @ErichDonGubler in [#6450](https://github.com/gfx-rs/wgpu/pull/6450). - The GLSL parser now uses less expressions for function calls. By @magcius in [#6604](https://github.com/gfx-rs/wgpu/pull/6604). @@ -1005,7 +1005,7 @@ By @ErichDonGubler in [#6456](https://github.com/gfx-rs/wgpu/pull/6456), [#6148] - Fix `wgpu-info` not showing dx12 adapters. By @wumpf in [#6844](https://github.com/gfx-rs/wgpu/pull/6844). - Use `transform_buffer_offset` when initialising `transform_buffer`. By @Vecvec in [#6864](https://github.com/gfx-rs/wgpu/pull/6864). -#### Naga +#### naga - Fix crash when a texture argument is missing. By @aedm in [#6486](https://github.com/gfx-rs/wgpu/pull/6486) - Emit an error in constant evaluation, rather than crash, in certain cases where `vecN` constructors have less than N arguments. By @ErichDonGubler in [#6508](https://github.com/gfx-rs/wgpu/pull/6508). @@ -1059,7 +1059,7 @@ Below changes were cherry-picked from 24.0.0 development line. ### Themes of this release -This release's theme is one that is likely to repeat for a few releases: convergence with the WebGPU specification! WGPU's design and base functionality are actually determined by two specifications: one for WebGPU, and one for the WebGPU Shading Language. +This release's theme is one that is likely to repeat for a few releases: convergence with the WebGPU specification! wgpu's design and base functionality are actually determined by two specifications: one for WebGPU, and one for the WebGPU Shading Language. This may not sound exciting, but let us convince you otherwise! All major web browsers have committed to offering WebGPU in their environment. Even JS runtimes like [Node][nodejs-webgpu-interest] and [Deno][deno_webgpu-crate-manifest] have communities that are very interested in providing WebGPU! WebGPU is slowly [eating the world][eat-the-world-meaning], as it were. 😀 It's really important, then, that WebGPU implementations behave in ways that one would expect across all platforms. For example, if Firefox's WebGPU implementation were to break when running scripts and shaders that worked just fine in Chrome, that would mean sad users for both application authors _and_ browser authors. @@ -1067,23 +1067,23 @@ This may not sound exciting, but let us convince you otherwise! All major web br [deno_webgpu-crate-manifest]: https://github.com/gfx-rs/wgpu/tree/64a61ee5c69569bbb3db03563997e88a229eba17/deno_webgpu#deno_webgpu [eat-the-world-meaning]: https://www.quora.com/What-did-Marc-Andreessen-mean-when-he-said-that-software-is-eating-the-world -WGPU also benefits from standard, portable behavior in the same way as web browsers. Because of this behavior, it's generally fairly easy to port over usage of WebGPU in JavaScript to WGPU. It is also what lets WGPU go full circle: WGPU can be an implementation of WebGPU on native targets, but _also_ it can use _other implementations of WebGPU_ as a backend in JavaScript when compiled to WASM. Therefore, the same dynamic applies: if WGPU's own behavior were significantly different, then WGPU and end users would be _sad, sad humans_ as soon as they discover places where their nice apps are breaking, right? +wgpu also benefits from standard, portable behavior in the same way as web browsers. Because of this behavior, it's generally fairly easy to port over usage of WebGPU in JavaScript to wgpu. It is also what lets wgpu go full circle: wgpu can be an implementation of WebGPU on native targets, but _also_ it can use _other implementations of WebGPU_ as a backend in JavaScript when compiled to WASM. Therefore, the same dynamic applies: if wgpu's own behavior were significantly different, then wgpu and end users would be _sad, sad humans_ as soon as they discover places where their nice apps are breaking, right? -The answer is: yes, we _do_ have sad, sad humans that really want their WGPU code to work _everywhere_. As Firefox and others use WGPU to implement WebGPU, the above example of Firefox diverging from standard is, unfortunately, today's reality. It _mostly_ behaves the same as a standards-compliant WebGPU, but it still doesn't in many important ways. Of particular note is Naga, its implementation of the WebGPU Shader Language. Shaders are pretty much a black-and-white point of failure in GPU programming; if they don't compile, then you can't use the rest of the API! And yet, it's extremely easy to run into a case like that from : +The answer is: yes, we _do_ have sad, sad humans that really want their wgpu code to work _everywhere_. As Firefox and others use wgpu to implement WebGPU, the above example of Firefox diverging from standard is, unfortunately, today's reality. It _mostly_ behaves the same as a standards-compliant WebGPU, but it still doesn't in many important ways. Of particular note is naga, its implementation of the WebGPU Shader Language. Shaders are pretty much a black-and-white point of failure in GPU programming; if they don't compile, then you can't use the rest of the API! And yet, it's extremely easy to run into a case like that from : ```wgsl fn gimme_a_float() -> f32 { - return 42; // fails in Naga, but standard WGSL happily converts to `f32` + return 42; // fails in naga, but standard WGSL happily converts to `f32` } ``` -We intend to continue making visible strides in converging with specifications for WebGPU and WGSL, as this release has. This is, unfortunately, one of the major reasons that WGPU has no plans to work hard at keeping a SemVer-stable interface for the foreseeable future; we have an entire platform of GPU programming functionality we have to catch up with, and SemVer stability is unfortunately in tension with that. So, for now, you're going to keep seeing major releases and breaking changes. Where possible, we'll try to make that painless, but compromises to do so don't always make sense with our limited resources. +We intend to continue making visible strides in converging with specifications for WebGPU and WGSL, as this release has. This is, unfortunately, one of the major reasons that wgpu has no plans to work hard at keeping a SemVer-stable interface for the foreseeable future; we have an entire platform of GPU programming functionality we have to catch up with, and SemVer stability is unfortunately in tension with that. So, for now, you're going to keep seeing major releases and breaking changes. Where possible, we'll try to make that painless, but compromises to do so don't always make sense with our limited resources. This is also the last planned major version release of 2024; the next milestone is set for January 1st, 2025, according to our regular 12-week cadence (offset from the originally planned date of 2024-10-09 for _this_ release 😅). We'll see you next year! ### Contributor spotlight: @sagudev -This release, we'd like to spotlight the work of @sagudev, who has made significant contributions to the WGPU ecosystem this release. Among other things, they contributed a particularly notable feature where runtime-known indices are finally allowed for use with `const` array values. For example, this WGSL shader previously wasn't allowed: +This release, we'd like to spotlight the work of @sagudev, who has made significant contributions to the wgpu ecosystem this release. Among other things, they contributed a particularly notable feature where runtime-known indices are finally allowed for use with `const` array values. For example, this WGSL shader previously wasn't allowed: ```wgsl const arr: array = array(1, 2, 3, 4); @@ -1095,7 +1095,7 @@ fn what_number_should_i_use(idx: u32) -> u32 { …but now it works! This is significant because this sort of shader rejection was one of the most impactful issues we are aware of for converging with the WGSL specification. There are more still to go—some of which we expect to even more drastically change how folks author shaders—but we suspect that many more will come in the next few releases, including with @sagudev's help. -We're excited for more of @sagudev's contributions via the Servo community. Oh, did we forget to mention that these contributions were motivated by their work on Servo? That's right, a _third_ well-known JavaScript runtime is now using WGPU to implement its WebGPU implementation. We're excited to support Servo to becoming another fully fledged browsing environment this way. +We're excited for more of @sagudev's contributions via the Servo community. Oh, did we forget to mention that these contributions were motivated by their work on Servo? That's right, a _third_ well-known JavaScript runtime is now using wgpu to implement its WebGPU implementation. We're excited to support Servo to becoming another fully fledged browsing environment this way. ### Major Changes @@ -1170,9 +1170,9 @@ fn fs_main() { /* … */ } [optional-entrypoint-in-spec]: https://github.com/gpuweb/gpuweb/issues/4342 -#### WGPU's DX12 backend is now based on the `windows` crate ecosystem, instead of the `d3d12` crate +#### wgpu's DX12 backend is now based on the `windows` crate ecosystem, instead of the `d3d12` crate -WGPU has retired the `d3d12` crate (based on `winapi`), and now uses the `windows` crate for interfacing with Windows. For many, this may not be a change that affects day-to-day work. However, for users who need to vet their dependencies, or who may vendor in dependencies, this may be a nontrivial migration. +wgpu has retired the `d3d12` crate (based on `winapi`), and now uses the `windows` crate for interfacing with Windows. For many, this may not be a change that affects day-to-day work. However, for users who need to vet their dependencies, or who may vendor in dependencies, this may be a nontrivial migration. By @MarijnS95 in [#6006](https://github.com/gfx-rs/wgpu/pull/6006). @@ -1182,7 +1182,7 @@ By @MarijnS95 in [#6006](https://github.com/gfx-rs/wgpu/pull/6006). - Added initial acceleration structure and ray query support into wgpu. By @expenses @daniel-keitel @Vecvec @JMS55 @atlv24 in [#6291](https://github.com/gfx-rs/wgpu/pull/6291) -#### Naga +#### naga - Support constant evaluation for `firstLeadingBit` and `firstTrailingBit` numeric built-ins in WGSL. Front-ends that translate to these built-ins also benefit from constant evaluation. By @ErichDonGubler in [#5101](https://github.com/gfx-rs/wgpu/pull/5101). - Add `first` and `either` sampling types for `@interpolate(flat, …)` in WGSL. By @ErichDonGubler in [#6181](https://github.com/gfx-rs/wgpu/pull/6181). @@ -1192,7 +1192,7 @@ By @MarijnS95 in [#6006](https://github.com/gfx-rs/wgpu/pull/6006). - Support polyfilling `inverse` in WGSL. By @chyyran in [#6385](https://github.com/gfx-rs/wgpu/pull/6385). - Add base support for parsing `requires`, `enable`, and `diagnostic` directives. No extensions or diagnostic filters are yet supported, but diagnostics have improved dramatically. By @ErichDonGubler in [#6352](https://github.com/gfx-rs/wgpu/pull/6352), [#6424](https://github.com/gfx-rs/wgpu/pull/6424), [#6437](https://github.com/gfx-rs/wgpu/pull/6437). - Include error chain information as a message and notes in shader compilation messages. By @ErichDonGubler in [#6436](https://github.com/gfx-rs/wgpu/pull/6436). -- Unify Naga CLI error output with the format of shader compilation messages. By @ErichDonGubler in [#6436](https://github.com/gfx-rs/wgpu/pull/6436). +- Unify naga CLI error output with the format of shader compilation messages. By @ErichDonGubler in [#6436](https://github.com/gfx-rs/wgpu/pull/6436). #### General @@ -1212,7 +1212,7 @@ By @MarijnS95 in [#6006](https://github.com/gfx-rs/wgpu/pull/6006). - Fix incorrect hlsl image output type conversion. By @atlv24 in [#6123](https://github.com/gfx-rs/wgpu/pull/6123). -#### Naga +#### naga - SPIR-V frontend splats depth texture sample and load results. Fixes [issue #4551](https://github.com/gfx-rs/wgpu/issues/4551). By @schell in [#6384](https://github.com/gfx-rs/wgpu/pull/6384). - Accept only `vec3` (not `vecN`) for the `cross` built-in. By @ErichDonGubler in [#6171](https://github.com/gfx-rs/wgpu/pull/6171). @@ -1236,7 +1236,7 @@ By @MarijnS95 in [#6006](https://github.com/gfx-rs/wgpu/pull/6006). - Deduplicate bind group layouts that are created from pipelines with "auto" layouts. By @teoxoy [#6049](https://github.com/gfx-rs/wgpu/pull/6049). - Document `wgpu_hal` bounds-checking promises, and adapt `wgpu_core`'s lazy initialization logic to the slightly weaker-than-expected guarantees. By @jimblandy in [#6201](https://github.com/gfx-rs/wgpu/pull/6201). - Raise validation error instead of panicking in `{Render,Compute}Pipeline::get_bind_group_layout` on native / WebGL. By @bgr360 in [#6280](https://github.com/gfx-rs/wgpu/pull/6280). -- **BREAKING**: Remove the last exposed C symbols in project, located in `wgpu_core::render::bundle::bundle_ffi`, to allow multiple versions of WGPU to compile together. By @ErichDonGubler in [#6272](https://github.com/gfx-rs/wgpu/pull/6272). +- **BREAKING**: Remove the last exposed C symbols in project, located in `wgpu_core::render::bundle::bundle_ffi`, to allow multiple versions of wgpu to compile together. By @ErichDonGubler in [#6272](https://github.com/gfx-rs/wgpu/pull/6272). - Call `flush_mapped_ranges` when unmapping write-mapped buffers. By @teoxoy in [#6089](https://github.com/gfx-rs/wgpu/pull/6089). - When mapping buffers for reading, mark buffers as initialized only when they have `MAP_WRITE` usage. By @teoxoy in [#6178](https://github.com/gfx-rs/wgpu/pull/6178). - Add a separate pipeline constants error. By @teoxoy in [#6094](https://github.com/gfx-rs/wgpu/pull/6094). @@ -1308,7 +1308,7 @@ This release includes `wgpu`, `wgpu-core` and `naga`. All other crates remain at ### Added -#### Naga +#### naga - Added back implementations of PartialEq for more IR types. By @teoxoy in [#6045](https://github.com/gfx-rs/wgpu/pull/6045) @@ -1329,21 +1329,21 @@ This release includes `wgpu`, `wgpu-core` and `naga`. All other crates remain at ### Our first major version release! -For the first time ever, WGPU is being released with a major version (i.e., 22.\* instead of 0.22.\*)! Maintainership has decided to fully adhere to [Semantic Versioning](https://semver.org/)'s recommendations for versioning production software. According to [SemVer 2.0.0's Q&A about when to use 1.0.0 versions (and beyond)](https://semver.org/spec/v2.0.0.html#how-do-i-know-when-to-release-100): +For the first time ever, wgpu is being released with a major version (i.e., 22.\* instead of 0.22.\*)! Maintainership has decided to fully adhere to [Semantic Versioning](https://semver.org/)'s recommendations for versioning production software. According to [SemVer 2.0.0's Q&A about when to use 1.0.0 versions (and beyond)](https://semver.org/spec/v2.0.0.html#how-do-i-know-when-to-release-100): > ### How do I know when to release 1.0.0? > > If your software is being used in production, it should probably already be 1.0.0. If you have a stable API on which users have come to depend, you should be 1.0.0. If you’re worrying a lot about backward compatibility, you should probably already be 1.0.0. -It is a well-known fact that WGPU has been used for applications and platforms already in production for years, at this point. We are often concerned with tracking breaking changes, and affecting these consumers' ability to ship. By releasing our first major version, we publicly acknowledge that this is the case. We encourage other projects in the Rust ecosystem to follow suit. +It is a well-known fact that wgpu has been used for applications and platforms already in production for years, at this point. We are often concerned with tracking breaking changes, and affecting these consumers' ability to ship. By releasing our first major version, we publicly acknowledge that this is the case. We encourage other projects in the Rust ecosystem to follow suit. -Note that while we start to use the major version number, WGPU is _not_ "going stable", as many Rust projects do. We anticipate many breaking changes before we fully comply with the WebGPU spec., which we expect to take a small number of years. +Note that while we start to use the major version number, wgpu is _not_ "going stable", as many Rust projects do. We anticipate many breaking changes before we fully comply with the WebGPU spec., which we expect to take a small number of years. ### Overview -A major ([pun intended](#our-first-major-version-release)) theme of this release is incremental improvement. Among the typically large set of bug fixes, new features, and other adjustments to WGPU by the many contributors listed below, @wumpf and @teoxoy have merged a series of many simplifications to WGPU's internals and, in one case, to the render and compute pass recording APIs. Many of these change WGPU to use atomically reference-counted resource tracking (i.e., `Arc<…>`), rather than using IDs to manage the lifetimes of platform-specific graphics resources in a registry of separate reference counts. This has led us to diagnose and fix many long-standing bugs, and net some neat performance improvements on the order of 40% or more of some workloads. +A major ([pun intended](#our-first-major-version-release)) theme of this release is incremental improvement. Among the typically large set of bug fixes, new features, and other adjustments to wgpu by the many contributors listed below, @wumpf and @teoxoy have merged a series of many simplifications to wgpu's internals and, in one case, to the render and compute pass recording APIs. Many of these change wgpu to use atomically reference-counted resource tracking (i.e., `Arc<…>`), rather than using IDs to manage the lifetimes of platform-specific graphics resources in a registry of separate reference counts. This has led us to diagnose and fix many long-standing bugs, and net some neat performance improvements on the order of 40% or more of some workloads. -While the above is exciting, we acknowledge already finding and fixing some (easy-to-fix) regressions from the above work. If you migrate to WGPU 22 and encounter such bugs, please engage us in the issue tracker right away! +While the above is exciting, we acknowledge already finding and fixing some (easy-to-fix) regressions from the above work. If you migrate to wgpu 22 and encounter such bugs, please engage us in the issue tracker right away! ### Major Changes @@ -1420,7 +1420,7 @@ Add the following flags to `wgpu_types::Features`: atomic operations available on Metal as of 3.1. Add corresponding flags to `naga::valid::Capabilities`. These are supported by the -WGSL front end, and all Naga backends. +WGSL front end, and all naga backends. Platform support: @@ -1465,7 +1465,7 @@ By @teoxoy in [#5901](https://github.com/gfx-rs/wgpu/pull/5901) - These hints may be ignored by some backends. Currently only the Vulkan and D3D12 backends take them into account. - Add `HTMLImageElement` and `ImageData` as external source for copying images. By @Valaphee in [#5668](https://github.com/gfx-rs/wgpu/pull/5668) -#### Naga +#### naga - Added -D, --defines option to naga CLI to define preprocessor macros by @theomonnom in [#5859](https://github.com/gfx-rs/wgpu/pull/5859) - Added type upgrades to SPIR-V atomic support. Added related infrastructure. Tracking issue is [here](https://github.com/gfx-rs/wgpu/issues/4489). By @schell in [#5775](https://github.com/gfx-rs/wgpu/pull/5775). @@ -1533,7 +1533,7 @@ By @teoxoy in [#5901](https://github.com/gfx-rs/wgpu/pull/5901) - Replace `glClear` with `glClearBufferF` because `glDrawBuffers` requires that the ith buffer must be `COLOR_ATTACHMENTi` or `NONE` [#5666](https://github.com/gfx-rs/wgpu/pull/5666) - Return the unmodified version in driver_info. By @Valaphee in [#5753](https://github.com/gfx-rs/wgpu/pull/5753) -#### Naga +#### naga - In spv-out don't decorate a `BindingArray`'s type with `Block` if the type is a struct with a runtime array by @Vecvec in [#5776](https://github.com/gfx-rs/wgpu/pull/5776) - Add `packed` as a keyword for GLSL by @kjarosh in [#5855](https://github.com/gfx-rs/wgpu/pull/5855) @@ -1577,7 +1577,7 @@ This release fixes the validation errors whenever a surface is used with the vul - Fix regression on OpenGL (EGL) where non-sRGB still used sRGB [#5642](https://github.com/gfx-rs/wgpu/pull/5642) -#### Naga +#### naga - Work around shader consumers that have bugs handling `switch` statements with a single body for all cases. These are now written as `do {} while(false);` loops in hlsl-out and glsl-out. By @Imberflur in [#5654](https://github.com/gfx-rs/wgpu/pull/5654) - In hlsl-out, defer `continue` statements in switches by setting a flag and breaking from the switch. This allows such constructs to work with FXC which does not support `continue` within a switch. By @Imberflur in [#5654](https://github.com/gfx-rs/wgpu/pull/5654) @@ -1676,9 +1676,9 @@ By @atlv24 and @cwfitzgerald in [#5154](https://github.com/gfx-rs/wgpu/pull/5154 - Added `wgpu::TextureView::as_hal` - `wgpu::Texture::as_hal` now returns a user-defined type to match the other as_hal functions -#### Naga +#### naga -- Allow user to select which MSL version to use via `--metal-version` with Naga CLI. By @pcleavelin in [#5392](https://github.com/gfx-rs/wgpu/pull/5392) +- Allow user to select which MSL version to use via `--metal-version` with naga CLI. By @pcleavelin in [#5392](https://github.com/gfx-rs/wgpu/pull/5392) - Support `arrayLength` for runtime-sized arrays inside binding arrays (for WGSL input and SPIR-V output). By @kvark in [#5428](https://github.com/gfx-rs/wgpu/pull/5428) - Added `--shader-stage` and `--input-kind` options to naga-cli for specifying vertex/fragment/compute shaders, and frontend. by @ratmice in [#5411](https://github.com/gfx-rs/wgpu/pull/5411) - Added a `create_validator` function to wgpu_core `Device` to create naga `Validator`s. By @atlv24 [#5606](https://github.com/gfx-rs/wgpu/pull/5606) @@ -1737,7 +1737,7 @@ By @atlv24 and @cwfitzgerald in [#5154](https://github.com/gfx-rs/wgpu/pull/5154 - Remove exposed C symbols (`extern "C"` + [no_mangle]) from RenderPass & ComputePass recording. By @wumpf in [#5409](https://github.com/gfx-rs/wgpu/pull/5409). - Fix surfaces being only compatible with first backend enabled on an instance, causing failures when manually specifying an adapter. By @Wumpf in [#5535](https://github.com/gfx-rs/wgpu/pull/5535). -#### Naga +#### naga - In spv-in, remove unnecessary "gl_PerVertex" name check so unused builtins will always be skipped. Prevents validation errors caused by capability requirements of these builtins [#4915](https://github.com/gfx-rs/wgpu/issues/4915). By @Imberflur in [#5227](https://github.com/gfx-rs/wgpu/pull/5227). - In spv-out, check for acceleration and ray-query types when enabling ray-query extension to prevent validation error. By @Vecvec in [#5463](https://github.com/gfx-rs/wgpu/pull/5463) @@ -2021,7 +2021,7 @@ Abstract types make numeric literals easier to use, by automatically converting literals and other constant expressions from abstract numeric types to concrete types when safe and necessary. For example, to build a vector of floating-point -numbers, Naga previously made you write: +numbers, naga previously made you write: ```rust vec3(1.0, 2.0, 3.0) @@ -2033,7 +2033,7 @@ With this change, you can now simply write: vec3(1, 2, 3) ``` -Even though the literals are abstract integers, Naga recognizes +Even though the literals are abstract integers, naga recognizes that it is safe and necessary to convert them to `f32` values in order to build the vector. You can also use abstract values as initializers for global constants and global and local variables, @@ -2044,15 +2044,15 @@ var unit_x: vec2 = vec2(1, 0); ``` The literals `1` and `0` are abstract integers, and the expression -`vec2(1, 0)` is an abstract vector. However, Naga recognizes that +`vec2(1, 0)` is an abstract vector. However, naga recognizes that it can convert that to the concrete type `vec2` to satisfy the given type of `unit_x`. The WGSL specification permits abstract integers and -floating-point values in almost all contexts, but Naga's support +floating-point values in almost all contexts, but naga's support for this is still incomplete. Many WGSL operators and builtin functions are specified to produce abstract results when applied -to abstract inputs, but for now Naga simply concretizes them all -before applying the operation. We will expand Naga's abstract type +to abstract inputs, but for now naga simply concretizes them all +before applying the operation. We will expand naga's abstract type support in subsequent pull requests. As part of this work, the public types `naga::ScalarKind` and `naga::Literal` now have new variants, `AbstractInt` and `AbstractFloat`. @@ -2104,15 +2104,15 @@ By @cwfitzgerald in [#5053](https://github.com/gfx-rs/wgpu/pull/5053) - `@builtin(instance_index)` now properly reflects the range provided in the draw call instead of always counting from 0. By @cwfitzgerald in [#4722](https://github.com/gfx-rs/wgpu/pull/4722). - Desktop GL now supports `POLYGON_MODE_LINE` and `POLYGON_MODE_POINT`. By @valaphee in [#4836](https://github.com/gfx-rs/wgpu/pull/4836). -#### Naga +#### naga -- Naga's WGSL front end now allows operators to produce values with abstract types, rather than concretizing their operands. By @jimblandy in [#4850](https://github.com/gfx-rs/wgpu/pull/4850) and [#4870](https://github.com/gfx-rs/wgpu/pull/4870). -- Naga's WGSL front and back ends now have experimental support for 64-bit floating-point literals: `1.0lf` denotes an `f64` value. There has been experimental support for an `f64` type for a while, but until now there was no syntax for writing literals with that type. As before, Naga module validation rejects `f64` values unless `naga::valid::Capabilities::FLOAT64` is requested. By @jimblandy in [#4747](https://github.com/gfx-rs/wgpu/pull/4747). -- Naga constant evaluation can now process binary operators whose operands are both vectors. By @jimblandy in [#4861](https://github.com/gfx-rs/wgpu/pull/4861). -- Add `--bulk-validate` option to Naga CLI. By @jimblandy in [#4871](https://github.com/gfx-rs/wgpu/pull/4871). -- Naga's `cargo xtask validate` now runs validation jobs in parallel, using the [jobserver](https://crates.io/crates/jobserver) protocol to limit concurrency, and offers a `validate all` subcommand, which runs all available validation types. By @jimblandy in [#4902](https://github.com/gfx-rs/wgpu/pull/4902). +- naga's WGSL front end now allows operators to produce values with abstract types, rather than concretizing their operands. By @jimblandy in [#4850](https://github.com/gfx-rs/wgpu/pull/4850) and [#4870](https://github.com/gfx-rs/wgpu/pull/4870). +- naga's WGSL front and back ends now have experimental support for 64-bit floating-point literals: `1.0lf` denotes an `f64` value. There has been experimental support for an `f64` type for a while, but until now there was no syntax for writing literals with that type. As before, naga module validation rejects `f64` values unless `naga::valid::Capabilities::FLOAT64` is requested. By @jimblandy in [#4747](https://github.com/gfx-rs/wgpu/pull/4747). +- naga constant evaluation can now process binary operators whose operands are both vectors. By @jimblandy in [#4861](https://github.com/gfx-rs/wgpu/pull/4861). +- Add `--bulk-validate` option to naga CLI. By @jimblandy in [#4871](https://github.com/gfx-rs/wgpu/pull/4871). +- naga's `cargo xtask validate` now runs validation jobs in parallel, using the [jobserver](https://crates.io/crates/jobserver) protocol to limit concurrency, and offers a `validate all` subcommand, which runs all available validation types. By @jimblandy in [#4902](https://github.com/gfx-rs/wgpu/pull/4902). - Remove `span` and `validate` features. Always fully validate shader modules, and always track source positions for use in error messages. By @teoxoy in [#4706](https://github.com/gfx-rs/wgpu/pull/4706). -- Introduce a new `Scalar` struct type for use in Naga's IR, and update all frontend, middle, and backend code appropriately. By @jimblandy in [#4673](https://github.com/gfx-rs/wgpu/pull/4673). +- Introduce a new `Scalar` struct type for use in naga's IR, and update all frontend, middle, and backend code appropriately. By @jimblandy in [#4673](https://github.com/gfx-rs/wgpu/pull/4673). - Add more metal keywords. By @fornwall in [#4707](https://github.com/gfx-rs/wgpu/pull/4707). - Add a new `naga::Literal` variant, `I64`, for signed 64-bit literals. [#4711](https://github.com/gfx-rs/wgpu/pull/4711). - Emit and init `struct` member padding always. By @ErichDonGubler in [#4701](https://github.com/gfx-rs/wgpu/pull/4701). @@ -2146,14 +2146,14 @@ By @cwfitzgerald in [#5053](https://github.com/gfx-rs/wgpu/pull/5053) - Create a hidden window per `wgpu::Instance` instead of sharing a global one. By @Zoxc in [#4603](https://github.com/gfx-rs/wgpu/issues/4603) -#### Naga +#### naga - Make module compaction preserve the module's named types, even if they are unused. By @jimblandy in [#4734](https://github.com/gfx-rs/wgpu/pull/4734). - Improve algorithm used by module compaction. By @jimblandy in [#4662](https://github.com/gfx-rs/wgpu/pull/4662). - When reading GLSL, fix the argument types of the double-precision floating-point overloads of the `dot`, `reflect`, `distance`, and `ldexp` builtin functions. Correct the WGSL generated for constructing 64-bit floating-point matrices. Add tests for all the above. By @jimblandy in [#4684](https://github.com/gfx-rs/wgpu/pull/4684). -- Allow Naga's IR types to represent matrices with elements elements of any scalar kind. This makes it possible for Naga IR types to represent WGSL abstract matrices. By @jimblandy in [#4735](https://github.com/gfx-rs/wgpu/pull/4735). +- Allow naga's IR types to represent matrices with elements elements of any scalar kind. This makes it possible for naga IR types to represent WGSL abstract matrices. By @jimblandy in [#4735](https://github.com/gfx-rs/wgpu/pull/4735). - Preserve the source spans for constants and expressions correctly across module compaction. By @jimblandy in [#4696](https://github.com/gfx-rs/wgpu/pull/4696). -- Record the names of WGSL `alias` declarations in Naga IR `Type`s. By @jimblandy in [#4733](https://github.com/gfx-rs/wgpu/pull/4733). +- Record the names of WGSL `alias` declarations in naga IR `Type`s. By @jimblandy in [#4733](https://github.com/gfx-rs/wgpu/pull/4733). #### Metal @@ -2171,7 +2171,7 @@ This release includes `naga` version 0.14.2. The crates `wgpu-core`, `wgpu-hal` ### Bug Fixes -#### Naga +#### naga - When evaluating const-expressions and generating SPIR-V, properly handle `Compose` expressions whose operands are `Splat` expressions. Such expressions are created and marked as constant by the constant evaluator. By @jimblandy in [#4695](https://github.com/gfx-rs/wgpu/pull/4695). @@ -2365,7 +2365,7 @@ By @teoxoy in [#4185](https://github.com/gfx-rs/wgpu/pull/4185) ### Added/New Features -- Re-export Naga. By @exrook in [#4172](https://github.com/gfx-rs/wgpu/pull/4172) +- Re-export naga. By @exrook in [#4172](https://github.com/gfx-rs/wgpu/pull/4172) - Add WinUI 3 SwapChainPanel support. By @ddrboxman in [#4191](https://github.com/gfx-rs/wgpu/pull/4191) ### Changes @@ -3251,7 +3251,7 @@ both `raw_window_handle::HasRawWindowHandle` and `raw_window_handle::HasRawDispl #### Vulkan - Fix `astc_hdr` formats support by @jinleili in [#2971]](https://github.com/gfx-rs/wgpu/pull/2971) -- Update to Naga b209d911 (2022-9-1) to avoid generating SPIR-V that +- Update to naga b209d911 (2022-9-1) to avoid generating SPIR-V that violates Vulkan valid usage rules `VUID-StandaloneSpirv-Flat-06202` and `VUID-StandaloneSpirv-Flat-04744`. By @jimblandy in [#3008](https://github.com/gfx-rs/wgpu/pull/3008) @@ -3279,7 +3279,7 @@ both `raw_window_handle::HasRawWindowHandle` and `raw_window_handle::HasRawDispl - Update Winit to version 0.27 and raw-window-handle to 0.5 by @wyatt-herkamp in [#2918](https://github.com/gfx-rs/wgpu/pull/2918) - Address Clippy 0.1.63 complaints. By @jimblandy in [#2977](https://github.com/gfx-rs/wgpu/pull/2977) - Don't use `PhantomData` for `IdentityManager`'s `Input` type. By @jimblandy in [#2972](https://github.com/gfx-rs/wgpu/pull/2972) -- Changed Naga variant in ShaderSource to `Cow<'static, Module>`, to allow loading global variables by @daxpedda in [#2903](https://github.com/gfx-rs/wgpu/pull/2903) +- Changed naga variant in ShaderSource to `Cow<'static, Module>`, to allow loading global variables by @daxpedda in [#2903](https://github.com/gfx-rs/wgpu/pull/2903) - Updated the maximum binding index to match the WebGPU specification by @nical in [#2957](https://github.com/gfx-rs/wgpu/pull/2957) - Add `unsafe_op_in_unsafe_fn` to Clippy lints in the entire workspace. By @ErichDonGubler in [#3044](https://github.com/gfx-rs/wgpu/pull/3044). @@ -3612,7 +3612,7 @@ DeviceDescriptor { - [WebGL] Add a downlevel capability for rendering to floating point textures by @expenses in [#2729](https://github.com/gfx-rs/wgpu/pull/2729) - allow creating wgpu::Instance from wgpu_core::Instance by @i509VCB in [#2763](https://github.com/gfx-rs/wgpu/pull/2763) - Force binding sizes to be multiples of 16 on webgl by @cwfitzgerald in [#2808](https://github.com/gfx-rs/wgpu/pull/2808) -- Add Naga variant to ShaderSource by @rttad in [#2801](https://github.com/gfx-rs/wgpu/pull/2801) +- Add naga variant to ShaderSource by @rttad in [#2801](https://github.com/gfx-rs/wgpu/pull/2801) - Implement Queue::write_buffer_with by @teoxoy in [#2777](https://github.com/gfx-rs/wgpu/pull/2777) #### Vulkan @@ -4049,7 +4049,7 @@ DeviceDescriptor { - new `PARTIALLY_BOUND_BINDING_ARRAY` - `NON_FILL_POLYGON_MODE` is split into `POLYGON_MODE_LINE` and `POLYGON_MODE_POINT` - fixes: - - many shader-related fixes in Naga-0.7 + - many shader-related fixes in naga-0.7 - fix a panic in resource cleanup happening when they are dropped on another thread - Vulkan: - create SPIR-V per entry point to work around driver bugs @@ -4199,7 +4199,7 @@ DeviceDescriptor { ## v0.8 (2021-04-29) -- Naga is used by default to translate shaders, SPIRV-Cross is optional behind `cross` feature +- naga is used by default to translate shaders, SPIRV-Cross is optional behind `cross` feature - Features: - buffers are zero-initialized - downlevel limits for DX11/OpenGL support @@ -4298,7 +4298,7 @@ DeviceDescriptor { - all transfer operations - all resource creation - bind group matching to the layout - - experimental shader interface matching with Naga + - experimental shader interface matching with naga ### wgpu-core-0.5.6 (2020-07-09) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index be0bddfc1d8..04aaf6fb9c2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,18 +1,18 @@ -This document is a guide for contributions to the WGPU project. +This document is a guide for contributions to the wgpu project. ## Welcome! -First of all, welcome to the WGPU community! 👋 We're glad you want to -contribute. If you are unfamiliar with the WGPU project, we recommend you read +First of all, welcome to the wgpu community! 👋 We're glad you want to +contribute. If you are unfamiliar with the wgpu project, we recommend you read [`GOVERNANCE.md`] for an overview of its goals, and how it's governed. ## Documentation Overview: -- [`GOVERNANCE.md`]: An overview of the WGPU project's goals and governance. -- [`CODE_OF_CONDUCT.md`]: The code of conduct for the WGPU project. -- [`docs/release-checklist.md`]: Checklist for creating a new release of WGPU. -- [`docs/review-checklist.md`]: Checklist for reviewing a pull request in WGPU. -- [`docs/testing.md`]: Information on the test suites in WGPU and Naga. +- [`GOVERNANCE.md`]: An overview of the wgpu project's goals and governance. +- [`CODE_OF_CONDUCT.md`]: The code of conduct for the wgpu project. +- [`docs/release-checklist.md`]: Checklist for creating a new release of wgpu. +- [`docs/review-checklist.md`]: Checklist for reviewing a pull request in wgpu. +- [`docs/testing.md`]: Information on the test suites in wgpu and naga. [`GOVERNANCE.md`]: ./GOVERNANCE.md [`CODE_OF_CONDUCT.md`]: ./CODE_OF_CONDUCT.md @@ -20,9 +20,9 @@ contribute. If you are unfamiliar with the WGPU project, we recommend you read [`docs/review-checklist.md`]: ./docs/review-checklist.md [`docs/testing.md`]: ./docs/testing.md -## Talking to other humans in the WGPU project +## Talking to other humans in the wgpu project -The WGPU project has multiple official platforms for community engagement: +The wgpu project has multiple official platforms for community engagement: - The Matrix channel [`wgpu:matrix.org`](https://matrix.to/#/#wgpu:matrix.org) is dedicated to informal chat about contributions the project. It is @@ -73,10 +73,10 @@ The WGPU project has multiple official platforms for community engagement: [Meeting Link]: https://meet.google.com/ubo-ztcw-gwf [`CODE_OF_CONDUCT.md`]: ./CODE_OF_CONDUCT.md -## Contributing to WGPU +## Contributing to wgpu Community response to contributions are, in general, prioritized based on their -relevance to WGPU's mission and decision-making groups' interest (see +relevance to wgpu's mission and decision-making groups' interest (see [`GOVERNANCE.md`]). ### "What can I work on?" as a new contributor @@ -84,24 +84,24 @@ relevance to WGPU's mission and decision-making groups' interest (see TODO We discourage new contributors from submitting large changes or opinionated -refactors unless they have been specifically validated by WGPU maintainership. +refactors unless they have been specifically validated by wgpu maintainership. These are likely to be rejected on basis of needing discussion before a formal review. -### Setting up a WGPU development environment +### Setting up a wgpu development environment -We use the following components in a WGPU development environment: +We use the following components in a wgpu development environment: - [A Rust toolchain][install-rust] matching the version specified in - [`rust-toolchain.toml`](./rust-toolchain.toml), to compile WGPU's code. If you + [`rust-toolchain.toml`](./rust-toolchain.toml), to compile wgpu's code. If you use `rustup`, this will be automatically installed when you first run a `cargo` command in the repository. - [Taplo](https://taplo.tamasfe.dev/) to keep TOML files formatted. - [Vulkan SDK](https://vulkan.lunarg.com/) to provide Vulkan validation layers and other Vulkan/SPIR-V tools for testing. -Once these are done, you should be ready to hack on WGPU! Drop into your -favorite editor, make some changes to the repository's code, and test that WGPU +Once these are done, you should be ready to hack on wgpu! Drop into your +favorite editor, make some changes to the repository's code, and test that wgpu has been changed the way you expect. Take a look at [`docs/testing.md`] for more info on testing. @@ -111,8 +111,8 @@ and a [`git` dependency][git-deps] pointing to your own fork to share changes with other contributors. Once you are ready to request a review of your changes so they become part of -WGPU public history, create a pull request with your changes committed to a -branch in your own fork of WGPU in GitHub. See documentation for that +wgpu public history, create a pull request with your changes committed to a +branch in your own fork of wgpu in GitHub. See documentation for that [here](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork). [install-rust]: https://www.rust-lang.org/tools/install @@ -157,9 +157,9 @@ assignment is simply to ensure that pull requests don't get neglected. #### Designing new features -As an open source project, WGPU wants to serve a broad audience. This +As an open source project, wgpu wants to serve a broad audience. This helps us cast a wide net for contributors, and widens the impact of -their work. However, WGPU does not promise to incorporate every +their work. However, wgpu does not promise to incorporate every proposed feature. Large efforts that are ultimately rejected tend to burn contributors @@ -176,11 +176,11 @@ Contributors should anticipate that the larger and more complex a pull request is, the less likely it is that reviewers will accept it, regardless of its merits. -The WGPU project has had poor experiences with large, complex pull +The wgpu project has had poor experiences with large, complex pull requests: - Complex pull requests are difficult to review effectively. It is - common for us to debug a problem in WGPU and find that it was + common for us to debug a problem in wgpu and find that it was introduced by some massive pull request that we had reviewed and accepted, showing that we obviously hadn't understood it as well as we'd thought. @@ -190,7 +190,7 @@ requests: stressful to question its design decisions, knowing that changing them will require the author to essentially reimplement the project from scratch. Such pull requests make it hard for maintainers to - uphold their responsibility to keep WGPU maintainable. Incremental + uphold their responsibility to keep wgpu maintainable. Incremental changes are easier to discuss and revise without drama. These problems are serious enough that maintainers may choose to @@ -199,7 +199,7 @@ feature or the technical merit of the code. The problem isn't really the *size* of the pull request: a simple rename, with no changes to functionality, might touch hundreds of -files, but be easy to review. Or, a change to Naga might affect dozens +files, but be easy to review. Or, a change to naga might affect dozens of snapshot test output files, without being hard to understand. Rather, the problem is the *complexity* of the pull request: how many diff --git a/GOVERNANCE.md b/GOVERNANCE.md index 73205cc41f5..b3e7a4086a3 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -1,15 +1,15 @@ -The **WGPU project** is a set of open-source libraries that _enables application +The **wgpu project** is a set of open-source libraries that _enables application authors to write portable and performant graphics programs_. It was originally conceived to provide an implementation of WebGPU for Firefox as the standard evolved, and settled into something that could be shipped on all web browsers. -WGPU has also enjoyed much contribution and use from other projects that require +wgpu has also enjoyed much contribution and use from other projects that require graphics programming. We expect that these sorts of users will continue for the lifetime of project, and we embrace these contributors' needs and effort as the -lifeblood of WGPU. +lifeblood of wgpu. ## Mission -The WGPU community seeks to realize the following directives through the +The wgpu community seeks to realize the following directives through the project: it… 1. …provides libraries for the WebGPU API that… @@ -28,7 +28,7 @@ project: it… ## Decision-making -The WGPU community's decision-making is influenced by the following +The wgpu community's decision-making is influenced by the following groups: * Community leadership: @@ -38,18 +38,18 @@ groups: * Firefox's WebGPU team (@jimblandy, @nical, @teoxoy, @ErichDonGubler, and others) * Deno's WebGPU contributors (@crowlKats) -* Other users that ship applications based on WGPU +* Other users that ship applications based on wgpu It is no coincidence that these groups correspond to the historically most -active and consistent contributors. In general, WGPU's community structure is +active and consistent contributors. In general, wgpu's community structure is meritocratic: social influence is granted proportionate to groups' contribution -to and stake in WGPU's mission. +to and stake in wgpu's mission. These decision-making groups meet together regularly to discuss issues of -importance to the community, with a focus on WGPU's [mission](#Mission). +importance to the community, with a focus on wgpu's [mission](#Mission). --- NOTE: The above is a snapshot of a perpetually changing state of affairs in the -WGPU community. It is not a binding contract between users and decision-makers -of the WGPU project. +wgpu community. It is not a binding contract between users and decision-makers +of the wgpu project. diff --git a/SECURITY.md b/SECURITY.md index 1f7cf02121e..d6651d1e8e6 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,6 +1,6 @@ -# WGPU Security Policy +# wgpu Security Policy -This document describes what is considered a security vulnerability in WGPU and +This document describes what is considered a security vulnerability in wgpu and how vulnerabilities should be reported. @@ -18,10 +18,10 @@ misused, and failures to do so may be considered vulnerabilities. (This is also in accordance with the Rust principle of safe vs. unsafe code, since the `wgpu` library exposes a safe API.) -The WGPU maintainers have discretion in assigning a severity to individual +The wgpu maintainers have discretion in assigning a severity to individual vulnerabilities. It is generally considered a high-severity vulnerability in -WGPU if JavaScript or WebAssembly code, running with privileges of ordinary web -content in a browser that is using WGPU to provide the WebGPU API to that +wgpu if JavaScript or WebAssembly code, running with privileges of ordinary web +content in a browser that is using wgpu to provide the WebGPU API to that content, is able to: - Access data associated with native applications other than the user agent, @@ -31,24 +31,24 @@ content, is able to: - Consume system resources to the point that it is difficult to recover (e.g. by closing the web page). -The WGPU Rust API offers some functionality, both supported and experimental, +The wgpu Rust API offers some functionality, both supported and experimental, that is not part of the WebGPU standard and is not made available in JavaScript -environments using WGPU. Associated vulnerabilities may be assigned lower -severity than vulnerabilities that apply to a WGPU-based WebGPU implementation +environments using wgpu. Associated vulnerabilities may be assigned lower +severity than vulnerabilities that apply to a wgpu-based WebGPU implementation exposed to JavaScript. ## Supported Versions -The WGPU project maintains security support for serious vulnerabilities in the +The wgpu project maintains security support for serious vulnerabilities in the [most recent major release](https://github.com/gfx-rs/wgpu/releases). Fixes for security vulnerabilities found shortly after the initial release of a major version may also be provided for the previous major release. -Mozilla provides security support for versions of WGPU used in [current +Mozilla provides security support for versions of wgpu used in [current versions of Firefox](https://whattrainisitnow.com/). -The version of WGPU that is active can be found in the Firefox repositories: +The version of wgpu that is active can be found in the Firefox repositories: - [release](https://github.com/mozilla-firefox/firefox/blob/release/gfx/wgpu_bindings/Cargo.toml), - [beta](https://github.com/mozilla-firefox/firefox/blob/beta/gfx/wgpu_bindings/Cargo.toml), and @@ -60,11 +60,11 @@ versions or in the latest code on the `trunk` branch. ## Reporting a Vulnerability -Although not all vulnerabilities in WGPU will affect Firefox, Mozilla accepts -all vulnerability reports for WGPU and directs them appropriately. Additionally, -Mozilla serves as the CVE numbering authority for the WGPU project. +Although not all vulnerabilities in wgpu will affect Firefox, Mozilla accepts +all vulnerability reports for wgpu and directs them appropriately. Additionally, +Mozilla serves as the CVE numbering authority for the wgpu project. -To report a security problem with WGPU, create a bug in Mozilla's Bugzilla +To report a security problem with wgpu, create a bug in Mozilla's Bugzilla instance in the [Core :: Graphics :: WebGPU](https://bugzilla.mozilla.org/enter_bug.cgi?product=Core&component=Graphics%3A+WebGPU&groups=core-security&groups=gfx-core-security) component. diff --git a/examples/README.md b/examples/README.md index 2de633e6997..4cdc532751b 100644 --- a/examples/README.md +++ b/examples/README.md @@ -4,7 +4,7 @@ # Examples -If you are just starting your graphics programming journey entirely, we recommend going through [Learn-WGPU](https://sotrh.github.io/learn-wgpu/) +If you are just starting your graphics programming journey entirely, we recommend going through [Learn-wgpu](https://sotrh.github.io/learn-wgpu/) for a mode guided tutorial, which will also teach you the basics of graphics programming. ## Standalone Examples @@ -32,12 +32,12 @@ These examples use a common framework to handle wgpu init, window creation, and #### Graphics -- `hello_triangle` - Provides an example of a bare-bones WGPU workflow using the Winit crate that simply renders a red triangle on a green background. +- `hello_triangle` - Provides an example of a bare-bones wgpu workflow using the Winit crate that simply renders a red triangle on a green background. - `uniform_values` - Demonstrates the basics of enabling shaders and the GPU, in general, to access app state through uniform variables. `uniform_values` also serves as an example of rudimentary app building as the app stores state and takes window-captured keyboard events. The app displays the Mandelbrot Set in grayscale (similar to `storage_texture`) but allows the user to navigate and explore it using their arrow keys and scroll wheel. - `cube` - Introduces the user to slightly more advanced models. The example creates a set of triangles to form a cube on the CPU and then uses a vertex and index buffer to send the generated model to the GPU for usage in rendering. It also uses a texture generated on the CPU to shade the sides of the cube and a uniform variable to apply a transformation matrix to the cube in the shader. - `bunnymark` - Demonstrates many things, but chief among them is performing numerous draw calls with different bind groups in one render pass. The example also uses textures for the icon and uniform buffers to transfer both global and per-particle states. - `skybox` - Shows off too many concepts to list here. The name comes from game development where a "skybox" acts as a background for rendering, usually to add a sky texture for immersion, although they can also be used for backdrops to give the idea of a world beyond the game scene. This example does so much more than this, though, as it uses a car model loaded from a file and uses the user's mouse to rotate the car model in 3d. `skybox` also makes use of depth textures and similar app patterns to `uniform_values`. -- `shadow` - Likely by far the most complex example (certainly the largest in lines of code) of the official WGPU examples. `shadow` demonstrates basic scene rendering with the main attraction being lighting and shadows (as the name implies). It is recommended that any user looking into lighting be very familiar with the basic concepts of not only rendering with WGPU but also the primary mathematical ideas of computer graphics. +- `shadow` - Likely by far the most complex example (certainly the largest in lines of code) of the official wgpu examples. `shadow` demonstrates basic scene rendering with the main attraction being lighting and shadows (as the name implies). It is recommended that any user looking into lighting be very familiar with the basic concepts of not only rendering with wgpu but also the primary mathematical ideas of computer graphics. - `multiple-render-targets` - Demonstrates how to render to two texture targets simultaneously from fragment shader. - `render_to_texture` - Renders to an image texture offscreen, demonstrating both off-screen rendering as well as how to add a sort of resolution-agnostic screenshot feature to an engine. This example either outputs an image file of your naming (pass command line arguments after specifying a `--` like `cargo run --bin wgpu-examples -- render_to_texture "test.png"`) or adds an `img` element containing the image to the page in WASM. - `ray_cube_fragment` - Demonstrates using ray queries with a fragment shader. diff --git a/examples/features/src/storage_texture/mod.rs b/examples/features/src/storage_texture/mod.rs index b028e09a9d1..754e8406bce 100644 --- a/examples/features/src/storage_texture/mod.rs +++ b/examples/features/src/storage_texture/mod.rs @@ -4,7 +4,7 @@ //! //! Storage textures work like normal textures but they operate similar to storage buffers //! in that they can be written to. The issue is that as it stands, write-only is the -//! only valid access mode for storage textures in WGSL and although there is a WGPU feature +//! only valid access mode for storage textures in WGSL and although there is a wgpu feature //! to allow for read-write access, this is unfortunately a native-only feature and thus //! we won't be using it here. If we needed a reference texture, we would need to add a //! second texture to act as a reference and attach that as well. Luckily, we don't need diff --git a/examples/features/src/uniform_values/mod.rs b/examples/features/src/uniform_values/mod.rs index 3ee86767255..7215b72384f 100644 --- a/examples/features/src/uniform_values/mod.rs +++ b/examples/features/src/uniform_values/mod.rs @@ -18,7 +18,7 @@ use std::sync::Arc; // We won't bring StorageBuffer into scope as that might be too easy to confuse -// with actual GPU-allocated WGPU storage buffers. +// with actual GPU-allocated wgpu storage buffers. use encase::ShaderType; use winit::{ event::{Event, KeyEvent, WindowEvent}, diff --git a/wgpu-hal/examples/raw-gles.rs b/wgpu-hal/examples/raw-gles.rs index b7b14e3611b..e90561efe19 100644 --- a/wgpu-hal/examples/raw-gles.rs +++ b/wgpu-hal/examples/raw-gles.rs @@ -31,7 +31,7 @@ fn main() { // Other platforms don't really need one. let window_builder = cfg!(windows).then(|| { winit::window::WindowBuilder::new() - .with_title("WGPU raw GLES example (press Escape to exit)") + .with_title("wgpu raw GLES example (press Escape to exit)") }); // The template will match only the configurations supporting rendering @@ -70,7 +70,7 @@ fn main() { // Glutin tries to create an OpenGL context by default. Force it to use any version of GLES. let context_attributes = glutin::context::ContextAttributesBuilder::new() - // WGPU expects GLES 3.0+. + // wgpu expects GLES 3.0+. .with_context_api(glutin::context::ContextApi::Gles(Some(Version::new(3, 0)))) .build(raw_window_handle); @@ -112,7 +112,7 @@ fn main() { Event::Resumed => { let window = window.take().unwrap_or_else(|| { let window_builder = winit::window::WindowBuilder::new() - .with_title("WGPU raw GLES example (press Escape to exit)"); + .with_title("wgpu raw GLES example (press Escape to exit)"); glutin_winit::finalize_window(window_target, window_builder, &gl_config) .unwrap() }); diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 768658a5bf0..e0be64c1772 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -1190,7 +1190,7 @@ impl DownlevelCapabilities { bitflags::bitflags! { /// Binary flags listing features that may or may not be present on downlevel adapters. /// - /// A downlevel adapter is a GPU adapter that WGPU supports, but with potentially limited + /// A downlevel adapter is a GPU adapter that wgpu supports, but with potentially limited /// features, due to the lack of hardware feature support. /// /// Flags that are **not** present for a downlevel adapter or device usually indicates diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index da200d6e8b2..a6a37da6cb4 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -130,7 +130,7 @@ serde = ["wgpu-core?/serde", "wgpu-types/serde"] ## Enables statically linking DXC. ## -## Normally, to use the modern DXC shader compiler with WGPU, the final application +## Normally, to use the modern DXC shader compiler with wgpu, the final application ## must be shipped alongside `dxcompiler.dll` (min v1.8.2502) (which can be downloaded from [Microsoft's GitHub][dxc]). ## This feature statically links a version of DXC so that no external binaries are required ## to compile DX12 shaders. diff --git a/wgpu/src/backend/webgpu.rs b/wgpu/src/backend/webgpu.rs index 603922f86a8..aeef22fce3b 100644 --- a/wgpu/src/backend/webgpu.rs +++ b/wgpu/src/backend/webgpu.rs @@ -1876,7 +1876,7 @@ impl dispatch::DeviceInterface for WebDevice { Err(crate::CompilationInfo { messages: vec![crate::CompilationMessage { message: - "Passthrough shader not compiled for WGSL on WebGPU backend (WGPU error)" + "Passthrough shader not compiled for WGSL on WebGPU backend (wgpu error)" .to_string(), location: None, message_type: crate::CompilationMessageType::Error, From 2ff46cd7cda46252d91a2468bb73f625b5f31231 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 28 Aug 2025 12:00:14 -0400 Subject: [PATCH 168/303] Remove MULTI_DRAW_INDIRECT feature (#8162) --- CHANGELOG.md | 10 ++++++++ deno_webgpu/webidl.rs | 6 ----- tests/tests/wgpu-gpu/mesh_shader/mod.rs | 5 ++-- wgpu-core/src/command/render.rs | 7 ------ wgpu-hal/src/dx12/adapter.rs | 1 - wgpu-hal/src/gles/adapter.rs | 2 -- wgpu-hal/src/metal/adapter.rs | 5 +--- wgpu-hal/src/vulkan/adapter.rs | 6 ++--- wgpu-hal/src/vulkan/command.rs | 32 ++++++++++++++++++------- wgpu-hal/src/vulkan/mod.rs | 1 + wgpu-types/src/features.rs | 25 ++++--------------- wgpu/src/api/render_pass.rs | 11 ++++++--- wgpu/src/backend/webgpu.rs | 3 +-- 13 files changed, 54 insertions(+), 60 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c195abde1d9..31a05b94129 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,6 +74,16 @@ Difference for SPIR-V passthrough: This allows using precompiled shaders without manually checking which backend's code to pass, for example if you have shaders precompiled for both DXIL and SPIR-V. +#### Multi-draw indirect is now unconditionally supported when indirect draws are supported + +We have removed `Features::MULTI_DRAW_INDIRECT` as it was unconditionally available on all platforms. +`RenderPass::multi_draw_indirect` is now available if the device supports downlevel flag `DownlevelFlags::INDIRECT_EXECUTION`. + +If you are using spirv-passthrough with multi-draw indirect and `gl_DrawID`, you can know if `MULTI_DRAW_INDIRECT` is being emulated +by if the `Feature::MULTI_DRAW_INDIRECT_COUNT` feature is available on the device, this feature cannot be emulated efficicently. + +By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). + ### New Features #### General diff --git a/deno_webgpu/webidl.rs b/deno_webgpu/webidl.rs index 75a19d372c3..2f521f47f23 100644 --- a/deno_webgpu/webidl.rs +++ b/deno_webgpu/webidl.rs @@ -399,8 +399,6 @@ pub enum GPUFeatureName { UniformBufferBindingArrays, #[webidl(rename = "partially-bound-binding-array")] PartiallyBoundBindingArray, - #[webidl(rename = "multi-draw-indirect")] - MultiDrawIndirect, #[webidl(rename = "multi-draw-indirect-count")] MultiDrawIndirectCount, #[webidl(rename = "push-constants")] @@ -470,7 +468,6 @@ pub fn feature_names_to_features(names: Vec) -> wgpu_types::Feat GPUFeatureName::StorageTextureArrayNonUniformIndexing => Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, GPUFeatureName::UniformBufferBindingArrays => Features::UNIFORM_BUFFER_BINDING_ARRAYS, GPUFeatureName::PartiallyBoundBindingArray => Features::PARTIALLY_BOUND_BINDING_ARRAY, - GPUFeatureName::MultiDrawIndirect => Features::MULTI_DRAW_INDIRECT, GPUFeatureName::MultiDrawIndirectCount => Features::MULTI_DRAW_INDIRECT_COUNT, GPUFeatureName::PushConstants => Features::PUSH_CONSTANTS, GPUFeatureName::AddressModeClampToZero => Features::ADDRESS_MODE_CLAMP_TO_ZERO, @@ -593,9 +590,6 @@ pub fn features_to_feature_names(features: wgpu_types::Features) -> HashSet GpuTestConfiguration { wgpu::Features::EXPERIMENTAL_MESH_SHADER | wgpu::Features::EXPERIMENTAL_PASSTHROUGH_SHADERS | match draw_type { - DrawType::Standard | DrawType::Indirect => wgpu::Features::empty(), - DrawType::MultiIndirect => wgpu::Features::MULTI_DRAW_INDIRECT, + DrawType::Standard | DrawType::Indirect | DrawType::MultiIndirect => { + wgpu::Features::empty() + } DrawType::MultiIndirectCount => wgpu::Features::MULTI_DRAW_INDIRECT_COUNT, }, ) diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 6546b71c324..b3c100a10fd 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -2696,13 +2696,6 @@ fn multi_draw_indirect( state.is_ready(family)?; - if count != 1 { - state - .general - .device - .require_features(wgt::Features::MULTI_DRAW_INDIRECT)?; - } - state .general .device diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index 88d01103629..1645088afb4 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -343,7 +343,6 @@ impl super::Adapter { | wgt::Features::DEPTH32FLOAT_STENCIL8 | wgt::Features::INDIRECT_FIRST_INSTANCE | wgt::Features::MAPPABLE_PRIMARY_BUFFERS - | wgt::Features::MULTI_DRAW_INDIRECT | wgt::Features::MULTI_DRAW_INDIRECT_COUNT | wgt::Features::ADDRESS_MODE_CLAMP_TO_BORDER | wgt::Features::ADDRESS_MODE_CLAMP_TO_ZERO diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index 87e8caff667..6016bc8e414 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -479,8 +479,6 @@ impl super::Adapter { wgt::Features::SHADER_EARLY_DEPTH_TEST, supported((3, 1), (4, 2)) || extensions.contains("GL_ARB_shader_image_load_store"), ); - // We emulate MDI with a loop of draw calls. - features.set(wgt::Features::MULTI_DRAW_INDIRECT, indirect_execution); if extensions.contains("GL_ARB_timer_query") { features.set(wgt::Features::TIMESTAMP_QUERY, true); features.set(wgt::Features::TIMESTAMP_QUERY_INSIDE_ENCODERS, true); diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index 44e2c3010a6..47ffbd3c6c1 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -931,10 +931,7 @@ impl super::PrivateCapabilities { | F::EXTERNAL_TEXTURE; features.set(F::FLOAT32_FILTERABLE, self.supports_float_filtering); - features.set( - F::INDIRECT_FIRST_INSTANCE | F::MULTI_DRAW_INDIRECT, - self.indirect_draw_dispatch, - ); + features.set(F::INDIRECT_FIRST_INSTANCE, self.indirect_draw_dispatch); features.set( F::TIMESTAMP_QUERY | F::TIMESTAMP_QUERY_INSIDE_ENCODERS, self.timestamp_query_support diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 71c469806e0..7f888aae14b 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -266,9 +266,7 @@ impl PhysicalDeviceFeatures { requested_features.contains(wgt::Features::INDIRECT_FIRST_INSTANCE), ) //.dual_src_blend(requested_features.contains(wgt::Features::DUAL_SRC_BLENDING)) - .multi_draw_indirect( - requested_features.contains(wgt::Features::MULTI_DRAW_INDIRECT), - ) + .multi_draw_indirect(phd_features.core.multi_draw_indirect != 0) .fill_mode_non_solid(requested_features.intersects( wgt::Features::POLYGON_MODE_LINE | wgt::Features::POLYGON_MODE_POINT, )) @@ -602,7 +600,6 @@ impl PhysicalDeviceFeatures { self.core.draw_indirect_first_instance != 0, ); //if self.core.dual_src_blend != 0 - features.set(F::MULTI_DRAW_INDIRECT, self.core.multi_draw_indirect != 0); features.set(F::POLYGON_MODE_LINE, self.core.fill_mode_non_solid != 0); features.set(F::POLYGON_MODE_POINT, self.core.fill_mode_non_solid != 0); //if self.core.depth_bounds != 0 { @@ -1775,6 +1772,7 @@ impl super::Instance { vk::ImageTiling::OPTIMAL, depth_stencil_required_flags(), ), + multi_draw_indirect: phd_features.core.multi_draw_indirect != 0, non_coherent_map_mask: phd_capabilities.properties.limits.non_coherent_atom_size - 1, can_present: true, //TODO: make configurable diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index 93c6b652a62..651fdcf0cc6 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -1146,15 +1146,29 @@ impl crate::CommandEncoder for super::CommandEncoder { offset: wgt::BufferAddress, draw_count: u32, ) { - unsafe { - self.device.raw.cmd_draw_indexed_indirect( - self.active, - buffer.raw, - offset, - draw_count, - size_of::() as u32, - ) - }; + if draw_count >= 1 && self.device.private_caps.multi_draw_indirect { + unsafe { + self.device.raw.cmd_draw_indexed_indirect( + self.active, + buffer.raw, + offset, + draw_count, + size_of::() as u32, + ) + }; + } else { + for _ in 0..draw_count { + unsafe { + self.device.raw.cmd_draw_indexed_indirect( + self.active, + buffer.raw, + offset, + 1, + size_of::() as u32, + ) + }; + } + } } unsafe fn draw_mesh_tasks_indirect( &mut self, diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 6608331f4fe..8a0bb03fc3c 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -575,6 +575,7 @@ struct PrivateCapabilities { /// Ability to present contents to any screen. Only needed to work around broken platform configurations. can_present: bool, non_coherent_map_mask: wgt::BufferAddress, + multi_draw_indirect: bool, /// True if this adapter advertises the [`robustBufferAccess`][vrba] feature. /// diff --git a/wgpu-types/src/features.rs b/wgpu-types/src/features.rs index 2c4bd7245b3..fc584d3f052 100644 --- a/wgpu-types/src/features.rs +++ b/wgpu-types/src/features.rs @@ -784,28 +784,11 @@ bitflags_array! { /// /// This is a native only feature. const PARTIALLY_BOUND_BINDING_ARRAY = 1 << 13; - /// Allows the user to call [`RenderPass::multi_draw_indirect`] and [`RenderPass::multi_draw_indexed_indirect`]. - /// - /// Allows multiple indirect calls to be dispatched from a single buffer. - /// - /// Natively Supported Platforms: - /// - DX12 - /// - Vulkan - /// - /// Emulated Platforms: - /// - Metal - /// - OpenGL - /// - WebGPU - /// - /// Emulation is preformed by looping over the individual indirect draw calls in the backend. This is still significantly - /// faster than enulating it yourself, as wgpu only does draw call validation once. - /// - /// [`RenderPass::multi_draw_indirect`]: ../wgpu/struct.RenderPass.html#method.multi_draw_indirect - /// [`RenderPass::multi_draw_indexed_indirect`]: ../wgpu/struct.RenderPass.html#method.multi_draw_indexed_indirect - const MULTI_DRAW_INDIRECT = 1 << 14; /// Allows the user to call [`RenderPass::multi_draw_indirect_count`] and [`RenderPass::multi_draw_indexed_indirect_count`]. /// - /// This allows the use of a buffer containing the actual number of draw calls. + /// This allows the use of a buffer containing the actual number of draw calls. This feature being present also implies + /// that all calls to [`RenderPass::multi_draw_indirect`] and [`RenderPass::multi_draw_indexed_indirect`] are not being emulated + /// with a series of `draw_indirect` calls. /// /// Supported platforms: /// - DX12 @@ -813,6 +796,8 @@ bitflags_array! { /// /// This is a native only feature. /// + /// [`RenderPass::multi_draw_indirect`]: ../wgpu/struct.RenderPass.html#method.multi_draw_indirect + /// [`RenderPass::multi_draw_indexed_indirect`]: ../wgpu/struct.RenderPass.html#method.multi_draw_indexed_indirect /// [`RenderPass::multi_draw_indirect_count`]: ../wgpu/struct.RenderPass.html#method.multi_draw_indirect_count /// [`RenderPass::multi_draw_indexed_indirect_count`]: ../wgpu/struct.RenderPass.html#method.multi_draw_indexed_indirect_count const MULTI_DRAW_INDIRECT_COUNT = 1 << 15; diff --git a/wgpu/src/api/render_pass.rs b/wgpu/src/api/render_pass.rs index 8163b4261f0..0dd96b37ec5 100644 --- a/wgpu/src/api/render_pass.rs +++ b/wgpu/src/api/render_pass.rs @@ -236,6 +236,8 @@ impl RenderPass<'_> { /// /// This is like calling [`RenderPass::draw`] but the contents of the call are specified in the `indirect_buffer`. /// The structure expected in `indirect_buffer` must conform to [`DrawIndirectArgs`](crate::util::DrawIndirectArgs). + /// + /// Calling this requires the device support [`DownlevelFlags::INDIRECT_EXECUTION`]. pub fn draw_indirect(&mut self, indirect_buffer: &Buffer, indirect_offset: BufferAddress) { self.inner .draw_indirect(&indirect_buffer.inner, indirect_offset); @@ -246,6 +248,8 @@ impl RenderPass<'_> { /// /// This is like calling [`RenderPass::draw_indexed`] but the contents of the call are specified in the `indirect_buffer`. /// The structure expected in `indirect_buffer` must conform to [`DrawIndexedIndirectArgs`](crate::util::DrawIndexedIndirectArgs). + /// + /// Calling this requires the device support [`DownlevelFlags::INDIRECT_EXECUTION`]. pub fn draw_indexed_indirect( &mut self, indirect_buffer: &Buffer, @@ -287,10 +291,7 @@ impl RenderPass<'_> { self.inner.execute_bundles(&mut render_bundles); } -} -/// [`Features::MULTI_DRAW_INDIRECT`] must be enabled on the device in order to call these functions. -impl RenderPass<'_> { /// Dispatches multiple draw calls from the active vertex buffer(s) based on the contents of the `indirect_buffer`. /// `count` draw calls are issued. /// @@ -299,6 +300,8 @@ impl RenderPass<'_> { /// The structure expected in `indirect_buffer` must conform to [`DrawIndirectArgs`](crate::util::DrawIndirectArgs). /// These draw structures are expected to be tightly packed. /// + /// Calling this requires the device support [`DownlevelFlags::INDIRECT_EXECUTION`]. + /// /// This drawing command uses the current render state, as set by preceding `set_*()` methods. /// It is not affected by changes to the state that are performed after it is called. pub fn multi_draw_indirect( @@ -320,6 +323,8 @@ impl RenderPass<'_> { /// The structure expected in `indirect_buffer` must conform to [`DrawIndexedIndirectArgs`](crate::util::DrawIndexedIndirectArgs). /// These draw structures are expected to be tightly packed. /// + /// Calling this requires the device support [`DownlevelFlags::INDIRECT_EXECUTION`]. + /// /// This drawing command uses the current render state, as set by preceding `set_*()` methods. /// It is not affected by changes to the state that are performed after it is called. pub fn multi_draw_indexed_indirect( diff --git a/wgpu/src/backend/webgpu.rs b/wgpu/src/backend/webgpu.rs index aeef22fce3b..75049d38ceb 100644 --- a/wgpu/src/backend/webgpu.rs +++ b/wgpu/src/backend/webgpu.rs @@ -772,8 +772,7 @@ const FEATURES_MAPPING: [(wgt::Features, webgpu_sys::GpuFeatureName); 15] = [ ]; fn map_wgt_features(supported_features: webgpu_sys::GpuSupportedFeatures) -> wgt::Features { - // We emulate MDI. - let mut features = wgt::Features::MULTI_DRAW_INDIRECT; + let mut features = wgt::Features::empty(); for (wgpu_feat, web_feat) in FEATURES_MAPPING { match wasm_bindgen::JsValue::from(web_feat).as_string() { Some(value) if supported_features.has(&value) => features |= wgpu_feat, From 967cd4b7ff25e209569a92b83f91db3913ae21c7 Mon Sep 17 00:00:00 2001 From: David Duarte Date: Thu, 28 Aug 2025 18:01:15 +0200 Subject: [PATCH 169/303] ci: Extract linux vulkan installation into its own action (#8164) --- .github/actions/install-vulkan-sdk/action.yml | 23 +++++++++++++++++++ .github/workflows/ci.yml | 16 ++----------- .github/workflows/shaders.yml | 19 +-------------- 3 files changed, 26 insertions(+), 32 deletions(-) create mode 100644 .github/actions/install-vulkan-sdk/action.yml diff --git a/.github/actions/install-vulkan-sdk/action.yml b/.github/actions/install-vulkan-sdk/action.yml new file mode 100644 index 00000000000..8446c2c8854 --- /dev/null +++ b/.github/actions/install-vulkan-sdk/action.yml @@ -0,0 +1,23 @@ +name: "Install Vulkan SDK" +description: "Install Vulkan SDK" +runs: + using: "composite" + steps: + - name: Install Vulkan SDK + shell: bash + env: + # Sourced from https://vulkan.lunarg.com/sdk/home#linux + VULKAN_SDK_VERSION: "1.4.321" + VULKAN_FULL_SDK_VERSION: "1.4.321.0" + run: | + set -e + + curl -L --retry 5 https://sdk.lunarg.com/sdk/download/${{ env.VULKAN_FULL_SDK_VERSION }}/linux/vulkansdk-linux-x86_64-${{ env.VULKAN_FULL_SDK_VERSION }}.tar.xz -o vulkan-sdk.tar.xz + mkdir vulkan-sdk + tar xpf vulkan-sdk.tar.xz -C vulkan-sdk + + mv ./vulkan-sdk/${{ env.VULKAN_FULL_SDK_VERSION }} $HOME/VulkanSDK + + echo "$HOME/VulkanSDK/x86_64/bin" >> "$GITHUB_PATH" + echo "LD_LIBRARY_PATH=$HOME/VulkanSDK/x86_64/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" >> "$GITHUB_ENV" + echo "VK_ADD_LAYER_PATH=$HOME/VulkanSDK/x86_64/share/vulkan/explicit_layer.d" >> "$GITHUB_ENV" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 029de381c13..30abd643f3b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,7 @@ env: # # Sourced from https://vulkan.lunarg.com/sdk/home#linux + # These Vulkan version definition is duplicated in the install-vulkan action. VULKAN_SDK_VERSION: "1.4.321" VULKAN_FULL_SDK_VERSION: "1.4.321.0" @@ -604,20 +605,7 @@ jobs: - name: (Linux) Install Vulkan SDK if: matrix.os == 'ubuntu-24.04' - shell: bash - run: | - set -e - - curl -L --retry 5 https://sdk.lunarg.com/sdk/download/${{ env.VULKAN_FULL_SDK_VERSION }}/linux/vulkansdk-linux-x86_64-${{ env.VULKAN_FULL_SDK_VERSION }}.tar.xz -o vulkan-sdk.tar.xz - mkdir vulkan-sdk - tar xpf vulkan-sdk.tar.xz -C vulkan-sdk - - mv ./vulkan-sdk/${{ env.VULKAN_FULL_SDK_VERSION }} $HOME/VulkanSDK - - echo "$HOME/VulkanSDK/x86_64/bin" >> "$GITHUB_PATH" - echo "LD_LIBRARY_PATH=$HOME/VulkanSDK/x86_64/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" >> "$GITHUB_ENV" - echo "VK_ADD_LAYER_PATH=$HOME/VulkanSDK/x86_64/share/vulkan/explicit_layer.d" >> "$GITHUB_ENV" - + uses: ./.github/actions/install-vulkan-sdk - name: (Linux) Install Mesa if: matrix.os == 'ubuntu-24.04' diff --git a/.github/workflows/shaders.yml b/.github/workflows/shaders.yml index 9bd57478987..bc2d2843010 100644 --- a/.github/workflows/shaders.yml +++ b/.github/workflows/shaders.yml @@ -13,11 +13,6 @@ on: pull_request: merge_group: -env: - # Sourced from https://vulkan.lunarg.com/sdk/home#linux - VULKAN_SDK_VERSION: "1.4.321" - VULKAN_FULL_SDK_VERSION: "1.4.321.0" - # Every time a PR is pushed to, cancel any previous jobs. This # makes us behave nicer to github and get faster turnaround times # on PRs that are pushed to multiple times in rapid succession. @@ -99,19 +94,7 @@ jobs: - uses: actions/checkout@v5 - name: Install Vulkan SDK - shell: bash - run: | - set -e - - curl -L --retry 5 https://sdk.lunarg.com/sdk/download/${{ env.VULKAN_FULL_SDK_VERSION }}/linux/vulkansdk-linux-x86_64-${{ env.VULKAN_FULL_SDK_VERSION }}.tar.xz -o vulkan-sdk.tar.xz - mkdir vulkan-sdk - tar xpf vulkan-sdk.tar.xz -C vulkan-sdk - - mv ./vulkan-sdk/${{ env.VULKAN_FULL_SDK_VERSION }} $HOME/VulkanSDK - - echo "$HOME/VulkanSDK/x86_64/bin" >> "$GITHUB_PATH" - echo "LD_LIBRARY_PATH=$HOME/VulkanSDK/x86_64/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" >> "$GITHUB_ENV" - echo "VK_ADD_LAYER_PATH=$HOME/VulkanSDK/x86_64/share/vulkan/explicit_layer.d" >> "$GITHUB_ENV" + uses: ./.github/actions/install-vulkan-sdk - name: Install Graphviz run: sudo apt-get install graphviz From 2e78c5b061ff6e848e4cfe346dd4fb29b3c95378 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Fri, 22 Aug 2025 10:05:44 -0700 Subject: [PATCH 170/303] typo: s/investiagate/investigate --- naga/tests/naga/validation.rs | 2 +- naga/tests/naga/wgsl_errors.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/naga/tests/naga/validation.rs b/naga/tests/naga/validation.rs index 78fb8ea37a5..0a0b6fdfc0b 100644 --- a/naga/tests/naga/validation.rs +++ b/naga/tests/naga/validation.rs @@ -1,5 +1,5 @@ #![allow( - // We need to investiagate these. + // We need to investigate these. clippy::result_large_err )] diff --git a/naga/tests/naga/wgsl_errors.rs b/naga/tests/naga/wgsl_errors.rs index adb60a18485..c8d7b331627 100644 --- a/naga/tests/naga/wgsl_errors.rs +++ b/naga/tests/naga/wgsl_errors.rs @@ -3,7 +3,7 @@ Tests for the WGSL front end. */ #![cfg(feature = "wgsl-in")] #![allow( - // We need to investiagate these. + // We need to investigate these. clippy::result_large_err )] From e939bf273a41634c38116def66b9507d47ad57a3 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Fri, 22 Aug 2025 10:05:44 -0700 Subject: [PATCH 171/303] feat(naga): expose `{,Implemented}EnableExtension` --- naga/src/front/wgsl/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/naga/src/front/wgsl/mod.rs b/naga/src/front/wgsl/mod.rs index 1080392cc61..b7ae910a8dd 100644 --- a/naga/src/front/wgsl/mod.rs +++ b/naga/src/front/wgsl/mod.rs @@ -11,6 +11,8 @@ mod parse; #[cfg(test)] mod tests; +pub use parse::directive::enable_extension::{EnableExtension, ImplementedEnableExtension}; + pub use crate::front::wgsl::error::ParseError; pub use crate::front::wgsl::parse::directive::language_extension::{ ImplementedLanguageExtension, LanguageExtension, UnimplementedLanguageExtension, From 1689c56ee3674518b258287e5f7cd00811d0ec76 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Fri, 22 Aug 2025 10:05:44 -0700 Subject: [PATCH 172/303] refactor(naga): use explicit `\x20` in error output instead of trailing spaces --- naga/tests/naga/wgsl_errors.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/naga/tests/naga/wgsl_errors.rs b/naga/tests/naga/wgsl_errors.rs index c8d7b331627..a874112aa29 100644 --- a/naga/tests/naga/wgsl_errors.rs +++ b/naga/tests/naga/wgsl_errors.rs @@ -2112,7 +2112,7 @@ error: type mismatch for reject and accept values in `select` call │ 5 │ _ = select(true, 1, false); │ ^^^^ ^ accept value of type `{AbstractInt}` - │ │ + │ │\x20\x20\x20\x20\x20\x20 │ reject value of type `bool` ", @@ -3488,19 +3488,19 @@ fn inconsistent_type() { "fn foo() -> f32 { return dot(vec4(), vec3()); }", - r#"error: inconsistent type passed as argument #2 to `dot` + "error: inconsistent type passed as argument #2 to `dot` ┌─ wgsl:2:20 │ 2 │ return dot(vec4(), vec3()); │ ^^^ ^^^^^^^^^^ ^^^^^^^^^^ argument #2 has type vec3 - │ │ + │ │\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20 │ this argument has type vec4, which constrains subsequent arguments │ = note: Because argument #1 has type vec4, only the following types = note: (or types that automatically convert to them) are accepted for argument #2: = note: allowed type: vec4 -"#, +", ); } From 4a7b6abb194811e4b2abb77addcc126f74c5023e Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Fri, 22 Aug 2025 10:05:44 -0700 Subject: [PATCH 173/303] Add `F16_IN_F32` downlevel flag for pack/unpack/quantize f16 (#8130) Although the operation of these functions is defined in terms of f16 semantics, the input/output types are not f16, and they are generally available even when native `f16` support is not. But in at least one case, they are only available with `f16` support, so add a new downlevel flag that is cleared when these functions are not available. Add some infrastructure to simplify testing of missing capabilities/extensions, and add tests for a few more kinds of f16 usage. Co-authored-by: Erich Gubler --- CHANGELOG.md | 1 + naga/src/valid/expression.rs | 14 + naga/src/valid/mod.rs | 21 + .../in/glsl/{bits_glsl.frag => bits.frag} | 0 naga/tests/in/glsl/bits.toml | 1 + naga/tests/in/wgsl/bits-optimized-msl.toml | 1 + naga/tests/in/wgsl/bits.toml | 2 + naga/tests/in/wgsl/math-functions.toml | 1 + naga/tests/naga/validation.rs | 4 + naga/tests/naga/wgsl_errors.rs | 386 +++++++++++++----- ...its_glsl.frag.wgsl => glsl-bits.frag.wgsl} | 0 wgpu-core/src/device/mod.rs | 4 + wgpu-hal/src/vulkan/adapter.rs | 11 +- wgpu-types/src/features.rs | 2 +- wgpu-types/src/lib.rs | 6 + 15 files changed, 345 insertions(+), 109 deletions(-) rename naga/tests/in/glsl/{bits_glsl.frag => bits.frag} (100%) create mode 100644 naga/tests/in/glsl/bits.toml create mode 100644 naga/tests/in/wgsl/math-functions.toml rename naga/tests/out/wgsl/{glsl-bits_glsl.frag.wgsl => glsl-bits.frag.wgsl} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31a05b94129..8ba2f28264a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -110,6 +110,7 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). By @kpreid in [#8011](https://github.com/gfx-rs/wgpu/pull/8011). - Make a compacted hal acceleration structure inherit a label from the base BLAS. By @Vecvec in [#8103](https://github.com/gfx-rs/wgpu/pull/8103). - The limits requested for a device must now satisfy `min_subgroup_size <= max_subgroup_size`. By @andyleiserson in [#8085](https://github.com/gfx-rs/wgpu/pull/8085). +- Require new `F16_IN_F32` downlevel flag for `quantizeToF16`, `pack2x16float`, and `unpack2x16float` in WGSL input. By @aleiserson in [#8130](https://github.com/gfx-rs/wgpu/pull/8130). #### naga diff --git a/naga/src/valid/expression.rs b/naga/src/valid/expression.rs index 5661094f33b..68023b5bf01 100644 --- a/naga/src/valid/expression.rs +++ b/naga/src/valid/expression.rs @@ -1060,6 +1060,20 @@ impl super::Validator { arg2, arg3, } => { + if matches!( + fun, + crate::MathFunction::QuantizeToF16 + | crate::MathFunction::Pack2x16float + | crate::MathFunction::Unpack2x16float + ) && !self + .capabilities + .contains(crate::valid::Capabilities::SHADER_FLOAT16_IN_FLOAT32) + { + return Err(ExpressionError::MissingCapabilities( + crate::valid::Capabilities::SHADER_FLOAT16_IN_FLOAT32, + )); + } + let actuals: &[_] = match (arg1, arg2, arg3) { (None, None, None) => &[arg], (Some(arg1), None, None) => &[arg, arg1], diff --git a/naga/src/valid/mod.rs b/naga/src/valid/mod.rs index fe45d3bfb07..24938684afe 100644 --- a/naga/src/valid/mod.rs +++ b/naga/src/valid/mod.rs @@ -170,6 +170,27 @@ bitflags::bitflags! { const SHADER_FLOAT16 = 1 << 26; /// Support for [`ImageClass::External`] const TEXTURE_EXTERNAL = 1 << 27; + /// Support for `quantizeToF16`, `pack2x16float`, and `unpack2x16float`, which store + /// `f16`-precision values in `f32`s. + const SHADER_FLOAT16_IN_FLOAT32 = 1 << 28; + } +} + +impl Capabilities { + /// Returns the extension corresponding to this capability, if there is one. + /// + /// This is used by integration tests. + #[cfg(feature = "wgsl-in")] + #[doc(hidden)] + pub const fn extension(&self) -> Option { + use crate::front::wgsl::ImplementedEnableExtension as Ext; + match *self { + Self::DUAL_SOURCE_BLENDING => Some(Ext::DualSourceBlending), + // NOTE: `SHADER_FLOAT16_IN_FLOAT32` _does not_ require the `f16` extension + Self::SHADER_FLOAT16 => Some(Ext::F16), + Self::CLIP_DISTANCE => Some(Ext::ClipDistances), + _ => None, + } } } diff --git a/naga/tests/in/glsl/bits_glsl.frag b/naga/tests/in/glsl/bits.frag similarity index 100% rename from naga/tests/in/glsl/bits_glsl.frag rename to naga/tests/in/glsl/bits.frag diff --git a/naga/tests/in/glsl/bits.toml b/naga/tests/in/glsl/bits.toml new file mode 100644 index 00000000000..d5abbf371ea --- /dev/null +++ b/naga/tests/in/glsl/bits.toml @@ -0,0 +1 @@ +god_mode = true # requires F16_IN_F32 diff --git a/naga/tests/in/wgsl/bits-optimized-msl.toml b/naga/tests/in/wgsl/bits-optimized-msl.toml index 9409d2ac77c..8f41da00c78 100644 --- a/naga/tests/in/wgsl/bits-optimized-msl.toml +++ b/naga/tests/in/wgsl/bits-optimized-msl.toml @@ -1,3 +1,4 @@ +god_mode = true # requires F16_IN_F32 targets = "METAL" [msl] diff --git a/naga/tests/in/wgsl/bits.toml b/naga/tests/in/wgsl/bits.toml index 2751860cfe1..26ad6e67293 100644 --- a/naga/tests/in/wgsl/bits.toml +++ b/naga/tests/in/wgsl/bits.toml @@ -1,3 +1,5 @@ +god_mode = true # requires F16_IN_F32 + [msl] fake_missing_bindings = false lang_version = [1, 2] diff --git a/naga/tests/in/wgsl/math-functions.toml b/naga/tests/in/wgsl/math-functions.toml new file mode 100644 index 00000000000..d5abbf371ea --- /dev/null +++ b/naga/tests/in/wgsl/math-functions.toml @@ -0,0 +1 @@ +god_mode = true # requires F16_IN_F32 diff --git a/naga/tests/naga/validation.rs b/naga/tests/naga/validation.rs index 0a0b6fdfc0b..370919ffc51 100644 --- a/naga/tests/naga/validation.rs +++ b/naga/tests/naga/validation.rs @@ -1,3 +1,7 @@ +//! Tests of the module validator. +//! +//! There are also some validation tests in [`wgsl_errors`](super::wgsl_errors). + #![allow( // We need to investigate these. clippy::result_large_err diff --git a/naga/tests/naga/wgsl_errors.rs b/naga/tests/naga/wgsl_errors.rs index a874112aa29..e304b60283e 100644 --- a/naga/tests/naga/wgsl_errors.rs +++ b/naga/tests/naga/wgsl_errors.rs @@ -1,6 +1,10 @@ -/*! -Tests for the WGSL front end. -*/ +//! Tests for the WGSL front end. +//! +//! This file also contains some tests of the module validator. In some cases, +//! the validator and the frontend both raise an error, and it is easier to +//! have both tests in one place. In other cases, it might be more appropriate +//! for the validator tests to be in the `validation` test suite. + #![cfg(feature = "wgsl-in")] #![allow( // We need to investigate these. @@ -950,50 +954,6 @@ fn matrix_constructor_inferred() { ); } -#[test] -fn float16_requires_enable() { - check( - r#" - const a: f16 = 1.0; - "#, - r#"error: the `f16` enable extension is not enabled - ┌─ wgsl:2:22 - │ -2 │ const a: f16 = 1.0; - │ ^^^ the `f16` "Enable Extension" is needed for this functionality, but it is not currently enabled. - │ - = note: You can enable this extension by adding `enable f16;` at the top of the shader, before any other items. - -"#, - ); - - check( - r#" - const a = 1.0h; - "#, - r#"error: the `f16` enable extension is not enabled - ┌─ wgsl:2:23 - │ -2 │ const a = 1.0h; - │ ^^^^ the `f16` "Enable Extension" is needed for this functionality, but it is not currently enabled. - │ - = note: You can enable this extension by adding `enable f16;` at the top of the shader, before any other items. - -"#, - ); -} - -#[test] -fn multiple_enables_valid() { - check_success( - r#" - enable f16; - enable f16; - const a: f16 = 1.0h; - "#, - ); -} - /// Check the result of validating a WGSL program against a pattern. /// /// Unless you are generating code programmatically, the @@ -1042,6 +1002,125 @@ macro_rules! check_one_validation { } } +/// Test validation of required extensions and capabilities. +/// +/// This tests that the shader is rejected either if the required extension is +/// not declared in an `enable` directive, or if the validator is configured +/// without the required capability. +/// +/// For the first case, we use the supplied test case source verbatim (which +/// should not include the `enable` directive), and check for a parse error +/// matching the expected error message text. For the second case, we add the +/// `enable` directive to the supplied test case, and check for a validation +/// error matching the expected pattern. +/// +/// The WGSL frontend is not the only way of producing Naga IR, and the +/// validator must reject an invalid module however produced. So it is important +/// that the validator check for missing capabilities. Checking missing +/// extensions in the frontend as well can produce better error messages or +/// simplify implementation of the frontend by eliminating some cases of invalid +/// programs earlier. +/// +/// Multiple capabilities can be specified in the macro argument in the case +/// where any one of them grants access to a feature (e.g. `SUBGROUP` and +/// `SUBGROUP_BARRIER` for `subgroupBarrier`). When passing multiple capabilities, +/// all of the passed capabilities must be covered by the same enable-extension. +/// +/// NOTE: The only reason we don't use a function for this is because we need to syntactically +/// re-use `$val_err_pat`. +macro_rules! check_extension_validation { + ( $caps:expr, $source:expr, $parse_err:expr, $val_err_pat:pat ) => { + let caps = $caps; + let source = $source; + let mut ext = None; + for cap in caps.iter() { + match cap.extension() { + Some(this_ext) if ext.is_none() => ext = Some(this_ext), + Some(this_ext) if ext.is_some_and(|ext| ext != this_ext) => { + panic!( + concat!( + "the capabilities {:?} in `check_extension_validation` ", + "are not all covered by the same extension ", + "(found both {:?} and {:?})", + ), + caps, ext, this_ext, + ); + } + _ => {} + } + } + let Some(ext) = ext else { + panic!( + concat!( + "None of the capabilities {:?} in `check_extension_validation` ", + "are associated with an extension. ", + "Use `check_validation!` to check validator behavior ", + "when there isn't a corresponding parse error.", + ), + caps + ); + }; + let directive = format!( + "enable {};", + naga::front::wgsl::EnableExtension::Implemented(ext).to_ident() + ); + assert!( + !source.contains(&directive), + "test case for `check_extension_validation!` should not contain the enable directive", + ); + + // First check, for the expected WGSL parse error when extension is not enabled + check(&source, $parse_err); + let source_with_enable = format!("{directive}\n{source}"); + let module = match naga::front::wgsl::parse_str(&source_with_enable) { + Ok(module) => module, + Err(err) => { + eprintln!("WGSL parse failed:"); + panic!("{}", err.emit_to_string(source)); + } + }; + + // Second check, for the expected validation error when the capability is not present + let error = naga::valid::Validator::new(naga::valid::ValidationFlags::all(), !caps) + .validate(&module) + .map_err(|e| e.into_inner()); // TODO: Add tests for spans, too? + #[allow(clippy::redundant_pattern_matching)] + if !matches!(&error, $val_err_pat) { + eprintln!( + concat!( + "validation error without {:?} does not match pattern:\n", + "source code: {}\n", + "\n", + "actual result:\n", + "{:#?}\n", + "\n", + "expected match for pattern:\n", + "{}", + ), + caps, + &source, + error, + stringify!($val_err_pat) + ); + panic!("validation error does not match pattern"); + } + + // Also check that when multiple capabililiites can enable a feature, + // any one of them is sufficient. + if !caps.bits().is_power_of_two() { + for cap in caps.iter() { + let res = naga::valid::Validator::new(naga::valid::ValidationFlags::all(), cap) + .validate(&module); + + match res { + Ok(_) => {} + Err(err) => panic!("Module did not validate with only {cap:?}: {err:?}"), + } + } + } + }; +} + macro_rules! check_validation { // We want to support an optional guard expression after the pattern, so // that we can check values we can't match against, like strings. @@ -1100,12 +1179,136 @@ fn int64_capability() { } #[test] -fn float16_capability() { - check_validation! { - "enable f16; var input: f16;", - "enable f16; var input: vec2;": +fn multiple_enables_valid() { + check_success( + r#" + enable f16; + enable f16; + const a: f16 = 1.0h; + "#, + ); +} + +#[test] +fn float16_capability_and_enable() { + // A zero value expression + check_extension_validation! { + Capabilities::SHADER_FLOAT16, + r#"fn foo() { + let a = f16(); + } + "#, + r#"error: the `f16` enable extension is not enabled + ┌─ wgsl:2:21 + │ +2 │ let a = f16(); + │ ^^^ the `f16` "Enable Extension" is needed for this functionality, but it is not currently enabled. + │ + = note: You can enable this extension by adding `enable f16;` at the top of the shader, before any other items. + +"#, Err(naga::valid::ValidationError::Type { - source: naga::valid::TypeError::WidthError(naga::valid::WidthError::MissingCapability {flag: "FLOAT16",..}), + source: naga::valid::TypeError::WidthError(naga::valid::WidthError::MissingCapability { flag: "FLOAT16", .. }), + .. + }) + } + + // Literals + check_extension_validation! { + Capabilities::SHADER_FLOAT16, + r#"fn foo() { + let a = f16(1); + } + "#, + r#"error: the `f16` enable extension is not enabled + ┌─ wgsl:2:21 + │ +2 │ let a = f16(1); + │ ^^^ the `f16` "Enable Extension" is needed for this functionality, but it is not currently enabled. + │ + = note: You can enable this extension by adding `enable f16;` at the top of the shader, before any other items. + +"#, + Err(naga::valid::ValidationError::Function { + source: naga::valid::FunctionError::Expression { + source: naga::valid::ExpressionError::Literal( + naga::valid::LiteralError::Width( + naga::valid::WidthError::MissingCapability { flag: "FLOAT16", .. } + ) + ), + .. + }, + .. + }) + } + check_extension_validation! { + Capabilities::SHADER_FLOAT16, + r#" + const a = 1.0h; + "#, + r#"error: the `f16` enable extension is not enabled + ┌─ wgsl:2:23 + │ +2 │ const a = 1.0h; + │ ^^^^ the `f16` "Enable Extension" is needed for this functionality, but it is not currently enabled. + │ + = note: You can enable this extension by adding `enable f16;` at the top of the shader, before any other items. + +"#, + Err(naga::valid::ValidationError::Type { + source: naga::valid::TypeError::WidthError(naga::valid::WidthError::MissingCapability { flag: "FLOAT16", .. }), + .. + }) + } + + // `f16`-typed declarations + check_extension_validation! { + Capabilities::SHADER_FLOAT16, + r#" + const a: f16 = 1.0; + "#, + r#"error: the `f16` enable extension is not enabled + ┌─ wgsl:2:22 + │ +2 │ const a: f16 = 1.0; + │ ^^^ the `f16` "Enable Extension" is needed for this functionality, but it is not currently enabled. + │ + = note: You can enable this extension by adding `enable f16;` at the top of the shader, before any other items. + +"#, + Err(naga::valid::ValidationError::Type { + source: naga::valid::TypeError::WidthError(naga::valid::WidthError::MissingCapability { flag: "FLOAT16", .. }), + .. + }) + } + check_extension_validation! { + Capabilities::SHADER_FLOAT16, + "var input: f16;", + r#"error: the `f16` enable extension is not enabled + ┌─ wgsl:1:12 + │ +1 │ var input: f16; + │ ^^^ the `f16` "Enable Extension" is needed for this functionality, but it is not currently enabled. + │ + = note: You can enable this extension by adding `enable f16;` at the top of the shader, before any other items. + +"#, + Err(naga::valid::ValidationError::Type { + source: naga::valid::TypeError::WidthError(naga::valid::WidthError::MissingCapability { flag: "FLOAT16", .. }), + .. + }) + } + + // Functions that operate on `f16`-precision values stored in `f32`s. + check_validation! { + "fn foo() -> f32 { return quantizeToF16(1.0f); }", + "fn foo() -> u32 { return pack2x16float(vec2(1.0f, 2.0f)); }", + "fn foo() -> vec2 { return unpack2x16float(0x7c007c00); }": + Err(naga::valid::ValidationError::Function { + source: naga::valid::FunctionError::Expression { + source: naga::valid::ExpressionError::MissingCapabilities(Capabilities::SHADER_FLOAT16_IN_FLOAT32), + .. + }, .. }) } @@ -1669,37 +1872,16 @@ fn missing_bindings2() { #[test] fn invalid_blend_src() { - // Missing capability. - check_validation! { + // Missing capability or enable directive + check_extension_validation! { + Capabilities::DUAL_SOURCE_BLENDING, " - enable dual_source_blending; struct FragmentOutput { @location(0) @blend_src(0) output0: vec4, @location(0) @blend_src(1) output1: vec4, } @fragment fn main() -> FragmentOutput { return FragmentOutput(vec4(0.0), vec4(1.0)); } - ": - Err( - naga::valid::ValidationError::EntryPoint { - stage: naga::ShaderStage::Fragment, - source: naga::valid::EntryPointError::Result( - naga::valid::VaryingError::UnsupportedCapability(Capabilities::DUAL_SOURCE_BLENDING), - ), - .. - }, - ) - } - - // Missing enable directive. - // Note that this is a parsing error, not a validation error. - check(" - struct FragmentOutput { - @location(0) @blend_src(0) output0: vec4, - @location(0) @blend_src(1) output1: vec4, - } - @fragment - fn main(@builtin(position) position: vec4) -> FragmentOutput { return FragmentOutput(vec4(0.0), vec4(0.0)); } ", r###"error: the `dual_source_blending` enable extension is not enabled ┌─ wgsl:3:27 @@ -1710,7 +1892,16 @@ fn invalid_blend_src() { = note: You can enable this extension by adding `enable dual_source_blending;` at the top of the shader, before any other items. "###, - ); + Err( + naga::valid::ValidationError::EntryPoint { + stage: naga::ShaderStage::Fragment, + source: naga::valid::EntryPointError::Result( + naga::valid::VaryingError::UnsupportedCapability(Capabilities::DUAL_SOURCE_BLENDING), + ), + .. + }, + ) + } // Using blend_src on an input. check_validation! { @@ -3677,35 +3868,9 @@ fn subgroup_invalid_broadcast() { #[test] fn invalid_clip_distances() { - // Missing capability. - check_validation! { - r#" - enable clip_distances; - struct VertexOutput { - @builtin(position) pos: vec4f, - @builtin(clip_distances) clip_distances: array, - } - - @vertex - fn vs_main() -> VertexOutput { - var out: VertexOutput; - return out; - } - "#: - Err( - naga::valid::ValidationError::EntryPoint { - stage: naga::ShaderStage::Vertex, - source: naga::valid::EntryPointError::Result( - naga::valid::VaryingError::UnsupportedCapability(Capabilities::CLIP_DISTANCE), - ), - .. - }, - ) - } - - // Missing enable directive. - // Note that this is a parsing error, not a validation error. - check( + // Missing capability or enable directive + check_extension_validation! { + Capabilities::CLIP_DISTANCE, r#" @vertex fn vs_main() -> @builtin(clip_distances) array { @@ -3722,7 +3887,14 @@ fn invalid_clip_distances() { = note: You can enable this extension by adding `enable clip_distances;` at the top of the shader, before any other items. "###, - ); + Err(naga::valid::ValidationError::EntryPoint { + stage: naga::ShaderStage::Vertex, + source: naga::valid::EntryPointError::Result( + naga::valid::VaryingError::UnsupportedCapability(Capabilities::CLIP_DISTANCE) + ), + .. + }) + } // Maximum clip distances exceeded check_validation! { diff --git a/naga/tests/out/wgsl/glsl-bits_glsl.frag.wgsl b/naga/tests/out/wgsl/glsl-bits.frag.wgsl similarity index 100% rename from naga/tests/out/wgsl/glsl-bits_glsl.frag.wgsl rename to naga/tests/out/wgsl/glsl-bits.frag.wgsl diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 0780e7ccffb..643b07c8f3b 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -412,6 +412,10 @@ pub fn create_validator( Caps::SHADER_FLOAT16, features.contains(wgt::Features::SHADER_F16), ); + caps.set( + Caps::SHADER_FLOAT16_IN_FLOAT32, + downlevel.contains(wgt::DownlevelFlags::SHADER_F16_IN_F32), + ); caps.set( Caps::PRIMITIVE_INDEX, features.contains(wgt::Features::SHADER_PRIMITIVE_INDEX), diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 7f888aae14b..8ced7c41761 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -1677,7 +1677,7 @@ impl super::Instance { }, backend: wgt::Backend::Vulkan, }; - let (available_features, downlevel_flags) = + let (available_features, mut downlevel_flags) = phd_features.to_wgpu(&self.shared.raw, phd, &phd_capabilities); let mut workarounds = super::Workarounds::empty(); { @@ -1693,6 +1693,15 @@ impl super::Instance { ); }; + if info.driver_info.contains("Mesa ") { + // The `F16_IN_F32` instructions do not normally require native `F16` support, but on + // Mesa, they do. + downlevel_flags.set( + wgt::DownlevelFlags::SHADER_F16_IN_F32, + available_features.contains(wgt::Features::SHADER_F16), + ); + } + if let Some(driver) = phd_capabilities.driver { if driver.conformance_version.major == 0 { if driver.driver_id == vk::DriverId::MOLTENVK { diff --git a/wgpu-types/src/features.rs b/wgpu-types/src/features.rs index fc584d3f052..34de52a140b 100644 --- a/wgpu-types/src/features.rs +++ b/wgpu-types/src/features.rs @@ -1227,7 +1227,7 @@ bitflags_array! { /// Features that are not guaranteed to be supported. /// - /// These are part of the webgpu standard. For all features see [`Features`] + /// These are part of the WebGPU standard. For all features, see [`Features`]. /// /// If you want to use a feature, you need to first verify that the adapter supports /// the feature. If the adapter does not support the feature, requesting a device with it enabled diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index e0be64c1772..251b6f13e71 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -1323,6 +1323,12 @@ bitflags::bitflags! { /// Not Supported by: /// - GL ES / WebGL const NONBLOCKING_QUERY_RESOLVE = 1 << 22; + + /// Allows shaders to use `quantizeToF16`, `pack2x16float`, and `unpack2x16float`, which + /// operate on `f16`-precision values stored in `f32`s. + /// + /// Not supported by Vulkan on Mesa when [`Features::SHADER_F16`] is absent. + const SHADER_F16_IN_F32 = 1 << 23; } } From 7933dd78aa2a9247573f404dc5bbba5ed2a3b428 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Sun, 24 Aug 2025 12:23:45 -0700 Subject: [PATCH 174/303] docs(types): note intent to move `EXTERNAL_TEXTURE` to a downlevel flag --- wgpu-types/src/features.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/wgpu-types/src/features.rs b/wgpu-types/src/features.rs index 34de52a140b..d3db2264ba3 100644 --- a/wgpu-types/src/features.rs +++ b/wgpu-types/src/features.rs @@ -535,7 +535,11 @@ bitflags_array! { /// Features that are not guaranteed to be supported. /// - /// These are extension features supported by wgpu when targeting native. For all features see [`Features`] + /// Most of these are native-only extension features supported by wgpu only when targeting + /// native. A few are intended to align with a proposed WebGPU extension, and one + /// (`EXTERNAL_TEXTURE`) controls WebGPU-specified behavior that is not optional in the + /// standard, but that we don't want to make a [`crate::DownlevelFlags`] until the + /// implementation is more complete. For all features see [`Features`]. /// /// If you want to use a feature, you need to first verify that the adapter supports /// the feature. If the adapter does not support the feature, requesting a device with it enabled From 03513e8f90407bab195935d6ca4670860d66d208 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Tue, 26 Aug 2025 14:29:24 -0700 Subject: [PATCH 175/303] chore(tests): add issue links for TODOs --- naga/tests/in/glsl/bits.toml | 3 ++- naga/tests/in/glsl/dual-source-blending.toml | 3 ++- naga/tests/in/wgsl/bits-optimized-msl.toml | 3 ++- naga/tests/in/wgsl/bits.toml | 3 ++- naga/tests/in/wgsl/math-functions.toml | 3 ++- naga/tests/naga/wgsl_errors.rs | 4 ++-- 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/naga/tests/in/glsl/bits.toml b/naga/tests/in/glsl/bits.toml index d5abbf371ea..96a1d507b4f 100644 --- a/naga/tests/in/glsl/bits.toml +++ b/naga/tests/in/glsl/bits.toml @@ -1 +1,2 @@ -god_mode = true # requires F16_IN_F32 +# TODO(https://github.com/gfx-rs/wgpu/issues/8154): enable only `F16_IN_F32` capability +god_mode = true diff --git a/naga/tests/in/glsl/dual-source-blending.toml b/naga/tests/in/glsl/dual-source-blending.toml index c3c2d8aa9b0..a51f548feec 100644 --- a/naga/tests/in/glsl/dual-source-blending.toml +++ b/naga/tests/in/glsl/dual-source-blending.toml @@ -1 +1,2 @@ -god_mode = true # TODO: replace with finer `DUAL_SOURCE_BLENDING` capability +# TODO(https://github.com/gfx-rs/wgpu/issues/8154): enable only `DUAL_SOURCE_BLENDING` capability +god_mode = true diff --git a/naga/tests/in/wgsl/bits-optimized-msl.toml b/naga/tests/in/wgsl/bits-optimized-msl.toml index 8f41da00c78..7dbe8fcbf00 100644 --- a/naga/tests/in/wgsl/bits-optimized-msl.toml +++ b/naga/tests/in/wgsl/bits-optimized-msl.toml @@ -1,4 +1,5 @@ -god_mode = true # requires F16_IN_F32 +# TODO(https://github.com/gfx-rs/wgpu/issues/8154): enable only `F16_IN_F32` capability +god_mode = true targets = "METAL" [msl] diff --git a/naga/tests/in/wgsl/bits.toml b/naga/tests/in/wgsl/bits.toml index 26ad6e67293..7d254eb02f2 100644 --- a/naga/tests/in/wgsl/bits.toml +++ b/naga/tests/in/wgsl/bits.toml @@ -1,4 +1,5 @@ -god_mode = true # requires F16_IN_F32 +# TODO(https://github.com/gfx-rs/wgpu/issues/8154): enable only `F16_IN_F32` capability +god_mode = true [msl] fake_missing_bindings = false diff --git a/naga/tests/in/wgsl/math-functions.toml b/naga/tests/in/wgsl/math-functions.toml index d5abbf371ea..96a1d507b4f 100644 --- a/naga/tests/in/wgsl/math-functions.toml +++ b/naga/tests/in/wgsl/math-functions.toml @@ -1 +1,2 @@ -god_mode = true # requires F16_IN_F32 +# TODO(https://github.com/gfx-rs/wgpu/issues/8154): enable only `F16_IN_F32` capability +god_mode = true diff --git a/naga/tests/naga/wgsl_errors.rs b/naga/tests/naga/wgsl_errors.rs index e304b60283e..6e5059e2eda 100644 --- a/naga/tests/naga/wgsl_errors.rs +++ b/naga/tests/naga/wgsl_errors.rs @@ -1083,7 +1083,7 @@ macro_rules! check_extension_validation { // Second check, for the expected validation error when the capability is not present let error = naga::valid::Validator::new(naga::valid::ValidationFlags::all(), !caps) .validate(&module) - .map_err(|e| e.into_inner()); // TODO: Add tests for spans, too? + .map_err(|e| e.into_inner()); // TODO(https://github.com/gfx-rs/wgpu/issues/8153): Add tests for spans #[allow(clippy::redundant_pattern_matching)] if !matches!(&error, $val_err_pat) { eprintln!( @@ -1163,7 +1163,7 @@ fn validation_error( }; naga::valid::Validator::new(naga::valid::ValidationFlags::all(), caps) .validate(&module) - .map_err(|e| e.into_inner()) // TODO: Add tests for spans, too? + .map_err(|e| e.into_inner()) // TODO(https://github.com/gfx-rs/wgpu/issues/8153): Add tests for spans } #[test] From 0aacfeadffa8cff876b69e8d4d3597a1571a95a5 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 27 Aug 2025 11:18:30 -0700 Subject: [PATCH 176/303] fix(hal): adjust the conditions when F16_IN_F32 is available --- wgpu-hal/src/gles/adapter.rs | 3 ++- wgpu-hal/src/vulkan/adapter.rs | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index 6016bc8e414..806f5567ba2 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -384,7 +384,8 @@ impl super::Adapter { let mut downlevel_flags = wgt::DownlevelFlags::empty() | wgt::DownlevelFlags::NON_POWER_OF_TWO_MIPMAPPED_TEXTURES | wgt::DownlevelFlags::CUBE_ARRAY_TEXTURES - | wgt::DownlevelFlags::COMPARISON_SAMPLERS; + | wgt::DownlevelFlags::COMPARISON_SAMPLERS + | wgt::DownlevelFlags::SHADER_F16_IN_F32; downlevel_flags.set(wgt::DownlevelFlags::COMPUTE_SHADERS, supports_compute); downlevel_flags.set( wgt::DownlevelFlags::FRAGMENT_WRITABLE_STORAGE, diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 8ced7c41761..0ebf1fec9a4 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -575,7 +575,8 @@ impl PhysicalDeviceFeatures { | Df::INDIRECT_EXECUTION | Df::VIEW_FORMATS | Df::UNRESTRICTED_EXTERNAL_TEXTURE_COPIES - | Df::NONBLOCKING_QUERY_RESOLVE; + | Df::NONBLOCKING_QUERY_RESOLVE + | Df::SHADER_F16_IN_F32; dl_flags.set( Df::SURFACE_VIEW_FORMATS, @@ -1693,9 +1694,9 @@ impl super::Instance { ); }; - if info.driver_info.contains("Mesa ") { + if info.driver == "llvmpipe" { // The `F16_IN_F32` instructions do not normally require native `F16` support, but on - // Mesa, they do. + // llvmpipe, they do. downlevel_flags.set( wgt::DownlevelFlags::SHADER_F16_IN_F32, available_features.contains(wgt::Features::SHADER_F16), From cd14b194a4b376ab3ccaa7060391b199ab4295d5 Mon Sep 17 00:00:00 2001 From: Lucas Abel <22837557+uael@users.noreply.github.com> Date: Thu, 28 Aug 2025 23:59:54 +0200 Subject: [PATCH 177/303] [egl] get rid of `unwrap` where possible (#8024) Co-authored-by: Andreas Reich --- CHANGELOG.md | 4 + wgpu-hal/src/gles/egl.rs | 260 +++++++++++++++++++++++---------------- 2 files changed, 155 insertions(+), 109 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ba2f28264a..3493e84495a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -133,6 +133,10 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). - Fixed a bug where access to matrices with 2 rows would not work in some cases. By @andyleiserson in [#7438](https://github.com/gfx-rs/wgpu/pull/7438). +##### EGL + +- Fixed unwrap failed in context creation for some Android devices. By @uael in [#8024](https://github.com/gfx-rs/wgpu/pull/8024). + #### naga - [wgsl-in] Allow a trailing comma in `@blend_src(…)` attributes. By @ErichDonGubler in [#8137](https://github.com/gfx-rs/wgpu/pull/8137). diff --git a/wgpu-hal/src/gles/egl.rs b/wgpu-hal/src/gles/egl.rs index ff4d77a3357..43b817745d8 100644 --- a/wgpu-hal/src/gles/egl.rs +++ b/wgpu-hal/src/gles/egl.rs @@ -136,8 +136,13 @@ impl Drop for DisplayOwner { fn drop(&mut self) { match self.display { DisplayRef::X11(ptr) => unsafe { - let func: libloading::Symbol = - self.library.get(c"XCloseDisplay".to_bytes()).unwrap(); + let Ok(func): Result, _> = self + .library + .get(c"XCloseDisplay".to_bytes()) + .inspect_err(|err| log::error!("Failed to load XCloseDisplay: {err:?}")) + else { + return; + }; func(ptr.as_ptr()); }, DisplayRef::Wayland => {} @@ -149,8 +154,10 @@ fn open_x_display() -> Option { log::debug!("Loading X11 library to get the current display"); unsafe { let library = find_library(&["libX11.so.6", "libX11.so"])?; - let func: libloading::Symbol = - library.get(c"XOpenDisplay".to_bytes()).unwrap(); + let func: libloading::Symbol = library + .get(c"XOpenDisplay".to_bytes()) + .inspect_err(|err| log::error!("Failed to load XOpenDisplay: {err:?}")) + .ok()?; let result = func(ptr::null()); ptr::NonNull::new(result).map(|ptr| DisplayOwner { display: DisplayRef::X11(ptr), @@ -178,10 +185,12 @@ fn test_wayland_display() -> Option { let client_library = find_library(&["libwayland-client.so.0", "libwayland-client.so"])?; let wl_display_connect: libloading::Symbol = client_library .get(c"wl_display_connect".to_bytes()) - .unwrap(); + .inspect_err(|err| log::error!("Failed to load wl_display_connect: {err:?}")) + .ok()?; let wl_display_disconnect: libloading::Symbol = client_library .get(c"wl_display_disconnect".to_bytes()) - .unwrap(); + .inspect_err(|err| log::error!("Failed to load wl_display_disconnect: {err:?}")) + .ok()?; let display = ptr::NonNull::new(wl_display_connect(ptr::null()))?; wl_display_disconnect(display.as_ptr()); find_library(&["libwayland-egl.so.1", "libwayland-egl.so"])? @@ -394,9 +403,9 @@ impl<'a> core::ops::Deref for AdapterContextLock<'a> { impl<'a> Drop for AdapterContextLock<'a> { fn drop(&mut self) { if let Some(egl) = self.egl.take() { - egl.instance - .make_current(egl.display, None, None, None) - .unwrap(); + if let Err(err) = egl.instance.make_current(egl.display, None, None, None) { + log::error!("Failed to make EGL context current: {err:?}"); + } } } } @@ -501,6 +510,12 @@ fn terminate_display( } } +fn instance_err( + message: impl Into, +) -> impl FnOnce(E) -> crate::InstanceError { + move |e| crate::InstanceError::with_source(message.into(), e) +} + impl Inner { fn create( flags: wgt::InstanceFlags, @@ -508,18 +523,14 @@ impl Inner { display: khronos_egl::Display, force_gles_minor_version: wgt::Gles3MinorVersion, ) -> Result { - let version = initialize_display(&egl, display).map_err(|e| { - crate::InstanceError::with_source( - String::from("failed to initialize EGL display connection"), - e, - ) - })?; + let version = initialize_display(&egl, display) + .map_err(instance_err("failed to initialize EGL display connection"))?; let vendor = egl .query_string(Some(display), khronos_egl::VENDOR) - .unwrap(); + .map_err(instance_err("failed to query EGL vendor"))?; let display_extensions = egl .query_string(Some(display), khronos_egl::EXTENSIONS) - .unwrap() + .map_err(instance_err("failed to query EGL display extensions"))? .to_string_lossy(); log::debug!("Display vendor {vendor:?}, version {version:?}",); log::debug!( @@ -540,16 +551,19 @@ impl Inner { if log::max_level() >= log::LevelFilter::Trace { log::trace!("Configurations:"); - let config_count = egl.get_config_count(display).unwrap(); + let config_count = egl + .get_config_count(display) + .map_err(instance_err("failed to get config count"))?; let mut configurations = Vec::with_capacity(config_count); - egl.get_configs(display, &mut configurations).unwrap(); + egl.get_configs(display, &mut configurations) + .map_err(instance_err("failed to get configs"))?; for &config in configurations.iter() { - log::trace!("\tCONFORMANT=0x{:X}, RENDERABLE=0x{:X}, NATIVE_RENDERABLE=0x{:X}, SURFACE_TYPE=0x{:X}, ALPHA_SIZE={}", - egl.get_config_attrib(display, config, khronos_egl::CONFORMANT).unwrap(), - egl.get_config_attrib(display, config, khronos_egl::RENDERABLE_TYPE).unwrap(), - egl.get_config_attrib(display, config, khronos_egl::NATIVE_RENDERABLE).unwrap(), - egl.get_config_attrib(display, config, khronos_egl::SURFACE_TYPE).unwrap(), - egl.get_config_attrib(display, config, khronos_egl::ALPHA_SIZE).unwrap(), + log::trace!("\tCONFORMANT=0x{:X?}, RENDERABLE=0x{:X?}, NATIVE_RENDERABLE=0x{:X?}, SURFACE_TYPE=0x{:X?}, ALPHA_SIZE={:?}", + egl.get_config_attrib(display, config, khronos_egl::CONFORMANT), + egl.get_config_attrib(display, config, khronos_egl::RENDERABLE_TYPE), + egl.get_config_attrib(display, config, khronos_egl::NATIVE_RENDERABLE), + egl.get_config_attrib(display, config, khronos_egl::SURFACE_TYPE), + egl.get_config_attrib(display, config, khronos_egl::ALPHA_SIZE), ); } } @@ -559,7 +573,7 @@ impl Inner { let supports_opengl = if version >= (1, 4) { let client_apis = egl .query_string(Some(display), khronos_egl::CLIENT_APIS) - .unwrap() + .map_err(instance_err("failed to query EGL client APIs string"))? .to_string_lossy(); client_apis .split(' ') @@ -572,7 +586,7 @@ impl Inner { } else { khronos_egl::OPENGL_ES_API }) - .unwrap(); + .map_err(instance_err("failed to bind API"))?; let mut khr_context_flags = 0; let supports_khr_context = display_extensions.contains("EGL_KHR_create_context"); @@ -661,7 +675,7 @@ impl Inner { let result = if supports_opengl { egl.create_context(display, config, None, &gl_context_attributes) .or_else(|_| { - egl.bind_api(khronos_egl::OPENGL_ES_API).unwrap(); + egl.bind_api(khronos_egl::OPENGL_ES_API)?; egl.create_context(display, config, None, &gles_context_attributes) }) } else { @@ -848,15 +862,9 @@ impl crate::Instance for Instance { } else { unsafe { khronos_egl::DynamicInstance::::load_required() } }; - let egl = match egl_result { - Ok(egl) => Arc::new(egl), - Err(e) => { - return Err(crate::InstanceError::with_source( - String::from("unable to open libEGL"), - e, - )); - } - }; + let egl = egl_result + .map(Arc::new) + .map_err(instance_err("unable to open libEGL"))?; let client_extensions = egl.query_string(None, khronos_egl::EXTENSIONS); @@ -891,75 +899,83 @@ impl crate::Instance for Instance { #[cfg(Emscripten)] let egl1_5: Option<&Arc> = Some(&egl); - let (display, display_owner, wsi_kind) = - if let (Some(library), Some(egl)) = (wayland_library, egl1_5) { - log::info!("Using Wayland platform"); - let display_attributes = [khronos_egl::ATTRIB_NONE]; - let display = unsafe { - egl.get_platform_display( - EGL_PLATFORM_WAYLAND_KHR, - khronos_egl::DEFAULT_DISPLAY, - &display_attributes, - ) - } - .unwrap(); - (display, Some(Rc::new(library)), WindowKind::Wayland) - } else if let (Some(display_owner), Some(egl)) = (x11_display_library, egl1_5) { - log::info!("Using X11 platform"); - let display_attributes = [khronos_egl::ATTRIB_NONE]; - let display = unsafe { - egl.get_platform_display( - EGL_PLATFORM_X11_KHR, - display_owner.display.as_ptr(), - &display_attributes, - ) - } - .unwrap(); - (display, Some(Rc::new(display_owner)), WindowKind::X11) - } else if let (Some(display_owner), Some(egl)) = (angle_x11_display_library, egl1_5) { - log::info!("Using Angle platform with X11"); - let display_attributes = [ - EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE as khronos_egl::Attrib, - EGL_PLATFORM_X11_KHR as khronos_egl::Attrib, - EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED as khronos_egl::Attrib, - usize::from(desc.flags.contains(wgt::InstanceFlags::VALIDATION)), - khronos_egl::ATTRIB_NONE, - ]; - let display = unsafe { - egl.get_platform_display( - EGL_PLATFORM_ANGLE_ANGLE, - display_owner.display.as_ptr(), - &display_attributes, - ) - } - .unwrap(); - (display, Some(Rc::new(display_owner)), WindowKind::AngleX11) - } else if client_ext_str.contains("EGL_MESA_platform_surfaceless") { - log::warn!("No windowing system present. Using surfaceless platform"); - #[allow(clippy::unnecessary_literal_unwrap)] // This is only a literal on Emscripten - let egl = egl1_5.expect("Failed to get EGL 1.5 for surfaceless"); - let display = unsafe { - egl.get_platform_display( - EGL_PLATFORM_SURFACELESS_MESA, - khronos_egl::DEFAULT_DISPLAY, - &[khronos_egl::ATTRIB_NONE], - ) - } - .unwrap(); + let (display, display_owner, wsi_kind) = if let (Some(library), Some(egl)) = + (wayland_library, egl1_5) + { + log::info!("Using Wayland platform"); + let display_attributes = [khronos_egl::ATTRIB_NONE]; + let display = unsafe { + egl.get_platform_display( + EGL_PLATFORM_WAYLAND_KHR, + khronos_egl::DEFAULT_DISPLAY, + &display_attributes, + ) + } + .map_err(instance_err("failed to get Wayland display"))?; + (display, Some(Rc::new(library)), WindowKind::Wayland) + } else if let (Some(display_owner), Some(egl)) = (x11_display_library, egl1_5) { + log::info!("Using X11 platform"); + let display_attributes = [khronos_egl::ATTRIB_NONE]; + let display = unsafe { + egl.get_platform_display( + EGL_PLATFORM_X11_KHR, + display_owner.display.as_ptr(), + &display_attributes, + ) + } + .map_err(instance_err("failed to get x11 display"))?; + (display, Some(Rc::new(display_owner)), WindowKind::X11) + } else if let (Some(display_owner), Some(egl)) = (angle_x11_display_library, egl1_5) { + log::info!("Using Angle platform with X11"); + let display_attributes = [ + EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE as khronos_egl::Attrib, + EGL_PLATFORM_X11_KHR as khronos_egl::Attrib, + EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED as khronos_egl::Attrib, + usize::from(desc.flags.contains(wgt::InstanceFlags::VALIDATION)), + khronos_egl::ATTRIB_NONE, + ]; + let display = unsafe { + egl.get_platform_display( + EGL_PLATFORM_ANGLE_ANGLE, + display_owner.display.as_ptr(), + &display_attributes, + ) + } + .map_err(instance_err("failed to get Angle display"))?; + (display, Some(Rc::new(display_owner)), WindowKind::AngleX11) + } else if client_ext_str.contains("EGL_MESA_platform_surfaceless") { + log::warn!("No windowing system present. Using surfaceless platform"); + #[allow(clippy::unnecessary_literal_unwrap)] // This is only a literal on Emscripten + let egl = egl1_5.expect("Failed to get EGL 1.5 for surfaceless"); + let display = unsafe { + egl.get_platform_display( + EGL_PLATFORM_SURFACELESS_MESA, + khronos_egl::DEFAULT_DISPLAY, + &[khronos_egl::ATTRIB_NONE], + ) + } + .map_err(instance_err("failed to get MESA display"))?; - (display, None, WindowKind::Unknown) - } else { - log::warn!("EGL_MESA_platform_surfaceless not available. Using default platform"); - let display = unsafe { egl.get_display(khronos_egl::DEFAULT_DISPLAY) }.unwrap(); - (display, None, WindowKind::Unknown) - }; + (display, None, WindowKind::Unknown) + } else { + log::warn!("EGL_MESA_platform_surfaceless not available. Using default platform"); + let display = unsafe { egl.get_display(khronos_egl::DEFAULT_DISPLAY) } + .ok_or_else(|| crate::InstanceError::new("Failed to get default display".into()))?; + (display, None, WindowKind::Unknown) + }; if desc.flags.contains(wgt::InstanceFlags::VALIDATION) && client_ext_str.contains("EGL_KHR_debug") { log::debug!("Enabling EGL debug output"); let function: EglDebugMessageControlFun = { - let addr = egl.get_proc_address("eglDebugMessageControlKHR").unwrap(); + let addr = egl + .get_proc_address("eglDebugMessageControlKHR") + .ok_or_else(|| { + crate::InstanceError::new( + "failed to get `eglDebugMessageControlKHR` proc address".into(), + ) + })?; unsafe { core::mem::transmute(addr) } }; let attributes = [ @@ -1021,7 +1037,7 @@ impl crate::Instance for Instance { inner.config, khronos_egl::NATIVE_VISUAL_ID, ) - .unwrap(); + .map_err(instance_err("failed to get config NATIVE_VISUAL_ID"))?; let ret = unsafe { ndk_sys::ANativeWindow_setBuffersGeometry( @@ -1064,14 +1080,18 @@ impl crate::Instance for Instance { .egl .instance .upcast::() - .unwrap() + .ok_or_else(|| { + crate::InstanceError::new( + "EGL 1.5 is required for Wayland support".into(), + ) + })? .get_platform_display( EGL_PLATFORM_WAYLAND_KHR, display_handle.display.as_ptr(), &display_attributes, ) } - .unwrap(); + .map_err(instance_err("failed to get wayland display"))?; let new_inner = Inner::create( self.flags, @@ -1237,7 +1257,9 @@ impl Surface { ) -> Result<(), crate::SurfaceError> { let gl = unsafe { context.get_without_egl_lock() }; let swapchain = self.swapchain.read(); - let sc = swapchain.as_ref().unwrap(); + let sc = swapchain.as_ref().ok_or(crate::SurfaceError::Other( + "Surface has no swap-chain configured", + ))?; self.egl .instance @@ -1363,9 +1385,20 @@ impl crate::Surface for Surface { } (WindowKind::Unknown, Rwh::OhosNdk(handle)) => handle.native_window.as_ptr(), (WindowKind::Wayland, Rwh::Wayland(handle)) => { - let library = &self.wsi.display_owner.as_ref().unwrap().library; + let library = &self + .wsi + .display_owner + .as_ref() + .ok_or(crate::SurfaceError::Other("No WSI display owner"))? + .library; let wl_egl_window_create: libloading::Symbol = - unsafe { library.get(c"wl_egl_window_create".to_bytes()) }.unwrap(); + unsafe { library.get(c"wl_egl_window_create".to_bytes()) }.map_err( + |_| { + crate::SurfaceError::Other( + "Failed to load `wl_egl_window_create", + ) + }, + )?; let window = unsafe { wl_egl_window_create(handle.surface.as_ptr(), 640, 480) } .cast(); @@ -1475,9 +1508,16 @@ impl crate::Surface for Surface { }; if let Some(window) = wl_window { - let library = &self.wsi.display_owner.as_ref().unwrap().library; - let wl_egl_window_resize: libloading::Symbol = - unsafe { library.get(c"wl_egl_window_resize".to_bytes()) }.unwrap(); + let library = &self + .wsi + .display_owner + .as_ref() + .ok_or(crate::SurfaceError::Other("No WSI display owner"))? + .library; + let wl_egl_window_resize: libloading::Symbol = unsafe { + library.get(c"wl_egl_window_resize".to_bytes()) + } + .map_err(|_| crate::SurfaceError::Other("Failed to load `wl_egl_window_resize"))?; unsafe { wl_egl_window_resize( window, @@ -1561,7 +1601,9 @@ impl crate::Surface for Surface { _fence: &super::Fence, ) -> Result>, crate::SurfaceError> { let swapchain = self.swapchain.read(); - let sc = swapchain.as_ref().unwrap(); + let sc = swapchain.as_ref().ok_or(crate::SurfaceError::Other( + "Surface has no swap-chain configured", + ))?; let texture = super::Texture { inner: super::TextureInner::Renderbuffer { raw: sc.renderbuffer, From 80a742094ca8c6fe061881280eedf4e5110da415 Mon Sep 17 00:00:00 2001 From: Matthias Reitinger Date: Fri, 29 Aug 2025 12:03:35 +0200 Subject: [PATCH 178/303] [wgpu-core] Improve errors for forbidden texture copy formats (#8156) TransferError now has separate variants for texture copy formats that are only forbidden in combination with specific aspects (CopyFrom/ToForbiddenTextureFormatAspect), and texture copy formats that are always forbidden, irrespective of the aspect (CopyFrom/ToForbiddenTextureFormat). This produces a less confusing error message by not mentioning the aspect it is not relevant. --- CHANGELOG.md | 1 + tests/tests/wgpu-validation/api/texture.rs | 210 +++++++++++++++++++++ wgpu-core/src/command/transfer.rs | 82 +++++--- wgpu-core/src/conv.rs | 25 --- wgpu-core/src/device/queue.rs | 16 +- 5 files changed, 278 insertions(+), 56 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3493e84495a..c9560fc4e3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -111,6 +111,7 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). - Make a compacted hal acceleration structure inherit a label from the base BLAS. By @Vecvec in [#8103](https://github.com/gfx-rs/wgpu/pull/8103). - The limits requested for a device must now satisfy `min_subgroup_size <= max_subgroup_size`. By @andyleiserson in [#8085](https://github.com/gfx-rs/wgpu/pull/8085). - Require new `F16_IN_F32` downlevel flag for `quantizeToF16`, `pack2x16float`, and `unpack2x16float` in WGSL input. By @aleiserson in [#8130](https://github.com/gfx-rs/wgpu/pull/8130). +- The error message for non-copyable depth/stencil formats no longer mentions the aspect when it is not relevant. By @reima in [#8156](https://github.com/gfx-rs/wgpu/pull/8156). #### naga diff --git a/tests/tests/wgpu-validation/api/texture.rs b/tests/tests/wgpu-validation/api/texture.rs index 4b1e93ebb16..01c88c7bdf7 100644 --- a/tests/tests/wgpu-validation/api/texture.rs +++ b/tests/tests/wgpu-validation/api/texture.rs @@ -298,3 +298,213 @@ fn planar_texture_bad_size() { ); } } + +/// Creates a texture and a buffer, and encodes a copy from the texture to the +/// buffer. +fn encode_copy_texture_to_buffer( + device: &wgpu::Device, + format: wgpu::TextureFormat, + aspect: wgpu::TextureAspect, + bytes_per_texel: u32, +) -> wgpu::CommandEncoder { + let size = wgpu::Extent3d { + width: 256, + height: 256, + depth_or_array_layers: 1, + }; + + let texture = device.create_texture(&wgpu::TextureDescriptor { + label: None, + size, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format, + usage: wgpu::TextureUsages::COPY_SRC, + view_formats: &[], + }); + + let buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: (size.width * size.height * bytes_per_texel) as u64, + usage: wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false, + }); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + + encoder.copy_texture_to_buffer( + wgpu::TexelCopyTextureInfo { + texture: &texture, + mip_level: 0, + origin: wgpu::Origin3d::ZERO, + aspect, + }, + wgpu::TexelCopyBufferInfo { + buffer: &buffer, + layout: wgpu::TexelCopyBufferLayout { + offset: 0, + bytes_per_row: Some(size.width * bytes_per_texel), + rows_per_image: None, + }, + }, + size, + ); + + encoder +} + +/// Ensures that attempting to copy a texture with a forbidden source format to +/// a buffer fails validation. +#[test] +fn copy_texture_to_buffer_forbidden_format() { + let (device, _queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + + let format = wgpu::TextureFormat::Depth24Plus; + + let encoder = encode_copy_texture_to_buffer(&device, format, wgpu::TextureAspect::All, 4); + + fail( + &device, + || { + encoder.finish(); + }, + Some(&format!( + "Copying from textures with format {format:?} is forbidden" + )), + ); +} + +/// Ensures that attempting ta copy a texture with a forbidden source +/// format/aspect combination to a buffer fails validation. +#[test] +fn copy_texture_to_buffer_forbidden_format_aspect() { + let (device, _queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + + let format = wgpu::TextureFormat::Depth24PlusStencil8; + let aspect = wgpu::TextureAspect::DepthOnly; + + let encoder = encode_copy_texture_to_buffer(&device, format, aspect, 4); + + fail( + &device, + || { + encoder.finish(); + }, + Some(&format!( + "Copying from textures with format {format:?} and aspect {aspect:?} is forbidden" + )), + ); +} + +/// Creates a texture and a buffer, and encodes a copy from the buffer to the +/// texture. +fn encode_copy_buffer_to_texture( + device: &wgpu::Device, + format: wgpu::TextureFormat, + aspect: wgpu::TextureAspect, + bytes_per_texel: u32, +) -> wgpu::CommandEncoder { + let size = wgpu::Extent3d { + width: 256, + height: 256, + depth_or_array_layers: 1, + }; + + let texture = device.create_texture(&wgpu::TextureDescriptor { + label: None, + size, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format, + usage: wgpu::TextureUsages::COPY_DST, + view_formats: &[], + }); + + let buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: (size.width * size.height * bytes_per_texel) as u64, + usage: wgpu::BufferUsages::COPY_SRC, + mapped_at_creation: false, + }); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + + encoder.copy_buffer_to_texture( + wgpu::TexelCopyBufferInfo { + buffer: &buffer, + layout: wgpu::TexelCopyBufferLayout { + offset: 0, + bytes_per_row: Some(size.width * bytes_per_texel), + rows_per_image: None, + }, + }, + wgpu::TexelCopyTextureInfo { + texture: &texture, + mip_level: 0, + origin: wgpu::Origin3d::ZERO, + aspect, + }, + size, + ); + + encoder +} + +/// Ensures that attempting to copy a buffer to a texture with a forbidden +/// destination format fails validation. +#[test] +fn copy_buffer_to_texture_forbidden_format() { + let (device, _queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + + for format in [ + wgpu::TextureFormat::Depth24Plus, + wgpu::TextureFormat::Depth32Float, + ] { + let encoder = encode_copy_buffer_to_texture(&device, format, wgpu::TextureAspect::All, 4); + + fail( + &device, + || { + encoder.finish(); + }, + Some(&format!( + "Copying to textures with format {format:?} is forbidden" + )), + ); + } +} + +/// Ensures that attempting to copy a buffer to a texture with a forbidden +/// destination format/aspect combination fails validation. +#[test] +fn copy_buffer_to_texture_forbidden_format_aspect() { + let required_features = wgpu::Features::DEPTH32FLOAT_STENCIL8; + let device_desc = wgpu::DeviceDescriptor { + required_features, + ..Default::default() + }; + let (device, _queue) = wgpu::Device::noop(&device_desc); + + let aspect = wgpu::TextureAspect::DepthOnly; + + for (format, bytes_per_texel) in [ + (wgpu::TextureFormat::Depth24PlusStencil8, 4), + (wgpu::TextureFormat::Depth32FloatStencil8, 8), + ] { + let encoder = encode_copy_buffer_to_texture(&device, format, aspect, bytes_per_texel); + + fail( + &device, + || { + encoder.finish(); + }, + Some(&format!( + "Copying to textures with format {format:?} and aspect {aspect:?} is forbidden" + )), + ); + } +} diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 3a818e148cb..2115b23b753 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -13,7 +13,6 @@ use crate::device::trace::Command as TraceCommand; use crate::{ api_log, command::{clear_texture, CommandEncoderError, EncoderStateError}, - conv, device::{Device, MissingDownlevelFlags}, global::Global, id::{BufferId, CommandEncoderId, TextureId}, @@ -133,13 +132,17 @@ pub enum TransferError { CopyDstMissingAspects, #[error("Copy aspect must refer to a single aspect of texture format")] CopyAspectNotOne, + #[error("Copying from textures with format {0:?} is forbidden")] + CopyFromForbiddenTextureFormat(wgt::TextureFormat), #[error("Copying from textures with format {format:?} and aspect {aspect:?} is forbidden")] - CopyFromForbiddenTextureFormat { + CopyFromForbiddenTextureFormatAspect { format: wgt::TextureFormat, aspect: wgt::TextureAspect, }, + #[error("Copying to textures with format {0:?} is forbidden")] + CopyToForbiddenTextureFormat(wgt::TextureFormat), #[error("Copying to textures with format {format:?} and aspect {aspect:?} is forbidden")] - CopyToForbiddenTextureFormat { + CopyToForbiddenTextureFormatAspect { format: wgt::TextureFormat, aspect: wgt::TextureAspect, }, @@ -200,8 +203,10 @@ impl WebGpuError for TransferError { | Self::CopySrcMissingAspects | Self::CopyDstMissingAspects | Self::CopyAspectNotOne - | Self::CopyFromForbiddenTextureFormat { .. } - | Self::CopyToForbiddenTextureFormat { .. } + | Self::CopyFromForbiddenTextureFormat(..) + | Self::CopyFromForbiddenTextureFormatAspect { .. } + | Self::CopyToForbiddenTextureFormat(..) + | Self::CopyToForbiddenTextureFormatAspect { .. } | Self::ExternalCopyToForbiddenTextureFormat(..) | Self::TextureFormatsNotCopyCompatible { .. } | Self::MissingDownlevelFlags(..) @@ -364,6 +369,54 @@ pub(crate) fn validate_linear_texture_data( Ok((bytes_in_copy, image_stride_bytes)) } +/// Validate the source format of a texture copy. +/// +/// This performs the check from WebGPU's [validating texture buffer copy][vtbc] +/// algorithm that ensures that the format and aspect form a valid texel copy source +/// as defined in the [depth-stencil formats][dsf]. +/// +/// [vtbc]: https://gpuweb.github.io/gpuweb/#abstract-opdef-validating-texture-buffer-copy +/// [dsf]: https://gpuweb.github.io/gpuweb/#depth-formats +pub(crate) fn validate_texture_copy_src_format( + format: wgt::TextureFormat, + aspect: wgt::TextureAspect, +) -> Result<(), TransferError> { + use wgt::TextureAspect as Ta; + use wgt::TextureFormat as Tf; + match (format, aspect) { + (Tf::Depth24Plus, _) => Err(TransferError::CopyFromForbiddenTextureFormat(format)), + (Tf::Depth24PlusStencil8, Ta::DepthOnly) => { + Err(TransferError::CopyFromForbiddenTextureFormatAspect { format, aspect }) + } + _ => Ok(()), + } +} + +/// Validate the destination format of a texture copy. +/// +/// This performs the check from WebGPU's [validating texture buffer copy][vtbc] +/// algorithm that ensures that the format and aspect form a valid texel copy destination +/// as defined in the [depth-stencil formats][dsf]. +/// +/// [vtbc]: https://gpuweb.github.io/gpuweb/#abstract-opdef-validating-texture-buffer-copy +/// [dsf]: https://gpuweb.github.io/gpuweb/#depth-formats +pub(crate) fn validate_texture_copy_dst_format( + format: wgt::TextureFormat, + aspect: wgt::TextureAspect, +) -> Result<(), TransferError> { + use wgt::TextureAspect as Ta; + use wgt::TextureFormat as Tf; + match (format, aspect) { + (Tf::Depth24Plus | Tf::Depth32Float, _) => { + Err(TransferError::CopyToForbiddenTextureFormat(format)) + } + (Tf::Depth24PlusStencil8 | Tf::Depth32FloatStencil8, Ta::DepthOnly) => { + Err(TransferError::CopyToForbiddenTextureFormatAspect { format, aspect }) + } + _ => Ok(()), + } +} + /// Validation for texture/buffer copies. /// /// This implements the following checks from WebGPU's [validating texture buffer copy][vtbc] @@ -376,7 +429,7 @@ pub(crate) fn validate_linear_texture_data( /// * Invocation of other validation algorithms. /// * The texture usage (COPY_DST / COPY_SRC) check. /// * The check for non-copyable depth/stencil formats. The caller must perform -/// this check using `is_valid_copy_src_format` / `is_valid_copy_dst_format` +/// this check using `validate_texture_copy_src_format` / `validate_texture_copy_dst_format` /// before calling this function. This function will panic if /// [`wgt::TextureFormat::block_copy_size`] returns `None` due to a /// non-copyable format. @@ -945,14 +998,7 @@ impl Global { .map(|pending| pending.into_hal(dst_raw)) .collect::>(); - if !conv::is_valid_copy_dst_texture_format(dst_texture.desc.format, destination.aspect) - { - return Err(TransferError::CopyToForbiddenTextureFormat { - format: dst_texture.desc.format, - aspect: destination.aspect, - } - .into()); - } + validate_texture_copy_dst_format(dst_texture.desc.format, destination.aspect)?; validate_texture_buffer_copy( destination, @@ -1073,13 +1119,7 @@ impl Global { .into()); } - if !conv::is_valid_copy_src_texture_format(src_texture.desc.format, source.aspect) { - return Err(TransferError::CopyFromForbiddenTextureFormat { - format: src_texture.desc.format, - aspect: source.aspect, - } - .into()); - } + validate_texture_copy_src_format(src_texture.desc.format, source.aspect)?; validate_texture_buffer_copy( source, diff --git a/wgpu-core/src/conv.rs b/wgpu-core/src/conv.rs index aa6ceb046d1..3aca805659c 100644 --- a/wgpu-core/src/conv.rs +++ b/wgpu-core/src/conv.rs @@ -5,31 +5,6 @@ use crate::resource::{self, TextureDescriptor}; // Some core-only texture format helpers. The helper methods on `TextureFormat` // defined in wgpu-types may need to be modified along with the ones here. -pub fn is_valid_copy_src_texture_format( - format: wgt::TextureFormat, - aspect: wgt::TextureAspect, -) -> bool { - use wgt::TextureAspect as Ta; - use wgt::TextureFormat as Tf; - match (format, aspect) { - (Tf::Depth24Plus, _) | (Tf::Depth24PlusStencil8, Ta::DepthOnly) => false, - _ => true, - } -} - -pub fn is_valid_copy_dst_texture_format( - format: wgt::TextureFormat, - aspect: wgt::TextureAspect, -) -> bool { - use wgt::TextureAspect as Ta; - use wgt::TextureFormat as Tf; - match (format, aspect) { - (Tf::Depth24Plus | Tf::Depth32Float, _) - | (Tf::Depth24PlusStencil8 | Tf::Depth32FloatStencil8, Ta::DepthOnly) => false, - _ => true, - } -} - #[cfg_attr(any(not(webgl)), expect(unused))] pub fn is_valid_external_image_copy_dst_texture_format(format: wgt::TextureFormat) -> bool { use wgt::TextureFormat as Tf; diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 63f9130b61e..d9f338cf7c7 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -20,10 +20,10 @@ use crate::{ api_log, command::{ extract_texture_selector, validate_linear_texture_data, validate_texture_buffer_copy, - validate_texture_copy_range, ClearError, CommandAllocator, CommandBuffer, CommandEncoder, - CommandEncoderError, CopySide, TexelCopyTextureInfo, TransferError, + validate_texture_copy_dst_format, validate_texture_copy_range, ClearError, + CommandAllocator, CommandBuffer, CommandEncoder, CommandEncoderError, CopySide, + TexelCopyTextureInfo, TransferError, }, - conv, device::{DeviceError, WaitIdleError}, get_lowest_common_denom, global::Global, @@ -757,13 +757,7 @@ impl Queue { let (selector, dst_base) = extract_texture_selector(&destination, size, &dst)?; - if !conv::is_valid_copy_dst_texture_format(dst.desc.format, destination.aspect) { - return Err(TransferError::CopyToForbiddenTextureFormat { - format: dst.desc.format, - aspect: destination.aspect, - } - .into()); - } + validate_texture_copy_dst_format(dst.desc.format, destination.aspect)?; validate_texture_buffer_copy( &destination, @@ -961,6 +955,8 @@ impl Queue { destination: wgt::CopyExternalImageDestInfo>, size: wgt::Extent3d, ) -> Result<(), QueueWriteError> { + use crate::conv; + profiling::scope!("Queue::copy_external_image_to_texture"); self.device.check_is_valid()?; From 5d4cf56689feb57f5c3d76b53072374649407640 Mon Sep 17 00:00:00 2001 From: Lucas Abel <22837557+uael@users.noreply.github.com> Date: Fri, 29 Aug 2025 18:30:55 +0200 Subject: [PATCH 179/303] [api] expose invalid submission index to `PollError` (#8169) --- wgpu-core/src/device/life.rs | 3 +++ wgpu-types/src/lib.rs | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index ed8b3862af7..aef58019f8a 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -138,6 +138,9 @@ impl WaitIdleError { pub fn to_poll_error(&self) -> Option { match self { WaitIdleError::Timeout => Some(wgt::PollError::Timeout), + &WaitIdleError::WrongSubmissionIndex(a, b) => { + Some(wgt::PollError::WrongSubmissionIndex(a, b)) + } _ => None, } } diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 251b6f13e71..457b1b9f6ab 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -4555,6 +4555,12 @@ pub enum PollError { error("The requested Wait timed out before the submission was completed.") )] Timeout, + /// The requested Wait was given a wrong submission index. + #[cfg_attr( + feature = "std", + error("Tried to wait using a submission index ({0}) that has not been returned by a successful submission (last successful submission: {1})") + )] + WrongSubmissionIndex(u64, u64), } /// Status of device poll operation. From 5a24e2474d0aaae1deec040d398fd5cadae4a62c Mon Sep 17 00:00:00 2001 From: Alphyr <47725341+a1phyr@users.noreply.github.com> Date: Fri, 29 Aug 2025 18:31:31 +0200 Subject: [PATCH 180/303] wgpu-types: Do not depend on "bitflags/serde" if feature "serde" is not enabled (#8170) --- wgpu-types/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu-types/Cargo.toml b/wgpu-types/Cargo.toml index 921f319592a..3aaadb9db9b 100644 --- a/wgpu-types/Cargo.toml +++ b/wgpu-types/Cargo.toml @@ -49,7 +49,7 @@ trace = ["std"] web = ["dep:js-sys", "dep:web-sys"] [dependencies] -bitflags = { workspace = true, features = ["serde"] } +bitflags.workspace = true bytemuck = { workspace = true, features = ["derive"] } log.workspace = true thiserror = { workspace = true, optional = true } From e58223bedf819deb5287c79dc8292fb8b3996a09 Mon Sep 17 00:00:00 2001 From: Lucas Abel <22837557+uael@users.noreply.github.com> Date: Fri, 29 Aug 2025 18:32:34 +0200 Subject: [PATCH 181/303] [metal] allow access to command buffer (#8166) --- wgpu-hal/src/metal/command.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wgpu-hal/src/metal/command.rs b/wgpu-hal/src/metal/command.rs index 72a799a0275..5888eb4e909 100644 --- a/wgpu-hal/src/metal/command.rs +++ b/wgpu-hal/src/metal/command.rs @@ -33,6 +33,10 @@ impl Default for super::CommandState { } impl super::CommandEncoder { + pub fn raw_command_buffer(&self) -> Option<&metal::CommandBuffer> { + self.raw_cmd_buf.as_ref() + } + fn enter_blit(&mut self) -> &metal::BlitCommandEncoderRef { if self.state.blit.is_none() { debug_assert!(self.state.render.is_none() && self.state.compute.is_none()); From 8d1f4bb5f224d772679b5fb18172d5ccb0340ec7 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Fri, 29 Aug 2025 15:43:27 -0400 Subject: [PATCH 182/303] Require token for experimental features (#8163) --- CHANGELOG.md | 15 ++++ benches/benches/wgpu-benchmark/main.rs | 1 + deno_webgpu/adapter.rs | 1 + examples/features/src/framework.rs | 1 + .../features/src/hello_synchronization/mod.rs | 1 + examples/features/src/hello_triangle/mod.rs | 1 + examples/features/src/hello_windows/mod.rs | 1 + examples/features/src/hello_workgroups/mod.rs | 1 + .../features/src/render_to_texture/mod.rs | 1 + examples/features/src/repeated_compute/mod.rs | 1 + examples/features/src/storage_texture/mod.rs | 1 + .../features/src/timestamp_queries/mod.rs | 1 + examples/features/src/uniform_values/mod.rs | 1 + .../standalone/01_hello_compute/src/main.rs | 1 + player/tests/player/main.rs | 1 + tests/src/init.rs | 1 + tests/tests/wgpu-gpu/device.rs | 2 +- .../tests/wgpu-validation/api/experimental.rs | 70 +++++++++++++++++++ tests/tests/wgpu-validation/api/mod.rs | 1 + wgpu-core/src/instance.rs | 18 ++++- wgpu-types/src/features.rs | 22 ++++++ wgpu-types/src/lib.rs | 6 ++ wgpu-types/src/tokens.rs | 43 ++++++++++++ wgpu/src/lib.rs | 2 +- 24 files changed, 191 insertions(+), 3 deletions(-) create mode 100644 tests/tests/wgpu-validation/api/experimental.rs create mode 100644 wgpu-types/src/tokens.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index c9560fc4e3a..ffca24947bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,21 @@ Difference for SPIR-V passthrough: ``` This allows using precompiled shaders without manually checking which backend's code to pass, for example if you have shaders precompiled for both DXIL and SPIR-V. +#### `EXPERIMENTAL_*` features now require unsafe code to enable + +We want to be able to expose potentially experimental features to our users before we have ensured that they are fully sound to use. +As such, we now require any feature that is prefixed with `EXPERIMENTAL` to have a special unsafe token enabled in the device descriptor +acknowledging that the features may still have bugs in them and to report any they find. + +```rust +adapter.request_device(&wgpu::DeviceDescriptor { + features: wgpu::Features::EXPERIMENTAL_MESH_SHADER, + experimental_features: unsafe { wgpu::ExperimentalFeatures::enabled() } + .. +}) +``` + +By @cwfitzgerald in [#8163](https://github.com/gfx-rs/wgpu/pull/8163). #### Multi-draw indirect is now unconditionally supported when indirect draws are supported diff --git a/benches/benches/wgpu-benchmark/main.rs b/benches/benches/wgpu-benchmark/main.rs index c087f1f8499..091ba8d0e58 100644 --- a/benches/benches/wgpu-benchmark/main.rs +++ b/benches/benches/wgpu-benchmark/main.rs @@ -47,6 +47,7 @@ impl DeviceState { required_features: adapter.features(), required_limits: adapter.limits(), memory_hints: wgpu::MemoryHints::Performance, + experimental_features: unsafe { wgpu::ExperimentalFeatures::enabled() }, label: Some("Compute/RenderPass Device"), trace: wgpu::Trace::Off, })) diff --git a/deno_webgpu/adapter.rs b/deno_webgpu/adapter.rs index a97f7ddb3ff..fe0b6de4f62 100644 --- a/deno_webgpu/adapter.rs +++ b/deno_webgpu/adapter.rs @@ -146,6 +146,7 @@ impl GPUAdapter { descriptor.required_features, ), required_limits, + experimental_features: wgpu_types::ExperimentalFeatures::disabled(), memory_hints: Default::default(), trace, }; diff --git a/examples/features/src/framework.rs b/examples/features/src/framework.rs index 7a3017848fa..994eba8746e 100644 --- a/examples/features/src/framework.rs +++ b/examples/features/src/framework.rs @@ -287,6 +287,7 @@ impl ExampleContext { required_features: (E::optional_features() & adapter.features()) | E::required_features(), required_limits: needed_limits, + experimental_features: unsafe { wgpu::ExperimentalFeatures::enabled() }, memory_hints: wgpu::MemoryHints::MemoryUsage, trace: match std::env::var_os("WGPU_TRACE") { Some(path) => wgpu::Trace::Directory(path.into()), diff --git a/examples/features/src/hello_synchronization/mod.rs b/examples/features/src/hello_synchronization/mod.rs index da2f103f248..e7061004771 100644 --- a/examples/features/src/hello_synchronization/mod.rs +++ b/examples/features/src/hello_synchronization/mod.rs @@ -16,6 +16,7 @@ async fn run() { label: None, required_features: wgpu::Features::empty(), required_limits: wgpu::Limits::downlevel_defaults(), + experimental_features: wgpu::ExperimentalFeatures::disabled(), memory_hints: wgpu::MemoryHints::Performance, trace: wgpu::Trace::Off, }) diff --git a/examples/features/src/hello_triangle/mod.rs b/examples/features/src/hello_triangle/mod.rs index 89ef9864f5b..eca99f6bb37 100644 --- a/examples/features/src/hello_triangle/mod.rs +++ b/examples/features/src/hello_triangle/mod.rs @@ -31,6 +31,7 @@ async fn run(event_loop: EventLoop<()>, window: Window) { // Make sure we use the texture resolution limits from the adapter, so we can support images the size of the swapchain. required_limits: wgpu::Limits::downlevel_webgl2_defaults() .using_resolution(adapter.limits()), + experimental_features: wgpu::ExperimentalFeatures::disabled(), memory_hints: wgpu::MemoryHints::MemoryUsage, trace: wgpu::Trace::Off, }) diff --git a/examples/features/src/hello_windows/mod.rs b/examples/features/src/hello_windows/mod.rs index 9885d240221..fbd69f0bff2 100644 --- a/examples/features/src/hello_windows/mod.rs +++ b/examples/features/src/hello_windows/mod.rs @@ -74,6 +74,7 @@ async fn run(event_loop: EventLoop<()>, viewports: Vec<(Arc, wgpu::Color label: None, required_features: wgpu::Features::empty(), required_limits: wgpu::Limits::downlevel_defaults(), + experimental_features: wgpu::ExperimentalFeatures::disabled(), memory_hints: wgpu::MemoryHints::MemoryUsage, trace: wgpu::Trace::Off, }) diff --git a/examples/features/src/hello_workgroups/mod.rs b/examples/features/src/hello_workgroups/mod.rs index 5a8e7ffab0a..ee2c6fe5948 100644 --- a/examples/features/src/hello_workgroups/mod.rs +++ b/examples/features/src/hello_workgroups/mod.rs @@ -31,6 +31,7 @@ async fn run() { label: None, required_features: wgpu::Features::empty(), required_limits: wgpu::Limits::downlevel_defaults(), + experimental_features: wgpu::ExperimentalFeatures::disabled(), memory_hints: wgpu::MemoryHints::MemoryUsage, trace: wgpu::Trace::Off, }) diff --git a/examples/features/src/render_to_texture/mod.rs b/examples/features/src/render_to_texture/mod.rs index 3460864b004..7981f665506 100644 --- a/examples/features/src/render_to_texture/mod.rs +++ b/examples/features/src/render_to_texture/mod.rs @@ -20,6 +20,7 @@ async fn run(_path: Option) { label: None, required_features: wgpu::Features::empty(), required_limits: wgpu::Limits::downlevel_defaults(), + experimental_features: wgpu::ExperimentalFeatures::disabled(), memory_hints: wgpu::MemoryHints::MemoryUsage, trace: wgpu::Trace::Off, }) diff --git a/examples/features/src/repeated_compute/mod.rs b/examples/features/src/repeated_compute/mod.rs index f6104d948b5..77e5f9c5114 100644 --- a/examples/features/src/repeated_compute/mod.rs +++ b/examples/features/src/repeated_compute/mod.rs @@ -164,6 +164,7 @@ impl WgpuContext { label: None, required_features: wgpu::Features::empty(), required_limits: wgpu::Limits::downlevel_defaults(), + experimental_features: wgpu::ExperimentalFeatures::disabled(), memory_hints: wgpu::MemoryHints::Performance, trace: wgpu::Trace::Off, }) diff --git a/examples/features/src/storage_texture/mod.rs b/examples/features/src/storage_texture/mod.rs index 754e8406bce..07c3d48f7fa 100644 --- a/examples/features/src/storage_texture/mod.rs +++ b/examples/features/src/storage_texture/mod.rs @@ -34,6 +34,7 @@ async fn run(_path: Option) { label: None, required_features: wgpu::Features::empty(), required_limits: wgpu::Limits::downlevel_defaults(), + experimental_features: wgpu::ExperimentalFeatures::disabled(), memory_hints: wgpu::MemoryHints::MemoryUsage, trace: wgpu::Trace::Off, }) diff --git a/examples/features/src/timestamp_queries/mod.rs b/examples/features/src/timestamp_queries/mod.rs index 23746a6ee6a..2531cc4e692 100644 --- a/examples/features/src/timestamp_queries/mod.rs +++ b/examples/features/src/timestamp_queries/mod.rs @@ -210,6 +210,7 @@ async fn run() { label: None, required_features: features, required_limits: wgpu::Limits::downlevel_defaults(), + experimental_features: wgpu::ExperimentalFeatures::disabled(), memory_hints: wgpu::MemoryHints::MemoryUsage, trace: wgpu::Trace::Off, }) diff --git a/examples/features/src/uniform_values/mod.rs b/examples/features/src/uniform_values/mod.rs index 7215b72384f..6a42f2635e1 100644 --- a/examples/features/src/uniform_values/mod.rs +++ b/examples/features/src/uniform_values/mod.rs @@ -114,6 +114,7 @@ impl WgpuContext { label: None, required_features: wgpu::Features::empty(), required_limits: wgpu::Limits::downlevel_defaults(), + experimental_features: wgpu::ExperimentalFeatures::disabled(), memory_hints: wgpu::MemoryHints::MemoryUsage, trace: wgpu::Trace::Off, }) diff --git a/examples/standalone/01_hello_compute/src/main.rs b/examples/standalone/01_hello_compute/src/main.rs index 4a1f0346554..e9035c034db 100644 --- a/examples/standalone/01_hello_compute/src/main.rs +++ b/examples/standalone/01_hello_compute/src/main.rs @@ -70,6 +70,7 @@ fn main() { label: None, required_features: wgpu::Features::empty(), required_limits: wgpu::Limits::downlevel_defaults(), + experimental_features: wgpu::ExperimentalFeatures::disabled(), memory_hints: wgpu::MemoryHints::MemoryUsage, trace: wgpu::Trace::Off, })) diff --git a/player/tests/player/main.rs b/player/tests/player/main.rs index 1e16c3f0359..e50e4368d08 100644 --- a/player/tests/player/main.rs +++ b/player/tests/player/main.rs @@ -95,6 +95,7 @@ impl Test<'_> { label: None, required_features: self.features, required_limits: wgt::Limits::default(), + experimental_features: unsafe { wgt::ExperimentalFeatures::enabled() }, memory_hints: wgt::MemoryHints::default(), trace: wgt::Trace::Off, }, diff --git a/tests/src/init.rs b/tests/src/init.rs index 0a33f969f25..38073fa1b39 100644 --- a/tests/src/init.rs +++ b/tests/src/init.rs @@ -163,6 +163,7 @@ pub async fn initialize_device( label: None, required_features: features, required_limits: limits, + experimental_features: unsafe { wgpu::ExperimentalFeatures::enabled() }, memory_hints: wgpu::MemoryHints::MemoryUsage, trace: wgpu::Trace::Off, }) diff --git a/tests/tests/wgpu-gpu/device.rs b/tests/tests/wgpu-gpu/device.rs index 002ce316a21..5accb3d33b8 100644 --- a/tests/tests/wgpu-gpu/device.rs +++ b/tests/tests/wgpu-gpu/device.rs @@ -156,7 +156,7 @@ async fn request_device_error_message() { let expected = "TypeError"; } else { // This message appears whenever wgpu-core is used as the implementation. - let expected = "Unsupported features were requested: Features {"; + let expected = "Unsupported features were requested:"; } } assert!(device_error.contains(expected), "{device_error}"); diff --git a/tests/tests/wgpu-validation/api/experimental.rs b/tests/tests/wgpu-validation/api/experimental.rs new file mode 100644 index 00000000000..23cdc8ea4d3 --- /dev/null +++ b/tests/tests/wgpu-validation/api/experimental.rs @@ -0,0 +1,70 @@ +fn noop_adapter() -> wgpu::Adapter { + let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + backends: wgpu::Backends::NOOP, + backend_options: wgpu::BackendOptions { + noop: wgpu::NoopBackendOptions { enable: true }, + ..Default::default() + }, + ..Default::default() + }); + + pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions::default())) + .expect("noop backend adapter absent when it should be") +} + +#[test] +fn request_no_experimental_features() { + let adapter = noop_adapter(); + + let dq = pollster::block_on(adapter.request_device(&wgpu::DeviceDescriptor { + // Not experimental + required_features: wgpu::Features::FLOAT32_FILTERABLE, + experimental_features: wgpu::ExperimentalFeatures::disabled(), + ..Default::default() + })); + + assert!(dq.is_ok()); +} + +#[test] +fn request_experimental_features() { + let adapter = noop_adapter(); + + let dq = pollster::block_on(adapter.request_device(&wgpu::DeviceDescriptor { + // Experimental + required_features: wgpu::Features::EXPERIMENTAL_MESH_SHADER, + experimental_features: unsafe { wgpu::ExperimentalFeatures::enabled() }, + ..Default::default() + })); + + assert!(dq.is_ok()); +} + +#[test] +fn request_experimental_features_when_not_enabled() { + let adapter = noop_adapter(); + + let dq = pollster::block_on(adapter.request_device(&wgpu::DeviceDescriptor { + // Experimental + required_features: wgpu::Features::EXPERIMENTAL_MESH_SHADER, + experimental_features: wgpu::ExperimentalFeatures::disabled(), + ..Default::default() + })); + + assert!(dq.is_err()); +} + +#[test] +fn request_multiple_experimental_features_when_not_enabled() { + let adapter = noop_adapter(); + + let dq = pollster::block_on(adapter.request_device(&wgpu::DeviceDescriptor { + // Experimental + required_features: wgpu::Features::EXPERIMENTAL_MESH_SHADER + | wgpu::Features::EXPERIMENTAL_PASSTHROUGH_SHADERS, + experimental_features: wgpu::ExperimentalFeatures::disabled(), + ..Default::default() + })); + + assert!(dq.is_err()); +} diff --git a/tests/tests/wgpu-validation/api/mod.rs b/tests/tests/wgpu-validation/api/mod.rs index 383e86d3008..1266113fa36 100644 --- a/tests/tests/wgpu-validation/api/mod.rs +++ b/tests/tests/wgpu-validation/api/mod.rs @@ -2,6 +2,7 @@ mod binding_arrays; mod buffer; mod buffer_slice; mod device; +mod experimental; mod external_texture; mod instance; mod texture; diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 99f967f033b..4344622311d 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -797,6 +797,18 @@ impl Adapter { )); } + // Check if experimental features are permitted to be enabled. + if desc + .required_features + .intersects(wgt::Features::all_experimental_mask()) + && !desc.experimental_features.is_enabled() + { + return Err(RequestDeviceError::ExperimentalFeaturesNotEnabled( + desc.required_features + .intersection(wgt::Features::all_experimental_mask()), + )); + } + let caps = &self.raw.capabilities; if Backends::PRIMARY.contains(Backends::from(self.backend())) && !caps.downlevel.is_webgpu_compliant() @@ -857,8 +869,12 @@ pub enum RequestDeviceError { LimitsExceeded(#[from] FailedLimit), #[error("Failed to initialize Timestamp Normalizer")] TimestampNormalizerInitFailed(#[from] TimestampNormalizerInitError), - #[error("Unsupported features were requested: {0:?}")] + #[error("Unsupported features were requested: {0}")] UnsupportedFeature(wgt::Features), + #[error( + "Some experimental features, {0}, were requested, but experimental features are not enabled" + )] + ExperimentalFeaturesNotEnabled(wgt::Features), } #[derive(Clone, Debug, Error)] diff --git a/wgpu-types/src/features.rs b/wgpu-types/src/features.rs index d3db2264ba3..94a9a91cb50 100644 --- a/wgpu-types/src/features.rs +++ b/wgpu-types/src/features.rs @@ -1498,6 +1498,19 @@ impl Features { ])) } + /// Mask of all features which are experimental. + #[must_use] + pub const fn all_experimental_mask() -> Self { + Self::from_bits_truncate(FeatureBits([ + FeaturesWGPU::EXPERIMENTAL_MESH_SHADER.bits() + | FeaturesWGPU::EXPERIMENTAL_MESH_SHADER_MULTIVIEW.bits() + | FeaturesWGPU::EXPERIMENTAL_RAY_QUERY.bits() + | FeaturesWGPU::EXPERIMENTAL_RAY_HIT_VERTEX_RETURN.bits() + | FeaturesWGPU::EXPERIMENTAL_PASSTHROUGH_SHADERS.bits(), + FeaturesWebGPU::empty().bits(), + ])) + } + /// Vertex formats allowed for creating and building BLASes #[must_use] pub fn allowed_vertex_formats_for_blas(&self) -> Vec { @@ -1624,4 +1637,13 @@ mod tests { ) ); } + + #[test] + fn experimental_features_part_of_experimental_mask() { + for (name, feature) in Features::all().iter_names() { + let prefixed_with_experimental = name.starts_with("EXPERIMENTAL_"); + let in_experimental_mask = Features::all_experimental_mask().contains(feature); + assert_eq!(in_experimental_mask, prefixed_with_experimental); + } + } } diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 457b1b9f6ab..7674c0a95d8 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -41,11 +41,13 @@ pub mod error; mod features; pub mod instance; pub mod math; +mod tokens; mod transfers; pub use counters::*; pub use features::*; pub use instance::*; +pub use tokens::*; pub use transfers::*; /// Integral type used for [`Buffer`] offsets and sizes. @@ -1468,6 +1470,9 @@ pub struct DeviceDescriptor { /// Exactly the specified limits, and no better or worse, /// will be allowed in validation of API calls on the resulting device. pub required_limits: Limits, + /// Specifies whether `self.required_features` is allowed to contain experimental features. + #[cfg_attr(feature = "serde", serde(skip))] + pub experimental_features: ExperimentalFeatures, /// Hints for memory allocation strategies. pub memory_hints: MemoryHints, /// Whether API tracing for debugging is enabled, @@ -1483,6 +1488,7 @@ impl DeviceDescriptor { label: fun(&self.label), required_features: self.required_features, required_limits: self.required_limits.clone(), + experimental_features: self.experimental_features, memory_hints: self.memory_hints.clone(), trace: self.trace.clone(), } diff --git a/wgpu-types/src/tokens.rs b/wgpu-types/src/tokens.rs new file mode 100644 index 00000000000..ecf100ddb01 --- /dev/null +++ b/wgpu-types/src/tokens.rs @@ -0,0 +1,43 @@ +/// Token of the user agreeing to access experimental features. +#[derive(Debug, Default, Copy, Clone)] +pub struct ExperimentalFeatures { + enabled: bool, +} + +impl ExperimentalFeatures { + /// Uses of [`Features`] prefixed with "EXPERIMENTAL" are disallowed. + /// + /// [`Features`]: ../wgpu/struct.Features.html + pub const fn disabled() -> Self { + Self { enabled: false } + } + + /// Uses of [`Features`] prefixed with "EXPERIMENTAL" may result + /// in undefined behavior when used incorrectly. The exact bounds + /// of these issues varies by the feature. These instances are + /// inherently bugs in our implementation that we will eventually fix. + /// + /// By giving access to still work-in-progress APIs, users can get + /// access to newer technology sooner, and we can work with users + /// to fix bugs quicker. + /// + /// Look inside our repo at the [`api-specs`] for more information + /// on various experimental apis. + /// + /// # Safety + /// + /// - You acknowledge that there may be UB-containing bugs in these + /// apis and those may be hit by calling otherwise safe code. + /// - You agree to report any such bugs to us, if you find them. + /// + /// [`Features`]: ../wgpu/struct.Features.html + /// [`api-specs`]: https://github.com/gfx-rs/wgpu/tree/trunk/docs/api-specs + pub const unsafe fn enabled() -> Self { + Self { enabled: true } + } + + /// Returns true if the user has agreed to access experimental features. + pub const fn is_enabled(&self) -> bool { + self.enabled + } +} diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index dcfc1933810..85d9b901bab 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -91,7 +91,7 @@ pub use wgt::{ CommandBufferDescriptor, CompareFunction, CompositeAlphaMode, CopyExternalImageDestInfo, CoreCounters, DepthBiasState, DepthStencilState, DeviceLostReason, DeviceType, DownlevelCapabilities, DownlevelFlags, DownlevelLimits, Dx12BackendOptions, Dx12Compiler, - DxcShaderModel, DynamicOffset, Extent3d, ExternalTextureFormat, + DxcShaderModel, DynamicOffset, ExperimentalFeatures, Extent3d, ExternalTextureFormat, ExternalTextureTransferFunction, Face, Features, FeaturesWGPU, FeaturesWebGPU, FilterMode, FrontFace, GlBackendOptions, GlFenceBehavior, Gles3MinorVersion, HalCounters, ImageSubresourceRange, IndexFormat, InstanceDescriptor, InstanceFlags, InternalCounters, From 188a8cb3b4dd2354cce2d61caefec0eb62de9d2b Mon Sep 17 00:00:00 2001 From: David Duarte Date: Sat, 30 Aug 2025 00:53:43 +0200 Subject: [PATCH 183/303] ci: Make the install-{mesa,vulkan-sdk} action multiplatform (#8167) This also allow to remove the MESA_VERSION and VULKAN_SDK_VERSION duplication between the ci workflow and the install action. To pass down the version in each steps, I added action inputs because there is no way as of today to define environments variables that are shared between steps in composite actions (no top level `env:` like for workflows). --- .github/actions/install-mesa/action.yml | 39 +++++++++++--- .github/actions/install-vulkan-sdk/action.yml | 53 ++++++++++++++++--- .github/workflows/ci.yml | 44 ++------------- 3 files changed, 81 insertions(+), 55 deletions(-) diff --git a/.github/actions/install-mesa/action.yml b/.github/actions/install-mesa/action.yml index d6cbb580895..103c1e218f9 100644 --- a/.github/actions/install-mesa/action.yml +++ b/.github/actions/install-mesa/action.yml @@ -1,16 +1,22 @@ name: 'Install Mesa' description: 'Install Mesa' +inputs: + # Sourced from https://archive.mesa3d.org/. Bumping this requires + # updating the mesa build in https://github.com/gfx-rs/ci-build and creating a new release. + version: + default: '24.3.4' + # Corresponds to https://github.com/gfx-rs/ci-build/releases + ci-binary-build: + default: 'build20' runs: - using: "composite" + using: 'composite' steps: - - name: Install Mesa + - name: (Linux) Install Mesa + if: runner.os == 'Linux' shell: bash env: - # Sourced from https://archive.mesa3d.org/. Bumping this requires - # updating the mesa build in https://github.com/gfx-rs/ci-build and creating a new release. - MESA_VERSION: "24.3.4" - # Corresponds to https://github.com/gfx-rs/ci-build/releases - CI_BINARY_BUILD: "build20" + MESA_VERSION: ${{ inputs.version }} + CI_BINARY_BUILD: ${{ inputs.ci-binary-build }} run: | set -e @@ -34,3 +40,22 @@ runs: echo "VK_DRIVER_FILES=$PWD/icd.json" >> "$GITHUB_ENV" echo "LD_LIBRARY_PATH=$PWD/mesa/lib/x86_64-linux-gnu/:$LD_LIBRARY_PATH" >> "$GITHUB_ENV" echo "LIBGL_DRIVERS_PATH=$PWD/mesa/lib/x86_64-linux-gnu/dri" >> "$GITHUB_ENV" + + - name: (Windows) Install Mesa + if: runner.os == 'Windows' + shell: bash + env: + MESA_VERSION: ${{ inputs.version }} + CI_BINARY_BUILD: ${{ inputs.ci-binary-build }} + run: | + set -e + + curl.exe -L --retry 5 https://github.com/pal1000/mesa-dist-win/releases/download/$MESA_VERSION/mesa3d-$MESA_VERSION-release-msvc.7z -o mesa.7z + 7z.exe e mesa.7z -omesa x64/{opengl32.dll,libgallium_wgl.dll,libglapi.dll,vulkan_lvp.dll,lvp_icd.x86_64.json} + + cp -v mesa/* target/llvm-cov-target/debug/ + cp -v mesa/* target/llvm-cov-target/debug/deps + + # We need to use cygpath to convert PWD to a windows path as we're using bash. + echo "VK_DRIVER_FILES=`cygpath --windows $PWD/mesa/lvp_icd.x86_64.json`" >> "$GITHUB_ENV" + echo "GALLIUM_DRIVER=llvmpipe" >> "$GITHUB_ENV" diff --git a/.github/actions/install-vulkan-sdk/action.yml b/.github/actions/install-vulkan-sdk/action.yml index 8446c2c8854..e53dfa2a25f 100644 --- a/.github/actions/install-vulkan-sdk/action.yml +++ b/.github/actions/install-vulkan-sdk/action.yml @@ -1,14 +1,20 @@ -name: "Install Vulkan SDK" -description: "Install Vulkan SDK" +name: 'Install Vulkan SDK' +description: 'Install Vulkan SDK' +inputs: + # Sourced from https://vulkan.lunarg.com/sdk/home#linux + version: + default: '1.4.321' + full-version: + default: '1.4.321.0' runs: - using: "composite" + using: 'composite' steps: - - name: Install Vulkan SDK + - name: (Linux) Install Vulkan SDK + if: runner.os == 'Linux' shell: bash env: - # Sourced from https://vulkan.lunarg.com/sdk/home#linux - VULKAN_SDK_VERSION: "1.4.321" - VULKAN_FULL_SDK_VERSION: "1.4.321.0" + VULKAN_SDK_VERSION: ${{ inputs.version }} + VULKAN_FULL_SDK_VERSION: ${{ inputs.full-version }} run: | set -e @@ -21,3 +27,36 @@ runs: echo "$HOME/VulkanSDK/x86_64/bin" >> "$GITHUB_PATH" echo "LD_LIBRARY_PATH=$HOME/VulkanSDK/x86_64/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" >> "$GITHUB_ENV" echo "VK_ADD_LAYER_PATH=$HOME/VulkanSDK/x86_64/share/vulkan/explicit_layer.d" >> "$GITHUB_ENV" + + - name: (Windows) Install Vulkan SDK + if: runner.os == 'Windows' + shell: bash + env: + VULKAN_SDK_VERSION: ${{ inputs.version }} + VULKAN_FULL_SDK_VERSION: ${{ inputs.full-version }} + run: | + set -e + + curl.exe -L --retry 5 https://sdk.lunarg.com/sdk/download/${{ env.VULKAN_FULL_SDK_VERSION }}/windows/vulkansdk-windows-X64-${{ env.VULKAN_FULL_SDK_VERSION }}.exe -o vulkan-sdk-installer.exe + + ./vulkan-sdk-installer.exe --accept-licenses --default-answer --confirm-command install + + echo "C:/VulkanSDK/${{ env.VULKAN_FULL_SDK_VERSION }}/Bin" >> "$GITHUB_PATH" + + + - name: (Mac) Install Vulkan SDK + if: runner.os == 'macOS' + shell: bash + env: + VULKAN_SDK_VERSION: ${{ inputs.version }} + VULKAN_FULL_SDK_VERSION: ${{ inputs.full-version }} + run: | + set -e + + curl -L --retry 5 https://sdk.lunarg.com/sdk/download/${{ env.VULKAN_FULL_SDK_VERSION }}/mac/vulkansdk-macos-${{ env.VULKAN_FULL_SDK_VERSION }}.zip -o vulkan-sdk.zip + unzip vulkan-sdk.zip -d vulkan-sdk + + ls -l vulkan-sdk + sudo ./vulkan-sdk/vulkansdk-macOS-${{ env.VULKAN_FULL_SDK_VERSION }}.app/Contents/MacOS/vulkansdk-macOS-${{ env.VULKAN_FULL_SDK_VERSION }} --root "$HOME/VulkanSDK" --accept-licenses --default-answer --confirm-command install + + echo "$HOME/VulkanSDK/macOS/bin" >> "$GITHUB_PATH" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 30abd643f3b..6529ff5e8e4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,14 +18,6 @@ env: # Dependency versioning # - # Sourced from https://vulkan.lunarg.com/sdk/home#linux - # These Vulkan version definition is duplicated in the install-vulkan action. - VULKAN_SDK_VERSION: "1.4.321" - VULKAN_FULL_SDK_VERSION: "1.4.321.0" - - # These Mesa version definition is duplicated in the install-mesa action. - MESA_VERSION: "24.3.4" - # This is the MSRV used by `wgpu` itself and all surrounding infrastructure. REPO_MSRV: "1.88" # This is the MSRV used by the `wgpu-core`, `wgpu-hal`, and `wgpu-types` crates, @@ -563,45 +555,15 @@ jobs: - name: (Windows) Install Mesa if: matrix.os == 'windows-2022' - shell: bash - run: | - set -e - - curl.exe -L --retry 5 https://github.com/pal1000/mesa-dist-win/releases/download/$MESA_VERSION/mesa3d-$MESA_VERSION-release-msvc.7z -o mesa.7z - 7z.exe e mesa.7z -omesa x64/{opengl32.dll,libgallium_wgl.dll,libglapi.dll,vulkan_lvp.dll,lvp_icd.x86_64.json} - - cp -v mesa/* target/llvm-cov-target/debug/ - cp -v mesa/* target/llvm-cov-target/debug/deps - - # We need to use cygpath to convert PWD to a windows path as we're using bash. - echo "VK_DRIVER_FILES=`cygpath --windows $PWD/mesa/lvp_icd.x86_64.json`" >> "$GITHUB_ENV" - echo "GALLIUM_DRIVER=llvmpipe" >> "$GITHUB_ENV" + uses: ./.github/actions/install-mesa - name: (Windows) Install Vulkan SDK if: matrix.os == 'windows-2022' - shell: bash - run: | - set -e - - curl.exe -L --retry 5 https://sdk.lunarg.com/sdk/download/${{ env.VULKAN_FULL_SDK_VERSION }}/windows/vulkansdk-windows-X64-${{ env.VULKAN_FULL_SDK_VERSION }}.exe -o vulkan-sdk-installer.exe - - ./vulkan-sdk-installer.exe --accept-licenses --default-answer --confirm-command install - - echo "C:/VulkanSDK/${{ env.VULKAN_FULL_SDK_VERSION }}/Bin" >> "$GITHUB_PATH" + uses: ./.github/actions/install-vulkan-sdk - name: (Mac) Install Vulkan SDK if: matrix.os == 'macos-14' - shell: bash - run: | - set -e - - curl -L --retry 5 https://sdk.lunarg.com/sdk/download/${{ env.VULKAN_FULL_SDK_VERSION }}/mac/vulkansdk-macos-${{ env.VULKAN_FULL_SDK_VERSION }}.zip -o vulkan-sdk.zip - unzip vulkan-sdk.zip -d vulkan-sdk - - ls -l vulkan-sdk - sudo ./vulkan-sdk/vulkansdk-macOS-${{ env.VULKAN_FULL_SDK_VERSION }}.app/Contents/MacOS/vulkansdk-macOS-${{ env.VULKAN_FULL_SDK_VERSION }} --root "$HOME/VulkanSDK" --accept-licenses --default-answer --confirm-command install - - echo "$HOME/VulkanSDK/macOS/bin" >> "$GITHUB_PATH" + uses: ./.github/actions/install-vulkan-sdk - name: (Linux) Install Vulkan SDK if: matrix.os == 'ubuntu-24.04' From 12c8b378a1f96729565125b2d6aac09ca044a0be Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Mon, 1 Sep 2025 13:37:42 +0100 Subject: [PATCH 184/303] [naga wgsl-in] add "texture_external" to reserved keyword list (#8178) --- naga/src/keywords/wgsl.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/naga/src/keywords/wgsl.rs b/naga/src/keywords/wgsl.rs index 9bfce05d2f9..8ec0dd59c5f 100644 --- a/naga/src/keywords/wgsl.rs +++ b/naga/src/keywords/wgsl.rs @@ -36,6 +36,7 @@ pub const RESERVED: &[&str] = &[ "texture_3d", "texture_cube", "texture_cube_array", + "texture_external", "texture_multisampled_2d", "texture_storage_1d", "texture_storage_2d", From c488bbe60447d28736c26c82a32cd87794b3bf1d Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Tue, 2 Sep 2025 12:21:16 -0400 Subject: [PATCH 185/303] [wgpu] Improve buffer mapping errors and allow multiple immutable borrows (#8150) Co-authored-by: Andreas Reich --- CHANGELOG.md | 1 + .../wgpu-validation/api/buffer_mapping.rs | 191 ++++++++++++++++++ tests/tests/wgpu-validation/api/mod.rs | 1 + wgpu/src/api/buffer.rs | 160 ++++++++++++--- wgpu/src/api/device.rs | 10 +- wgpu/src/lib.rs | 5 +- 6 files changed, 326 insertions(+), 42 deletions(-) create mode 100644 tests/tests/wgpu-validation/api/buffer_mapping.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index ffca24947bf..c85b7697418 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -125,6 +125,7 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). By @kpreid in [#8011](https://github.com/gfx-rs/wgpu/pull/8011). - Make a compacted hal acceleration structure inherit a label from the base BLAS. By @Vecvec in [#8103](https://github.com/gfx-rs/wgpu/pull/8103). - The limits requested for a device must now satisfy `min_subgroup_size <= max_subgroup_size`. By @andyleiserson in [#8085](https://github.com/gfx-rs/wgpu/pull/8085). +- Improve errors when buffer mapping is done incorrectly. Allow aliasing immutable [`BufferViews`]. By @cwfitzgerald in [#8150](https://github.com/gfx-rs/wgpu/pull/8150). - Require new `F16_IN_F32` downlevel flag for `quantizeToF16`, `pack2x16float`, and `unpack2x16float` in WGSL input. By @aleiserson in [#8130](https://github.com/gfx-rs/wgpu/pull/8130). - The error message for non-copyable depth/stencil formats no longer mentions the aspect when it is not relevant. By @reima in [#8156](https://github.com/gfx-rs/wgpu/pull/8156). diff --git a/tests/tests/wgpu-validation/api/buffer_mapping.rs b/tests/tests/wgpu-validation/api/buffer_mapping.rs new file mode 100644 index 00000000000..62fcf0a8068 --- /dev/null +++ b/tests/tests/wgpu-validation/api/buffer_mapping.rs @@ -0,0 +1,191 @@ +fn mapping_is_zeroed(array: &[u8]) { + for (i, &byte) in array.iter().enumerate() { + assert_eq!(byte, 0, "Byte at index {i} is not zero"); + } +} + +// Ensure that a simple immutable mapping works and it is zeroed. +#[test] +fn full_immutable_binding() { + let (device, _queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + + let buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 1024, + usage: wgpu::BufferUsages::MAP_READ, + mapped_at_creation: false, + }); + + buffer.map_async(wgpu::MapMode::Read, .., |_| {}); + device.poll(wgpu::PollType::Wait).unwrap(); + + let mapping = buffer.slice(..).get_mapped_range(); + + mapping_is_zeroed(&mapping); + + drop(mapping); + + buffer.unmap(); +} + +// Ensure that a simple mutable binding works and it is zeroed. +#[test] +fn full_mut_binding() { + let (device, _queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + + let buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 1024, + usage: wgpu::BufferUsages::MAP_WRITE | wgpu::BufferUsages::COPY_SRC, + mapped_at_creation: true, + }); + + let mapping = buffer.slice(..).get_mapped_range_mut(); + + mapping_is_zeroed(&mapping); + + drop(mapping); + + buffer.unmap(); +} + +// Ensure that you can make two non-overlapping immutable ranges, which are both zeroed +#[test] +fn split_immutable_binding() { + let (device, _queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + + let buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 1024, + usage: wgpu::BufferUsages::MAP_READ, + mapped_at_creation: false, + }); + + buffer.map_async(wgpu::MapMode::Read, .., |_| {}); + device.poll(wgpu::PollType::Wait).unwrap(); + + let mapping0 = buffer.slice(0..512).get_mapped_range(); + let mapping1 = buffer.slice(512..1024).get_mapped_range(); + + mapping_is_zeroed(&mapping0); + mapping_is_zeroed(&mapping1); + + drop(mapping0); + drop(mapping1); + + buffer.unmap(); +} + +/// Ensure that you can make two non-overlapping mapped ranges, which are both zeroed +#[test] +fn split_mut_binding() { + let (device, _queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + + let buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 1024, + usage: wgpu::BufferUsages::MAP_WRITE | wgpu::BufferUsages::COPY_SRC, + mapped_at_creation: true, + }); + + let mapping0 = buffer.slice(0..512).get_mapped_range_mut(); + let mapping1 = buffer.slice(512..1024).get_mapped_range_mut(); + + mapping_is_zeroed(&mapping0); + mapping_is_zeroed(&mapping1); + + drop(mapping0); + drop(mapping1); + + buffer.unmap(); +} + +/// Ensure that you can make two overlapping immutablely mapped ranges. +#[test] +fn overlapping_ref_binding() { + let (device, _queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + + let buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 1024, + usage: wgpu::BufferUsages::MAP_WRITE | wgpu::BufferUsages::COPY_SRC, + mapped_at_creation: true, + }); + + let _mapping0 = buffer.slice(0..512).get_mapped_range(); + let _mapping1 = buffer.slice(256..768).get_mapped_range(); +} + +/// Ensure that two overlapping mutably mapped ranges panics. +#[test] +#[should_panic(expected = "break Rust memory aliasing rules")] +fn overlapping_mut_binding() { + let (device, _queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + + let buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 1024, + usage: wgpu::BufferUsages::MAP_WRITE | wgpu::BufferUsages::COPY_SRC, + mapped_at_creation: true, + }); + + let _mapping0 = buffer.slice(0..512).get_mapped_range_mut(); + let _mapping1 = buffer.slice(256..768).get_mapped_range_mut(); +} + +/// Ensure that when you try to get a mapped range from an unmapped buffer, it panics with +/// an error mentioning a completely unmapped buffer. +#[test] +#[should_panic(expected = "an unmapped buffer")] +fn not_mapped() { + let (device, _queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + + let buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 1024, + usage: wgpu::BufferUsages::MAP_WRITE | wgpu::BufferUsages::COPY_SRC, + mapped_at_creation: false, + }); + + let _mapping = buffer.slice(..).get_mapped_range_mut(); +} + +/// Ensure that when you partially map a buffer, then try to read outside of that range, it panics +/// mentioning the mapped indices. +#[test] +#[should_panic( + expected = "Attempted to get range 512..1024 (Mutable), but the mapped range is 0..512" +)] +fn partially_mapped() { + let (device, _queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + + let buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 1024, + usage: wgpu::BufferUsages::MAP_WRITE | wgpu::BufferUsages::COPY_SRC, + mapped_at_creation: false, + }); + + buffer.map_async(wgpu::MapMode::Write, 0..512, |_| {}); + device.poll(wgpu::PollType::Wait).unwrap(); + + let _mapping0 = buffer.slice(0..512).get_mapped_range_mut(); + let _mapping1 = buffer.slice(512..1024).get_mapped_range_mut(); +} + +/// Ensure that you cannot unmap a buffer while there are still accessible mapped views. +#[test] +#[should_panic(expected = "You cannot unmap a buffer that still has accessible mapped views")] +fn unmap_while_visible() { + let (device, _queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + + let buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 1024, + usage: wgpu::BufferUsages::MAP_WRITE | wgpu::BufferUsages::COPY_SRC, + mapped_at_creation: true, + }); + + let _mapping0 = buffer.slice(..).get_mapped_range_mut(); + buffer.unmap(); +} diff --git a/tests/tests/wgpu-validation/api/mod.rs b/tests/tests/wgpu-validation/api/mod.rs index 1266113fa36..9d591fa6b94 100644 --- a/tests/tests/wgpu-validation/api/mod.rs +++ b/tests/tests/wgpu-validation/api/mod.rs @@ -1,5 +1,6 @@ mod binding_arrays; mod buffer; +mod buffer_mapping; mod buffer_slice; mod device; mod experimental; diff --git a/wgpu/src/api/buffer.rs b/wgpu/src/api/buffer.rs index 28b43b76b0d..537b95b8196 100644 --- a/wgpu/src/api/buffer.rs +++ b/wgpu/src/api/buffer.rs @@ -396,9 +396,10 @@ impl Buffer { /// - If `bounds` has a length less than 1. /// - If the start and end of `bounds` are not aligned to [`MAP_ALIGNMENT`]. /// - If the buffer to which `self` refers is not currently [mapped]. - /// - If you try to create overlapping views of a buffer, mutable or otherwise. + /// - If you try to create a view which overlaps an existing [`BufferViewMut`]. /// /// [mapped]: Buffer#mapping-buffers + #[track_caller] pub fn get_mapped_range>(&self, bounds: S) -> BufferView { self.slice(bounds).get_mapped_range() } @@ -419,9 +420,10 @@ impl Buffer { /// - If `bounds` has a length less than 1. /// - If the start and end of `bounds` are not aligned to [`MAP_ALIGNMENT`]. /// - If the buffer to which `self` refers is not currently [mapped]. - /// - If you try to create overlapping views of a buffer, mutable or otherwise. + /// - If you try to create a view which overlaps an existing [`BufferView`] or [`BufferViewMut`]. /// /// [mapped]: Buffer#mapping-buffers + #[track_caller] pub fn get_mapped_range_mut>(&self, bounds: S) -> BufferViewMut { self.slice(bounds).get_mapped_range_mut() } @@ -534,9 +536,9 @@ impl<'a> BufferSlice<'a> { callback: impl FnOnce(Result<(), BufferAsyncError>) + WasmNotSend + 'static, ) { let mut mc = self.buffer.map_context.lock(); - assert_eq!(mc.initial_range, 0..0, "Buffer is already mapped"); + assert_eq!(mc.mapped_range, 0..0, "Buffer is already mapped"); let end = self.offset + self.size.get(); - mc.initial_range = self.offset..end; + mc.mapped_range = self.offset..end; self.buffer .inner @@ -557,12 +559,17 @@ impl<'a> BufferSlice<'a> { /// /// - If the endpoints of this slice are not aligned to [`MAP_ALIGNMENT`] within the buffer. /// - If the buffer to which `self` refers is not currently [mapped]. - /// - If you try to create overlapping views of a buffer, mutable or otherwise. + /// - If you try to create a view which overlaps an existing [`BufferViewMut`]. /// /// [mapped]: Buffer#mapping-buffers + #[track_caller] pub fn get_mapped_range(&self) -> BufferView { - let end = self.buffer.map_context.lock().add(self.offset, self.size); - let range = self.buffer.inner.get_mapped_range(self.offset..end); + let subrange = Subrange::new(self.offset, self.size, RangeMappingKind::Immutable); + self.buffer + .map_context + .lock() + .validate_and_add(subrange.clone()); + let range = self.buffer.inner.get_mapped_range(subrange.index); BufferView { buffer: self.buffer.clone(), size: self.size, @@ -585,12 +592,17 @@ impl<'a> BufferSlice<'a> { /// /// - If the endpoints of this slice are not aligned to [`MAP_ALIGNMENT`]. /// - If the buffer to which `self` refers is not currently [mapped]. - /// - If you try to create overlapping views of a buffer, mutable or otherwise. + /// - If you try to create a view which overlaps an existing [`BufferView`] or [`BufferViewMut`]. /// /// [mapped]: Buffer#mapping-buffers + #[track_caller] pub fn get_mapped_range_mut(&self) -> BufferViewMut { - let end = self.buffer.map_context.lock().add(self.offset, self.size); - let range = self.buffer.inner.get_mapped_range(self.offset..end); + let subrange = Subrange::new(self.offset, self.size, RangeMappingKind::Mutable); + self.buffer + .map_context + .lock() + .validate_and_add(subrange.clone()); + let range = self.buffer.inner.get_mapped_range(subrange.index); BufferViewMut { buffer: self.buffer.clone(), size: self.size, @@ -640,6 +652,53 @@ impl<'a> From> for crate::BindingResource<'a> { } } +fn range_overlaps(a: &Range, b: &Range) -> bool { + a.start < b.end && b.start < a.end +} + +#[derive(Debug, Copy, Clone)] +enum RangeMappingKind { + Mutable, + Immutable, +} + +impl RangeMappingKind { + /// Returns true if a range of this kind can touch the same bytes as a range of the other kind. + /// + /// This is Rust's Mutable XOR Shared rule. + fn allowed_concurrently_with(self, other: Self) -> bool { + matches!( + (self, other), + (RangeMappingKind::Immutable, RangeMappingKind::Immutable) + ) + } +} + +#[derive(Debug, Clone)] +struct Subrange { + index: Range, + kind: RangeMappingKind, +} + +impl Subrange { + fn new(offset: BufferAddress, size: BufferSize, kind: RangeMappingKind) -> Self { + Self { + index: offset..(offset + size.get()), + kind, + } + } +} + +impl fmt::Display for Subrange { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}..{} ({:?})", + self.index.start, self.index.end, self.kind + ) + } +} + /// The mapped portion of a buffer, if any, and its outstanding views. /// /// This ensures that views fall within the mapped range and don't overlap. @@ -653,25 +712,31 @@ pub(crate) struct MapContext { /// *or has been requested to be* mapped.) /// /// All [`BufferView`]s and [`BufferViewMut`]s must fall within this range. - pub(crate) initial_range: Range, + mapped_range: Range, /// The ranges covered by all outstanding [`BufferView`]s and /// [`BufferViewMut`]s. These are non-overlapping, and are all contained - /// within `initial_range`. - sub_ranges: Vec>, + /// within `mapped_range`. + sub_ranges: Vec, } impl MapContext { - pub(crate) fn new() -> Self { + /// Creates a new `MapContext`. + /// + /// For [`mapped_at_creation`] buffers, pass the full buffer range in the + /// `mapped_range` argument. For other buffers, pass `None`. + /// + /// [`mapped_at_creation`]: BufferDescriptor::mapped_at_creation + pub(crate) fn new(mapped_range: Option>) -> Self { Self { - initial_range: 0..0, + mapped_range: mapped_range.unwrap_or(0..0), sub_ranges: Vec::new(), } } /// Record that the buffer is no longer mapped. fn reset(&mut self) { - self.initial_range = 0..0; + self.mapped_range = 0..0; assert!( self.sub_ranges.is_empty(), @@ -681,25 +746,38 @@ impl MapContext { /// Record that the `size` bytes of the buffer at `offset` are now viewed. /// - /// Return the byte offset within the buffer of the end of the viewed range. - /// /// # Panics /// - /// This panics if the given range overlaps with any existing range. - fn add(&mut self, offset: BufferAddress, size: BufferSize) -> BufferAddress { - let end = offset + size.get(); - assert!(self.initial_range.start <= offset && end <= self.initial_range.end); + /// This panics if the given range is invalid. + #[track_caller] + fn validate_and_add(&mut self, new_sub: Subrange) { + if self.mapped_range.is_empty() { + panic!("tried to call get_mapped_range(_mut) on an unmapped buffer"); + } + if !range_overlaps(&self.mapped_range, &new_sub.index) { + panic!( + "tried to call get_mapped_range(_mut) on a range that is not entirely mapped. \ + Attempted to get range {}, but the mapped range is {}..{}", + new_sub, self.mapped_range.start, self.mapped_range.end + ); + } + // This check is essential for avoiding undefined behavior: it is the // only thing that ensures that `&mut` references to the buffer's // contents don't alias anything else. for sub in self.sub_ranges.iter() { - assert!( - end <= sub.start || offset >= sub.end, - "Intersecting map range with {sub:?}" - ); + if range_overlaps(&sub.index, &new_sub.index) + && !sub.kind.allowed_concurrently_with(new_sub.kind) + { + panic!( + "tried to call get_mapped_range(_mut) on a range that has already \ + been mapped and would break Rust memory aliasing rules. Attempted \ + to get range {}, and the conflicting range is {}", + new_sub, sub + ); + } } - self.sub_ranges.push(offset..end); - end + self.sub_ranges.push(new_sub); } /// Record that the `size` bytes of the buffer at `offset` are no longer viewed. @@ -707,16 +785,14 @@ impl MapContext { /// # Panics /// /// This panics if the given range does not exactly match one previously - /// passed to [`add`]. - /// - /// [`add]`: MapContext::add + /// passed to [`MapContext::validate_and_add`]. fn remove(&mut self, offset: BufferAddress, size: BufferSize) { let end = offset + size.get(); let index = self .sub_ranges .iter() - .position(|r| *r == (offset..end)) + .position(|r| r.index == (offset..end)) .expect("unable to remove range from map context"); self.sub_ranges.swap_remove(index); } @@ -922,7 +998,9 @@ fn range_to_offset_size>( #[cfg(test)] mod tests { - use super::{check_buffer_bounds, range_to_offset_size, BufferAddress, BufferSize}; + use super::{ + check_buffer_bounds, range_overlaps, range_to_offset_size, BufferAddress, BufferSize, + }; fn bs(value: BufferAddress) -> BufferSize { BufferSize::new(value).unwrap() @@ -972,4 +1050,20 @@ mod tests { fn check_buffer_bounds_panics_for_end_wraparound() { check_buffer_bounds(u64::MAX, 1, bs(u64::MAX)); } + + #[test] + fn range_overlapping() { + // First range to the left + assert_eq!(range_overlaps(&(0..1), &(1..3)), false); + // First range overlaps left edge + assert_eq!(range_overlaps(&(0..2), &(1..3)), true); + // First range completely inside second + assert_eq!(range_overlaps(&(1..2), &(0..3)), true); + // First range completely surrounds second + assert_eq!(range_overlaps(&(0..3), &(1..2)), true); + // First range overlaps right edge + assert_eq!(range_overlaps(&(1..3), &(0..2)), true); + // First range entirely to the right + assert_eq!(range_overlaps(&(2..3), &(0..2)), false); + } } diff --git a/wgpu/src/api/device.rs b/wgpu/src/api/device.rs index a0b51c4be7b..c3929587038 100644 --- a/wgpu/src/api/device.rs +++ b/wgpu/src/api/device.rs @@ -262,10 +262,7 @@ impl Device { /// Creates a [`Buffer`]. #[must_use] pub fn create_buffer(&self, desc: &BufferDescriptor<'_>) -> Buffer { - let mut map_context = MapContext::new(); - if desc.mapped_at_creation { - map_context.initial_range = 0..desc.size; - } + let map_context = MapContext::new(desc.mapped_at_creation.then_some(0..desc.size)); let buffer = self.inner.create_buffer(desc); @@ -371,10 +368,7 @@ impl Device { hal_buffer: A::Buffer, desc: &BufferDescriptor<'_>, ) -> Buffer { - let mut map_context = MapContext::new(); - if desc.mapped_at_creation { - map_context.initial_range = 0..desc.size; - } + let map_context = MapContext::new(desc.mapped_at_creation.then_some(0..desc.size)); let buffer = unsafe { let core_device = self.inner.as_core(); diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 85d9b901bab..a9f5d898205 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -45,7 +45,10 @@ )] #![allow( // We need to investiagate these. - clippy::large_enum_variant + clippy::large_enum_variant, + // These degrade readability significantly. + clippy::bool_assert_comparison, + clippy::bool_comparison, )] // NOTE: Keep this in sync with `wgpu-core`. #![cfg_attr(not(send_sync), allow(clippy::arc_with_non_send_sync))] From fcde047ae8da41d30ccfee0069e46ceb5fd9073c Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Thu, 4 Sep 2025 11:58:31 -0700 Subject: [PATCH 186/303] Fix `cargo deny` problems (#8182) --- Cargo.lock | 58 +++++++++++++++++------------------------------------- 1 file changed, 18 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b51813cbaf9..3dd9d255891 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1350,9 +1350,9 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "encase" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6257b506d94265d4ec55a02fc6fe8a7311c1718e99cd5d2fc63c76674a94c801" +checksum = "02ba239319a4f60905966390f5e52799d868103a533bb7e27822792332504ddd" dependencies = [ "const_panic", "encase_derive", @@ -1362,18 +1362,18 @@ dependencies = [ [[package]] name = "encase_derive" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71a9aa6b6a1caf2d2e04e4adcee9c8466e86cd84129bd8e9d15bad2b003396af" +checksum = "5223d6c647f09870553224f6e37261fe5567bc5a4f4cf13ed337476e79990f2f" dependencies = [ "encase_derive_impl", ] [[package]] name = "encase_derive_impl" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0a79c61182bf68a5dff807c3feb93d5348310afdb3fbe4c907db0e1696f500f" +checksum = "1796db3d892515842ca2dfb11124c4bb4a9e58d9f2c5c1072e5bca1b2334507b" dependencies = [ "proc-macro2", "quote", @@ -2400,11 +2400,11 @@ dependencies = [ [[package]] name = "matchers" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" dependencies = [ - "regex-automata 0.1.10", + "regex-automata", ] [[package]] @@ -2680,12 +2680,11 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.46.0" +version = "0.50.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" dependencies = [ - "overload", - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -3068,12 +3067,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "owned_ttf_parser" version = "0.25.1" @@ -3505,17 +3498,8 @@ checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.10", - "regex-syntax 0.8.6", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", + "regex-automata", + "regex-syntax", ] [[package]] @@ -3526,7 +3510,7 @@ checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.6", + "regex-syntax", ] [[package]] @@ -3535,12 +3519,6 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "943f41321c63ef1c92fd763bfe054d2668f7f225a5c29f0105903dc2fc04ba30" -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - [[package]] name = "regex-syntax" version = "0.8.6" @@ -4355,14 +4333,14 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ "matchers", "nu-ansi-term", "once_cell", - "regex", + "regex-automata", "sharded-slab", "smallvec", "thread_local", From 989d48ccb6459f705831833956fca95df9b1444a Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 13 Aug 2025 20:11:41 -0700 Subject: [PATCH 187/303] Tweak the bytes_per_row alignment check Previously, the check was skipped if the copy was a single row, which is not correct. The check should be made whenever bytes_per_row is specified. It is permissible not to specify bytes_per_row if the copy is a single row, but if it is specified, it must be aligned. Also removes a redundant check of the `offset` alignment. Since the offset and bytesPerRow alignment checks are not part of "validating linear texture data", I chose to remove that instance of them. These checks are now in `validate_texture_buffer_copy`, which does not correspond 1:1 with the spec, but has a comment explaining how it does correspond. --- CHANGELOG.md | 1 + cts_runner/test.lst | 2 ++ wgpu-core/src/command/transfer.rs | 50 ++++++++++++++----------------- wgpu-core/src/device/queue.rs | 5 ++-- 4 files changed, 27 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c85b7697418..45280e4e8d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -118,6 +118,7 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). - Copies within the same texture must not overlap. - Copies of multisampled or depth/stencil formats must span an entire subresource (layer). - Copies of depth/stencil formats must be 4B aligned. + - For texture-buffer copies, `bytes_per_row` on the buffer side must be 256B-aligned, even if the transfer is a single row. - The offset for `set_vertex_buffer` and `set_index_buffer` must be 4B aligned. By @andyleiserson in [#7929](https://github.com/gfx-rs/wgpu/pull/7929). - The offset and size of bindings are validated as fitting within the underlying buffer in more cases. By @andyleiserson in [#7911](https://github.com/gfx-rs/wgpu/pull/7911). - The function you pass to `Device::on_uncaptured_error()` must now implement `Sync` in addition to `Send`, and be wrapped in `Arc` instead of `Box`. diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 918b37e06d2..5643586f15f 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -82,6 +82,8 @@ fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:depth_sten webgpu:api,validation,image_copy,buffer_texture_copies:sample_count:* webgpu:api,validation,image_copy,buffer_texture_copies:texture_buffer_usages:* webgpu:api,validation,image_copy,buffer_texture_copies:device_mismatch:* +fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="rgba32float";copyType="CopyB2T";dimension="1d" +fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="rgba32float";copyType="CopyT2B";dimension="1d" fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="rgba8unorm";copyType="CopyB2T";dimension="2d" fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="rgba8unorm";copyType="CopyT2B";dimension="2d" fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="rgba8unorm";copyType="CopyB2T";dimension="3d" diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 2115b23b753..5caee246543 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -288,7 +288,6 @@ pub(crate) fn validate_linear_texture_data( buffer_size: BufferAddress, buffer_side: CopySide, copy_size: &Extent3d, - need_copy_aligned_rows: bool, ) -> Result<(BufferAddress, BufferAddress), TransferError> { let wgt::BufferTextureCopyInfo { copy_width, @@ -297,7 +296,7 @@ pub(crate) fn validate_linear_texture_data( offset, - block_size_bytes, + block_size_bytes: _, block_width_texels, block_height_texels, @@ -338,24 +337,6 @@ pub(crate) fn validate_linear_texture_data( return Err(TransferError::UnspecifiedRowsPerImage); }; - if need_copy_aligned_rows { - let bytes_per_row_alignment = wgt::COPY_BYTES_PER_ROW_ALIGNMENT as BufferAddress; - - let mut offset_alignment = block_size_bytes; - if format.is_depth_stencil_format() { - offset_alignment = 4 - } - if offset % offset_alignment != 0 { - return Err(TransferError::UnalignedBufferOffset(offset)); - } - - // The alignment of row_stride_bytes is only required if there are - // multiple rows - if requires_multiple_rows && row_stride_bytes % bytes_per_row_alignment != 0 { - return Err(TransferError::UnalignedBytesPerRow); - } - } - // Avoid underflow in the subtraction by checking bytes_in_copy against buffer_size first. if bytes_in_copy > buffer_size || offset > buffer_size - bytes_in_copy { return Err(TransferError::BufferOverrun { @@ -425,7 +406,15 @@ pub(crate) fn validate_texture_copy_dst_format( /// * The copy must be from/to a single aspect of the texture. /// * If `aligned` is true, the buffer offset must be aligned appropriately. /// -/// The following steps in the algorithm are implemented elsewhere: +/// And implements the following check from WebGPU's [validating GPUTexelCopyBufferInfo][vtcbi] +/// algorithm: +/// * If `aligned` is true, `bytesPerRow` must be a multiple of 256. +/// +/// Note that the `bytesPerRow` alignment check is enforced whenever +/// `bytesPerRow` is specified, even if the transfer is not multiple rows and +/// `bytesPerRow` could have been omitted. +/// +/// The following steps in [validating texture buffer copy][vtbc] are implemented elsewhere: /// * Invocation of other validation algorithms. /// * The texture usage (COPY_DST / COPY_SRC) check. /// * The check for non-copyable depth/stencil formats. The caller must perform @@ -435,11 +424,12 @@ pub(crate) fn validate_texture_copy_dst_format( /// non-copyable format. /// /// [vtbc]: https://gpuweb.github.io/gpuweb/#abstract-opdef-validating-texture-buffer-copy +/// [vtcbi]: https://www.w3.org/TR/webgpu/#abstract-opdef-validating-gputexelcopybufferinfo pub(crate) fn validate_texture_buffer_copy( texture_copy_view: &wgt::TexelCopyTextureInfo, aspect: hal::FormatAspects, desc: &wgt::TextureDescriptor<(), Vec>, - offset: BufferAddress, + layout: &wgt::TexelCopyBufferLayout, aligned: bool, ) -> Result<(), TransferError> { if desc.sample_count != 1 { @@ -464,8 +454,14 @@ pub(crate) fn validate_texture_buffer_copy( .expect("non-copyable formats should have been rejected previously") }; - if aligned && offset % u64::from(offset_alignment) != 0 { - return Err(TransferError::UnalignedBufferOffset(offset)); + if aligned && layout.offset % u64::from(offset_alignment) != 0 { + return Err(TransferError::UnalignedBufferOffset(layout.offset)); + } + + if let Some(bytes_per_row) = layout.bytes_per_row { + if aligned && bytes_per_row % wgt::COPY_BYTES_PER_ROW_ALIGNMENT != 0 { + return Err(TransferError::UnalignedBytesPerRow); + } } Ok(()) @@ -1004,7 +1000,7 @@ impl Global { destination, dst_base.aspect, &dst_texture.desc, - source.layout.offset, + &source.layout, true, // alignment required for buffer offset )?; @@ -1016,7 +1012,6 @@ impl Global { src_buffer.size, CopySide::Source, copy_size, - true, )?; if dst_texture.desc.format.is_depth_stencil_format() { @@ -1125,7 +1120,7 @@ impl Global { source, src_base.aspect, &src_texture.desc, - destination.layout.offset, + &destination.layout, true, // alignment required for buffer offset )?; @@ -1137,7 +1132,6 @@ impl Global { dst_buffer.size, CopySide::Destination, copy_size, - true, )?; if src_texture.desc.format.is_depth_stencil_format() { diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index d9f338cf7c7..f7a60fe733c 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -763,8 +763,8 @@ impl Queue { &destination, dst_base.aspect, &dst.desc, - data_layout.offset, - false, // alignment not required for buffer offset + &data_layout, + false, // alignment not required for buffer offset or bytes per row )?; // Note: `_source_bytes_per_array_layer` is ignored since we @@ -776,7 +776,6 @@ impl Queue { data.len() as wgt::BufferAddress, CopySide::Source, size, - false, )?; if dst.desc.format.is_depth_stencil_format() { From 4853133eaa2acaacafc3768bd3a5337849a953f5 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 13 Aug 2025 20:13:31 -0700 Subject: [PATCH 188/303] Fix buffer initialization tracking for some buffer-texture copies (#8099) Fixes #7947 Fixes #8021 Fixes #8097 --- CHANGELOG.md | 1 + cts_runner/test.lst | 17 ++-- wgpu-core/src/command/transfer.rs | 134 +++++++++++++++++++++++++----- wgpu-core/src/device/queue.rs | 19 +++-- 4 files changed, 132 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45280e4e8d8..bc716bd4b2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -129,6 +129,7 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). - Improve errors when buffer mapping is done incorrectly. Allow aliasing immutable [`BufferViews`]. By @cwfitzgerald in [#8150](https://github.com/gfx-rs/wgpu/pull/8150). - Require new `F16_IN_F32` downlevel flag for `quantizeToF16`, `pack2x16float`, and `unpack2x16float` in WGSL input. By @aleiserson in [#8130](https://github.com/gfx-rs/wgpu/pull/8130). - The error message for non-copyable depth/stencil formats no longer mentions the aspect when it is not relevant. By @reima in [#8156](https://github.com/gfx-rs/wgpu/pull/8156). +- Track the initialization status of buffer memory correctly when `copy_texture_to_buffer` skips over padding space between rows or layers, or when the start/end of a texture-buffer transfer is not 4B aligned. By @andyleiserson in [#8099](https://github.com/gfx-rs/wgpu/pull/8099). #### naga diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 5643586f15f..468cf3caa44 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -13,12 +13,9 @@ webgpu:api,operation,compute,basic:memcpy:* //FAIL: webgpu:api,operation,compute,basic:large_dispatch:* webgpu:api,operation,compute_pipeline,overrides:* webgpu:api,operation,device,lost:* -// This is all the storeOp tests, but some of them fail if run in a single invocation. -// https://github.com/gfx-rs/wgpu/issues/8021 -webgpu:api,operation,render_pass,storeOp:render_pass_store_op,color_attachment_with_depth_stencil_attachment:* -webgpu:api,operation,render_pass,storeOp:render_pass_store_op,color_attachment_only:* -webgpu:api,operation,render_pass,storeOp:render_pass_store_op,multiple_color_attachments:* -webgpu:api,operation,render_pass,storeOp:render_pass_store_op,depth_stencil_attachment_only:* +webgpu:api,operation,render_pass,storeOp:* +// Presumably vertex pulling, revisit after https://github.com/gfx-rs/wgpu/issues/7981 is fixed. +fails-if(metal) webgpu:api,operation,vertex_state,correctness:setVertexBuffer_offset_and_attribute_offset:* fails-if(dx12) webgpu:api,validation,capability_checks,limits,maxBindGroups:setBindGroup,* webgpu:api,validation,createBindGroup:buffer,effective_buffer_binding_size:* webgpu:api,validation,encoding,beginComputePass:* @@ -74,14 +71,18 @@ webgpu:shader,validation,extension,dual_source_blending:blend_src_syntax_validat webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_usage_and_aspect:* webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_buffer_size:* // image_copy depth/stencil failures on dx12: https://github.com/gfx-rs/wgpu/issues/8133 +fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_buffer_offset:format="stencil8";aspect="stencil-only";copyType="CopyB2T" +fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_buffer_offset:format="stencil8";aspect="stencil-only";copyType="CopyT2B" fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_buffer_offset:format="depth32float";aspect="depth-only";copyType="CopyT2B" fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_buffer_offset:format="depth24plus-stencil8";aspect="stencil-only";copyType="CopyB2T" fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:depth_stencil_format,copy_buffer_offset:format="depth24plus-stencil8";aspect="stencil-only";copyType="CopyT2B" //mix of PASS and FAIL: other subtests of copy_buffer_offset. Related bugs: -// https://github.com/gfx-rs/wgpu/issues/7946, https://github.com/gfx-rs/wgpu/issues/7947 +// https://github.com/gfx-rs/wgpu/issues/7946 webgpu:api,validation,image_copy,buffer_texture_copies:sample_count:* webgpu:api,validation,image_copy,buffer_texture_copies:texture_buffer_usages:* webgpu:api,validation,image_copy,buffer_texture_copies:device_mismatch:* +fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="r8uint";copyType="CopyB2T";dimension="1d" +fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="r8uint";copyType="CopyT2B";dimension="1d" fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="rgba32float";copyType="CopyB2T";dimension="1d" fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="rgba32float";copyType="CopyT2B";dimension="1d" fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="rgba8unorm";copyType="CopyB2T";dimension="2d" @@ -95,7 +96,7 @@ fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="astc-4x4-unorm";copyType="CopyT2B";dimension="3d" fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and_bytesPerRow:format="astc-4x4-unorm";copyType="CopyB2T";dimension="3d" //mix of PASS and FAIL: other subtests of offset_and_bytesPerRow. Related bugs: -// https://github.com/gfx-rs/wgpu/issues/7946, https://github.com/gfx-rs/wgpu/issues/7947 +// https://github.com/gfx-rs/wgpu/issues/7946 webgpu:api,validation,image_copy,layout_related:copy_end_overflows_u64:* // Fails with OOM in CI. fails-if(dx12) webgpu:api,validation,image_copy,layout_related:offset_alignment:* diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 5caee246543..a9a125331db 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -21,7 +21,7 @@ use crate::{ TextureInitTrackerAction, }, resource::{ - MissingBufferUsageError, MissingTextureUsageError, ParentDevice, RawResourceAccess, + Buffer, MissingBufferUsageError, MissingTextureUsageError, ParentDevice, RawResourceAccess, Texture, TextureErrorDimension, }, snatch::SnatchGuard, @@ -33,7 +33,7 @@ pub type TexelCopyBufferInfo = wgt::TexelCopyBufferInfo; pub type TexelCopyTextureInfo = wgt::TexelCopyTextureInfo; pub type CopyExternalImageDestInfo = wgt::CopyExternalImageDestInfo; -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum CopySide { Source, Destination, @@ -276,9 +276,11 @@ pub(crate) fn extract_texture_selector( /// /// Copied with some modifications from WebGPU standard. /// -/// If successful, returns a pair `(bytes, stride)`, where: +/// If successful, returns a tuple `(bytes, stride, is_contiguous)`, where: /// - `bytes` is the number of buffer bytes required for this copy, and /// - `stride` number of bytes between array layers. +/// - `is_contiguous` is true if the linear texture data does not have padding +/// between rows or between images. /// /// [vltd]: https://gpuweb.github.io/gpuweb/#abstract-opdef-validating-linear-texture-data pub(crate) fn validate_linear_texture_data( @@ -288,7 +290,7 @@ pub(crate) fn validate_linear_texture_data( buffer_size: BufferAddress, buffer_side: CopySide, copy_size: &Extent3d, -) -> Result<(BufferAddress, BufferAddress), TransferError> { +) -> Result<(BufferAddress, BufferAddress, bool), TransferError> { let wgt::BufferTextureCopyInfo { copy_width, copy_height, @@ -303,14 +305,14 @@ pub(crate) fn validate_linear_texture_data( width_blocks: _, height_blocks, - row_bytes_dense: _, + row_bytes_dense, row_stride_bytes, image_stride_rows: _, image_stride_bytes, image_rows_dense: _, - image_bytes_dense: _, + image_bytes_dense, bytes_in_copy, } = layout.get_buffer_texture_copy_info(format, aspect, copy_size)?; @@ -347,7 +349,10 @@ pub(crate) fn validate_linear_texture_data( }); } - Ok((bytes_in_copy, image_stride_bytes)) + let is_contiguous = (row_stride_bytes == row_bytes_dense || !requires_multiple_rows) + && (image_stride_bytes == image_bytes_dense || !requires_multiple_images); + + Ok((bytes_in_copy, image_stride_bytes, is_contiguous)) } /// Validate the source format of a texture copy. @@ -733,6 +738,90 @@ fn handle_dst_texture_init( Ok(()) } +/// Handle initialization tracking for a transfer's source or destination buffer. +/// +/// Ensures that the transfer will not read from uninitialized memory, and updates +/// the initialization state information to reflect the transfer. +fn handle_buffer_init( + cmd_buf_data: &mut CommandBufferMutable, + info: &TexelCopyBufferInfo, + buffer: &Arc, + direction: CopySide, + required_buffer_bytes_in_copy: BufferAddress, + is_contiguous: bool, +) { + const ALIGN_SIZE: BufferAddress = wgt::COPY_BUFFER_ALIGNMENT; + const ALIGN_MASK: BufferAddress = wgt::COPY_BUFFER_ALIGNMENT - 1; + + let start = info.layout.offset; + let end = info.layout.offset + required_buffer_bytes_in_copy; + if !is_contiguous || direction == CopySide::Source { + // If the transfer will read the buffer, then the whole region needs to + // be initialized. + // + // If the transfer will not write a contiguous region of the buffer, + // then we need to make sure the padding areas are initialized. For now, + // initialize the whole region, although this could be improved to + // initialize only the necessary parts if doing so is likely to be + // faster than initializing the whole thing. + // + // Adjust the start/end outwards to 4B alignment. + let aligned_start = start & !ALIGN_MASK; + let aligned_end = (end + ALIGN_MASK) & !ALIGN_MASK; + cmd_buf_data.buffer_memory_init_actions.extend( + buffer.initialization_status.read().create_action( + buffer, + aligned_start..aligned_end, + MemoryInitKind::NeedsInitializedMemory, + ), + ); + } else { + // If the transfer will write a contiguous region of the buffer, then we + // don't need to initialize that region. + // + // However, if the start and end are not 4B aligned, we need to make + // sure that we don't end up trying to initialize non-4B-aligned regions + // later. + // + // Adjust the start/end inwards to 4B alignment, we will handle the + // first/last pieces differently. + let aligned_start = (start + ALIGN_MASK) & !ALIGN_MASK; + let aligned_end = end & !ALIGN_MASK; + if aligned_start != start { + cmd_buf_data.buffer_memory_init_actions.extend( + buffer.initialization_status.read().create_action( + buffer, + aligned_start - ALIGN_SIZE..aligned_start, + MemoryInitKind::NeedsInitializedMemory, + ), + ); + } + if aligned_start != aligned_end { + cmd_buf_data.buffer_memory_init_actions.extend( + buffer.initialization_status.read().create_action( + buffer, + aligned_start..aligned_end, + MemoryInitKind::ImplicitlyInitialized, + ), + ); + } + if aligned_end != end { + // It is possible that `aligned_end + ALIGN_SIZE > dst_buffer.size`, + // because `dst_buffer.size` is the user-requested size, not the + // final size of the buffer. The final size of the buffer is not + // readily available, but was rounded up to COPY_BUFFER_ALIGNMENT, + // so no overrun is possible. + cmd_buf_data.buffer_memory_init_actions.extend( + buffer.initialization_status.read().create_action( + buffer, + aligned_end..aligned_end + ALIGN_SIZE, + MemoryInitKind::NeedsInitializedMemory, + ), + ); + } + } +} + impl Global { pub fn command_encoder_copy_buffer_to_buffer( &self, @@ -1004,7 +1093,7 @@ impl Global { true, // alignment required for buffer offset )?; - let (required_buffer_bytes_in_copy, bytes_per_array_layer) = + let (required_buffer_bytes_in_copy, bytes_per_array_layer, is_contiguous) = validate_linear_texture_data( &source.layout, dst_texture.desc.format, @@ -1020,12 +1109,13 @@ impl Global { .map_err(TransferError::from)?; } - cmd_buf_data.buffer_memory_init_actions.extend( - src_buffer.initialization_status.read().create_action( - &src_buffer, - source.layout.offset..(source.layout.offset + required_buffer_bytes_in_copy), - MemoryInitKind::NeedsInitializedMemory, - ), + handle_buffer_init( + cmd_buf_data, + source, + &src_buffer, + CopySide::Source, + required_buffer_bytes_in_copy, + is_contiguous, ); let regions = (0..array_layer_count) @@ -1124,7 +1214,7 @@ impl Global { true, // alignment required for buffer offset )?; - let (required_buffer_bytes_in_copy, bytes_per_array_layer) = + let (required_buffer_bytes_in_copy, bytes_per_array_layer, is_contiguous) = validate_linear_texture_data( &destination.layout, src_texture.desc.format, @@ -1180,13 +1270,13 @@ impl Global { let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); - cmd_buf_data.buffer_memory_init_actions.extend( - dst_buffer.initialization_status.read().create_action( - &dst_buffer, - destination.layout.offset - ..(destination.layout.offset + required_buffer_bytes_in_copy), - MemoryInitKind::ImplicitlyInitialized, - ), + handle_buffer_init( + cmd_buf_data, + destination, + &dst_buffer, + CopySide::Destination, + required_buffer_bytes_in_copy, + is_contiguous, ); let regions = (0..array_layer_count) diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index f7a60fe733c..934e710e110 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -763,20 +763,21 @@ impl Queue { &destination, dst_base.aspect, &dst.desc, - &data_layout, + data_layout, false, // alignment not required for buffer offset or bytes per row )?; // Note: `_source_bytes_per_array_layer` is ignored since we // have a staging copy, and it can have a different value. - let (required_bytes_in_copy, _source_bytes_per_array_layer) = validate_linear_texture_data( - data_layout, - dst.desc.format, - destination.aspect, - data.len() as wgt::BufferAddress, - CopySide::Source, - size, - )?; + let (required_bytes_in_copy, _source_bytes_per_array_layer, _) = + validate_linear_texture_data( + data_layout, + dst.desc.format, + destination.aspect, + data.len() as wgt::BufferAddress, + CopySide::Source, + size, + )?; if dst.desc.format.is_depth_stencil_format() { self.device From 832609959d09030534adbba9c8868e76dfb31277 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Sun, 7 Sep 2025 03:34:06 -0400 Subject: [PATCH 189/303] Convert QueueWriteBufferView to be lifetime-less (#8161) --- CHANGELOG.md | 16 ++++++++++++++++ wgpu/src/api/queue.rs | 30 +++++++++++++++--------------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc716bd4b2f..890fdbb3c4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ We have merged the acceleration structure feature into the `RayQuery` feature. T By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). #### New `EXPERIMENTAL_PRECOMPILED_SHADERS` API + We have added `Features::EXPERIMENTAL_PRECOMPILED_SHADERS`, replacing existing passthrough types with a unified `CreateShaderModuleDescriptorPassthrough` which allows passing multiple shader codes for different backends. By @SupaMaggie70Incorporated in [#7834](https://github.com/gfx-rs/wgpu/pull/7834) Difference for SPIR-V passthrough: @@ -73,6 +74,21 @@ Difference for SPIR-V passthrough: ``` This allows using precompiled shaders without manually checking which backend's code to pass, for example if you have shaders precompiled for both DXIL and SPIR-V. +#### Buffer mapping apis no longer have lifetimes + +`Buffer::get_mapped_range()`, `Buffer::get_mapped_range_mut()`, and `Queue::write_buffer_with()` now return guard objects without any lifetimes. This +makes it significantly easier to store these types in structs, which is useful for building utilities that build the contents of a buffer over time. + +```diff +- let buffer_mapping_ref: wgpu::BufferView<'_> = buffer.get_mapped_range(..); +- let buffer_mapping_mut: wgpu::BufferViewMut<'_> = buffer.get_mapped_range_mut(..); +- let queue_write_with: wgpu::QueueWriteBufferView<'_> = queue.write_buffer_with(..); ++ let buffer_mapping_ref: wgpu::BufferView = buffer.get_mapped_range(..); ++ let buffer_mapping_mut: wgpu::BufferViewMut = buffer.get_mapped_range_mut(..); ++ let queue_write_with: wgpu::QueueWriteBufferView = queue.write_buffer_with(..); +``` + +By @sagudev in [#8046](https://github.com/gfx-rs/wgpu/pull/8046) and @cwfitzgerald in [#8070](https://github.com/gfx-rs/wgpu/pull/8161). #### `EXPERIMENTAL_*` features now require unsafe code to enable We want to be able to expose potentially experimental features to our users before we have ensured that they are fully sound to use. diff --git a/wgpu/src/api/queue.rs b/wgpu/src/api/queue.rs index d7c2749b056..a71c7e4ec64 100644 --- a/wgpu/src/api/queue.rs +++ b/wgpu/src/api/queue.rs @@ -58,16 +58,16 @@ static_assertions::assert_impl_all!(PollType: Send, Sync); /// Reading into this buffer won't yield the contents of the buffer from the /// GPU and is likely to be slow. Because of this, although [`AsMut`] is /// implemented for this type, [`AsRef`] is not. -pub struct QueueWriteBufferView<'a> { - queue: &'a Queue, - buffer: &'a Buffer, +pub struct QueueWriteBufferView { + queue: Queue, + buffer: Buffer, offset: BufferAddress, inner: dispatch::DispatchQueueWriteBuffer, } #[cfg(send_sync)] -static_assertions::assert_impl_all!(QueueWriteBufferView<'_>: Send, Sync); +static_assertions::assert_impl_all!(QueueWriteBufferView: Send, Sync); -impl QueueWriteBufferView<'_> { +impl QueueWriteBufferView { #[cfg(custom)] /// Returns custom implementation of QueueWriteBufferView (if custom backend and is internally T) pub fn as_custom(&self) -> Option<&T> { @@ -75,7 +75,7 @@ impl QueueWriteBufferView<'_> { } } -impl Deref for QueueWriteBufferView<'_> { +impl Deref for QueueWriteBufferView { type Target = [u8]; fn deref(&self) -> &Self::Target { @@ -84,19 +84,19 @@ impl Deref for QueueWriteBufferView<'_> { } } -impl DerefMut for QueueWriteBufferView<'_> { +impl DerefMut for QueueWriteBufferView { fn deref_mut(&mut self) -> &mut Self::Target { self.inner.slice_mut() } } -impl AsMut<[u8]> for QueueWriteBufferView<'_> { +impl AsMut<[u8]> for QueueWriteBufferView { fn as_mut(&mut self) -> &mut [u8] { self.inner.slice_mut() } } -impl Drop for QueueWriteBufferView<'_> { +impl Drop for QueueWriteBufferView { fn drop(&mut self) { self.queue .inner @@ -182,19 +182,19 @@ impl Queue { /// allocations, you might be able to use [`StagingBelt`](crate::util::StagingBelt), /// or buffers you explicitly create, map, and unmap yourself. #[must_use] - pub fn write_buffer_with<'a>( - &'a self, - buffer: &'a Buffer, + pub fn write_buffer_with( + &self, + buffer: &Buffer, offset: BufferAddress, size: BufferSize, - ) -> Option> { + ) -> Option { profiling::scope!("Queue::write_buffer_with"); self.inner .validate_write_buffer(&buffer.inner, offset, size)?; let staging_buffer = self.inner.create_staging_buffer(size)?; Some(QueueWriteBufferView { - queue: self, - buffer, + queue: self.clone(), + buffer: buffer.clone(), offset, inner: staging_buffer, }) From fb28da16c1520964e7b1bec5fdfa30c29afa7ef7 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 21 Aug 2025 00:42:58 -0400 Subject: [PATCH 190/303] [wgpu] add convience functions for deferring mapping/callbacks Co-authored-by: Kevin Reid --- CHANGELOG.md | 22 ++ .../api/command_buffer_actions.rs | 261 ++++++++++++++++++ tests/tests/wgpu-validation/api/mod.rs | 1 + wgpu/src/api/buffer.rs | 78 ++++-- wgpu/src/api/command_buffer.rs | 11 +- wgpu/src/api/command_buffer_actions.rs | 147 ++++++++++ wgpu/src/api/command_encoder.rs | 19 +- wgpu/src/api/compute_pass.rs | 11 +- wgpu/src/api/device.rs | 7 +- wgpu/src/api/mod.rs | 3 + wgpu/src/api/queue.rs | 40 ++- wgpu/src/api/render_pass.rs | 9 +- wgpu/src/dispatch.rs | 1 + 13 files changed, 565 insertions(+), 45 deletions(-) create mode 100644 tests/tests/wgpu-validation/api/command_buffer_actions.rs create mode 100644 wgpu/src/api/command_buffer_actions.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 890fdbb3c4c..1bcccc723ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,28 @@ Bottom level categories: ### Major Changes +#### Deferred command buffer actions: `map_buffer_on_submit` and `on_submitted_work_done` + +You may schedule buffer mapping and a submission-complete callback to run automatically after you submit, directly from encoders, command buffers, and passes. + +```rust +// Record some GPU work so the submission isn't empty and touches `buffer`. +encoder.clear_buffer(&buffer, 0, None); + +// Defer mapping until this encoder is submitted. +encoder.map_buffer_on_submit(&buffer, wgpu::MapMode::Read, 0..size, |result| { .. }); + +// Fires after the command buffer's work is finished. +encoder.on_submitted_work_done(|| { .. }); + +// Automatically calls `map_async` and `on_submitted_work_done` after this submission finishes. +queue.submit([encoder.finish()]); +``` + +Available on `CommandEncoder`, `CommandBuffer`, `RenderPass`, and `ComputePass`. + +By @cwfitzgerald in [#8125](https://github.com/gfx-rs/wgpu/pull/8125). + #### `EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE` has been merged into `EXPERIMENTAL_RAY_QUERY` We have merged the acceleration structure feature into the `RayQuery` feature. This is to help work around an AMD driver bug and reduce the feature complexity of ray tracing. In the future when ray tracing pipelines are implemented, if either feature is enabled, acceleration structures will be available. diff --git a/tests/tests/wgpu-validation/api/command_buffer_actions.rs b/tests/tests/wgpu-validation/api/command_buffer_actions.rs new file mode 100644 index 00000000000..fd427fae47e --- /dev/null +++ b/tests/tests/wgpu-validation/api/command_buffer_actions.rs @@ -0,0 +1,261 @@ +use std::sync::atomic::{AtomicBool, AtomicU32, Ordering::SeqCst}; +use std::sync::Arc; + +/// Helper to create a small mappable buffer for READ tests. +fn make_read_buffer(device: &wgpu::Device, size: u64) -> wgpu::Buffer { + device.create_buffer(&wgpu::BufferDescriptor { + label: Some("read buffer"), + size, + usage: wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false, + }) +} + +/// map_buffer_on_submit defers mapping until submit, then invokes the callback after polling. +#[test] +fn encoder_map_buffer_on_submit_defers_until_submit() { + let (device, queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + let buffer = make_read_buffer(&device, 16); + + let fired = Arc::new(AtomicBool::new(false)); + let fired_cl = Arc::clone(&fired); + + let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { + label: Some("encoder"), + }); + + // Register deferred map. + encoder.map_buffer_on_submit(&buffer, wgpu::MapMode::Read, 0..4, move |_| { + fired_cl.store(true, SeqCst); + }); + // Include a trivial command that uses the buffer. + encoder.clear_buffer(&buffer, 0, None); + + // Polling before submit should not trigger the callback. + _ = device.poll(wgpu::PollType::Poll); + assert!(!fired.load(SeqCst)); + + // Submit and wait; callback should fire. + queue.submit([encoder.finish()]); + _ = device.poll(wgpu::PollType::Wait); + assert!(fired.load(SeqCst)); +} + +/// Empty ranges panic immediately when registering the deferred map. +#[test] +#[should_panic = "buffer slices can not be empty"] +fn encoder_map_buffer_on_submit_empty_range_panics_immediately() { + let (device, _queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + let buffer = make_read_buffer(&device, 16); + + let encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + + // This panics inside map_buffer_on_submit (range_to_offset_size). + encoder.map_buffer_on_submit(&buffer, wgpu::MapMode::Read, 8..8, |_| {}); +} + +/// Out-of-bounds ranges panic during submit (when the deferred map executes). +#[test] +#[should_panic = "is out of range for buffer of size"] +fn encoder_map_buffer_on_submit_out_of_bounds_panics_on_submit() { + let (device, queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + let buffer = make_read_buffer(&device, 16); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + // 12..24 overflows the 16-byte buffer (size=12, end=24). + encoder.map_buffer_on_submit(&buffer, wgpu::MapMode::Read, 12..24, |_| {}); + encoder.clear_buffer(&buffer, 0, None); + + // Panic happens inside submit when executing deferred actions. + queue.submit([encoder.finish()]); +} + +/// If the buffer is already mapped when the deferred mapping executes, it panics during submit. +#[test] +#[should_panic = "Buffer with 'read buffer' label is still mapped"] +fn encoder_map_buffer_on_submit_panics_if_already_mapped_on_submit() { + let (device, queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + let buffer = make_read_buffer(&device, 16); + + // Start a mapping now so the buffer is considered mapped. + buffer.slice(0..4).map_async(wgpu::MapMode::Read, |_| {}); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + // Deferred mapping of an already-mapped buffer will panic when executed on submit or be rejected by submit. + encoder.map_buffer_on_submit(&buffer, wgpu::MapMode::Read, 0..4, |_| {}); + // Include any trivial work; using the same buffer ensures core validation catches the mapped hazard. + encoder.clear_buffer(&buffer, 0, None); + + queue.submit([encoder.finish()]); +} + +/// on_submitted_work_done is deferred until submit. +#[test] +fn encoder_on_submitted_work_done_defers_until_submit() { + let (device, queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + + let fired = Arc::new(AtomicBool::new(false)); + let fired_cl = Arc::clone(&fired); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + + encoder.on_submitted_work_done(move || { + fired_cl.store(true, SeqCst); + }); + + // Include a trivial command so the command buffer isn't completely empty. + let dummy = make_read_buffer(&device, 4); + encoder.clear_buffer(&dummy, 0, None); + + // Without submission, polling shouldn't invoke the callback. + _ = device.poll(wgpu::PollType::Poll); + assert!(!fired.load(SeqCst)); + + queue.submit([encoder.finish()]); + _ = device.poll(wgpu::PollType::Wait); + assert!(fired.load(SeqCst)); +} + +/// Both kinds of deferred callbacks are enqueued and eventually invoked. +#[test] +fn encoder_both_callbacks_fire_after_submit() { + let (device, queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + let buffer = make_read_buffer(&device, 16); + + let map_fired = Arc::new(AtomicBool::new(false)); + let map_fired_cl = Arc::clone(&map_fired); + let queue_fired = Arc::new(AtomicBool::new(false)); + let queue_fired_cl = Arc::clone(&queue_fired); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + encoder.map_buffer_on_submit(&buffer, wgpu::MapMode::Read, 0..4, move |_| { + map_fired_cl.store(true, SeqCst); + }); + encoder.on_submitted_work_done(move || { + queue_fired_cl.store(true, SeqCst); + }); + encoder.clear_buffer(&buffer, 0, None); + + queue.submit([encoder.finish()]); + _ = device.poll(wgpu::PollType::Wait); + + assert!(map_fired.load(SeqCst)); + assert!(queue_fired.load(SeqCst)); +} + +/// Registering multiple deferred mappings works; all callbacks fire after submit. +#[test] +fn encoder_multiple_map_buffer_on_submit_callbacks_fire() { + let (device, queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + let buffer1 = make_read_buffer(&device, 32); + let buffer2 = make_read_buffer(&device, 32); + + let counter = Arc::new(AtomicU32::new(0)); + let c1 = Arc::clone(&counter); + let c2 = Arc::clone(&counter); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + encoder.map_buffer_on_submit(&buffer1, wgpu::MapMode::Read, 0..4, move |_| { + c1.fetch_add(1, SeqCst); + }); + encoder.map_buffer_on_submit(&buffer2, wgpu::MapMode::Read, 8..12, move |_| { + c2.fetch_add(1, SeqCst); + }); + encoder.clear_buffer(&buffer1, 0, None); + + queue.submit([encoder.finish()]); + _ = device.poll(wgpu::PollType::Wait); + + assert_eq!(counter.load(SeqCst), 2); +} + +/// Mapping with a buffer lacking MAP_* usage should panic when executed on submit. +#[test] +#[should_panic] +fn encoder_map_buffer_on_submit_panics_if_usage_invalid_on_submit() { + let (device, queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + let unmappable = device.create_buffer(&wgpu::BufferDescriptor { + label: Some("unmappable buffer"), + size: 16, + usage: wgpu::BufferUsages::COPY_DST, // No MAP_READ or MAP_WRITE + mapped_at_creation: false, + }); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + encoder.map_buffer_on_submit(&unmappable, wgpu::MapMode::Read, 0..4, |_| {}); + + // Add unrelated work so the submission isn't empty. + let dummy = make_read_buffer(&device, 4); + encoder.clear_buffer(&dummy, 0, None); + + // Panic expected when deferred mapping executes. + queue.submit([encoder.finish()]); +} + +/// Deferred map callbacks run before on_submitted_work_done for the same submission. +#[test] +fn encoder_deferred_map_runs_before_on_submitted_work_done() { + let (device, queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + let buffer = make_read_buffer(&device, 16); + + #[derive(Default)] + struct Order { + map_order: AtomicU32, + queue_order: AtomicU32, + counter: AtomicU32, + } + let order = Arc::new(Order::default()); + let o_map = Arc::clone(&order); + let o_queue = Arc::clone(&order); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + encoder.map_buffer_on_submit(&buffer, wgpu::MapMode::Read, 0..4, move |_| { + let v = o_map.counter.fetch_add(1, SeqCst); + o_map.map_order.store(v, SeqCst); + }); + encoder.on_submitted_work_done(move || { + let v = o_queue.counter.fetch_add(1, SeqCst); + o_queue.queue_order.store(v, SeqCst); + }); + encoder.clear_buffer(&buffer, 0, None); + + queue.submit([encoder.finish()]); + _ = device.poll(wgpu::PollType::Wait); + + assert_eq!(order.counter.load(SeqCst), 2); + assert_eq!(order.map_order.load(SeqCst), 0); + assert_eq!(order.queue_order.load(SeqCst), 1); +} + +/// Multiple on_submitted_work_done callbacks registered on encoder all fire after submit. +#[test] +fn encoder_multiple_on_submitted_callbacks_fire() { + let (device, queue) = wgpu::Device::noop(&wgpu::DeviceDescriptor::default()); + let buffer = make_read_buffer(&device, 4); + + let counter = Arc::new(AtomicU32::new(0)); + let c1 = Arc::clone(&counter); + let c2 = Arc::clone(&counter); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + encoder.on_submitted_work_done(move || { + c1.fetch_add(1, SeqCst); + }); + encoder.on_submitted_work_done(move || { + c2.fetch_add(1, SeqCst); + }); + encoder.clear_buffer(&buffer, 0, None); + + queue.submit([encoder.finish()]); + _ = device.poll(wgpu::PollType::Wait); + + assert_eq!(counter.load(SeqCst), 2); +} diff --git a/tests/tests/wgpu-validation/api/mod.rs b/tests/tests/wgpu-validation/api/mod.rs index 9d591fa6b94..a9c6abf1d16 100644 --- a/tests/tests/wgpu-validation/api/mod.rs +++ b/tests/tests/wgpu-validation/api/mod.rs @@ -2,6 +2,7 @@ mod binding_arrays; mod buffer; mod buffer_mapping; mod buffer_slice; +mod command_buffer_actions; mod device; mod experimental; mod external_texture; diff --git a/wgpu/src/api/buffer.rs b/wgpu/src/api/buffer.rs index 537b95b8196..f38c70427d7 100644 --- a/wgpu/src/api/buffer.rs +++ b/wgpu/src/api/buffer.rs @@ -347,20 +347,28 @@ impl Buffer { self.usage } - /// Map the buffer to host (CPU) memory, making it available for reading or writing - /// via [`get_mapped_range()`](Self::get_mapped_range). - /// It is available once the `callback` is called with an [`Ok`] response. + /// Map the buffer to host (CPU) memory, making it available for reading or writing via + /// [`get_mapped_range()`](Self::get_mapped_range). The buffer becomes accessible once the + /// `callback` is invoked with [`Ok`]. /// - /// For the callback to complete, either `queue.submit(..)`, `instance.poll_all(..)`, or `device.poll(..)` - /// must be called elsewhere in the runtime, possibly integrated into an event loop or run on a separate thread. + /// Use this when you want to map the buffer immediately. If you need to submit GPU work that + /// uses the buffer before mapping it, use `map_buffer_on_submit` on + /// [`CommandEncoder`][CEmbos], [`CommandBuffer`][CBmbos], [`RenderPass`][RPmbos], or + /// [`ComputePass`][CPmbos] to schedule the mapping after submission. This avoids extra calls to + /// [`Buffer::map_async()`] or [`BufferSlice::map_async()`] and lets you initiate mapping from a + /// more convenient place. /// - /// The callback will be called on the thread that first calls the above functions after the GPU work - /// has completed. There are no restrictions on the code you can run in the callback, however on native the - /// call to the function will not complete until the callback returns, so prefer keeping callbacks short - /// and used to set flags, send messages, etc. + /// For the callback to run, either [`queue.submit(..)`][q::s], [`instance.poll_all(..)`][i::p_a], + /// or [`device.poll(..)`][d::p] must be called elsewhere in the runtime, possibly integrated into + /// an event loop or run on a separate thread. /// - /// As long as a buffer is mapped, it is not available for use by any other commands; - /// at all times, either the GPU or the CPU has exclusive access to the contents of the buffer. + /// The callback runs on the thread that first calls one of the above functions after the GPU work + /// completes. There are no restrictions on the code you can run in the callback; however, on native + /// the polling call will not return until the callback finishes, so keep callbacks short (set flags, + /// send messages, etc.). + /// + /// While a buffer is mapped, it cannot be used by other commands; at any time, either the GPU or + /// the CPU has exclusive access to the buffer’s contents. /// /// This can also be performed using [`BufferSlice::map_async()`]. /// @@ -371,6 +379,14 @@ impl Buffer { /// - If `bounds` is outside of the bounds of `self`. /// - If `bounds` has a length less than 1. /// - If the start and end of `bounds` are not be aligned to [`MAP_ALIGNMENT`]. + /// + /// [CEmbos]: CommandEncoder::map_buffer_on_submit + /// [CBmbos]: CommandBuffer::map_buffer_on_submit + /// [RPmbos]: RenderPass::map_buffer_on_submit + /// [CPmbos]: ComputePass::map_buffer_on_submit + /// [q::s]: Queue::submit + /// [i::p_a]: Instance::poll_all + /// [d::p]: Device::poll pub fn map_async>( &self, mode: MapMode, @@ -508,20 +524,28 @@ impl<'a> BufferSlice<'a> { } } - /// Map the buffer to host (CPU) memory, making it available for reading or writing - /// via [`get_mapped_range()`](Self::get_mapped_range). - /// It is available once the `callback` is called with an [`Ok`] response. + /// Map the buffer to host (CPU) memory, making it available for reading or writing via + /// [`get_mapped_range()`](Self::get_mapped_range). The buffer becomes accessible once the + /// `callback` is invoked with [`Ok`]. /// - /// For the callback to complete, either `queue.submit(..)`, `instance.poll_all(..)`, or `device.poll(..)` - /// must be called elsewhere in the runtime, possibly integrated into an event loop or run on a separate thread. + /// Use this when you want to map the buffer immediately. If you need to submit GPU work that + /// uses the buffer before mapping it, use `map_buffer_on_submit` on + /// [`CommandEncoder`][CEmbos], [`CommandBuffer`][CBmbos], [`RenderPass`][RPmbos], or + /// [`ComputePass`][CPmbos] to schedule the mapping after submission. This avoids extra calls to + /// [`Buffer::map_async()`] or [`BufferSlice::map_async()`] and lets you initiate mapping from a + /// more convenient place. /// - /// The callback will be called on the thread that first calls the above functions after the GPU work - /// has completed. There are no restrictions on the code you can run in the callback, however on native the - /// call to the function will not complete until the callback returns, so prefer keeping callbacks short - /// and used to set flags, send messages, etc. + /// For the callback to run, either [`queue.submit(..)`][q::s], [`instance.poll_all(..)`][i::p_a], + /// or [`device.poll(..)`][d::p] must be called elsewhere in the runtime, possibly integrated into + /// an event loop or run on a separate thread. /// - /// As long as a buffer is mapped, it is not available for use by any other commands; - /// at all times, either the GPU or the CPU has exclusive access to the contents of the buffer. + /// The callback runs on the thread that first calls one of the above functions after the GPU work + /// completes. There are no restrictions on the code you can run in the callback; however, on native + /// the polling call will not return until the callback finishes, so keep callbacks short (set flags, + /// send messages, etc.). + /// + /// While a buffer is mapped, it cannot be used by other commands; at any time, either the GPU or + /// the CPU has exclusive access to the buffer’s contents. /// /// This can also be performed using [`Buffer::map_async()`]. /// @@ -530,6 +554,14 @@ impl<'a> BufferSlice<'a> { /// - If the buffer is already mapped. /// - If the buffer’s [`BufferUsages`] do not allow the requested [`MapMode`]. /// - If the endpoints of this slice are not aligned to [`MAP_ALIGNMENT`] within the buffer. + /// + /// [CEmbos]: CommandEncoder::map_buffer_on_submit + /// [CBmbos]: CommandBuffer::map_buffer_on_submit + /// [RPmbos]: RenderPass::map_buffer_on_submit + /// [CPmbos]: ComputePass::map_buffer_on_submit + /// [q::s]: Queue::submit + /// [i::p_a]: Instance::poll_all + /// [d::p]: Device::poll pub fn map_async( &self, mode: MapMode, @@ -977,7 +1009,7 @@ fn check_buffer_bounds( } #[track_caller] -fn range_to_offset_size>( +pub(crate) fn range_to_offset_size>( bounds: S, whole_size: BufferAddress, ) -> (BufferAddress, BufferSize) { diff --git a/wgpu/src/api/command_buffer.rs b/wgpu/src/api/command_buffer.rs index eb1358946aa..7685e240380 100644 --- a/wgpu/src/api/command_buffer.rs +++ b/wgpu/src/api/command_buffer.rs @@ -1,4 +1,7 @@ -use crate::*; +use crate::{ + api::{impl_deferred_command_buffer_actions, SharedDeferredCommandBufferActions}, + *, +}; /// Handle to a command buffer on the GPU. /// @@ -10,6 +13,8 @@ use crate::*; #[derive(Debug)] pub struct CommandBuffer { pub(crate) buffer: dispatch::DispatchCommandBuffer, + /// Deferred actions recorded at encode time, to run at Queue::submit. + pub(crate) actions: SharedDeferredCommandBufferActions, } #[cfg(send_sync)] static_assertions::assert_impl_all!(CommandBuffer: Send, Sync); @@ -20,4 +25,8 @@ impl CommandBuffer { pub fn as_custom(&self) -> Option<&T> { self.buffer.as_custom() } + + // Expose map_buffer_on_submit/on_submitted_work_done on CommandBuffer as well, + // so callers can schedule after finishing encoding. + impl_deferred_command_buffer_actions!(); } diff --git a/wgpu/src/api/command_buffer_actions.rs b/wgpu/src/api/command_buffer_actions.rs new file mode 100644 index 00000000000..16b2bc6fdf4 --- /dev/null +++ b/wgpu/src/api/command_buffer_actions.rs @@ -0,0 +1,147 @@ +use alloc::{sync::Arc, vec::Vec}; +use core::num::NonZeroU64; + +use crate::{util::Mutex, *}; + +/// A deferred buffer mapping request captured during encoding (or a pass) +/// and executed later when the command buffer is submitted. +pub(crate) struct DeferredBufferMapping { + pub buffer: api::Buffer, + pub mode: MapMode, + pub offset: u64, + pub size: NonZeroU64, + pub callback: dispatch::BufferMapCallback, +} + +pub(super) type SharedDeferredCommandBufferActions = Arc>; + +/// Set of actions to take when the command buffer is submitted. +#[derive(Default)] +pub(crate) struct DeferredCommandBufferActions { + pub buffer_mappings: Vec, + pub on_submitted_work_done_callbacks: Vec, +} + +impl DeferredCommandBufferActions { + pub fn append(&mut self, other: &mut Self) { + self.buffer_mappings.append(&mut other.buffer_mappings); + self.on_submitted_work_done_callbacks + .append(&mut other.on_submitted_work_done_callbacks); + } + + pub fn execute(self, queue: &dispatch::DispatchQueue) { + for mapping in self.buffer_mappings { + mapping.buffer.map_async( + mapping.mode, + mapping.offset..mapping.offset + mapping.size.get(), + mapping.callback, + ); + } + for callback in self.on_submitted_work_done_callbacks { + queue.on_submitted_work_done(callback); + } + } +} + +impl core::fmt::Debug for DeferredCommandBufferActions { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("DeferredCommandBufferActions") + .field("buffer_mappings.len()", &self.buffer_mappings.len()) + .field( + "on_submitted_work_done_callbacks.len()", + &self.on_submitted_work_done_callbacks.len(), + ) + .finish() + } +} + +// We can't just implement this on CommandEncoders as by default passes make it so that +// you can't call any commands on the encoder while this is happening. As such, we need +// to implement these methods on the passes too. Use a macro to avoid massive code duplication +macro_rules! impl_deferred_command_buffer_actions { + () => { + /// On submission, maps the buffer to host (CPU) memory, making it available + /// for reading or writing via [`get_mapped_range()`](Buffer::get_mapped_range). + /// The buffer becomes accessible once the `callback` is invoked with [`Ok`]. + /// + /// Use this when you need to submit work that uses the buffer before mapping it. + /// Because that submission must happen before calling `map_async`, this method + /// schedules the mapping for after submission, avoiding extra calls to + /// [`Buffer::map_async()`] or [`BufferSlice::map_async()`] and letting you start + /// the mapping from a more convenient place. + /// + /// For the callback to run, either [`queue.submit(..)`][q::s], [`instance.poll_all(..)`][i::p_a], + /// or [`device.poll(..)`][d::p] must be called elsewhere in the runtime, possibly integrated + /// into an event loop or run on a separate thread. + /// + /// The callback runs on the thread that first calls one of the above functions + /// after the GPU work completes. There are no restrictions on the code you can run + /// in the callback; however, on native the polling call will not return until the + /// callback finishes, so keep callbacks short (set flags, send messages, etc.). + /// + /// While a buffer is mapped, it cannot be used by other commands; at any time, + /// either the GPU or the CPU has exclusive access to the buffer’s contents. + /// + /// # Panics + /// + /// - If `bounds` is outside the bounds of `buffer`. + /// - If `bounds` has a length less than 1. + /// + /// # Panics During Submit + /// + /// - If the buffer is already mapped. + /// - If the buffer’s [`BufferUsages`] do not allow the requested [`MapMode`]. + /// - If the endpoints of this slice are not aligned to [`MAP_ALIGNMENT`] within the buffer. + /// + /// [q::s]: Queue::submit + /// [i::p_a]: Instance::poll_all + /// [d::p]: Device::poll + /// [CEmbos]: CommandEncoder::map_buffer_on_submit + /// [CBmbos]: CommandBuffer::map_buffer_on_submit + /// [RPmbos]: RenderPass::map_buffer_on_submit + /// [CPmbos]: ComputePass::map_buffer_on_submit + pub fn map_buffer_on_submit>( + &self, + buffer: &api::Buffer, + mode: MapMode, + bounds: S, + callback: impl FnOnce(Result<(), BufferAsyncError>) + WasmNotSend + 'static, + ) { + let (offset, size) = range_to_offset_size(bounds, buffer.size); + self.actions.lock().buffer_mappings.push( + crate::api::command_buffer_actions::DeferredBufferMapping { + buffer: buffer.clone(), + mode, + offset, + size, + callback: alloc::boxed::Box::new(callback), + }, + ); + } + + /// Registers a callback that is invoked when this command buffer’s work finishes + /// executing on the GPU. When this callback runs, all mapped-buffer callbacks + /// registered for the same submission are guaranteed to have been called. + /// + /// For the callback to run, either [`queue.submit(..)`][q::s], [`instance.poll_all(..)`][i::p_a], + /// or [`device.poll(..)`][d::p] must be called elsewhere in the runtime, possibly integrated + /// into an event loop or run on a separate thread. + /// + /// The callback runs on the thread that first calls one of the above functions + /// after the GPU work completes. There are no restrictions on the code you can run + /// in the callback; however, on native the polling call will not return until the + /// callback finishes, so keep callbacks short (set flags, send messages, etc.). + /// + /// [q::s]: Queue::submit + /// [i::p_a]: Instance::poll_all + /// [d::p]: Device::poll + pub fn on_submitted_work_done(&self, callback: impl FnOnce() + Send + 'static) { + self.actions + .lock() + .on_submitted_work_done_callbacks + .push(alloc::boxed::Box::new(callback)); + } + }; +} + +pub(crate) use impl_deferred_command_buffer_actions; diff --git a/wgpu/src/api/command_encoder.rs b/wgpu/src/api/command_encoder.rs index 77cb4d1a29e..30afbb90905 100644 --- a/wgpu/src/api/command_encoder.rs +++ b/wgpu/src/api/command_encoder.rs @@ -1,7 +1,11 @@ +use alloc::sync::Arc; use core::ops::Range; use crate::{ - api::{blas::BlasBuildEntry, tlas::Tlas}, + api::{ + blas::BlasBuildEntry, impl_deferred_command_buffer_actions, tlas::Tlas, + SharedDeferredCommandBufferActions, + }, *, }; @@ -17,6 +21,7 @@ use crate::{ #[derive(Debug)] pub struct CommandEncoder { pub(crate) inner: dispatch::DispatchCommandEncoder, + pub(crate) actions: SharedDeferredCommandBufferActions, } #[cfg(send_sync)] static_assertions::assert_impl_all!(CommandEncoder: Send, Sync); @@ -52,10 +57,10 @@ static_assertions::assert_impl_all!(TexelCopyTextureInfo<'_>: Send, Sync); impl CommandEncoder { /// Finishes recording and returns a [`CommandBuffer`] that can be submitted for execution. - pub fn finish(mut self) -> CommandBuffer { - let buffer = self.inner.finish(); - - CommandBuffer { buffer } + pub fn finish(self) -> CommandBuffer { + let Self { mut inner, actions } = self; + let buffer = inner.finish(); + CommandBuffer { buffer, actions } } /// Begins recording of a render pass. @@ -75,6 +80,7 @@ impl CommandEncoder { let rpass = self.inner.begin_render_pass(desc); RenderPass { inner: rpass, + actions: Arc::clone(&self.actions), _encoder_guard: api::PhantomDrop::default(), } } @@ -96,6 +102,7 @@ impl CommandEncoder { let cpass = self.inner.begin_compute_pass(desc); ComputePass { inner: cpass, + actions: Arc::clone(&self.actions), _encoder_guard: api::PhantomDrop::default(), } } @@ -232,6 +239,8 @@ impl CommandEncoder { ); } + impl_deferred_command_buffer_actions!(); + /// Get the [`wgpu_hal`] command encoder from this `CommandEncoder`. /// /// The returned command encoder will be ready to record onto. diff --git a/wgpu/src/api/compute_pass.rs b/wgpu/src/api/compute_pass.rs index 18d2f30eeb6..9c62ca3128b 100644 --- a/wgpu/src/api/compute_pass.rs +++ b/wgpu/src/api/compute_pass.rs @@ -1,4 +1,7 @@ -use crate::*; +use crate::{ + api::{impl_deferred_command_buffer_actions, SharedDeferredCommandBufferActions}, + *, +}; /// In-progress recording of a compute pass. /// @@ -10,6 +13,9 @@ use crate::*; pub struct ComputePass<'encoder> { pub(crate) inner: dispatch::DispatchComputePass, + /// Shared with CommandEncoder to enqueue deferred actions from within a pass. + pub(crate) actions: SharedDeferredCommandBufferActions, + /// This lifetime is used to protect the [`CommandEncoder`] from being used /// while the pass is alive. This needs to be PhantomDrop to prevent the lifetime /// from being shortened. @@ -37,6 +43,7 @@ impl ComputePass<'_> { pub fn forget_lifetime(self) -> ComputePass<'static> { ComputePass { inner: self.inner, + actions: self.actions, _encoder_guard: crate::api::PhantomDrop::default(), } } @@ -95,6 +102,8 @@ impl ComputePass<'_> { .dispatch_workgroups_indirect(&indirect_buffer.inner, indirect_offset); } + impl_deferred_command_buffer_actions!(); + #[cfg(custom)] /// Returns custom implementation of ComputePass (if custom backend and is internally T) pub fn as_custom(&self) -> Option<&T> { diff --git a/wgpu/src/api/device.rs b/wgpu/src/api/device.rs index c3929587038..482a439f1b1 100644 --- a/wgpu/src/api/device.rs +++ b/wgpu/src/api/device.rs @@ -198,7 +198,12 @@ impl Device { #[must_use] pub fn create_command_encoder(&self, desc: &CommandEncoderDescriptor<'_>) -> CommandEncoder { let encoder = self.inner.create_command_encoder(desc); - CommandEncoder { inner: encoder } + // Each encoder starts with its own deferred-action store that travels + // with the CommandBuffer produced by finish(). + CommandEncoder { + inner: encoder, + actions: Default::default(), + } } /// Creates an empty [`RenderBundleEncoder`]. diff --git a/wgpu/src/api/mod.rs b/wgpu/src/api/mod.rs index 8178d2be576..b564aa75f16 100644 --- a/wgpu/src/api/mod.rs +++ b/wgpu/src/api/mod.rs @@ -26,6 +26,8 @@ mod bind_group_layout; mod blas; mod buffer; mod command_buffer; +/// Not a root type, but common types for command buffer deferral actions. +mod command_buffer_actions; mod command_encoder; // Not a root type, but common descriptor types for pipelines. mod common_pipeline; @@ -56,6 +58,7 @@ pub use bind_group_layout::*; pub use blas::*; pub use buffer::*; pub use command_buffer::*; +use command_buffer_actions::*; pub use command_encoder::*; pub use common_pipeline::*; pub use compute_pass::*; diff --git a/wgpu/src/api/queue.rs b/wgpu/src/api/queue.rs index a71c7e4ec64..a61d0b023fb 100644 --- a/wgpu/src/api/queue.rs +++ b/wgpu/src/api/queue.rs @@ -1,7 +1,7 @@ use alloc::boxed::Box; use core::ops::{Deref, DerefMut}; -use crate::*; +use crate::{api::DeferredCommandBufferActions, *}; /// Handle to a command queue on a device. /// @@ -248,10 +248,19 @@ impl Queue { &self, command_buffers: I, ) -> SubmissionIndex { - let mut command_buffers = command_buffers.into_iter().map(|comb| comb.buffer); + // As submit drains the iterator (even on error), collect deferred actions + // from each CommandBuffer along the way. + let mut actions = DeferredCommandBufferActions::default(); + let mut command_buffers = command_buffers.into_iter().map(|comb| { + actions.append(&mut comb.actions.lock()); + comb.buffer + }); let index = self.inner.submit(&mut command_buffers); + // Execute all deferred actions after submit. + actions.execute(&self.inner); + SubmissionIndex { index } } @@ -265,17 +274,22 @@ impl Queue { self.inner.get_timestamp_period() } - /// Registers a callback when the previous call to submit finishes running on the gpu. This callback - /// being called implies that all mapped buffer callbacks which were registered before this call will - /// have been called. - /// - /// For the callback to complete, either `queue.submit(..)`, `instance.poll_all(..)`, or `device.poll(..)` - /// must be called elsewhere in the runtime, possibly integrated into an event loop or run on a separate thread. - /// - /// The callback will be called on the thread that first calls the above functions after the gpu work - /// has completed. There are no restrictions on the code you can run in the callback, however on native the - /// call to the function will not complete until the callback returns, so prefer keeping callbacks short - /// and used to set flags, send messages, etc. + /// Registers a callback that is invoked when the previous [`Queue::submit`] finishes executing + /// on the GPU. When this callback runs, all mapped-buffer callbacks registered for the same + /// submission are guaranteed to have been called. + /// + /// For the callback to run, either [`queue.submit(..)`][q::s], [`instance.poll_all(..)`][i::p_a], + /// or [`device.poll(..)`][d::p] must be called elsewhere in the runtime, possibly integrated into + /// an event loop or run on a separate thread. + /// + /// The callback runs on the thread that first calls one of the above functions after the GPU work + /// completes. There are no restrictions on the code you can run in the callback; however, on native + /// the polling call will not return until the callback finishes, so keep callbacks short (set flags, + /// send messages, etc.). + /// + /// [q::s]: Queue::submit + /// [i::p_a]: Instance::poll_all + /// [d::p]: Device::poll pub fn on_submitted_work_done(&self, callback: impl FnOnce() + Send + 'static) { self.inner.on_submitted_work_done(Box::new(callback)); } diff --git a/wgpu/src/api/render_pass.rs b/wgpu/src/api/render_pass.rs index 0dd96b37ec5..c8cc56018eb 100644 --- a/wgpu/src/api/render_pass.rs +++ b/wgpu/src/api/render_pass.rs @@ -1,6 +1,9 @@ use core::ops::Range; -use crate::*; +use crate::{ + api::{impl_deferred_command_buffer_actions, SharedDeferredCommandBufferActions}, + *, +}; pub use wgt::{LoadOp, Operations, StoreOp}; /// In-progress recording of a render pass: a list of render commands in a [`CommandEncoder`]. @@ -24,6 +27,7 @@ pub use wgt::{LoadOp, Operations, StoreOp}; #[derive(Debug)] pub struct RenderPass<'encoder> { pub(crate) inner: dispatch::DispatchRenderPass, + pub(crate) actions: SharedDeferredCommandBufferActions, /// This lifetime is used to protect the [`CommandEncoder`] from being used /// while the pass is alive. This needs to be PhantomDrop to prevent the lifetime @@ -52,6 +56,7 @@ impl RenderPass<'_> { pub fn forget_lifetime(self) -> RenderPass<'static> { RenderPass { inner: self.inner, + actions: self.actions, _encoder_guard: crate::api::PhantomDrop::default(), } } @@ -278,6 +283,8 @@ impl RenderPass<'_> { .draw_mesh_tasks_indirect(&indirect_buffer.inner, indirect_offset); } + impl_deferred_command_buffer_actions!(); + /// Execute a [render bundle][RenderBundle], which is a set of pre-recorded commands /// that can be run together. /// diff --git a/wgpu/src/dispatch.rs b/wgpu/src/dispatch.rs index 0ec87fadddb..7ce26df0653 100644 --- a/wgpu/src/dispatch.rs +++ b/wgpu/src/dispatch.rs @@ -232,6 +232,7 @@ pub trait QueueInterface: CommonTraits { size: crate::Extent3d, ); + /// Submit must always drain the iterator, even in the case of error. fn submit(&self, command_buffers: &mut dyn Iterator) -> u64; fn get_timestamp_period(&self) -> f32; From 6bab36d1fd946fe6456e4c86d98459122a7547ed Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 18:14:34 -0400 Subject: [PATCH 191/303] chore(deps): update cargo.lock (#8197) * chore(deps): update cargo.lock * Update to png 0.18 * Waive cargo-deny advisory check for `adler` crate --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Andy Leiserson --- .deny.toml | 13 +- Cargo.lock | 304 ++++++++++++++----------- Cargo.toml | 2 +- examples/features/src/bunnymark/mod.rs | 5 +- tests/src/image.rs | 7 +- 5 files changed, 192 insertions(+), 139 deletions(-) diff --git a/.deny.toml b/.deny.toml index 80fc40130f1..b95868d767d 100644 --- a/.deny.toml +++ b/.deny.toml @@ -49,9 +49,16 @@ wildcards = "deny" allow-wildcard-paths = true [advisories] -# `paste` crate is no longer maintained https://rustsec.org/advisories/RUSTSEC-2024-0436 -# It's a dependency of `metal` (which is to be replaced with `objc2`) and a transitive dependency of `deno`. -ignore = ["RUSTSEC-2024-0436"] +ignore = [ + # `paste` crate is no longer maintained https://rustsec.org/advisories/RUSTSEC-2024-0436 + # It's a dependency of `metal` (which is to be replaced with `objc2-metal`), and a + # transitive dependency of `deno`. https://github.com/gfx-rs/wgpu/issues/7873 + "RUSTSEC-2024-0436", + # `adler` crate is no longer maintained https://rustsec.org/advisories/RUSTSEC-2025-0056 + # It's a dependency of `miniz_oxide` 0.7.4, and a transitive dependency of `deno`. + # https://github.com/gfx-rs/wgpu/issues/7961 + "RUSTSEC-2025-0056", +] [licenses] allow = [ diff --git a/Cargo.lock b/Cargo.lock index 3dd9d255891..a518e7ef7e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,7 +74,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee91c0c2905bae44f84bfa4e044536541df26b7703fd0888deeb9060fcc44289" dependencies = [ "android-properties", - "bitflags 2.9.3", + "bitflags 2.9.4", "cc", "cesu8", "jni", @@ -95,7 +95,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" dependencies = [ "android-properties", - "bitflags 2.9.3", + "bitflags 2.9.4", "cc", "cesu8", "jni", @@ -370,7 +370,7 @@ version = "0.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "cexpr", "clang-sys", "itertools 0.13.0", @@ -422,9 +422,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.3" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" dependencies = [ "arbitrary", "serde", @@ -520,7 +520,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "log", "polling", "rustix 0.38.44", @@ -534,7 +534,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "log", "polling", "rustix 0.38.44", @@ -568,9 +568,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.11" +version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d07aa9a93b00c76f71bc35d598bed923f6d4f3a9ca5c24b7737ae1a292841c0" +checksum = "dd0b03af37dad7a14518b7691d81acb0f8222604ad3d1b02f6b4bed5188c0cd5" dependencies = [ "serde", ] @@ -652,10 +652,11 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.34" +version = "1.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42bc4aea80032b7bf409b0bc7ccad88853858911b7713a8062fdc0623867bedc" +checksum = "5252b3d2648e5eedbc1a6f501e3c795e07025c1e93bbf8bbdd6eef7f447a6d54" dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", @@ -743,9 +744,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.45" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc0e74a703892159f5ae7d3aac52c8e6c392f5ae5f359c70b5881d60aaac318" +checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931" dependencies = [ "clap_builder", "clap_derive", @@ -753,9 +754,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.44" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e7f4214277f3c7aa526a59dd3fbe306a370daee1f8b7b8c987069cd8e888a8" +checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6" dependencies = [ "anstream", "anstyle", @@ -765,9 +766,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.45" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -921,7 +922,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "core-foundation 0.10.1", "libc", ] @@ -1480,6 +1481,12 @@ dependencies = [ "log", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d" + [[package]] name = "fixedbitset" version = "0.4.2" @@ -1696,12 +1703,12 @@ dependencies = [ [[package]] name = "gethostname" -version = "0.4.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +checksum = "fc257fdb4038301ce4b9cd1b3b51704509692bb3ff716a410cbd07925d9dae55" dependencies = [ - "libc", - "windows-targets 0.48.5", + "rustix 1.0.8", + "windows-targets 0.52.6", ] [[package]] @@ -1727,7 +1734,7 @@ dependencies = [ "js-sys", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasi 0.14.4+wasi-0.2.4", "wasm-bindgen", ] @@ -1781,7 +1788,7 @@ version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18fcd4ae4e86d991ad1300b8f57166e5be0c95ef1f63f3f5b827f8a164548746" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "cfg_aliases 0.1.1", "cgl", "core-foundation 0.9.4", @@ -1844,7 +1851,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "gpu-alloc-types", ] @@ -1854,7 +1861,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", ] [[package]] @@ -1875,7 +1882,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "gpu-descriptor-types", "hashbrown", ] @@ -1886,7 +1893,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", ] [[package]] @@ -2085,18 +2092,19 @@ dependencies = [ [[package]] name = "if_chain" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" +checksum = "cd62e6b5e86ea8eeeb8db1de02880a6abc01a397b2ebb64b5d74ac255318f5cb" [[package]] name = "image" -version = "0.25.6" +version = "0.25.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a" +checksum = "529feb3e6769d234375c4cf1ee2ce713682b8e76538cb13f9fc23e1400a591e7" dependencies = [ "bytemuck", "byteorder-lite", + "moxcms", "num-traits", "png", ] @@ -2132,7 +2140,7 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "cfg-if", "libc", ] @@ -2225,9 +2233,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "0c0b063578492ceec17683ef2f8c5e89121fbd0b172cbc280635ab7567db2738" dependencies = [ "once_cell", "wasm-bindgen", @@ -2256,7 +2264,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff7f53bdf698e7aa7ec916411bbdc8078135da11b66db5182675b2227f6c0d07" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", ] [[package]] @@ -2304,7 +2312,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "libc", "redox_syscall 0.5.17", ] @@ -2366,9 +2374,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "loom" @@ -2437,7 +2445,7 @@ version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00c15a6f673ff72ddcc22394663290f870fb224c1bfce55734a75c414150e605" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "block", "core-graphics-types 0.2.0", "foreign-types", @@ -2492,6 +2500,16 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "moxcms" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd32fa8935aeadb8a8a6b6b351e40225570a37c43de67690383d87ef170cd08" +dependencies = [ + "num-traits", + "pxfm", +] + [[package]] name = "naga" version = "26.0.0" @@ -2499,7 +2517,7 @@ dependencies = [ "arbitrary", "arrayvec", "bit-set 0.8.0", - "bitflags 2.9.3", + "bitflags 2.9.4", "cfg-if", "cfg_aliases 0.2.1", "codespan-reporting", @@ -2608,7 +2626,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "jni-sys", "log", "ndk-sys 0.5.0+25.2.9519653", @@ -2624,7 +2642,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "jni-sys", "log", "ndk-sys 0.6.0+11769913", @@ -2814,7 +2832,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "block2 0.5.1", "libc", "objc2 0.5.2", @@ -2830,7 +2848,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "block2 0.5.1", "objc2 0.5.2", "objc2-core-location", @@ -2854,7 +2872,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation", @@ -2902,7 +2920,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "block2 0.5.1", "dispatch", "libc", @@ -2927,7 +2945,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation", @@ -2939,7 +2957,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation", @@ -2962,7 +2980,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "block2 0.5.1", "objc2 0.5.2", "objc2-cloud-kit", @@ -2994,7 +3012,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "block2 0.5.1", "objc2 0.5.2", "objc2-core-location", @@ -3230,11 +3248,11 @@ dependencies = [ [[package]] name = "png" -version = "0.17.16" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" +checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.9.4", "crc32fast", "fdeflate", "flate2", @@ -3292,9 +3310,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" dependencies = [ "zerovec", ] @@ -3371,6 +3389,15 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" +[[package]] +name = "pxfm" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55f4fedc84ed39cb7a489322318976425e42a147e2be79d8f878e2884f94e84" +dependencies = [ + "num-traits", +] + [[package]] name = "quick-xml" version = "0.37.5" @@ -3487,7 +3514,7 @@ version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", ] [[package]] @@ -3538,7 +3565,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f" dependencies = [ "base64", - "bitflags 2.9.3", + "bitflags 2.9.4", "serde", "serde_derive", "unicode-ident", @@ -3587,7 +3614,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "errno", "libc", "linux-raw-sys 0.4.15", @@ -3600,7 +3627,7 @@ version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "errno", "libc", "linux-raw-sys 0.9.4", @@ -3848,7 +3875,7 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "calloop 0.12.4", "calloop-wayland-source 0.2.0", "cursor-icon", @@ -3873,7 +3900,7 @@ version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "calloop 0.13.0", "calloop-wayland-source 0.3.0", "cursor-icon", @@ -3945,7 +3972,7 @@ version = "0.3.0+sdk-1.3.268.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "serde", ] @@ -4399,9 +4426,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typewit" -version = "1.13.0" +version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd91acc53c592cb800c11c83e8e7ee1d48378d05cfa33b5474f5f80c5b236bf" +checksum = "4c98488b93df24b7c794d6a58c4198d7a2abde676324beaca84f7fb5b39c0811" [[package]] name = "unic-char-property" @@ -4524,9 +4551,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.18.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f33196643e165781c20a5ead5582283a7dacbb87855d867fbc2df3f81eddc1be" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ "getrandom 0.3.3", "js-sys", @@ -4541,7 +4568,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21c7a224a7eaf3f98c1bad772fbaee56394dce185ef7b19a2e0ca5e3d274165d" dependencies = [ "bindgen", - "bitflags 2.9.3", + "bitflags 2.9.4", "fslock", "gzip-header", "home", @@ -4593,30 +4620,31 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" -version = "0.14.2+wasi-0.2.4" +version = "0.14.4+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "88a5f4a424faf49c3c2c344f166f0662341d470ea185e939657aaff130f0ec4a" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb" dependencies = [ "bumpalo", "log", @@ -4628,9 +4656,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "0ca85039a9b469b38336411d6d6ced91f3fc87109a2a27b0c197663f5144dffe" dependencies = [ "cfg-if", "js-sys", @@ -4641,9 +4669,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4651,9 +4679,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa" dependencies = [ "proc-macro2", "quote", @@ -4664,18 +4692,18 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1" dependencies = [ "unicode-ident", ] [[package]] name = "wasm-bindgen-test" -version = "0.3.50" +version = "0.3.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c8d5e33ca3b6d9fa3b4676d774c5778031d27a578c2b007f905acf816152c3" +checksum = "80cc7f8a4114fdaa0c58383caf973fc126cf004eba25c9dc639bccd3880d55ad" dependencies = [ "js-sys", "minicov", @@ -4686,9 +4714,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.50" +version = "0.3.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17d5042cc5fa009658f9a7333ef24291b1291a25b6382dd68862a7f3b969f69b" +checksum = "c5ada2ab788d46d4bda04c9d567702a79c8ced14f51f221646a16ed39d0e6a5d" dependencies = [ "proc-macro2", "quote", @@ -4725,7 +4753,7 @@ version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "rustix 1.0.8", "wayland-backend", "wayland-scanner", @@ -4737,7 +4765,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "cursor-icon", "wayland-backend", ] @@ -4759,7 +4787,7 @@ version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "wayland-backend", "wayland-client", "wayland-scanner", @@ -4771,7 +4799,7 @@ version = "0.32.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "wayland-backend", "wayland-client", "wayland-scanner", @@ -4783,7 +4811,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "wayland-backend", "wayland-client", "wayland-protocols 0.31.2", @@ -4796,7 +4824,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a07a14257c077ab3279987c4f8bb987851bf57081b93710381daea94f2c2c032" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "wayland-backend", "wayland-client", "wayland-protocols 0.32.9", @@ -4809,7 +4837,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "wayland-backend", "wayland-client", "wayland-protocols 0.31.2", @@ -4822,7 +4850,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efd94963ed43cf9938a090ca4f7da58eb55325ec8200c3848963e98dc25b78ec" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "wayland-backend", "wayland-client", "wayland-protocols 0.32.9", @@ -4854,9 +4882,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "77e4b637749ff0d92b8fad63aa1f7cff3cbe125fd49c175cd6345e7272638b12" dependencies = [ "js-sys", "wasm-bindgen", @@ -4887,7 +4915,7 @@ name = "wgpu" version = "26.0.0" dependencies = [ "arrayvec", - "bitflags 2.9.3", + "bitflags 2.9.4", "bytemuck", "cfg-if", "cfg_aliases 0.2.1", @@ -4933,7 +4961,7 @@ dependencies = [ "arrayvec", "bit-set 0.8.0", "bit-vec 0.8.0", - "bitflags 2.9.3", + "bitflags 2.9.4", "bytemuck", "cfg_aliases 0.2.1", "document-features", @@ -5055,7 +5083,7 @@ dependencies = [ "arrayvec", "ash", "bit-set 0.8.0", - "bitflags 2.9.3", + "bitflags 2.9.4", "block", "bytemuck", "cfg-if", @@ -5106,7 +5134,7 @@ name = "wgpu-info" version = "26.0.0" dependencies = [ "anyhow", - "bitflags 2.9.3", + "bitflags 2.9.4", "env_logger", "hashbrown", "pico-args", @@ -5131,7 +5159,7 @@ dependencies = [ "anyhow", "approx", "arrayvec", - "bitflags 2.9.3", + "bitflags 2.9.4", "bytemuck", "cargo_metadata", "cfg-if", @@ -5169,7 +5197,7 @@ dependencies = [ name = "wgpu-types" version = "26.0.0" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "bytemuck", "js-sys", "log", @@ -5232,11 +5260,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.0", ] [[package]] @@ -5264,7 +5292,7 @@ dependencies = [ "windows-collections", "windows-core 0.61.2", "windows-future", - "windows-link", + "windows-link 0.1.3", "windows-numerics", ] @@ -5298,7 +5326,7 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement 0.60.0", "windows-interface 0.59.1", - "windows-link", + "windows-link 0.1.3", "windows-result 0.3.4", "windows-strings 0.4.2", ] @@ -5310,7 +5338,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ "windows-core 0.61.2", - "windows-link", + "windows-link 0.1.3", "windows-threading", ] @@ -5364,6 +5392,12 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +[[package]] +name = "windows-link" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + [[package]] name = "windows-numerics" version = "0.2.0" @@ -5371,7 +5405,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" dependencies = [ "windows-core 0.61.2", - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -5389,7 +5423,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -5408,7 +5442,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -5456,6 +5490,15 @@ dependencies = [ "windows-targets 0.53.3", ] +[[package]] +name = "windows-sys" +version = "0.61.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" +dependencies = [ + "windows-link 0.2.0", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -5508,7 +5551,7 @@ version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" dependencies = [ - "windows-link", + "windows-link 0.1.3", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", @@ -5525,7 +5568,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -5717,7 +5760,7 @@ dependencies = [ "ahash", "android-activity 0.5.2", "atomic-waker", - "bitflags 2.9.3", + "bitflags 2.9.4", "bytemuck", "calloop 0.12.4", "cfg_aliases 0.1.1", @@ -5766,7 +5809,7 @@ dependencies = [ "ahash", "android-activity 0.6.0", "atomic-waker", - "bitflags 2.9.3", + "bitflags 2.9.4", "block2 0.5.1", "bytemuck", "calloop 0.13.0", @@ -5825,13 +5868,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.9.3", -] +checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36" [[package]] name = "writeable" @@ -5861,24 +5901,24 @@ dependencies = [ [[package]] name = "x11rb" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" +checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" dependencies = [ "as-raw-xcb-connection", "gethostname", "libc", "libloading", "once_cell", - "rustix 0.38.44", + "rustix 1.0.8", "x11rb-protocol", ] [[package]] name = "x11rb-protocol" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" +checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" [[package]] name = "xcursor" @@ -5892,7 +5932,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "dlib", "log", "once_cell", @@ -5952,18 +5992,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index b28edfcf10d..1fba257724c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -158,7 +158,7 @@ pico-args = { version = "0.5", features = [ "short-space-opt", "combined-flags", ] } -png = "0.17.6" +png = "0.18" pollster = "0.4" portable-atomic = "1.8" portable-atomic-util = "0.2.4" diff --git a/examples/features/src/bunnymark/mod.rs b/examples/features/src/bunnymark/mod.rs index 689eb329dfd..233fe8ba539 100644 --- a/examples/features/src/bunnymark/mod.rs +++ b/examples/features/src/bunnymark/mod.rs @@ -237,7 +237,10 @@ impl crate::framework::Example for Example { let img_data = include_bytes!("../../../../logo.png"); let decoder = png::Decoder::new(std::io::Cursor::new(img_data)); let mut reader = decoder.read_info().unwrap(); - let mut buf = vec![0; reader.output_buffer_size()]; + let buf_len = reader + .output_buffer_size() + .expect("output buffer would not fit in memory"); + let mut buf = vec![0; buf_len]; let info = reader.next_frame(&mut buf).unwrap(); let size = wgpu::Extent3d { diff --git a/tests/src/image.rs b/tests/src/image.rs index 5cb66a647f8..94924757fab 100644 --- a/tests/src/image.rs +++ b/tests/src/image.rs @@ -23,7 +23,10 @@ async fn read_png(path: impl AsRef, width: u32, height: u32) -> Option Date: Tue, 9 Sep 2025 08:31:46 -0400 Subject: [PATCH 192/303] chore(deps): update crate-ci/typos action to v1.36.2 (#8193) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6529ff5e8e4..92e445dee13 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -684,7 +684,7 @@ jobs: run: taplo format --check --diff - name: Check for typos - uses: crate-ci/typos@v1.35.5 + uses: crate-ci/typos@v1.36.2 check-cts-runner: # runtime is normally 2 minutes From a9638c8e3ac09ce4f27ac171f8175671e30365fd Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Tue, 9 Sep 2025 10:03:12 -0700 Subject: [PATCH 193/303] Remove `pending_query_resets` from `CommandBufferMutable` (#8187) It is emptied by `reset_queries` at the end of every render pass, so it's just keeping an allocation alive, not holding any state. It seems unlikely that there is sufficient performance gain from reusing the memory allocation to justify the complexity of additional state at higher layers. --- wgpu-core/src/command/mod.rs | 3 --- wgpu-core/src/command/render.rs | 16 ++++++++-------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 2467784d57a..c401514c0fc 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -645,8 +645,6 @@ pub struct CommandBufferMutable { buffer_memory_init_actions: Vec, texture_memory_actions: CommandBufferTextureMemoryActions, - pub(crate) pending_query_resets: QueryResetMap, - as_actions: Vec, temp_resources: Vec, @@ -722,7 +720,6 @@ impl CommandEncoder { trackers: Tracker::new(), buffer_memory_init_actions: Default::default(), texture_memory_actions: Default::default(), - pending_query_resets: QueryResetMap::new(), as_actions: Default::default(), temp_resources: Default::default(), indirect_draw_validation_resources: diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index b3c100a10fd..344d55bd6d4 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1848,12 +1848,11 @@ impl Global { let mut indirect_draw_validation_batcher = crate::indirect_validation::DrawBatcher::new(); - let (scope, pending_discard_init_fixups) = { + let (scope, pending_discard_init_fixups, mut pending_query_resets) = { let encoder = &mut cmd_buf_data.encoder; let tracker = &mut cmd_buf_data.trackers; let buffer_memory_init_actions = &mut cmd_buf_data.buffer_memory_init_actions; let texture_memory_actions = &mut cmd_buf_data.texture_memory_actions; - let pending_query_resets = &mut cmd_buf_data.pending_query_resets; let indirect_draw_validation_resources = &mut cmd_buf_data.indirect_draw_validation_resources; @@ -1865,6 +1864,7 @@ impl Global { .open_pass(base.label.as_deref()) .map_pass_err(pass_scope)?; + let mut pending_query_resets = QueryResetMap::new(); let mut pending_discard_init_fixups = SurfacesInDiscardState::new(); let info = RenderPassInfo::start( @@ -1879,7 +1879,7 @@ impl Global { encoder, tracker, texture_memory_actions, - pending_query_resets, + &mut pending_query_resets, &mut pending_discard_init_fixups, snatch_guard, ) @@ -2139,7 +2139,7 @@ impl Global { pass::write_timestamp::( &mut state.general, cmd_enc.as_ref(), - Some(&mut cmd_buf_data.pending_query_resets), + Some(&mut pending_query_resets), query_set, query_index, ) @@ -2160,7 +2160,7 @@ impl Global { state.general.raw_encoder, &mut state.general.tracker.query_sets, query_index, - Some(&mut cmd_buf_data.pending_query_resets), + Some(&mut pending_query_resets), &mut state.active_occlusion_query, ) .map_pass_err(scope)?; @@ -2191,7 +2191,7 @@ impl Global { &mut state.general.tracker.query_sets, cmd_enc.as_ref(), query_index, - Some(&mut cmd_buf_data.pending_query_resets), + Some(&mut pending_query_resets), &mut state.active_pipeline_statistics_query, ) .map_pass_err(scope)?; @@ -2243,7 +2243,7 @@ impl Global { let pending_discard_init_fixups = state.general.pending_discard_init_fixups; encoder.close().map_pass_err(pass_scope)?; - (trackers, pending_discard_init_fixups) + (trackers, pending_discard_init_fixups, pending_query_resets) }; let encoder = &mut cmd_buf_data.encoder; @@ -2265,7 +2265,7 @@ impl Global { snatch_guard, ); - cmd_buf_data.pending_query_resets.reset_queries(transit); + pending_query_resets.reset_queries(transit); CommandEncoder::insert_barriers_from_scope(transit, tracker, &scope, snatch_guard); From 1791064a306881c7ddf218e69b4ffdafdae1be0d Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Tue, 9 Sep 2025 11:14:41 -0700 Subject: [PATCH 194/303] Update comments on IdentityValues (#8183) --- wgpu-core/src/identity.rs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/wgpu-core/src/identity.rs b/wgpu-core/src/identity.rs index b34282207d7..ea2f6326e56 100644 --- a/wgpu-core/src/identity.rs +++ b/wgpu-core/src/identity.rs @@ -32,9 +32,20 @@ enum IdSource { /// - `IdentityValues` reuses the index values of freed ids before returning /// ids with new index values. Freed vector entries get reused. /// +/// - The non-reuse property is achieved by storing an `epoch` alongside the +/// index in an `Id`. Index values are reused, but only with a different +/// epoch. +/// +/// `IdentityValues` can also be used to track the count of IDs allocated by +/// some external allocator. Combining internal and external allocation is not +/// allowed; calling both `alloc` and `mark_as_used` on the same +/// `IdentityValues` will result in a panic. The external mode is used when +/// [playing back a trace of wgpu operations][player]. +/// /// [`Id`]: crate::id::Id /// [`alloc`]: IdentityValues::alloc /// [`release`]: IdentityValues::release +/// [player]: https://github.com/gfx-rs/wgpu/tree/trunk/player/ #[derive(Debug)] pub(super) struct IdentityValues { free: Vec<(Index, Epoch)>, @@ -47,10 +58,11 @@ pub(super) struct IdentityValues { } impl IdentityValues { - /// Allocate a fresh, never-before-seen id with the given `backend`. + /// Allocate a fresh, never-before-seen ID. + /// + /// # Panics /// - /// The backend is incorporated into the id, so that ids allocated with - /// different `backend` values are always distinct. + /// If `mark_as_used` has previously been called on this `IdentityValues`. pub fn alloc(&mut self) -> Id { assert!( self.id_source != IdSource::External, @@ -70,6 +82,11 @@ impl IdentityValues { } } + /// Increment the count of used IDs. + /// + /// # Panics + /// + /// If `alloc` has previously been called on this `IdentityValues`. pub fn mark_as_used(&mut self, id: Id) -> Id { assert!( self.id_source != IdSource::Allocated, @@ -81,7 +98,9 @@ impl IdentityValues { id } - /// Free `id`. It will never be returned from `alloc` again. + /// Free `id` and/or decrement the count of used IDs. + /// + /// Freed IDs will never be returned from `alloc` again. pub fn release(&mut self, id: Id) { if let IdSource::Allocated = self.id_source { let (index, epoch) = id.unzip(); From 3902b0c11c984afca542ca11e91370b4a0466c63 Mon Sep 17 00:00:00 2001 From: Night_Hunter Date: Thu, 11 Sep 2025 12:19:42 +1200 Subject: [PATCH 195/303] Add support for builtin DComp swapchains (#7550) Co-authored-by: Connor Fitzgerald Co-authored-by: Marijn Suijten --- CHANGELOG.md | 21 ++++++++++++ wgpu-hal/src/dx12/adapter.rs | 6 +++- wgpu-hal/src/dx12/dcomp.rs | 61 +++++++++++++++++++++++++++++++++++ wgpu-hal/src/dx12/instance.rs | 28 +++++++++++----- wgpu-hal/src/dx12/mod.rs | 39 +++++++++++++++++++++- wgpu-types/src/instance.rs | 59 ++++++++++++++++++++++++++++++++- 6 files changed, 203 insertions(+), 11 deletions(-) create mode 100644 wgpu-hal/src/dx12/dcomp.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bcccc723ba..6a1f20c7695 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,27 @@ Available on `CommandEncoder`, `CommandBuffer`, `RenderPass`, and `ComputePass`. By @cwfitzgerald in [#8125](https://github.com/gfx-rs/wgpu/pull/8125). +#### Builtin Support for DXGI swapchains on top of of DirectComposition Visuals in DX12 + +By enabling DirectComposition support, the dx12 backend can now support transparent windows. + +This creates a single `IDCompositionVisual` over the entire window that is used by the mf`Surface`. If a user wants to manage the composition tree themselves, they should create their own device and composition, and pass the relevant visual down into `wgpu` via `SurfaceTargetUnsafe::CompositionVisual`. + +```rust +let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor { + backend_options: wgpu::BackendOptions { + dx12: wgpu::Dx12BackendOptions { + presentation_system: wgpu::Dx12SwapchainKind::DxgiFromVisual, + .. + }, + .. + }, + .. +}); +``` + +By @n1ght-hunter in [#7550](https://github.com/gfx-rs/wgpu/pull/7550). + #### `EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE` has been merged into `EXPERIMENTAL_RAY_QUERY` We have merged the acceleration structure feature into the `RayQuery` feature. This is to help work around an AMD driver bug and reduce the feature complexity of ray tracing. In the future when ray tracing pipelines are implemented, if either feature is enabled, acceleration structures will be available. diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index 1645088afb4..7f96bbcbaff 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -919,7 +919,10 @@ impl crate::Adapter for super::Adapter { ) -> Option { let current_extent = { match surface.target { - SurfaceTarget::WndHandle(wnd_handle) => { + SurfaceTarget::WndHandle(wnd_handle) + | SurfaceTarget::VisualFromWndHandle { + handle: wnd_handle, .. + } => { let mut rect = Default::default(); if unsafe { WindowsAndMessaging::GetClientRect(wnd_handle, &mut rect) }.is_ok() { @@ -963,6 +966,7 @@ impl crate::Adapter for super::Adapter { composite_alpha_modes: match surface.target { SurfaceTarget::WndHandle(_) => vec![wgt::CompositeAlphaMode::Opaque], SurfaceTarget::Visual(_) + | SurfaceTarget::VisualFromWndHandle { .. } | SurfaceTarget::SurfaceHandle(_) | SurfaceTarget::SwapChainPanel(_) => vec![ wgt::CompositeAlphaMode::Auto, diff --git a/wgpu-hal/src/dx12/dcomp.rs b/wgpu-hal/src/dx12/dcomp.rs new file mode 100644 index 00000000000..a6bc83352a6 --- /dev/null +++ b/wgpu-hal/src/dx12/dcomp.rs @@ -0,0 +1,61 @@ +use windows::Win32::{Foundation::HWND, Graphics::DirectComposition}; + +#[derive(Default)] +pub struct DCompState { + inner: Option, +} + +impl DCompState { + /// This will create a DirectComposition device and a target for the window handle if not already initialized. + /// If the device is already initialized, it will return the existing state. + pub unsafe fn get_or_init( + &mut self, + hwnd: &HWND, + ) -> Result<&mut InnerState, crate::SurfaceError> { + if self.inner.is_none() { + self.inner = Some(unsafe { InnerState::init(hwnd) }?); + } + Ok(self.inner.as_mut().unwrap()) + } +} + +pub struct InnerState { + pub visual: DirectComposition::IDCompositionVisual, + pub device: DirectComposition::IDCompositionDevice, + // Must be kept alive but is otherwise unused after initialization. + pub _target: DirectComposition::IDCompositionTarget, +} + +impl InnerState { + /// Creates a DirectComposition device and a target for the given window handle. + pub unsafe fn init(hwnd: &HWND) -> Result { + profiling::scope!("DCompState::init"); + let dcomp_device: DirectComposition::IDCompositionDevice = { + unsafe { DirectComposition::DCompositionCreateDevice2(None) }.map_err(|err| { + log::error!("DirectComposition::DCompositionCreateDevice failed: {err}"); + crate::SurfaceError::Other("DirectComposition::DCompositionCreateDevice") + })? + }; + + let target = unsafe { dcomp_device.CreateTargetForHwnd(*hwnd, false) }.map_err(|err| { + log::error!("IDCompositionDevice::CreateTargetForHwnd failed: {err}"); + crate::SurfaceError::Other("IDCompositionDevice::CreateTargetForHwnd") + })?; + + let visual = unsafe { dcomp_device.CreateVisual() }.map_err(|err| { + log::error!("IDCompositionDevice::CreateVisual failed: {err}"); + crate::SurfaceError::Other("IDCompositionDevice::CreateVisual") + })?; + + unsafe { target.SetRoot(&visual) }.map_err(|err| { + log::error!("IDCompositionTarget::SetRoot failed: {err}"); + crate::SurfaceError::Other("IDCompositionTarget::SetRoot") + })?; + + Ok(InnerState { + visual, + device: dcomp_device, + _target: target, + }) + } +} diff --git a/wgpu-hal/src/dx12/instance.rs b/wgpu-hal/src/dx12/instance.rs index 69bfa77d8e8..5f137836f85 100644 --- a/wgpu-hal/src/dx12/instance.rs +++ b/wgpu-hal/src/dx12/instance.rs @@ -104,6 +104,7 @@ impl crate::Instance for super::Instance { factory, factory_media, library: Arc::new(lib_main), + presentation_system: desc.backend_options.dx12.presentation_system, _lib_dxgi: lib_dxgi, supports_allow_tearing, flags: desc.flags, @@ -119,15 +120,26 @@ impl crate::Instance for super::Instance { window_handle: raw_window_handle::RawWindowHandle, ) -> Result { match window_handle { - raw_window_handle::RawWindowHandle::Win32(handle) => Ok(super::Surface { - factory: self.factory.clone(), - factory_media: self.factory_media.clone(), + raw_window_handle::RawWindowHandle::Win32(handle) => { // https://github.com/rust-windowing/raw-window-handle/issues/171 - target: SurfaceTarget::WndHandle(Foundation::HWND(handle.hwnd.get() as *mut _)), - supports_allow_tearing: self.supports_allow_tearing, - swap_chain: RwLock::new(None), - options: self.options.clone(), - }), + let handle = Foundation::HWND(handle.hwnd.get() as *mut _); + let target = match self.presentation_system { + wgt::Dx12SwapchainKind::DxgiFromHwnd => SurfaceTarget::WndHandle(handle), + wgt::Dx12SwapchainKind::DxgiFromVisual => SurfaceTarget::VisualFromWndHandle { + handle, + dcomp_state: Default::default(), + }, + }; + + Ok(super::Surface { + factory: self.factory.clone(), + factory_media: self.factory_media.clone(), + target, + supports_allow_tearing: self.supports_allow_tearing, + swap_chain: RwLock::new(None), + options: self.options.clone(), + }) + } _ => Err(crate::InstanceError::new(format!( "window handle {window_handle:?} is not a Win32 handle" ))), diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index c15f3b81e4e..a2570048b97 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -75,6 +75,7 @@ Otherwise, we pass a range corresponding only to the current bind group. mod adapter; mod command; mod conv; +mod dcomp; mod descriptor; mod device; mod instance; @@ -460,6 +461,7 @@ pub struct Instance { factory_media: Option, library: Arc, supports_allow_tearing: bool, + presentation_system: wgt::Dx12SwapchainKind, _lib_dxgi: DxgiLib, flags: wgt::InstanceFlags, memory_budget_thresholds: wgt::MemoryBudgetThresholds, @@ -542,6 +544,11 @@ struct SwapChain { enum SurfaceTarget { /// Borrowed, lifetime externally managed WndHandle(Foundation::HWND), + /// `handle` is borrowed, lifetime externally managed + VisualFromWndHandle { + handle: Foundation::HWND, + dcomp_state: Mutex, + }, Visual(DirectComposition::IDCompositionVisual), /// Borrowed, lifetime externally managed SurfaceHandle(Foundation::HANDLE), @@ -1297,7 +1304,9 @@ impl crate::Surface for Surface { Flags: flags.0 as u32, }; let swap_chain1 = match self.target { - SurfaceTarget::Visual(_) | SurfaceTarget::SwapChainPanel(_) => { + SurfaceTarget::Visual(_) + | SurfaceTarget::VisualFromWndHandle { .. } + | SurfaceTarget::SwapChainPanel(_) => { profiling::scope!("IDXGIFactory2::CreateSwapChainForComposition"); unsafe { self.factory.CreateSwapChainForComposition( @@ -1344,6 +1353,33 @@ impl crate::Surface for Surface { match &self.target { SurfaceTarget::WndHandle(_) | SurfaceTarget::SurfaceHandle(_) => {} + SurfaceTarget::VisualFromWndHandle { + handle, + dcomp_state, + } => { + let mut dcomp_state = dcomp_state.lock(); + let dcomp_state = unsafe { dcomp_state.get_or_init(handle) }?; + // Set the new swap chain as the content for the backing visual + // and commit the changes to the composition visual tree. + { + profiling::scope!("IDCompositionVisual::SetContent"); + unsafe { dcomp_state.visual.SetContent(&swap_chain1) }.map_err( + |err| { + log::error!("IDCompositionVisual::SetContent failed: {err}"); + crate::SurfaceError::Other("IDCompositionVisual::SetContent") + }, + )?; + } + + // Commit the changes to the composition device. + { + profiling::scope!("IDCompositionDevice::Commit"); + unsafe { dcomp_state.device.Commit() }.map_err(|err| { + log::error!("IDCompositionDevice::Commit failed: {err}"); + crate::SurfaceError::Other("IDCompositionDevice::Commit") + })?; + } + } SurfaceTarget::Visual(visual) => { if let Err(err) = unsafe { visual.SetContent(&swap_chain1) } { log::error!("Unable to SetContent: {err}"); @@ -1381,6 +1417,7 @@ impl crate::Surface for Surface { .into_device_result("MakeWindowAssociation")?; } SurfaceTarget::Visual(_) + | SurfaceTarget::VisualFromWndHandle { .. } | SurfaceTarget::SurfaceHandle(_) | SurfaceTarget::SwapChainPanel(_) => {} } diff --git a/wgpu-types/src/instance.rs b/wgpu-types/src/instance.rs index c78fccdb665..b19ce6ff933 100644 --- a/wgpu-types/src/instance.rs +++ b/wgpu-types/src/instance.rs @@ -359,6 +359,8 @@ impl GlBackendOptions { pub struct Dx12BackendOptions { /// Which DX12 shader compiler to use. pub shader_compiler: Dx12Compiler, + /// Presentation system to use. + pub presentation_system: Dx12SwapchainKind, /// Whether to wait for the latency waitable object before acquiring the next swapchain image. pub latency_waitable_object: Dx12UseFrameLatencyWaitableObject, } @@ -370,10 +372,12 @@ impl Dx12BackendOptions { #[must_use] pub fn from_env_or_default() -> Self { let compiler = Dx12Compiler::from_env().unwrap_or_default(); + let presentation_system = Dx12SwapchainKind::from_env().unwrap_or_default(); let latency_waitable_object = Dx12UseFrameLatencyWaitableObject::from_env().unwrap_or_default(); Self { shader_compiler: compiler, + presentation_system, latency_waitable_object, } } @@ -384,10 +388,11 @@ impl Dx12BackendOptions { #[must_use] pub fn with_env(self) -> Self { let shader_compiler = self.shader_compiler.with_env(); + let presentation_system = self.presentation_system.with_env(); let latency_waitable_object = self.latency_waitable_object.with_env(); - Self { shader_compiler, + presentation_system, latency_waitable_object, } } @@ -439,6 +444,58 @@ impl NoopBackendOptions { } } +#[derive(Clone, Debug, Default, Copy, PartialEq, Eq)] +/// Selects which kind of swapchain to use on DX12. +pub enum Dx12SwapchainKind { + /// Use a DXGI swapchain made directly from the window's HWND. + /// + /// This does not support transparency but has better support from developer tooling from RenderDoc. + #[default] + DxgiFromHwnd, + /// Use a DXGI swapchain made from a DirectComposition visual made automatically from the window's HWND. + /// + /// This creates a single [`IDCompositionVisual`] over the entire window that is used by the `Surface`. + /// If a user wants to manage the composition tree themselves, they should create their own device and + /// composition, and pass the relevant visual down via [`SurfaceTargetUnsafe::CompositionVisual`][CV]. + /// + /// This supports transparent windows, but does not have support from RenderDoc. + /// + /// [`IDCompositionVisual`]: https://learn.microsoft.com/en-us/windows/win32/api/dcomp/nn-dcomp-idcompositionvisual + /// [CV]: ../wgpu/struct.SurfaceTargetUnsafe.html#variant.CompositionVisual + DxgiFromVisual, +} + +impl Dx12SwapchainKind { + /// Choose which presentation system to use from the environment variable `WGPU_DX12_PRESENTATION_SYSTEM`. + /// + /// Valid values, case insensitive: + /// - `DxgiFromVisual` or `Visual` + /// - `DxgiFromHwnd` or `Hwnd` for [`Self::DxgiFromHwnd`] + #[must_use] + pub fn from_env() -> Option { + let value = crate::env::var("WGPU_DX12_PRESENTATION_SYSTEM") + .as_deref()? + .to_lowercase(); + match value.as_str() { + "dxgifromvisual" | "visual" => Some(Self::DxgiFromVisual), + "dxgifromhwnd" | "hwnd" => Some(Self::DxgiFromHwnd), + _ => None, + } + } + + /// Takes the given presentation system, modifies it based on the `WGPU_DX12_PRESENTATION_SYSTEM` environment variable, and returns the result. + /// + /// See [`from_env`](Self::from_env) for more information. + #[must_use] + pub fn with_env(self) -> Self { + if let Some(presentation_system) = Self::from_env() { + presentation_system + } else { + self + } + } +} + /// DXC shader model. #[derive(Clone, Debug)] #[allow(missing_docs)] From 3758b08be931848acca0820c4f9eb6b1718ac293 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 10 Sep 2025 17:50:25 -0700 Subject: [PATCH 196/303] Update cts to 20d2805 (#8201) --- cts_runner/revision.txt | 2 +- cts_runner/test.lst | 12 +++++++++++- xtask/src/cts.rs | 33 ++++++++++++++++++++++++++++++--- xtask/src/main.rs | 23 ++++++++++++++++------- xtask/src/run_wasm.rs | 14 +++++++++----- xtask/src/test.rs | 15 ++++++++++++--- xtask/src/util.rs | 23 ++++++++++++++++++++++- 7 files changed, 101 insertions(+), 21 deletions(-) diff --git a/cts_runner/revision.txt b/cts_runner/revision.txt index 782dc437bf3..b7f5c896781 100644 --- a/cts_runner/revision.txt +++ b/cts_runner/revision.txt @@ -1 +1 @@ -f164473e801f80c0e560e67a9abb356b09e06506 +20d2805a255a3ea41227200a61405ddb2871bcc0 diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 468cf3caa44..99f06512a1e 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -1,3 +1,7 @@ +// The following may be useful to generate lists of tests for this file: +// ``` +// cargo xtask cts -- --list +// ``` unittests:* webgpu:api,operation,command_buffer,basic:* webgpu:api,operation,command_buffer,copyBufferToBuffer:* @@ -102,7 +106,13 @@ webgpu:api,validation,image_copy,layout_related:copy_end_overflows_u64:* fails-if(dx12) webgpu:api,validation,image_copy,layout_related:offset_alignment:* webgpu:api,validation,image_copy,texture_related:format:dimension="1d";* webgpu:api,validation,queue,submit:command_buffer,* -webgpu:api,validation,render_pass,render_pass_descriptor:attachments,* +// `GPUTexture` as `GPUTextureView` not supported by Deno. https://github.com/gfx-rs/wgpu/issues/8200 +//FAIL: webgpu:api,validation,render_pass,render_pass_descriptor:attachments,one_color_attachment: +//FAIL: webgpu:api,validation,render_pass,render_pass_descriptor:attachments,one_depth_stencil_attachment: +webgpu:api,validation,render_pass,render_pass_descriptor:attachments,same_size: +webgpu:api,validation,render_pass,render_pass_descriptor:attachments,color_depth_mismatch: +webgpu:api,validation,render_pass,render_pass_descriptor:attachments,layer_count:* +webgpu:api,validation,render_pass,render_pass_descriptor:attachments,mip_level_count:* webgpu:api,validation,render_pass,render_pass_descriptor:resolveTarget,* webgpu:api,validation,texture,rg11b10ufloat_renderable:* webgpu:api,operation,render_pipeline,overrides:* diff --git a/xtask/src/cts.rs b/xtask/src/cts.rs index fdeae96c3cf..c1b675a3259 100644 --- a/xtask/src/cts.rs +++ b/xtask/src/cts.rs @@ -62,7 +62,11 @@ struct TestLine { pub fails_if: Option, } -pub fn run_cts(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { +pub fn run_cts( + shell: Shell, + mut args: Arguments, + passthrough_args: Option>, +) -> anyhow::Result<()> { let skip_checkout = args.contains("--skip-checkout"); let llvm_cov = args.contains("--llvm-cov"); let release = args.contains("--release"); @@ -89,8 +93,12 @@ pub fn run_cts(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { .collect::>(); if tests.is_empty() && list_files.is_empty() { - log::info!("Reading default test list from {CTS_DEFAULT_TEST_LIST}"); - list_files.push(OsString::from(CTS_DEFAULT_TEST_LIST)); + if passthrough_args.is_none() { + log::info!("Reading default test list from {CTS_DEFAULT_TEST_LIST}"); + list_files.push(OsString::from(CTS_DEFAULT_TEST_LIST)); + } + } else if passthrough_args.is_some() { + bail!("Test(s) and test list(s) are incompatible with passthrough arguments."); } for file in list_files { @@ -208,6 +216,25 @@ pub fn run_cts(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { &["run"][..] }; + if let Some(passthrough_args) = passthrough_args { + let mut cmd = shell + .cmd("cargo") + .args(run_flags) + .args(["--manifest-path".as_ref(), wgpu_cargo_toml.as_os_str()]) + .args(["-p", "cts_runner"]) + .args(["--bin", "cts_runner"]); + + if release { + cmd = cmd.arg("--release") + } + + cmd.args(["--", "./tools/run_deno", "--verbose"]) + .args(&passthrough_args) + .run()?; + + return Ok(()); + } + log::info!("Running CTS"); for test in &tests { match (&test.fails_if, &running_on_backend) { diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 1c23ceeb765..81e0b6db521 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -17,11 +17,15 @@ const HELP: &str = "\ Usage: xtask Commands: - cts [--skip-checkout] [ | -f ]... + cts [] [ | -f | -- ] Check out, build, and run CTS tests - --skip-checkout Don't check out the pinned CTS version, use whatever is - already checked out. + --skip-checkout Don't check out the pinned CTS version, use whatever + is already checked out. + --release Build and run in release mode + --llvm-cov Run with LLVM code coverage + --backend Specify the backend (metal, dx12, or vulkan). Used + to evaluate `fails-if` conditions in the test list. run-wasm Build and run web examples @@ -75,7 +79,12 @@ fn main() -> anyhow::Result { .format_indent(Some(0)) .init(); - let mut args = Arguments::from_env(); + let mut args = std::env::args_os().skip(1).collect::>(); + let passthrough_args = args + .iter() + .position(|arg| arg == "--") + .map(|pos| args.drain(pos..).skip(1).collect()); + let mut args = Arguments::from_vec(args); if args.contains(["-h", "--help"]) { eprint!("{HELP}"); @@ -92,10 +101,10 @@ fn main() -> anyhow::Result { shell.change_dir(String::from(env!("CARGO_MANIFEST_DIR")) + "/.."); match subcommand.as_deref() { - Some("cts") => cts::run_cts(shell, args)?, - Some("run-wasm") => run_wasm::run_wasm(shell, args)?, + Some("cts") => cts::run_cts(shell, args, passthrough_args)?, + Some("run-wasm") => run_wasm::run_wasm(shell, args, passthrough_args)?, Some("miri") => miri::run_miri(shell, args)?, - Some("test") => test::run_tests(shell, args)?, + Some("test") => test::run_tests(shell, args, passthrough_args)?, Some("vendor-web-sys") => vendor_web_sys::run_vendor_web_sys(shell, args)?, Some(subcommand) => { bad_arguments!("Unknown subcommand: {}", subcommand) diff --git a/xtask/src/run_wasm.rs b/xtask/src/run_wasm.rs index eace62f2ee6..8c556895d15 100644 --- a/xtask/src/run_wasm.rs +++ b/xtask/src/run_wasm.rs @@ -1,13 +1,19 @@ -use anyhow::Context; +use std::ffi::OsString; +use anyhow::Context; use pico_args::Arguments; use xshell::Shell; -use crate::util::{check_all_programs, Program}; +use crate::util::{check_all_programs, flatten_args, Program}; -pub(crate) fn run_wasm(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { +pub(crate) fn run_wasm( + shell: Shell, + mut args: Arguments, + passthrough_args: Option>, +) -> anyhow::Result<()> { let should_serve = !args.contains("--no-serve"); let release = args.contains("--release"); + let cargo_args = flatten_args(args, passthrough_args); let mut programs_needed = vec![Program { crate_name: "wasm-bindgen-cli", @@ -28,8 +34,6 @@ pub(crate) fn run_wasm(shell: Shell, mut args: Arguments) -> anyhow::Result<()> log::info!("building webgpu examples"); - let cargo_args = args.finish(); - xshell::cmd!( shell, "cargo build --target wasm32-unknown-unknown -p wgpu-examples --no-default-features --features webgpu {release_flag...}" diff --git a/xtask/src/test.rs b/xtask/src/test.rs index f1bce2c07dd..58516fb1b60 100644 --- a/xtask/src/test.rs +++ b/xtask/src/test.rs @@ -1,10 +1,19 @@ +use std::ffi::OsString; + use anyhow::Context; use pico_args::Arguments; use xshell::Shell; -pub fn run_tests(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { +use crate::util::flatten_args; + +pub fn run_tests( + shell: Shell, + mut args: Arguments, + passthrough_args: Option>, +) -> anyhow::Result<()> { let llvm_cov = args.contains("--llvm-cov"); let list = args.contains("--list"); + let cargo_args = flatten_args(args, passthrough_args); // Retries handled by cargo nextest natively // These needs to match the command in "run wgpu-info" in `.github/workflows/ci.yml` @@ -58,7 +67,7 @@ pub fn run_tests(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { .cmd("cargo") .args(llvm_cov_nextest_flags) .args(["-v", "--benches", "--tests", "--all-features"]) - .args(args.finish()) + .args(cargo_args) .run() .context("Failed to list tests")?; return Ok(()); @@ -69,7 +78,7 @@ pub fn run_tests(shell: Shell, mut args: Arguments) -> anyhow::Result<()> { .cmd("cargo") .args(llvm_cov_nextest_flags) .args(["--benches", "--tests", "--all-features"]) - .args(args.finish()) + .args(cargo_args) .quiet() .run() .context("Tests failed")?; diff --git a/xtask/src/util.rs b/xtask/src/util.rs index eb3e7819f56..aaece549a17 100644 --- a/xtask/src/util.rs +++ b/xtask/src/util.rs @@ -1,6 +1,7 @@ -use std::{io, process::Command}; +use std::{ffi::OsString, io, process::Command}; use anyhow::Context; +use pico_args::Arguments; use xshell::Shell; pub(crate) struct Program { @@ -12,6 +13,26 @@ pub(crate) fn looks_like_git_sha(input: &str) -> bool { input.len() == 40 && input.chars().all(|c| c.is_ascii_hexdigit()) } +pub(crate) fn flatten_args( + args: Arguments, + passthrough_args: Option>, +) -> Vec { + if let Some(passthrough_args) = passthrough_args { + let mut args = args.finish(); + // The following matches the historical behavior of our xtasks, however, + // it would be more general not to re-insert the terminator here, so + // that arguments can be passed either to cargo or to tests. i.e., with + // the next line, the args are interpreted as `xtask test + // -- `, without it the args would be interpreted as `xtask + // test -- -- `. + args.push(OsString::from("--")); + args.extend(passthrough_args); + args + } else { + args.finish() + } +} + pub(crate) fn check_all_programs(programs: &[Program]) -> anyhow::Result<()> { let mut failed_crates = Vec::new(); for &Program { From d31d944ed5b2eb71a9d857225aab7dc534e08915 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 10 Sep 2025 17:53:56 -0700 Subject: [PATCH 197/303] Clarify the effect of the SUBGROUP features and capabilities (#8203) --- CHANGELOG.md | 6 ++ naga/src/valid/mod.rs | 29 ++++-- naga/tests/naga/wgsl_errors.rs | 176 +++++++++++++++++++++++++++++++++ wgpu-types/src/features.rs | 10 +- 4 files changed, 212 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a1f20c7695..e8ab28d7845 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -219,6 +219,12 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). - [wgsl-in] Allow a trailing comma in `@blend_src(…)` attributes. By @ErichDonGubler in [#8137](https://github.com/gfx-rs/wgpu/pull/8137). +### Documentation + +#### General + +- Clarify that subgroup barriers require both the `SUBGROUP` and `SUBGROUP_BARRIER` features / capabilities. By @andyleiserson in TBD. + ## v26.0.4 (2025-08-07) ### Bug Fixes diff --git a/naga/src/valid/mod.rs b/naga/src/valid/mod.rs index 24938684afe..426b3d637d7 100644 --- a/naga/src/valid/mod.rs +++ b/naga/src/valid/mod.rs @@ -131,13 +131,26 @@ bitflags::bitflags! { const CUBE_ARRAY_TEXTURES = 1 << 15; /// Support for 64-bit signed and unsigned integers. const SHADER_INT64 = 1 << 16; - /// Support for subgroup operations. - /// Implies support for subgroup operations in both fragment and compute stages, - /// but not necessarily in the vertex stage, which requires [`Capabilities::SUBGROUP_VERTEX_STAGE`]. + /// Support for subgroup operations (except barriers) in fragment and compute shaders. + /// + /// Subgroup operations in the vertex stage require + /// [`Capabilities::SUBGROUP_VERTEX_STAGE`] in addition to `Capabilities::SUBGROUP`. + /// (But note that `create_validator` automatically sets + /// `Capabilities::SUBGROUP` whenever `Features::SUBGROUP_VERTEX` is + /// available.) + /// + /// Subgroup barriers require [`Capabilities::SUBGROUP_BARRIER`] in addition to + /// `Capabilities::SUBGROUP`. const SUBGROUP = 1 << 17; - /// Support for subgroup barriers. + /// Support for subgroup barriers in compute shaders. + /// + /// Requires [`Capabilities::SUBGROUP`]. Without it, enables nothing. const SUBGROUP_BARRIER = 1 << 18; - /// Support for subgroup operations in the vertex stage. + /// Support for subgroup operations (not including barriers) in the vertex stage. + /// + /// Without [`Capabilities::SUBGROUP`], enables nothing. (But note that + /// `create_validator` automatically sets `Capabilities::SUBGROUP` + /// whenever `Features::SUBGROUP_VERTEX` is available.) const SUBGROUP_VERTEX_STAGE = 1 << 19; /// Support for [`AtomicFunction::Min`] and [`AtomicFunction::Max`] on /// 64-bit integers in the [`Storage`] address space, when the return @@ -206,7 +219,11 @@ bitflags::bitflags! { #[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub struct SubgroupOperationSet: u8 { - /// Elect, Barrier + /// Barriers + // Possibly elections, when that is supported. + // https://github.com/gfx-rs/wgpu/issues/6042#issuecomment-3272603431 + // Contrary to what the name "basic" suggests, HLSL/DX12 support the + // other subgroup operations, but do not support subgroup barriers. const BASIC = 1 << 0; /// Any, All const VOTE = 1 << 1; diff --git a/naga/tests/naga/wgsl_errors.rs b/naga/tests/naga/wgsl_errors.rs index 6e5059e2eda..249d77c2215 100644 --- a/naga/tests/naga/wgsl_errors.rs +++ b/naga/tests/naga/wgsl_errors.rs @@ -1166,6 +1166,16 @@ fn validation_error( .map_err(|e| e.into_inner()) // TODO(https://github.com/gfx-rs/wgpu/issues/8153): Add tests for spans } +/// Check that a shader validates successfully. +/// +/// In a few tests it is useful to check conditions where a validation error +/// should be absent alongside conditions where it should be present. This +/// wrapper is less confusing than `validation_error().unwrap()`. +#[track_caller] +fn no_validation_error(source: &str, caps: naga::valid::Capabilities) { + validation_error(source, caps).unwrap(); +} + #[test] fn int64_capability() { check_validation! { @@ -3585,6 +3595,7 @@ fn issue7165() { fn invalid_return_type(a: Struct) -> i32 { return a; } "; + // We need the span for the error, so have to invoke manually. let module = naga::front::wgsl::parse_str(shader).unwrap(); let err = naga::valid::Validator::new( naga::valid::ValidationFlags::all(), @@ -3834,6 +3845,171 @@ fn const_eval_value_errors() { assert!(variant("f32(abs(-9223372036854775807 - 1))").is_ok()); } +#[test] +fn subgroup_capability() { + // Some of these tests should be `check_extension_validation` tests that + // also check handling of the enable directive, but that handling is not + // currently correct. https://github.com/gfx-rs/wgpu/issues/8202 + + // Non-barrier subgroup operations... + + // ...in fragment and compute shaders require [`Capabilities::SUBGROUP`]`. + for stage in [naga::ShaderStage::Fragment, naga::ShaderStage::Compute] { + let stage_attr = match stage { + naga::ShaderStage::Fragment => "@fragment", + naga::ShaderStage::Compute => "@compute @workgroup_size(1)", + _ => unreachable!(), + }; + check_one_validation! { + &format!(" + {stage_attr} + fn main() {{ + subgroupBallot(); + }} + "), + Err(naga::valid::ValidationError::EntryPoint { + stage: err_stage, + source: naga::valid::EntryPointError::Function( + naga::valid::FunctionError::MissingCapability(Capabilities::SUBGROUP) + ), + .. + }) if *err_stage == stage + } + } + + // ...in fragment and compute shaders require *only* [`Capabilities::SUBGROUP`]`. + for stage in [naga::ShaderStage::Fragment, naga::ShaderStage::Compute] { + let stage_attr = match stage { + naga::ShaderStage::Fragment => "@fragment", + naga::ShaderStage::Compute => "@compute @workgroup_size(1)", + _ => unreachable!(), + }; + no_validation_error( + &format!( + " + {stage_attr} + fn main() {{ + subgroupBallot(); + }} + " + ), + Capabilities::SUBGROUP, + ); + } + + // ...in vertex shaders require both [`Capabilities::SUBGROUP`] and + // [`Capabilities::SUBGROUP_VERTEX_STAGE`]`. (But note that + // `create_validator` automatically sets `Capabilities::SUBGROUP` whenever + // `Features::SUBGROUP_VERTEX` is available.) + for cap in [Capabilities::SUBGROUP, Capabilities::SUBGROUP_VERTEX_STAGE] { + check_validation! { + " + @vertex + fn main() -> @builtin(position) vec4 {{ + subgroupBallot(); + return vec4(); + }} + ": + Err(_), + cap + } + } + no_validation_error( + " + @vertex + fn main() -> @builtin(position) vec4 {{ + subgroupBallot(); + return vec4(); + }} + ", + Capabilities::SUBGROUP | Capabilities::SUBGROUP_VERTEX_STAGE, + ); + + // Subgroup barriers... + + // ...require both SUBGROUP and SUBGROUP_BARRIER. + for cap in [Capabilities::SUBGROUP, Capabilities::SUBGROUP_BARRIER] { + check_validation! { + r#" + @compute @workgroup_size(1) + fn main() { + subgroupBarrier(); + } + "#: + Err(naga::valid::ValidationError::EntryPoint { + stage: naga::ShaderStage::Compute, + source: naga::valid::EntryPointError::Function( + naga::valid::FunctionError::MissingCapability(required_caps) + ), + .. + }) if *required_caps == Capabilities::SUBGROUP | Capabilities::SUBGROUP_BARRIER, + cap + } + } + + // ...are never supported in vertex shaders. + check_validation! { + r#" + @vertex + fn main() -> @builtin(position) vec4 { + subgroupBarrier(); + return vec4(); + } + "#: + Err(naga::valid::ValidationError::EntryPoint { + stage: naga::ShaderStage::Vertex, + source: naga::valid::EntryPointError::ForbiddenStageOperations, + .. + }), + Capabilities::SUBGROUP | Capabilities::SUBGROUP_BARRIER | Capabilities::SUBGROUP_VERTEX_STAGE + } + + // ...are never supported in fragment shaders. + check_validation! { + r#" + @fragment + fn main() { + subgroupBarrier(); + } + "#: + Err(naga::valid::ValidationError::EntryPoint { + stage: naga::ShaderStage::Fragment, + source: naga::valid::EntryPointError::ForbiddenStageOperations, + .. + }), + Capabilities::SUBGROUP | Capabilities::SUBGROUP_BARRIER + } + + // The `subgroup_id` built-in... + + // ...in compute shaders requires [`Capabilities::SUBGROUP`]`. + check_one_validation! { + " + @compute @workgroup_size(1) + fn main(@builtin(subgroup_id) subgroup_id: u32) {{ + }} + ", + Err(naga::valid::ValidationError::EntryPoint { + stage: naga::ShaderStage::Compute, + source: naga::valid::EntryPointError::Argument( + _, + naga::valid::VaryingError::UnsupportedCapability(Capabilities::SUBGROUP) + ), + .. + }) + } + + // ...in compute shaders requires *only* [`Capabilities::SUBGROUP`]`. + no_validation_error( + " + @compute @workgroup_size(1) + fn main(@builtin(subgroup_id) subgroup_id: u32) {{ + }} + ", + Capabilities::SUBGROUP, + ); +} + #[test] fn subgroup_invalid_broadcast() { check_validation! { diff --git a/wgpu-types/src/features.rs b/wgpu-types/src/features.rs index 94a9a91cb50..397de544d6d 100644 --- a/wgpu-types/src/features.rs +++ b/wgpu-types/src/features.rs @@ -1058,7 +1058,8 @@ bitflags_array! { /// /// This is a native only feature. const SHADER_INT64 = 1 << 37; - /// Allows compute and fragment shaders to use the subgroup operation built-ins + /// Allows compute and fragment shaders to use the subgroup operation + /// built-ins and perform subgroup operations (except barriers). /// /// Supported Platforms: /// - Vulkan @@ -1067,14 +1068,17 @@ bitflags_array! { /// /// This is a native only feature. const SUBGROUP = 1 << 38; - /// Allows vertex shaders to use the subgroup operation built-ins + /// Allows vertex shaders to use the subgroup operation built-ins and + /// perform subgroup operations (except barriers). /// /// Supported Platforms: /// - Vulkan /// /// This is a native only feature. const SUBGROUP_VERTEX = 1 << 39; - /// Allows shaders to use the subgroup barrier + /// Allows compute shaders to use the subgroup barrier. + /// + /// Requires [`Features::SUBGROUP`]. Without it, enables nothing. /// /// Supported Platforms: /// - Vulkan From 54ce9f7f98b7da77029bbaea5e1e2fb01c2562fb Mon Sep 17 00:00:00 2001 From: Magnus <85136135+SupaMaggie70Incorporated@users.noreply.github.com> Date: Wed, 10 Sep 2025 19:55:42 -0500 Subject: [PATCH 198/303] Update shader bencher to share some logic with snapshots (#8108) Co-authored-by: Connor Fitzgerald --- Cargo.lock | 19 +- Cargo.toml | 3 + benches/Cargo.toml | 1 + benches/benches/wgpu-benchmark/shader.rs | 247 ++++---- naga-test/Cargo.toml | 39 ++ naga-test/src/lib.rs | 452 +++++++++++++++ naga/Cargo.toml | 9 +- naga/src/back/spv/writer.rs | 18 + naga/src/front/wgsl/mod.rs | 3 + naga/tests/naga/snapshots.rs | 681 ++++------------------- naga/tests/naga/spirv_capabilities.rs | 2 - naga/tests/naga/validation.rs | 20 - naga/tests/naga/wgsl_errors.rs | 7 - 13 files changed, 791 insertions(+), 710 deletions(-) create mode 100644 naga-test/Cargo.toml create mode 100644 naga-test/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index a518e7ef7e9..46276fd94b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2531,6 +2531,7 @@ dependencies = [ "itertools 0.14.0", "libm", "log", + "naga-test", "num-traits", "once_cell", "petgraph 0.8.2", @@ -2542,7 +2543,6 @@ dependencies = [ "spirv", "strum 0.27.2", "thiserror 2.0.16", - "toml 0.9.5", "unicode-ident", "walkdir", ] @@ -2570,6 +2570,22 @@ dependencies = [ "naga", ] +[[package]] +name = "naga-test" +version = "26.0.0" +dependencies = [ + "bitflags 2.9.3", + "env_logger", + "naga", + "ron", + "rspirv", + "serde", + "serde_json", + "spirv", + "toml 0.9.5", + "walkdir", +] + [[package]] name = "naga-xtask" version = "0.1.0" @@ -4946,6 +4962,7 @@ dependencies = [ "bytemuck", "criterion", "naga", + "naga-test", "nanorand 0.8.0", "pollster", "profiling", diff --git a/Cargo.toml b/Cargo.toml index 1fba257724c..5614a5fb4ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ members = [ "examples/standalone/*", "lock-analyzer", "naga-cli", + "naga-test", "naga", "naga/fuzz", "naga/hlsl-snapshots", @@ -32,6 +33,7 @@ default-members = [ "examples/standalone/*", "lock-analyzer", "naga-cli", + "naga-test", "naga", "naga/fuzz", "naga/hlsl-snapshots", @@ -64,6 +66,7 @@ authors = ["gfx-rs developers"] [workspace.dependencies] naga = { version = "26.0.0", path = "./naga" } +naga-test = { version = "26.0.0", path = "./naga-test" } wgpu = { version = "26.0.0", path = "./wgpu", default-features = false, features = [ "serde", "wgsl", diff --git a/benches/Cargo.toml b/benches/Cargo.toml index 9af4cf4ae7d..a1d09eea3a3 100644 --- a/benches/Cargo.toml +++ b/benches/Cargo.toml @@ -41,6 +41,7 @@ naga = { workspace = true, features = [ "glsl-out", "wgsl-out", ] } +naga-test = { workspace = true, features = [] } nanorand.workspace = true pollster.workspace = true profiling.workspace = true diff --git a/benches/benches/wgpu-benchmark/shader.rs b/benches/benches/wgpu-benchmark/shader.rs index b98cef01ae5..7e74df4f57c 100644 --- a/benches/benches/wgpu-benchmark/shader.rs +++ b/benches/benches/wgpu-benchmark/shader.rs @@ -1,57 +1,56 @@ use criterion::*; -use std::{fs, path::PathBuf, process::Command}; +use std::{fs, process::Command}; -struct Input { - filename: String, - size: u64, +const DIR_IN: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../naga/tests/in"); + +use naga_test::*; + +struct InputWithInfo { + inner: Input, data: Vec, string: Option, + options: Parameters, module: Option, module_info: Option, } +impl From for InputWithInfo { + fn from(value: Input) -> Self { + let mut options = value.read_parameters(DIR_IN); + options.targets = Some(options.targets.unwrap_or(Targets::all())); + Self { + options, + inner: value, + data: Vec::new(), + string: None, + module: None, + module_info: None, + } + } +} +impl InputWithInfo { + fn filename(&self) -> &str { + self.inner.file_name.file_name().unwrap().to_str().unwrap() + } +} struct Inputs { - inner: Vec, + inner: Vec, } impl Inputs { #[track_caller] fn from_dir(folder: &str, extension: &str) -> Self { - let mut inputs = Vec::new(); - let read_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")) - .join(folder) - .read_dir() - .unwrap(); - - for file_entry in read_dir { - match file_entry { - Ok(entry) => match entry.path().extension() { - Some(ostr) if ostr == extension => { - let path = entry.path(); - - inputs.push(Input { - filename: path.to_string_lossy().into_owned(), - size: entry.metadata().unwrap().len(), - string: None, - data: vec![], - module: None, - module_info: None, - }); - } - _ => continue, - }, - Err(e) => { - eprintln!("Skipping file: {e:?}"); - continue; - } - } - } + let inputs: Vec = Input::files_in_dir(folder, &[extension], DIR_IN) + .map(|a| a.into()) + .collect(); Self { inner: inputs } } - fn bytes(&self) -> u64 { - self.inner.iter().map(|input| input.size).sum() + self.inner + .iter() + .map(|input| input.inner.bytes(DIR_IN)) + .sum() } fn load(&mut self) { @@ -60,7 +59,7 @@ impl Inputs { continue; } - input.data = fs::read(&input.filename).unwrap_or_default(); + input.data = fs::read(input.inner.input_path(DIR_IN)).unwrap_or_default(); } } @@ -85,6 +84,8 @@ impl Inputs { continue; } + parser.set_options((&input.options.wgsl_in).into()); + input.module = Some(parser.parse(input.string.as_ref().unwrap()).unwrap()); } } @@ -122,22 +123,22 @@ fn parse_glsl(stage: naga::ShaderStage, inputs: &Inputs) { }; for input in &inputs.inner { parser - .parse(&options, input.string.as_deref().unwrap()) + .parse(&options, &input.inner.read_source(DIR_IN, false)) .unwrap(); } } fn get_wgsl_inputs() -> Inputs { - let mut inputs = Inputs::from_dir("../naga/tests/in/wgsl", "wgsl"); + let mut inputs: Vec = Input::files_in_dir("wgsl", &["wgsl"], DIR_IN) + .map(|a| a.into()) + .collect(); // remove "large-source" tests, they skew the results - inputs - .inner - .retain(|input| !input.filename.contains("large-source")); + inputs.retain(|input| !input.filename().contains("large-source")); assert!(!inputs.is_empty()); - inputs + Inputs { inner: inputs } } fn frontends(c: &mut Criterion) { @@ -178,19 +179,20 @@ fn frontends(c: &mut Criterion) { let mut frontend = naga::front::wgsl::Frontend::new(); b.iter(|| { for input in &inputs_wgsl.inner { + frontend.set_options((&input.options.wgsl_in).into()); frontend.parse(input.string.as_ref().unwrap()).unwrap(); } }); }); - let inputs_spirv = Inputs::from_dir("../naga/tests/in/spv", "spvasm"); + let inputs_spirv = Inputs::from_dir("spv", "spvasm"); assert!(!inputs_spirv.is_empty()); // Assemble all the SPIR-V assembly. let mut assembled_spirv = Vec::>::new(); 'spirv: for input in &inputs_spirv.inner { let output = match Command::new("spirv-as") - .arg(&input.filename) + .arg(input.inner.input_path(DIR_IN)) .arg("-o") .arg("-") .output() @@ -220,19 +222,32 @@ fn frontends(c: &mut Criterion) { let total_bytes = assembled_spirv.iter().map(|spv| spv.len() as u64).sum(); + assert!(assembled_spirv.len() == inputs_spirv.inner.len() || assembled_spirv.is_empty()); + group.throughput(Throughput::Bytes(total_bytes)); group.bench_function("shader: spv-in", |b| { b.iter(|| { - let options = naga::front::spv::Options::default(); - for input in &assembled_spirv { - let parser = naga::front::spv::Frontend::new(input.iter().cloned(), &options); + for (i, input) in assembled_spirv.iter().enumerate() { + let params = &inputs_spirv.inner[i].options; + let SpirvInParameters { + adjust_coordinate_space, + } = params.spv_in; + + let parser = naga::front::spv::Frontend::new( + input.iter().cloned(), + &naga::front::spv::Options { + adjust_coordinate_space, + strict_capabilities: true, + ..Default::default() + }, + ); parser.parse().unwrap(); } }); }); - let mut inputs_vertex = Inputs::from_dir("../naga/tests/in/glsl", "vert"); - let mut inputs_fragment = Inputs::from_dir("../naga/tests/in/glsl", "frag"); + let mut inputs_vertex = Inputs::from_dir("glsl", "vert"); + let mut inputs_fragment = Inputs::from_dir("glsl", "frag"); assert!(!inputs_vertex.is_empty()); assert!(!inputs_fragment.is_empty()); // let mut inputs_compute = Inputs::from_dir("../naga/tests/in/glsl", "comp"); @@ -312,14 +327,16 @@ fn backends(c: &mut Criterion) { group.bench_function("shader: wgsl-out", |b| { b.iter(|| { let mut string = String::new(); - let flags = naga::back::wgsl::WriterFlags::empty(); for input in &inputs.inner { - let mut writer = naga::back::wgsl::Writer::new(&mut string, flags); - let _ = writer.write( - input.module.as_ref().unwrap(), - input.module_info.as_ref().unwrap(), - ); - string.clear(); + if input.options.targets.unwrap().contains(Targets::WGSL) { + let mut writer = + naga::back::wgsl::Writer::new(&mut string, (&input.options.wgsl).into()); + let _ = writer.write( + input.module.as_ref().unwrap(), + input.module_info.as_ref().unwrap(), + ); + string.clear(); + } } }); }); @@ -327,21 +344,28 @@ fn backends(c: &mut Criterion) { group.bench_function("shader: spv-out", |b| { b.iter(|| { let mut data = Vec::new(); - let options = naga::back::spv::Options::default(); + let mut writer = naga::back::spv::Writer::new(&Default::default()).unwrap(); for input in &inputs.inner { - if input.filename.contains("pointer-function-arg") { - // These fail due to https://github.com/gfx-rs/wgpu/issues/7315 - continue; + if input.options.targets.unwrap().contains(Targets::SPIRV) { + if input.filename().contains("pointer-function-arg") { + // These fail due to https://github.com/gfx-rs/wgpu/issues/7315 + continue; + } + let opt = input + .options + .spv + .to_options(input.options.bounds_check_policies, None); + if writer.set_options(&opt).is_ok() { + let _ = writer.write( + input.module.as_ref().unwrap(), + input.module_info.as_ref().unwrap(), + None, + &None, + &mut data, + ); + data.clear(); + } } - let mut writer = naga::back::spv::Writer::new(&options).unwrap(); - let _ = writer.write( - input.module.as_ref().unwrap(), - input.module_info.as_ref().unwrap(), - None, - &None, - &mut data, - ); - data.clear(); } }); }); @@ -350,25 +374,27 @@ fn backends(c: &mut Criterion) { let mut data = Vec::new(); let options = naga::back::spv::Options::default(); for input in &inputs.inner { - if input.filename.contains("pointer-function-arg") { - // These fail due to https://github.com/gfx-rs/wgpu/issues/7315 - continue; - } - let mut writer = naga::back::spv::Writer::new(&options).unwrap(); - let module = input.module.as_ref().unwrap(); - for ep in module.entry_points.iter() { - let pipeline_options = naga::back::spv::PipelineOptions { - shader_stage: ep.stage, - entry_point: ep.name.clone(), - }; - let _ = writer.write( - input.module.as_ref().unwrap(), - input.module_info.as_ref().unwrap(), - Some(&pipeline_options), - &None, - &mut data, - ); - data.clear(); + if input.options.targets.unwrap().contains(Targets::SPIRV) { + if input.filename().contains("pointer-function-arg") { + // These fail due to https://github.com/gfx-rs/wgpu/issues/7315 + continue; + } + let mut writer = naga::back::spv::Writer::new(&options).unwrap(); + let module = input.module.as_ref().unwrap(); + for ep in module.entry_points.iter() { + let pipeline_options = naga::back::spv::PipelineOptions { + shader_stage: ep.stage, + entry_point: ep.name.clone(), + }; + let _ = writer.write( + input.module.as_ref().unwrap(), + input.module_info.as_ref().unwrap(), + Some(&pipeline_options), + &None, + &mut data, + ); + data.clear(); + } } } }); @@ -379,15 +405,17 @@ fn backends(c: &mut Criterion) { let mut string = String::new(); let options = naga::back::msl::Options::default(); for input in &inputs.inner { - let pipeline_options = naga::back::msl::PipelineOptions::default(); - let mut writer = naga::back::msl::Writer::new(&mut string); - let _ = writer.write( - input.module.as_ref().unwrap(), - input.module_info.as_ref().unwrap(), - &options, - &pipeline_options, - ); - string.clear(); + if input.options.targets.unwrap().contains(Targets::METAL) { + let pipeline_options = naga::back::msl::PipelineOptions::default(); + let mut writer = naga::back::msl::Writer::new(&mut string); + let _ = writer.write( + input.module.as_ref().unwrap(), + input.module_info.as_ref().unwrap(), + &options, + &pipeline_options, + ); + string.clear(); + } } }); }); @@ -397,15 +425,17 @@ fn backends(c: &mut Criterion) { let options = naga::back::hlsl::Options::default(); let mut string = String::new(); for input in &inputs.inner { - let pipeline_options = Default::default(); - let mut writer = - naga::back::hlsl::Writer::new(&mut string, &options, &pipeline_options); - let _ = writer.write( - input.module.as_ref().unwrap(), - input.module_info.as_ref().unwrap(), - None, - ); // may fail on unimplemented things - string.clear(); + if input.options.targets.unwrap().contains(Targets::HLSL) { + let pipeline_options = Default::default(); + let mut writer = + naga::back::hlsl::Writer::new(&mut string, &options, &pipeline_options); + let _ = writer.write( + input.module.as_ref().unwrap(), + input.module_info.as_ref().unwrap(), + None, + ); // may fail on unimplemented things + string.clear(); + } } }); }); @@ -420,6 +450,9 @@ fn backends(c: &mut Criterion) { zero_initialize_workgroup_memory: true, }; for input in &inputs.inner { + if !input.options.targets.unwrap().contains(Targets::GLSL) { + continue; + } let module = input.module.as_ref().unwrap(); let info = input.module_info.as_ref().unwrap(); for ep in module.entry_points.iter() { diff --git a/naga-test/Cargo.toml b/naga-test/Cargo.toml new file mode 100644 index 00000000000..54b626e2cfa --- /dev/null +++ b/naga-test/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "naga-test" +version.workspace = true +authors.workspace = true +edition.workspace = true +description = "common code for naga tests" +homepage.workspace = true +repository.workspace = true +keywords.workspace = true +license.workspace = true +rust-version.workspace = true +publish = false + + +[features] + +[dependencies] +naga = { workspace = true, features = [ + "serialize", + "deserialize", + "glsl-in", + "glsl-out", + "spv-in", + "spv-out", + "wgsl-in", + "wgsl-out", + "msl-out", + "dot-out", + "hlsl-out", +] } +spirv = { workspace = true, features = ["deserialize"] } +rspirv.workspace = true +ron.workspace = true +toml.workspace = true +bitflags.workspace = true +serde_json.workspace = true +serde.workspace = true +walkdir.workspace = true +env_logger.workspace = true diff --git a/naga-test/src/lib.rs b/naga-test/src/lib.rs new file mode 100644 index 00000000000..6f219005c62 --- /dev/null +++ b/naga-test/src/lib.rs @@ -0,0 +1,452 @@ +// A lot of the code can be unused based on configuration flags, +// the corresponding warnings aren't helpful. +#![allow(dead_code, unused_imports)] + +use core::fmt::Write; + +use std::{ + fs, + path::{Path, PathBuf}, +}; + +use naga::compact::KeepUnused; +use ron::de; + +bitflags::bitflags! { + #[derive(Clone, Copy, serde::Deserialize)] + #[serde(transparent)] + #[derive(Debug, Eq, PartialEq)] + pub struct Targets: u32 { + /// A serialization of the `naga::Module`, in RON format. + const IR = 1; + + /// A serialization of the `naga::valid::ModuleInfo`, in RON format. + const ANALYSIS = 1 << 1; + + const SPIRV = 1 << 2; + const METAL = 1 << 3; + const GLSL = 1 << 4; + const DOT = 1 << 5; + const HLSL = 1 << 6; + const WGSL = 1 << 7; + const NO_VALIDATION = 1 << 8; + } +} + +impl Targets { + /// Defaults for `spv` and `glsl` snapshots. + pub fn non_wgsl_default() -> Self { + Targets::WGSL + } + + /// Defaults for `wgsl` snapshots. + pub fn wgsl_default() -> Self { + Targets::HLSL | Targets::SPIRV | Targets::GLSL | Targets::METAL | Targets::WGSL + } +} + +#[derive(serde::Deserialize)] +pub struct SpvOutVersion(pub u8, pub u8); +impl Default for SpvOutVersion { + fn default() -> Self { + SpvOutVersion(1, 1) + } +} + +#[derive(serde::Deserialize)] +pub struct BindingMapSerialization { + pub resource_binding: naga::ResourceBinding, + pub bind_target: naga::back::spv::BindingInfo, +} + +pub fn deserialize_binding_map<'de, D>( + deserializer: D, +) -> Result +where + D: serde::Deserializer<'de>, +{ + use serde::Deserialize; + + let vec = Vec::::deserialize(deserializer)?; + let mut map = naga::back::spv::BindingMap::default(); + for item in vec { + map.insert(item.resource_binding, item.bind_target); + } + Ok(map) +} + +#[derive(Default, serde::Deserialize)] +#[serde(default)] +pub struct WgslInParameters { + pub parse_doc_comments: bool, +} +impl From<&WgslInParameters> for naga::front::wgsl::Options { + fn from(value: &WgslInParameters) -> Self { + Self { + parse_doc_comments: value.parse_doc_comments, + } + } +} + +#[derive(Default, serde::Deserialize)] +#[serde(default)] +pub struct SpirvInParameters { + pub adjust_coordinate_space: bool, +} +impl From<&SpirvInParameters> for naga::front::spv::Options { + fn from(value: &SpirvInParameters) -> Self { + Self { + adjust_coordinate_space: value.adjust_coordinate_space, + ..Default::default() + } + } +} + +#[derive(serde::Deserialize)] +#[serde(default)] +pub struct SpirvOutParameters { + pub version: SpvOutVersion, + pub capabilities: naga::FastHashSet, + pub debug: bool, + pub adjust_coordinate_space: bool, + pub force_point_size: bool, + pub clamp_frag_depth: bool, + pub separate_entry_points: bool, + #[serde(deserialize_with = "deserialize_binding_map")] + pub binding_map: naga::back::spv::BindingMap, + pub use_storage_input_output_16: bool, +} +impl Default for SpirvOutParameters { + fn default() -> Self { + Self { + version: SpvOutVersion::default(), + capabilities: naga::FastHashSet::default(), + debug: false, + adjust_coordinate_space: false, + force_point_size: false, + clamp_frag_depth: false, + separate_entry_points: false, + use_storage_input_output_16: true, + binding_map: naga::back::spv::BindingMap::default(), + } + } +} +impl SpirvOutParameters { + pub fn to_options<'a>( + &'a self, + bounds_check_policies: naga::proc::BoundsCheckPolicies, + debug_info: Option>, + ) -> naga::back::spv::Options<'a> { + use naga::back::spv; + let mut flags = spv::WriterFlags::LABEL_VARYINGS; + flags.set(spv::WriterFlags::DEBUG, self.debug); + flags.set( + spv::WriterFlags::ADJUST_COORDINATE_SPACE, + self.adjust_coordinate_space, + ); + flags.set(spv::WriterFlags::FORCE_POINT_SIZE, self.force_point_size); + flags.set(spv::WriterFlags::CLAMP_FRAG_DEPTH, self.clamp_frag_depth); + naga::back::spv::Options { + lang_version: (self.version.0, self.version.1), + flags, + capabilities: if self.capabilities.is_empty() { + None + } else { + Some(self.capabilities.clone()) + }, + bounds_check_policies, + binding_map: self.binding_map.clone(), + zero_initialize_workgroup_memory: spv::ZeroInitializeWorkgroupMemoryMode::Polyfill, + force_loop_bounding: true, + debug_info, + use_storage_input_output_16: self.use_storage_input_output_16, + } + } +} + +#[derive(Default, serde::Deserialize)] +#[serde(default)] +pub struct WgslOutParameters { + pub explicit_types: bool, +} +impl From<&WgslOutParameters> for naga::back::wgsl::WriterFlags { + fn from(value: &WgslOutParameters) -> Self { + let mut flags = Self::empty(); + flags.set(Self::EXPLICIT_TYPES, value.explicit_types); + flags + } +} + +#[derive(Default, serde::Deserialize)] +pub struct FragmentModule { + pub path: String, + pub entry_point: String, +} + +#[derive(Default, serde::Deserialize)] +#[serde(default)] +pub struct Parameters { + // -- GOD MODE -- + pub god_mode: bool, + + // -- wgsl-in options -- + #[serde(rename = "wgsl-in")] + pub wgsl_in: WgslInParameters, + + // -- spirv-in options -- + #[serde(rename = "spv-in")] + pub spv_in: SpirvInParameters, + + // -- SPIR-V options -- + pub spv: SpirvOutParameters, + + /// Defaults to [`Targets::non_wgsl_default()`] for `spv` and `glsl` snapshots, + /// and [`Targets::wgsl_default()`] for `wgsl` snapshots. + pub targets: Option, + + // -- MSL options -- + pub msl: naga::back::msl::Options, + #[serde(default)] + pub msl_pipeline: naga::back::msl::PipelineOptions, + + // -- GLSL options -- + pub glsl: naga::back::glsl::Options, + pub glsl_exclude_list: naga::FastHashSet, + pub glsl_multiview: Option, + + // -- HLSL options -- + pub hlsl: naga::back::hlsl::Options, + + // -- WGSL options -- + pub wgsl: WgslOutParameters, + + // -- General options -- + + // Allow backends to be aware of the fragment module. + // Is the name of a WGSL file in the same directory as the test file. + pub fragment_module: Option, + + pub bounds_check_policies: naga::proc::BoundsCheckPolicies, + pub pipeline_constants: naga::back::PipelineConstants, +} + +/// Information about a shader input file. +#[derive(Debug)] +pub struct Input { + /// The subdirectory of `tests/in` to which this input belongs, if any. + /// + /// If the subdirectory is omitted, we assume that the output goes + /// to "wgsl". + pub subdirectory: PathBuf, + + /// The input filename name, without a directory. + pub file_name: PathBuf, + + /// True if output filenames should add the output extension on top of + /// `file_name`'s existing extension, rather than replacing it. + /// + /// This is used by `convert_snapshots_glsl`, which wants to take input files + /// like `210-bevy-2d-shader.frag` and just add `.wgsl` to it, producing + /// `210-bevy-2d-shader.frag.wgsl`. + pub keep_input_extension: bool, +} + +impl Input { + /// Read an input file and its corresponding parameters file. + /// + /// Given `input`, the relative path of a shader input file, return + /// a `Source` value containing its path, code, and parameters. + /// + /// The `input` path is interpreted relative to the `BASE_DIR_IN` + /// subdirectory of the directory given by the `CARGO_MANIFEST_DIR` + /// environment variable. + pub fn new(subdirectory: &str, name: &str, extension: &str) -> Input { + Input { + subdirectory: PathBuf::from(subdirectory), + // Don't wipe out any extensions on `name`, as + // `with_extension` would do. + file_name: PathBuf::from(format!("{name}.{extension}")), + keep_input_extension: false, + } + } + + /// Return an iterator that produces an `Input` for each entry in `subdirectory`. + pub fn files_in_dir<'a>( + subdirectory: &'a str, + file_extensions: &'a [&'a str], + dir_in: &str, + ) -> impl Iterator + 'a { + let input_directory = Path::new(dir_in).join(subdirectory); + + let entries = match std::fs::read_dir(&input_directory) { + Ok(entries) => entries, + Err(err) => panic!( + "Error opening directory '{}': {}", + input_directory.display(), + err + ), + }; + + entries.filter_map(move |result| { + let entry = result.expect("error reading directory"); + if !entry.file_type().unwrap().is_file() { + return None; + } + + let file_name = PathBuf::from(entry.file_name()); + let extension = file_name + .extension() + .expect("all files in snapshot input directory should have extensions"); + + if !file_extensions.contains(&extension.to_str().unwrap()) { + return None; + } + + if let Ok(pat) = std::env::var("NAGA_SNAPSHOT") { + if !file_name.to_string_lossy().contains(&pat) { + return None; + } + } + + let input = Input::new( + subdirectory, + file_name.file_stem().unwrap().to_str().unwrap(), + extension.to_str().unwrap(), + ); + Some(input) + }) + } + + /// Return the path to the input directory. + pub fn input_directory(&self, dir_in: &str) -> PathBuf { + Path::new(dir_in).join(&self.subdirectory) + } + + /// Return the path to the output directory. + pub fn output_directory(subdirectory: &str, dir_out: &str) -> PathBuf { + Path::new(dir_out).join(subdirectory) + } + + /// Return the path to the input file. + pub fn input_path(&self, dir_in: &str) -> PathBuf { + let mut input = self.input_directory(dir_in); + input.push(&self.file_name); + input + } + + pub fn output_path(&self, subdirectory: &str, extension: &str, dir_out: &str) -> PathBuf { + let mut output = Self::output_directory(subdirectory, dir_out); + if self.keep_input_extension { + let file_name = format!( + "{}-{}.{}", + self.subdirectory.display(), + self.file_name.display(), + extension + ); + + output.push(&file_name); + } else { + let file_name = format!( + "{}-{}", + self.subdirectory.display(), + self.file_name.display() + ); + + output.push(&file_name); + output.set_extension(extension); + } + output + } + + /// Return the contents of the input file as a string. + pub fn read_source(&self, dir_in: &str, print: bool) -> String { + if print { + println!("Processing '{}'", self.file_name.display()); + } + let input_path = self.input_path(dir_in); + match fs::read_to_string(&input_path) { + Ok(source) => source, + Err(err) => { + panic!( + "Couldn't read shader input file `{}`: {}", + input_path.display(), + err + ); + } + } + } + + /// Return the contents of the input file as a vector of bytes. + pub fn read_bytes(&self, dir_in: &str, print: bool) -> Vec { + if print { + println!("Processing '{}'", self.file_name.display()); + } + let input_path = self.input_path(dir_in); + match fs::read(&input_path) { + Ok(bytes) => bytes, + Err(err) => { + panic!( + "Couldn't read shader input file `{}`: {}", + input_path.display(), + err + ); + } + } + } + + pub fn bytes(&self, dir_in: &str) -> u64 { + let input_path = self.input_path(dir_in); + std::fs::metadata(input_path).unwrap().len() + } + + /// Return this input's parameter file, parsed. + pub fn read_parameters(&self, dir_in: &str) -> Parameters { + let mut param_path = self.input_path(dir_in); + param_path.set_extension("toml"); + let mut params = match fs::read_to_string(¶m_path) { + Ok(string) => match toml::de::from_str(&string) { + Ok(params) => params, + Err(e) => panic!( + "Couldn't parse param file: {} due to: {e}", + param_path.display() + ), + }, + Err(_) => Parameters::default(), + }; + + if params.targets.is_none() { + match self + .input_path(dir_in) + .extension() + .unwrap() + .to_str() + .unwrap() + { + "wgsl" => params.targets = Some(Targets::wgsl_default()), + "spvasm" => params.targets = Some(Targets::non_wgsl_default()), + "vert" | "frag" | "comp" => params.targets = Some(Targets::non_wgsl_default()), + e => { + panic!("Unknown extension: {e}"); + } + } + } + + params + } + + /// Write `data` to a file corresponding to this input file in + /// `subdirectory`, with `extension`. + pub fn write_output_file( + &self, + subdirectory: &str, + extension: &str, + data: impl AsRef<[u8]>, + dir_out: &str, + ) { + let output_path = self.output_path(subdirectory, extension, dir_out); + fs::create_dir_all(output_path.parent().unwrap()).unwrap(); + if let Err(err) = fs::write(&output_path, data) { + panic!("Error writing {}: {}", output_path.display(), err); + } + } +} diff --git a/naga/Cargo.toml b/naga/Cargo.toml index 02eda4c198a..0b139f54dcc 100644 --- a/naga/Cargo.toml +++ b/naga/Cargo.toml @@ -113,12 +113,17 @@ env_logger.workspace = true hashbrown = { workspace = true, features = ["serde"] } hlsl-snapshots.workspace = true itertools.workspace = true +naga-test.workspace = true ron.workspace = true rspirv.workspace = true +# So we don't actually need this, however if we remove this, it +# brakes calling `--features spirv` at the workspace level. I think +# this is because there is a `dep:spirv` in the regular feature set, +# so cargo tries to match the feature against that, fails as it's a optional dep, +# and then refuses to build instead of ignoring it. +spirv.workspace = true serde = { workspace = true, features = ["default", "derive"] } -spirv = { workspace = true, features = ["deserialize"] } strum = { workspace = true } -toml.workspace = true walkdir.workspace = true [lints.clippy] diff --git a/naga/src/back/spv/writer.rs b/naga/src/back/spv/writer.rs index 48d13f03c25..eb414219492 100644 --- a/naga/src/back/spv/writer.rs +++ b/naga/src/back/spv/writer.rs @@ -99,6 +99,24 @@ impl Writer { }) } + pub fn set_options(&mut self, options: &Options) -> Result<(), Error> { + let (major, minor) = options.lang_version; + if major != 1 { + return Err(Error::UnsupportedVersion(major, minor)); + } + self.physical_layout = PhysicalLayout::new(major, minor); + self.capabilities_available = options.capabilities.clone(); + self.flags = options.flags; + self.bounds_check_policies = options.bounds_check_policies; + self.zero_initialize_workgroup_memory = options.zero_initialize_workgroup_memory; + self.force_loop_bounding = options.force_loop_bounding; + self.use_storage_input_output_16 = options.use_storage_input_output_16; + self.binding_map = options.binding_map.clone(); + self.io_f16_polyfills = + super::f16_polyfill::F16IoPolyfill::new(options.use_storage_input_output_16); + Ok(()) + } + /// Returns `(major, minor)` of the SPIR-V language version. pub const fn lang_version(&self) -> (u8, u8) { self.physical_layout.lang_version() diff --git a/naga/src/front/wgsl/mod.rs b/naga/src/front/wgsl/mod.rs index b7ae910a8dd..2c3387e9cdd 100644 --- a/naga/src/front/wgsl/mod.rs +++ b/naga/src/front/wgsl/mod.rs @@ -50,6 +50,9 @@ impl Frontend { options, } } + pub fn set_options(&mut self, options: Options) { + self.options = options; + } pub fn parse(&mut self, source: &str) -> core::result::Result { self.inner(source).map_err(|x| x.as_parse_error(source)) diff --git a/naga/tests/naga/snapshots.rs b/naga/tests/naga/snapshots.rs index f08ca3b0f65..e2d9402813f 100644 --- a/naga/tests/naga/snapshots.rs +++ b/naga/tests/naga/snapshots.rs @@ -1,407 +1,12 @@ -// A lot of the code can be unused based on configuration flags, -// the corresponding warnings aren't helpful. -#![allow(dead_code, unused_imports)] - -use core::fmt::Write; - -use std::{ - fs, - path::{Path, PathBuf}, -}; - use naga::compact::KeepUnused; -use ron::de; - -const CRATE_ROOT: &str = env!("CARGO_MANIFEST_DIR"); -const BASE_DIR_IN: &str = "tests/in"; -const BASE_DIR_OUT: &str = "tests/out"; - -bitflags::bitflags! { - #[derive(Clone, Copy, serde::Deserialize)] - #[serde(transparent)] - #[derive(Debug, Eq, PartialEq)] - struct Targets: u32 { - /// A serialization of the `naga::Module`, in RON format. - const IR = 1; - - /// A serialization of the `naga::valid::ModuleInfo`, in RON format. - const ANALYSIS = 1 << 1; - - const SPIRV = 1 << 2; - const METAL = 1 << 3; - const GLSL = 1 << 4; - const DOT = 1 << 5; - const HLSL = 1 << 6; - const WGSL = 1 << 7; - const NO_VALIDATION = 1 << 8; - } -} - -impl Targets { - /// Defaults for `spv` and `glsl` snapshots. - fn non_wgsl_default() -> Self { - Targets::WGSL - } - - /// Defaults for `wgsl` snapshots. - fn wgsl_default() -> Self { - Targets::HLSL | Targets::SPIRV | Targets::GLSL | Targets::METAL | Targets::WGSL - } -} - -#[derive(serde::Deserialize)] -struct SpvOutVersion(u8, u8); -impl Default for SpvOutVersion { - fn default() -> Self { - SpvOutVersion(1, 1) - } -} - -#[cfg(all(feature = "deserialize", spv_out))] -#[derive(serde::Deserialize)] -struct BindingMapSerialization { - resource_binding: naga::ResourceBinding, - bind_target: naga::back::spv::BindingInfo, -} - -#[cfg(all(feature = "deserialize", spv_out))] -fn deserialize_binding_map<'de, D>(deserializer: D) -> Result -where - D: serde::Deserializer<'de>, -{ - use serde::Deserialize; - - let vec = Vec::::deserialize(deserializer)?; - let mut map = naga::back::spv::BindingMap::default(); - for item in vec { - map.insert(item.resource_binding, item.bind_target); - } - Ok(map) -} - -#[derive(Default, serde::Deserialize)] -#[serde(default)] -struct WgslInParameters { - parse_doc_comments: bool, -} - -#[derive(Default, serde::Deserialize)] -#[serde(default)] -struct SpirvInParameters { - adjust_coordinate_space: bool, -} - -#[derive(serde::Deserialize)] -#[serde(default)] -struct SpirvOutParameters { - version: SpvOutVersion, - capabilities: naga::FastHashSet, - debug: bool, - adjust_coordinate_space: bool, - force_point_size: bool, - clamp_frag_depth: bool, - separate_entry_points: bool, - use_storage_input_output_16: bool, - #[cfg(all(feature = "deserialize", spv_out))] - #[serde(deserialize_with = "deserialize_binding_map")] - binding_map: naga::back::spv::BindingMap, -} - -impl Default for SpirvOutParameters { - fn default() -> Self { - Self { - version: SpvOutVersion::default(), - capabilities: naga::FastHashSet::default(), - debug: false, - adjust_coordinate_space: false, - force_point_size: false, - clamp_frag_depth: false, - separate_entry_points: false, - use_storage_input_output_16: true, - #[cfg(all(feature = "deserialize", spv_out))] - binding_map: naga::back::spv::BindingMap::default(), - } - } -} - -#[derive(Default, serde::Deserialize)] -#[serde(default)] -struct WgslOutParameters { - explicit_types: bool, -} - -#[derive(Default, serde::Deserialize)] -struct FragmentModule { - path: String, - entry_point: String, -} - -#[derive(Default, serde::Deserialize)] -#[serde(default)] -struct Parameters { - // -- GOD MODE -- - god_mode: bool, - - // -- wgsl-in options -- - #[serde(rename = "wgsl-in")] - wgsl_in: WgslInParameters, - - // -- spirv-in options -- - #[serde(rename = "spv-in")] - spv_in: SpirvInParameters, - - // -- SPIR-V options -- - spv: SpirvOutParameters, - - /// Defaults to [`Targets::non_wgsl_default()`] for `spv` and `glsl` snapshots, - /// and [`Targets::wgsl_default()`] for `wgsl` snapshots. - targets: Option, - - // -- MSL options -- - #[cfg(all(feature = "deserialize", msl_out))] - msl: naga::back::msl::Options, - #[cfg(all(feature = "deserialize", msl_out))] - #[serde(default)] - msl_pipeline: naga::back::msl::PipelineOptions, +use naga_test::*; - // -- GLSL options -- - #[cfg(all(feature = "deserialize", glsl_out))] - glsl: naga::back::glsl::Options, - glsl_exclude_list: naga::FastHashSet, - #[cfg(all(feature = "deserialize", glsl_out))] - glsl_multiview: Option, - - // -- HLSL options -- - #[cfg(all(feature = "deserialize", hlsl_out))] - hlsl: naga::back::hlsl::Options, - - // -- WGSL options -- - wgsl: WgslOutParameters, - - // -- General options -- - - // Allow backends to be aware of the fragment module. - // Is the name of a WGSL file in the same directory as the test file. - fragment_module: Option, - - #[cfg(feature = "deserialize")] - bounds_check_policies: naga::proc::BoundsCheckPolicies, - - #[cfg(all(feature = "deserialize", any(hlsl_out, msl_out, spv_out, glsl_out)))] - pipeline_constants: naga::back::PipelineConstants, -} - -/// Information about a shader input file. -#[derive(Debug)] -struct Input { - /// The subdirectory of `tests/in` to which this input belongs, if any. - /// - /// If the subdirectory is omitted, we assume that the output goes - /// to "wgsl". - subdirectory: PathBuf, - - /// The input filename name, without a directory. - file_name: PathBuf, - - /// True if output filenames should add the output extension on top of - /// `file_name`'s existing extension, rather than replacing it. - /// - /// This is used by `convert_snapshots_glsl`, which wants to take input files - /// like `210-bevy-2d-shader.frag` and just add `.wgsl` to it, producing - /// `210-bevy-2d-shader.frag.wgsl`. - keep_input_extension: bool, -} - -impl Input { - /// Read an input file and its corresponding parameters file. - /// - /// Given `input`, the relative path of a shader input file, return - /// a `Source` value containing its path, code, and parameters. - /// - /// The `input` path is interpreted relative to the `BASE_DIR_IN` - /// subdirectory of the directory given by the `CARGO_MANIFEST_DIR` - /// environment variable. - fn new(subdirectory: &str, name: &str, extension: &str) -> Input { - Input { - subdirectory: PathBuf::from(subdirectory), - // Don't wipe out any extensions on `name`, as - // `with_extension` would do. - file_name: PathBuf::from(format!("{name}.{extension}")), - keep_input_extension: false, - } - } - - /// Return an iterator that produces an `Input` for each entry in `subdirectory`. - fn files_in_dir( - subdirectory: &'static str, - file_extensions: &'static [&'static str], - ) -> impl Iterator + 'static { - let input_directory = Path::new(CRATE_ROOT).join(BASE_DIR_IN).join(subdirectory); - - let entries = match std::fs::read_dir(&input_directory) { - Ok(entries) => entries, - Err(err) => panic!( - "Error opening directory '{}': {}", - input_directory.display(), - err - ), - }; - - entries.filter_map(move |result| { - let entry = result.expect("error reading directory"); - if !entry.file_type().unwrap().is_file() { - return None; - } - - let file_name = PathBuf::from(entry.file_name()); - let extension = file_name - .extension() - .expect("all files in snapshot input directory should have extensions"); - - if !file_extensions.contains(&extension.to_str().unwrap()) { - return None; - } - - if let Ok(pat) = std::env::var("NAGA_SNAPSHOT") { - if !file_name.to_string_lossy().contains(&pat) { - return None; - } - } - - let input = Input::new( - subdirectory, - file_name.file_stem().unwrap().to_str().unwrap(), - extension.to_str().unwrap(), - ); - Some(input) - }) - } - - /// Return the path to the input directory. - fn input_directory(&self) -> PathBuf { - let mut dir = Path::new(CRATE_ROOT).join(BASE_DIR_IN); - dir.push(&self.subdirectory); - dir - } - - /// Return the path to the output directory. - fn output_directory(subdirectory: &str) -> PathBuf { - let mut dir = Path::new(CRATE_ROOT).join(BASE_DIR_OUT); - dir.push(subdirectory); - dir - } - - /// Return the path to the input file. - fn input_path(&self) -> PathBuf { - let mut input = self.input_directory(); - input.push(&self.file_name); - input - } - - fn output_path(&self, subdirectory: &str, extension: &str) -> PathBuf { - let mut output = Self::output_directory(subdirectory); - if self.keep_input_extension { - let file_name = format!( - "{}-{}.{}", - self.subdirectory.display(), - self.file_name.display(), - extension - ); - - output.push(&file_name); - } else { - let file_name = format!( - "{}-{}", - self.subdirectory.display(), - self.file_name.display() - ); - - output.push(&file_name); - output.set_extension(extension); - } - output - } - - /// Return the contents of the input file as a string. - fn read_source(&self) -> String { - println!("Processing '{}'", self.file_name.display()); - let input_path = self.input_path(); - match fs::read_to_string(&input_path) { - Ok(source) => source, - Err(err) => { - panic!( - "Couldn't read shader input file `{}`: {}", - input_path.display(), - err - ); - } - } - } - - /// Return the contents of the input file as a vector of bytes. - fn read_bytes(&self) -> Vec { - println!("Processing '{}'", self.file_name.display()); - let input_path = self.input_path(); - match fs::read(&input_path) { - Ok(bytes) => bytes, - Err(err) => { - panic!( - "Couldn't read shader input file `{}`: {}", - input_path.display(), - err - ); - } - } - } - - /// Return this input's parameter file, parsed. - fn read_parameters(&self) -> Parameters { - let mut param_path = self.input_path(); - param_path.set_extension("toml"); - let mut params = match fs::read_to_string(¶m_path) { - Ok(string) => match toml::de::from_str(&string) { - Ok(params) => params, - Err(e) => panic!( - "Couldn't parse param file: {} due to: {e}", - param_path.display() - ), - }, - Err(_) => Parameters::default(), - }; - - if params.targets.is_none() { - match self.input_path().extension().unwrap().to_str().unwrap() { - "wgsl" => params.targets = Some(Targets::wgsl_default()), - "spvasm" => params.targets = Some(Targets::non_wgsl_default()), - "vert" | "frag" | "comp" => params.targets = Some(Targets::non_wgsl_default()), - e => { - panic!("Unknown extension: {e}"); - } - } - } - - params - } - - /// Write `data` to a file corresponding to this input file in - /// `subdirectory`, with `extension`. - fn write_output_file(&self, subdirectory: &str, extension: &str, data: impl AsRef<[u8]>) { - let output_path = self.output_path(subdirectory, extension); - fs::create_dir_all(output_path.parent().unwrap()).unwrap(); - if let Err(err) = fs::write(&output_path, data) { - panic!("Error writing {}: {}", output_path.display(), err); - } - } -} - -#[cfg(hlsl_out)] -type FragmentEntryPoint<'a> = naga::back::hlsl::FragmentEntryPoint<'a>; -#[cfg(not(hlsl_out))] -type FragmentEntryPoint<'a> = (); +const DIR_IN: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/tests/in"); +const DIR_OUT: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/tests/out"); #[allow(unused_variables)] fn check_targets(input: &Input, module: &mut naga::Module, source_code: Option<&str>) { - let params = input.read_parameters(); + let params = input.read_parameters(DIR_IN); let name = &input.file_name; let targets = params.targets.unwrap(); @@ -420,12 +25,11 @@ fn check_targets(input: &Input, module: &mut naga::Module, source_code: Option<& ) }; - #[cfg(feature = "serialize")] { if targets.contains(Targets::IR) { let config = ron::ser::PrettyConfig::default().new_line("\n".to_string()); let string = ron::ser::to_string_pretty(module, config).unwrap(); - input.write_output_file("ir", "ron", string); + input.write_output_file("ir", "ron", string, DIR_OUT); } } @@ -456,12 +60,11 @@ fn check_targets(input: &Input, module: &mut naga::Module, source_code: Option<& // snapshots makes the output independent of unused arena entries. naga::compact::compact(module, KeepUnused::No); - #[cfg(feature = "serialize")] { if targets.contains(Targets::IR) { let config = ron::ser::PrettyConfig::default().new_line("\n".to_string()); let string = ron::ser::to_string_pretty(module, config).unwrap(); - input.write_output_file("ir", "compact.ron", string); + input.write_output_file("ir", "compact.ron", string, DIR_OUT); } } @@ -478,130 +81,112 @@ fn check_targets(input: &Input, module: &mut naga::Module, source_code: Option<& }) }; - #[cfg(feature = "serialize")] { if targets.contains(Targets::ANALYSIS) { let config = ron::ser::PrettyConfig::default().new_line("\n".to_string()); let string = ron::ser::to_string_pretty(&info, config).unwrap(); - input.write_output_file("analysis", "info.ron", string); + input.write_output_file("analysis", "info.ron", string, DIR_OUT); } } - #[cfg(all(feature = "deserialize", spv_out))] - { - if targets.contains(Targets::SPIRV) { - let mut debug_info = None; - if let Some(source_code) = source_code { - debug_info = Some(naga::back::spv::DebugInfo { - source_code, - file_name: name.as_path().into(), - // wgpu#6266: we technically know all the information here to - // produce the valid language but it's not too important for - // validation purposes - language: naga::back::spv::SourceLanguage::Unknown, - }) - } - - write_output_spv( - input, - module, - &info, - debug_info, - ¶ms.spv, - params.bounds_check_policies, - ¶ms.pipeline_constants, - ); + if targets.contains(Targets::SPIRV) { + let mut debug_info = None; + if let Some(source_code) = source_code { + debug_info = Some(naga::back::spv::DebugInfo { + source_code, + file_name: name.as_path().into(), + // wgpu#6266: we technically know all the information here to + // produce the valid language but it's not too important for + // validation purposes + language: naga::back::spv::SourceLanguage::Unknown, + }) } + + write_output_spv( + input, + module, + &info, + debug_info, + ¶ms.spv, + params.bounds_check_policies, + ¶ms.pipeline_constants, + ); } - #[cfg(all(feature = "deserialize", msl_out))] - { - if targets.contains(Targets::METAL) { - write_output_msl( + + if targets.contains(Targets::METAL) { + write_output_msl( + input, + module, + &info, + ¶ms.msl, + ¶ms.msl_pipeline, + params.bounds_check_policies, + ¶ms.pipeline_constants, + ); + } + + if targets.contains(Targets::GLSL) { + for ep in module.entry_points.iter() { + if params.glsl_exclude_list.contains(&ep.name) { + continue; + } + write_output_glsl( input, module, &info, - ¶ms.msl, - ¶ms.msl_pipeline, + ep.stage, + &ep.name, + ¶ms.glsl, params.bounds_check_policies, + params.glsl_multiview, ¶ms.pipeline_constants, ); } } - #[cfg(all(feature = "deserialize", glsl_out))] - { - if targets.contains(Targets::GLSL) { - for ep in module.entry_points.iter() { - if params.glsl_exclude_list.contains(&ep.name) { - continue; - } - write_output_glsl( - input, - module, - &info, - ep.stage, - &ep.name, - ¶ms.glsl, - params.bounds_check_policies, - params.glsl_multiview, - ¶ms.pipeline_constants, - ); - } - } - } - #[cfg(dot_out)] - { - if targets.contains(Targets::DOT) { - let string = naga::back::dot::write(module, Some(&info), Default::default()).unwrap(); - input.write_output_file("dot", "dot", string); - } + + if targets.contains(Targets::DOT) { + let string = naga::back::dot::write(module, Some(&info), Default::default()).unwrap(); + input.write_output_file("dot", "dot", string, DIR_OUT); } - #[cfg(all(feature = "deserialize", hlsl_out))] - { - if targets.contains(Targets::HLSL) { - let frag_module; - let mut frag_ep = None; - if let Some(ref module_spec) = params.fragment_module { - let full_path = input.input_directory().join(&module_spec.path); - - assert_eq!( - full_path.extension().unwrap().to_string_lossy(), - "wgsl", - "Currently all fragment modules must be in WGSL" - ); - - let frag_src = fs::read_to_string(full_path).unwrap(); - - frag_module = naga::front::wgsl::parse_str(&frag_src) - .expect("Failed to parse fragment module"); - - frag_ep = Some( - naga::back::hlsl::FragmentEntryPoint::new( - &frag_module, - &module_spec.entry_point, - ) - .expect("Could not find fragment entry point"), - ); - } - write_output_hlsl( - input, - module, - &info, - ¶ms.hlsl, - ¶ms.pipeline_constants, - frag_ep, + if targets.contains(Targets::HLSL) { + let frag_module; + let mut frag_ep = None; + if let Some(ref module_spec) = params.fragment_module { + let full_path = input.input_directory(DIR_IN).join(&module_spec.path); + + assert_eq!( + full_path.extension().unwrap().to_string_lossy(), + "wgsl", + "Currently all fragment modules must be in WGSL" + ); + + let frag_src = std::fs::read_to_string(full_path).unwrap(); + + frag_module = + naga::front::wgsl::parse_str(&frag_src).expect("Failed to parse fragment module"); + + frag_ep = Some( + naga::back::hlsl::FragmentEntryPoint::new(&frag_module, &module_spec.entry_point) + .expect("Could not find fragment entry point"), ); } + + write_output_hlsl( + input, + module, + &info, + ¶ms.hlsl, + ¶ms.pipeline_constants, + frag_ep, + ); } - #[cfg(all(feature = "deserialize", wgsl_out))] - { - if targets.contains(Targets::WGSL) { - write_output_wgsl(input, module, &info, ¶ms.wgsl); - } + + if targets.contains(Targets::WGSL) { + write_output_wgsl(input, module, &info, ¶ms.wgsl); } } -#[cfg(spv_out)] fn write_output_spv( input: &Input, module: &naga::Module, @@ -612,32 +197,8 @@ fn write_output_spv( pipeline_constants: &naga::back::PipelineConstants, ) { use naga::back::spv; - use rspirv::binary::Disassemble; - let mut flags = spv::WriterFlags::LABEL_VARYINGS; - flags.set(spv::WriterFlags::DEBUG, params.debug); - flags.set( - spv::WriterFlags::ADJUST_COORDINATE_SPACE, - params.adjust_coordinate_space, - ); - flags.set(spv::WriterFlags::FORCE_POINT_SIZE, params.force_point_size); - flags.set(spv::WriterFlags::CLAMP_FRAG_DEPTH, params.clamp_frag_depth); - - let options = spv::Options { - lang_version: (params.version.0, params.version.1), - flags, - capabilities: if params.capabilities.is_empty() { - None - } else { - Some(params.capabilities.clone()) - }, - bounds_check_policies, - binding_map: params.binding_map.clone(), - zero_initialize_workgroup_memory: spv::ZeroInitializeWorkgroupMemoryMode::Polyfill, - force_loop_bounding: true, - use_storage_input_output_16: params.use_storage_input_output_16, - debug_info, - }; + let options = params.to_options(bounds_check_policies, debug_info); let (module, info) = naga::back::pipeline_constants::process_overrides(module, info, None, pipeline_constants) @@ -663,7 +224,6 @@ fn write_output_spv( } } -#[cfg(spv_out)] fn write_output_spv_inner( input: &Input, module: &naga::Module, @@ -686,10 +246,9 @@ fn write_output_spv_inner( } else { dis }; - input.write_output_file("spv", extension, dis); + input.write_output_file("spv", extension, dis, DIR_OUT); } -#[cfg(msl_out)] fn write_output_msl( input: &Input, module: &naga::Module, @@ -718,10 +277,9 @@ fn write_output_msl( } } - input.write_output_file("msl", "msl", string); + input.write_output_file("msl", "msl", string, DIR_OUT); } -#[cfg(glsl_out)] #[allow(clippy::too_many_arguments)] fn write_output_glsl( input: &Input, @@ -760,10 +318,9 @@ fn write_output_glsl( writer.write().expect("GLSL write failed"); let extension = format!("{ep_name}.{stage:?}.glsl"); - input.write_output_file("glsl", &extension, buffer); + input.write_output_file("glsl", &extension, buffer, DIR_OUT); } -#[cfg(hlsl_out)] fn write_output_hlsl( input: &Input, module: &naga::Module, @@ -772,7 +329,6 @@ fn write_output_hlsl( pipeline_constants: &naga::back::PipelineConstants, frag_ep: Option, ) { - use core::fmt::Write as _; use naga::back::hlsl; println!("generating HLSL"); @@ -788,7 +344,7 @@ fn write_output_hlsl( .write(&module, &info, frag_ep.as_ref()) .expect("HLSL write failed"); - input.write_output_file("hlsl", "hlsl", buffer); + input.write_output_file("hlsl", "hlsl", buffer, DIR_OUT); // We need a config file for validation script // This file contains an info about profiles (shader stages) contains inside generated shader @@ -815,10 +371,11 @@ fn write_output_hlsl( }); } - config.to_file(input.output_path("hlsl", "ron")).unwrap(); + config + .to_file(input.output_path("hlsl", "ron", DIR_OUT)) + .unwrap(); } -#[cfg(wgsl_out)] fn write_output_wgsl( input: &Input, module: &naga::Module, @@ -829,44 +386,37 @@ fn write_output_wgsl( println!("generating WGSL"); - let mut flags = wgsl::WriterFlags::empty(); - flags.set(wgsl::WriterFlags::EXPLICIT_TYPES, params.explicit_types); + let string = wgsl::write_string(module, info, params.into()).expect("WGSL write failed"); - let string = wgsl::write_string(module, info, flags).expect("WGSL write failed"); - - input.write_output_file("wgsl", "wgsl", string); + input.write_output_file("wgsl", "wgsl", string, DIR_OUT); } // While we _can_ run this test under miri, it is extremely slow (>5 minutes), // and naga isn't the primary target for miri testing, so we disable it. -#[cfg(feature = "wgsl-in")] #[cfg_attr(miri, ignore)] #[test] fn convert_snapshots_wgsl() { let _ = env_logger::try_init(); - for input in Input::files_in_dir("wgsl", &["wgsl"]) { - let source = input.read_source(); + for input in Input::files_in_dir("wgsl", &["wgsl"], DIR_IN) { + let source = input.read_source(DIR_IN, true); // crlf will make the large split output different on different platform let source = source.replace('\r', ""); - let params = input.read_parameters(); - let WgslInParameters { parse_doc_comments } = params.wgsl_in; + let params = input.read_parameters(DIR_IN); - let options = naga::front::wgsl::Options { parse_doc_comments }; - let mut frontend = naga::front::wgsl::Frontend::new_with_options(options); + let mut frontend = naga::front::wgsl::Frontend::new_with_options((¶ms.wgsl_in).into()); match frontend.parse(&source) { Ok(mut module) => check_targets(&input, &mut module, Some(&source)), Err(e) => panic!( "{}", - e.emit_to_string_with_path(&source, input.input_path()) + e.emit_to_string_with_path(&source, input.input_path(DIR_IN)) ), } } } // miri doesn't allow us to shell out to `spirv-as` -#[cfg(feature = "spv-in")] #[cfg_attr(miri, ignore)] #[test] fn convert_snapshots_spv() { @@ -874,11 +424,11 @@ fn convert_snapshots_spv() { let _ = env_logger::try_init(); - for input in Input::files_in_dir("spv", &["spvasm"]) { + for input in Input::files_in_dir("spv", &["spvasm"], DIR_IN) { println!("Assembling '{}'", input.file_name.display()); let command = Command::new("spirv-as") - .arg(input.input_path()) + .arg(input.input_path(DIR_IN)) .arg("-o") .arg("-") .output() @@ -897,20 +447,10 @@ fn convert_snapshots_spv() { ); } - let params = input.read_parameters(); - let SpirvInParameters { - adjust_coordinate_space, - } = params.spv_in; - - let mut module = naga::front::spv::parse_u8_slice( - &command.stdout, - &naga::front::spv::Options { - adjust_coordinate_space, - strict_capabilities: true, - ..Default::default() - }, - ) - .unwrap(); + let params = input.read_parameters(DIR_IN); + + let mut module = + naga::front::spv::parse_u8_slice(&command.stdout, &(¶ms.spv_in).into()).unwrap(); check_targets(&input, &mut module, None); } @@ -918,14 +458,13 @@ fn convert_snapshots_spv() { // While we _can_ run this test under miri, it is extremely slow (>5 minutes), // and naga isn't the primary target for miri testing, so we disable it. -#[cfg(feature = "glsl-in")] #[cfg_attr(miri, ignore)] #[allow(unused_variables)] #[test] fn convert_snapshots_glsl() { let _ = env_logger::try_init(); - for input in Input::files_in_dir("glsl", &["vert", "frag", "comp"]) { + for input in Input::files_in_dir("glsl", &["vert", "frag", "comp"], DIR_IN) { let input = Input { keep_input_extension: true, ..input @@ -946,7 +485,7 @@ fn convert_snapshots_glsl() { stage, defines: Default::default(), }, - &input.read_source(), + &input.read_source(DIR_IN, true), ) .unwrap(); diff --git a/naga/tests/naga/spirv_capabilities.rs b/naga/tests/naga/spirv_capabilities.rs index 6d0e8153b81..3ac0efa2407 100644 --- a/naga/tests/naga/spirv_capabilities.rs +++ b/naga/tests/naga/spirv_capabilities.rs @@ -6,7 +6,6 @@ Test SPIR-V backend capability checks. use spirv::Capability as Ca; -#[cfg(spv_out)] use rspirv::binary::Disassemble; fn capabilities_used(source: &str) -> naga::FastIndexSet { @@ -276,7 +275,6 @@ fn f16_io_capabilities() { assert!(caps_polyfill.contains(&Ca::Float16)); } -#[cfg(spv_out)] #[test] fn f16_io_polyfill_codegen() { let source = r#" diff --git a/naga/tests/naga/validation.rs b/naga/tests/naga/validation.rs index 370919ffc51..7c12e79620f 100644 --- a/naga/tests/naga/validation.rs +++ b/naga/tests/naga/validation.rs @@ -361,7 +361,6 @@ fn builtin_cross_product_args() { assert!(variant(VectorSize::Quad, 2).is_err()); } -#[cfg(feature = "wgsl-in")] #[test] fn incompatible_interpolation_and_sampling_types() { use dummy_interpolation_shader::DummyInterpolationShader; @@ -443,7 +442,6 @@ fn incompatible_interpolation_and_sampling_types() { } } -#[cfg(all(feature = "wgsl-in", feature = "glsl-out"))] #[test] fn no_flat_first_in_glsl() { use dummy_interpolation_shader::DummyInterpolationShader; @@ -484,13 +482,11 @@ fn no_flat_first_in_glsl() { )); } -#[cfg(all(test, feature = "wgsl-in"))] mod dummy_interpolation_shader { pub struct DummyInterpolationShader { pub source: String, pub module: naga::Module, pub interpolate_attr: String, - #[cfg_attr(not(feature = "glsl-out"), expect(dead_code))] pub entry_point: &'static str, } @@ -656,7 +652,6 @@ fn binding_arrays_cannot_hold_scalars() { assert!(t.validator.validate(&t.module).is_err()); } -#[cfg(feature = "wgsl-in")] #[test] fn validation_error_messages() { let cases = [( @@ -693,7 +688,6 @@ error: Function [1] 'main' is invalid } } -#[cfg(feature = "wgsl-in")] #[test] fn bad_texture_dimensions_level() { fn validate(level: &str) -> Result { @@ -790,7 +784,6 @@ fn arity_check() { assert!(validate(Mf::Pow, &[3]).is_err()); } -#[cfg(feature = "wgsl-in")] #[test] fn global_use_scalar() { let source = " @@ -815,7 +808,6 @@ fn main() { ); } -#[cfg(feature = "wgsl-in")] #[test] fn global_use_array() { let source = " @@ -840,7 +832,6 @@ fn main() { ); } -#[cfg(feature = "wgsl-in")] #[test] fn global_use_array_index() { let source = " @@ -865,7 +856,6 @@ fn main() { ); } -#[cfg(feature = "wgsl-in")] #[test] fn global_use_phony() { let source = " @@ -890,7 +880,6 @@ fn main() { ); } -#[cfg(feature = "wgsl-in")] #[test] fn global_use_unreachable() { // We should allow statements after `return`, and such statements should @@ -924,7 +913,6 @@ fn main() { /// Parse and validate the module defined in `source`. /// /// Panics if unsuccessful. -#[cfg(feature = "wgsl-in")] fn parse_validate(source: &str) -> (Module, ModuleInfo) { let module = naga::front::wgsl::parse_str(source).expect("module should parse"); let info = valid::Validator::new(Default::default(), valid::Capabilities::all()) @@ -948,7 +936,6 @@ fn parse_validate(source: &str) -> (Module, ModuleInfo) { /// /// The optional `unused_body` can introduce additional objects to the module, /// to verify that they are adjusted correctly by compaction. -#[cfg(feature = "wgsl-in")] fn override_test(test_case: &str, unused_body: Option<&str>) { use hashbrown::HashMap; use naga::back::pipeline_constants::PipelineConstantError; @@ -1004,7 +991,6 @@ fn unused() { .unwrap(); } -#[cfg(feature = "wgsl-in")] #[test] fn override_in_workgroup_size() { override_test( @@ -1017,7 +1003,6 @@ fn used() { ); } -#[cfg(feature = "wgsl-in")] #[test] fn override_in_workgroup_size_nested() { // Initializer for override used in workgroup size refers to another @@ -1034,7 +1019,6 @@ fn used() { ); } -#[cfg(feature = "wgsl-in")] #[test] fn override_in_function() { override_test( @@ -1052,7 +1036,6 @@ fn used() { ); } -#[cfg(feature = "wgsl-in")] #[test] fn override_in_entrypoint() { override_test( @@ -1070,7 +1053,6 @@ fn used() { ); } -#[cfg(feature = "wgsl-in")] #[test] fn override_in_array_size() { override_test( @@ -1086,7 +1068,6 @@ fn used() { ); } -#[cfg(feature = "wgsl-in")] #[test] fn override_in_global_init() { override_test( @@ -1102,7 +1083,6 @@ fn used() { ); } -#[cfg(feature = "wgsl-in")] #[test] fn override_with_multiple_globals() { // Test that when compaction of the `unused` entrypoint removes `arr1`, the diff --git a/naga/tests/naga/wgsl_errors.rs b/naga/tests/naga/wgsl_errors.rs index 249d77c2215..c1e8421ace1 100644 --- a/naga/tests/naga/wgsl_errors.rs +++ b/naga/tests/naga/wgsl_errors.rs @@ -4098,7 +4098,6 @@ fn invalid_clip_distances() { } } -#[cfg(feature = "wgsl-in")] #[test] fn max_type_size_large_array() { // The total size of an array is not resolved until validation. Type aliases @@ -4114,7 +4113,6 @@ fn max_type_size_large_array() { } } -#[cfg(feature = "wgsl-in")] #[test] fn max_type_size_array_of_arrays() { // If the size of the base type of an array is oversize, the error is raised @@ -4129,7 +4127,6 @@ fn max_type_size_array_of_arrays() { ); } -#[cfg(feature = "wgsl-in")] #[test] fn max_type_size_override_array() { // The validation that occurs after override processing should reject any @@ -4166,7 +4163,6 @@ fn max_type_size_override_array() { )); } -#[cfg(feature = "wgsl-in")] #[test] fn max_type_size_array_in_struct() { // If a struct member is oversize, the error is raised during lowering. @@ -4189,7 +4185,6 @@ fn max_type_size_array_in_struct() { ); } -#[cfg(feature = "wgsl-in")] #[test] fn max_type_size_two_arrays_in_struct() { // The total size of a struct is checked during lowering. For a struct, @@ -4215,7 +4210,6 @@ fn max_type_size_two_arrays_in_struct() { ); } -#[cfg(feature = "wgsl-in")] #[test] fn max_type_size_array_of_structs() { // The total size of an array is not resolved until validation. Type aliases @@ -4236,7 +4230,6 @@ fn max_type_size_array_of_structs() { } } -#[cfg(feature = "wgsl-in")] #[test] fn source_with_control_char() { check( From f4ea8642a5aa46aa2e6fc9e03c9bac62ff5ee4ba Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 10 Sep 2025 21:52:02 -0700 Subject: [PATCH 199/303] docs(CHANGELOG): Update pull request reference (#8208) --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8ab28d7845..8bac70e359f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -223,7 +223,7 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). #### General -- Clarify that subgroup barriers require both the `SUBGROUP` and `SUBGROUP_BARRIER` features / capabilities. By @andyleiserson in TBD. +- Clarify that subgroup barriers require both the `SUBGROUP` and `SUBGROUP_BARRIER` features / capabilities. By @andyleiserson in [#8203](https://github.com/gfx-rs/wgpu/pull/8203). ## v26.0.4 (2025-08-07) From 885845087f2c88491f2d28d75ed33e3d531641f8 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Fri, 29 Aug 2025 17:02:07 -0700 Subject: [PATCH 200/303] Extract the parts of PassState that apply to the base encoder And rename a few things. --- wgpu-core/src/command/compute.rs | 176 +++++++++++++++----------- wgpu-core/src/command/encoder.rs | 30 +++++ wgpu-core/src/command/mod.rs | 1 + wgpu-core/src/command/pass.rs | 88 ++++++------- wgpu-core/src/command/render.rs | 209 ++++++++++++++++--------------- 5 files changed, 288 insertions(+), 216 deletions(-) create mode 100644 wgpu-core/src/command/encoder.rs diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index 0d8aaf27eb2..52f8e09cfcb 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -8,7 +8,8 @@ use alloc::{borrow::Cow, boxed::Box, sync::Arc, vec::Vec}; use core::{fmt, str}; use crate::command::{ - pass, CommandEncoder, DebugGroupError, EncoderStateError, PassStateError, TimestampWritesError, + encoder::EncodingState, pass, CommandEncoder, DebugGroupError, EncoderStateError, + PassStateError, TimestampWritesError, }; use crate::resource::DestroyedResourceError; use crate::{binding_model::BindError, resource::RawResourceAccess}; @@ -256,7 +257,7 @@ impl WebGpuError for ComputePassError { struct State<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { pipeline: Option>, - general: pass::BaseState<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder>, + pass: pass::PassState<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder>, active_query: Option<(Arc, u32)>, @@ -270,8 +271,8 @@ impl<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { fn is_ready(&self) -> Result<(), DispatchError> { if let Some(pipeline) = self.pipeline.as_ref() { - self.general.binder.check_compatibility(pipeline.as_ref())?; - self.general.binder.check_late_buffer_bindings()?; + self.pass.binder.check_compatibility(pipeline.as_ref())?; + self.pass.binder.check_late_buffer_bindings()?; Ok(()) } else { Err(DispatchError::MissingPipeline(pass::MissingPipeline)) @@ -284,19 +285,16 @@ impl<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> &mut self, indirect_buffer: Option, ) -> Result<(), ResourceUsageCompatibilityError> { - for bind_group in self.general.binder.list_active() { - unsafe { self.general.scope.merge_bind_group(&bind_group.used)? }; + for bind_group in self.pass.binder.list_active() { + unsafe { self.pass.scope.merge_bind_group(&bind_group.used)? }; // Note: stateless trackers are not merged: the lifetime reference // is held to the bind group itself. } - for bind_group in self.general.binder.list_active() { + for bind_group in self.pass.binder.list_active() { unsafe { self.intermediate_trackers - .set_and_remove_from_usage_scope_sparse( - &mut self.general.scope, - &bind_group.used, - ) + .set_and_remove_from_usage_scope_sparse(&mut self.pass.scope, &bind_group.used) } } @@ -305,15 +303,15 @@ impl<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> self.intermediate_trackers .buffers .set_and_remove_from_usage_scope_sparse( - &mut self.general.scope.buffers, + &mut self.pass.scope.buffers, indirect_buffer, ); } CommandEncoder::drain_barriers( - self.general.raw_encoder, + self.pass.base.raw_encoder, &mut self.intermediate_trackers, - self.general.snatch_guard, + self.pass.base.snatch_guard, ); Ok(()) } @@ -536,27 +534,32 @@ impl Global { .map_pass_err(pass_scope)?; let snatch_guard = device.snatchable_lock.read(); + let mut debug_scope_depth = 0; let mut state = State { pipeline: None, - general: pass::BaseState { - device, - raw_encoder, - tracker: &mut cmd_buf_data.trackers, - buffer_memory_init_actions: &mut cmd_buf_data.buffer_memory_init_actions, - texture_memory_actions: &mut cmd_buf_data.texture_memory_actions, - as_actions: &mut cmd_buf_data.as_actions, + pass: pass::PassState { + base: EncodingState { + device, + raw_encoder, + tracker: &mut cmd_buf_data.trackers, + buffer_memory_init_actions: &mut cmd_buf_data.buffer_memory_init_actions, + texture_memory_actions: &mut cmd_buf_data.texture_memory_actions, + as_actions: &mut cmd_buf_data.as_actions, + indirect_draw_validation_resources: &mut cmd_buf_data + .indirect_draw_validation_resources, + snatch_guard: &snatch_guard, + debug_scope_depth: &mut debug_scope_depth, + }, binder: Binder::new(), temp_offsets: Vec::new(), dynamic_offset_count: 0, pending_discard_init_fixups: SurfacesInDiscardState::new(), - snatch_guard: &snatch_guard, scope: device.new_usage_scope(), - debug_scope_depth: 0, string_offset: 0, }, active_query: None, @@ -566,14 +569,16 @@ impl Global { intermediate_trackers: Tracker::new(), }; - let indices = &state.general.device.tracker_indices; + let indices = &state.pass.base.device.tracker_indices; state - .general + .pass + .base .tracker .buffers .set_size(indices.buffers.size()); state - .general + .pass + .base .tracker .textures .set_size(indices.textures.size()); @@ -584,7 +589,12 @@ impl Global { .same_device_as(cmd_enc.as_ref()) .map_pass_err(pass_scope)?; - let query_set = state.general.tracker.query_sets.insert_single(tw.query_set); + let query_set = state + .pass + .base + .tracker + .query_sets + .insert_single(tw.query_set); // Unlike in render passes we can't delay resetting the query sets since // there is no auxiliary pass. @@ -602,7 +612,8 @@ impl Global { if let Some(range) = range { unsafe { state - .general + .pass + .base .raw_encoder .reset_queries(query_set.raw(), range); } @@ -623,7 +634,7 @@ impl Global { }; unsafe { - state.general.raw_encoder.begin_compute_pass(&hal_desc); + state.pass.base.raw_encoder.begin_compute_pass(&hal_desc); } for command in base.commands.drain(..) { @@ -635,7 +646,7 @@ impl Global { } => { let scope = PassErrorScope::SetBindGroup; pass::set_bind_group::( - &mut state.general, + &mut state.pass, cmd_enc.as_ref(), &base.dynamic_offsets, index, @@ -656,7 +667,7 @@ impl Global { } => { let scope = PassErrorScope::SetPushConstant; pass::set_push_constant::( - &mut state.general, + &mut state.pass, &base.push_constant_data, wgt::ShaderStages::COMPUTE, offset, @@ -683,15 +694,15 @@ impl Global { .map_pass_err(scope)?; } ArcComputeCommand::PushDebugGroup { color: _, len } => { - pass::push_debug_group(&mut state.general, &base.string_data, len); + pass::push_debug_group(&mut state.pass, &base.string_data, len); } ArcComputeCommand::PopDebugGroup => { let scope = PassErrorScope::PopDebugGroup; - pass::pop_debug_group::(&mut state.general) + pass::pop_debug_group::(&mut state.pass) .map_pass_err(scope)?; } ArcComputeCommand::InsertDebugMarker { color: _, len } => { - pass::insert_debug_marker(&mut state.general, &base.string_data, len); + pass::insert_debug_marker(&mut state.pass, &base.string_data, len); } ArcComputeCommand::WriteTimestamp { query_set, @@ -699,7 +710,7 @@ impl Global { } => { let scope = PassErrorScope::WriteTimestamp; pass::write_timestamp::( - &mut state.general, + &mut state.pass, cmd_enc.as_ref(), None, query_set, @@ -714,8 +725,8 @@ impl Global { let scope = PassErrorScope::BeginPipelineStatisticsQuery; validate_and_begin_pipeline_statistics_query( query_set, - state.general.raw_encoder, - &mut state.general.tracker.query_sets, + state.pass.base.raw_encoder, + &mut state.pass.base.tracker.query_sets, cmd_enc.as_ref(), query_index, None, @@ -726,7 +737,7 @@ impl Global { ArcComputeCommand::EndPipelineStatisticsQuery => { let scope = PassErrorScope::EndPipelineStatisticsQuery; end_pipeline_statistics_query( - state.general.raw_encoder, + state.pass.base.raw_encoder, &mut state.active_query, ) .map_pass_err(scope)?; @@ -734,7 +745,7 @@ impl Global { } } - if state.general.debug_scope_depth > 0 { + if *state.pass.base.debug_scope_depth > 0 { Err( ComputePassErrorInner::DebugGroupError(DebugGroupError::MissingPop) .map_pass_err(pass_scope), @@ -742,13 +753,13 @@ impl Global { } unsafe { - state.general.raw_encoder.end_compute_pass(); + state.pass.base.raw_encoder.end_compute_pass(); } let State { - general: - pass::BaseState { - tracker, + pass: + pass::PassState { + base: EncodingState { tracker, .. }, pending_discard_init_fixups, .. }, @@ -799,7 +810,8 @@ fn set_pipeline( state.pipeline = Some(pipeline.clone()); let pipeline = state - .general + .pass + .base .tracker .compute_pipelines .insert_single(pipeline) @@ -807,14 +819,15 @@ fn set_pipeline( unsafe { state - .general + .pass + .base .raw_encoder .set_compute_pipeline(pipeline.raw()); } // Rebind resources pass::rebind_resources::( - &mut state.general, + &mut state.pass, &pipeline.layout, &pipeline.late_sized_buffer_groups, || { @@ -843,7 +856,8 @@ fn dispatch(state: &mut State, groups: [u32; 3]) -> Result<(), ComputePassErrorI state.flush_states(None)?; let groups_size_limit = state - .general + .pass + .base .device .limits .max_compute_workgroups_per_dimension; @@ -861,7 +875,7 @@ fn dispatch(state: &mut State, groups: [u32; 3]) -> Result<(), ComputePassErrorI } unsafe { - state.general.raw_encoder.dispatch(groups); + state.pass.base.raw_encoder.dispatch(groups); } Ok(()) } @@ -877,12 +891,13 @@ fn dispatch_indirect( state.is_ready()?; state - .general + .pass + .base .device .require_downlevel_flags(wgt::DownlevelFlags::INDIRECT_EXECUTION)?; buffer.check_usage(wgt::BufferUsages::INDIRECT)?; - buffer.check_destroyed(state.general.snatch_guard)?; + buffer.check_destroyed(state.pass.base.snatch_guard)?; if offset % 4 != 0 { return Err(ComputePassErrorInner::UnalignedIndirectBufferOffset(offset)); @@ -898,7 +913,7 @@ fn dispatch_indirect( } let stride = 3 * 4; // 3 integers, x/y/z group size - state.general.buffer_memory_init_actions.extend( + state.pass.base.buffer_memory_init_actions.extend( buffer.initialization_status.read().create_action( &buffer, offset..(offset + stride), @@ -906,21 +921,23 @@ fn dispatch_indirect( ), ); - if let Some(ref indirect_validation) = state.general.device.indirect_validation { - let params = - indirect_validation - .dispatch - .params(&state.general.device.limits, offset, buffer.size); + if let Some(ref indirect_validation) = state.pass.base.device.indirect_validation { + let params = indirect_validation.dispatch.params( + &state.pass.base.device.limits, + offset, + buffer.size, + ); unsafe { state - .general + .pass + .base .raw_encoder .set_compute_pipeline(params.pipeline); } unsafe { - state.general.raw_encoder.set_push_constants( + state.pass.base.raw_encoder.set_push_constants( params.pipeline_layout, wgt::ShaderStages::COMPUTE, 0, @@ -929,7 +946,7 @@ fn dispatch_indirect( } unsafe { - state.general.raw_encoder.set_bind_group( + state.pass.base.raw_encoder.set_bind_group( params.pipeline_layout, 0, Some(params.dst_bind_group), @@ -937,13 +954,13 @@ fn dispatch_indirect( ); } unsafe { - state.general.raw_encoder.set_bind_group( + state.pass.base.raw_encoder.set_bind_group( params.pipeline_layout, 1, Some( buffer .indirect_validation_bind_groups - .get(state.general.snatch_guard) + .get(state.pass.base.snatch_guard) .unwrap() .dispatch .as_ref(), @@ -957,17 +974,19 @@ fn dispatch_indirect( .buffers .set_single(&buffer, wgt::BufferUses::STORAGE_READ_ONLY); let src_barrier = src_transition - .map(|transition| transition.into_hal(&buffer, state.general.snatch_guard)); + .map(|transition| transition.into_hal(&buffer, state.pass.base.snatch_guard)); unsafe { state - .general + .pass + .base .raw_encoder .transition_buffers(src_barrier.as_slice()); } unsafe { state - .general + .pass + .base .raw_encoder .transition_buffers(&[hal::BufferBarrier { buffer: params.dst_buffer, @@ -979,7 +998,7 @@ fn dispatch_indirect( } unsafe { - state.general.raw_encoder.dispatch([1, 1, 1]); + state.pass.base.raw_encoder.dispatch([1, 1, 1]); } // reset state @@ -988,14 +1007,15 @@ fn dispatch_indirect( unsafe { state - .general + .pass + .base .raw_encoder .set_compute_pipeline(pipeline.raw()); } if !state.push_constants.is_empty() { unsafe { - state.general.raw_encoder.set_push_constants( + state.pass.base.raw_encoder.set_push_constants( pipeline.layout.raw(), wgt::ShaderStages::COMPUTE, 0, @@ -1004,11 +1024,11 @@ fn dispatch_indirect( } } - for (i, e) in state.general.binder.list_valid() { + for (i, e) in state.pass.binder.list_valid() { let group = e.group.as_ref().unwrap(); - let raw_bg = group.try_raw(state.general.snatch_guard)?; + let raw_bg = group.try_raw(state.pass.base.snatch_guard)?; unsafe { - state.general.raw_encoder.set_bind_group( + state.pass.base.raw_encoder.set_bind_group( pipeline.layout.raw(), i as u32, Some(raw_bg), @@ -1020,7 +1040,8 @@ fn dispatch_indirect( unsafe { state - .general + .pass + .base .raw_encoder .transition_buffers(&[hal::BufferBarrier { buffer: params.dst_buffer, @@ -1034,13 +1055,14 @@ fn dispatch_indirect( state.flush_states(None)?; unsafe { state - .general + .pass + .base .raw_encoder .dispatch_indirect(params.dst_buffer, 0); } } else { state - .general + .pass .scope .buffers .merge_single(&buffer, wgt::BufferUses::INDIRECT)?; @@ -1048,9 +1070,13 @@ fn dispatch_indirect( use crate::resource::Trackable; state.flush_states(Some(buffer.tracker_index()))?; - let buf_raw = buffer.try_raw(state.general.snatch_guard)?; + let buf_raw = buffer.try_raw(state.pass.base.snatch_guard)?; unsafe { - state.general.raw_encoder.dispatch_indirect(buf_raw, offset); + state + .pass + .base + .raw_encoder + .dispatch_indirect(buf_raw, offset); } } diff --git a/wgpu-core/src/command/encoder.rs b/wgpu-core/src/command/encoder.rs new file mode 100644 index 00000000000..4d0455e1892 --- /dev/null +++ b/wgpu-core/src/command/encoder.rs @@ -0,0 +1,30 @@ +use alloc::{sync::Arc, vec::Vec}; + +use crate::{ + command::memory_init::CommandBufferTextureMemoryActions, device::Device, + init_tracker::BufferInitTrackerAction, ray_tracing::AsAction, snatch::SnatchGuard, + track::Tracker, +}; + +/// State applicable when encoding commands onto a compute pass, or onto a +/// render pass, or directly with a command encoder. +pub(crate) struct EncodingState<'snatch_guard, 'cmd_enc, 'raw_encoder> { + pub(crate) device: &'cmd_enc Arc, + + pub(crate) raw_encoder: &'raw_encoder mut dyn hal::DynCommandEncoder, + + pub(crate) tracker: &'cmd_enc mut Tracker, + pub(crate) buffer_memory_init_actions: &'cmd_enc mut Vec, + pub(crate) texture_memory_actions: &'cmd_enc mut CommandBufferTextureMemoryActions, + pub(crate) as_actions: &'cmd_enc mut Vec, + pub(crate) indirect_draw_validation_resources: + &'cmd_enc mut crate::indirect_validation::DrawResources, + + pub(crate) snatch_guard: &'snatch_guard SnatchGuard<'snatch_guard>, + + /// Current debug scope nesting depth. + /// + /// When encoding a compute or render pass, this is the depth of debug + /// scopes in the pass, not the depth of debug scopes in the parent encoder. + pub(crate) debug_scope_depth: &'cmd_enc mut u32, +} diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index c401514c0fc..e16c9fe18a2 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -5,6 +5,7 @@ mod clear; mod compute; mod compute_command; mod draw; +mod encoder; mod memory_init; mod pass; mod query; diff --git a/wgpu-core/src/command/pass.rs b/wgpu-core/src/command/pass.rs index 916f99118e0..52eb15bf082 100644 --- a/wgpu-core/src/command/pass.rs +++ b/wgpu-core/src/command/pass.rs @@ -2,15 +2,14 @@ use crate::binding_model::{BindError, BindGroup, PushConstantUploadError}; use crate::command::bind::Binder; -use crate::command::memory_init::{CommandBufferTextureMemoryActions, SurfacesInDiscardState}; +use crate::command::encoder::EncodingState; +use crate::command::memory_init::SurfacesInDiscardState; use crate::command::{CommandEncoder, DebugGroupError, QueryResetMap, QueryUseError}; -use crate::device::{Device, DeviceError, MissingFeatures}; -use crate::init_tracker::BufferInitTrackerAction; +use crate::device::{DeviceError, MissingFeatures}; use crate::pipeline::LateSizedBufferGroup; use crate::ray_tracing::AsAction; use crate::resource::{DestroyedResourceError, Labeled, ParentDevice, QuerySet}; -use crate::snatch::SnatchGuard; -use crate::track::{ResourceUsageCompatibilityError, Tracker, UsageScope}; +use crate::track::{ResourceUsageCompatibilityError, UsageScope}; use crate::{api_log, binding_model}; use alloc::sync::Arc; use alloc::vec::Vec; @@ -42,15 +41,8 @@ impl WebGpuError for InvalidValuesOffset { } } -pub(crate) struct BaseState<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { - pub(crate) device: &'cmd_enc Arc, - - pub(crate) raw_encoder: &'raw_encoder mut dyn hal::DynCommandEncoder, - - pub(crate) tracker: &'cmd_enc mut Tracker, - pub(crate) buffer_memory_init_actions: &'cmd_enc mut Vec, - pub(crate) texture_memory_actions: &'cmd_enc mut CommandBufferTextureMemoryActions, - pub(crate) as_actions: &'cmd_enc mut Vec, +pub(crate) struct PassState<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { + pub(crate) base: EncodingState<'snatch_guard, 'cmd_enc, 'raw_encoder>, /// Immediate texture inits required because of prior discards. Need to /// be inserted before texture reads. @@ -64,14 +56,11 @@ pub(crate) struct BaseState<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { pub(crate) dynamic_offset_count: usize, - pub(crate) snatch_guard: &'snatch_guard SnatchGuard<'snatch_guard>, - - pub(crate) debug_scope_depth: u32, pub(crate) string_offset: usize, } pub(crate) fn set_bind_group( - state: &mut BaseState, + state: &mut PassState, cmd_enc: &CommandEncoder, dynamic_offsets: &[DynamicOffset], index: u32, @@ -95,7 +84,7 @@ where ); } - let max_bind_groups = state.device.limits.max_bind_groups; + let max_bind_groups = state.base.device.limits.max_bind_groups; if index >= max_bind_groups { return Err(BindGroupIndexOutOfRange { index, @@ -117,7 +106,7 @@ where } let bind_group = bind_group.unwrap(); - let bind_group = state.tracker.bind_groups.insert_single(bind_group); + let bind_group = state.base.tracker.bind_groups.insert_single(bind_group); bind_group.same_device_as(cmd_enc)?; @@ -133,6 +122,7 @@ where // is held to the bind group itself. state + .base .buffer_memory_init_actions .extend(bind_group.used_buffer_ranges.iter().filter_map(|action| { action @@ -142,9 +132,12 @@ where .check_action(action) })); for action in bind_group.used_texture_ranges.iter() { - state - .pending_discard_init_fixups - .extend(state.texture_memory_actions.register_init_action(action)); + state.pending_discard_init_fixups.extend( + state + .base + .texture_memory_actions + .register_init_action(action), + ); } let used_resource = bind_group @@ -153,7 +146,7 @@ where .into_iter() .map(|tlas| AsAction::UseTlas(tlas.clone())); - state.as_actions.extend(used_resource); + state.base.as_actions.extend(used_resource); let pipeline_layout = state.binder.pipeline_layout.clone(); let entries = state @@ -163,9 +156,9 @@ where let pipeline_layout = pipeline_layout.as_ref().unwrap().raw(); for (i, e) in entries.iter().enumerate() { if let Some(group) = e.group.as_ref() { - let raw_bg = group.try_raw(state.snatch_guard)?; + let raw_bg = group.try_raw(state.base.snatch_guard)?; unsafe { - state.raw_encoder.set_bind_group( + state.base.raw_encoder.set_bind_group( pipeline_layout, index + i as u32, Some(raw_bg), @@ -180,7 +173,7 @@ where /// After a pipeline has been changed, resources must be rebound pub(crate) fn rebind_resources( - state: &mut BaseState, + state: &mut PassState, pipeline_layout: &Arc, late_sized_buffer_groups: &[LateSizedBufferGroup], f: F, @@ -202,9 +195,9 @@ where if !entries.is_empty() { for (i, e) in entries.iter().enumerate() { if let Some(group) = e.group.as_ref() { - let raw_bg = group.try_raw(state.snatch_guard)?; + let raw_bg = group.try_raw(state.base.snatch_guard)?; unsafe { - state.raw_encoder.set_bind_group( + state.base.raw_encoder.set_bind_group( pipeline_layout.raw(), start_index as u32 + i as u32, Some(raw_bg), @@ -225,7 +218,7 @@ where let offset = range.range.start; let size_bytes = range.range.end - offset; super::push_constant_clear(offset, size_bytes, |clear_offset, clear_data| unsafe { - state.raw_encoder.set_push_constants( + state.base.raw_encoder.set_push_constants( pipeline_layout.raw(), range.stages, clear_offset, @@ -238,7 +231,7 @@ where } pub(crate) fn set_push_constant( - state: &mut BaseState, + state: &mut PassState, push_constant_data: &[u32], stages: wgt::ShaderStages, offset: u32, @@ -269,6 +262,7 @@ where unsafe { state + .base .raw_encoder .set_push_constants(pipeline_layout.raw(), stages, offset, data_slice) } @@ -276,7 +270,7 @@ where } pub(crate) fn write_timestamp( - state: &mut BaseState, + state: &mut PassState, cmd_enc: &CommandEncoder, pending_query_resets: Option<&mut QueryResetMap>, query_set: Arc, @@ -293,18 +287,24 @@ where query_set.same_device_as(cmd_enc)?; state + .base .device .require_features(wgt::Features::TIMESTAMP_QUERY_INSIDE_PASSES)?; - let query_set = state.tracker.query_sets.insert_single(query_set); + let query_set = state.base.tracker.query_sets.insert_single(query_set); - query_set.validate_and_write_timestamp(state.raw_encoder, query_index, pending_query_resets)?; + query_set.validate_and_write_timestamp( + state.base.raw_encoder, + query_index, + pending_query_resets, + )?; Ok(()) } -pub(crate) fn push_debug_group(state: &mut BaseState, string_data: &[u8], len: usize) { - state.debug_scope_depth += 1; +pub(crate) fn push_debug_group(state: &mut PassState, string_data: &[u8], len: usize) { + *state.base.debug_scope_depth += 1; if !state + .base .device .instance_flags .contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) @@ -314,36 +314,38 @@ pub(crate) fn push_debug_group(state: &mut BaseState, string_data: &[u8], len: u api_log!("Pass::push_debug_group {label:?}"); unsafe { - state.raw_encoder.begin_debug_marker(label); + state.base.raw_encoder.begin_debug_marker(label); } } state.string_offset += len; } -pub(crate) fn pop_debug_group(state: &mut BaseState) -> Result<(), E> +pub(crate) fn pop_debug_group(state: &mut PassState) -> Result<(), E> where E: From, { api_log!("Pass::pop_debug_group"); - if state.debug_scope_depth == 0 { + if *state.base.debug_scope_depth == 0 { return Err(DebugGroupError::InvalidPop.into()); } - state.debug_scope_depth -= 1; + *state.base.debug_scope_depth -= 1; if !state + .base .device .instance_flags .contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) { unsafe { - state.raw_encoder.end_debug_marker(); + state.base.raw_encoder.end_debug_marker(); } } Ok(()) } -pub(crate) fn insert_debug_marker(state: &mut BaseState, string_data: &[u8], len: usize) { +pub(crate) fn insert_debug_marker(state: &mut PassState, string_data: &[u8], len: usize) { if !state + .base .device .instance_flags .contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) @@ -352,7 +354,7 @@ pub(crate) fn insert_debug_marker(state: &mut BaseState, string_data: &[u8], len str::from_utf8(&string_data[state.string_offset..state.string_offset + len]).unwrap(); api_log!("Pass::insert_debug_marker {label:?}"); unsafe { - state.raw_encoder.insert_debug_marker(label); + state.base.raw_encoder.insert_debug_marker(label); } } state.string_offset += len; diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 344d55bd6d4..20a568aa586 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -10,7 +10,7 @@ use wgt::{ }; use crate::command::{ - pass, pass_base, pass_try, validate_and_begin_occlusion_query, + encoder::EncodingState, pass, pass_base, pass_try, validate_and_begin_occlusion_query, validate_and_begin_pipeline_statistics_query, DebugGroupError, EncoderStateError, InnerCommandEncoder, PassStateError, TimestampWritesError, }; @@ -504,7 +504,7 @@ struct State<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { info: RenderPassInfo, - general: pass::BaseState<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder>, + pass: pass::PassState<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder>, active_occlusion_query: Option<(Arc, u32)>, active_pipeline_statistics_query: Option<(Arc, u32)>, @@ -515,8 +515,8 @@ impl<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { fn is_ready(&self, family: DrawCommandFamily) -> Result<(), DrawError> { if let Some(pipeline) = self.pipeline.as_ref() { - self.general.binder.check_compatibility(pipeline.as_ref())?; - self.general.binder.check_late_buffer_bindings()?; + self.pass.binder.check_compatibility(pipeline.as_ref())?; + self.pass.binder.check_late_buffer_bindings()?; if self.blend_constant == OptionalState::Required { return Err(DrawError::MissingBlendConstant); @@ -569,7 +569,7 @@ impl<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> /// Reset the `RenderBundle`-related states. fn reset_bundle(&mut self) { - self.general.binder.reset(); + self.pass.binder.reset(); self.pipeline = None; self.index.reset(); self.vertex = Default::default(); @@ -1853,8 +1853,6 @@ impl Global { let tracker = &mut cmd_buf_data.trackers; let buffer_memory_init_actions = &mut cmd_buf_data.buffer_memory_init_actions; let texture_memory_actions = &mut cmd_buf_data.texture_memory_actions; - let indirect_draw_validation_resources = - &mut cmd_buf_data.indirect_draw_validation_resources; // We automatically keep extending command buffers over time, and because // we want to insert a command buffer _before_ what we're about to record, @@ -1889,6 +1887,8 @@ impl Global { tracker.buffers.set_size(indices.buffers.size()); tracker.textures.set_size(indices.textures.size()); + let mut debug_scope_depth = 0; + let mut state = State { pipeline_flags: PipelineFlags::empty(), blend_constant: OptionalState::Unused, @@ -1899,23 +1899,26 @@ impl Global { info, - general: pass::BaseState { - device, - raw_encoder: encoder.raw.as_mut(), - tracker, - buffer_memory_init_actions, - texture_memory_actions, - as_actions: &mut cmd_buf_data.as_actions, + pass: pass::PassState { + base: EncodingState { + device, + raw_encoder: encoder.raw.as_mut(), + tracker, + buffer_memory_init_actions, + texture_memory_actions, + as_actions: &mut cmd_buf_data.as_actions, + indirect_draw_validation_resources: &mut cmd_buf_data + .indirect_draw_validation_resources, + snatch_guard, + debug_scope_depth: &mut debug_scope_depth, + }, pending_discard_init_fixups, scope: device.new_usage_scope(), binder: Binder::new(), - snatch_guard, - temp_offsets: Vec::new(), dynamic_offset_count: 0, - debug_scope_depth: 0, string_offset: 0, }, @@ -1932,7 +1935,7 @@ impl Global { } => { let scope = PassErrorScope::SetBindGroup; pass::set_bind_group::( - &mut state.general, + &mut state.pass, cmd_enc.as_ref(), &base.dynamic_offsets, index, @@ -1996,7 +1999,7 @@ impl Global { } => { let scope = PassErrorScope::SetPushConstant; pass::set_push_constant::( - &mut state.general, + &mut state.pass, &base.push_constant_data, stages, offset, @@ -2086,7 +2089,6 @@ impl Global { }; multi_draw_indirect( &mut state, - indirect_draw_validation_resources, &mut indirect_draw_validation_batcher, &cmd_enc, buffer, @@ -2121,15 +2123,15 @@ impl Global { .map_pass_err(scope)?; } ArcRenderCommand::PushDebugGroup { color: _, len } => { - pass::push_debug_group(&mut state.general, &base.string_data, len); + pass::push_debug_group(&mut state.pass, &base.string_data, len); } ArcRenderCommand::PopDebugGroup => { let scope = PassErrorScope::PopDebugGroup; - pass::pop_debug_group::(&mut state.general) + pass::pop_debug_group::(&mut state.pass) .map_pass_err(scope)?; } ArcRenderCommand::InsertDebugMarker { color: _, len } => { - pass::insert_debug_marker(&mut state.general, &base.string_data, len); + pass::insert_debug_marker(&mut state.pass, &base.string_data, len); } ArcRenderCommand::WriteTimestamp { query_set, @@ -2137,7 +2139,7 @@ impl Global { } => { let scope = PassErrorScope::WriteTimestamp; pass::write_timestamp::( - &mut state.general, + &mut state.pass, cmd_enc.as_ref(), Some(&mut pending_query_resets), query_set, @@ -2157,8 +2159,8 @@ impl Global { validate_and_begin_occlusion_query( query_set, - state.general.raw_encoder, - &mut state.general.tracker.query_sets, + state.pass.base.raw_encoder, + &mut state.pass.base.tracker.query_sets, query_index, Some(&mut pending_query_resets), &mut state.active_occlusion_query, @@ -2170,7 +2172,7 @@ impl Global { let scope = PassErrorScope::EndOcclusionQuery; end_occlusion_query( - state.general.raw_encoder, + state.pass.base.raw_encoder, &mut state.active_occlusion_query, ) .map_pass_err(scope)?; @@ -2187,8 +2189,8 @@ impl Global { validate_and_begin_pipeline_statistics_query( query_set, - state.general.raw_encoder, - &mut state.general.tracker.query_sets, + state.pass.base.raw_encoder, + &mut state.pass.base.tracker.query_sets, cmd_enc.as_ref(), query_index, Some(&mut pending_query_resets), @@ -2201,7 +2203,7 @@ impl Global { let scope = PassErrorScope::EndPipelineStatisticsQuery; end_pipeline_statistics_query( - state.general.raw_encoder, + state.pass.base.raw_encoder, &mut state.active_pipeline_statistics_query, ) .map_pass_err(scope)?; @@ -2210,7 +2212,6 @@ impl Global { let scope = PassErrorScope::ExecuteBundle; execute_bundle( &mut state, - indirect_draw_validation_resources, &mut indirect_draw_validation_batcher, &cmd_enc, bundle, @@ -2220,7 +2221,7 @@ impl Global { } } - if state.general.debug_scope_depth > 0 { + if *state.pass.base.debug_scope_depth > 0 { Err( RenderPassErrorInner::DebugGroupError(DebugGroupError::MissingPop) .map_pass_err(pass_scope), @@ -2231,16 +2232,16 @@ impl Global { .info .finish( device, - state.general.raw_encoder, - state.general.snatch_guard, - &mut state.general.scope, + state.pass.base.raw_encoder, + state.pass.base.snatch_guard, + &mut state.pass.scope, self.instance.flags, ) .map_pass_err(pass_scope)?; - let trackers = state.general.scope; + let trackers = state.pass.scope; - let pending_discard_init_fixups = state.general.pending_discard_init_fixups; + let pending_discard_init_fixups = state.pass.pending_discard_init_fixups; encoder.close().map_pass_err(pass_scope)?; (trackers, pending_discard_init_fixups, pending_query_resets) @@ -2301,7 +2302,8 @@ fn set_pipeline( state.pipeline = Some(pipeline.clone()); let pipeline = state - .general + .pass + .base .tracker .render_pipelines .insert_single(pipeline) @@ -2330,7 +2332,8 @@ fn set_pipeline( unsafe { state - .general + .pass + .base .raw_encoder .set_render_pipeline(pipeline.raw()); } @@ -2338,7 +2341,8 @@ fn set_pipeline( if pipeline.flags.contains(PipelineFlags::STENCIL_REFERENCE) { unsafe { state - .general + .pass + .base .raw_encoder .set_stencil_reference(state.stencil_reference); } @@ -2346,7 +2350,7 @@ fn set_pipeline( // Rebind resource pass::rebind_resources::( - &mut state.general, + &mut state.pass, &pipeline.layout, &pipeline.late_sized_buffer_groups, || {}, @@ -2369,7 +2373,7 @@ fn set_index_buffer( api_log!("RenderPass::set_index_buffer {}", buffer.error_ident()); state - .general + .pass .scope .buffers .merge_single(&buffer, wgt::BufferUses::INDEX)?; @@ -2386,12 +2390,12 @@ fn set_index_buffer( .into()); } let (binding, resolved_size) = buffer - .binding(offset, size, state.general.snatch_guard) + .binding(offset, size, state.pass.base.snatch_guard) .map_err(RenderCommandError::from)?; let end = offset + resolved_size; state.index.update_buffer(offset..end, index_format); - state.general.buffer_memory_init_actions.extend( + state.pass.base.buffer_memory_init_actions.extend( buffer.initialization_status.read().create_action( &buffer, offset..end, @@ -2400,7 +2404,11 @@ fn set_index_buffer( ); unsafe { - hal::DynCommandEncoder::set_index_buffer(state.general.raw_encoder, binding, index_format); + hal::DynCommandEncoder::set_index_buffer( + state.pass.base.raw_encoder, + binding, + index_format, + ); } Ok(()) } @@ -2420,14 +2428,14 @@ fn set_vertex_buffer( ); state - .general + .pass .scope .buffers .merge_single(&buffer, wgt::BufferUses::VERTEX)?; buffer.same_device_as(cmd_enc.as_ref())?; - let max_vertex_buffers = state.general.device.limits.max_vertex_buffers; + let max_vertex_buffers = state.pass.base.device.limits.max_vertex_buffers; if slot >= max_vertex_buffers { return Err(RenderCommandError::VertexBufferIndexOutOfRange { index: slot, @@ -2442,11 +2450,11 @@ fn set_vertex_buffer( return Err(RenderCommandError::UnalignedVertexBuffer { slot, offset }.into()); } let (binding, buffer_size) = buffer - .binding(offset, size, state.general.snatch_guard) + .binding(offset, size, state.pass.base.snatch_guard) .map_err(RenderCommandError::from)?; state.vertex.buffer_sizes[slot as usize] = Some(buffer_size); - state.general.buffer_memory_init_actions.extend( + state.pass.base.buffer_memory_init_actions.extend( buffer.initialization_status.read().create_action( &buffer, offset..(offset + buffer_size), @@ -2455,7 +2463,7 @@ fn set_vertex_buffer( ); unsafe { - hal::DynCommandEncoder::set_vertex_buffer(state.general.raw_encoder, slot, binding); + hal::DynCommandEncoder::set_vertex_buffer(state.pass.base.raw_encoder, slot, binding); } if let Some(pipeline) = state.pipeline.as_ref() { state.vertex.update_limits(&pipeline.vertex_steps); @@ -2474,7 +2482,7 @@ fn set_blend_constant(state: &mut State, color: &Color) { color.a as f32, ]; unsafe { - state.general.raw_encoder.set_blend_constants(&array); + state.pass.base.raw_encoder.set_blend_constants(&array); } } @@ -2487,7 +2495,7 @@ fn set_stencil_reference(state: &mut State, value: u32) { .contains(PipelineFlags::STENCIL_REFERENCE) { unsafe { - state.general.raw_encoder.set_stencil_reference(value); + state.pass.base.raw_encoder.set_stencil_reference(value); } } } @@ -2502,18 +2510,18 @@ fn set_viewport( if rect.w < 0.0 || rect.h < 0.0 - || rect.w > state.general.device.limits.max_texture_dimension_2d as f32 - || rect.h > state.general.device.limits.max_texture_dimension_2d as f32 + || rect.w > state.pass.base.device.limits.max_texture_dimension_2d as f32 + || rect.h > state.pass.base.device.limits.max_texture_dimension_2d as f32 { return Err(RenderCommandError::InvalidViewportRectSize { w: rect.w, h: rect.h, - max: state.general.device.limits.max_texture_dimension_2d, + max: state.pass.base.device.limits.max_texture_dimension_2d, } .into()); } - let max_viewport_range = state.general.device.limits.max_texture_dimension_2d as f32 * 2.0; + let max_viewport_range = state.pass.base.device.limits.max_texture_dimension_2d as f32 * 2.0; if rect.x < -max_viewport_range || rect.y < -max_viewport_range @@ -2541,7 +2549,8 @@ fn set_viewport( }; unsafe { state - .general + .pass + .base .raw_encoder .set_viewport(&r, depth_min..depth_max); } @@ -2563,7 +2572,7 @@ fn set_scissor(state: &mut State, rect: Rect) -> Result<(), RenderPassError h: rect.h, }; unsafe { - state.general.raw_encoder.set_scissor_rect(&r); + state.pass.base.raw_encoder.set_scissor_rect(&r); } Ok(()) } @@ -2590,7 +2599,7 @@ fn draw( unsafe { if instance_count > 0 && vertex_count > 0 { - state.general.raw_encoder.draw( + state.pass.base.raw_encoder.draw( first_vertex, vertex_count, first_instance, @@ -2628,7 +2637,7 @@ fn draw_indexed( unsafe { if instance_count > 0 && index_count > 0 { - state.general.raw_encoder.draw_indexed( + state.pass.base.raw_encoder.draw_indexed( first_index, index_count, base_vertex, @@ -2651,11 +2660,12 @@ fn draw_mesh_tasks( state.is_ready(DrawCommandFamily::DrawMeshTasks)?; let groups_size_limit = state - .general + .pass + .base .device .limits .max_task_workgroups_per_dimension; - let max_groups = state.general.device.limits.max_task_workgroup_total_count; + let max_groups = state.pass.base.device.limits.max_task_workgroup_total_count; if group_count_x > groups_size_limit || group_count_y > groups_size_limit || group_count_z > groups_size_limit @@ -2670,10 +2680,11 @@ fn draw_mesh_tasks( unsafe { if group_count_x > 0 && group_count_y > 0 && group_count_z > 0 { - state - .general - .raw_encoder - .draw_mesh_tasks(group_count_x, group_count_y, group_count_z); + state.pass.base.raw_encoder.draw_mesh_tasks( + group_count_x, + group_count_y, + group_count_z, + ); } } Ok(()) @@ -2681,7 +2692,6 @@ fn draw_mesh_tasks( fn multi_draw_indirect( state: &mut State, - indirect_draw_validation_resources: &mut crate::indirect_validation::DrawResources, indirect_draw_validation_batcher: &mut crate::indirect_validation::DrawBatcher, cmd_enc: &Arc, indirect_buffer: Arc, @@ -2697,13 +2707,14 @@ fn multi_draw_indirect( state.is_ready(family)?; state - .general + .pass + .base .device .require_downlevel_flags(wgt::DownlevelFlags::INDIRECT_EXECUTION)?; indirect_buffer.same_device_as(cmd_enc.as_ref())?; indirect_buffer.check_usage(BufferUsages::INDIRECT)?; - indirect_buffer.check_destroyed(state.general.snatch_guard)?; + indirect_buffer.check_destroyed(state.pass.base.snatch_guard)?; if offset % 4 != 0 { return Err(RenderPassErrorInner::UnalignedIndirectBufferOffset(offset)); @@ -2721,7 +2732,7 @@ fn multi_draw_indirect( }); } - state.general.buffer_memory_init_actions.extend( + state.pass.base.buffer_memory_init_actions.extend( indirect_buffer.initialization_status.read().create_action( &indirect_buffer, offset..end_offset, @@ -2749,9 +2760,9 @@ fn multi_draw_indirect( } } - if state.general.device.indirect_validation.is_some() { + if state.pass.base.device.indirect_validation.is_some() { state - .general + .pass .scope .buffers .merge_single(&indirect_buffer, wgt::BufferUses::STORAGE_READ_ONLY)?; @@ -2807,9 +2818,9 @@ fn multi_draw_indirect( } let mut draw_ctx = DrawContext { - raw_encoder: state.general.raw_encoder, - device: state.general.device, - indirect_draw_validation_resources, + raw_encoder: state.pass.base.raw_encoder, + device: state.pass.base.device, + indirect_draw_validation_resources: state.pass.base.indirect_draw_validation_resources, indirect_draw_validation_batcher, indirect_buffer, family, @@ -2841,15 +2852,15 @@ fn multi_draw_indirect( draw_ctx.draw(current_draw_data); } else { state - .general + .pass .scope .buffers .merge_single(&indirect_buffer, wgt::BufferUses::INDIRECT)?; draw( - state.general.raw_encoder, + state.pass.base.raw_encoder, family, - indirect_buffer.try_raw(state.general.snatch_guard)?, + indirect_buffer.try_raw(state.pass.base.snatch_guard)?, offset, count, ); @@ -2879,11 +2890,13 @@ fn multi_draw_indirect_count( let stride = get_stride_of_indirect_args(family); state - .general + .pass + .base .device .require_features(wgt::Features::MULTI_DRAW_INDIRECT_COUNT)?; state - .general + .pass + .base .device .require_downlevel_flags(wgt::DownlevelFlags::INDIRECT_EXECUTION)?; @@ -2891,22 +2904,22 @@ fn multi_draw_indirect_count( count_buffer.same_device_as(cmd_enc.as_ref())?; state - .general + .pass .scope .buffers .merge_single(&indirect_buffer, wgt::BufferUses::INDIRECT)?; indirect_buffer.check_usage(BufferUsages::INDIRECT)?; - let indirect_raw = indirect_buffer.try_raw(state.general.snatch_guard)?; + let indirect_raw = indirect_buffer.try_raw(state.pass.base.snatch_guard)?; state - .general + .pass .scope .buffers .merge_single(&count_buffer, wgt::BufferUses::INDIRECT)?; count_buffer.check_usage(BufferUsages::INDIRECT)?; - let count_raw = count_buffer.try_raw(state.general.snatch_guard)?; + let count_raw = count_buffer.try_raw(state.pass.base.snatch_guard)?; if offset % 4 != 0 { return Err(RenderPassErrorInner::UnalignedIndirectBufferOffset(offset)); @@ -2921,7 +2934,7 @@ fn multi_draw_indirect_count( buffer_size: indirect_buffer.size, }); } - state.general.buffer_memory_init_actions.extend( + state.pass.base.buffer_memory_init_actions.extend( indirect_buffer.initialization_status.read().create_action( &indirect_buffer, offset..end_offset, @@ -2938,7 +2951,7 @@ fn multi_draw_indirect_count( count_buffer_size: count_buffer.size, }); } - state.general.buffer_memory_init_actions.extend( + state.pass.base.buffer_memory_init_actions.extend( count_buffer.initialization_status.read().create_action( &count_buffer, count_buffer_offset..end_count_offset, @@ -2948,7 +2961,7 @@ fn multi_draw_indirect_count( match family { DrawCommandFamily::Draw => unsafe { - state.general.raw_encoder.draw_indirect_count( + state.pass.base.raw_encoder.draw_indirect_count( indirect_raw, offset, count_raw, @@ -2957,7 +2970,7 @@ fn multi_draw_indirect_count( ); }, DrawCommandFamily::DrawIndexed => unsafe { - state.general.raw_encoder.draw_indexed_indirect_count( + state.pass.base.raw_encoder.draw_indexed_indirect_count( indirect_raw, offset, count_raw, @@ -2966,7 +2979,7 @@ fn multi_draw_indirect_count( ); }, DrawCommandFamily::DrawMeshTasks => unsafe { - state.general.raw_encoder.draw_mesh_tasks_indirect_count( + state.pass.base.raw_encoder.draw_mesh_tasks_indirect_count( indirect_raw, offset, count_raw, @@ -2980,14 +2993,13 @@ fn multi_draw_indirect_count( fn execute_bundle( state: &mut State, - indirect_draw_validation_resources: &mut crate::indirect_validation::DrawResources, indirect_draw_validation_batcher: &mut crate::indirect_validation::DrawBatcher, cmd_enc: &Arc, bundle: Arc, ) -> Result<(), RenderPassErrorInner> { api_log!("RenderPass::execute_bundle {}", bundle.error_ident()); - let bundle = state.general.tracker.bundles.insert_single(bundle); + let bundle = state.pass.base.tracker.bundles.insert_single(bundle); bundle.same_device_as(cmd_enc.as_ref())?; @@ -3010,7 +3022,7 @@ fn execute_bundle( ); } - state.general.buffer_memory_init_actions.extend( + state.pass.base.buffer_memory_init_actions.extend( bundle .buffer_memory_init_actions .iter() @@ -3023,9 +3035,10 @@ fn execute_bundle( }), ); for action in bundle.texture_memory_init_actions.iter() { - state.general.pending_discard_init_fixups.extend( + state.pass.pending_discard_init_fixups.extend( state - .general + .pass + .base .texture_memory_actions .register_init_action(action), ); @@ -3033,10 +3046,10 @@ fn execute_bundle( unsafe { bundle.execute( - state.general.raw_encoder, - indirect_draw_validation_resources, + state.pass.base.raw_encoder, + state.pass.base.indirect_draw_validation_resources, indirect_draw_validation_batcher, - state.general.snatch_guard, + state.pass.base.snatch_guard, ) } .map_err(|e| match e { @@ -3050,7 +3063,7 @@ fn execute_bundle( })?; unsafe { - state.general.scope.merge_render_bundle(&bundle.used)?; + state.pass.scope.merge_render_bundle(&bundle.used)?; }; state.reset_bundle(); Ok(()) From c0c16078e972ce8511dc71e1200ef2ca43e5affc Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Fri, 29 Aug 2025 17:10:46 -0700 Subject: [PATCH 201/303] Rename and relocate ID resolution helpers --- wgpu-core/src/command/mod.rs | 21 ++++++++++ wgpu-core/src/command/render.rs | 72 ++++++++------------------------- 2 files changed, 37 insertions(+), 56 deletions(-) diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index e16c9fe18a2..cdf3435002d 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -36,6 +36,7 @@ use crate::binding_model::BindingError; use crate::command::transition_resources::TransitionResourcesError; use crate::device::queue::TempResource; use crate::device::{Device, DeviceError, MissingFeatures}; +use crate::id::Id; use crate::lock::{rank, Mutex}; use crate::snatch::SnatchGuard; @@ -1155,6 +1156,26 @@ impl WebGpuError for TimestampWritesError { } impl Global { + fn resolve_buffer_id( + &self, + buffer_id: Id, + ) -> Result, InvalidResourceError> { + let hub = &self.hub; + let buffer = hub.buffers.get(buffer_id).get()?; + + Ok(buffer) + } + + fn resolve_query_set( + &self, + query_set_id: Id, + ) -> Result, InvalidResourceError> { + let hub = &self.hub; + let query_set = hub.query_sets.get(query_set_id).get()?; + + Ok(query_set) + } + pub fn command_encoder_finish( &self, encoder_id: id::CommandEncoderId, diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 20a568aa586..7e38c468f93 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -3082,26 +3082,6 @@ fn execute_bundle( // that the `pass_try!` and `pass_base!` macros may return early from the // function that invokes them, like the `?` operator. impl Global { - fn resolve_render_pass_buffer_id( - &self, - buffer_id: id::Id, - ) -> Result, InvalidResourceError> { - let hub = &self.hub; - let buffer = hub.buffers.get(buffer_id).get()?; - - Ok(buffer) - } - - fn resolve_render_pass_query_set( - &self, - query_set_id: id::Id, - ) -> Result, InvalidResourceError> { - let hub = &self.hub; - let query_set = hub.query_sets.get(query_set_id).get()?; - - Ok(query_set) - } - pub fn render_pass_set_bind_group( &self, pass: &mut RenderPass, @@ -3183,7 +3163,7 @@ impl Global { let base = pass_base!(pass, scope); base.commands.push(ArcRenderCommand::SetIndexBuffer { - buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), + buffer: pass_try!(base, scope, self.resolve_buffer_id(buffer_id)), index_format, offset, size, @@ -3205,7 +3185,7 @@ impl Global { base.commands.push(ArcRenderCommand::SetVertexBuffer { slot, - buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), + buffer: pass_try!(base, scope, self.resolve_buffer_id(buffer_id)), offset, size, }); @@ -3413,7 +3393,7 @@ impl Global { let base = pass_base!(pass, scope); base.commands.push(ArcRenderCommand::DrawIndirect { - buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), + buffer: pass_try!(base, scope, self.resolve_buffer_id(buffer_id)), offset, count: 1, family: DrawCommandFamily::Draw, @@ -3438,7 +3418,7 @@ impl Global { let base = pass_base!(pass, scope); base.commands.push(ArcRenderCommand::DrawIndirect { - buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), + buffer: pass_try!(base, scope, self.resolve_buffer_id(buffer_id)), offset, count: 1, family: DrawCommandFamily::DrawIndexed, @@ -3463,7 +3443,7 @@ impl Global { let base = pass_base!(pass, scope); base.commands.push(ArcRenderCommand::DrawIndirect { - buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), + buffer: pass_try!(base, scope, self.resolve_buffer_id(buffer_id)), offset, count: 1, family: DrawCommandFamily::DrawMeshTasks, @@ -3489,7 +3469,7 @@ impl Global { let base = pass_base!(pass, scope); base.commands.push(ArcRenderCommand::DrawIndirect { - buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), + buffer: pass_try!(base, scope, self.resolve_buffer_id(buffer_id)), offset, count, family: DrawCommandFamily::Draw, @@ -3515,7 +3495,7 @@ impl Global { let base = pass_base!(pass, scope); base.commands.push(ArcRenderCommand::DrawIndirect { - buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), + buffer: pass_try!(base, scope, self.resolve_buffer_id(buffer_id)), offset, count, family: DrawCommandFamily::DrawIndexed, @@ -3541,7 +3521,7 @@ impl Global { let base = pass_base!(pass, scope); base.commands.push(ArcRenderCommand::DrawIndirect { - buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), + buffer: pass_try!(base, scope, self.resolve_buffer_id(buffer_id)), offset, count, family: DrawCommandFamily::DrawMeshTasks, @@ -3570,13 +3550,9 @@ impl Global { base.commands .push(ArcRenderCommand::MultiDrawIndirectCount { - buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), + buffer: pass_try!(base, scope, self.resolve_buffer_id(buffer_id)), offset, - count_buffer: pass_try!( - base, - scope, - self.resolve_render_pass_buffer_id(count_buffer_id) - ), + count_buffer: pass_try!(base, scope, self.resolve_buffer_id(count_buffer_id)), count_buffer_offset, max_count, family: DrawCommandFamily::Draw, @@ -3602,13 +3578,9 @@ impl Global { base.commands .push(ArcRenderCommand::MultiDrawIndirectCount { - buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), + buffer: pass_try!(base, scope, self.resolve_buffer_id(buffer_id)), offset, - count_buffer: pass_try!( - base, - scope, - self.resolve_render_pass_buffer_id(count_buffer_id) - ), + count_buffer: pass_try!(base, scope, self.resolve_buffer_id(count_buffer_id)), count_buffer_offset, max_count, family: DrawCommandFamily::DrawIndexed, @@ -3634,13 +3606,9 @@ impl Global { base.commands .push(ArcRenderCommand::MultiDrawIndirectCount { - buffer: pass_try!(base, scope, self.resolve_render_pass_buffer_id(buffer_id)), + buffer: pass_try!(base, scope, self.resolve_buffer_id(buffer_id)), offset, - count_buffer: pass_try!( - base, - scope, - self.resolve_render_pass_buffer_id(count_buffer_id) - ), + count_buffer: pass_try!(base, scope, self.resolve_buffer_id(count_buffer_id)), count_buffer_offset, max_count, family: DrawCommandFamily::DrawMeshTasks, @@ -3705,11 +3673,7 @@ impl Global { let base = pass_base!(pass, scope); base.commands.push(ArcRenderCommand::WriteTimestamp { - query_set: pass_try!( - base, - scope, - self.resolve_render_pass_query_set(query_set_id) - ), + query_set: pass_try!(base, scope, self.resolve_query_set(query_set_id)), query_index, }); @@ -3753,11 +3717,7 @@ impl Global { base.commands .push(ArcRenderCommand::BeginPipelineStatisticsQuery { - query_set: pass_try!( - base, - scope, - self.resolve_render_pass_query_set(query_set_id) - ), + query_set: pass_try!(base, scope, self.resolve_query_set(query_set_id)), query_index, }); From 718497356c43303653d177f062bffa8f165f8900 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Thu, 28 Aug 2025 16:58:32 -0700 Subject: [PATCH 202/303] Move `enum Command` from `device::trace` to `command::encoder_command`. --- player/src/lib.rs | 36 ++++++------ wgpu-core/src/command/clear.rs | 2 +- wgpu-core/src/command/compute.rs | 2 +- wgpu-core/src/command/encoder_command.rs | 70 ++++++++++++++++++++++++ wgpu-core/src/command/mod.rs | 7 ++- wgpu-core/src/command/query.rs | 2 +- wgpu-core/src/command/ray_tracing.rs | 2 +- wgpu-core/src/command/render.rs | 2 +- wgpu-core/src/command/transfer.rs | 2 +- wgpu-core/src/device/trace.rs | 67 +---------------------- 10 files changed, 98 insertions(+), 94 deletions(-) create mode 100644 wgpu-core/src/command/encoder_command.rs diff --git a/player/src/lib.rs b/player/src/lib.rs index 8ba7e13ce1b..437f51b14bb 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -6,7 +6,7 @@ extern crate wgpu_core as wgc; extern crate wgpu_types as wgt; -use wgc::{device::trace, identity::IdentityManager}; +use wgc::{command::Command, device::trace, identity::IdentityManager}; use std::{borrow::Cow, fs, path::Path}; @@ -14,7 +14,7 @@ pub trait GlobalPlay { fn encode_commands( &self, encoder: wgc::id::CommandEncoderId, - commands: Vec, + commands: Vec, command_buffer_id_manager: &mut IdentityManager, ) -> wgc::id::CommandBufferId; fn process( @@ -32,12 +32,12 @@ impl GlobalPlay for wgc::global::Global { fn encode_commands( &self, encoder: wgc::id::CommandEncoderId, - commands: Vec, + commands: Vec, command_buffer_id_manager: &mut IdentityManager, ) -> wgc::id::CommandBufferId { for command in commands { match command { - trace::Command::CopyBufferToBuffer { + Command::CopyBufferToBuffer { src, src_offset, dst, @@ -48,31 +48,31 @@ impl GlobalPlay for wgc::global::Global { encoder, src, src_offset, dst, dst_offset, size, ) .unwrap(), - trace::Command::CopyBufferToTexture { src, dst, size } => self + Command::CopyBufferToTexture { src, dst, size } => self .command_encoder_copy_buffer_to_texture(encoder, &src, &dst, &size) .unwrap(), - trace::Command::CopyTextureToBuffer { src, dst, size } => self + Command::CopyTextureToBuffer { src, dst, size } => self .command_encoder_copy_texture_to_buffer(encoder, &src, &dst, &size) .unwrap(), - trace::Command::CopyTextureToTexture { src, dst, size } => self + Command::CopyTextureToTexture { src, dst, size } => self .command_encoder_copy_texture_to_texture(encoder, &src, &dst, &size) .unwrap(), - trace::Command::ClearBuffer { dst, offset, size } => self + Command::ClearBuffer { dst, offset, size } => self .command_encoder_clear_buffer(encoder, dst, offset, size) .unwrap(), - trace::Command::ClearTexture { + Command::ClearTexture { dst, subresource_range, } => self .command_encoder_clear_texture(encoder, dst, &subresource_range) .unwrap(), - trace::Command::WriteTimestamp { + Command::WriteTimestamp { query_set_id, query_index, } => self .command_encoder_write_timestamp(encoder, query_set_id, query_index) .unwrap(), - trace::Command::ResolveQuerySet { + Command::ResolveQuerySet { query_set_id, start_query, query_count, @@ -88,16 +88,14 @@ impl GlobalPlay for wgc::global::Global { destination_offset, ) .unwrap(), - trace::Command::PushDebugGroup(marker) => self + Command::PushDebugGroup(marker) => self .command_encoder_push_debug_group(encoder, &marker) .unwrap(), - trace::Command::PopDebugGroup => { - self.command_encoder_pop_debug_group(encoder).unwrap() - } - trace::Command::InsertDebugMarker(marker) => self + Command::PopDebugGroup => self.command_encoder_pop_debug_group(encoder).unwrap(), + Command::InsertDebugMarker(marker) => self .command_encoder_insert_debug_marker(encoder, &marker) .unwrap(), - trace::Command::RunComputePass { + Command::RunComputePass { base, timestamp_writes, } => { @@ -107,7 +105,7 @@ impl GlobalPlay for wgc::global::Global { timestamp_writes.as_ref(), ); } - trace::Command::RunRenderPass { + Command::RunRenderPass { base, target_colors, target_depth_stencil, @@ -123,7 +121,7 @@ impl GlobalPlay for wgc::global::Global { occlusion_query_set_id, ); } - trace::Command::BuildAccelerationStructures { blas, tlas } => { + Command::BuildAccelerationStructures { blas, tlas } => { let blas_iter = blas.iter().map(|x| { let geometries = match &x.geometries { wgc::ray_tracing::TraceBlasGeometries::TriangleGeometries( diff --git a/wgpu-core/src/command/clear.rs b/wgpu-core/src/command/clear.rs index 840e9068125..323bf5d4892 100644 --- a/wgpu-core/src/command/clear.rs +++ b/wgpu-core/src/command/clear.rs @@ -2,7 +2,7 @@ use alloc::{sync::Arc, vec::Vec}; use core::ops::Range; #[cfg(feature = "trace")] -use crate::device::trace::Command as TraceCommand; +use crate::command::Command as TraceCommand; use crate::{ api_log, command::EncoderStateError, diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index 52f8e09cfcb..f34c7779c1d 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -438,7 +438,7 @@ impl Global { let cmd_buf_data = cmd_buf_data.get_inner(); if let Some(ref mut list) = cmd_buf_data.commands { - list.push(crate::device::trace::Command::RunComputePass { + list.push(crate::command::Command::RunComputePass { base: BasePass { label: base.label.clone(), error: None, diff --git a/wgpu-core/src/command/encoder_command.rs b/wgpu-core/src/command/encoder_command.rs new file mode 100644 index 00000000000..31d50504f77 --- /dev/null +++ b/wgpu-core/src/command/encoder_command.rs @@ -0,0 +1,70 @@ +use core::convert::Infallible; + +use alloc::{string::String, vec::Vec}; + +use crate::id; + +#[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum Command { + CopyBufferToBuffer { + src: id::BufferId, + src_offset: wgt::BufferAddress, + dst: id::BufferId, + dst_offset: wgt::BufferAddress, + size: Option, + }, + CopyBufferToTexture { + src: crate::command::TexelCopyBufferInfo, + dst: crate::command::TexelCopyTextureInfo, + size: wgt::Extent3d, + }, + CopyTextureToBuffer { + src: crate::command::TexelCopyTextureInfo, + dst: crate::command::TexelCopyBufferInfo, + size: wgt::Extent3d, + }, + CopyTextureToTexture { + src: crate::command::TexelCopyTextureInfo, + dst: crate::command::TexelCopyTextureInfo, + size: wgt::Extent3d, + }, + ClearBuffer { + dst: id::BufferId, + offset: wgt::BufferAddress, + size: Option, + }, + ClearTexture { + dst: id::TextureId, + subresource_range: wgt::ImageSubresourceRange, + }, + WriteTimestamp { + query_set_id: id::QuerySetId, + query_index: u32, + }, + ResolveQuerySet { + query_set_id: id::QuerySetId, + start_query: u32, + query_count: u32, + destination: id::BufferId, + destination_offset: wgt::BufferAddress, + }, + PushDebugGroup(String), + PopDebugGroup, + InsertDebugMarker(String), + RunComputePass { + base: crate::command::BasePass, + timestamp_writes: Option, + }, + RunRenderPass { + base: crate::command::BasePass, + target_colors: Vec>, + target_depth_stencil: Option, + timestamp_writes: Option, + occlusion_query_set_id: Option, + }, + BuildAccelerationStructures { + blas: Vec, + tlas: Vec, + }, +} diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index cdf3435002d..831b071d702 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -6,6 +6,7 @@ mod compute; mod compute_command; mod draw; mod encoder; +mod encoder_command; mod memory_init; mod pass; mod query; @@ -22,8 +23,8 @@ use core::ops; pub(crate) use self::clear::clear_texture; pub use self::{ - bundle::*, clear::ClearError, compute::*, compute_command::ComputeCommand, draw::*, query::*, - render::*, render_command::RenderCommand, transfer::*, + bundle::*, clear::ClearError, compute::*, compute_command::ComputeCommand, draw::*, + encoder_command::Command, query::*, render::*, render_command::RenderCommand, transfer::*, }; pub(crate) use allocator::CommandAllocator; @@ -55,7 +56,7 @@ use wgt::error::{ErrorType, WebGpuError}; use thiserror::Error; #[cfg(feature = "trace")] -use crate::device::trace::Command as TraceCommand; +type TraceCommand = Command; const PUSH_CONSTANT_CLEAR_ARRAY: &[u32] = &[0_u32; 64]; diff --git a/wgpu-core/src/command/query.rs b/wgpu-core/src/command/query.rs index c47374b028d..afd73384575 100644 --- a/wgpu-core/src/command/query.rs +++ b/wgpu-core/src/command/query.rs @@ -2,7 +2,7 @@ use alloc::{sync::Arc, vec, vec::Vec}; use core::{iter, mem}; #[cfg(feature = "trace")] -use crate::device::trace::Command as TraceCommand; +use crate::command::Command as TraceCommand; use crate::{ command::{CommandEncoder, EncoderStateError}, device::{DeviceError, MissingFeatures}, diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index e4553ff222b..1aac0014f3d 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -201,7 +201,7 @@ impl Global { cmd_buf_data.record_with(|cmd_buf_data| { #[cfg(feature = "trace")] if let Some(ref mut list) = cmd_buf_data.commands { - list.push(crate::device::trace::Command::BuildAccelerationStructures { + list.push(crate::command::Command::BuildAccelerationStructures { blas: trace_blas.clone(), tlas: trace_tlas.clone(), }); diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 7e38c468f93..30f45f1b00e 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1753,7 +1753,7 @@ impl Global { let cmd_buf_data = cmd_buf_data.get_inner(); if let Some(ref mut list) = cmd_buf_data.commands { - list.push(crate::device::trace::Command::RunRenderPass { + list.push(crate::command::Command::RunRenderPass { base: BasePass { label: base.label.clone(), error: None, diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index a9a125331db..e351de4c120 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -9,7 +9,7 @@ use wgt::{ }; #[cfg(feature = "trace")] -use crate::device::trace::Command as TraceCommand; +use crate::command::Command as TraceCommand; use crate::{ api_log, command::{clear_texture, CommandEncoderError, EncoderStateError}, diff --git a/wgpu-core/src/device/trace.rs b/wgpu-core/src/device/trace.rs index 80432d5e938..8b76c852dbe 100644 --- a/wgpu-core/src/device/trace.rs +++ b/wgpu-core/src/device/trace.rs @@ -4,7 +4,7 @@ use core::{convert::Infallible, ops::Range}; #[cfg(feature = "trace")] use {alloc::borrow::Cow, std::io::Write as _}; -use crate::id; +use crate::{command::Command, id}; //TODO: consider a readable Id that doesn't include the backend @@ -159,71 +159,6 @@ pub enum Action<'a> { DestroyTlas(id::TlasId), } -#[derive(Debug)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub enum Command { - CopyBufferToBuffer { - src: id::BufferId, - src_offset: wgt::BufferAddress, - dst: id::BufferId, - dst_offset: wgt::BufferAddress, - size: Option, - }, - CopyBufferToTexture { - src: crate::command::TexelCopyBufferInfo, - dst: crate::command::TexelCopyTextureInfo, - size: wgt::Extent3d, - }, - CopyTextureToBuffer { - src: crate::command::TexelCopyTextureInfo, - dst: crate::command::TexelCopyBufferInfo, - size: wgt::Extent3d, - }, - CopyTextureToTexture { - src: crate::command::TexelCopyTextureInfo, - dst: crate::command::TexelCopyTextureInfo, - size: wgt::Extent3d, - }, - ClearBuffer { - dst: id::BufferId, - offset: wgt::BufferAddress, - size: Option, - }, - ClearTexture { - dst: id::TextureId, - subresource_range: wgt::ImageSubresourceRange, - }, - WriteTimestamp { - query_set_id: id::QuerySetId, - query_index: u32, - }, - ResolveQuerySet { - query_set_id: id::QuerySetId, - start_query: u32, - query_count: u32, - destination: id::BufferId, - destination_offset: wgt::BufferAddress, - }, - PushDebugGroup(String), - PopDebugGroup, - InsertDebugMarker(String), - RunComputePass { - base: crate::command::BasePass, - timestamp_writes: Option, - }, - RunRenderPass { - base: crate::command::BasePass, - target_colors: Vec>, - target_depth_stencil: Option, - timestamp_writes: Option, - occlusion_query_set_id: Option, - }, - BuildAccelerationStructures { - blas: Vec, - tlas: Vec, - }, -} - #[cfg(feature = "trace")] #[derive(Debug)] pub struct Trace { From d79a49a060219b571cb5c3a75a92aea93a8c445f Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Fri, 29 Aug 2025 18:38:30 -0700 Subject: [PATCH 203/303] Rename `commands` to `trace_commands` --- wgpu-core/src/command/clear.rs | 4 ++-- wgpu-core/src/command/compute.rs | 2 +- wgpu-core/src/command/mod.rs | 10 +++++----- wgpu-core/src/command/query.rs | 4 ++-- wgpu-core/src/command/ray_tracing.rs | 2 +- wgpu-core/src/command/render.rs | 2 +- wgpu-core/src/command/transfer.rs | 8 ++++---- wgpu-core/src/device/queue.rs | 2 +- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/wgpu-core/src/command/clear.rs b/wgpu-core/src/command/clear.rs index 323bf5d4892..3781cd20331 100644 --- a/wgpu-core/src/command/clear.rs +++ b/wgpu-core/src/command/clear.rs @@ -120,7 +120,7 @@ impl Global { let mut cmd_buf_data = cmd_enc.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), ClearError> { #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.commands { + if let Some(ref mut list) = cmd_buf_data.trace_commands { list.push(TraceCommand::ClearBuffer { dst, offset, size }); } @@ -205,7 +205,7 @@ impl Global { let mut cmd_buf_data = cmd_enc.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), ClearError> { #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.commands { + if let Some(ref mut list) = cmd_buf_data.trace_commands { list.push(TraceCommand::ClearTexture { dst, subresource_range: *subresource_range, diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index f34c7779c1d..a9d0795e7d0 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -437,7 +437,7 @@ impl Global { let mut cmd_buf_data = cmd_enc.data.lock(); let cmd_buf_data = cmd_buf_data.get_inner(); - if let Some(ref mut list) = cmd_buf_data.commands { + if let Some(ref mut list) = cmd_buf_data.trace_commands { list.push(crate::command::Command::RunComputePass { base: BasePass { label: base.label.clone(), diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 831b071d702..0a84f107403 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -656,7 +656,7 @@ pub struct CommandBufferMutable { debug_scope_depth: u32, #[cfg(feature = "trace")] - pub(crate) commands: Option>, + pub(crate) trace_commands: Option>, } impl CommandBufferMutable { @@ -729,7 +729,7 @@ impl CommandEncoder { crate::indirect_validation::DrawResources::new(device.clone()), debug_scope_depth: 0, #[cfg(feature = "trace")] - commands: if device.trace.lock().is_some() { + trace_commands: if device.trace.lock().is_some() { Some(Vec::new()) } else { None @@ -1225,7 +1225,7 @@ impl Global { cmd_buf_data.debug_scope_depth += 1; #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.commands { + if let Some(ref mut list) = cmd_buf_data.trace_commands { list.push(TraceCommand::PushDebugGroup(label.to_owned())); } @@ -1260,7 +1260,7 @@ impl Global { let mut cmd_buf_data = cmd_enc.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.commands { + if let Some(ref mut list) = cmd_buf_data.trace_commands { list.push(TraceCommand::InsertDebugMarker(label.to_owned())); } @@ -1299,7 +1299,7 @@ impl Global { cmd_buf_data.debug_scope_depth -= 1; #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.commands { + if let Some(ref mut list) = cmd_buf_data.trace_commands { list.push(TraceCommand::PopDebugGroup); } diff --git a/wgpu-core/src/command/query.rs b/wgpu-core/src/command/query.rs index afd73384575..dc754f8070b 100644 --- a/wgpu-core/src/command/query.rs +++ b/wgpu-core/src/command/query.rs @@ -367,7 +367,7 @@ impl Global { let mut cmd_buf_data = cmd_enc.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), QueryError> { #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.commands { + if let Some(ref mut list) = cmd_buf_data.trace_commands { list.push(TraceCommand::WriteTimestamp { query_set_id, query_index, @@ -408,7 +408,7 @@ impl Global { let mut cmd_buf_data = cmd_enc.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), QueryError> { #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.commands { + if let Some(ref mut list) = cmd_buf_data.trace_commands { list.push(TraceCommand::ResolveQuerySet { query_set_id, start_query, diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 1aac0014f3d..adee3999742 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -200,7 +200,7 @@ impl Global { let mut cmd_buf_data = cmd_enc.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| { #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.commands { + if let Some(ref mut list) = cmd_buf_data.trace_commands { list.push(crate::command::Command::BuildAccelerationStructures { blas: trace_blas.clone(), tlas: trace_tlas.clone(), diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 30f45f1b00e..fe88fb2afd4 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1752,7 +1752,7 @@ impl Global { let mut cmd_buf_data = cmd_enc.data.lock(); let cmd_buf_data = cmd_buf_data.get_inner(); - if let Some(ref mut list) = cmd_buf_data.commands { + if let Some(ref mut list) = cmd_buf_data.trace_commands { list.push(crate::command::Command::RunRenderPass { base: BasePass { label: base.label.clone(), diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index e351de4c120..52a0312b503 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -850,7 +850,7 @@ impl Global { } #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.commands { + if let Some(ref mut list) = cmd_buf_data.trace_commands { list.push(TraceCommand::CopyBufferToBuffer { src: source, src_offset: source_offset, @@ -1013,7 +1013,7 @@ impl Global { device.check_is_valid()?; #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.commands { + if let Some(ref mut list) = cmd_buf_data.trace_commands { list.push(TraceCommand::CopyBufferToTexture { src: *source, dst: *destination, @@ -1166,7 +1166,7 @@ impl Global { device.check_is_valid()?; #[cfg(feature = "trace")] - if let Some(list) = cmd_buf_data.commands.as_mut() { + if let Some(list) = cmd_buf_data.trace_commands.as_mut() { list.push(TraceCommand::CopyTextureToBuffer { src: *source, dst: *destination, @@ -1333,7 +1333,7 @@ impl Global { let snatch_guard = device.snatchable_lock.read(); #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.commands { + if let Some(ref mut list) = cmd_buf_data.trace_commands { list.push(TraceCommand::CopyTextureToTexture { src: *source, dst: *destination, diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 934e710e110..b900a437a92 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -1206,7 +1206,7 @@ impl Queue { if let Ok(ref mut cmd_buf_data) = cmd_buf_data { trace.add(Action::Submit( submit_index, - cmd_buf_data.commands.take().unwrap(), + cmd_buf_data.trace_commands.take().unwrap(), )); } } From aaf52e93d9929912a63b1a4febdd6bc692505977 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 10 Sep 2025 15:18:46 -0700 Subject: [PATCH 204/303] Move some `*Copy*Info` types out of `wgpu_core::command::transfer` In the future `transfer` will want to use the `Arc` versions of these types. I have exported them from `wgpu_core::command::ffi`, to document that these are used for FFI purposes, and from `wgpu_core::command`, for backwards compatibility, although I also change the in-tree uses to use them from `wgpu_types` instead of from `wgpu_core::command`. --- wgpu-core/src/command/encoder_command.rs | 12 ++++++------ wgpu-core/src/command/ffi.rs | 7 +++++++ wgpu-core/src/command/mod.rs | 5 +++++ wgpu-core/src/command/transfer.rs | 7 +++---- wgpu-core/src/device/queue.rs | 4 ++-- wgpu-core/src/device/trace.rs | 2 +- wgpu/src/backend/wgpu_core.rs | 10 ++++++---- 7 files changed, 30 insertions(+), 17 deletions(-) create mode 100644 wgpu-core/src/command/ffi.rs diff --git a/wgpu-core/src/command/encoder_command.rs b/wgpu-core/src/command/encoder_command.rs index 31d50504f77..058caed025c 100644 --- a/wgpu-core/src/command/encoder_command.rs +++ b/wgpu-core/src/command/encoder_command.rs @@ -15,18 +15,18 @@ pub enum Command { size: Option, }, CopyBufferToTexture { - src: crate::command::TexelCopyBufferInfo, - dst: crate::command::TexelCopyTextureInfo, + src: wgt::TexelCopyBufferInfo, + dst: wgt::TexelCopyTextureInfo, size: wgt::Extent3d, }, CopyTextureToBuffer { - src: crate::command::TexelCopyTextureInfo, - dst: crate::command::TexelCopyBufferInfo, + src: wgt::TexelCopyTextureInfo, + dst: wgt::TexelCopyBufferInfo, size: wgt::Extent3d, }, CopyTextureToTexture { - src: crate::command::TexelCopyTextureInfo, - dst: crate::command::TexelCopyTextureInfo, + src: wgt::TexelCopyTextureInfo, + dst: wgt::TexelCopyTextureInfo, size: wgt::Extent3d, }, ClearBuffer { diff --git a/wgpu-core/src/command/ffi.rs b/wgpu-core/src/command/ffi.rs new file mode 100644 index 00000000000..9f53d7b5634 --- /dev/null +++ b/wgpu-core/src/command/ffi.rs @@ -0,0 +1,7 @@ +//! Types that are useful for FFI bindings to `wgpu`. + +use crate::id; + +pub type TexelCopyBufferInfo = wgt::TexelCopyBufferInfo; +pub type TexelCopyTextureInfo = wgt::TexelCopyTextureInfo; +pub type CopyExternalImageDestInfo = wgt::CopyExternalImageDestInfo; diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 0a84f107403..7ecc517a87e 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -7,6 +7,7 @@ mod compute_command; mod draw; mod encoder; mod encoder_command; +pub mod ffi; mod memory_init; mod pass; mod query; @@ -58,6 +59,10 @@ use thiserror::Error; #[cfg(feature = "trace")] type TraceCommand = Command; +pub type TexelCopyBufferInfo = ffi::TexelCopyBufferInfo; +pub type TexelCopyTextureInfo = ffi::TexelCopyTextureInfo; +pub type CopyExternalImageDestInfo = ffi::CopyExternalImageDestInfo; + const PUSH_CONSTANT_CLEAR_ARRAY: &[u32] = &[0_u32; 64]; /// The current state of a command or pass encoder. diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 52a0312b503..5ce0a2722f2 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -15,7 +15,7 @@ use crate::{ command::{clear_texture, CommandEncoderError, EncoderStateError}, device::{Device, MissingDownlevelFlags}, global::Global, - id::{BufferId, CommandEncoderId, TextureId}, + id::{BufferId, CommandEncoderId}, init_tracker::{ has_copy_partial_init_tracker_coverage, MemoryInitKind, TextureInitRange, TextureInitTrackerAction, @@ -29,9 +29,8 @@ use crate::{ use super::{ClearError, CommandBufferMutable}; -pub type TexelCopyBufferInfo = wgt::TexelCopyBufferInfo; -pub type TexelCopyTextureInfo = wgt::TexelCopyTextureInfo; -pub type CopyExternalImageDestInfo = wgt::CopyExternalImageDestInfo; +use super::TexelCopyBufferInfo; +use super::TexelCopyTextureInfo; #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum CopySide { diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index b900a437a92..eb936ce7095 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -22,7 +22,7 @@ use crate::{ extract_texture_selector, validate_linear_texture_data, validate_texture_buffer_copy, validate_texture_copy_dst_format, validate_texture_copy_range, ClearError, CommandAllocator, CommandBuffer, CommandEncoder, CommandEncoderError, CopySide, - TexelCopyTextureInfo, TransferError, + TransferError, }, device::{DeviceError, WaitIdleError}, get_lowest_common_denom, @@ -1617,7 +1617,7 @@ impl Global { pub fn queue_write_texture( &self, queue_id: QueueId, - destination: &TexelCopyTextureInfo, + destination: &wgt::TexelCopyTextureInfo, data: &[u8], data_layout: &wgt::TexelCopyBufferLayout, size: &wgt::Extent3d, diff --git a/wgpu-core/src/device/trace.rs b/wgpu-core/src/device/trace.rs index 8b76c852dbe..fcb3f589154 100644 --- a/wgpu-core/src/device/trace.rs +++ b/wgpu-core/src/device/trace.rs @@ -140,7 +140,7 @@ pub enum Action<'a> { queued: bool, }, WriteTexture { - to: crate::command::TexelCopyTextureInfo, + to: wgt::TexelCopyTextureInfo, data: FileName, layout: wgt::TexelCopyBufferLayout, size: wgt::Extent3d, diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index 812cd5276a4..b39e846efe3 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -386,8 +386,10 @@ impl ContextWgpuCore { } } -fn map_buffer_copy_view(view: crate::TexelCopyBufferInfo<'_>) -> wgc::command::TexelCopyBufferInfo { - wgc::command::TexelCopyBufferInfo { +fn map_buffer_copy_view( + view: crate::TexelCopyBufferInfo<'_>, +) -> wgt::TexelCopyBufferInfo { + wgt::TexelCopyBufferInfo { buffer: view.buffer.inner.as_core().id, layout: view.layout, } @@ -407,8 +409,8 @@ fn map_texture_copy_view( #[cfg_attr(not(webgl), expect(unused))] fn map_texture_tagged_copy_view( view: crate::CopyExternalImageDestInfo<&api::Texture>, -) -> wgc::command::CopyExternalImageDestInfo { - wgc::command::CopyExternalImageDestInfo { +) -> wgt::CopyExternalImageDestInfo { + wgt::CopyExternalImageDestInfo { texture: view.texture.inner.as_core().id, mip_level: view.mip_level, origin: view.origin, From 1bef4ff193f34aadff530a89d23d678decf510a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20du=20Garreau?= Date: Wed, 27 Aug 2025 18:04:00 +0200 Subject: [PATCH 205/303] wgpu: Make `CommandBuffer` not shared/clonable --- wgpu/src/backend/custom.rs | 2 +- wgpu/src/dispatch.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wgpu/src/backend/custom.rs b/wgpu/src/backend/custom.rs index 767281b5c6a..4d205e0012d 100644 --- a/wgpu/src/backend/custom.rs +++ b/wgpu/src/backend/custom.rs @@ -90,7 +90,7 @@ dyn_type!(pub ref struct DynPipelineCache(dyn PipelineCacheInterface)); dyn_type!(pub mut struct DynCommandEncoder(dyn CommandEncoderInterface)); dyn_type!(pub mut struct DynComputePass(dyn ComputePassInterface)); dyn_type!(pub mut struct DynRenderPass(dyn RenderPassInterface)); -dyn_type!(pub ref struct DynCommandBuffer(dyn CommandBufferInterface)); +dyn_type!(pub mut struct DynCommandBuffer(dyn CommandBufferInterface)); dyn_type!(pub mut struct DynRenderBundleEncoder(dyn RenderBundleEncoderInterface)); dyn_type!(pub ref struct DynRenderBundle(dyn RenderBundleInterface)); dyn_type!(pub ref struct DynSurface(dyn SurfaceInterface)); diff --git a/wgpu/src/dispatch.rs b/wgpu/src/dispatch.rs index 7ce26df0653..06921e9ac2c 100644 --- a/wgpu/src/dispatch.rs +++ b/wgpu/src/dispatch.rs @@ -884,7 +884,7 @@ dispatch_types! {ref type DispatchPipelineCache: PipelineCacheInterface = CorePi dispatch_types! {mut type DispatchCommandEncoder: CommandEncoderInterface = CoreCommandEncoder, WebCommandEncoder, DynCommandEncoder} dispatch_types! {mut type DispatchComputePass: ComputePassInterface = CoreComputePass, WebComputePassEncoder, DynComputePass} dispatch_types! {mut type DispatchRenderPass: RenderPassInterface = CoreRenderPass, WebRenderPassEncoder, DynRenderPass} -dispatch_types! {ref type DispatchCommandBuffer: CommandBufferInterface = CoreCommandBuffer, WebCommandBuffer, DynCommandBuffer} +dispatch_types! {mut type DispatchCommandBuffer: CommandBufferInterface = CoreCommandBuffer, WebCommandBuffer, DynCommandBuffer} dispatch_types! {mut type DispatchRenderBundleEncoder: RenderBundleEncoderInterface = CoreRenderBundleEncoder, WebRenderBundleEncoder, DynRenderBundleEncoder} dispatch_types! {ref type DispatchRenderBundle: RenderBundleInterface = CoreRenderBundle, WebRenderBundle, DynRenderBundle} dispatch_types! {ref type DispatchSurface: SurfaceInterface = CoreSurface, WebSurface, DynSurface} From 33a45e16e0f236e9bc4d7ef0c3edeaa90bf97217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20du=20Garreau?= Date: Wed, 27 Aug 2025 18:08:20 +0200 Subject: [PATCH 206/303] wgpu: Remove `Arc` in WebGPU backend --- wgpu/src/backend/webgpu.rs | 51 +++++++++++++++++++------------------- wgpu/src/cmp.rs | 2 +- wgpu/src/dispatch.rs | 6 ++--- 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/wgpu/src/backend/webgpu.rs b/wgpu/src/backend/webgpu.rs index 75049d38ceb..920ad58ba17 100644 --- a/wgpu/src/backend/webgpu.rs +++ b/wgpu/src/backend/webgpu.rs @@ -51,6 +51,7 @@ macro_rules! impl_send_sync { }; } +#[derive(Clone)] pub struct ContextWebGpu { /// `None` if browser does not advertise support for WebGPU. gpu: Option>, @@ -86,7 +87,7 @@ impl crate::Error { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebShaderModule { module: webgpu_sys::GpuShaderModule, compilation_info: WebShaderCompilationInfo, @@ -1107,7 +1108,7 @@ extern "C" { fn worker(this: &Global) -> JsValue; } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum Canvas { Canvas(web_sys::HtmlCanvasElement), Offscreen(web_sys::OffscreenCanvas), @@ -1147,49 +1148,49 @@ pub fn get_browser_gpu_property( Ok(DefinedNonNullJsValue::new(maybe_undefined_gpu)) } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebAdapter { pub(crate) inner: webgpu_sys::GpuAdapter, /// Unique identifier for this Adapter. ident: crate::cmp::Identifier, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebDevice { pub(crate) inner: webgpu_sys::GpuDevice, /// Unique identifier for this Device. ident: crate::cmp::Identifier, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebQueue { pub(crate) inner: webgpu_sys::GpuQueue, /// Unique identifier for this Queue. ident: crate::cmp::Identifier, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebBindGroupLayout { pub(crate) inner: webgpu_sys::GpuBindGroupLayout, /// Unique identifier for this BindGroupLayout. ident: crate::cmp::Identifier, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebBindGroup { pub(crate) inner: webgpu_sys::GpuBindGroup, /// Unique identifier for this BindGroup. ident: crate::cmp::Identifier, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebTextureView { pub(crate) inner: webgpu_sys::GpuTextureView, /// Unique identifier for this TextureView. ident: crate::cmp::Identifier, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebSampler { pub(crate) inner: webgpu_sys::GpuSampler, /// Unique identifier for this Sampler. @@ -1198,7 +1199,7 @@ pub struct WebSampler { /// Remembers which portion of a buffer has been mapped, along with a reference /// to the mapped portion. -#[derive(Debug)] +#[derive(Debug, Clone)] struct WebBufferMapState { /// The mapped memory of the buffer. pub mapped_buffer: Option, @@ -1210,7 +1211,7 @@ struct WebBufferMapState { /// The WebGPU specification forbids calling `getMappedRange` on a `webgpu_sys::GpuBuffer` more than /// once, so this struct stores the initial mapped range and re-uses it, allowing for multiple `get_mapped_range` /// calls on the Rust-side. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebBuffer { /// The associated GPU buffer. inner: webgpu_sys::GpuBuffer, @@ -1258,66 +1259,66 @@ impl WebBuffer { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebTexture { pub(crate) inner: webgpu_sys::GpuTexture, /// Unique identifier for this Texture. ident: crate::cmp::Identifier, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebExternalTexture { /// Unique identifier for this ExternalTexture. ident: crate::cmp::Identifier, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebBlas { /// Unique identifier for this Blas. ident: crate::cmp::Identifier, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebTlas { /// Unique identifier for this Blas. ident: crate::cmp::Identifier, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebQuerySet { pub(crate) inner: webgpu_sys::GpuQuerySet, /// Unique identifier for this QuerySet. ident: crate::cmp::Identifier, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebPipelineLayout { pub(crate) inner: webgpu_sys::GpuPipelineLayout, /// Unique identifier for this PipelineLayout. ident: crate::cmp::Identifier, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebRenderPipeline { pub(crate) inner: webgpu_sys::GpuRenderPipeline, /// Unique identifier for this RenderPipeline. ident: crate::cmp::Identifier, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebComputePipeline { pub(crate) inner: webgpu_sys::GpuComputePipeline, /// Unique identifier for this ComputePipeline. ident: crate::cmp::Identifier, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebPipelineCache { /// Unique identifier for this PipelineCache. ident: crate::cmp::Identifier, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebCommandEncoder { pub(crate) inner: webgpu_sys::GpuCommandEncoder, /// Unique identifier for this CommandEncoder. @@ -1345,21 +1346,21 @@ pub struct WebCommandBuffer { ident: crate::cmp::Identifier, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebRenderBundleEncoder { pub(crate) inner: webgpu_sys::GpuRenderBundleEncoder, /// Unique identifier for this RenderBundleEncoder. ident: crate::cmp::Identifier, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebRenderBundle { pub(crate) inner: webgpu_sys::GpuRenderBundle, /// Unique identifier for this RenderBundle. ident: crate::cmp::Identifier, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebSurface { gpu: Option>, canvas: Canvas, @@ -1368,7 +1369,7 @@ pub struct WebSurface { ident: crate::cmp::Identifier, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct WebSurfaceOutputDetail { /// Unique identifier for this SurfaceOutputDetail. ident: crate::cmp::Identifier, diff --git a/wgpu/src/cmp.rs b/wgpu/src/cmp.rs index 07e05f49eab..c2ec1265e18 100644 --- a/wgpu/src/cmp.rs +++ b/wgpu/src/cmp.rs @@ -13,7 +13,7 @@ use core::{num::NonZeroU64, sync::atomic::Ordering}; static NEXT_ID: AtomicU64 = AtomicU64::new(1); -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Identifier { inner: NonZeroU64, } diff --git a/wgpu/src/dispatch.rs b/wgpu/src/dispatch.rs index 06921e9ac2c..8e48f7d593e 100644 --- a/wgpu/src/dispatch.rs +++ b/wgpu/src/dispatch.rs @@ -596,7 +596,7 @@ macro_rules! dispatch_types { #[cfg(wgpu_core)] Core(Arc<$core_type>), #[cfg(webgpu)] - WebGPU(Arc<$webgpu_type>), + WebGPU($webgpu_type), #[allow(clippy::allow_attributes, private_interfaces)] #[cfg(custom)] Custom($custom_type), @@ -672,7 +672,7 @@ macro_rules! dispatch_types { impl From<$webgpu_type> for $name { #[inline] fn from(value: $webgpu_type) -> Self { - Self::WebGPU(Arc::new(value)) + Self::WebGPU(value) } } @@ -685,7 +685,7 @@ macro_rules! dispatch_types { #[cfg(wgpu_core)] Self::Core(value) => value.as_ref(), #[cfg(webgpu)] - Self::WebGPU(value) => value.as_ref(), + Self::WebGPU(value) => value, #[cfg(custom)] Self::Custom(value) => value.deref(), #[cfg(not(any(wgpu_core, webgpu)))] From 6815bd364d5aeb26a19ded9d36724cc733c38da6 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Thu, 11 Sep 2025 12:09:13 -0700 Subject: [PATCH 207/303] chore(deps): Update bitflags version (#8209) I think what happened here is that another reference to 2.9.3 was added to Cargo.lock in parallel with the renovate change that bumped the version to 2.9.4. --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 46276fd94b5..57ee57c5425 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2574,7 +2574,7 @@ dependencies = [ name = "naga-test" version = "26.0.0" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "env_logger", "naga", "ron", From 67bdd80a389fd51470b87a261fa93e1fee9404e8 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Thu, 11 Sep 2025 12:10:05 -0700 Subject: [PATCH 208/303] Add cbindgen:ignore directives (#8212) --- wgpu-core/src/command/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 7ecc517a87e..ca3a831efed 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -59,8 +59,11 @@ use thiserror::Error; #[cfg(feature = "trace")] type TraceCommand = Command; +/// cbindgen:ignore pub type TexelCopyBufferInfo = ffi::TexelCopyBufferInfo; +/// cbindgen:ignore pub type TexelCopyTextureInfo = ffi::TexelCopyTextureInfo; +/// cbindgen:ignore pub type CopyExternalImageDestInfo = ffi::CopyExternalImageDestInfo; const PUSH_CONSTANT_CLEAR_ARRAY: &[u32] = &[0_u32; 64]; From 04a34016384963bf26353fad472b5d2c5ecdc359 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Thu, 11 Sep 2025 12:15:33 -0700 Subject: [PATCH 209/303] Extract command encoding to free functions (#8210) --- wgpu-core/src/command/clear.rs | 303 ++++--- wgpu-core/src/command/compute.rs | 518 +++++------ wgpu-core/src/command/memory_init.rs | 2 +- wgpu-core/src/command/mod.rs | 151 ++-- wgpu-core/src/command/query.rs | 298 ++++--- wgpu-core/src/command/ray_tracing.rs | 623 +++++++------- wgpu-core/src/command/render.rs | 843 +++++++++--------- wgpu-core/src/command/transfer.rs | 1184 +++++++++++++------------- 8 files changed, 2027 insertions(+), 1895 deletions(-) diff --git a/wgpu-core/src/command/clear.rs b/wgpu-core/src/command/clear.rs index 3781cd20331..04d800e670e 100644 --- a/wgpu-core/src/command/clear.rs +++ b/wgpu-core/src/command/clear.rs @@ -5,7 +5,7 @@ use core::ops::Range; use crate::command::Command as TraceCommand; use crate::{ api_log, - command::EncoderStateError, + command::{CommandBufferMutable, CommandEncoder, EncoderStateError}, device::{DeviceError, MissingFeatures}, get_lowest_common_denom, global::Global, @@ -119,74 +119,7 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), ClearError> { - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::ClearBuffer { dst, offset, size }); - } - - cmd_enc.device.check_is_valid()?; - - let dst_buffer = hub.buffers.get(dst).get()?; - - dst_buffer.same_device_as(cmd_enc.as_ref())?; - - let dst_pending = cmd_buf_data - .trackers - .buffers - .set_single(&dst_buffer, wgt::BufferUses::COPY_DST); - - let snatch_guard = dst_buffer.device.snatchable_lock.read(); - let dst_raw = dst_buffer.try_raw(&snatch_guard)?; - dst_buffer.check_usage(BufferUsages::COPY_DST)?; - - // Check if offset & size are valid. - if offset % wgt::COPY_BUFFER_ALIGNMENT != 0 { - return Err(ClearError::UnalignedBufferOffset(offset)); - } - - let size = size.unwrap_or(dst_buffer.size.saturating_sub(offset)); - if size % wgt::COPY_BUFFER_ALIGNMENT != 0 { - return Err(ClearError::UnalignedFillSize(size)); - } - let end_offset = - offset - .checked_add(size) - .ok_or(ClearError::OffsetPlusSizeExceeds64BitBounds { - start_offset: offset, - requested_size: size, - })?; - if end_offset > dst_buffer.size { - return Err(ClearError::BufferOverrun { - start_offset: offset, - end_offset, - buffer_size: dst_buffer.size, - }); - } - - if offset == end_offset { - log::trace!("Ignoring fill_buffer of size 0"); - return Ok(()); - } - - // Mark dest as initialized. - cmd_buf_data.buffer_memory_init_actions.extend( - dst_buffer.initialization_status.read().create_action( - &dst_buffer, - offset..end_offset, - MemoryInitKind::ImplicitlyInitialized, - ), - ); - - // actual hal barrier & operation - let dst_barrier = - dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); - let cmd_buf_raw = cmd_buf_data.encoder.open()?; - unsafe { - cmd_buf_raw.transition_buffers(dst_barrier.as_slice()); - cmd_buf_raw.clear_buffer(dst_raw, offset..end_offset); - } - - Ok(()) + clear_buffer(cmd_buf_data, hub, &cmd_enc, dst, offset, size) }) } @@ -204,83 +137,181 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), ClearError> { - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::ClearTexture { - dst, - subresource_range: *subresource_range, - }); - } + clear_texture_cmd(cmd_buf_data, hub, &cmd_enc, dst, subresource_range) + }) + } +} - cmd_enc.device.check_is_valid()?; +pub(super) fn clear_buffer( + cmd_buf_data: &mut CommandBufferMutable, + hub: &crate::hub::Hub, + cmd_enc: &Arc, + dst: BufferId, + offset: BufferAddress, + size: Option, +) -> Result<(), ClearError> { + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace_commands { + list.push(TraceCommand::ClearBuffer { dst, offset, size }); + } - cmd_enc - .device - .require_features(wgt::Features::CLEAR_TEXTURE)?; + cmd_enc.device.check_is_valid()?; - let dst_texture = hub.textures.get(dst).get()?; + let dst_buffer = hub.buffers.get(dst).get()?; - dst_texture.same_device_as(cmd_enc.as_ref())?; + dst_buffer.same_device_as(cmd_enc.as_ref())?; - // Check if subresource aspects are valid. - let clear_aspects = - hal::FormatAspects::new(dst_texture.desc.format, subresource_range.aspect); - if clear_aspects.is_empty() { - return Err(ClearError::MissingTextureAspect { - texture_format: dst_texture.desc.format, - subresource_range_aspects: subresource_range.aspect, - }); - }; + let dst_pending = cmd_buf_data + .trackers + .buffers + .set_single(&dst_buffer, wgt::BufferUses::COPY_DST); - // Check if subresource level range is valid - let subresource_mip_range = - subresource_range.mip_range(dst_texture.full_range.mips.end); - if dst_texture.full_range.mips.start > subresource_mip_range.start - || dst_texture.full_range.mips.end < subresource_mip_range.end - { - return Err(ClearError::InvalidTextureLevelRange { - texture_level_range: dst_texture.full_range.mips.clone(), - subresource_base_mip_level: subresource_range.base_mip_level, - subresource_mip_level_count: subresource_range.mip_level_count, - }); - } - // Check if subresource layer range is valid - let subresource_layer_range = - subresource_range.layer_range(dst_texture.full_range.layers.end); - if dst_texture.full_range.layers.start > subresource_layer_range.start - || dst_texture.full_range.layers.end < subresource_layer_range.end - { - return Err(ClearError::InvalidTextureLayerRange { - texture_layer_range: dst_texture.full_range.layers.clone(), - subresource_base_array_layer: subresource_range.base_array_layer, - subresource_array_layer_count: subresource_range.array_layer_count, - }); - } + let snatch_guard = dst_buffer.device.snatchable_lock.read(); + let dst_raw = dst_buffer.try_raw(&snatch_guard)?; + dst_buffer.check_usage(BufferUsages::COPY_DST)?; - let device = &cmd_enc.device; - device.check_is_valid()?; - let (encoder, tracker) = cmd_buf_data.open_encoder_and_tracker()?; - - let snatch_guard = device.snatchable_lock.read(); - clear_texture( - &dst_texture, - TextureInitRange { - mip_range: subresource_mip_range, - layer_range: subresource_layer_range, - }, - encoder, - &mut tracker.textures, - &device.alignments, - device.zero_buffer.as_ref(), - &snatch_guard, - device.instance_flags, - )?; - - Ok(()) - }) + // Check if offset & size are valid. + if offset % wgt::COPY_BUFFER_ALIGNMENT != 0 { + return Err(ClearError::UnalignedBufferOffset(offset)); + } + + let size = size.unwrap_or(dst_buffer.size.saturating_sub(offset)); + if size % wgt::COPY_BUFFER_ALIGNMENT != 0 { + return Err(ClearError::UnalignedFillSize(size)); + } + let end_offset = + offset + .checked_add(size) + .ok_or(ClearError::OffsetPlusSizeExceeds64BitBounds { + start_offset: offset, + requested_size: size, + })?; + if end_offset > dst_buffer.size { + return Err(ClearError::BufferOverrun { + start_offset: offset, + end_offset, + buffer_size: dst_buffer.size, + }); } + + if offset == end_offset { + log::trace!("Ignoring fill_buffer of size 0"); + return Ok(()); + } + + // Mark dest as initialized. + cmd_buf_data.buffer_memory_init_actions.extend( + dst_buffer.initialization_status.read().create_action( + &dst_buffer, + offset..end_offset, + MemoryInitKind::ImplicitlyInitialized, + ), + ); + + // actual hal barrier & operation + let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); + let cmd_buf_raw = cmd_buf_data.encoder.open()?; + unsafe { + cmd_buf_raw.transition_buffers(dst_barrier.as_slice()); + cmd_buf_raw.clear_buffer(dst_raw, offset..end_offset); + } + + Ok(()) +} + +/// Validate and encode a "Clear Texture" command. +/// +/// This function implements `CommandEncoder::clear_texture` when invoked via +/// the command encoder APIs or trace playback. It has the suffix `_cmd` to +/// distinguish it from [`clear_texture`]. [`clear_texture`], used internally by +/// this function, is a lower-level function that encodes a texture clear +/// operation without validating it. +pub(super) fn clear_texture_cmd( + cmd_buf_data: &mut CommandBufferMutable, + hub: &crate::hub::Hub, + cmd_enc: &Arc, + dst: TextureId, + subresource_range: &ImageSubresourceRange, +) -> Result<(), ClearError> { + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace_commands { + list.push(TraceCommand::ClearTexture { + dst, + subresource_range: *subresource_range, + }); + } + + cmd_enc.device.check_is_valid()?; + + cmd_enc + .device + .require_features(wgt::Features::CLEAR_TEXTURE)?; + + let dst_texture = hub.textures.get(dst).get()?; + + dst_texture.same_device_as(cmd_enc.as_ref())?; + + // Check if subresource aspects are valid. + let clear_aspects = hal::FormatAspects::new(dst_texture.desc.format, subresource_range.aspect); + if clear_aspects.is_empty() { + return Err(ClearError::MissingTextureAspect { + texture_format: dst_texture.desc.format, + subresource_range_aspects: subresource_range.aspect, + }); + }; + + // Check if subresource level range is valid + let subresource_mip_range = subresource_range.mip_range(dst_texture.full_range.mips.end); + if dst_texture.full_range.mips.start > subresource_mip_range.start + || dst_texture.full_range.mips.end < subresource_mip_range.end + { + return Err(ClearError::InvalidTextureLevelRange { + texture_level_range: dst_texture.full_range.mips.clone(), + subresource_base_mip_level: subresource_range.base_mip_level, + subresource_mip_level_count: subresource_range.mip_level_count, + }); + } + // Check if subresource layer range is valid + let subresource_layer_range = subresource_range.layer_range(dst_texture.full_range.layers.end); + if dst_texture.full_range.layers.start > subresource_layer_range.start + || dst_texture.full_range.layers.end < subresource_layer_range.end + { + return Err(ClearError::InvalidTextureLayerRange { + texture_layer_range: dst_texture.full_range.layers.clone(), + subresource_base_array_layer: subresource_range.base_array_layer, + subresource_array_layer_count: subresource_range.array_layer_count, + }); + } + + let device = &cmd_enc.device; + device.check_is_valid()?; + let (encoder, tracker) = cmd_buf_data.open_encoder_and_tracker()?; + + let snatch_guard = device.snatchable_lock.read(); + clear_texture( + &dst_texture, + TextureInitRange { + mip_range: subresource_mip_range, + layer_range: subresource_layer_range, + }, + encoder, + &mut tracker.textures, + &device.alignments, + device.zero_buffer.as_ref(), + &snatch_guard, + device.instance_flags, + )?; + + Ok(()) } +/// Encode a texture clear operation. +/// +/// This function encodes a texture clear operation without validating it. +/// Texture clears requested via the API call this function via +/// [`clear_texture_cmd`], which does the validation. This function is also +/// called directly from various places within wgpu that need to clear a +/// texture. pub(crate) fn clear_texture( dst_texture: &Arc, range: TextureInitRange, diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index a9d0795e7d0..dd0258797a1 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -8,8 +8,8 @@ use alloc::{borrow::Cow, boxed::Box, sync::Arc, vec::Vec}; use core::{fmt, str}; use crate::command::{ - encoder::EncodingState, pass, CommandEncoder, DebugGroupError, EncoderStateError, - PassStateError, TimestampWritesError, + encoder::EncodingState, pass, CommandBufferMutable, CommandEncoder, DebugGroupError, + EncoderStateError, PassStateError, TimestampWritesError, }; use crate::resource::DestroyedResourceError; use crate::{binding_model::BindError, resource::RawResourceAccess}; @@ -486,7 +486,6 @@ impl Global { } pub fn compute_pass_end(&self, pass: &mut ComputePass) -> Result<(), EncoderStateError> { - let pass_scope = PassErrorScope::Pass; profiling::scope!( "CommandEncoder::run_compute_pass {}", pass.base.label.as_deref().unwrap_or("") @@ -518,286 +517,291 @@ impl Global { } cmd_buf_data.unlock_and_record(|cmd_buf_data| -> Result<(), ComputePassError> { - let device = &cmd_enc.device; - device.check_is_valid().map_pass_err(pass_scope)?; + encode_compute_pass(cmd_buf_data, &cmd_enc, pass) + }) + } +} - let base = &mut pass.base; +fn encode_compute_pass( + cmd_buf_data: &mut CommandBufferMutable, + cmd_enc: &Arc, + pass: &mut ComputePass, +) -> Result<(), ComputePassError> { + let pass_scope = PassErrorScope::Pass; - let encoder = &mut cmd_buf_data.encoder; + let device = &cmd_enc.device; + device.check_is_valid().map_pass_err(pass_scope)?; - // We automatically keep extending command buffers over time, and because - // we want to insert a command buffer _before_ what we're about to record, - // we need to make sure to close the previous one. - encoder.close_if_open().map_pass_err(pass_scope)?; - let raw_encoder = encoder - .open_pass(base.label.as_deref()) - .map_pass_err(pass_scope)?; + let base = &mut pass.base; - let snatch_guard = device.snatchable_lock.read(); - let mut debug_scope_depth = 0; - - let mut state = State { - pipeline: None, - - pass: pass::PassState { - base: EncodingState { - device, - raw_encoder, - tracker: &mut cmd_buf_data.trackers, - buffer_memory_init_actions: &mut cmd_buf_data.buffer_memory_init_actions, - texture_memory_actions: &mut cmd_buf_data.texture_memory_actions, - as_actions: &mut cmd_buf_data.as_actions, - indirect_draw_validation_resources: &mut cmd_buf_data - .indirect_draw_validation_resources, - snatch_guard: &snatch_guard, - debug_scope_depth: &mut debug_scope_depth, - }, - binder: Binder::new(), - temp_offsets: Vec::new(), - dynamic_offset_count: 0, + let encoder = &mut cmd_buf_data.encoder; - pending_discard_init_fixups: SurfacesInDiscardState::new(), + // We automatically keep extending command buffers over time, and because + // we want to insert a command buffer _before_ what we're about to record, + // we need to make sure to close the previous one. + encoder.close_if_open().map_pass_err(pass_scope)?; + let raw_encoder = encoder + .open_pass(base.label.as_deref()) + .map_pass_err(pass_scope)?; - scope: device.new_usage_scope(), + let snatch_guard = device.snatchable_lock.read(); + let mut debug_scope_depth = 0; - string_offset: 0, - }, - active_query: None, + let mut state = State { + pipeline: None, - push_constants: Vec::new(), + pass: pass::PassState { + base: EncodingState { + device, + raw_encoder, + tracker: &mut cmd_buf_data.trackers, + buffer_memory_init_actions: &mut cmd_buf_data.buffer_memory_init_actions, + texture_memory_actions: &mut cmd_buf_data.texture_memory_actions, + as_actions: &mut cmd_buf_data.as_actions, + indirect_draw_validation_resources: &mut cmd_buf_data + .indirect_draw_validation_resources, + snatch_guard: &snatch_guard, + debug_scope_depth: &mut debug_scope_depth, + }, + binder: Binder::new(), + temp_offsets: Vec::new(), + dynamic_offset_count: 0, - intermediate_trackers: Tracker::new(), - }; + pending_discard_init_fixups: SurfacesInDiscardState::new(), - let indices = &state.pass.base.device.tracker_indices; - state - .pass - .base - .tracker - .buffers - .set_size(indices.buffers.size()); - state + scope: device.new_usage_scope(), + + string_offset: 0, + }, + active_query: None, + + push_constants: Vec::new(), + + intermediate_trackers: Tracker::new(), + }; + + let indices = &state.pass.base.device.tracker_indices; + state + .pass + .base + .tracker + .buffers + .set_size(indices.buffers.size()); + state + .pass + .base + .tracker + .textures + .set_size(indices.textures.size()); + + let timestamp_writes: Option> = + if let Some(tw) = pass.timestamp_writes.take() { + tw.query_set + .same_device_as(cmd_enc.as_ref()) + .map_pass_err(pass_scope)?; + + let query_set = state .pass .base .tracker - .textures - .set_size(indices.textures.size()); + .query_sets + .insert_single(tw.query_set); - let timestamp_writes: Option> = - if let Some(tw) = pass.timestamp_writes.take() { - tw.query_set - .same_device_as(cmd_enc.as_ref()) - .map_pass_err(pass_scope)?; - - let query_set = state + // Unlike in render passes we can't delay resetting the query sets since + // there is no auxiliary pass. + let range = if let (Some(index_a), Some(index_b)) = + (tw.beginning_of_pass_write_index, tw.end_of_pass_write_index) + { + Some(index_a.min(index_b)..index_a.max(index_b) + 1) + } else { + tw.beginning_of_pass_write_index + .or(tw.end_of_pass_write_index) + .map(|i| i..i + 1) + }; + // Range should always be Some, both values being None should lead to a validation error. + // But no point in erroring over that nuance here! + if let Some(range) = range { + unsafe { + state .pass .base - .tracker - .query_sets - .insert_single(tw.query_set); - - // Unlike in render passes we can't delay resetting the query sets since - // there is no auxiliary pass. - let range = if let (Some(index_a), Some(index_b)) = - (tw.beginning_of_pass_write_index, tw.end_of_pass_write_index) - { - Some(index_a.min(index_b)..index_a.max(index_b) + 1) - } else { - tw.beginning_of_pass_write_index - .or(tw.end_of_pass_write_index) - .map(|i| i..i + 1) - }; - // Range should always be Some, both values being None should lead to a validation error. - // But no point in erroring over that nuance here! - if let Some(range) = range { - unsafe { - state - .pass - .base - .raw_encoder - .reset_queries(query_set.raw(), range); - } - } + .raw_encoder + .reset_queries(query_set.raw(), range); + } + } - Some(hal::PassTimestampWrites { - query_set: query_set.raw(), - beginning_of_pass_write_index: tw.beginning_of_pass_write_index, - end_of_pass_write_index: tw.end_of_pass_write_index, - }) - } else { - None - }; + Some(hal::PassTimestampWrites { + query_set: query_set.raw(), + beginning_of_pass_write_index: tw.beginning_of_pass_write_index, + end_of_pass_write_index: tw.end_of_pass_write_index, + }) + } else { + None + }; - let hal_desc = hal::ComputePassDescriptor { - label: hal_label(base.label.as_deref(), device.instance_flags), - timestamp_writes, - }; + let hal_desc = hal::ComputePassDescriptor { + label: hal_label(base.label.as_deref(), device.instance_flags), + timestamp_writes, + }; - unsafe { - state.pass.base.raw_encoder.begin_compute_pass(&hal_desc); - } + unsafe { + state.pass.base.raw_encoder.begin_compute_pass(&hal_desc); + } - for command in base.commands.drain(..) { - match command { - ArcComputeCommand::SetBindGroup { - index, - num_dynamic_offsets, - bind_group, - } => { - let scope = PassErrorScope::SetBindGroup; - pass::set_bind_group::( - &mut state.pass, - cmd_enc.as_ref(), - &base.dynamic_offsets, - index, - num_dynamic_offsets, - bind_group, - false, - ) - .map_pass_err(scope)?; - } - ArcComputeCommand::SetPipeline(pipeline) => { - let scope = PassErrorScope::SetPipelineCompute; - set_pipeline(&mut state, cmd_enc.as_ref(), pipeline).map_pass_err(scope)?; - } - ArcComputeCommand::SetPushConstant { - offset, - size_bytes, - values_offset, - } => { - let scope = PassErrorScope::SetPushConstant; - pass::set_push_constant::( - &mut state.pass, - &base.push_constant_data, - wgt::ShaderStages::COMPUTE, - offset, - size_bytes, - Some(values_offset), - |data_slice| { - let offset_in_elements = - (offset / wgt::PUSH_CONSTANT_ALIGNMENT) as usize; - let size_in_elements = - (size_bytes / wgt::PUSH_CONSTANT_ALIGNMENT) as usize; - state.push_constants[offset_in_elements..][..size_in_elements] - .copy_from_slice(data_slice); - }, - ) - .map_pass_err(scope)?; - } - ArcComputeCommand::Dispatch(groups) => { - let scope = PassErrorScope::Dispatch { indirect: false }; - dispatch(&mut state, groups).map_pass_err(scope)?; - } - ArcComputeCommand::DispatchIndirect { buffer, offset } => { - let scope = PassErrorScope::Dispatch { indirect: true }; - dispatch_indirect(&mut state, cmd_enc.as_ref(), buffer, offset) - .map_pass_err(scope)?; - } - ArcComputeCommand::PushDebugGroup { color: _, len } => { - pass::push_debug_group(&mut state.pass, &base.string_data, len); - } - ArcComputeCommand::PopDebugGroup => { - let scope = PassErrorScope::PopDebugGroup; - pass::pop_debug_group::(&mut state.pass) - .map_pass_err(scope)?; - } - ArcComputeCommand::InsertDebugMarker { color: _, len } => { - pass::insert_debug_marker(&mut state.pass, &base.string_data, len); - } - ArcComputeCommand::WriteTimestamp { - query_set, - query_index, - } => { - let scope = PassErrorScope::WriteTimestamp; - pass::write_timestamp::( - &mut state.pass, - cmd_enc.as_ref(), - None, - query_set, - query_index, - ) - .map_pass_err(scope)?; - } - ArcComputeCommand::BeginPipelineStatisticsQuery { - query_set, - query_index, - } => { - let scope = PassErrorScope::BeginPipelineStatisticsQuery; - validate_and_begin_pipeline_statistics_query( - query_set, - state.pass.base.raw_encoder, - &mut state.pass.base.tracker.query_sets, - cmd_enc.as_ref(), - query_index, - None, - &mut state.active_query, - ) - .map_pass_err(scope)?; - } - ArcComputeCommand::EndPipelineStatisticsQuery => { - let scope = PassErrorScope::EndPipelineStatisticsQuery; - end_pipeline_statistics_query( - state.pass.base.raw_encoder, - &mut state.active_query, - ) - .map_pass_err(scope)?; - } - } + for command in base.commands.drain(..) { + match command { + ArcComputeCommand::SetBindGroup { + index, + num_dynamic_offsets, + bind_group, + } => { + let scope = PassErrorScope::SetBindGroup; + pass::set_bind_group::( + &mut state.pass, + cmd_enc.as_ref(), + &base.dynamic_offsets, + index, + num_dynamic_offsets, + bind_group, + false, + ) + .map_pass_err(scope)?; } - - if *state.pass.base.debug_scope_depth > 0 { - Err( - ComputePassErrorInner::DebugGroupError(DebugGroupError::MissingPop) - .map_pass_err(pass_scope), - )?; + ArcComputeCommand::SetPipeline(pipeline) => { + let scope = PassErrorScope::SetPipelineCompute; + set_pipeline(&mut state, cmd_enc.as_ref(), pipeline).map_pass_err(scope)?; } - - unsafe { - state.pass.base.raw_encoder.end_compute_pass(); + ArcComputeCommand::SetPushConstant { + offset, + size_bytes, + values_offset, + } => { + let scope = PassErrorScope::SetPushConstant; + pass::set_push_constant::( + &mut state.pass, + &base.push_constant_data, + wgt::ShaderStages::COMPUTE, + offset, + size_bytes, + Some(values_offset), + |data_slice| { + let offset_in_elements = (offset / wgt::PUSH_CONSTANT_ALIGNMENT) as usize; + let size_in_elements = (size_bytes / wgt::PUSH_CONSTANT_ALIGNMENT) as usize; + state.push_constants[offset_in_elements..][..size_in_elements] + .copy_from_slice(data_slice); + }, + ) + .map_pass_err(scope)?; + } + ArcComputeCommand::Dispatch(groups) => { + let scope = PassErrorScope::Dispatch { indirect: false }; + dispatch(&mut state, groups).map_pass_err(scope)?; + } + ArcComputeCommand::DispatchIndirect { buffer, offset } => { + let scope = PassErrorScope::Dispatch { indirect: true }; + dispatch_indirect(&mut state, cmd_enc.as_ref(), buffer, offset) + .map_pass_err(scope)?; + } + ArcComputeCommand::PushDebugGroup { color: _, len } => { + pass::push_debug_group(&mut state.pass, &base.string_data, len); + } + ArcComputeCommand::PopDebugGroup => { + let scope = PassErrorScope::PopDebugGroup; + pass::pop_debug_group::(&mut state.pass) + .map_pass_err(scope)?; + } + ArcComputeCommand::InsertDebugMarker { color: _, len } => { + pass::insert_debug_marker(&mut state.pass, &base.string_data, len); + } + ArcComputeCommand::WriteTimestamp { + query_set, + query_index, + } => { + let scope = PassErrorScope::WriteTimestamp; + pass::write_timestamp::( + &mut state.pass, + cmd_enc.as_ref(), + None, + query_set, + query_index, + ) + .map_pass_err(scope)?; + } + ArcComputeCommand::BeginPipelineStatisticsQuery { + query_set, + query_index, + } => { + let scope = PassErrorScope::BeginPipelineStatisticsQuery; + validate_and_begin_pipeline_statistics_query( + query_set, + state.pass.base.raw_encoder, + &mut state.pass.base.tracker.query_sets, + cmd_enc.as_ref(), + query_index, + None, + &mut state.active_query, + ) + .map_pass_err(scope)?; + } + ArcComputeCommand::EndPipelineStatisticsQuery => { + let scope = PassErrorScope::EndPipelineStatisticsQuery; + end_pipeline_statistics_query(state.pass.base.raw_encoder, &mut state.active_query) + .map_pass_err(scope)?; } + } + } - let State { - pass: - pass::PassState { - base: EncodingState { tracker, .. }, - pending_discard_init_fixups, - .. - }, - intermediate_trackers, - .. - } = state; - - // Stop the current command encoder. - encoder.close().map_pass_err(pass_scope)?; - - // Create a new command encoder, which we will insert _before_ the body of the compute pass. - // - // Use that buffer to insert barriers and clear discarded images. - let transit = encoder - .open_pass(hal_label( - Some("(wgpu internal) Pre Pass"), - self.instance.flags, - )) - .map_pass_err(pass_scope)?; - fixup_discarded_surfaces( - pending_discard_init_fixups.into_iter(), - transit, - &mut tracker.textures, - device, - &snatch_guard, - ); - CommandEncoder::insert_barriers_from_tracker( - transit, - tracker, - &intermediate_trackers, - &snatch_guard, - ); - // Close the command encoder, and swap it with the previous. - encoder.close_and_swap().map_pass_err(pass_scope)?; + if *state.pass.base.debug_scope_depth > 0 { + Err( + ComputePassErrorInner::DebugGroupError(DebugGroupError::MissingPop) + .map_pass_err(pass_scope), + )?; + } - Ok(()) - }) + unsafe { + state.pass.base.raw_encoder.end_compute_pass(); } + + let State { + pass: + pass::PassState { + base: EncodingState { tracker, .. }, + pending_discard_init_fixups, + .. + }, + intermediate_trackers, + .. + } = state; + + // Stop the current command encoder. + encoder.close().map_pass_err(pass_scope)?; + + // Create a new command encoder, which we will insert _before_ the body of the compute pass. + // + // Use that buffer to insert barriers and clear discarded images. + let transit = encoder + .open_pass(hal_label( + Some("(wgpu internal) Pre Pass"), + device.instance_flags, + )) + .map_pass_err(pass_scope)?; + fixup_discarded_surfaces( + pending_discard_init_fixups.into_iter(), + transit, + &mut tracker.textures, + device, + &snatch_guard, + ); + CommandEncoder::insert_barriers_from_tracker( + transit, + tracker, + &intermediate_trackers, + &snatch_guard, + ); + // Close the command encoder, and swap it with the previous. + encoder.close_and_swap().map_pass_err(pass_scope)?; + + Ok(()) } fn set_pipeline( diff --git a/wgpu-core/src/command/memory_init.rs b/wgpu-core/src/command/memory_init.rs index 9057e637256..faca417040e 100644 --- a/wgpu-core/src/command/memory_init.rs +++ b/wgpu-core/src/command/memory_init.rs @@ -15,7 +15,7 @@ use crate::{ FastHashMap, }; -use super::{clear::clear_texture, BakedCommands, ClearError}; +use super::{clear_texture, BakedCommands, ClearError}; /// Surface that was discarded by `StoreOp::Discard` of a preceding renderpass. /// Any read access to this surface needs to be preceded by a texture initialization. diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index ca3a831efed..29b1c7da267 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -1230,27 +1230,7 @@ impl Global { let cmd_enc = hub.command_encoders.get(encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - cmd_buf_data.debug_scope_depth += 1; - - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::PushDebugGroup(label.to_owned())); - } - - cmd_enc.device.check_is_valid()?; - - let cmd_buf_raw = cmd_buf_data.encoder.open()?; - if !cmd_enc - .device - .instance_flags - .contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) - { - unsafe { - cmd_buf_raw.begin_debug_marker(label); - } - } - - Ok(()) + push_debug_group(cmd_buf_data, &cmd_enc, label) }) } @@ -1267,25 +1247,7 @@ impl Global { let cmd_enc = hub.command_encoders.get(encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::InsertDebugMarker(label.to_owned())); - } - - cmd_enc.device.check_is_valid()?; - - if !cmd_enc - .device - .instance_flags - .contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) - { - let cmd_buf_raw = cmd_buf_data.encoder.open()?; - unsafe { - cmd_buf_raw.insert_debug_marker(label); - } - } - - Ok(()) + insert_debug_marker(cmd_buf_data, &cmd_enc, label) }) } @@ -1301,30 +1263,7 @@ impl Global { let cmd_enc = hub.command_encoders.get(encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - if cmd_buf_data.debug_scope_depth == 0 { - return Err(DebugGroupError::InvalidPop.into()); - } - cmd_buf_data.debug_scope_depth -= 1; - - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::PopDebugGroup); - } - - cmd_enc.device.check_is_valid()?; - - let cmd_buf_raw = cmd_buf_data.encoder.open()?; - if !cmd_enc - .device - .instance_flags - .contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) - { - unsafe { - cmd_buf_raw.end_debug_marker(); - } - } - - Ok(()) + pop_debug_group(cmd_buf_data, &cmd_enc) }) } @@ -1380,6 +1319,90 @@ impl Global { } } +pub(crate) fn push_debug_group( + cmd_buf_data: &mut CommandBufferMutable, + cmd_enc: &Arc, + label: &str, +) -> Result<(), CommandEncoderError> { + cmd_buf_data.debug_scope_depth += 1; + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace_commands { + list.push(TraceCommand::PushDebugGroup(label.to_owned())); + } + + cmd_enc.device.check_is_valid()?; + + let cmd_buf_raw = cmd_buf_data.encoder.open()?; + if !cmd_enc + .device + .instance_flags + .contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) + { + unsafe { + cmd_buf_raw.begin_debug_marker(label); + } + } + + Ok(()) +} + +pub(crate) fn insert_debug_marker( + cmd_buf_data: &mut CommandBufferMutable, + cmd_enc: &Arc, + label: &str, +) -> Result<(), CommandEncoderError> { + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace_commands { + list.push(TraceCommand::InsertDebugMarker(label.to_owned())); + } + + cmd_enc.device.check_is_valid()?; + + if !cmd_enc + .device + .instance_flags + .contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) + { + let cmd_buf_raw = cmd_buf_data.encoder.open()?; + unsafe { + cmd_buf_raw.insert_debug_marker(label); + } + } + + Ok(()) +} + +pub(crate) fn pop_debug_group( + cmd_buf_data: &mut CommandBufferMutable, + cmd_enc: &Arc, +) -> Result<(), CommandEncoderError> { + if cmd_buf_data.debug_scope_depth == 0 { + return Err(DebugGroupError::InvalidPop.into()); + } + cmd_buf_data.debug_scope_depth -= 1; + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace_commands { + list.push(TraceCommand::PopDebugGroup); + } + + cmd_enc.device.check_is_valid()?; + + let cmd_buf_raw = cmd_buf_data.encoder.open()?; + if !cmd_enc + .device + .instance_flags + .contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) + { + unsafe { + cmd_buf_raw.end_debug_marker(); + } + } + + Ok(()) +} + fn push_constant_clear(offset: u32, size_bytes: u32, mut push_fn: PushFn) where PushFn: FnMut(u32, &[u32]), diff --git a/wgpu-core/src/command/query.rs b/wgpu-core/src/command/query.rs index dc754f8070b..694b41525d2 100644 --- a/wgpu-core/src/command/query.rs +++ b/wgpu-core/src/command/query.rs @@ -4,7 +4,7 @@ use core::{iter, mem}; #[cfg(feature = "trace")] use crate::command::Command as TraceCommand; use crate::{ - command::{CommandEncoder, EncoderStateError}, + command::{CommandBufferMutable, CommandEncoder, EncoderStateError}, device::{DeviceError, MissingFeatures}, global::Global, id, @@ -366,30 +366,7 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), QueryError> { - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::WriteTimestamp { - query_set_id, - query_index, - }); - } - - cmd_enc.device.check_is_valid()?; - - cmd_enc - .device - .require_features(wgt::Features::TIMESTAMP_QUERY_INSIDE_ENCODERS)?; - - let raw_encoder = cmd_buf_data.encoder.open()?; - - let query_set = hub.query_sets.get(query_set_id).get()?; - query_set.same_device_as(cmd_enc.as_ref())?; - - query_set.validate_and_write_timestamp(raw_encoder, query_index, None)?; - - cmd_buf_data.trackers.query_sets.insert_single(query_set); - - Ok(()) + write_timestamp(cmd_buf_data, hub, &cmd_enc, query_set_id, query_index) }) } @@ -407,129 +384,182 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), QueryError> { - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::ResolveQuerySet { - query_set_id, - start_query, - query_count, - destination, - destination_offset, - }); - } + resolve_query_set( + cmd_buf_data, + hub, + &cmd_enc, + query_set_id, + start_query, + query_count, + destination, + destination_offset, + ) + }) + } +} + +pub(super) fn write_timestamp( + cmd_buf_data: &mut CommandBufferMutable, + hub: &crate::hub::Hub, + cmd_enc: &Arc, + query_set_id: id::QuerySetId, + query_index: u32, +) -> Result<(), QueryError> { + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace_commands { + list.push(TraceCommand::WriteTimestamp { + query_set_id, + query_index, + }); + } - cmd_enc.device.check_is_valid()?; + cmd_enc.device.check_is_valid()?; - if destination_offset % wgt::QUERY_RESOLVE_BUFFER_ALIGNMENT != 0 { - return Err(QueryError::Resolve(ResolveError::BufferOffsetAlignment)); - } + cmd_enc + .device + .require_features(wgt::Features::TIMESTAMP_QUERY_INSIDE_ENCODERS)?; + + let raw_encoder = cmd_buf_data.encoder.open()?; + + let query_set = hub.query_sets.get(query_set_id).get()?; + query_set.same_device_as(cmd_enc.as_ref())?; + + query_set.validate_and_write_timestamp(raw_encoder, query_index, None)?; - let query_set = hub.query_sets.get(query_set_id).get()?; + cmd_buf_data.trackers.query_sets.insert_single(query_set); - query_set.same_device_as(cmd_enc.as_ref())?; + Ok(()) +} - let dst_buffer = hub.buffers.get(destination).get()?; +pub(super) fn resolve_query_set( + cmd_buf_data: &mut CommandBufferMutable, + hub: &crate::hub::Hub, + cmd_enc: &Arc, + query_set_id: id::QuerySetId, + start_query: u32, + query_count: u32, + destination: id::BufferId, + destination_offset: BufferAddress, +) -> Result<(), QueryError> { + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace_commands { + list.push(TraceCommand::ResolveQuerySet { + query_set_id, + start_query, + query_count, + destination, + destination_offset, + }); + } - dst_buffer.same_device_as(cmd_enc.as_ref())?; + cmd_enc.device.check_is_valid()?; - let snatch_guard = dst_buffer.device.snatchable_lock.read(); - dst_buffer.check_destroyed(&snatch_guard)?; + if destination_offset % wgt::QUERY_RESOLVE_BUFFER_ALIGNMENT != 0 { + return Err(QueryError::Resolve(ResolveError::BufferOffsetAlignment)); + } - let dst_pending = cmd_buf_data - .trackers - .buffers - .set_single(&dst_buffer, wgt::BufferUses::COPY_DST); + let query_set = hub.query_sets.get(query_set_id).get()?; - let dst_barrier = - dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); + query_set.same_device_as(cmd_enc.as_ref())?; - dst_buffer - .check_usage(wgt::BufferUsages::QUERY_RESOLVE) - .map_err(ResolveError::MissingBufferUsage)?; + let dst_buffer = hub.buffers.get(destination).get()?; - let end_query = u64::from(start_query) - .checked_add(u64::from(query_count)) - .expect("`u64` overflow from adding two `u32`s, should be unreachable"); - if end_query > u64::from(query_set.desc.count) { - return Err(ResolveError::QueryOverrun { - start_query, - end_query, - query_set_size: query_set.desc.count, - } - .into()); - } - let end_query = u32::try_from(end_query) - .expect("`u32` overflow for `end_query`, which should be `u32`"); - - let elements_per_query = match query_set.desc.ty { - wgt::QueryType::Occlusion => 1, - wgt::QueryType::PipelineStatistics(ps) => ps.bits().count_ones(), - wgt::QueryType::Timestamp => 1, - }; - let stride = elements_per_query * wgt::QUERY_SIZE; - let bytes_used: BufferAddress = u64::from(stride) - .checked_mul(u64::from(query_count)) - .expect("`stride` * `query_count` overflowed `u32`, should be unreachable"); - - let buffer_start_offset = destination_offset; - let buffer_end_offset = buffer_start_offset - .checked_add(bytes_used) - .filter(|buffer_end_offset| *buffer_end_offset <= dst_buffer.size) - .ok_or(ResolveError::BufferOverrun { - start_query, - end_query, - stride, - buffer_size: dst_buffer.size, - buffer_start_offset, - bytes_used, - })?; - - // TODO(https://github.com/gfx-rs/wgpu/issues/3993): Need to track initialization state. - cmd_buf_data.buffer_memory_init_actions.extend( - dst_buffer.initialization_status.read().create_action( - &dst_buffer, - buffer_start_offset..buffer_end_offset, - MemoryInitKind::ImplicitlyInitialized, - ), - ); + dst_buffer.same_device_as(cmd_enc.as_ref())?; - let raw_dst_buffer = dst_buffer.try_raw(&snatch_guard)?; - let raw_encoder = cmd_buf_data.encoder.open()?; - unsafe { - raw_encoder.transition_buffers(dst_barrier.as_slice()); - raw_encoder.copy_query_results( - query_set.raw(), - start_query..end_query, - raw_dst_buffer, - destination_offset, - wgt::BufferSize::new_unchecked(stride as u64), - ); - } + let snatch_guard = dst_buffer.device.snatchable_lock.read(); + dst_buffer.check_destroyed(&snatch_guard)?; - if matches!(query_set.desc.ty, wgt::QueryType::Timestamp) { - // Timestamp normalization is only needed for timestamps. - cmd_enc - .device - .timestamp_normalizer - .get() - .unwrap() - .normalize( - &snatch_guard, - raw_encoder, - &mut cmd_buf_data.trackers.buffers, - dst_buffer - .timestamp_normalization_bind_group - .get(&snatch_guard) - .unwrap(), - &dst_buffer, - destination_offset, - query_count, - ); - } + let dst_pending = cmd_buf_data + .trackers + .buffers + .set_single(&dst_buffer, wgt::BufferUses::COPY_DST); + let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); - cmd_buf_data.trackers.query_sets.insert_single(query_set); + dst_buffer + .check_usage(wgt::BufferUsages::QUERY_RESOLVE) + .map_err(ResolveError::MissingBufferUsage)?; - Ok(()) - }) + let end_query = u64::from(start_query) + .checked_add(u64::from(query_count)) + .expect("`u64` overflow from adding two `u32`s, should be unreachable"); + if end_query > u64::from(query_set.desc.count) { + return Err(ResolveError::QueryOverrun { + start_query, + end_query, + query_set_size: query_set.desc.count, + } + .into()); + } + let end_query = + u32::try_from(end_query).expect("`u32` overflow for `end_query`, which should be `u32`"); + + let elements_per_query = match query_set.desc.ty { + wgt::QueryType::Occlusion => 1, + wgt::QueryType::PipelineStatistics(ps) => ps.bits().count_ones(), + wgt::QueryType::Timestamp => 1, + }; + let stride = elements_per_query * wgt::QUERY_SIZE; + let bytes_used: BufferAddress = u64::from(stride) + .checked_mul(u64::from(query_count)) + .expect("`stride` * `query_count` overflowed `u32`, should be unreachable"); + + let buffer_start_offset = destination_offset; + let buffer_end_offset = buffer_start_offset + .checked_add(bytes_used) + .filter(|buffer_end_offset| *buffer_end_offset <= dst_buffer.size) + .ok_or(ResolveError::BufferOverrun { + start_query, + end_query, + stride, + buffer_size: dst_buffer.size, + buffer_start_offset, + bytes_used, + })?; + + // TODO(https://github.com/gfx-rs/wgpu/issues/3993): Need to track initialization state. + cmd_buf_data.buffer_memory_init_actions.extend( + dst_buffer.initialization_status.read().create_action( + &dst_buffer, + buffer_start_offset..buffer_end_offset, + MemoryInitKind::ImplicitlyInitialized, + ), + ); + + let raw_dst_buffer = dst_buffer.try_raw(&snatch_guard)?; + let raw_encoder = cmd_buf_data.encoder.open()?; + unsafe { + raw_encoder.transition_buffers(dst_barrier.as_slice()); + raw_encoder.copy_query_results( + query_set.raw(), + start_query..end_query, + raw_dst_buffer, + destination_offset, + wgt::BufferSize::new_unchecked(stride as u64), + ); + } + + if matches!(query_set.desc.ty, wgt::QueryType::Timestamp) { + // Timestamp normalization is only needed for timestamps. + cmd_enc + .device + .timestamp_normalizer + .get() + .unwrap() + .normalize( + &snatch_guard, + raw_encoder, + &mut cmd_buf_data.trackers.buffers, + dst_buffer + .timestamp_normalization_bind_group + .get(&snatch_guard) + .unwrap(), + &dst_buffer, + destination_offset, + query_count, + ); } + + cmd_buf_data.trackers.query_sets.insert_single(query_set); + + Ok(()) } diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index adee3999742..6e7f553e84b 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -7,7 +7,6 @@ use core::{ use wgt::{math::align_to, BufferUsages, BufferUses, Features}; -use crate::ray_tracing::{AsAction, AsBuild, TlasBuild, ValidateAsActionsError}; use crate::{ command::CommandBufferMutable, device::queue::TempResource, @@ -25,6 +24,10 @@ use crate::{ snatch::SnatchGuard, track::PendingTransition, }; +use crate::{ + command::CommandEncoder, + ray_tracing::{AsAction, AsBuild, TlasBuild, ValidateAsActionsError}, +}; use crate::{command::EncoderStateError, device::resource::CommandIndices}; use crate::{lock::RwLockWriteGuard, resource::RawResourceAccess}; @@ -109,8 +112,6 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); - let mut build_command = AsBuild::default(); - let trace_blas: Vec = blas_iter .map(|blas_entry| { let geometries = match blas_entry.geometries { @@ -159,345 +160,367 @@ impl Global { }) .collect(); - let blas_iter = trace_blas.iter().map(|blas_entry| { - let geometries = match &blas_entry.geometries { - TraceBlasGeometries::TriangleGeometries(triangle_geometries) => { - let iter = triangle_geometries.iter().map(|tg| BlasTriangleGeometry { - size: &tg.size, - vertex_buffer: tg.vertex_buffer, - index_buffer: tg.index_buffer, - transform_buffer: tg.transform_buffer, - first_vertex: tg.first_vertex, - vertex_stride: tg.vertex_stride, - first_index: tg.first_index, - transform_buffer_offset: tg.transform_buffer_offset, - }); - BlasGeometries::TriangleGeometries(Box::new(iter)) + let mut cmd_buf_data = cmd_enc.data.lock(); + cmd_buf_data.record_with(|cmd_buf_data| { + let blas_iter = trace_blas.iter().map(|blas_entry| { + let geometries = match &blas_entry.geometries { + TraceBlasGeometries::TriangleGeometries(triangle_geometries) => { + let iter = triangle_geometries.iter().map(|tg| BlasTriangleGeometry { + size: &tg.size, + vertex_buffer: tg.vertex_buffer, + index_buffer: tg.index_buffer, + transform_buffer: tg.transform_buffer, + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + first_index: tg.first_index, + transform_buffer_offset: tg.transform_buffer_offset, + }); + BlasGeometries::TriangleGeometries(Box::new(iter)) + } + }; + BlasBuildEntry { + blas_id: blas_entry.blas_id, + geometries, } - }; - BlasBuildEntry { - blas_id: blas_entry.blas_id, - geometries, - } - }); - - let tlas_iter = trace_tlas.iter().map(|tlas_package| { - let instances = tlas_package.instances.iter().map(|instance| { - instance.as_ref().map(|instance| TlasInstance { - blas_id: instance.blas_id, - transform: &instance.transform, - custom_data: instance.custom_data, - mask: instance.mask, - }) }); - TlasPackage { - tlas_id: tlas_package.tlas_id, - instances: Box::new(instances), - lowest_unmodified: tlas_package.lowest_unmodified, - } - }); - let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| { - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(crate::command::Command::BuildAccelerationStructures { - blas: trace_blas.clone(), - tlas: trace_tlas.clone(), + let tlas_iter = trace_tlas.iter().map(|tlas_package| { + let instances = tlas_package.instances.iter().map(|instance| { + instance.as_ref().map(|instance| TlasInstance { + blas_id: instance.blas_id, + transform: &instance.transform, + custom_data: instance.custom_data, + mask: instance.mask, + }) }); - } - - let device = &cmd_enc.device; - device.check_is_valid()?; - device.require_features(Features::EXPERIMENTAL_RAY_QUERY)?; - - let mut buf_storage = Vec::new(); - iter_blas( - blas_iter, - cmd_buf_data, - &mut build_command, - &mut buf_storage, - hub, - )?; + TlasPackage { + tlas_id: tlas_package.tlas_id, + instances: Box::new(instances), + lowest_unmodified: tlas_package.lowest_unmodified, + } + }); - let snatch_guard = device.snatchable_lock.read(); - let mut input_barriers = Vec::>::new(); - let mut scratch_buffer_blas_size = 0; - let mut blas_storage = Vec::new(); - iter_buffers( - &mut buf_storage, - &snatch_guard, - &mut input_barriers, + build_acceleration_structures( cmd_buf_data, - &mut scratch_buffer_blas_size, - &mut blas_storage, hub, - device.alignments.ray_tracing_scratch_buffer_alignment, - )?; - let mut tlas_lock_store = Vec::<(Option, Arc)>::new(); - - for package in tlas_iter { - let tlas = hub.tlas_s.get(package.tlas_id).get()?; - - cmd_buf_data.trackers.tlas_s.insert_single(tlas.clone()); - - tlas_lock_store.push((Some(package), tlas)) - } - - let mut scratch_buffer_tlas_size = 0; - let mut tlas_storage = Vec::::new(); - let mut instance_buffer_staging_source = Vec::::new(); + &cmd_enc, + trace_blas.clone(), + trace_tlas.clone(), + blas_iter, + tlas_iter, + ) + }) + } +} - for (package, tlas) in &mut tlas_lock_store { - let package = package.take().unwrap(); +pub(crate) fn build_acceleration_structures<'a>( + cmd_buf_data: &'a mut CommandBufferMutable, + hub: &'a Hub, + cmd_enc: &'a Arc, + trace_blas: Vec, + trace_tlas: Vec, + blas_iter: impl Iterator>, + tlas_iter: impl Iterator>, +) -> Result<(), BuildAccelerationStructureError> { + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace_commands { + list.push(crate::command::Command::BuildAccelerationStructures { + blas: trace_blas, + tlas: trace_tlas, + }); + } + #[cfg(not(feature = "trace"))] + { + let _ = trace_blas; + let _ = trace_tlas; + } - let scratch_buffer_offset = scratch_buffer_tlas_size; - scratch_buffer_tlas_size += align_to( - tlas.size_info.build_scratch_size as u32, - device.alignments.ray_tracing_scratch_buffer_alignment, - ) as u64; + let device = &cmd_enc.device; + device.check_is_valid()?; + device.require_features(Features::EXPERIMENTAL_RAY_QUERY)?; + + let mut build_command = AsBuild::default(); + let mut buf_storage = Vec::new(); + iter_blas( + blas_iter, + cmd_buf_data, + &mut build_command, + &mut buf_storage, + hub, + )?; + + let snatch_guard = device.snatchable_lock.read(); + let mut input_barriers = Vec::>::new(); + let mut scratch_buffer_blas_size = 0; + let mut blas_storage = Vec::new(); + iter_buffers( + &mut buf_storage, + &snatch_guard, + &mut input_barriers, + cmd_buf_data, + &mut scratch_buffer_blas_size, + &mut blas_storage, + hub, + device.alignments.ray_tracing_scratch_buffer_alignment, + )?; + let mut tlas_lock_store = Vec::<(Option, Arc)>::new(); + + for package in tlas_iter { + let tlas = hub.tlas_s.get(package.tlas_id).get()?; + + cmd_buf_data.trackers.tlas_s.insert_single(tlas.clone()); + + tlas_lock_store.push((Some(package), tlas)) + } - let first_byte_index = instance_buffer_staging_source.len(); + let mut scratch_buffer_tlas_size = 0; + let mut tlas_storage = Vec::::new(); + let mut instance_buffer_staging_source = Vec::::new(); - let mut dependencies = Vec::new(); + for (package, tlas) in &mut tlas_lock_store { + let package = package.take().unwrap(); - let mut instance_count = 0; - for instance in package.instances.flatten() { - if instance.custom_data >= (1u32 << 24u32) { - return Err(BuildAccelerationStructureError::TlasInvalidCustomIndex( - tlas.error_ident(), - )); - } - let blas = hub.blas_s.get(instance.blas_id).get()?; + let scratch_buffer_offset = scratch_buffer_tlas_size; + scratch_buffer_tlas_size += align_to( + tlas.size_info.build_scratch_size as u32, + device.alignments.ray_tracing_scratch_buffer_alignment, + ) as u64; - cmd_buf_data.trackers.blas_s.insert_single(blas.clone()); + let first_byte_index = instance_buffer_staging_source.len(); - instance_buffer_staging_source.extend(device.raw().tlas_instance_to_bytes( - hal::TlasInstance { - transform: *instance.transform, - custom_data: instance.custom_data, - mask: instance.mask, - blas_address: blas.handle, - }, - )); - - if tlas.flags.contains( - wgpu_types::AccelerationStructureFlags::ALLOW_RAY_HIT_VERTEX_RETURN, - ) && !blas.flags.contains( - wgpu_types::AccelerationStructureFlags::ALLOW_RAY_HIT_VERTEX_RETURN, - ) { - return Err( - BuildAccelerationStructureError::TlasDependentMissingVertexReturn( - tlas.error_ident(), - blas.error_ident(), - ), - ); - } - - instance_count += 1; + let mut dependencies = Vec::new(); - dependencies.push(blas.clone()); - } + let mut instance_count = 0; + for instance in package.instances.flatten() { + if instance.custom_data >= (1u32 << 24u32) { + return Err(BuildAccelerationStructureError::TlasInvalidCustomIndex( + tlas.error_ident(), + )); + } + let blas = hub.blas_s.get(instance.blas_id).get()?; - build_command.tlas_s_built.push(TlasBuild { - tlas: tlas.clone(), - dependencies, - }); + cmd_buf_data.trackers.blas_s.insert_single(blas.clone()); - if instance_count > tlas.max_instance_count { - return Err(BuildAccelerationStructureError::TlasInstanceCountExceeded( + instance_buffer_staging_source.extend(device.raw().tlas_instance_to_bytes( + hal::TlasInstance { + transform: *instance.transform, + custom_data: instance.custom_data, + mask: instance.mask, + blas_address: blas.handle, + }, + )); + + if tlas + .flags + .contains(wgpu_types::AccelerationStructureFlags::ALLOW_RAY_HIT_VERTEX_RETURN) + && !blas + .flags + .contains(wgpu_types::AccelerationStructureFlags::ALLOW_RAY_HIT_VERTEX_RETURN) + { + return Err( + BuildAccelerationStructureError::TlasDependentMissingVertexReturn( tlas.error_ident(), - instance_count, - tlas.max_instance_count, - )); - } - - tlas_storage.push(TlasStore { - internal: UnsafeTlasStore { - tlas: tlas.clone(), - entries: hal::AccelerationStructureEntries::Instances( - hal::AccelerationStructureInstances { - buffer: Some(tlas.instance_buffer.as_ref()), - offset: 0, - count: instance_count, - }, - ), - scratch_buffer_offset, - }, - range: first_byte_index..instance_buffer_staging_source.len(), - }); + blas.error_ident(), + ), + ); } - let Some(scratch_size) = - wgt::BufferSize::new(max(scratch_buffer_blas_size, scratch_buffer_tlas_size)) - else { - // if the size is zero there is nothing to build - return Ok(()); - }; + instance_count += 1; - let scratch_buffer = ScratchBuffer::new(device, scratch_size)?; + dependencies.push(blas.clone()); + } - let scratch_buffer_barrier = hal::BufferBarrier:: { - buffer: scratch_buffer.raw(), - usage: hal::StateTransition { - from: BufferUses::ACCELERATION_STRUCTURE_SCRATCH, - to: BufferUses::ACCELERATION_STRUCTURE_SCRATCH, - }, - }; + build_command.tlas_s_built.push(TlasBuild { + tlas: tlas.clone(), + dependencies, + }); - let mut tlas_descriptors = Vec::with_capacity(tlas_storage.len()); + if instance_count > tlas.max_instance_count { + return Err(BuildAccelerationStructureError::TlasInstanceCountExceeded( + tlas.error_ident(), + instance_count, + tlas.max_instance_count, + )); + } - for &TlasStore { - internal: - UnsafeTlasStore { - ref tlas, - ref entries, - ref scratch_buffer_offset, + tlas_storage.push(TlasStore { + internal: UnsafeTlasStore { + tlas: tlas.clone(), + entries: hal::AccelerationStructureEntries::Instances( + hal::AccelerationStructureInstances { + buffer: Some(tlas.instance_buffer.as_ref()), + offset: 0, + count: instance_count, }, - .. - } in &tlas_storage - { - if tlas.update_mode == wgt::AccelerationStructureUpdateMode::PreferUpdate { - log::info!("only rebuild implemented") - } - tlas_descriptors.push(hal::BuildAccelerationStructureDescriptor { - entries, - mode: hal::AccelerationStructureBuildMode::Build, - flags: tlas.flags, - source_acceleration_structure: None, - destination_acceleration_structure: tlas.try_raw(&snatch_guard)?, - scratch_buffer: scratch_buffer.raw(), - scratch_buffer_offset: *scratch_buffer_offset, - }) - } + ), + scratch_buffer_offset, + }, + range: first_byte_index..instance_buffer_staging_source.len(), + }); + } - let blas_present = !blas_storage.is_empty(); - let tlas_present = !tlas_storage.is_empty(); + let Some(scratch_size) = + wgt::BufferSize::new(max(scratch_buffer_blas_size, scratch_buffer_tlas_size)) + else { + // if the size is zero there is nothing to build + return Ok(()); + }; + + let scratch_buffer = ScratchBuffer::new(device, scratch_size)?; + + let scratch_buffer_barrier = hal::BufferBarrier:: { + buffer: scratch_buffer.raw(), + usage: hal::StateTransition { + from: BufferUses::ACCELERATION_STRUCTURE_SCRATCH, + to: BufferUses::ACCELERATION_STRUCTURE_SCRATCH, + }, + }; + + let mut tlas_descriptors = Vec::with_capacity(tlas_storage.len()); + + for &TlasStore { + internal: + UnsafeTlasStore { + ref tlas, + ref entries, + ref scratch_buffer_offset, + }, + .. + } in &tlas_storage + { + if tlas.update_mode == wgt::AccelerationStructureUpdateMode::PreferUpdate { + log::info!("only rebuild implemented") + } + tlas_descriptors.push(hal::BuildAccelerationStructureDescriptor { + entries, + mode: hal::AccelerationStructureBuildMode::Build, + flags: tlas.flags, + source_acceleration_structure: None, + destination_acceleration_structure: tlas.try_raw(&snatch_guard)?, + scratch_buffer: scratch_buffer.raw(), + scratch_buffer_offset: *scratch_buffer_offset, + }) + } - let cmd_buf_raw = cmd_buf_data.encoder.open()?; + let blas_present = !blas_storage.is_empty(); + let tlas_present = !tlas_storage.is_empty(); - let mut blas_s_compactable = Vec::new(); - let mut descriptors = Vec::new(); + let cmd_buf_raw = cmd_buf_data.encoder.open()?; - for storage in &blas_storage { - descriptors.push(map_blas( - storage, - scratch_buffer.raw(), - &snatch_guard, - &mut blas_s_compactable, - )?); - } + let mut blas_s_compactable = Vec::new(); + let mut descriptors = Vec::new(); - build_blas( - cmd_buf_raw, - blas_present, - tlas_present, - input_barriers, - &descriptors, - scratch_buffer_barrier, - blas_s_compactable, - ); + for storage in &blas_storage { + descriptors.push(map_blas( + storage, + scratch_buffer.raw(), + &snatch_guard, + &mut blas_s_compactable, + )?); + } - if tlas_present { - let staging_buffer = if !instance_buffer_staging_source.is_empty() { - let mut staging_buffer = StagingBuffer::new( - device, - wgt::BufferSize::new(instance_buffer_staging_source.len() as u64).unwrap(), - )?; - staging_buffer.write(&instance_buffer_staging_source); - let flushed = staging_buffer.flush(); - Some(flushed) - } else { - None - }; + build_blas( + cmd_buf_raw, + blas_present, + tlas_present, + input_barriers, + &descriptors, + scratch_buffer_barrier, + blas_s_compactable, + ); - unsafe { - if let Some(ref staging_buffer) = staging_buffer { - cmd_buf_raw.transition_buffers(&[ - hal::BufferBarrier:: { - buffer: staging_buffer.raw(), - usage: hal::StateTransition { - from: BufferUses::MAP_WRITE, - to: BufferUses::COPY_SRC, - }, - }, - ]); - } - } + if tlas_present { + let staging_buffer = if !instance_buffer_staging_source.is_empty() { + let mut staging_buffer = StagingBuffer::new( + device, + wgt::BufferSize::new(instance_buffer_staging_source.len() as u64).unwrap(), + )?; + staging_buffer.write(&instance_buffer_staging_source); + let flushed = staging_buffer.flush(); + Some(flushed) + } else { + None + }; - let mut instance_buffer_barriers = Vec::new(); - for &TlasStore { - internal: UnsafeTlasStore { ref tlas, .. }, - ref range, - } in &tlas_storage - { - let size = match wgt::BufferSize::new((range.end - range.start) as u64) { - None => continue, - Some(size) => size, - }; - instance_buffer_barriers.push(hal::BufferBarrier:: { - buffer: tlas.instance_buffer.as_ref(), - usage: hal::StateTransition { - from: BufferUses::COPY_DST, - to: BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, - }, - }); - unsafe { - cmd_buf_raw.transition_buffers(&[ - hal::BufferBarrier:: { - buffer: tlas.instance_buffer.as_ref(), - usage: hal::StateTransition { - from: BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, - to: BufferUses::COPY_DST, - }, - }, - ]); - let temp = hal::BufferCopy { - src_offset: range.start as u64, - dst_offset: 0, - size, - }; - cmd_buf_raw.copy_buffer_to_buffer( - // the range whose size we just checked end is at (at that point in time) instance_buffer_staging_source.len() - // and since instance_buffer_staging_source doesn't shrink we can un wrap this without a panic - staging_buffer.as_ref().unwrap().raw(), - tlas.instance_buffer.as_ref(), - &[temp], - ); - } - } + unsafe { + if let Some(ref staging_buffer) = staging_buffer { + cmd_buf_raw.transition_buffers(&[hal::BufferBarrier:: { + buffer: staging_buffer.raw(), + usage: hal::StateTransition { + from: BufferUses::MAP_WRITE, + to: BufferUses::COPY_SRC, + }, + }]); + } + } - unsafe { - cmd_buf_raw.transition_buffers(&instance_buffer_barriers); + let mut instance_buffer_barriers = Vec::new(); + for &TlasStore { + internal: UnsafeTlasStore { ref tlas, .. }, + ref range, + } in &tlas_storage + { + let size = match wgt::BufferSize::new((range.end - range.start) as u64) { + None => continue, + Some(size) => size, + }; + instance_buffer_barriers.push(hal::BufferBarrier:: { + buffer: tlas.instance_buffer.as_ref(), + usage: hal::StateTransition { + from: BufferUses::COPY_DST, + to: BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, + }, + }); + unsafe { + cmd_buf_raw.transition_buffers(&[hal::BufferBarrier:: { + buffer: tlas.instance_buffer.as_ref(), + usage: hal::StateTransition { + from: BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, + to: BufferUses::COPY_DST, + }, + }]); + let temp = hal::BufferCopy { + src_offset: range.start as u64, + dst_offset: 0, + size, + }; + cmd_buf_raw.copy_buffer_to_buffer( + // the range whose size we just checked end is at (at that point in time) instance_buffer_staging_source.len() + // and since instance_buffer_staging_source doesn't shrink we can un wrap this without a panic + staging_buffer.as_ref().unwrap().raw(), + tlas.instance_buffer.as_ref(), + &[temp], + ); + } + } - cmd_buf_raw.build_acceleration_structures(&tlas_descriptors); + unsafe { + cmd_buf_raw.transition_buffers(&instance_buffer_barriers); - cmd_buf_raw.place_acceleration_structure_barrier( - hal::AccelerationStructureBarrier { - usage: hal::StateTransition { - from: hal::AccelerationStructureUses::BUILD_OUTPUT, - to: hal::AccelerationStructureUses::SHADER_INPUT, - }, - }, - ); - } + cmd_buf_raw.build_acceleration_structures(&tlas_descriptors); - if let Some(staging_buffer) = staging_buffer { - cmd_buf_data - .temp_resources - .push(TempResource::StagingBuffer(staging_buffer)); - } - } + cmd_buf_raw.place_acceleration_structure_barrier(hal::AccelerationStructureBarrier { + usage: hal::StateTransition { + from: hal::AccelerationStructureUses::BUILD_OUTPUT, + to: hal::AccelerationStructureUses::SHADER_INPUT, + }, + }); + } + if let Some(staging_buffer) = staging_buffer { cmd_buf_data .temp_resources - .push(TempResource::ScratchBuffer(scratch_buffer)); + .push(TempResource::StagingBuffer(staging_buffer)); + } + } - cmd_buf_data.as_actions.push(AsAction::Build(build_command)); + cmd_buf_data + .temp_resources + .push(TempResource::ScratchBuffer(scratch_buffer)); - Ok(()) - }) - } + cmd_buf_data.as_actions.push(AsAction::Build(build_command)); + + Ok(()) } impl CommandBufferMutable { diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index fe88fb2afd4..bf19edf7921 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -11,8 +11,8 @@ use wgt::{ use crate::command::{ encoder::EncodingState, pass, pass_base, pass_try, validate_and_begin_occlusion_query, - validate_and_begin_pipeline_statistics_query, DebugGroupError, EncoderStateError, - InnerCommandEncoder, PassStateError, TimestampWritesError, + validate_and_begin_pipeline_statistics_query, CommandBufferMutable, DebugGroupError, + EncoderStateError, InnerCommandEncoder, PassStateError, TimestampWritesError, }; use crate::pipeline::{RenderPipeline, VertexStep}; use crate::resource::RawResourceAccess; @@ -1807,7 +1807,6 @@ impl Global { } pub fn render_pass_end(&self, pass: &mut RenderPass) -> Result<(), EncoderStateError> { - let pass_scope = PassErrorScope::Pass; profiling::scope!( "CommandEncoder::run_render_pass {}", pass.base.label.as_deref().unwrap_or("") @@ -1839,457 +1838,453 @@ impl Global { } cmd_buf_data.unlock_and_record(|cmd_buf_data| -> Result<(), RenderPassError> { - let device = &cmd_enc.device; - device.check_is_valid().map_pass_err(pass_scope)?; - let snatch_guard = &device.snatchable_lock.read(); + encode_render_pass(cmd_buf_data, &cmd_enc, pass) + }) + } +} - let base = &mut pass.base; +fn encode_render_pass( + cmd_buf_data: &mut CommandBufferMutable, + cmd_enc: &Arc, + pass: &mut RenderPass, +) -> Result<(), RenderPassError> { + let pass_scope = PassErrorScope::Pass; + + let device = &cmd_enc.device; + device.check_is_valid().map_pass_err(pass_scope)?; + let snatch_guard = &device.snatchable_lock.read(); + + let base = &mut pass.base; + + let mut indirect_draw_validation_batcher = crate::indirect_validation::DrawBatcher::new(); + + let (scope, pending_discard_init_fixups, mut pending_query_resets) = { + let encoder = &mut cmd_buf_data.encoder; + let tracker = &mut cmd_buf_data.trackers; + let buffer_memory_init_actions = &mut cmd_buf_data.buffer_memory_init_actions; + let texture_memory_actions = &mut cmd_buf_data.texture_memory_actions; + + // We automatically keep extending command buffers over time, and because + // we want to insert a command buffer _before_ what we're about to record, + // we need to make sure to close the previous one. + encoder.close_if_open().map_pass_err(pass_scope)?; + encoder + .open_pass(base.label.as_deref()) + .map_pass_err(pass_scope)?; + + let mut pending_query_resets = QueryResetMap::new(); + let mut pending_discard_init_fixups = SurfacesInDiscardState::new(); + + let info = RenderPassInfo::start( + device, + hal_label(base.label.as_deref(), device.instance_flags), + pass.color_attachments.take(), + pass.depth_stencil_attachment.take(), + pass.timestamp_writes.take(), + // Still needed down the line. + // TODO(wumpf): by restructuring the code, we could get rid of some of this Arc clone. + pass.occlusion_query_set.clone(), + encoder, + tracker, + texture_memory_actions, + &mut pending_query_resets, + &mut pending_discard_init_fixups, + snatch_guard, + ) + .map_pass_err(pass_scope)?; - let mut indirect_draw_validation_batcher = - crate::indirect_validation::DrawBatcher::new(); + let indices = &device.tracker_indices; + tracker.buffers.set_size(indices.buffers.size()); + tracker.textures.set_size(indices.textures.size()); - let (scope, pending_discard_init_fixups, mut pending_query_resets) = { - let encoder = &mut cmd_buf_data.encoder; - let tracker = &mut cmd_buf_data.trackers; - let buffer_memory_init_actions = &mut cmd_buf_data.buffer_memory_init_actions; - let texture_memory_actions = &mut cmd_buf_data.texture_memory_actions; + let mut debug_scope_depth = 0; - // We automatically keep extending command buffers over time, and because - // we want to insert a command buffer _before_ what we're about to record, - // we need to make sure to close the previous one. - encoder.close_if_open().map_pass_err(pass_scope)?; - encoder - .open_pass(base.label.as_deref()) - .map_pass_err(pass_scope)?; + let mut state = State { + pipeline_flags: PipelineFlags::empty(), + blend_constant: OptionalState::Unused, + stencil_reference: 0, + pipeline: None, + index: IndexState::default(), + vertex: VertexState::default(), - let mut pending_query_resets = QueryResetMap::new(); - let mut pending_discard_init_fixups = SurfacesInDiscardState::new(); + info, - let info = RenderPassInfo::start( + pass: pass::PassState { + base: EncodingState { device, - hal_label(base.label.as_deref(), device.instance_flags), - pass.color_attachments.take(), - pass.depth_stencil_attachment.take(), - pass.timestamp_writes.take(), - // Still needed down the line. - // TODO(wumpf): by restructuring the code, we could get rid of some of this Arc clone. - pass.occlusion_query_set.clone(), - encoder, + raw_encoder: encoder.raw.as_mut(), tracker, + buffer_memory_init_actions, texture_memory_actions, - &mut pending_query_resets, - &mut pending_discard_init_fixups, + as_actions: &mut cmd_buf_data.as_actions, + indirect_draw_validation_resources: &mut cmd_buf_data + .indirect_draw_validation_resources, snatch_guard, - ) - .map_pass_err(pass_scope)?; + debug_scope_depth: &mut debug_scope_depth, + }, + pending_discard_init_fixups, + scope: device.new_usage_scope(), + binder: Binder::new(), - let indices = &device.tracker_indices; - tracker.buffers.set_size(indices.buffers.size()); - tracker.textures.set_size(indices.textures.size()); - - let mut debug_scope_depth = 0; - - let mut state = State { - pipeline_flags: PipelineFlags::empty(), - blend_constant: OptionalState::Unused, - stencil_reference: 0, - pipeline: None, - index: IndexState::default(), - vertex: VertexState::default(), - - info, - - pass: pass::PassState { - base: EncodingState { - device, - raw_encoder: encoder.raw.as_mut(), - tracker, - buffer_memory_init_actions, - texture_memory_actions, - as_actions: &mut cmd_buf_data.as_actions, - indirect_draw_validation_resources: &mut cmd_buf_data - .indirect_draw_validation_resources, - snatch_guard, - debug_scope_depth: &mut debug_scope_depth, - }, - pending_discard_init_fixups, - scope: device.new_usage_scope(), - binder: Binder::new(), + temp_offsets: Vec::new(), + dynamic_offset_count: 0, - temp_offsets: Vec::new(), - dynamic_offset_count: 0, + string_offset: 0, + }, - string_offset: 0, - }, + active_occlusion_query: None, + active_pipeline_statistics_query: None, + }; - active_occlusion_query: None, - active_pipeline_statistics_query: None, - }; + for command in base.commands.drain(..) { + match command { + ArcRenderCommand::SetBindGroup { + index, + num_dynamic_offsets, + bind_group, + } => { + let scope = PassErrorScope::SetBindGroup; + pass::set_bind_group::( + &mut state.pass, + cmd_enc.as_ref(), + &base.dynamic_offsets, + index, + num_dynamic_offsets, + bind_group, + true, + ) + .map_pass_err(scope)?; + } + ArcRenderCommand::SetPipeline(pipeline) => { + let scope = PassErrorScope::SetPipelineRender; + set_pipeline(&mut state, cmd_enc, pipeline).map_pass_err(scope)?; + } + ArcRenderCommand::SetIndexBuffer { + buffer, + index_format, + offset, + size, + } => { + let scope = PassErrorScope::SetIndexBuffer; + set_index_buffer(&mut state, cmd_enc, buffer, index_format, offset, size) + .map_pass_err(scope)?; + } + ArcRenderCommand::SetVertexBuffer { + slot, + buffer, + offset, + size, + } => { + let scope = PassErrorScope::SetVertexBuffer; + set_vertex_buffer(&mut state, cmd_enc, slot, buffer, offset, size) + .map_pass_err(scope)?; + } + ArcRenderCommand::SetBlendConstant(ref color) => { + set_blend_constant(&mut state, color); + } + ArcRenderCommand::SetStencilReference(value) => { + set_stencil_reference(&mut state, value); + } + ArcRenderCommand::SetViewport { + rect, + depth_min, + depth_max, + } => { + let scope = PassErrorScope::SetViewport; + set_viewport(&mut state, rect, depth_min, depth_max).map_pass_err(scope)?; + } + ArcRenderCommand::SetPushConstant { + stages, + offset, + size_bytes, + values_offset, + } => { + let scope = PassErrorScope::SetPushConstant; + pass::set_push_constant::( + &mut state.pass, + &base.push_constant_data, + stages, + offset, + size_bytes, + values_offset, + |_| {}, + ) + .map_pass_err(scope)?; + } + ArcRenderCommand::SetScissor(rect) => { + let scope = PassErrorScope::SetScissorRect; + set_scissor(&mut state, rect).map_pass_err(scope)?; + } + ArcRenderCommand::Draw { + vertex_count, + instance_count, + first_vertex, + first_instance, + } => { + let scope = PassErrorScope::Draw { + kind: DrawKind::Draw, + family: DrawCommandFamily::Draw, + }; + draw( + &mut state, + vertex_count, + instance_count, + first_vertex, + first_instance, + ) + .map_pass_err(scope)?; + } + ArcRenderCommand::DrawIndexed { + index_count, + instance_count, + first_index, + base_vertex, + first_instance, + } => { + let scope = PassErrorScope::Draw { + kind: DrawKind::Draw, + family: DrawCommandFamily::DrawIndexed, + }; + draw_indexed( + &mut state, + index_count, + instance_count, + first_index, + base_vertex, + first_instance, + ) + .map_pass_err(scope)?; + } + ArcRenderCommand::DrawMeshTasks { + group_count_x, + group_count_y, + group_count_z, + } => { + let scope = PassErrorScope::Draw { + kind: DrawKind::Draw, + family: DrawCommandFamily::DrawMeshTasks, + }; + draw_mesh_tasks(&mut state, group_count_x, group_count_y, group_count_z) + .map_pass_err(scope)?; + } + ArcRenderCommand::DrawIndirect { + buffer, + offset, + count, + family, + + vertex_or_index_limit: _, + instance_limit: _, + } => { + let scope = PassErrorScope::Draw { + kind: if count != 1 { + DrawKind::MultiDrawIndirect + } else { + DrawKind::DrawIndirect + }, + family, + }; + multi_draw_indirect( + &mut state, + &mut indirect_draw_validation_batcher, + cmd_enc, + buffer, + offset, + count, + family, + ) + .map_pass_err(scope)?; + } + ArcRenderCommand::MultiDrawIndirectCount { + buffer, + offset, + count_buffer, + count_buffer_offset, + max_count, + family, + } => { + let scope = PassErrorScope::Draw { + kind: DrawKind::MultiDrawIndirectCount, + family, + }; + multi_draw_indirect_count( + &mut state, + cmd_enc, + buffer, + offset, + count_buffer, + count_buffer_offset, + max_count, + family, + ) + .map_pass_err(scope)?; + } + ArcRenderCommand::PushDebugGroup { color: _, len } => { + pass::push_debug_group(&mut state.pass, &base.string_data, len); + } + ArcRenderCommand::PopDebugGroup => { + let scope = PassErrorScope::PopDebugGroup; + pass::pop_debug_group::(&mut state.pass) + .map_pass_err(scope)?; + } + ArcRenderCommand::InsertDebugMarker { color: _, len } => { + pass::insert_debug_marker(&mut state.pass, &base.string_data, len); + } + ArcRenderCommand::WriteTimestamp { + query_set, + query_index, + } => { + let scope = PassErrorScope::WriteTimestamp; + pass::write_timestamp::( + &mut state.pass, + cmd_enc.as_ref(), + Some(&mut pending_query_resets), + query_set, + query_index, + ) + .map_pass_err(scope)?; + } + ArcRenderCommand::BeginOcclusionQuery { query_index } => { + api_log!("RenderPass::begin_occlusion_query {query_index}"); + let scope = PassErrorScope::BeginOcclusionQuery; + + let query_set = pass + .occlusion_query_set + .clone() + .ok_or(RenderPassErrorInner::MissingOcclusionQuerySet) + .map_pass_err(scope)?; + + validate_and_begin_occlusion_query( + query_set, + state.pass.base.raw_encoder, + &mut state.pass.base.tracker.query_sets, + query_index, + Some(&mut pending_query_resets), + &mut state.active_occlusion_query, + ) + .map_pass_err(scope)?; + } + ArcRenderCommand::EndOcclusionQuery => { + api_log!("RenderPass::end_occlusion_query"); + let scope = PassErrorScope::EndOcclusionQuery; - for command in base.commands.drain(..) { - match command { - ArcRenderCommand::SetBindGroup { - index, - num_dynamic_offsets, - bind_group, - } => { - let scope = PassErrorScope::SetBindGroup; - pass::set_bind_group::( - &mut state.pass, - cmd_enc.as_ref(), - &base.dynamic_offsets, - index, - num_dynamic_offsets, - bind_group, - true, - ) - .map_pass_err(scope)?; - } - ArcRenderCommand::SetPipeline(pipeline) => { - let scope = PassErrorScope::SetPipelineRender; - set_pipeline(&mut state, &cmd_enc, pipeline).map_pass_err(scope)?; - } - ArcRenderCommand::SetIndexBuffer { - buffer, - index_format, - offset, - size, - } => { - let scope = PassErrorScope::SetIndexBuffer; - set_index_buffer( - &mut state, - &cmd_enc, - buffer, - index_format, - offset, - size, - ) - .map_pass_err(scope)?; - } - ArcRenderCommand::SetVertexBuffer { - slot, - buffer, - offset, - size, - } => { - let scope = PassErrorScope::SetVertexBuffer; - set_vertex_buffer(&mut state, &cmd_enc, slot, buffer, offset, size) - .map_pass_err(scope)?; - } - ArcRenderCommand::SetBlendConstant(ref color) => { - set_blend_constant(&mut state, color); - } - ArcRenderCommand::SetStencilReference(value) => { - set_stencil_reference(&mut state, value); - } - ArcRenderCommand::SetViewport { - rect, - depth_min, - depth_max, - } => { - let scope = PassErrorScope::SetViewport; - set_viewport(&mut state, rect, depth_min, depth_max) - .map_pass_err(scope)?; - } - ArcRenderCommand::SetPushConstant { - stages, - offset, - size_bytes, - values_offset, - } => { - let scope = PassErrorScope::SetPushConstant; - pass::set_push_constant::( - &mut state.pass, - &base.push_constant_data, - stages, - offset, - size_bytes, - values_offset, - |_| {}, - ) - .map_pass_err(scope)?; - } - ArcRenderCommand::SetScissor(rect) => { - let scope = PassErrorScope::SetScissorRect; - set_scissor(&mut state, rect).map_pass_err(scope)?; - } - ArcRenderCommand::Draw { - vertex_count, - instance_count, - first_vertex, - first_instance, - } => { - let scope = PassErrorScope::Draw { - kind: DrawKind::Draw, - family: DrawCommandFamily::Draw, - }; - draw( - &mut state, - vertex_count, - instance_count, - first_vertex, - first_instance, - ) - .map_pass_err(scope)?; - } - ArcRenderCommand::DrawIndexed { - index_count, - instance_count, - first_index, - base_vertex, - first_instance, - } => { - let scope = PassErrorScope::Draw { - kind: DrawKind::Draw, - family: DrawCommandFamily::DrawIndexed, - }; - draw_indexed( - &mut state, - index_count, - instance_count, - first_index, - base_vertex, - first_instance, - ) - .map_pass_err(scope)?; - } - ArcRenderCommand::DrawMeshTasks { - group_count_x, - group_count_y, - group_count_z, - } => { - let scope = PassErrorScope::Draw { - kind: DrawKind::Draw, - family: DrawCommandFamily::DrawMeshTasks, - }; - draw_mesh_tasks( - &mut state, - group_count_x, - group_count_y, - group_count_z, - ) - .map_pass_err(scope)?; - } - ArcRenderCommand::DrawIndirect { - buffer, - offset, - count, - family, - - vertex_or_index_limit: _, - instance_limit: _, - } => { - let scope = PassErrorScope::Draw { - kind: if count != 1 { - DrawKind::MultiDrawIndirect - } else { - DrawKind::DrawIndirect - }, - family, - }; - multi_draw_indirect( - &mut state, - &mut indirect_draw_validation_batcher, - &cmd_enc, - buffer, - offset, - count, - family, - ) - .map_pass_err(scope)?; - } - ArcRenderCommand::MultiDrawIndirectCount { - buffer, - offset, - count_buffer, - count_buffer_offset, - max_count, - family, - } => { - let scope = PassErrorScope::Draw { - kind: DrawKind::MultiDrawIndirectCount, - family, - }; - multi_draw_indirect_count( - &mut state, - &cmd_enc, - buffer, - offset, - count_buffer, - count_buffer_offset, - max_count, - family, - ) - .map_pass_err(scope)?; - } - ArcRenderCommand::PushDebugGroup { color: _, len } => { - pass::push_debug_group(&mut state.pass, &base.string_data, len); - } - ArcRenderCommand::PopDebugGroup => { - let scope = PassErrorScope::PopDebugGroup; - pass::pop_debug_group::(&mut state.pass) - .map_pass_err(scope)?; - } - ArcRenderCommand::InsertDebugMarker { color: _, len } => { - pass::insert_debug_marker(&mut state.pass, &base.string_data, len); - } - ArcRenderCommand::WriteTimestamp { - query_set, - query_index, - } => { - let scope = PassErrorScope::WriteTimestamp; - pass::write_timestamp::( - &mut state.pass, - cmd_enc.as_ref(), - Some(&mut pending_query_resets), - query_set, - query_index, - ) - .map_pass_err(scope)?; - } - ArcRenderCommand::BeginOcclusionQuery { query_index } => { - api_log!("RenderPass::begin_occlusion_query {query_index}"); - let scope = PassErrorScope::BeginOcclusionQuery; - - let query_set = pass - .occlusion_query_set - .clone() - .ok_or(RenderPassErrorInner::MissingOcclusionQuerySet) - .map_pass_err(scope)?; - - validate_and_begin_occlusion_query( - query_set, - state.pass.base.raw_encoder, - &mut state.pass.base.tracker.query_sets, - query_index, - Some(&mut pending_query_resets), - &mut state.active_occlusion_query, - ) - .map_pass_err(scope)?; - } - ArcRenderCommand::EndOcclusionQuery => { - api_log!("RenderPass::end_occlusion_query"); - let scope = PassErrorScope::EndOcclusionQuery; - - end_occlusion_query( - state.pass.base.raw_encoder, - &mut state.active_occlusion_query, - ) - .map_pass_err(scope)?; - } - ArcRenderCommand::BeginPipelineStatisticsQuery { - query_set, - query_index, - } => { - api_log!( - "RenderPass::begin_pipeline_statistics_query {query_index} {}", - query_set.error_ident() - ); - let scope = PassErrorScope::BeginPipelineStatisticsQuery; - - validate_and_begin_pipeline_statistics_query( - query_set, - state.pass.base.raw_encoder, - &mut state.pass.base.tracker.query_sets, - cmd_enc.as_ref(), - query_index, - Some(&mut pending_query_resets), - &mut state.active_pipeline_statistics_query, - ) - .map_pass_err(scope)?; - } - ArcRenderCommand::EndPipelineStatisticsQuery => { - api_log!("RenderPass::end_pipeline_statistics_query"); - let scope = PassErrorScope::EndPipelineStatisticsQuery; - - end_pipeline_statistics_query( - state.pass.base.raw_encoder, - &mut state.active_pipeline_statistics_query, - ) - .map_pass_err(scope)?; - } - ArcRenderCommand::ExecuteBundle(bundle) => { - let scope = PassErrorScope::ExecuteBundle; - execute_bundle( - &mut state, - &mut indirect_draw_validation_batcher, - &cmd_enc, - bundle, - ) - .map_pass_err(scope)?; - } - } + end_occlusion_query( + state.pass.base.raw_encoder, + &mut state.active_occlusion_query, + ) + .map_pass_err(scope)?; } + ArcRenderCommand::BeginPipelineStatisticsQuery { + query_set, + query_index, + } => { + api_log!( + "RenderPass::begin_pipeline_statistics_query {query_index} {}", + query_set.error_ident() + ); + let scope = PassErrorScope::BeginPipelineStatisticsQuery; - if *state.pass.base.debug_scope_depth > 0 { - Err( - RenderPassErrorInner::DebugGroupError(DebugGroupError::MissingPop) - .map_pass_err(pass_scope), - )?; + validate_and_begin_pipeline_statistics_query( + query_set, + state.pass.base.raw_encoder, + &mut state.pass.base.tracker.query_sets, + cmd_enc.as_ref(), + query_index, + Some(&mut pending_query_resets), + &mut state.active_pipeline_statistics_query, + ) + .map_pass_err(scope)?; } + ArcRenderCommand::EndPipelineStatisticsQuery => { + api_log!("RenderPass::end_pipeline_statistics_query"); + let scope = PassErrorScope::EndPipelineStatisticsQuery; - state - .info - .finish( - device, + end_pipeline_statistics_query( state.pass.base.raw_encoder, - state.pass.base.snatch_guard, - &mut state.pass.scope, - self.instance.flags, + &mut state.active_pipeline_statistics_query, ) - .map_pass_err(pass_scope)?; + .map_pass_err(scope)?; + } + ArcRenderCommand::ExecuteBundle(bundle) => { + let scope = PassErrorScope::ExecuteBundle; + execute_bundle( + &mut state, + &mut indirect_draw_validation_batcher, + cmd_enc, + bundle, + ) + .map_pass_err(scope)?; + } + } + } - let trackers = state.pass.scope; + if *state.pass.base.debug_scope_depth > 0 { + Err( + RenderPassErrorInner::DebugGroupError(DebugGroupError::MissingPop) + .map_pass_err(pass_scope), + )?; + } - let pending_discard_init_fixups = state.pass.pending_discard_init_fixups; + state + .info + .finish( + device, + state.pass.base.raw_encoder, + state.pass.base.snatch_guard, + &mut state.pass.scope, + device.instance_flags, + ) + .map_pass_err(pass_scope)?; - encoder.close().map_pass_err(pass_scope)?; - (trackers, pending_discard_init_fixups, pending_query_resets) - }; + let trackers = state.pass.scope; - let encoder = &mut cmd_buf_data.encoder; - let tracker = &mut cmd_buf_data.trackers; + let pending_discard_init_fixups = state.pass.pending_discard_init_fixups; - { - let transit = encoder - .open_pass(hal_label( - Some("(wgpu internal) Pre Pass"), - self.instance.flags, - )) - .map_pass_err(pass_scope)?; - - fixup_discarded_surfaces( - pending_discard_init_fixups.into_iter(), - transit, - &mut tracker.textures, - &cmd_enc.device, - snatch_guard, - ); + encoder.close().map_pass_err(pass_scope)?; + (trackers, pending_discard_init_fixups, pending_query_resets) + }; - pending_query_resets.reset_queries(transit); - - CommandEncoder::insert_barriers_from_scope(transit, tracker, &scope, snatch_guard); - - if let Some(ref indirect_validation) = device.indirect_validation { - indirect_validation - .draw - .inject_validation_pass( - device, - snatch_guard, - &mut cmd_buf_data.indirect_draw_validation_resources, - &mut cmd_buf_data.temp_resources, - transit, - indirect_draw_validation_batcher, - ) - .map_pass_err(pass_scope)?; - } - } + let encoder = &mut cmd_buf_data.encoder; + let tracker = &mut cmd_buf_data.trackers; - encoder.close_and_swap().map_pass_err(pass_scope)?; + { + let transit = encoder + .open_pass(hal_label( + Some("(wgpu internal) Pre Pass"), + device.instance_flags, + )) + .map_pass_err(pass_scope)?; + + fixup_discarded_surfaces( + pending_discard_init_fixups.into_iter(), + transit, + &mut tracker.textures, + &cmd_enc.device, + snatch_guard, + ); - Ok(()) - }) + pending_query_resets.reset_queries(transit); + + CommandEncoder::insert_barriers_from_scope(transit, tracker, &scope, snatch_guard); + + if let Some(ref indirect_validation) = device.indirect_validation { + indirect_validation + .draw + .inject_validation_pass( + device, + snatch_guard, + &mut cmd_buf_data.indirect_draw_validation_resources, + &mut cmd_buf_data.temp_resources, + transit, + indirect_draw_validation_batcher, + ) + .map_pass_err(pass_scope)?; + } } + + encoder.close_and_swap().map_pass_err(pass_scope)?; + + Ok(()) } fn set_pipeline( diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 5ce0a2722f2..b14831ff5d0 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -841,151 +841,16 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - let device = &cmd_enc.device; - device.check_is_valid()?; - - if source == destination { - return Err(TransferError::SameSourceDestinationBuffer.into()); - } - - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::CopyBufferToBuffer { - src: source, - src_offset: source_offset, - dst: destination, - dst_offset: destination_offset, - size, - }); - } - - let snatch_guard = device.snatchable_lock.read(); - - let src_buffer = hub.buffers.get(source).get()?; - - src_buffer.same_device_as(cmd_enc.as_ref())?; - - let src_pending = cmd_buf_data - .trackers - .buffers - .set_single(&src_buffer, wgt::BufferUses::COPY_SRC); - - let src_raw = src_buffer.try_raw(&snatch_guard)?; - src_buffer - .check_usage(BufferUsages::COPY_SRC) - .map_err(TransferError::MissingBufferUsage)?; - // expecting only a single barrier - let src_barrier = - src_pending.map(|pending| pending.into_hal(&src_buffer, &snatch_guard)); - - let dst_buffer = hub.buffers.get(destination).get()?; - - dst_buffer.same_device_as(cmd_enc.as_ref())?; - - let dst_pending = cmd_buf_data - .trackers - .buffers - .set_single(&dst_buffer, wgt::BufferUses::COPY_DST); - - let dst_raw = dst_buffer.try_raw(&snatch_guard)?; - dst_buffer - .check_usage(BufferUsages::COPY_DST) - .map_err(TransferError::MissingBufferUsage)?; - let dst_barrier = - dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); - - let (size, source_end_offset) = match size { - Some(size) => (size, source_offset + size), - None => (src_buffer.size - source_offset, src_buffer.size), - }; - - if size % wgt::COPY_BUFFER_ALIGNMENT != 0 { - return Err(TransferError::UnalignedCopySize(size).into()); - } - if source_offset % wgt::COPY_BUFFER_ALIGNMENT != 0 { - return Err(TransferError::UnalignedBufferOffset(source_offset).into()); - } - if destination_offset % wgt::COPY_BUFFER_ALIGNMENT != 0 { - return Err(TransferError::UnalignedBufferOffset(destination_offset).into()); - } - if !device - .downlevel - .flags - .contains(wgt::DownlevelFlags::UNRESTRICTED_INDEX_BUFFER) - && (src_buffer.usage.contains(BufferUsages::INDEX) - || dst_buffer.usage.contains(BufferUsages::INDEX)) - { - let forbidden_usages = BufferUsages::VERTEX - | BufferUsages::UNIFORM - | BufferUsages::INDIRECT - | BufferUsages::STORAGE; - if src_buffer.usage.intersects(forbidden_usages) - || dst_buffer.usage.intersects(forbidden_usages) - { - return Err(TransferError::MissingDownlevelFlags(MissingDownlevelFlags( - wgt::DownlevelFlags::UNRESTRICTED_INDEX_BUFFER, - )) - .into()); - } - } - - let destination_end_offset = destination_offset + size; - if source_end_offset > src_buffer.size { - return Err(TransferError::BufferOverrun { - start_offset: source_offset, - end_offset: source_end_offset, - buffer_size: src_buffer.size, - side: CopySide::Source, - } - .into()); - } - if destination_end_offset > dst_buffer.size { - return Err(TransferError::BufferOverrun { - start_offset: destination_offset, - end_offset: destination_end_offset, - buffer_size: dst_buffer.size, - side: CopySide::Destination, - } - .into()); - } - - if size == 0 { - log::trace!("Ignoring copy_buffer_to_buffer of size 0"); - return Ok(()); - } - - // Make sure source is initialized memory and mark dest as initialized. - cmd_buf_data.buffer_memory_init_actions.extend( - dst_buffer.initialization_status.read().create_action( - &dst_buffer, - destination_offset..(destination_offset + size), - MemoryInitKind::ImplicitlyInitialized, - ), - ); - cmd_buf_data.buffer_memory_init_actions.extend( - src_buffer.initialization_status.read().create_action( - &src_buffer, - source_offset..(source_offset + size), - MemoryInitKind::NeedsInitializedMemory, - ), - ); - - let region = hal::BufferCopy { - src_offset: source_offset, - dst_offset: destination_offset, - size: wgt::BufferSize::new(size).unwrap(), - }; - let cmd_buf_raw = cmd_buf_data.encoder.open()?; - let barriers = src_barrier - .into_iter() - .chain(dst_barrier) - .collect::>(); - unsafe { - cmd_buf_raw.transition_buffers(&barriers); - cmd_buf_raw.copy_buffer_to_buffer(src_raw, dst_raw, &[region]); - } - - Ok(()) + copy_buffer_to_buffer( + cmd_buf_data, + hub, + &cmd_enc, + source, + source_offset, + destination, + destination_offset, + size, + ) }) } @@ -1008,137 +873,7 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - let device = &cmd_enc.device; - device.check_is_valid()?; - - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::CopyBufferToTexture { - src: *source, - dst: *destination, - size: *copy_size, - }); - } - - let dst_texture = hub.textures.get(destination.texture).get()?; - let src_buffer = hub.buffers.get(source.buffer).get()?; - - dst_texture.same_device_as(cmd_enc.as_ref())?; - src_buffer.same_device_as(cmd_enc.as_ref())?; - - let (hal_copy_size, array_layer_count) = validate_texture_copy_range( - destination, - &dst_texture.desc, - CopySide::Destination, - copy_size, - )?; - - let (dst_range, dst_base) = - extract_texture_selector(destination, copy_size, &dst_texture)?; - - let snatch_guard = device.snatchable_lock.read(); - - let src_raw = src_buffer.try_raw(&snatch_guard)?; - let dst_raw = dst_texture.try_raw(&snatch_guard)?; - - if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth_or_array_layers == 0 - { - log::trace!("Ignoring copy_buffer_to_texture of size 0"); - return Ok(()); - } - - // Handle texture init *before* dealing with barrier transitions so we - // have an easier time inserting "immediate-inits" that may be required - // by prior discards in rare cases. - handle_dst_texture_init( - cmd_buf_data, - device, - destination, - copy_size, - &dst_texture, - &snatch_guard, - )?; - - let src_pending = cmd_buf_data - .trackers - .buffers - .set_single(&src_buffer, wgt::BufferUses::COPY_SRC); - - src_buffer - .check_usage(BufferUsages::COPY_SRC) - .map_err(TransferError::MissingBufferUsage)?; - let src_barrier = - src_pending.map(|pending| pending.into_hal(&src_buffer, &snatch_guard)); - - let dst_pending = cmd_buf_data.trackers.textures.set_single( - &dst_texture, - dst_range, - wgt::TextureUses::COPY_DST, - ); - dst_texture - .check_usage(TextureUsages::COPY_DST) - .map_err(TransferError::MissingTextureUsage)?; - let dst_barrier = dst_pending - .map(|pending| pending.into_hal(dst_raw)) - .collect::>(); - - validate_texture_copy_dst_format(dst_texture.desc.format, destination.aspect)?; - - validate_texture_buffer_copy( - destination, - dst_base.aspect, - &dst_texture.desc, - &source.layout, - true, // alignment required for buffer offset - )?; - - let (required_buffer_bytes_in_copy, bytes_per_array_layer, is_contiguous) = - validate_linear_texture_data( - &source.layout, - dst_texture.desc.format, - destination.aspect, - src_buffer.size, - CopySide::Source, - copy_size, - )?; - - if dst_texture.desc.format.is_depth_stencil_format() { - device - .require_downlevel_flags(wgt::DownlevelFlags::DEPTH_TEXTURE_AND_BUFFER_COPIES) - .map_err(TransferError::from)?; - } - - handle_buffer_init( - cmd_buf_data, - source, - &src_buffer, - CopySide::Source, - required_buffer_bytes_in_copy, - is_contiguous, - ); - - let regions = (0..array_layer_count) - .map(|rel_array_layer| { - let mut texture_base = dst_base.clone(); - texture_base.array_layer += rel_array_layer; - let mut buffer_layout = source.layout; - buffer_layout.offset += rel_array_layer as u64 * bytes_per_array_layer; - hal::BufferTextureCopy { - buffer_layout, - texture_base, - size: hal_copy_size, - } - }) - .collect::>(); - - let cmd_buf_raw = cmd_buf_data.encoder.open()?; - unsafe { - cmd_buf_raw.transition_textures(&dst_barrier); - cmd_buf_raw.transition_buffers(src_barrier.as_slice()); - cmd_buf_raw.copy_buffer_to_texture(src_raw, dst_raw, ®ions); - } - - Ok(()) + copy_buffer_to_texture(cmd_buf_data, hub, &cmd_enc, source, destination, copy_size) }) } @@ -1161,344 +896,635 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - let device = &cmd_enc.device; - device.check_is_valid()?; - - #[cfg(feature = "trace")] - if let Some(list) = cmd_buf_data.trace_commands.as_mut() { - list.push(TraceCommand::CopyTextureToBuffer { - src: *source, - dst: *destination, - size: *copy_size, - }); - } + copy_texture_to_buffer(cmd_buf_data, hub, &cmd_enc, source, destination, copy_size) + }) + } - let src_texture = hub.textures.get(source.texture).get()?; - let dst_buffer = hub.buffers.get(destination.buffer).get()?; + pub fn command_encoder_copy_texture_to_texture( + &self, + command_encoder_id: CommandEncoderId, + source: &TexelCopyTextureInfo, + destination: &TexelCopyTextureInfo, + copy_size: &Extent3d, + ) -> Result<(), EncoderStateError> { + profiling::scope!("CommandEncoder::copy_texture_to_texture"); + api_log!( + "CommandEncoder::copy_texture_to_texture {:?} -> {:?} {copy_size:?}", + source.texture, + destination.texture + ); - src_texture.same_device_as(cmd_enc.as_ref())?; - dst_buffer.same_device_as(cmd_enc.as_ref())?; + let hub = &self.hub; - let (hal_copy_size, array_layer_count) = validate_texture_copy_range( - source, - &src_texture.desc, - CopySide::Source, - copy_size, - )?; + let cmd_enc = hub.command_encoders.get(command_encoder_id); + let mut cmd_buf_data = cmd_enc.data.lock(); + cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { + copy_texture_to_texture(cmd_buf_data, hub, &cmd_enc, source, destination, copy_size) + }) + } +} - let (src_range, src_base) = extract_texture_selector(source, copy_size, &src_texture)?; +fn copy_buffer_to_buffer( + cmd_buf_data: &mut CommandBufferMutable, + hub: &crate::hub::Hub, + cmd_enc: &Arc, + source: BufferId, + source_offset: BufferAddress, + destination: BufferId, + destination_offset: BufferAddress, + size: Option, +) -> Result<(), CommandEncoderError> { + let device = &cmd_enc.device; + device.check_is_valid()?; + + if source == destination { + return Err(TransferError::SameSourceDestinationBuffer.into()); + } - let snatch_guard = device.snatchable_lock.read(); + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace_commands { + list.push(TraceCommand::CopyBufferToBuffer { + src: source, + src_offset: source_offset, + dst: destination, + dst_offset: destination_offset, + size, + }); + } - let src_raw = src_texture.try_raw(&snatch_guard)?; - src_texture - .check_usage(TextureUsages::COPY_SRC) - .map_err(TransferError::MissingTextureUsage)?; + let snatch_guard = device.snatchable_lock.read(); - if source.mip_level >= src_texture.desc.mip_level_count { - return Err(TransferError::InvalidMipLevel { - requested: source.mip_level, - count: src_texture.desc.mip_level_count, - } - .into()); - } + let src_buffer = hub.buffers.get(source).get()?; - validate_texture_copy_src_format(src_texture.desc.format, source.aspect)?; + src_buffer.same_device_as(cmd_enc.as_ref())?; - validate_texture_buffer_copy( - source, - src_base.aspect, - &src_texture.desc, - &destination.layout, - true, // alignment required for buffer offset - )?; + let src_pending = cmd_buf_data + .trackers + .buffers + .set_single(&src_buffer, wgt::BufferUses::COPY_SRC); - let (required_buffer_bytes_in_copy, bytes_per_array_layer, is_contiguous) = - validate_linear_texture_data( - &destination.layout, - src_texture.desc.format, - source.aspect, - dst_buffer.size, - CopySide::Destination, - copy_size, - )?; - - if src_texture.desc.format.is_depth_stencil_format() { - device - .require_downlevel_flags(wgt::DownlevelFlags::DEPTH_TEXTURE_AND_BUFFER_COPIES) - .map_err(TransferError::from)?; - } + let src_raw = src_buffer.try_raw(&snatch_guard)?; + src_buffer + .check_usage(BufferUsages::COPY_SRC) + .map_err(TransferError::MissingBufferUsage)?; + // expecting only a single barrier + let src_barrier = src_pending.map(|pending| pending.into_hal(&src_buffer, &snatch_guard)); - let dst_raw = dst_buffer.try_raw(&snatch_guard)?; - dst_buffer - .check_usage(BufferUsages::COPY_DST) - .map_err(TransferError::MissingBufferUsage)?; + let dst_buffer = hub.buffers.get(destination).get()?; - if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth_or_array_layers == 0 - { - log::trace!("Ignoring copy_texture_to_buffer of size 0"); - return Ok(()); - } + dst_buffer.same_device_as(cmd_enc.as_ref())?; - // Handle texture init *before* dealing with barrier transitions so we - // have an easier time inserting "immediate-inits" that may be required - // by prior discards in rare cases. - handle_src_texture_init( - cmd_buf_data, - device, - source, - copy_size, - &src_texture, - &snatch_guard, - )?; + let dst_pending = cmd_buf_data + .trackers + .buffers + .set_single(&dst_buffer, wgt::BufferUses::COPY_DST); - let src_pending = cmd_buf_data.trackers.textures.set_single( - &src_texture, - src_range, - wgt::TextureUses::COPY_SRC, - ); - let src_barrier = src_pending - .map(|pending| pending.into_hal(src_raw)) - .collect::>(); + let dst_raw = dst_buffer.try_raw(&snatch_guard)?; + dst_buffer + .check_usage(BufferUsages::COPY_DST) + .map_err(TransferError::MissingBufferUsage)?; + let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); - let dst_pending = cmd_buf_data - .trackers - .buffers - .set_single(&dst_buffer, wgt::BufferUses::COPY_DST); + let (size, source_end_offset) = match size { + Some(size) => (size, source_offset + size), + None => (src_buffer.size - source_offset, src_buffer.size), + }; - let dst_barrier = - dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); + if size % wgt::COPY_BUFFER_ALIGNMENT != 0 { + return Err(TransferError::UnalignedCopySize(size).into()); + } + if source_offset % wgt::COPY_BUFFER_ALIGNMENT != 0 { + return Err(TransferError::UnalignedBufferOffset(source_offset).into()); + } + if destination_offset % wgt::COPY_BUFFER_ALIGNMENT != 0 { + return Err(TransferError::UnalignedBufferOffset(destination_offset).into()); + } + if !device + .downlevel + .flags + .contains(wgt::DownlevelFlags::UNRESTRICTED_INDEX_BUFFER) + && (src_buffer.usage.contains(BufferUsages::INDEX) + || dst_buffer.usage.contains(BufferUsages::INDEX)) + { + let forbidden_usages = BufferUsages::VERTEX + | BufferUsages::UNIFORM + | BufferUsages::INDIRECT + | BufferUsages::STORAGE; + if src_buffer.usage.intersects(forbidden_usages) + || dst_buffer.usage.intersects(forbidden_usages) + { + return Err(TransferError::MissingDownlevelFlags(MissingDownlevelFlags( + wgt::DownlevelFlags::UNRESTRICTED_INDEX_BUFFER, + )) + .into()); + } + } - handle_buffer_init( - cmd_buf_data, - destination, - &dst_buffer, - CopySide::Destination, - required_buffer_bytes_in_copy, - is_contiguous, - ); + let destination_end_offset = destination_offset + size; + if source_end_offset > src_buffer.size { + return Err(TransferError::BufferOverrun { + start_offset: source_offset, + end_offset: source_end_offset, + buffer_size: src_buffer.size, + side: CopySide::Source, + } + .into()); + } + if destination_end_offset > dst_buffer.size { + return Err(TransferError::BufferOverrun { + start_offset: destination_offset, + end_offset: destination_end_offset, + buffer_size: dst_buffer.size, + side: CopySide::Destination, + } + .into()); + } - let regions = (0..array_layer_count) - .map(|rel_array_layer| { - let mut texture_base = src_base.clone(); - texture_base.array_layer += rel_array_layer; - let mut buffer_layout = destination.layout; - buffer_layout.offset += rel_array_layer as u64 * bytes_per_array_layer; - hal::BufferTextureCopy { - buffer_layout, - texture_base, - size: hal_copy_size, - } - }) - .collect::>(); - let cmd_buf_raw = cmd_buf_data.encoder.open()?; - unsafe { - cmd_buf_raw.transition_buffers(dst_barrier.as_slice()); - cmd_buf_raw.transition_textures(&src_barrier); - cmd_buf_raw.copy_texture_to_buffer( - src_raw, - wgt::TextureUses::COPY_SRC, - dst_raw, - ®ions, - ); - } + if size == 0 { + log::trace!("Ignoring copy_buffer_to_buffer of size 0"); + return Ok(()); + } - Ok(()) - }) + // Make sure source is initialized memory and mark dest as initialized. + cmd_buf_data.buffer_memory_init_actions.extend( + dst_buffer.initialization_status.read().create_action( + &dst_buffer, + destination_offset..(destination_offset + size), + MemoryInitKind::ImplicitlyInitialized, + ), + ); + cmd_buf_data.buffer_memory_init_actions.extend( + src_buffer.initialization_status.read().create_action( + &src_buffer, + source_offset..(source_offset + size), + MemoryInitKind::NeedsInitializedMemory, + ), + ); + + let region = hal::BufferCopy { + src_offset: source_offset, + dst_offset: destination_offset, + size: wgt::BufferSize::new(size).unwrap(), + }; + let cmd_buf_raw = cmd_buf_data.encoder.open()?; + let barriers = src_barrier + .into_iter() + .chain(dst_barrier) + .collect::>(); + unsafe { + cmd_buf_raw.transition_buffers(&barriers); + cmd_buf_raw.copy_buffer_to_buffer(src_raw, dst_raw, &[region]); } - pub fn command_encoder_copy_texture_to_texture( - &self, - command_encoder_id: CommandEncoderId, - source: &TexelCopyTextureInfo, - destination: &TexelCopyTextureInfo, - copy_size: &Extent3d, - ) -> Result<(), EncoderStateError> { - profiling::scope!("CommandEncoder::copy_texture_to_texture"); - api_log!( - "CommandEncoder::copy_texture_to_texture {:?} -> {:?} {copy_size:?}", - source.texture, - destination.texture - ); + Ok(()) +} - let hub = &self.hub; +fn copy_buffer_to_texture( + cmd_buf_data: &mut CommandBufferMutable, + hub: &crate::hub::Hub, + cmd_enc: &Arc, + source: &TexelCopyBufferInfo, + destination: &TexelCopyTextureInfo, + copy_size: &Extent3d, +) -> Result<(), CommandEncoderError> { + let device = &cmd_enc.device; + device.check_is_valid()?; + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace_commands { + list.push(TraceCommand::CopyBufferToTexture { + src: *source, + dst: *destination, + size: *copy_size, + }); + } - let cmd_enc = hub.command_encoders.get(command_encoder_id); - let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - let device = &cmd_enc.device; - device.check_is_valid()?; - - let snatch_guard = device.snatchable_lock.read(); - - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::CopyTextureToTexture { - src: *source, - dst: *destination, - size: *copy_size, - }); - } + let dst_texture = hub.textures.get(destination.texture).get()?; + let src_buffer = hub.buffers.get(source.buffer).get()?; - let src_texture = hub.textures.get(source.texture).get()?; - let dst_texture = hub.textures.get(destination.texture).get()?; - - src_texture.same_device_as(cmd_enc.as_ref())?; - dst_texture.same_device_as(cmd_enc.as_ref())?; - - // src and dst texture format must be copy-compatible - // https://gpuweb.github.io/gpuweb/#copy-compatible - if src_texture.desc.format.remove_srgb_suffix() - != dst_texture.desc.format.remove_srgb_suffix() - { - return Err(TransferError::TextureFormatsNotCopyCompatible { - src_format: src_texture.desc.format, - dst_format: dst_texture.desc.format, - } - .into()); - } + dst_texture.same_device_as(cmd_enc.as_ref())?; + src_buffer.same_device_as(cmd_enc.as_ref())?; - let (src_copy_size, array_layer_count) = validate_texture_copy_range( - source, - &src_texture.desc, - CopySide::Source, - copy_size, - )?; - let (dst_copy_size, _) = validate_texture_copy_range( - destination, - &dst_texture.desc, - CopySide::Destination, - copy_size, - )?; + let (hal_copy_size, array_layer_count) = validate_texture_copy_range( + destination, + &dst_texture.desc, + CopySide::Destination, + copy_size, + )?; - if Arc::as_ptr(&src_texture) == Arc::as_ptr(&dst_texture) { - validate_copy_within_same_texture( - source, - destination, - src_texture.desc.format, - array_layer_count, - )?; - } + let (dst_range, dst_base) = extract_texture_selector(destination, copy_size, &dst_texture)?; - let (src_range, src_tex_base) = - extract_texture_selector(source, copy_size, &src_texture)?; - let (dst_range, dst_tex_base) = - extract_texture_selector(destination, copy_size, &dst_texture)?; - let src_texture_aspects = hal::FormatAspects::from(src_texture.desc.format); - let dst_texture_aspects = hal::FormatAspects::from(dst_texture.desc.format); - if src_tex_base.aspect != src_texture_aspects { - return Err(TransferError::CopySrcMissingAspects.into()); - } - if dst_tex_base.aspect != dst_texture_aspects { - return Err(TransferError::CopyDstMissingAspects.into()); - } + let snatch_guard = device.snatchable_lock.read(); - if src_texture.desc.sample_count != dst_texture.desc.sample_count { - return Err(TransferError::SampleCountNotEqual { - src_sample_count: src_texture.desc.sample_count, - dst_sample_count: dst_texture.desc.sample_count, - } - .into()); - } + let src_raw = src_buffer.try_raw(&snatch_guard)?; + let dst_raw = dst_texture.try_raw(&snatch_guard)?; - // Handle texture init *before* dealing with barrier transitions so we - // have an easier time inserting "immediate-inits" that may be required - // by prior discards in rare cases. - handle_src_texture_init( - cmd_buf_data, - device, - source, - copy_size, - &src_texture, - &snatch_guard, - )?; - handle_dst_texture_init( - cmd_buf_data, - device, - destination, - copy_size, - &dst_texture, - &snatch_guard, - )?; + if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth_or_array_layers == 0 { + log::trace!("Ignoring copy_buffer_to_texture of size 0"); + return Ok(()); + } - let src_raw = src_texture.try_raw(&snatch_guard)?; - src_texture - .check_usage(TextureUsages::COPY_SRC) - .map_err(TransferError::MissingTextureUsage)?; - let dst_raw = dst_texture.try_raw(&snatch_guard)?; - dst_texture - .check_usage(TextureUsages::COPY_DST) - .map_err(TransferError::MissingTextureUsage)?; - - if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth_or_array_layers == 0 - { - log::trace!("Ignoring copy_texture_to_texture of size 0"); - return Ok(()); - } + // Handle texture init *before* dealing with barrier transitions so we + // have an easier time inserting "immediate-inits" that may be required + // by prior discards in rare cases. + handle_dst_texture_init( + cmd_buf_data, + device, + destination, + copy_size, + &dst_texture, + &snatch_guard, + )?; - let src_pending = cmd_buf_data.trackers.textures.set_single( - &src_texture, - src_range, - wgt::TextureUses::COPY_SRC, - ); + let src_pending = cmd_buf_data + .trackers + .buffers + .set_single(&src_buffer, wgt::BufferUses::COPY_SRC); + + src_buffer + .check_usage(BufferUsages::COPY_SRC) + .map_err(TransferError::MissingBufferUsage)?; + let src_barrier = src_pending.map(|pending| pending.into_hal(&src_buffer, &snatch_guard)); + + let dst_pending = cmd_buf_data.trackers.textures.set_single( + &dst_texture, + dst_range, + wgt::TextureUses::COPY_DST, + ); + dst_texture + .check_usage(TextureUsages::COPY_DST) + .map_err(TransferError::MissingTextureUsage)?; + let dst_barrier = dst_pending + .map(|pending| pending.into_hal(dst_raw)) + .collect::>(); + + validate_texture_copy_dst_format(dst_texture.desc.format, destination.aspect)?; + + validate_texture_buffer_copy( + destination, + dst_base.aspect, + &dst_texture.desc, + &source.layout, + true, // alignment required for buffer offset + )?; - //TODO: try to avoid this the collection. It's needed because both - // `src_pending` and `dst_pending` try to hold `trackers.textures` mutably. - let mut barriers: ArrayVec<_, 2> = src_pending - .map(|pending| pending.into_hal(src_raw)) - .collect(); + let (required_buffer_bytes_in_copy, bytes_per_array_layer, is_contiguous) = + validate_linear_texture_data( + &source.layout, + dst_texture.desc.format, + destination.aspect, + src_buffer.size, + CopySide::Source, + copy_size, + )?; + + if dst_texture.desc.format.is_depth_stencil_format() { + device + .require_downlevel_flags(wgt::DownlevelFlags::DEPTH_TEXTURE_AND_BUFFER_COPIES) + .map_err(TransferError::from)?; + } - let dst_pending = cmd_buf_data.trackers.textures.set_single( - &dst_texture, - dst_range, - wgt::TextureUses::COPY_DST, - ); - barriers.extend(dst_pending.map(|pending| pending.into_hal(dst_raw))); - - let hal_copy_size = hal::CopyExtent { - width: src_copy_size.width.min(dst_copy_size.width), - height: src_copy_size.height.min(dst_copy_size.height), - depth: src_copy_size.depth.min(dst_copy_size.depth), - }; - - let regions = (0..array_layer_count).map(|rel_array_layer| { - let mut src_base = src_tex_base.clone(); - let mut dst_base = dst_tex_base.clone(); - src_base.array_layer += rel_array_layer; - dst_base.array_layer += rel_array_layer; - hal::TextureCopy { - src_base, - dst_base, - size: hal_copy_size, - } - }); - - let regions = if dst_tex_base.aspect == hal::FormatAspects::DEPTH_STENCIL { - regions - .flat_map(|region| { - let (mut depth, mut stencil) = (region.clone(), region); - depth.src_base.aspect = hal::FormatAspects::DEPTH; - depth.dst_base.aspect = hal::FormatAspects::DEPTH; - stencil.src_base.aspect = hal::FormatAspects::STENCIL; - stencil.dst_base.aspect = hal::FormatAspects::STENCIL; - [depth, stencil] - }) - .collect::>() - } else { - regions.collect::>() - }; - let cmd_buf_raw = cmd_buf_data.encoder.open()?; - unsafe { - cmd_buf_raw.transition_textures(&barriers); - cmd_buf_raw.copy_texture_to_texture( - src_raw, - wgt::TextureUses::COPY_SRC, - dst_raw, - ®ions, - ); + handle_buffer_init( + cmd_buf_data, + source, + &src_buffer, + CopySide::Source, + required_buffer_bytes_in_copy, + is_contiguous, + ); + + let regions = (0..array_layer_count) + .map(|rel_array_layer| { + let mut texture_base = dst_base.clone(); + texture_base.array_layer += rel_array_layer; + let mut buffer_layout = source.layout; + buffer_layout.offset += rel_array_layer as u64 * bytes_per_array_layer; + hal::BufferTextureCopy { + buffer_layout, + texture_base, + size: hal_copy_size, } + }) + .collect::>(); - Ok(()) + let cmd_buf_raw = cmd_buf_data.encoder.open()?; + unsafe { + cmd_buf_raw.transition_textures(&dst_barrier); + cmd_buf_raw.transition_buffers(src_barrier.as_slice()); + cmd_buf_raw.copy_buffer_to_texture(src_raw, dst_raw, ®ions); + } + + Ok(()) +} + +fn copy_texture_to_buffer( + cmd_buf_data: &mut CommandBufferMutable, + hub: &crate::hub::Hub, + cmd_enc: &Arc, + source: &TexelCopyTextureInfo, + destination: &TexelCopyBufferInfo, + copy_size: &Extent3d, +) -> Result<(), CommandEncoderError> { + let device = &cmd_enc.device; + device.check_is_valid()?; + + #[cfg(feature = "trace")] + if let Some(list) = cmd_buf_data.trace_commands.as_mut() { + list.push(TraceCommand::CopyTextureToBuffer { + src: *source, + dst: *destination, + size: *copy_size, + }); + } + + let src_texture = hub.textures.get(source.texture).get()?; + let dst_buffer = hub.buffers.get(destination.buffer).get()?; + + src_texture.same_device_as(cmd_enc.as_ref())?; + dst_buffer.same_device_as(cmd_enc.as_ref())?; + + let (hal_copy_size, array_layer_count) = + validate_texture_copy_range(source, &src_texture.desc, CopySide::Source, copy_size)?; + + let (src_range, src_base) = extract_texture_selector(source, copy_size, &src_texture)?; + + let snatch_guard = device.snatchable_lock.read(); + + let src_raw = src_texture.try_raw(&snatch_guard)?; + src_texture + .check_usage(TextureUsages::COPY_SRC) + .map_err(TransferError::MissingTextureUsage)?; + + if source.mip_level >= src_texture.desc.mip_level_count { + return Err(TransferError::InvalidMipLevel { + requested: source.mip_level, + count: src_texture.desc.mip_level_count, + } + .into()); + } + + validate_texture_copy_src_format(src_texture.desc.format, source.aspect)?; + + validate_texture_buffer_copy( + source, + src_base.aspect, + &src_texture.desc, + &destination.layout, + true, // alignment required for buffer offset + )?; + + let (required_buffer_bytes_in_copy, bytes_per_array_layer, is_contiguous) = + validate_linear_texture_data( + &destination.layout, + src_texture.desc.format, + source.aspect, + dst_buffer.size, + CopySide::Destination, + copy_size, + )?; + + if src_texture.desc.format.is_depth_stencil_format() { + device + .require_downlevel_flags(wgt::DownlevelFlags::DEPTH_TEXTURE_AND_BUFFER_COPIES) + .map_err(TransferError::from)?; + } + + let dst_raw = dst_buffer.try_raw(&snatch_guard)?; + dst_buffer + .check_usage(BufferUsages::COPY_DST) + .map_err(TransferError::MissingBufferUsage)?; + + if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth_or_array_layers == 0 { + log::trace!("Ignoring copy_texture_to_buffer of size 0"); + return Ok(()); + } + + // Handle texture init *before* dealing with barrier transitions so we + // have an easier time inserting "immediate-inits" that may be required + // by prior discards in rare cases. + handle_src_texture_init( + cmd_buf_data, + device, + source, + copy_size, + &src_texture, + &snatch_guard, + )?; + + let src_pending = cmd_buf_data.trackers.textures.set_single( + &src_texture, + src_range, + wgt::TextureUses::COPY_SRC, + ); + let src_barrier = src_pending + .map(|pending| pending.into_hal(src_raw)) + .collect::>(); + + let dst_pending = cmd_buf_data + .trackers + .buffers + .set_single(&dst_buffer, wgt::BufferUses::COPY_DST); + + let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); + + handle_buffer_init( + cmd_buf_data, + destination, + &dst_buffer, + CopySide::Destination, + required_buffer_bytes_in_copy, + is_contiguous, + ); + + let regions = (0..array_layer_count) + .map(|rel_array_layer| { + let mut texture_base = src_base.clone(); + texture_base.array_layer += rel_array_layer; + let mut buffer_layout = destination.layout; + buffer_layout.offset += rel_array_layer as u64 * bytes_per_array_layer; + hal::BufferTextureCopy { + buffer_layout, + texture_base, + size: hal_copy_size, + } }) + .collect::>(); + let cmd_buf_raw = cmd_buf_data.encoder.open()?; + unsafe { + cmd_buf_raw.transition_buffers(dst_barrier.as_slice()); + cmd_buf_raw.transition_textures(&src_barrier); + cmd_buf_raw.copy_texture_to_buffer(src_raw, wgt::TextureUses::COPY_SRC, dst_raw, ®ions); + } + + Ok(()) +} + +fn copy_texture_to_texture( + cmd_buf_data: &mut CommandBufferMutable, + hub: &crate::hub::Hub, + cmd_enc: &Arc, + source: &TexelCopyTextureInfo, + destination: &TexelCopyTextureInfo, + copy_size: &Extent3d, +) -> Result<(), CommandEncoderError> { + let device = &cmd_enc.device; + device.check_is_valid()?; + + let snatch_guard = device.snatchable_lock.read(); + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace_commands { + list.push(TraceCommand::CopyTextureToTexture { + src: *source, + dst: *destination, + size: *copy_size, + }); + } + + let src_texture = hub.textures.get(source.texture).get()?; + let dst_texture = hub.textures.get(destination.texture).get()?; + + src_texture.same_device_as(cmd_enc.as_ref())?; + dst_texture.same_device_as(cmd_enc.as_ref())?; + + // src and dst texture format must be copy-compatible + // https://gpuweb.github.io/gpuweb/#copy-compatible + if src_texture.desc.format.remove_srgb_suffix() != dst_texture.desc.format.remove_srgb_suffix() + { + return Err(TransferError::TextureFormatsNotCopyCompatible { + src_format: src_texture.desc.format, + dst_format: dst_texture.desc.format, + } + .into()); } + + let (src_copy_size, array_layer_count) = + validate_texture_copy_range(source, &src_texture.desc, CopySide::Source, copy_size)?; + let (dst_copy_size, _) = validate_texture_copy_range( + destination, + &dst_texture.desc, + CopySide::Destination, + copy_size, + )?; + + if Arc::as_ptr(&src_texture) == Arc::as_ptr(&dst_texture) { + validate_copy_within_same_texture( + source, + destination, + src_texture.desc.format, + array_layer_count, + )?; + } + + let (src_range, src_tex_base) = extract_texture_selector(source, copy_size, &src_texture)?; + let (dst_range, dst_tex_base) = extract_texture_selector(destination, copy_size, &dst_texture)?; + let src_texture_aspects = hal::FormatAspects::from(src_texture.desc.format); + let dst_texture_aspects = hal::FormatAspects::from(dst_texture.desc.format); + if src_tex_base.aspect != src_texture_aspects { + return Err(TransferError::CopySrcMissingAspects.into()); + } + if dst_tex_base.aspect != dst_texture_aspects { + return Err(TransferError::CopyDstMissingAspects.into()); + } + + if src_texture.desc.sample_count != dst_texture.desc.sample_count { + return Err(TransferError::SampleCountNotEqual { + src_sample_count: src_texture.desc.sample_count, + dst_sample_count: dst_texture.desc.sample_count, + } + .into()); + } + + // Handle texture init *before* dealing with barrier transitions so we + // have an easier time inserting "immediate-inits" that may be required + // by prior discards in rare cases. + handle_src_texture_init( + cmd_buf_data, + device, + source, + copy_size, + &src_texture, + &snatch_guard, + )?; + handle_dst_texture_init( + cmd_buf_data, + device, + destination, + copy_size, + &dst_texture, + &snatch_guard, + )?; + + let src_raw = src_texture.try_raw(&snatch_guard)?; + src_texture + .check_usage(TextureUsages::COPY_SRC) + .map_err(TransferError::MissingTextureUsage)?; + let dst_raw = dst_texture.try_raw(&snatch_guard)?; + dst_texture + .check_usage(TextureUsages::COPY_DST) + .map_err(TransferError::MissingTextureUsage)?; + + if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth_or_array_layers == 0 { + log::trace!("Ignoring copy_texture_to_texture of size 0"); + return Ok(()); + } + + let src_pending = cmd_buf_data.trackers.textures.set_single( + &src_texture, + src_range, + wgt::TextureUses::COPY_SRC, + ); + + //TODO: try to avoid this the collection. It's needed because both + // `src_pending` and `dst_pending` try to hold `trackers.textures` mutably. + let mut barriers: ArrayVec<_, 2> = src_pending + .map(|pending| pending.into_hal(src_raw)) + .collect(); + + let dst_pending = cmd_buf_data.trackers.textures.set_single( + &dst_texture, + dst_range, + wgt::TextureUses::COPY_DST, + ); + barriers.extend(dst_pending.map(|pending| pending.into_hal(dst_raw))); + + let hal_copy_size = hal::CopyExtent { + width: src_copy_size.width.min(dst_copy_size.width), + height: src_copy_size.height.min(dst_copy_size.height), + depth: src_copy_size.depth.min(dst_copy_size.depth), + }; + + let regions = (0..array_layer_count).map(|rel_array_layer| { + let mut src_base = src_tex_base.clone(); + let mut dst_base = dst_tex_base.clone(); + src_base.array_layer += rel_array_layer; + dst_base.array_layer += rel_array_layer; + hal::TextureCopy { + src_base, + dst_base, + size: hal_copy_size, + } + }); + + let regions = if dst_tex_base.aspect == hal::FormatAspects::DEPTH_STENCIL { + regions + .flat_map(|region| { + let (mut depth, mut stencil) = (region.clone(), region); + depth.src_base.aspect = hal::FormatAspects::DEPTH; + depth.dst_base.aspect = hal::FormatAspects::DEPTH; + stencil.src_base.aspect = hal::FormatAspects::STENCIL; + stencil.dst_base.aspect = hal::FormatAspects::STENCIL; + [depth, stencil] + }) + .collect::>() + } else { + regions.collect::>() + }; + let cmd_buf_raw = cmd_buf_data.encoder.open()?; + unsafe { + cmd_buf_raw.transition_textures(&barriers); + cmd_buf_raw.copy_texture_to_texture(src_raw, wgt::TextureUses::COPY_SRC, dst_raw, ®ions); + } + + Ok(()) } From aee8cd165084ba708fbc98d513b5bf274107b96e Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Mon, 15 Sep 2025 11:48:28 -0700 Subject: [PATCH 210/303] Lazy-load the dcomp library (#8216) --- Cargo.lock | 1 + wgpu-hal/Cargo.toml | 2 + wgpu-hal/src/dx12/adapter.rs | 5 ++- wgpu-hal/src/dx12/dcomp.rs | 73 +++++++++++++++++++++++++++++++---- wgpu-hal/src/dx12/device.rs | 4 +- wgpu-hal/src/dx12/instance.rs | 4 +- wgpu-hal/src/dx12/mod.rs | 7 +++- 7 files changed, 84 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 57ee57c5425..42da5cf0d78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5126,6 +5126,7 @@ dependencies = [ "naga", "ndk-sys 0.6.0+11769913", "objc", + "once_cell", "ordered-float 5.0.0", "parking_lot", "portable-atomic", diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index 94dc0e07e0c..3b8c37c861e 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -136,6 +136,7 @@ dx12 = [ "dep:libloading", "dep:log", "dep:ordered-float", + "dep:once_cell", "dep:parking_lot", "dep:profiling", "dep:range-alloc", @@ -258,6 +259,7 @@ windows-core = { workspace = true, optional = true } bit-set = { workspace = true, optional = true } range-alloc = { workspace = true, optional = true } gpu-allocator = { workspace = true, optional = true } +once_cell = { workspace = true, optional = true } # backend: GLES glutin_wgl_sys = { workspace = true, optional = true } diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index 7f96bbcbaff..6dce0ce97f0 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -17,7 +17,7 @@ use crate::{ self, dxgi::{factory::DxgiAdapter, result::HResult}, }, - dx12::{shader_compilation, SurfaceTarget}, + dx12::{dcomp::DCompLib, shader_compilation, SurfaceTarget}, }; impl Drop for super::Adapter { @@ -55,6 +55,7 @@ impl super::Adapter { pub(super) fn expose( adapter: DxgiAdapter, library: &Arc, + dcomp_lib: &Arc, instance_flags: wgt::InstanceFlags, memory_budget_thresholds: wgt::MemoryBudgetThresholds, compiler_container: Arc, @@ -559,6 +560,7 @@ impl super::Adapter { raw: adapter, device, library: Arc::clone(library), + dcomp_lib: Arc::clone(dcomp_lib), private_caps, presentation_timer, workarounds, @@ -726,6 +728,7 @@ impl crate::Adapter for super::Adapter { memory_hints, self.private_caps, &self.library, + &self.dcomp_lib, self.memory_budget_thresholds, self.compiler_container.clone(), self.options.clone(), diff --git a/wgpu-hal/src/dx12/dcomp.rs b/wgpu-hal/src/dx12/dcomp.rs index a6bc83352a6..e99849a6dcb 100644 --- a/wgpu-hal/src/dx12/dcomp.rs +++ b/wgpu-hal/src/dx12/dcomp.rs @@ -1,4 +1,65 @@ +use alloc::sync::Arc; +use core::{ffi, ptr}; + +use once_cell::sync::Lazy; use windows::Win32::{Foundation::HWND, Graphics::DirectComposition}; +use windows_core::Interface; + +use super::DynLib; + +// Lazy-loaded DirectComposition library +#[derive(Debug)] +pub(crate) struct DCompLib { + lib: Lazy>, +} + +impl DCompLib { + pub(crate) fn new() -> Self { + Self { + lib: Lazy::new(|| unsafe { + DynLib::new("dcomp.dll").map_err(|err| { + log::error!("Error loading dcomp.dll: {err}"); + crate::SurfaceError::Other("Error loading dcomp.dll") + }) + }), + } + } + + fn get_lib(&self) -> Result<&DynLib, crate::SurfaceError> { + match self.lib.as_ref() { + Ok(lib) => Ok(lib), + Err(err) => Err(err.clone()), + } + } + + pub(crate) fn create_device( + &self, + ) -> Result { + let lib = self.get_lib()?; + + // Calls windows::Win32::Graphics::DirectComposition::DCompositionCreateDevice2 on dcomp.dll + type Fun = extern "system" fn( + pdxdevice: *mut ffi::c_void, + riid: *const windows_core::GUID, + ppdcompdevice: *mut *mut ffi::c_void, + ) -> windows_core::HRESULT; + let func: libloading::Symbol = + unsafe { lib.get(c"DCompositionCreateDevice2".to_bytes()) }?; + + let mut res: Option = None; + + (func)( + ptr::null_mut(), + &DirectComposition::IDCompositionDevice::IID, + <*mut _>::cast(&mut res), + ) + .map(|| res.unwrap()) + .map_err(|err| { + log::error!("DirectComposition::DCompositionCreateDevice2 failed: {err}"); + crate::SurfaceError::Other("DirectComposition::DCompositionCreateDevice2") + }) + } +} #[derive(Default)] pub struct DCompState { @@ -10,10 +71,11 @@ impl DCompState { /// If the device is already initialized, it will return the existing state. pub unsafe fn get_or_init( &mut self, + lib: &Arc, hwnd: &HWND, ) -> Result<&mut InnerState, crate::SurfaceError> { if self.inner.is_none() { - self.inner = Some(unsafe { InnerState::init(hwnd) }?); + self.inner = Some(unsafe { InnerState::init(lib, hwnd) }?); } Ok(self.inner.as_mut().unwrap()) } @@ -28,14 +90,9 @@ pub struct InnerState { impl InnerState { /// Creates a DirectComposition device and a target for the given window handle. - pub unsafe fn init(hwnd: &HWND) -> Result { + pub unsafe fn init(lib: &Arc, hwnd: &HWND) -> Result { profiling::scope!("DCompState::init"); - let dcomp_device: DirectComposition::IDCompositionDevice = { - unsafe { DirectComposition::DCompositionCreateDevice2(None) }.map_err(|err| { - log::error!("DirectComposition::DCompositionCreateDevice failed: {err}"); - crate::SurfaceError::Other("DirectComposition::DCompositionCreateDevice") - })? - }; + let dcomp_device = lib.create_device()?; let target = unsafe { dcomp_device.CreateTargetForHwnd(*hwnd, false) }.map_err(|err| { log::error!("IDCompositionDevice::CreateTargetForHwnd failed: {err}"); diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 34454c9f963..27628a19a82 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -26,7 +26,7 @@ use crate::{ dxgi::{name::ObjectExt, result::HResult}, }, dx12::{ - borrow_optional_interface_temporarily, shader_compilation, suballocation, + borrow_optional_interface_temporarily, shader_compilation, suballocation, DCompLib, DynamicStorageBufferOffsets, Event, ShaderCacheKey, ShaderCacheValue, }, AccelerationStructureEntries, TlasInstance, @@ -46,6 +46,7 @@ impl super::Device { memory_hints: &wgt::MemoryHints, private_caps: super::PrivateCapabilities, library: &Arc, + dcomp_lib: &Arc, memory_budget_thresholds: wgt::MemoryBudgetThresholds, compiler_container: Arc, backend_options: wgt::Dx12BackendOptions, @@ -201,6 +202,7 @@ impl super::Device { )), options: backend_options, library: Arc::clone(library), + dcomp_lib: Arc::clone(dcomp_lib), #[cfg(feature = "renderdoc")] render_doc: Default::default(), null_rtv_handle, diff --git a/wgpu-hal/src/dx12/instance.rs b/wgpu-hal/src/dx12/instance.rs index 5f137836f85..38d790bcb98 100644 --- a/wgpu-hal/src/dx12/instance.rs +++ b/wgpu-hal/src/dx12/instance.rs @@ -12,7 +12,7 @@ use windows::{ use super::SurfaceTarget; use crate::{ auxil, - dx12::{shader_compilation::CompilerContainer, D3D12Lib}, + dx12::{shader_compilation::CompilerContainer, D3D12Lib, DCompLib}, }; impl crate::Instance for super::Instance { @@ -104,6 +104,7 @@ impl crate::Instance for super::Instance { factory, factory_media, library: Arc::new(lib_main), + dcomp_lib: Arc::new(DCompLib::new()), presentation_system: desc.backend_options.dx12.presentation_system, _lib_dxgi: lib_dxgi, supports_allow_tearing, @@ -158,6 +159,7 @@ impl crate::Instance for super::Instance { super::Adapter::expose( raw, &self.library, + &self.dcomp_lib, self.flags, self.memory_budget_thresholds, self.compiler_container.clone(), diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index a2570048b97..b355582ab1f 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -101,6 +101,7 @@ use windows::{ }, }; +use self::dcomp::DCompLib; use crate::auxil::{ self, dxgi::{ @@ -460,6 +461,7 @@ pub struct Instance { factory: DxgiFactory, factory_media: Option, library: Arc, + dcomp_lib: Arc, supports_allow_tearing: bool, presentation_system: wgt::Dx12SwapchainKind, _lib_dxgi: DxgiLib, @@ -612,6 +614,7 @@ pub struct Adapter { raw: DxgiAdapter, device: Direct3D12::ID3D12Device, library: Arc, + dcomp_lib: Arc, private_caps: PrivateCapabilities, presentation_timer: auxil::dxgi::time::PresentationTimer, // Note: this isn't used right now, but we'll need it later. @@ -685,6 +688,7 @@ pub struct Device { srv_uav_pool: Mutex, // library library: Arc, + dcomp_lib: Arc, #[cfg(feature = "renderdoc")] render_doc: auxil::renderdoc::RenderDoc, null_rtv_handle: descriptor::Handle, @@ -1358,7 +1362,8 @@ impl crate::Surface for Surface { dcomp_state, } => { let mut dcomp_state = dcomp_state.lock(); - let dcomp_state = unsafe { dcomp_state.get_or_init(handle) }?; + let dcomp_state = + unsafe { dcomp_state.get_or_init(&device.dcomp_lib, handle) }?; // Set the new swap chain as the content for the backing visual // and commit the changes to the composition visual tree. { From 023f124fa538f64dc0f41956114e9859ef3d578e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 07:56:22 -0400 Subject: [PATCH 211/303] chore(deps): update cts digest to 7a9fcc3 (#8227) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- cts_runner/revision.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cts_runner/revision.txt b/cts_runner/revision.txt index b7f5c896781..ceacddfbd42 100644 --- a/cts_runner/revision.txt +++ b/cts_runner/revision.txt @@ -1 +1 @@ -20d2805a255a3ea41227200a61405ddb2871bcc0 +7a9fcc3382d4b6abebd6b04221ec0e844b87e326 From b55c24cf2720e4d46b3ffd8a7673068438fe2452 Mon Sep 17 00:00:00 2001 From: Matthias Reitinger Date: Tue, 16 Sep 2025 13:58:23 +0200 Subject: [PATCH 212/303] [naga wgsl-in] Allow trailing comma in switch cases (#8165) --- CHANGELOG.md | 1 + naga/src/front/wgsl/parse/mod.rs | 15 +- naga/tests/in/wgsl/control-flow.wgsl | 19 + .../glsl/wgsl-control-flow.main.Compute.glsl | 29 +- naga/tests/out/hlsl/wgsl-control-flow.hlsl | 29 +- naga/tests/out/msl/wgsl-control-flow.msl | 29 +- naga/tests/out/spv/wgsl-control-flow.spvasm | 605 +++++++++--------- naga/tests/out/wgsl/wgsl-control-flow.wgsl | 25 +- 8 files changed, 447 insertions(+), 305 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bac70e359f..a0df9e6da4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -218,6 +218,7 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). #### naga - [wgsl-in] Allow a trailing comma in `@blend_src(…)` attributes. By @ErichDonGubler in [#8137](https://github.com/gfx-rs/wgpu/pull/8137). +- [wgsl-in] Allow a trailing comma in the list of `case` values inside a `switch`. By @reima in [#8165](https://github.com/gfx-rs/wgpu/pull/8165). ### Documentation diff --git a/naga/src/front/wgsl/parse/mod.rs b/naga/src/front/wgsl/parse/mod.rs index c7f81005e97..c01ba4de30f 100644 --- a/naga/src/front/wgsl/parse/mod.rs +++ b/naga/src/front/wgsl/parse/mod.rs @@ -2121,7 +2121,7 @@ impl Parser { let _ = lexer.next(); this.pop_rule_span(lexer); } - (Token::Paren('{') | Token::Attribute, _) => { + (token, _) if is_start_of_compound_statement(token) => { let (inner, span) = this.block(lexer, ctx, brace_nesting_level)?; block.stmts.push(ast::Statement { kind: ast::StatementKind::Block(inner), @@ -2287,11 +2287,14 @@ impl Parser { let value = loop { let value = this.switch_value(lexer, ctx)?; if lexer.skip(Token::Separator(',')) { - if lexer.skip(Token::Separator(':')) { + // list of values ends with ':' or a compound statement + let next_token = lexer.peek().0; + if next_token == Token::Separator(':') + || is_start_of_compound_statement(next_token) + { break value; } } else { - lexer.skip(Token::Separator(':')); break value; } cases.push(ast::SwitchCase { @@ -2301,6 +2304,8 @@ impl Parser { }); }; + lexer.skip(Token::Separator(':')); + let body = this.block(lexer, ctx, brace_nesting_level)?.0; cases.push(ast::SwitchCase { @@ -3244,3 +3249,7 @@ impl Parser { }) } } + +const fn is_start_of_compound_statement<'a>(token: Token<'a>) -> bool { + matches!(token, Token::Attribute | Token::Paren('{')) +} diff --git a/naga/tests/in/wgsl/control-flow.wgsl b/naga/tests/in/wgsl/control-flow.wgsl index d8e3fb8f588..932eecd4c79 100644 --- a/naga/tests/in/wgsl/control-flow.wgsl +++ b/naga/tests/in/wgsl/control-flow.wgsl @@ -58,6 +58,25 @@ fn control_flow() { pos = 3; } } + + // trailing commas + switch pos { + case 1, { + pos = 0; + } + case 2,: { + pos = 1; + } + case 3, 4, { + pos = 2; + } + case 5, 6,: { + pos = 3; + } + default { + pos = 4; + } + } } fn switch_default_break(i: i32) { diff --git a/naga/tests/out/glsl/wgsl-control-flow.main.Compute.glsl b/naga/tests/out/glsl/wgsl-control-flow.main.Compute.glsl index 6ca55cd7640..ac766ce9059 100644 --- a/naga/tests/out/glsl/wgsl-control-flow.main.Compute.glsl +++ b/naga/tests/out/glsl/wgsl-control-flow.main.Compute.glsl @@ -58,19 +58,44 @@ void control_flow() { } case 2: { pos = 1; - return; + break; } case 3: { pos = 2; + break; + } + case 4: { + break; + } + default: { + pos = 3; + break; + } + } + int _e15 = pos; + switch(_e15) { + case 1: { + pos = 0; return; } + case 2: { + pos = 1; + return; + } + case 3: case 4: { + pos = 2; return; } - default: { + case 5: + case 6: { pos = 3; return; } + default: { + pos = 4; + return; + } } } diff --git a/naga/tests/out/hlsl/wgsl-control-flow.hlsl b/naga/tests/out/hlsl/wgsl-control-flow.hlsl index 2798c90cfa9..4c907b68fe3 100644 --- a/naga/tests/out/hlsl/wgsl-control-flow.hlsl +++ b/naga/tests/out/hlsl/wgsl-control-flow.hlsl @@ -49,19 +49,44 @@ void control_flow() } case 2: { pos = int(1); - return; + break; } case 3: { pos = int(2); + break; + } + case 4: { + break; + } + default: { + pos = int(3); + break; + } + } + int _e15 = pos; + switch(_e15) { + case 1: { + pos = int(0); return; } + case 2: { + pos = int(1); + return; + } + case 3: case 4: { + pos = int(2); return; } - default: { + case 5: + case 6: { pos = int(3); return; } + default: { + pos = int(4); + return; + } } } diff --git a/naga/tests/out/msl/wgsl-control-flow.msl b/naga/tests/out/msl/wgsl-control-flow.msl index b93f9584654..ccb36a32edd 100644 --- a/naga/tests/out/msl/wgsl-control-flow.msl +++ b/naga/tests/out/msl/wgsl-control-flow.msl @@ -58,19 +58,44 @@ void control_flow( } case 2: { pos = 1; - return; + break; } case 3: { pos = 2; + break; + } + case 4: { + break; + } + default: { + pos = 3; + break; + } + } + int _e15 = pos; + switch(_e15) { + case 1: { + pos = 0; return; } + case 2: { + pos = 1; + return; + } + case 3: case 4: { + pos = 2; return; } - default: { + case 5: + case 6: { pos = 3; return; } + default: { + pos = 4; + return; + } } } diff --git a/naga/tests/out/spv/wgsl-control-flow.spvasm b/naga/tests/out/spv/wgsl-control-flow.spvasm index 93d82a6588b..e028903c447 100644 --- a/naga/tests/out/spv/wgsl-control-flow.spvasm +++ b/naga/tests/out/spv/wgsl-control-flow.spvasm @@ -1,12 +1,12 @@ ; SPIR-V ; Version: 1.1 ; Generator: rspirv -; Bound: 234 +; Bound: 241 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %224 "main" -OpExecutionMode %224 LocalSize 1 1 1 +OpEntryPoint GLCompute %231 "main" +OpExecutionMode %231 LocalSize 1 1 1 %2 = OpTypeVoid %3 = OpTypeInt 32 1 %6 = OpTypeFunction %2 @@ -24,16 +24,16 @@ OpExecutionMode %224 LocalSize 1 1 1 %20 = OpConstant %12 72 %21 = OpConstant %12 264 %22 = OpConstant %12 2056 -%45 = OpTypeFunction %2 %3 -%82 = OpTypeVector %12 2 -%83 = OpTypePointer Function %82 -%84 = OpTypeBool -%85 = OpTypeVector %84 2 -%86 = OpConstantComposite %82 %13 %13 -%87 = OpConstant %12 4294967295 -%88 = OpConstantComposite %82 %87 %87 -%108 = OpTypeFunction %2 %3 %3 %3 -%177 = OpTypeFunction %2 %3 %3 %3 %3 +%52 = OpTypeFunction %2 %3 +%89 = OpTypeVector %12 2 +%90 = OpTypePointer Function %89 +%91 = OpTypeBool +%92 = OpTypeVector %91 2 +%93 = OpConstantComposite %89 %13 %13 +%94 = OpConstant %12 4294967295 +%95 = OpConstantComposite %89 %94 %94 +%115 = OpTypeFunction %2 %3 %3 %3 +%184 = OpTypeFunction %2 %3 %3 %3 %3 %5 = OpFunction %2 None %6 %4 = OpLabel %14 = OpVariable %15 Function %16 @@ -82,343 +82,362 @@ OpStore %14 %8 OpBranch %36 %38 = OpLabel OpStore %14 %7 -OpReturn +OpBranch %36 %39 = OpLabel OpStore %14 %9 -OpReturn +OpBranch %36 %40 = OpLabel -OpReturn +OpBranch %36 %41 = OpLabel OpStore %14 %10 -OpReturn +OpBranch %36 %36 = OpLabel +%42 = OpLoad %3 %14 +OpSelectionMerge %43 None +OpSwitch %42 %48 1 %44 2 %45 3 %46 4 %46 5 %47 6 %47 +%44 = OpLabel +OpStore %14 %8 +OpReturn +%45 = OpLabel +OpStore %14 %7 OpReturn -OpFunctionEnd -%44 = OpFunction %2 None %45 -%43 = OpFunctionParameter %3 -%42 = OpLabel -OpBranch %46 %46 = OpLabel -OpSelectionMerge %47 None -OpSwitch %43 %48 -%48 = OpLabel -OpBranch %47 +OpStore %14 %9 +OpReturn %47 = OpLabel +OpStore %14 %10 +OpReturn +%48 = OpLabel +OpStore %14 %11 +OpReturn +%43 = OpLabel OpReturn OpFunctionEnd -%50 = OpFunction %2 None %6 +%51 = OpFunction %2 None %52 +%50 = OpFunctionParameter %3 %49 = OpLabel -OpBranch %51 -%51 = OpLabel -OpSelectionMerge %52 None -OpSwitch %8 %54 0 %53 +OpBranch %53 %53 = OpLabel -OpBranch %52 +OpSelectionMerge %54 None +OpSwitch %50 %55 +%55 = OpLabel +OpBranch %54 %54 = OpLabel -OpBranch %52 -%52 = OpLabel OpReturn OpFunctionEnd -%56 = OpFunction %2 None %6 -%55 = OpLabel -OpBranch %57 -%57 = OpLabel -OpSelectionMerge %58 None -OpSwitch %13 %60 0 %59 -%59 = OpLabel -OpBranch %58 -%60 = OpLabel +%57 = OpFunction %2 None %6 +%56 = OpLabel OpBranch %58 %58 = OpLabel -OpSelectionMerge %61 None -OpSwitch %13 %63 0 %62 -%62 = OpLabel -OpReturn -%63 = OpLabel -OpReturn +OpSelectionMerge %59 None +OpSwitch %8 %61 0 %60 +%60 = OpLabel +OpBranch %59 %61 = OpLabel +OpBranch %59 +%59 = OpLabel OpReturn OpFunctionEnd -%65 = OpFunction %2 None %6 +%63 = OpFunction %2 None %6 +%62 = OpLabel +OpBranch %64 %64 = OpLabel -OpBranch %66 +OpSelectionMerge %65 None +OpSwitch %13 %67 0 %66 %66 = OpLabel -OpSelectionMerge %67 None -OpSwitch %8 %73 0 %68 1 %69 2 %70 3 %71 4 %72 -%68 = OpLabel -OpReturn +OpBranch %65 +%67 = OpLabel +OpBranch %65 +%65 = OpLabel +OpSelectionMerge %68 None +OpSwitch %13 %70 0 %69 %69 = OpLabel OpReturn %70 = OpLabel OpReturn -%71 = OpLabel -OpReturn -%72 = OpLabel +%68 = OpLabel OpReturn +OpFunctionEnd +%72 = OpFunction %2 None %6 +%71 = OpLabel +OpBranch %73 %73 = OpLabel +OpSelectionMerge %74 None +OpSwitch %8 %80 0 %75 1 %76 2 %77 3 %78 4 %79 +%75 = OpLabel OpReturn -%67 = OpLabel +%76 = OpLabel OpReturn -OpFunctionEnd -%76 = OpFunction %2 None %45 -%75 = OpFunctionParameter %3 -%74 = OpLabel -%89 = OpVariable %83 Function %88 -OpBranch %77 %77 = OpLabel -OpBranch %78 +OpReturn %78 = OpLabel -OpLoopMerge %79 %81 None -OpBranch %90 -%90 = OpLabel -%91 = OpLoad %82 %89 -%92 = OpIEqual %85 %86 %91 -%93 = OpAll %84 %92 -OpSelectionMerge %94 None -OpBranchConditional %93 %79 %94 -%94 = OpLabel -%95 = OpCompositeExtract %12 %91 1 -%96 = OpIEqual %84 %95 %13 -%97 = OpSelect %12 %96 %19 %13 -%98 = OpCompositeConstruct %82 %97 %19 -%99 = OpISub %82 %91 %98 -OpStore %89 %99 -OpBranch %80 -%80 = OpLabel -OpSelectionMerge %100 None -OpSwitch %75 %102 1 %101 -%101 = OpLabel -OpBranch %81 -%102 = OpLabel -OpBranch %100 -%100 = OpLabel -OpBranch %81 -%81 = OpLabel -OpBranch %78 +OpReturn %79 = OpLabel OpReturn +%80 = OpLabel +OpReturn +%74 = OpLabel +OpReturn OpFunctionEnd -%107 = OpFunction %2 None %108 -%104 = OpFunctionParameter %3 -%105 = OpFunctionParameter %3 -%106 = OpFunctionParameter %3 -%103 = OpLabel -%114 = OpVariable %83 Function %88 -%136 = OpVariable %83 Function %88 -%156 = OpVariable %83 Function %88 -OpBranch %109 +%83 = OpFunction %2 None %52 +%82 = OpFunctionParameter %3 +%81 = OpLabel +%96 = OpVariable %90 Function %95 +OpBranch %84 +%84 = OpLabel +OpBranch %85 +%85 = OpLabel +OpLoopMerge %86 %88 None +OpBranch %97 +%97 = OpLabel +%98 = OpLoad %89 %96 +%99 = OpIEqual %92 %93 %98 +%100 = OpAll %91 %99 +OpSelectionMerge %101 None +OpBranchConditional %100 %86 %101 +%101 = OpLabel +%102 = OpCompositeExtract %12 %98 1 +%103 = OpIEqual %91 %102 %13 +%104 = OpSelect %12 %103 %19 %13 +%105 = OpCompositeConstruct %89 %104 %19 +%106 = OpISub %89 %98 %105 +OpStore %96 %106 +OpBranch %87 +%87 = OpLabel +OpSelectionMerge %107 None +OpSwitch %82 %109 1 %108 +%108 = OpLabel +OpBranch %88 %109 = OpLabel -OpBranch %110 +OpBranch %107 +%107 = OpLabel +OpBranch %88 +%88 = OpLabel +OpBranch %85 +%86 = OpLabel +OpReturn +OpFunctionEnd +%114 = OpFunction %2 None %115 +%111 = OpFunctionParameter %3 +%112 = OpFunctionParameter %3 +%113 = OpFunctionParameter %3 %110 = OpLabel -OpLoopMerge %111 %113 None -OpBranch %115 -%115 = OpLabel -%116 = OpLoad %82 %114 -%117 = OpIEqual %85 %86 %116 -%118 = OpAll %84 %117 -OpSelectionMerge %119 None -OpBranchConditional %118 %111 %119 -%119 = OpLabel -%120 = OpCompositeExtract %12 %116 1 -%121 = OpIEqual %84 %120 %13 -%122 = OpSelect %12 %121 %19 %13 -%123 = OpCompositeConstruct %82 %122 %19 -%124 = OpISub %82 %116 %123 -OpStore %114 %124 -OpBranch %112 -%112 = OpLabel -OpSelectionMerge %125 None -OpSwitch %104 %128 1 %126 2 %127 +%121 = OpVariable %90 Function %95 +%143 = OpVariable %90 Function %95 +%163 = OpVariable %90 Function %95 +OpBranch %116 +%116 = OpLabel +OpBranch %117 +%117 = OpLabel +OpLoopMerge %118 %120 None +OpBranch %122 +%122 = OpLabel +%123 = OpLoad %89 %121 +%124 = OpIEqual %92 %93 %123 +%125 = OpAll %91 %124 +OpSelectionMerge %126 None +OpBranchConditional %125 %118 %126 %126 = OpLabel -OpBranch %113 -%127 = OpLabel -OpSelectionMerge %129 None -OpSwitch %105 %131 1 %130 -%130 = OpLabel -OpBranch %113 -%131 = OpLabel -OpBranch %132 -%132 = OpLabel -OpLoopMerge %133 %135 None -OpBranch %137 -%137 = OpLabel -%138 = OpLoad %82 %136 -%139 = OpIEqual %85 %86 %138 -%140 = OpAll %84 %139 -OpSelectionMerge %141 None -OpBranchConditional %140 %133 %141 -%141 = OpLabel -%142 = OpCompositeExtract %12 %138 1 -%143 = OpIEqual %84 %142 %13 -%144 = OpSelect %12 %143 %19 %13 -%145 = OpCompositeConstruct %82 %144 %19 -%146 = OpISub %82 %138 %145 -OpStore %136 %146 -OpBranch %134 +%127 = OpCompositeExtract %12 %123 1 +%128 = OpIEqual %91 %127 %13 +%129 = OpSelect %12 %128 %19 %13 +%130 = OpCompositeConstruct %89 %129 %19 +%131 = OpISub %89 %123 %130 +OpStore %121 %131 +OpBranch %119 +%119 = OpLabel +OpSelectionMerge %132 None +OpSwitch %111 %135 1 %133 2 %134 +%133 = OpLabel +OpBranch %120 %134 = OpLabel -OpSelectionMerge %147 None -OpSwitch %106 %149 1 %148 +OpSelectionMerge %136 None +OpSwitch %112 %138 1 %137 +%137 = OpLabel +OpBranch %120 +%138 = OpLabel +OpBranch %139 +%139 = OpLabel +OpLoopMerge %140 %142 None +OpBranch %144 +%144 = OpLabel +%145 = OpLoad %89 %143 +%146 = OpIEqual %92 %93 %145 +%147 = OpAll %91 %146 +OpSelectionMerge %148 None +OpBranchConditional %147 %140 %148 %148 = OpLabel -OpBranch %135 -%149 = OpLabel -OpBranch %147 -%147 = OpLabel -OpBranch %135 +%149 = OpCompositeExtract %12 %145 1 +%150 = OpIEqual %91 %149 %13 +%151 = OpSelect %12 %150 %19 %13 +%152 = OpCompositeConstruct %89 %151 %19 +%153 = OpISub %89 %145 %152 +OpStore %143 %153 +OpBranch %141 +%141 = OpLabel +OpSelectionMerge %154 None +OpSwitch %113 %156 1 %155 +%155 = OpLabel +OpBranch %142 +%156 = OpLabel +OpBranch %154 +%154 = OpLabel +OpBranch %142 +%142 = OpLabel +OpBranch %139 +%140 = OpLabel +OpBranch %136 +%136 = OpLabel +OpBranch %132 %135 = OpLabel OpBranch %132 -%133 = OpLabel -OpBranch %129 -%129 = OpLabel -OpBranch %125 -%128 = OpLabel -OpBranch %125 -%125 = OpLabel -OpSelectionMerge %150 None -OpSwitch %105 %151 -%151 = OpLabel -OpBranch %113 -%150 = OpLabel -OpBranch %113 -%113 = OpLabel -OpBranch %110 -%111 = OpLabel -OpBranch %152 -%152 = OpLabel -OpLoopMerge %153 %155 None -OpBranch %157 +%132 = OpLabel +OpSelectionMerge %157 None +OpSwitch %112 %158 +%158 = OpLabel +OpBranch %120 %157 = OpLabel -%158 = OpLoad %82 %156 -%159 = OpIEqual %85 %86 %158 -%160 = OpAll %84 %159 -OpSelectionMerge %161 None -OpBranchConditional %160 %153 %161 -%161 = OpLabel -%162 = OpCompositeExtract %12 %158 1 -%163 = OpIEqual %84 %162 %13 -%164 = OpSelect %12 %163 %19 %13 -%165 = OpCompositeConstruct %82 %164 %19 -%166 = OpISub %82 %158 %165 -OpStore %156 %166 -OpBranch %154 -%154 = OpLabel -OpSelectionMerge %167 None -OpSwitch %105 %168 1 %168 +OpBranch %120 +%120 = OpLabel +OpBranch %117 +%118 = OpLabel +OpBranch %159 +%159 = OpLabel +OpLoopMerge %160 %162 None +OpBranch %164 +%164 = OpLabel +%165 = OpLoad %89 %163 +%166 = OpIEqual %92 %93 %165 +%167 = OpAll %91 %166 +OpSelectionMerge %168 None +OpBranchConditional %167 %160 %168 %168 = OpLabel -OpSelectionMerge %169 None -OpSwitch %106 %170 -%170 = OpLabel -OpBranch %155 -%169 = OpLabel -OpBranch %167 -%167 = OpLabel -OpBranch %155 -%155 = OpLabel -OpBranch %152 -%153 = OpLabel +%169 = OpCompositeExtract %12 %165 1 +%170 = OpIEqual %91 %169 %13 +%171 = OpSelect %12 %170 %19 %13 +%172 = OpCompositeConstruct %89 %171 %19 +%173 = OpISub %89 %165 %172 +OpStore %163 %173 +OpBranch %161 +%161 = OpLabel +OpSelectionMerge %174 None +OpSwitch %112 %175 1 %175 +%175 = OpLabel +OpSelectionMerge %176 None +OpSwitch %113 %177 +%177 = OpLabel +OpBranch %162 +%176 = OpLabel +OpBranch %174 +%174 = OpLabel +OpBranch %162 +%162 = OpLabel +OpBranch %159 +%160 = OpLabel OpReturn OpFunctionEnd -%176 = OpFunction %2 None %177 -%172 = OpFunctionParameter %3 -%173 = OpFunctionParameter %3 -%174 = OpFunctionParameter %3 -%175 = OpFunctionParameter %3 -%171 = OpLabel -%178 = OpVariable %15 Function %8 -%184 = OpVariable %83 Function %88 -%202 = OpVariable %83 Function %88 -OpBranch %179 -%179 = OpLabel -OpBranch %180 -%180 = OpLabel -OpLoopMerge %181 %183 None -OpBranch %185 -%185 = OpLabel -%186 = OpLoad %82 %184 -%187 = OpIEqual %85 %86 %186 -%188 = OpAll %84 %187 -OpSelectionMerge %189 None -OpBranchConditional %188 %181 %189 -%189 = OpLabel -%190 = OpCompositeExtract %12 %186 1 -%191 = OpIEqual %84 %190 %13 -%192 = OpSelect %12 %191 %19 %13 -%193 = OpCompositeConstruct %82 %192 %19 -%194 = OpISub %82 %186 %193 -OpStore %184 %194 -OpBranch %182 -%182 = OpLabel -OpSelectionMerge %195 None -OpSwitch %172 %197 1 %196 +%183 = OpFunction %2 None %184 +%179 = OpFunctionParameter %3 +%180 = OpFunctionParameter %3 +%181 = OpFunctionParameter %3 +%182 = OpFunctionParameter %3 +%178 = OpLabel +%185 = OpVariable %15 Function %8 +%191 = OpVariable %90 Function %95 +%209 = OpVariable %90 Function %95 +OpBranch %186 +%186 = OpLabel +OpBranch %187 +%187 = OpLabel +OpLoopMerge %188 %190 None +OpBranch %192 +%192 = OpLabel +%193 = OpLoad %89 %191 +%194 = OpIEqual %92 %93 %193 +%195 = OpAll %91 %194 +OpSelectionMerge %196 None +OpBranchConditional %195 %188 %196 %196 = OpLabel -OpStore %178 %7 -OpBranch %195 -%197 = OpLabel -OpBranch %195 -%195 = OpLabel -OpBranch %183 -%183 = OpLabel -OpBranch %180 -%181 = OpLabel -OpBranch %198 -%198 = OpLabel -OpLoopMerge %199 %201 None -OpBranch %203 +%197 = OpCompositeExtract %12 %193 1 +%198 = OpIEqual %91 %197 %13 +%199 = OpSelect %12 %198 %19 %13 +%200 = OpCompositeConstruct %89 %199 %19 +%201 = OpISub %89 %193 %200 +OpStore %191 %201 +OpBranch %189 +%189 = OpLabel +OpSelectionMerge %202 None +OpSwitch %179 %204 1 %203 %203 = OpLabel -%204 = OpLoad %82 %202 -%205 = OpIEqual %85 %86 %204 -%206 = OpAll %84 %205 -OpSelectionMerge %207 None -OpBranchConditional %206 %199 %207 -%207 = OpLabel -%208 = OpCompositeExtract %12 %204 1 -%209 = OpIEqual %84 %208 %13 -%210 = OpSelect %12 %209 %19 %13 -%211 = OpCompositeConstruct %82 %210 %19 -%212 = OpISub %82 %204 %211 -OpStore %202 %212 -OpBranch %200 -%200 = OpLabel -OpSelectionMerge %213 None -OpSwitch %172 %216 1 %214 2 %215 +OpStore %185 %7 +OpBranch %202 +%204 = OpLabel +OpBranch %202 +%202 = OpLabel +OpBranch %190 +%190 = OpLabel +OpBranch %187 +%188 = OpLabel +OpBranch %205 +%205 = OpLabel +OpLoopMerge %206 %208 None +OpBranch %210 +%210 = OpLabel +%211 = OpLoad %89 %209 +%212 = OpIEqual %92 %93 %211 +%213 = OpAll %91 %212 +OpSelectionMerge %214 None +OpBranchConditional %213 %206 %214 %214 = OpLabel -OpBranch %213 -%215 = OpLabel -OpSelectionMerge %217 None -OpSwitch %173 %219 1 %218 -%218 = OpLabel -OpBranch %201 -%219 = OpLabel +%215 = OpCompositeExtract %12 %211 1 +%216 = OpIEqual %91 %215 %13 +%217 = OpSelect %12 %216 %19 %13 +%218 = OpCompositeConstruct %89 %217 %19 +%219 = OpISub %89 %211 %218 +OpStore %209 %219 +OpBranch %207 +%207 = OpLabel OpSelectionMerge %220 None -OpSwitch %174 %222 1 %221 +OpSwitch %179 %223 1 %221 2 %222 %221 = OpLabel -OpStore %178 %9 OpBranch %220 %222 = OpLabel +OpSelectionMerge %224 None +OpSwitch %180 %226 1 %225 +%225 = OpLabel +OpBranch %208 +%226 = OpLabel +OpSelectionMerge %227 None +OpSwitch %181 %229 1 %228 +%228 = OpLabel +OpStore %185 %9 +OpBranch %227 +%229 = OpLabel +OpBranch %227 +%227 = OpLabel +OpBranch %224 +%224 = OpLabel +OpBranch %220 +%223 = OpLabel OpBranch %220 %220 = OpLabel -OpBranch %217 -%217 = OpLabel -OpBranch %213 -%216 = OpLabel -OpBranch %213 -%213 = OpLabel -OpBranch %201 -%201 = OpLabel -OpBranch %198 -%199 = OpLabel +OpBranch %208 +%208 = OpLabel +OpBranch %205 +%206 = OpLabel OpReturn OpFunctionEnd -%224 = OpFunction %2 None %6 -%223 = OpLabel -OpBranch %225 -%225 = OpLabel -%226 = OpFunctionCall %2 %5 -%227 = OpFunctionCall %2 %44 %7 -%228 = OpFunctionCall %2 %50 -%229 = OpFunctionCall %2 %56 -%230 = OpFunctionCall %2 %65 -%231 = OpFunctionCall %2 %76 %7 -%232 = OpFunctionCall %2 %107 %7 %9 %10 -%233 = OpFunctionCall %2 %176 %7 %9 %10 %11 +%231 = OpFunction %2 None %6 +%230 = OpLabel +OpBranch %232 +%232 = OpLabel +%233 = OpFunctionCall %2 %5 +%234 = OpFunctionCall %2 %51 %7 +%235 = OpFunctionCall %2 %57 +%236 = OpFunctionCall %2 %63 +%237 = OpFunctionCall %2 %72 +%238 = OpFunctionCall %2 %83 %7 +%239 = OpFunctionCall %2 %114 %7 %9 %10 +%240 = OpFunctionCall %2 %183 %7 %9 %10 %11 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/naga/tests/out/wgsl/wgsl-control-flow.wgsl b/naga/tests/out/wgsl/wgsl-control-flow.wgsl index 4baf30ce6ee..c8256b30263 100644 --- a/naga/tests/out/wgsl/wgsl-control-flow.wgsl +++ b/naga/tests/out/wgsl/wgsl-control-flow.wgsl @@ -42,17 +42,36 @@ fn control_flow() { } case 2: { pos = 1i; - return; } case 3: { pos = 2i; - return; } case 4: { - return; } default: { pos = 3i; + } + } + let _e15 = pos; + switch _e15 { + case 1: { + pos = 0i; + return; + } + case 2: { + pos = 1i; + return; + } + case 3, 4: { + pos = 2i; + return; + } + case 5, 6: { + pos = 3i; + return; + } + default: { + pos = 4i; return; } } From c7fd582f0586de515c7f4116a0621006f09252f8 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Tue, 16 Sep 2025 10:45:48 -0400 Subject: [PATCH 213/303] docs(README): Update statement on naga spec conformance (#8233) --- README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 51142739424..fd9e0024a18 100644 --- a/README.md +++ b/README.md @@ -255,12 +255,11 @@ as the implementation catches up. Exactly which WGSL features `wgpu` supports depends on how you are using it: -- When running as native code, `wgpu` uses the [Naga][naga] crate +- When running as native code, `wgpu` uses [Naga][naga] to translate WGSL code into the shading language of your platform's native GPU API. - Naga has [a milestone][naga wgsl milestone] - for catching up to the WGSL specification, - but in general, there is no up-to-date summary - of the differences between Naga and the WGSL spec. + Naga is working on catching up to the WGSL specification, + with [bugs][naga bugs] tracking various issues, + but there is no concise summary of differences from the specification. - When running in a web browser (by compilation to WebAssembly) without the `"webgl"` feature enabled, @@ -274,8 +273,8 @@ Exactly which WGSL features `wgpu` supports depends on how you are using it: [webgpu spec]: https://www.w3.org/TR/webgpu/ [wgsl spec]: https://gpuweb.github.io/gpuweb/wgsl/ -[naga]: https://github.com/gfx-rs/naga/ -[naga wgsl milestone]: https://github.com/gfx-rs/naga/milestone/4 +[naga]: https://github.com/gfx-rs/wgpu/tree/trunk/naga/ +[naga bugs]: https://github.com/gfx-rs/wgpu/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22naga%22 ## Coordinate Systems From 68199042ed40abcedf631c0d80fcd35ef7ee24a9 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Thu, 18 Sep 2025 23:48:58 -0400 Subject: [PATCH 214/303] Remove unused stale copy of webgpu.idl (#8242) --- deno_webgpu/webgpu.idl | 1244 ---------------------------------------- 1 file changed, 1244 deletions(-) delete mode 100644 deno_webgpu/webgpu.idl diff --git a/deno_webgpu/webgpu.idl b/deno_webgpu/webgpu.idl deleted file mode 100644 index cb4fff59655..00000000000 --- a/deno_webgpu/webgpu.idl +++ /dev/null @@ -1,1244 +0,0 @@ -interface mixin GPUObjectBase { - attribute USVString label; -}; - -dictionary GPUObjectDescriptorBase { - USVString label = ""; -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUSupportedLimits { - readonly attribute unsigned long maxTextureDimension1D; - readonly attribute unsigned long maxTextureDimension2D; - readonly attribute unsigned long maxTextureDimension3D; - readonly attribute unsigned long maxTextureArrayLayers; - readonly attribute unsigned long maxBindGroups; - readonly attribute unsigned long maxBindingsPerBindGroup; - readonly attribute unsigned long maxDynamicUniformBuffersPerPipelineLayout; - readonly attribute unsigned long maxDynamicStorageBuffersPerPipelineLayout; - readonly attribute unsigned long maxSampledTexturesPerShaderStage; - readonly attribute unsigned long maxSamplersPerShaderStage; - readonly attribute unsigned long maxStorageBuffersPerShaderStage; - readonly attribute unsigned long maxStorageTexturesPerShaderStage; - readonly attribute unsigned long maxUniformBuffersPerShaderStage; - readonly attribute unsigned long long maxUniformBufferBindingSize; - readonly attribute unsigned long long maxStorageBufferBindingSize; - readonly attribute unsigned long minUniformBufferOffsetAlignment; - readonly attribute unsigned long minStorageBufferOffsetAlignment; - readonly attribute unsigned long maxVertexBuffers; - readonly attribute unsigned long long maxBufferSize; - readonly attribute unsigned long maxVertexAttributes; - readonly attribute unsigned long maxVertexBufferArrayStride; - readonly attribute unsigned long maxColorAttachments; - readonly attribute unsigned long maxColorAttachmentBytesPerSample; - readonly attribute unsigned long maxComputeWorkgroupStorageSize; - readonly attribute unsigned long maxComputeInvocationsPerWorkgroup; - readonly attribute unsigned long maxComputeWorkgroupSizeX; - readonly attribute unsigned long maxComputeWorkgroupSizeY; - readonly attribute unsigned long maxComputeWorkgroupSizeZ; - readonly attribute unsigned long maxComputeWorkgroupsPerDimension; -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUSupportedFeatures { - readonly setlike; -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUAdapterInfo { - readonly attribute DOMString vendor; - readonly attribute DOMString architecture; - readonly attribute DOMString device; - readonly attribute DOMString description; - readonly attribute unsigned long subgroupMinSize; - readonly attribute unsigned long subgroupMaxSize; -}; - -interface mixin NavigatorGPU { - [SameObject, SecureContext] readonly attribute GPU gpu; -}; -Navigator includes NavigatorGPU; -WorkerNavigator includes NavigatorGPU; - -[Exposed=(Window, Worker), SecureContext] -interface GPU { - Promise requestAdapter(optional GPURequestAdapterOptions options = {}); - GPUTextureFormat getPreferredCanvasFormat(); -}; - -dictionary GPURequestAdapterOptions { - GPUPowerPreference powerPreference; - boolean forceFallbackAdapter = false; -}; - -enum GPUPowerPreference { - "low-power", - "high-performance", -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUAdapter { - [SameObject] readonly attribute GPUSupportedFeatures features; - [SameObject] readonly attribute GPUSupportedLimits limits; - [SameObject] readonly attribute GPUAdapterInfo info; - readonly attribute boolean isFallbackAdapter; - - Promise requestDevice(optional GPUDeviceDescriptor descriptor = {}); -}; - -dictionary GPUDeviceDescriptor - : GPUObjectDescriptorBase { - sequence requiredFeatures = []; - record requiredLimits = {}; -}; - -enum GPUFeatureName { - "depth-clip-control", - "depth32float-stencil8", - "texture-compression-bc", - "texture-compression-bc-sliced-3d", - "texture-compression-etc2", - "texture-compression-astc", - "texture-compression-astc-sliced-3d", - "timestamp-query", - "indirect-first-instance", - "shader-f16", - "rg11b10ufloat-renderable", - "bgra8unorm-storage", - "float32-filterable", - "subgroups", -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUDevice : EventTarget { - [SameObject] readonly attribute GPUSupportedFeatures features; - [SameObject] readonly attribute GPUSupportedLimits limits; - [SameObject] readonly attribute GPUAdapterInfo adapterInfo; - - [SameObject] readonly attribute GPUQueue queue; - - undefined destroy(); - - GPUBuffer createBuffer(GPUBufferDescriptor descriptor); - GPUTexture createTexture(GPUTextureDescriptor descriptor); - GPUSampler createSampler(optional GPUSamplerDescriptor descriptor = {}); - - GPUBindGroupLayout createBindGroupLayout(GPUBindGroupLayoutDescriptor descriptor); - GPUPipelineLayout createPipelineLayout(GPUPipelineLayoutDescriptor descriptor); - GPUBindGroup createBindGroup(GPUBindGroupDescriptor descriptor); - - GPUShaderModule createShaderModule(GPUShaderModuleDescriptor descriptor); - GPUComputePipeline createComputePipeline(GPUComputePipelineDescriptor descriptor); - GPURenderPipeline createRenderPipeline(GPURenderPipelineDescriptor descriptor); - Promise createComputePipelineAsync(GPUComputePipelineDescriptor descriptor); - Promise createRenderPipelineAsync(GPURenderPipelineDescriptor descriptor); - - GPUCommandEncoder createCommandEncoder(optional GPUCommandEncoderDescriptor descriptor = {}); - GPURenderBundleEncoder createRenderBundleEncoder(GPURenderBundleEncoderDescriptor descriptor); - - GPUQuerySet createQuerySet(GPUQuerySetDescriptor descriptor); -}; -GPUDevice includes GPUObjectBase; - -[Exposed=(Window, Worker), SecureContext] -interface GPUBuffer { - readonly attribute GPUSize64Out size; - readonly attribute GPUFlagsConstant usage; - - readonly attribute GPUBufferMapState mapState; - - Promise mapAsync(GPUMapModeFlags mode, optional GPUSize64 offset = 0, optional GPUSize64 size); - ArrayBuffer getMappedRange(optional GPUSize64 offset = 0, optional GPUSize64 size); - undefined unmap(); - - undefined destroy(); -}; -GPUBuffer includes GPUObjectBase; - -enum GPUBufferMapState { - "unmapped", - "pending", - "mapped", -}; - -dictionary GPUBufferDescriptor - : GPUObjectDescriptorBase { - required GPUSize64 size; - required GPUBufferUsageFlags usage; - boolean mappedAtCreation = false; -}; - -typedef [EnforceRange] unsigned long GPUBufferUsageFlags; -[Exposed=(Window, Worker), SecureContext] -namespace GPUBufferUsage { - const GPUFlagsConstant MAP_READ = 0x0001; - const GPUFlagsConstant MAP_WRITE = 0x0002; - const GPUFlagsConstant COPY_SRC = 0x0004; - const GPUFlagsConstant COPY_DST = 0x0008; - const GPUFlagsConstant INDEX = 0x0010; - const GPUFlagsConstant VERTEX = 0x0020; - const GPUFlagsConstant UNIFORM = 0x0040; - const GPUFlagsConstant STORAGE = 0x0080; - const GPUFlagsConstant INDIRECT = 0x0100; - const GPUFlagsConstant QUERY_RESOLVE = 0x0200; -}; - -typedef [EnforceRange] unsigned long GPUMapModeFlags; -[Exposed=(Window, Worker), SecureContext] -namespace GPUMapMode { - const GPUFlagsConstant READ = 0x0001; - const GPUFlagsConstant WRITE = 0x0002; -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUTexture { - GPUTextureView createView(optional GPUTextureViewDescriptor descriptor = {}); - - undefined destroy(); - - readonly attribute GPUIntegerCoordinateOut width; - readonly attribute GPUIntegerCoordinateOut height; - readonly attribute GPUIntegerCoordinateOut depthOrArrayLayers; - readonly attribute GPUIntegerCoordinateOut mipLevelCount; - readonly attribute GPUSize32Out sampleCount; - readonly attribute GPUTextureDimension dimension; - readonly attribute GPUTextureFormat format; - readonly attribute GPUFlagsConstant usage; -}; -GPUTexture includes GPUObjectBase; - -dictionary GPUTextureDescriptor - : GPUObjectDescriptorBase { - required GPUExtent3D size; - GPUIntegerCoordinate mipLevelCount = 1; - GPUSize32 sampleCount = 1; - GPUTextureDimension dimension = "2d"; - required GPUTextureFormat format; - required GPUTextureUsageFlags usage; - sequence viewFormats = []; -}; - -enum GPUTextureDimension { - "1d", - "2d", - "3d", -}; - -typedef [EnforceRange] unsigned long GPUTextureUsageFlags; -[Exposed=(Window, Worker), SecureContext] -namespace GPUTextureUsage { - const GPUFlagsConstant COPY_SRC = 0x01; - const GPUFlagsConstant COPY_DST = 0x02; - const GPUFlagsConstant TEXTURE_BINDING = 0x04; - const GPUFlagsConstant STORAGE_BINDING = 0x08; - const GPUFlagsConstant RENDER_ATTACHMENT = 0x10; -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUTextureView { -}; -GPUTextureView includes GPUObjectBase; - -dictionary GPUTextureViewDescriptor - : GPUObjectDescriptorBase { - GPUTextureFormat format; - GPUTextureViewDimension dimension; - GPUTextureUsageFlags usage = 0; - GPUTextureAspect aspect = "all"; - GPUIntegerCoordinate baseMipLevel = 0; - GPUIntegerCoordinate mipLevelCount; - GPUIntegerCoordinate baseArrayLayer = 0; - GPUIntegerCoordinate arrayLayerCount; -}; - -enum GPUTextureViewDimension { - "1d", - "2d", - "2d-array", - "cube", - "cube-array", - "3d", -}; - -enum GPUTextureAspect { - "all", - "stencil-only", - "depth-only", -}; - -enum GPUTextureFormat { - // 8-bit formats - "r8unorm", - "r8snorm", - "r8uint", - "r8sint", - - // 16-bit formats - "r16uint", - "r16sint", - "r16float", - "rg8unorm", - "rg8snorm", - "rg8uint", - "rg8sint", - - // 32-bit formats - "r32uint", - "r32sint", - "r32float", - "rg16uint", - "rg16sint", - "rg16float", - "rgba8unorm", - "rgba8unorm-srgb", - "rgba8snorm", - "rgba8uint", - "rgba8sint", - "bgra8unorm", - "bgra8unorm-srgb", - // Packed 32-bit formats - "rgb9e5ufloat", - "rgb10a2uint", - "rgb10a2unorm", - "rg11b10ufloat", - - // 64-bit formats - "rg32uint", - "rg32sint", - "rg32float", - "rgba16uint", - "rgba16sint", - "rgba16float", - - // 128-bit formats - "rgba32uint", - "rgba32sint", - "rgba32float", - - // Depth/stencil formats - "stencil8", - "depth16unorm", - "depth24plus", - "depth24plus-stencil8", - "depth32float", - - // "depth32float-stencil8" feature - "depth32float-stencil8", - - // BC compressed formats usable if "texture-compression-bc" is both - // supported by the device/user agent and enabled in requestDevice. - "bc1-rgba-unorm", - "bc1-rgba-unorm-srgb", - "bc2-rgba-unorm", - "bc2-rgba-unorm-srgb", - "bc3-rgba-unorm", - "bc3-rgba-unorm-srgb", - "bc4-r-unorm", - "bc4-r-snorm", - "bc5-rg-unorm", - "bc5-rg-snorm", - "bc6h-rgb-ufloat", - "bc6h-rgb-float", - "bc7-rgba-unorm", - "bc7-rgba-unorm-srgb", - - // ETC2 compressed formats usable if "texture-compression-etc2" is both - // supported by the device/user agent and enabled in requestDevice. - "etc2-rgb8unorm", - "etc2-rgb8unorm-srgb", - "etc2-rgb8a1unorm", - "etc2-rgb8a1unorm-srgb", - "etc2-rgba8unorm", - "etc2-rgba8unorm-srgb", - "eac-r11unorm", - "eac-r11snorm", - "eac-rg11unorm", - "eac-rg11snorm", - - // ASTC compressed formats usable if "texture-compression-astc" is both - // supported by the device/user agent and enabled in requestDevice. - "astc-4x4-unorm", - "astc-4x4-unorm-srgb", - "astc-5x4-unorm", - "astc-5x4-unorm-srgb", - "astc-5x5-unorm", - "astc-5x5-unorm-srgb", - "astc-6x5-unorm", - "astc-6x5-unorm-srgb", - "astc-6x6-unorm", - "astc-6x6-unorm-srgb", - "astc-8x5-unorm", - "astc-8x5-unorm-srgb", - "astc-8x6-unorm", - "astc-8x6-unorm-srgb", - "astc-8x8-unorm", - "astc-8x8-unorm-srgb", - "astc-10x5-unorm", - "astc-10x5-unorm-srgb", - "astc-10x6-unorm", - "astc-10x6-unorm-srgb", - "astc-10x8-unorm", - "astc-10x8-unorm-srgb", - "astc-10x10-unorm", - "astc-10x10-unorm-srgb", - "astc-12x10-unorm", - "astc-12x10-unorm-srgb", - "astc-12x12-unorm", - "astc-12x12-unorm-srgb", -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUSampler { -}; -GPUSampler includes GPUObjectBase; - -dictionary GPUSamplerDescriptor - : GPUObjectDescriptorBase { - GPUAddressMode addressModeU = "clamp-to-edge"; - GPUAddressMode addressModeV = "clamp-to-edge"; - GPUAddressMode addressModeW = "clamp-to-edge"; - GPUFilterMode magFilter = "nearest"; - GPUFilterMode minFilter = "nearest"; - GPUMipmapFilterMode mipmapFilter = "nearest"; - float lodMinClamp = 0; - float lodMaxClamp = 32; - GPUCompareFunction compare; - [Clamp] unsigned short maxAnisotropy = 1; -}; - -enum GPUAddressMode { - "clamp-to-edge", - "repeat", - "mirror-repeat", -}; - -enum GPUFilterMode { - "nearest", - "linear", -}; - -enum GPUMipmapFilterMode { - "nearest", - "linear", -}; - -enum GPUCompareFunction { - "never", - "less", - "equal", - "less-equal", - "greater", - "not-equal", - "greater-equal", - "always", -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUBindGroupLayout { -}; -GPUBindGroupLayout includes GPUObjectBase; - -dictionary GPUBindGroupLayoutDescriptor - : GPUObjectDescriptorBase { - required sequence entries; -}; - -dictionary GPUBindGroupLayoutEntry { - required GPUIndex32 binding; - required GPUShaderStageFlags visibility; - - GPUBufferBindingLayout buffer; - GPUSamplerBindingLayout sampler; - GPUTextureBindingLayout texture; - GPUStorageTextureBindingLayout storageTexture; -}; - -typedef [EnforceRange] unsigned long GPUShaderStageFlags; -[Exposed=(Window, Worker), SecureContext] -namespace GPUShaderStage { - const GPUFlagsConstant VERTEX = 0x1; - const GPUFlagsConstant FRAGMENT = 0x2; - const GPUFlagsConstant COMPUTE = 0x4; -}; - -enum GPUBufferBindingType { - "uniform", - "storage", - "read-only-storage", -}; - -dictionary GPUBufferBindingLayout { - GPUBufferBindingType type = "uniform"; - boolean hasDynamicOffset = false; - GPUSize64 minBindingSize = 0; -}; - -enum GPUSamplerBindingType { - "filtering", - "non-filtering", - "comparison", -}; - -dictionary GPUSamplerBindingLayout { - GPUSamplerBindingType type = "filtering"; -}; - -enum GPUTextureSampleType { - "float", - "unfilterable-float", - "depth", - "sint", - "uint", -}; - -dictionary GPUTextureBindingLayout { - GPUTextureSampleType sampleType = "float"; - GPUTextureViewDimension viewDimension = "2d"; - boolean multisampled = false; -}; - -enum GPUStorageTextureAccess { - "write-only", - "read-only", - "read-write", -}; - -dictionary GPUStorageTextureBindingLayout { - GPUStorageTextureAccess access = "write-only"; - required GPUTextureFormat format; - GPUTextureViewDimension viewDimension = "2d"; -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUBindGroup { -}; -GPUBindGroup includes GPUObjectBase; - -dictionary GPUBindGroupDescriptor - : GPUObjectDescriptorBase { - required GPUBindGroupLayout layout; - required sequence entries; -}; - -typedef (GPUSampler or GPUTextureView or GPUBufferBinding) GPUBindingResource; - -dictionary GPUBindGroupEntry { - required GPUIndex32 binding; - required GPUBindingResource resource; -}; - -dictionary GPUBufferBinding { - required GPUBuffer buffer; - GPUSize64 offset = 0; - GPUSize64 size; -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUPipelineLayout { -}; -GPUPipelineLayout includes GPUObjectBase; - -dictionary GPUPipelineLayoutDescriptor - : GPUObjectDescriptorBase { - required sequence bindGroupLayouts; -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUShaderModule { -}; -GPUShaderModule includes GPUObjectBase; - -dictionary GPUShaderModuleDescriptor - : GPUObjectDescriptorBase { - required USVString code; -}; - -enum GPUCompilationMessageType { - "error", - "warning", - "info", -}; - -[Exposed=(Window, Worker), Serializable, SecureContext] -interface GPUCompilationMessage { - readonly attribute DOMString message; - readonly attribute GPUCompilationMessageType type; - readonly attribute unsigned long long lineNum; - readonly attribute unsigned long long linePos; - readonly attribute unsigned long long offset; - readonly attribute unsigned long long length; -}; - -[Exposed=(Window, Worker), Serializable, SecureContext] -interface GPUCompilationInfo { - readonly attribute FrozenArray messages; -}; - -[Exposed=(Window, Worker), SecureContext, Serializable] -interface GPUPipelineError : DOMException { - constructor(optional DOMString message = "", GPUPipelineErrorInit options); - readonly attribute GPUPipelineErrorReason reason; -}; - -dictionary GPUPipelineErrorInit { - required GPUPipelineErrorReason reason; -}; - -enum GPUPipelineErrorReason { - "validation", - "internal", -}; - -enum GPUAutoLayoutMode { - "auto", -}; - -dictionary GPUPipelineDescriptorBase - : GPUObjectDescriptorBase { - required (GPUPipelineLayout or GPUAutoLayoutMode) layout; -}; - -interface mixin GPUPipelineBase { - [NewObject] GPUBindGroupLayout getBindGroupLayout(unsigned long index); -}; - -dictionary GPUProgrammableStage { - required GPUShaderModule module; - USVString entryPoint; - record constants = {}; -}; - -typedef double GPUPipelineConstantValue; // May represent WGSL's bool, f32, i32, u32, and f16 if enabled. - -[Exposed=(Window, Worker), SecureContext] -interface GPUComputePipeline { -}; -GPUComputePipeline includes GPUObjectBase; -GPUComputePipeline includes GPUPipelineBase; - -dictionary GPUComputePipelineDescriptor - : GPUPipelineDescriptorBase { - required GPUProgrammableStage compute; -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPURenderPipeline { -}; -GPURenderPipeline includes GPUObjectBase; -GPURenderPipeline includes GPUPipelineBase; - -dictionary GPURenderPipelineDescriptor - : GPUPipelineDescriptorBase { - required GPUVertexState vertex; - GPUPrimitiveState primitive = {}; - GPUDepthStencilState depthStencil; - GPUMultisampleState multisample = {}; - GPUFragmentState fragment; -}; - -dictionary GPUPrimitiveState { - GPUPrimitiveTopology topology = "triangle-list"; - GPUIndexFormat stripIndexFormat; - GPUFrontFace frontFace = "ccw"; - GPUCullMode cullMode = "none"; - - // Requires "depth-clip-control" feature. - boolean unclippedDepth = false; -}; - -enum GPUPrimitiveTopology { - "point-list", - "line-list", - "line-strip", - "triangle-list", - "triangle-strip", -}; - -enum GPUFrontFace { - "ccw", - "cw", -}; - -enum GPUCullMode { - "none", - "front", - "back", -}; - -dictionary GPUMultisampleState { - GPUSize32 count = 1; - GPUSampleMask mask = 0xFFFFFFFF; - boolean alphaToCoverageEnabled = false; -}; - -dictionary GPUFragmentState - : GPUProgrammableStage { - required sequence targets; -}; - -dictionary GPUColorTargetState { - required GPUTextureFormat format; - - GPUBlendState blend; - GPUColorWriteFlags writeMask = 0xF; // GPUColorWrite.ALL -}; - -dictionary GPUBlendState { - required GPUBlendComponent color; - required GPUBlendComponent alpha; -}; - -typedef [EnforceRange] unsigned long GPUColorWriteFlags; -[Exposed=(Window, Worker), SecureContext] -namespace GPUColorWrite { - const GPUFlagsConstant RED = 0x1; - const GPUFlagsConstant GREEN = 0x2; - const GPUFlagsConstant BLUE = 0x4; - const GPUFlagsConstant ALPHA = 0x8; - const GPUFlagsConstant ALL = 0xF; -}; - -dictionary GPUBlendComponent { - GPUBlendOperation operation = "add"; - GPUBlendFactor srcFactor = "one"; - GPUBlendFactor dstFactor = "zero"; -}; - -enum GPUBlendFactor { - "zero", - "one", - "src", - "one-minus-src", - "src-alpha", - "one-minus-src-alpha", - "dst", - "one-minus-dst", - "dst-alpha", - "one-minus-dst-alpha", - "src-alpha-saturated", - "constant", - "one-minus-constant", - "src1", - "one-minus-src1", - "src1-alpha", - "one-minus-src1-alpha", -}; - -enum GPUBlendOperation { - "add", - "subtract", - "reverse-subtract", - "min", - "max", -}; - -dictionary GPUDepthStencilState { - required GPUTextureFormat format; - - boolean depthWriteEnabled; - GPUCompareFunction depthCompare; - - GPUStencilFaceState stencilFront = {}; - GPUStencilFaceState stencilBack = {}; - - GPUStencilValue stencilReadMask = 0xFFFFFFFF; - GPUStencilValue stencilWriteMask = 0xFFFFFFFF; - - GPUDepthBias depthBias = 0; - float depthBiasSlopeScale = 0; - float depthBiasClamp = 0; -}; - -dictionary GPUStencilFaceState { - GPUCompareFunction compare = "always"; - GPUStencilOperation failOp = "keep"; - GPUStencilOperation depthFailOp = "keep"; - GPUStencilOperation passOp = "keep"; -}; - -enum GPUStencilOperation { - "keep", - "zero", - "replace", - "invert", - "increment-clamp", - "decrement-clamp", - "increment-wrap", - "decrement-wrap", -}; - -enum GPUIndexFormat { - "uint16", - "uint32", -}; - -enum GPUVertexFormat { - "uint8x2", - "uint8x4", - "sint8x2", - "sint8x4", - "unorm8x2", - "unorm8x4", - "snorm8x2", - "snorm8x4", - "uint16x2", - "uint16x4", - "sint16x2", - "sint16x4", - "unorm16x2", - "unorm16x4", - "snorm16x2", - "snorm16x4", - "float16x2", - "float16x4", - "float32", - "float32x2", - "float32x3", - "float32x4", - "uint32", - "uint32x2", - "uint32x3", - "uint32x4", - "sint32", - "sint32x2", - "sint32x3", - "sint32x4", - "unorm10-10-10-2", -}; - -enum GPUVertexStepMode { - "vertex", - "instance", -}; - -dictionary GPUVertexState - : GPUProgrammableStage { - sequence buffers = []; -}; - -dictionary GPUVertexBufferLayout { - required GPUSize64 arrayStride; - GPUVertexStepMode stepMode = "vertex"; - required sequence attributes; -}; - -dictionary GPUVertexAttribute { - required GPUVertexFormat format; - required GPUSize64 offset; - - required GPUIndex32 shaderLocation; -}; - -dictionary GPUTexelCopyBufferLayout { - GPUSize64 offset = 0; - GPUSize32 bytesPerRow; - GPUSize32 rowsPerImage; -}; - -dictionary GPUTexelCopyBufferInfo - : GPUTexelCopyBufferLayout { - required GPUBuffer buffer; -}; - -dictionary GPUTexelCopyTextureInfo { - required GPUTexture texture; - GPUIntegerCoordinate mipLevel = 0; - GPUOrigin3D origin = {}; - GPUTextureAspect aspect = "all"; -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUCommandBuffer { -}; -GPUCommandBuffer includes GPUObjectBase; - -dictionary GPUCommandBufferDescriptor - : GPUObjectDescriptorBase { -}; - -interface mixin GPUCommandsMixin { -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUCommandEncoder { - GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor); - GPUComputePassEncoder beginComputePass(optional GPUComputePassDescriptor descriptor = {}); - - undefined copyBufferToBuffer( - GPUBuffer source, - GPUSize64 sourceOffset, - GPUBuffer destination, - GPUSize64 destinationOffset, - GPUSize64 size); - - undefined copyBufferToTexture( - GPUTexelCopyBufferInfo source, - GPUTexelCopyTextureInfo destination, - GPUExtent3D copySize); - - undefined copyTextureToBuffer( - GPUTexelCopyTextureInfo source, - GPUTexelCopyBufferInfo destination, - GPUExtent3D copySize); - - undefined copyTextureToTexture( - GPUTexelCopyTextureInfo source, - GPUTexelCopyTextureInfo destination, - GPUExtent3D copySize); - - undefined clearBuffer( - GPUBuffer buffer, - optional GPUSize64 offset = 0, - optional GPUSize64 size); - - undefined resolveQuerySet( - GPUQuerySet querySet, - GPUSize32 firstQuery, - GPUSize32 queryCount, - GPUBuffer destination, - GPUSize64 destinationOffset); - - GPUCommandBuffer finish(optional GPUCommandBufferDescriptor descriptor = {}); -}; -GPUCommandEncoder includes GPUObjectBase; -GPUCommandEncoder includes GPUCommandsMixin; -GPUCommandEncoder includes GPUDebugCommandsMixin; - -dictionary GPUCommandEncoderDescriptor - : GPUObjectDescriptorBase { -}; - -interface mixin GPUBindingCommandsMixin { - undefined setBindGroup(GPUIndex32 index, GPUBindGroup? bindGroup, - optional sequence dynamicOffsets = []); - - undefined setBindGroup(GPUIndex32 index, GPUBindGroup? bindGroup, - Uint32Array dynamicOffsetsData, - GPUSize64 dynamicOffsetsDataStart, - GPUSize32 dynamicOffsetsDataLength); -}; - -interface mixin GPUDebugCommandsMixin { - undefined pushDebugGroup(USVString groupLabel); - undefined popDebugGroup(); - undefined insertDebugMarker(USVString markerLabel); -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUComputePassEncoder { - undefined setPipeline(GPUComputePipeline pipeline); - undefined dispatchWorkgroups(GPUSize32 workgroupCountX, optional GPUSize32 workgroupCountY = 1, optional GPUSize32 workgroupCountZ = 1); - undefined dispatchWorkgroupsIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset); - - undefined end(); -}; -GPUComputePassEncoder includes GPUObjectBase; -GPUComputePassEncoder includes GPUCommandsMixin; -GPUComputePassEncoder includes GPUDebugCommandsMixin; -GPUComputePassEncoder includes GPUBindingCommandsMixin; - -dictionary GPUComputePassTimestampWrites { - required GPUQuerySet querySet; - GPUSize32 beginningOfPassWriteIndex; - GPUSize32 endOfPassWriteIndex; -}; - -dictionary GPUComputePassDescriptor - : GPUObjectDescriptorBase { - GPUComputePassTimestampWrites timestampWrites; -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPURenderPassEncoder { - undefined setViewport(float x, float y, - float width, float height, - float minDepth, float maxDepth); - - undefined setScissorRect(GPUIntegerCoordinate x, GPUIntegerCoordinate y, - GPUIntegerCoordinate width, GPUIntegerCoordinate height); - - undefined setBlendConstant(GPUColor color); - undefined setStencilReference(GPUStencilValue reference); - - undefined beginOcclusionQuery(GPUSize32 queryIndex); - undefined endOcclusionQuery(); - - undefined executeBundles(sequence bundles); - undefined end(); -}; -GPURenderPassEncoder includes GPUObjectBase; -GPURenderPassEncoder includes GPUCommandsMixin; -GPURenderPassEncoder includes GPUDebugCommandsMixin; -GPURenderPassEncoder includes GPUBindingCommandsMixin; -GPURenderPassEncoder includes GPURenderCommandsMixin; - -dictionary GPURenderPassTimestampWrites { - required GPUQuerySet querySet; - GPUSize32 beginningOfPassWriteIndex; - GPUSize32 endOfPassWriteIndex; -}; - -dictionary GPURenderPassDescriptor - : GPUObjectDescriptorBase { - required sequence colorAttachments; - GPURenderPassDepthStencilAttachment depthStencilAttachment; - GPUQuerySet occlusionQuerySet; - GPURenderPassTimestampWrites timestampWrites; -}; - -dictionary GPURenderPassColorAttachment { - required GPUTextureView view; - GPUTextureView resolveTarget; - - GPUColor clearValue; - required GPULoadOp loadOp; - required GPUStoreOp storeOp; -}; - -dictionary GPURenderPassDepthStencilAttachment { - required GPUTextureView view; - - float depthClearValue; - GPULoadOp depthLoadOp; - GPUStoreOp depthStoreOp; - boolean depthReadOnly = false; - - GPUStencilValue stencilClearValue = 0; - GPULoadOp stencilLoadOp; - GPUStoreOp stencilStoreOp; - boolean stencilReadOnly = false; -}; - -enum GPULoadOp { - "load", - "clear", -}; - -enum GPUStoreOp { - "store", - "discard", -}; - -dictionary GPURenderPassLayout - : GPUObjectDescriptorBase { - required sequence colorFormats; - GPUTextureFormat depthStencilFormat; - GPUSize32 sampleCount = 1; -}; - -interface mixin GPURenderCommandsMixin { - undefined setPipeline(GPURenderPipeline pipeline); - - undefined setIndexBuffer(GPUBuffer buffer, GPUIndexFormat indexFormat, optional GPUSize64 offset = 0, optional GPUSize64 size); - undefined setVertexBuffer(GPUIndex32 slot, GPUBuffer buffer, optional GPUSize64 offset = 0, optional GPUSize64 size); - - undefined draw(GPUSize32 vertexCount, optional GPUSize32 instanceCount = 1, - optional GPUSize32 firstVertex = 0, optional GPUSize32 firstInstance = 0); - undefined drawIndexed(GPUSize32 indexCount, optional GPUSize32 instanceCount = 1, - optional GPUSize32 firstIndex = 0, - optional GPUSignedOffset32 baseVertex = 0, - optional GPUSize32 firstInstance = 0); - - undefined drawIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset); - undefined drawIndexedIndirect(GPUBuffer indirectBuffer, GPUSize64 indirectOffset); -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPURenderBundle { -}; -GPURenderBundle includes GPUObjectBase; - -dictionary GPURenderBundleDescriptor - : GPUObjectDescriptorBase { -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPURenderBundleEncoder { - GPURenderBundle finish(optional GPURenderBundleDescriptor descriptor = {}); -}; -GPURenderBundleEncoder includes GPUObjectBase; -GPURenderBundleEncoder includes GPUCommandsMixin; -GPURenderBundleEncoder includes GPUDebugCommandsMixin; -GPURenderBundleEncoder includes GPUBindingCommandsMixin; -GPURenderBundleEncoder includes GPURenderCommandsMixin; - -dictionary GPURenderBundleEncoderDescriptor - : GPURenderPassLayout { - boolean depthReadOnly = false; - boolean stencilReadOnly = false; -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUQueue { - undefined submit(sequence commandBuffers); - - Promise onSubmittedWorkDone(); - - undefined writeBuffer( - GPUBuffer buffer, - GPUSize64 bufferOffset, - AllowSharedBufferSource data, - optional GPUSize64 dataOffset = 0, - optional GPUSize64 size); - - undefined writeTexture( - GPUTexelCopyTextureInfo destination, - AllowSharedBufferSource data, - GPUTexelCopyBufferLayout dataLayout, - GPUExtent3D size); -}; -GPUQueue includes GPUObjectBase; - -[Exposed=(Window, Worker), SecureContext] -interface GPUQuerySet { - undefined destroy(); - - readonly attribute GPUQueryType type; - readonly attribute GPUSize32Out count; -}; -GPUQuerySet includes GPUObjectBase; - -dictionary GPUQuerySetDescriptor - : GPUObjectDescriptorBase { - required GPUQueryType type; - required GPUSize32 count; -}; - -enum GPUQueryType { - "occlusion", - "timestamp", -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUCanvasContext { - readonly attribute (HTMLCanvasElement or OffscreenCanvas) canvas; - - undefined configure(GPUCanvasConfiguration configuration); - undefined unconfigure(); - - GPUTexture getCurrentTexture(); -}; - -enum GPUCanvasAlphaMode { - "opaque", - "premultiplied", -}; - -dictionary GPUCanvasConfiguration { - required GPUDevice device; - required GPUTextureFormat format; - GPUTextureUsageFlags usage = 0x10; // GPUTextureUsage.RENDER_ATTACHMENT - sequence viewFormats = []; - GPUCanvasAlphaMode alphaMode = "opaque"; -}; - -enum GPUDeviceLostReason { - "unknown", - "destroyed", -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUDeviceLostInfo { - readonly attribute GPUDeviceLostReason reason; - readonly attribute DOMString message; -}; - -partial interface GPUDevice { - readonly attribute Promise lost; -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUError { - readonly attribute DOMString message; -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUValidationError - : GPUError { - constructor(DOMString message); -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUOutOfMemoryError - : GPUError { - constructor(DOMString message); -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUInternalError - : GPUError { - constructor(DOMString message); -}; - -enum GPUErrorFilter { - "validation", - "out-of-memory", - "internal", -}; - -partial interface GPUDevice { - undefined pushErrorScope(GPUErrorFilter filter); - Promise popErrorScope(); -}; - -[Exposed=(Window, Worker), SecureContext] -interface GPUUncapturedErrorEvent : Event { - constructor( - DOMString type, - GPUUncapturedErrorEventInit gpuUncapturedErrorEventInitDict - ); - [SameObject] readonly attribute GPUError error; -}; - -dictionary GPUUncapturedErrorEventInit : EventInit { - required GPUError error; -}; - -partial interface GPUDevice { - attribute EventHandler onuncapturederror; -}; - -typedef [EnforceRange] unsigned long GPUBufferDynamicOffset; -typedef [EnforceRange] unsigned long GPUStencilValue; -typedef [EnforceRange] unsigned long GPUSampleMask; -typedef [EnforceRange] long GPUDepthBias; - -typedef [EnforceRange] unsigned long long GPUSize64; -typedef [EnforceRange] unsigned long GPUIntegerCoordinate; -typedef [EnforceRange] unsigned long GPUIndex32; -typedef [EnforceRange] unsigned long GPUSize32; -typedef [EnforceRange] long GPUSignedOffset32; - -typedef unsigned long long GPUSize64Out; -typedef unsigned long GPUIntegerCoordinateOut; -typedef unsigned long GPUSize32Out; - -typedef unsigned long GPUFlagsConstant; - -dictionary GPUColorDict { - required double r; - required double g; - required double b; - required double a; -}; -typedef (sequence or GPUColorDict) GPUColor; - -dictionary GPUOrigin2DDict { - GPUIntegerCoordinate x = 0; - GPUIntegerCoordinate y = 0; -}; -typedef (sequence or GPUOrigin2DDict) GPUOrigin2D; - -dictionary GPUOrigin3DDict { - GPUIntegerCoordinate x = 0; - GPUIntegerCoordinate y = 0; - GPUIntegerCoordinate z = 0; -}; -typedef (sequence or GPUOrigin3DDict) GPUOrigin3D; - -dictionary GPUExtent3DDict { - required GPUIntegerCoordinate width; - GPUIntegerCoordinate height = 1; - GPUIntegerCoordinate depthOrArrayLayers = 1; -}; -typedef (sequence or GPUExtent3DDict) GPUExtent3D; From 0b38e963791ddc4061d197ec1cae9e067c49b3d9 Mon Sep 17 00:00:00 2001 From: Teodor Tanasoaia <28601907+teoxoy@users.noreply.github.com> Date: Sat, 20 Sep 2025 00:11:31 +0200 Subject: [PATCH 215/303] [msl] vertex pulling: fix unpacking `snorm16x2` & `snorm16x4` (#8249) --- cts_runner/test.lst | 1 + naga/src/back/msl/writer.rs | 30 +++++++++---------- .../tests/out/msl/wgsl-msl-vpt-formats-x1.msl | 8 ++--- .../tests/out/msl/wgsl-msl-vpt-formats-x2.msl | 8 ++--- .../tests/out/msl/wgsl-msl-vpt-formats-x3.msl | 8 ++--- .../tests/out/msl/wgsl-msl-vpt-formats-x4.msl | 8 ++--- 6 files changed, 32 insertions(+), 31 deletions(-) diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 99f06512a1e..20fb875f348 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -125,6 +125,7 @@ webgpu:api,operation,rendering,color_target_state:blend_constant,setting:* webgpu:api,operation,rendering,depth:* webgpu:api,operation,rendering,draw:* webgpu:api,operation,shader_module,compilation_info:* +webgpu:api,operation,vertex_state,correctness:non_zero_array_stride_and_attribute_offset:* // Likely due to https://github.com/gfx-rs/wgpu/issues/7357. fails-if(metal) webgpu:api,operation,uncapturederror:iff_uncaptured:* //FAIL: webgpu:shader,execution,expression,call,builtin,select:* diff --git a/naga/src/back/msl/writer.rs b/naga/src/back/msl/writer.rs index 6fa5c135e34..0bd8d0ab3fe 100644 --- a/naga/src/back/msl/writer.rs +++ b/naga/src/back/msl/writer.rs @@ -5144,14 +5144,14 @@ template let name = self.namer.call("unpackSnorm16x2"); writeln!( self.out, - "metal::float2 {name}(metal::ushort b0, \ - metal::ushort b1, \ - metal::ushort b2, \ - metal::ushort b3) {{" + "metal::float2 {name}(uint b0, \ + uint b1, \ + uint b2, \ + uint b3) {{" )?; writeln!( self.out, - "{}return metal::unpack_snorm2x16_to_float(b1 << 24 | b0 << 16 | b3 << 8 | b2);", + "{}return metal::unpack_snorm2x16_to_float(b3 << 24 | b2 << 16 | b1 << 8 | b0);", back::INDENT )?; writeln!(self.out, "}}")?; @@ -5161,19 +5161,19 @@ template let name = self.namer.call("unpackSnorm16x4"); writeln!( self.out, - "metal::float4 {name}(metal::ushort b0, \ - metal::ushort b1, \ - metal::ushort b2, \ - metal::ushort b3, \ - metal::ushort b4, \ - metal::ushort b5, \ - metal::ushort b6, \ - metal::ushort b7) {{" + "metal::float4 {name}(uint b0, \ + uint b1, \ + uint b2, \ + uint b3, \ + uint b4, \ + uint b5, \ + uint b6, \ + uint b7) {{" )?; writeln!( self.out, - "{}return metal::float4(metal::unpack_snorm2x16_to_float(b1 << 24 | b0 << 16 | b3 << 8 | b2), \ - metal::unpack_snorm2x16_to_float(b5 << 24 | b4 << 16 | b7 << 8 | b6));", + "{}return metal::float4(metal::unpack_snorm2x16_to_float(b3 << 24 | b2 << 16 | b1 << 8 | b0), \ + metal::unpack_snorm2x16_to_float(b7 << 24 | b6 << 16 | b5 << 8 | b4));", back::INDENT )?; writeln!(self.out, "}}")?; diff --git a/naga/tests/out/msl/wgsl-msl-vpt-formats-x1.msl b/naga/tests/out/msl/wgsl-msl-vpt-formats-x1.msl index b2a461c0b5e..766ffff6e59 100644 --- a/naga/tests/out/msl/wgsl-msl-vpt-formats-x1.msl +++ b/naga/tests/out/msl/wgsl-msl-vpt-formats-x1.msl @@ -120,11 +120,11 @@ metal::float4 unpackUnorm16x4_(metal::ushort b0, metal::ushort b1, metal::ushort float unpackSnorm16_(metal::ushort b0, metal::ushort b1) { return metal::unpack_snorm2x16_to_float(b1 << 8 | b0).x; } -metal::float2 unpackSnorm16x2_(metal::ushort b0, metal::ushort b1, metal::ushort b2, metal::ushort b3) { - return metal::unpack_snorm2x16_to_float(b1 << 24 | b0 << 16 | b3 << 8 | b2); +metal::float2 unpackSnorm16x2_(uint b0, uint b1, uint b2, uint b3) { + return metal::unpack_snorm2x16_to_float(b3 << 24 | b2 << 16 | b1 << 8 | b0); } -metal::float4 unpackSnorm16x4_(metal::ushort b0, metal::ushort b1, metal::ushort b2, metal::ushort b3, metal::ushort b4, metal::ushort b5, metal::ushort b6, metal::ushort b7) { - return metal::float4(metal::unpack_snorm2x16_to_float(b1 << 24 | b0 << 16 | b3 << 8 | b2), metal::unpack_snorm2x16_to_float(b5 << 24 | b4 << 16 | b7 << 8 | b6)); +metal::float4 unpackSnorm16x4_(uint b0, uint b1, uint b2, uint b3, uint b4, uint b5, uint b6, uint b7) { + return metal::float4(metal::unpack_snorm2x16_to_float(b3 << 24 | b2 << 16 | b1 << 8 | b0), metal::unpack_snorm2x16_to_float(b7 << 24 | b6 << 16 | b5 << 8 | b4)); } float unpackFloat16_(metal::ushort b0, metal::ushort b1) { return float(as_type(metal::ushort(b1 << 8 | b0))); diff --git a/naga/tests/out/msl/wgsl-msl-vpt-formats-x2.msl b/naga/tests/out/msl/wgsl-msl-vpt-formats-x2.msl index 46d1985d329..0559be74a89 100644 --- a/naga/tests/out/msl/wgsl-msl-vpt-formats-x2.msl +++ b/naga/tests/out/msl/wgsl-msl-vpt-formats-x2.msl @@ -120,11 +120,11 @@ metal::float4 unpackUnorm16x4_(metal::ushort b0, metal::ushort b1, metal::ushort float unpackSnorm16_(metal::ushort b0, metal::ushort b1) { return metal::unpack_snorm2x16_to_float(b1 << 8 | b0).x; } -metal::float2 unpackSnorm16x2_(metal::ushort b0, metal::ushort b1, metal::ushort b2, metal::ushort b3) { - return metal::unpack_snorm2x16_to_float(b1 << 24 | b0 << 16 | b3 << 8 | b2); +metal::float2 unpackSnorm16x2_(uint b0, uint b1, uint b2, uint b3) { + return metal::unpack_snorm2x16_to_float(b3 << 24 | b2 << 16 | b1 << 8 | b0); } -metal::float4 unpackSnorm16x4_(metal::ushort b0, metal::ushort b1, metal::ushort b2, metal::ushort b3, metal::ushort b4, metal::ushort b5, metal::ushort b6, metal::ushort b7) { - return metal::float4(metal::unpack_snorm2x16_to_float(b1 << 24 | b0 << 16 | b3 << 8 | b2), metal::unpack_snorm2x16_to_float(b5 << 24 | b4 << 16 | b7 << 8 | b6)); +metal::float4 unpackSnorm16x4_(uint b0, uint b1, uint b2, uint b3, uint b4, uint b5, uint b6, uint b7) { + return metal::float4(metal::unpack_snorm2x16_to_float(b3 << 24 | b2 << 16 | b1 << 8 | b0), metal::unpack_snorm2x16_to_float(b7 << 24 | b6 << 16 | b5 << 8 | b4)); } float unpackFloat16_(metal::ushort b0, metal::ushort b1) { return float(as_type(metal::ushort(b1 << 8 | b0))); diff --git a/naga/tests/out/msl/wgsl-msl-vpt-formats-x3.msl b/naga/tests/out/msl/wgsl-msl-vpt-formats-x3.msl index bd7471b3818..7db6980631d 100644 --- a/naga/tests/out/msl/wgsl-msl-vpt-formats-x3.msl +++ b/naga/tests/out/msl/wgsl-msl-vpt-formats-x3.msl @@ -120,11 +120,11 @@ metal::float4 unpackUnorm16x4_(metal::ushort b0, metal::ushort b1, metal::ushort float unpackSnorm16_(metal::ushort b0, metal::ushort b1) { return metal::unpack_snorm2x16_to_float(b1 << 8 | b0).x; } -metal::float2 unpackSnorm16x2_(metal::ushort b0, metal::ushort b1, metal::ushort b2, metal::ushort b3) { - return metal::unpack_snorm2x16_to_float(b1 << 24 | b0 << 16 | b3 << 8 | b2); +metal::float2 unpackSnorm16x2_(uint b0, uint b1, uint b2, uint b3) { + return metal::unpack_snorm2x16_to_float(b3 << 24 | b2 << 16 | b1 << 8 | b0); } -metal::float4 unpackSnorm16x4_(metal::ushort b0, metal::ushort b1, metal::ushort b2, metal::ushort b3, metal::ushort b4, metal::ushort b5, metal::ushort b6, metal::ushort b7) { - return metal::float4(metal::unpack_snorm2x16_to_float(b1 << 24 | b0 << 16 | b3 << 8 | b2), metal::unpack_snorm2x16_to_float(b5 << 24 | b4 << 16 | b7 << 8 | b6)); +metal::float4 unpackSnorm16x4_(uint b0, uint b1, uint b2, uint b3, uint b4, uint b5, uint b6, uint b7) { + return metal::float4(metal::unpack_snorm2x16_to_float(b3 << 24 | b2 << 16 | b1 << 8 | b0), metal::unpack_snorm2x16_to_float(b7 << 24 | b6 << 16 | b5 << 8 | b4)); } float unpackFloat16_(metal::ushort b0, metal::ushort b1) { return float(as_type(metal::ushort(b1 << 8 | b0))); diff --git a/naga/tests/out/msl/wgsl-msl-vpt-formats-x4.msl b/naga/tests/out/msl/wgsl-msl-vpt-formats-x4.msl index dba6657d6d5..d35045ffc75 100644 --- a/naga/tests/out/msl/wgsl-msl-vpt-formats-x4.msl +++ b/naga/tests/out/msl/wgsl-msl-vpt-formats-x4.msl @@ -120,11 +120,11 @@ metal::float4 unpackUnorm16x4_(metal::ushort b0, metal::ushort b1, metal::ushort float unpackSnorm16_(metal::ushort b0, metal::ushort b1) { return metal::unpack_snorm2x16_to_float(b1 << 8 | b0).x; } -metal::float2 unpackSnorm16x2_(metal::ushort b0, metal::ushort b1, metal::ushort b2, metal::ushort b3) { - return metal::unpack_snorm2x16_to_float(b1 << 24 | b0 << 16 | b3 << 8 | b2); +metal::float2 unpackSnorm16x2_(uint b0, uint b1, uint b2, uint b3) { + return metal::unpack_snorm2x16_to_float(b3 << 24 | b2 << 16 | b1 << 8 | b0); } -metal::float4 unpackSnorm16x4_(metal::ushort b0, metal::ushort b1, metal::ushort b2, metal::ushort b3, metal::ushort b4, metal::ushort b5, metal::ushort b6, metal::ushort b7) { - return metal::float4(metal::unpack_snorm2x16_to_float(b1 << 24 | b0 << 16 | b3 << 8 | b2), metal::unpack_snorm2x16_to_float(b5 << 24 | b4 << 16 | b7 << 8 | b6)); +metal::float4 unpackSnorm16x4_(uint b0, uint b1, uint b2, uint b3, uint b4, uint b5, uint b6, uint b7) { + return metal::float4(metal::unpack_snorm2x16_to_float(b3 << 24 | b2 << 16 | b1 << 8 | b0), metal::unpack_snorm2x16_to_float(b7 << 24 | b6 << 16 | b5 << 8 | b4)); } float unpackFloat16_(metal::ushort b0, metal::ushort b1) { return float(as_type(metal::ushort(b1 << 8 | b0))); From f6005a16c8a2e02bd6e42af254de3099009e5334 Mon Sep 17 00:00:00 2001 From: Andie Bradley Date: Sat, 20 Sep 2025 21:46:46 -0500 Subject: [PATCH 216/303] Include FreeBSD in conditional compile attributes (#8246) --- .github/workflows/ci.yml | 7 +++++++ wgpu-core/Cargo.toml | 2 +- wgpu-core/build.rs | 2 +- wgpu-core/platform-deps/windows-linux-android/Cargo.toml | 2 +- wgpu/build.rs | 4 ++-- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 92e445dee13..cccc07115ed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -127,6 +127,13 @@ jobs: tier: 1 kind: native + # FreeBSD + - name: FreeBSD x86_64 + os: ubuntu-24.04 + target: x86_64-unknown-freebsd + tier: 2 + kind: wgpu-only + # Android - name: Android aarch64 os: ubuntu-24.04 diff --git a/wgpu-core/Cargo.toml b/wgpu-core/Cargo.toml index d4772efa2df..170d0f74928 100644 --- a/wgpu-core/Cargo.toml +++ b/wgpu-core/Cargo.toml @@ -161,7 +161,7 @@ wgpu-core-deps-apple = { workspace = true, optional = true } wgpu-core-deps-emscripten = { workspace = true, optional = true } [target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies] wgpu-core-deps-wasm = { workspace = true, optional = true } -[target.'cfg(any(windows, target_os = "linux", target_os = "android"))'.dependencies] +[target.'cfg(any(windows, target_os = "linux", target_os = "android", target_os = "freebsd"))'.dependencies] wgpu-core-deps-windows-linux-android = { workspace = true, optional = true } [dependencies] diff --git a/wgpu-core/build.rs b/wgpu-core/build.rs index a01f5afe3bc..15982414032 100644 --- a/wgpu-core/build.rs +++ b/wgpu-core/build.rs @@ -1,6 +1,6 @@ fn main() { cfg_aliases::cfg_aliases! { - windows_linux_android: { any(windows, target_os = "linux", target_os = "android") }, + windows_linux_android: { any(windows, target_os = "linux", target_os = "android", target_os = "freebsd") }, send_sync: { all( feature = "std", any( diff --git a/wgpu-core/platform-deps/windows-linux-android/Cargo.toml b/wgpu-core/platform-deps/windows-linux-android/Cargo.toml index 7de228cdfb4..c014b8feba8 100644 --- a/wgpu-core/platform-deps/windows-linux-android/Cargo.toml +++ b/wgpu-core/platform-deps/windows-linux-android/Cargo.toml @@ -23,5 +23,5 @@ dx12 = ["wgpu-hal/dx12"] renderdoc = ["wgpu-hal/renderdoc"] # Depend on wgpu-hal conditionally, so that the above features only apply to wgpu-hal on this set of platforms. -[target.'cfg(any(windows, target_os = "linux", target_os = "android"))'.dependencies] +[target.'cfg(any(windows, target_os = "linux", target_os = "android", target_os = "freebsd"))'.dependencies] wgpu-hal.workspace = true diff --git a/wgpu/build.rs b/wgpu/build.rs index 70543ba3e6f..9a039c26531 100644 --- a/wgpu/build.rs +++ b/wgpu/build.rs @@ -16,7 +16,7 @@ fn main() { metal: { all(target_vendor = "apple", feature = "metal") }, vulkan: { any( // The `vulkan` feature enables the Vulkan backend only on "native Vulkan" platforms, i.e. Windows/Linux/Android - all(any(windows, target_os = "linux", target_os = "android"), feature = "vulkan"), + all(any(windows, target_os = "linux", target_os = "android", target_os = "freebsd"), feature = "vulkan"), // On Apple platforms, however, we require the `vulkan-portability` feature // to explicitly opt-in to Vulkan since it's meant to be used with MoltenVK. all(target_vendor = "apple", feature = "vulkan-portability") @@ -24,7 +24,7 @@ fn main() { gles: { any( // The `gles` feature enables the OpenGL/GLES backend only on "native OpenGL" platforms, i.e. Windows, Linux, Android, and Emscripten. // (Note that WebGL is also not included here!) - all(any(windows, target_os = "linux", target_os = "android", Emscripten), feature = "gles"), + all(any(windows, target_os = "linux", target_os = "android", target_os = "freebsd", Emscripten), feature = "gles"), // On Apple platforms, however, we require the `angle` feature to explicitly opt-in to OpenGL // since its meant to be used with ANGLE. all(target_vendor = "apple", feature = "angle") From 3efd640178a6dca4bd00f1c199e2a4f3dfc5fd20 Mon Sep 17 00:00:00 2001 From: EriKWDev Date: Sun, 21 Sep 2025 12:41:17 +0200 Subject: [PATCH 217/303] naga: Correct spelling in wgsl parsing rg11b10float -> rg11b10ufloat (#8219) --- CHANGELOG.md | 1 + naga/src/common/wgsl/to_wgsl.rs | 2 +- naga/src/front/wgsl/parse/conv.rs | 2 +- naga/src/front/wgsl/tests.rs | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0df9e6da4e..c22134b2b6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -196,6 +196,7 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). - If the shader source contains control characters, naga now replaces them with U+FFFD ("replacement character") in diagnostic output. By @andyleiserson in [#8049](https://github.com/gfx-rs/wgpu/pull/8049). - Add f16 IO polyfill on Vulkan backend to enable SHADER_F16 use without requiring `storageInputOutput16`. By @cryvosh in [#7884](https://github.com/gfx-rs/wgpu/pull/7884). - For custom Naga backend authors: `naga::proc::Namer` now accepts reserved keywords using two new dedicated types, `proc::{KeywordSet, CaseInsensitiveKeywordSet}`. By @kpreid in [#8136](https://github.com/gfx-rs/wgpu/pull/8136). +- **BREAKING**: Previously the WGSL storage-texture format `rg11b10float` was incorrectly accepted and generated by naga, but now only accepts the the correct name `rg11b10ufloat` instead. By @ErikWDev in [#8219](https://github.com/gfx-rs/wgpu/pull/8219). #### DX12 diff --git a/naga/src/common/wgsl/to_wgsl.rs b/naga/src/common/wgsl/to_wgsl.rs index 035c4eafb32..72be441288f 100644 --- a/naga/src/common/wgsl/to_wgsl.rs +++ b/naga/src/common/wgsl/to_wgsl.rs @@ -244,7 +244,7 @@ impl ToWgsl for crate::StorageFormat { Sf::Bgra8Unorm => "bgra8unorm", Sf::Rgb10a2Uint => "rgb10a2uint", Sf::Rgb10a2Unorm => "rgb10a2unorm", - Sf::Rg11b10Ufloat => "rg11b10float", + Sf::Rg11b10Ufloat => "rg11b10ufloat", Sf::R64Uint => "r64uint", Sf::Rg32Uint => "rg32uint", Sf::Rg32Sint => "rg32sint", diff --git a/naga/src/front/wgsl/parse/conv.rs b/naga/src/front/wgsl/parse/conv.rs index cbc485fb24a..30d0eb2d598 100644 --- a/naga/src/front/wgsl/parse/conv.rs +++ b/naga/src/front/wgsl/parse/conv.rs @@ -115,7 +115,7 @@ pub fn map_storage_format(word: &str, span: Span) -> Result<'_, crate::StorageFo "rgba8sint" => Sf::Rgba8Sint, "rgb10a2uint" => Sf::Rgb10a2Uint, "rgb10a2unorm" => Sf::Rgb10a2Unorm, - "rg11b10float" => Sf::Rg11b10Ufloat, + "rg11b10ufloat" => Sf::Rg11b10Ufloat, "r64uint" => Sf::R64Uint, "rg32uint" => Sf::Rg32Uint, "rg32sint" => Sf::Rg32Sint, diff --git a/naga/src/front/wgsl/tests.rs b/naga/src/front/wgsl/tests.rs index bdcd35d8a86..149f5d329fd 100644 --- a/naga/src/front/wgsl/tests.rs +++ b/naga/src/front/wgsl/tests.rs @@ -627,7 +627,7 @@ fn parse_texture_load_store_expecting_four_args() { for (func, texture) in [ ( "textureStore", - "texture_storage_2d_array", + "texture_storage_2d_array", ), ("textureLoad", "texture_2d_array"), ] { From ffd4e9fb53a98f8ad67bab8c5d2b42cc9dbdff24 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 23 Sep 2025 13:37:29 -0700 Subject: [PATCH 218/303] chore(deps): update cts digest to 81bfec7 (#8253) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- cts_runner/revision.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cts_runner/revision.txt b/cts_runner/revision.txt index ceacddfbd42..e377c24deb6 100644 --- a/cts_runner/revision.txt +++ b/cts_runner/revision.txt @@ -1 +1 @@ -7a9fcc3382d4b6abebd6b04221ec0e844b87e326 +81bfec725ae101551cc29f5f028c968b19c14467 From 725549363bfb0778d26a19b7fe52decbdfc66b3f Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Wed, 23 Jul 2025 16:33:47 +0100 Subject: [PATCH 219/303] [vulkan] Use corresponding bind group layout entries when creating bind groups, rather than list of vk::DescriptorType This is a refactoring of Vulkan BindGroupLayout and BindGroup creation in preparation for implementing external texture support. Currently when creating a BindGroupLayout the Vulkan backend creates a list of the vk::DescriptorType for each entry, as well as the count, for binding arrays. Then when creating the BindGroup, it iterates through this list and does whatever it needs to do for each entry based on these values. In order to support external textures, we will have to create multiple descriptors for each BindingType::ExternalTexture. This means we cannot map each binding type to a single Vulkan descriptor type. Instead, store the list of BindGroupLayoutEntries on the BindGroupLayout and use those when creating the BindGroup, using the same "layout_and_entry_iter" idiom used by other backends. In subsequent patches this will allow us to create multiple descriptors for a single resource binding. --- wgpu-hal/src/vulkan/device.rs | 170 +++++++++++++++++----------------- wgpu-hal/src/vulkan/mod.rs | 3 +- 2 files changed, 87 insertions(+), 86 deletions(-) diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 1297e57f09b..a1a74b0230e 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -1480,20 +1480,46 @@ impl crate::Device for super::Device { &self, desc: &crate::BindGroupLayoutDescriptor, ) -> Result { + // Iterate through the entries and accumulate our Vulkan + // DescriptorSetLayoutBindings and DescriptorBindingFlags, as well as + // the list of which bindings are binding arrays, and our descriptor + // counts. + // Note: not bothering with on stack arrays here as it's low frequency + let mut vk_bindings = Vec::new(); + let mut binding_flags = Vec::new(); + let mut binding_arrays = Vec::new(); let mut desc_count = gpu_descriptor::DescriptorTotalCount::default(); - let mut types = Vec::new(); - for entry in desc.entries { + for (i, entry) in desc.entries.iter().enumerate() { + if let Some(count) = entry.count { + binding_arrays.push((i as u32, count)) + } + + let partially_bound = desc + .flags + .contains(crate::BindGroupLayoutFlags::PARTIALLY_BOUND); + let mut flags = vk::DescriptorBindingFlags::empty(); + if partially_bound && entry.count.is_some() { + flags |= vk::DescriptorBindingFlags::PARTIALLY_BOUND; + } + if entry.count.is_some() { + flags |= vk::DescriptorBindingFlags::UPDATE_AFTER_BIND; + } + let count = entry.count.map_or(1, |c| c.get()); - if entry.binding as usize >= types.len() { - types.resize( - entry.binding as usize + 1, - (vk::DescriptorType::INPUT_ATTACHMENT, 0), - ); + match entry.ty { + wgt::BindingType::ExternalTexture => unimplemented!(), + _ => { + vk_bindings.push(vk::DescriptorSetLayoutBinding { + binding: entry.binding, + descriptor_type: conv::map_binding_type(entry.ty), + descriptor_count: count, + stage_flags: conv::map_shader_stage(entry.visibility), + p_immutable_samplers: ptr::null(), + _marker: Default::default(), + }); + binding_flags.push(flags); + } } - types[entry.binding as usize] = ( - conv::map_binding_type(entry.ty), - entry.count.map_or(1, |c| c.get()), - ); match entry.ty { wgt::BindingType::Buffer { @@ -1532,27 +1558,6 @@ impl crate::Device for super::Device { } } - //Note: not bothering with on stack array here as it's low frequency - let vk_bindings = desc - .entries - .iter() - .map(|entry| vk::DescriptorSetLayoutBinding { - binding: entry.binding, - descriptor_type: types[entry.binding as usize].0, - descriptor_count: types[entry.binding as usize].1, - stage_flags: conv::map_shader_stage(entry.visibility), - p_immutable_samplers: ptr::null(), - _marker: Default::default(), - }) - .collect::>(); - - let binding_arrays: Vec<_> = desc - .entries - .iter() - .enumerate() - .filter_map(|(idx, entry)| entry.count.map(|count| (idx as u32, count))) - .collect(); - let vk_info = vk::DescriptorSetLayoutCreateInfo::default() .bindings(&vk_bindings) .flags(if !binding_arrays.is_empty() { @@ -1561,30 +1566,8 @@ impl crate::Device for super::Device { vk::DescriptorSetLayoutCreateFlags::empty() }); - let partially_bound = desc - .flags - .contains(crate::BindGroupLayoutFlags::PARTIALLY_BOUND); - - let binding_flag_vec = desc - .entries - .iter() - .map(|entry| { - let mut flags = vk::DescriptorBindingFlags::empty(); - - if partially_bound && entry.count.is_some() { - flags |= vk::DescriptorBindingFlags::PARTIALLY_BOUND; - } - - if entry.count.is_some() { - flags |= vk::DescriptorBindingFlags::UPDATE_AFTER_BIND; - } - - flags - }) - .collect::>(); - - let mut binding_flag_info = vk::DescriptorSetLayoutBindingFlagsCreateInfo::default() - .binding_flags(&binding_flag_vec); + let mut binding_flag_info = + vk::DescriptorSetLayoutBindingFlagsCreateInfo::default().binding_flags(&binding_flags); let vk_info = vk_info.push_next(&mut binding_flag_info); @@ -1604,7 +1587,7 @@ impl crate::Device for super::Device { Ok(super::BindGroupLayout { raw, desc_count, - types: types.into_boxed_slice(), + entries: desc.entries.into(), binding_arrays, }) } @@ -1787,18 +1770,21 @@ impl crate::Device for super::Device { Vec::with_capacity(desc.acceleration_structures.len()); let mut raw_acceleration_structures = ExtendStack::from_vec_capacity(&mut raw_acceleration_structures); - for entry in desc.entries { - let (ty, size) = desc.layout.types[entry.binding as usize]; - if size == 0 { - continue; // empty slot - } - let mut write = vk::WriteDescriptorSet::default() - .dst_set(*set.raw()) - .dst_binding(entry.binding) - .descriptor_type(ty); - - write = match ty { - vk::DescriptorType::SAMPLER => { + + let layout_and_entry_iter = desc.entries.iter().map(|entry| { + let layout = desc + .layout + .entries + .iter() + .find(|layout_entry| layout_entry.binding == entry.binding) + .expect("internal error: no layout entry found with binding slot"); + (layout, entry) + }); + for (layout, entry) in layout_and_entry_iter { + let write = vk::WriteDescriptorSet::default().dst_set(*set.raw()); + + match layout.ty { + wgt::BindingType::Sampler(_) => { let start = entry.resource_index; let end = start + entry.count; let local_image_infos; @@ -1806,9 +1792,14 @@ impl crate::Device for super::Device { image_infos.extend(desc.samplers[start as usize..end as usize].iter().map( |sampler| vk::DescriptorImageInfo::default().sampler(sampler.raw), )); - write.image_info(local_image_infos) + writes.push( + write + .dst_binding(entry.binding) + .descriptor_type(conv::map_binding_type(layout.ty)) + .image_info(local_image_infos), + ); } - vk::DescriptorType::SAMPLED_IMAGE | vk::DescriptorType::STORAGE_IMAGE => { + wgt::BindingType::Texture { .. } | wgt::BindingType::StorageTexture { .. } => { let start = entry.resource_index; let end = start + entry.count; let local_image_infos; @@ -1822,12 +1813,14 @@ impl crate::Device for super::Device { .image_layout(layout) }, )); - write.image_info(local_image_infos) + writes.push( + write + .dst_binding(entry.binding) + .descriptor_type(conv::map_binding_type(layout.ty)) + .image_info(local_image_infos), + ); } - vk::DescriptorType::UNIFORM_BUFFER - | vk::DescriptorType::UNIFORM_BUFFER_DYNAMIC - | vk::DescriptorType::STORAGE_BUFFER - | vk::DescriptorType::STORAGE_BUFFER_DYNAMIC => { + wgt::BindingType::Buffer { .. } => { let start = entry.resource_index; let end = start + entry.count; let local_buffer_infos; @@ -1842,9 +1835,14 @@ impl crate::Device for super::Device { ) }, )); - write.buffer_info(local_buffer_infos) + writes.push( + write + .dst_binding(entry.binding) + .descriptor_type(conv::map_binding_type(layout.ty)) + .buffer_info(local_buffer_infos), + ); } - vk::DescriptorType::ACCELERATION_STRUCTURE_KHR => { + wgt::BindingType::AccelerationStructure { .. } => { let start = entry.resource_index; let end = start + entry.count; @@ -1867,14 +1865,16 @@ impl crate::Device for super::Device { .acceleration_structures(local_raw_acceleration_structures), ); - write - .descriptor_count(entry.count) - .push_next(local_acceleration_structure_infos) + writes.push( + write + .dst_binding(entry.binding) + .descriptor_type(conv::map_binding_type(layout.ty)) + .descriptor_count(entry.count) + .push_next(local_acceleration_structure_infos), + ); } - _ => unreachable!(), - }; - - writes.push(write); + wgt::BindingType::ExternalTexture => unimplemented!(), + } } unsafe { self.shared.raw.update_descriptor_sets(&writes, &[]) }; diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 8a0bb03fc3c..f94fed3a38e 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -1005,7 +1005,8 @@ impl crate::DynSampler for Sampler {} pub struct BindGroupLayout { raw: vk::DescriptorSetLayout, desc_count: gpu_descriptor::DescriptorTotalCount, - types: Box<[(vk::DescriptorType, u32)]>, + /// Sorted list of entries. + entries: Box<[wgt::BindGroupLayoutEntry]>, /// Map of binding index to size, binding_arrays: Vec<(u32, NonZeroU32)>, } From ba0b6b9b0ecb2716b4557d7271783d592e9025fd Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Thu, 24 Jul 2025 10:35:10 +0100 Subject: [PATCH 220/303] [vulkan, naga spv-out] Remap resource bindings In order to support external textures, we must be able to map a single external texture resource binding to multiple Vulkan descriptors. This means we must be able to override the `Binding` and `DescriptorSet` values for global variables when generating SPIR-V, rather than simply passing through the group and binding values from Naga IR. This patch extends the existing SPIR-V Naga backend's `BindingMap` to contain a descriptor set and binding value in addition to the existing array size. When creating BindGroupLayouts/BindGroups we use a sequentially incrementing value for each entry's binding value, continuing to just use the bind group index as the descriptor set value. The Naga backend looks up each resource in the map when emitting its `Binding` and `DescriptorSet` decorations. If the entry cannot be found in the map, it will either error or emit fake bindings based on its configuration. --- naga-test/src/lib.rs | 1 + naga/src/back/spv/mod.rs | 12 +++- naga/src/back/spv/writer.rs | 32 +++++++-- naga/tests/in/wgsl/binding-arrays.toml | 2 +- naga/tests/in/wgsl/binding-buffer-arrays.toml | 2 +- wgpu-hal/src/vulkan/adapter.rs | 1 + wgpu-hal/src/vulkan/device.rs | 71 +++++++++++-------- wgpu-hal/src/vulkan/mod.rs | 17 ++++- 8 files changed, 96 insertions(+), 42 deletions(-) diff --git a/naga-test/src/lib.rs b/naga-test/src/lib.rs index 6f219005c62..078aa27c405 100644 --- a/naga-test/src/lib.rs +++ b/naga-test/src/lib.rs @@ -155,6 +155,7 @@ impl SpirvOutParameters { Some(self.capabilities.clone()) }, bounds_check_policies, + fake_missing_bindings: true, binding_map: self.binding_map.clone(), zero_initialize_workgroup_memory: spv::ZeroInitializeWorkgroupMemoryMode::Polyfill, force_loop_bounding: true, diff --git a/naga/src/back/spv/mod.rs b/naga/src/back/spv/mod.rs index ab3abe95515..371b3f7dbec 100644 --- a/naga/src/back/spv/mod.rs +++ b/naga/src/back/spv/mod.rs @@ -79,6 +79,8 @@ pub enum Error { Override, #[error(transparent)] ResolveArraySizeError(#[from] crate::proc::ResolveArraySizeError), + #[error("mapping of {0:?} is missing")] + MissingBinding(crate::ResourceBinding), } #[derive(Default)] @@ -760,6 +762,7 @@ pub struct Writer { constant_ids: HandleVec, cached_constants: crate::FastHashMap, global_variables: HandleVec, + fake_missing_bindings: bool, binding_map: BindingMap, // Cached expressions are only meaningful within a BlockContext, but we @@ -811,10 +814,12 @@ bitflags::bitflags! { } } -#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serialize", derive(serde::Serialize))] #[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] pub struct BindingInfo { + pub descriptor_set: u32, + pub binding: u32, /// If the binding is an unsized binding array, this overrides the size. pub binding_array_size: Option, } @@ -839,6 +844,10 @@ pub struct Options<'a> { /// Configuration flags for the writer. pub flags: WriterFlags, + /// Don't panic on missing bindings. Instead use fake values for `Binding` + /// and `DescriptorSet` decorations. This may result in invalid SPIR-V. + pub fake_missing_bindings: bool, + /// Map of resources to information about the binding. pub binding_map: BindingMap, @@ -877,6 +886,7 @@ impl Default for Options<'_> { Options { lang_version: (1, 0), flags, + fake_missing_bindings: true, binding_map: BindingMap::default(), capabilities: None, bounds_check_policies: BoundsCheckPolicies::default(), diff --git a/naga/src/back/spv/writer.rs b/naga/src/back/spv/writer.rs index eb414219492..636766d1e5f 100644 --- a/naga/src/back/spv/writer.rs +++ b/naga/src/back/spv/writer.rs @@ -87,6 +87,7 @@ impl Writer { constant_ids: HandleVec::new(), cached_constants: crate::FastHashMap::default(), global_variables: HandleVec::new(), + fake_missing_bindings: options.fake_missing_bindings, binding_map: options.binding_map.clone(), saved_cached: CachedExpressions::default(), gl450_ext_inst_id, @@ -149,6 +150,7 @@ impl Writer { force_loop_bounding: self.force_loop_bounding, use_storage_input_output_16: self.use_storage_input_output_16, capabilities_available: take(&mut self.capabilities_available), + fake_missing_bindings: self.fake_missing_bindings, binding_map: take(&mut self.binding_map), // Initialized afresh: @@ -469,6 +471,26 @@ impl Writer { }) } + /// Resolve the [`BindingInfo`] for a [`crate::ResourceBinding`] from the + /// provided [`Writer::binding_map`]. + /// + /// If the specified resource is not present in the binding map this will + /// return an error, unless [`Writer::fake_missing_bindings`] is set. + fn resolve_resource_binding( + &self, + res_binding: &crate::ResourceBinding, + ) -> Result { + match self.binding_map.get(res_binding) { + Some(target) => Ok(*target), + None if self.fake_missing_bindings => Ok(BindingInfo { + descriptor_set: res_binding.group, + binding: res_binding.binding, + binding_array_size: None, + }), + None => Err(Error::MissingBinding(*res_binding)), + } + } + /// Emits code for any wrapper functions required by the expressions in ir_function. /// The IDs of any emitted functions will be stored in [`Self::wrapped_functions`]. fn write_wrapped_functions( @@ -2241,13 +2263,11 @@ impl Writer { // and it is failing on 0. let mut substitute_inner_type_lookup = None; if let Some(ref res_binding) = global_variable.binding { - self.decorate(id, Decoration::DescriptorSet, &[res_binding.group]); - self.decorate(id, Decoration::Binding, &[res_binding.binding]); + let bind_target = self.resolve_resource_binding(res_binding)?; + self.decorate(id, Decoration::DescriptorSet, &[bind_target.descriptor_set]); + self.decorate(id, Decoration::Binding, &[bind_target.binding]); - if let Some(&BindingInfo { - binding_array_size: Some(remapped_binding_array_size), - }) = self.binding_map.get(res_binding) - { + if let Some(remapped_binding_array_size) = bind_target.binding_array_size { if let crate::TypeInner::BindingArray { base, .. } = ir_module.types[global_variable.ty].inner { diff --git a/naga/tests/in/wgsl/binding-arrays.toml b/naga/tests/in/wgsl/binding-arrays.toml index 27c15064171..a76141a6727 100644 --- a/naga/tests/in/wgsl/binding-arrays.toml +++ b/naga/tests/in/wgsl/binding-arrays.toml @@ -62,5 +62,5 @@ resource_binding = { group = 0, binding = 8 } version = [1, 1] [[spv.binding_map]] -bind_target = { binding_array_size = 10 } +bind_target = { descriptor_set = 0, binding = 0, binding_array_size = 10 } resource_binding = { group = 0, binding = 0 } diff --git a/naga/tests/in/wgsl/binding-buffer-arrays.toml b/naga/tests/in/wgsl/binding-buffer-arrays.toml index be1b09cf10d..7532299cb76 100644 --- a/naga/tests/in/wgsl/binding-buffer-arrays.toml +++ b/naga/tests/in/wgsl/binding-buffer-arrays.toml @@ -9,5 +9,5 @@ image = "ReadZeroSkipWrite" version = [1, 1] [[spv.binding_map]] -bind_target = { binding_array_size = 10 } +bind_target = { descriptor_set = 0, binding = 0, binding_array_size = 10 } resource_binding = { group = 0, binding = 0 } diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 0ebf1fec9a4..4371c653018 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -2166,6 +2166,7 @@ impl super::Adapter { force_loop_bounding: true, use_storage_input_output_16: features.contains(wgt::Features::SHADER_F16) && self.phd_features.supports_storage_input_output_16(), + fake_missing_bindings: false, // We need to build this separately for each invocation, so just default it out here binding_map: BTreeMap::default(), debug_info: None, diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index a1a74b0230e..f04bce4954e 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -1482,16 +1482,17 @@ impl crate::Device for super::Device { ) -> Result { // Iterate through the entries and accumulate our Vulkan // DescriptorSetLayoutBindings and DescriptorBindingFlags, as well as - // the list of which bindings are binding arrays, and our descriptor - // counts. + // our binding map and our descriptor counts. // Note: not bothering with on stack arrays here as it's low frequency let mut vk_bindings = Vec::new(); let mut binding_flags = Vec::new(); - let mut binding_arrays = Vec::new(); + let mut binding_map = Vec::new(); + let mut next_binding = 0; + let mut contains_binding_arrays = false; let mut desc_count = gpu_descriptor::DescriptorTotalCount::default(); - for (i, entry) in desc.entries.iter().enumerate() { - if let Some(count) = entry.count { - binding_arrays.push((i as u32, count)) + for entry in desc.entries { + if entry.count.is_some() { + contains_binding_arrays = true; } let partially_bound = desc @@ -1510,7 +1511,7 @@ impl crate::Device for super::Device { wgt::BindingType::ExternalTexture => unimplemented!(), _ => { vk_bindings.push(vk::DescriptorSetLayoutBinding { - binding: entry.binding, + binding: next_binding, descriptor_type: conv::map_binding_type(entry.ty), descriptor_count: count, stage_flags: conv::map_shader_stage(entry.visibility), @@ -1518,6 +1519,14 @@ impl crate::Device for super::Device { _marker: Default::default(), }); binding_flags.push(flags); + binding_map.push(( + entry.binding, + super::BindingInfo { + binding: next_binding, + binding_array_size: entry.count, + }, + )); + next_binding += 1; } } @@ -1560,7 +1569,7 @@ impl crate::Device for super::Device { let vk_info = vk::DescriptorSetLayoutCreateInfo::default() .bindings(&vk_bindings) - .flags(if !binding_arrays.is_empty() { + .flags(if contains_binding_arrays { vk::DescriptorSetLayoutCreateFlags::UPDATE_AFTER_BIND_POOL } else { vk::DescriptorSetLayoutCreateFlags::empty() @@ -1588,7 +1597,8 @@ impl crate::Device for super::Device { raw, desc_count, entries: desc.entries.into(), - binding_arrays, + binding_map, + contains_binding_arrays, }) } unsafe fn destroy_bind_group_layout(&self, bg_layout: super::BindGroupLayout) { @@ -1640,27 +1650,25 @@ impl crate::Device for super::Device { unsafe { self.shared.set_object_name(raw, label) }; } - let mut binding_arrays = BTreeMap::new(); + let mut binding_map = BTreeMap::new(); for (group, &layout) in desc.bind_group_layouts.iter().enumerate() { - for &(binding, binding_array_size) in &layout.binding_arrays { - binding_arrays.insert( + for &(binding, binding_info) in &layout.binding_map { + binding_map.insert( naga::ResourceBinding { group: group as u32, binding, }, naga::back::spv::BindingInfo { - binding_array_size: Some(binding_array_size.get()), + descriptor_set: group as u32, + binding: binding_info.binding, + binding_array_size: binding_info.binding_array_size.map(NonZeroU32::get), }, ); } } self.counters.pipeline_layouts.add(1); - - Ok(super::PipelineLayout { - raw, - binding_arrays, - }) + Ok(super::PipelineLayout { raw, binding_map }) } unsafe fn destroy_pipeline_layout(&self, pipeline_layout: super::PipelineLayout) { unsafe { @@ -1682,9 +1690,7 @@ impl crate::Device for super::Device { super::AccelerationStructure, >, ) -> Result { - let contains_binding_arrays = !desc.layout.binding_arrays.is_empty(); - - let desc_set_layout_flags = if contains_binding_arrays { + let desc_set_layout_flags = if desc.layout.contains_binding_arrays { gpu_descriptor::DescriptorSetLayoutCreateFlags::UPDATE_AFTER_BIND } else { gpu_descriptor::DescriptorSetLayoutCreateFlags::empty() @@ -1780,6 +1786,7 @@ impl crate::Device for super::Device { .expect("internal error: no layout entry found with binding slot"); (layout, entry) }); + let mut next_binding = 0; for (layout, entry) in layout_and_entry_iter { let write = vk::WriteDescriptorSet::default().dst_set(*set.raw()); @@ -1794,10 +1801,11 @@ impl crate::Device for super::Device { )); writes.push( write - .dst_binding(entry.binding) + .dst_binding(next_binding) .descriptor_type(conv::map_binding_type(layout.ty)) .image_info(local_image_infos), ); + next_binding += 1; } wgt::BindingType::Texture { .. } | wgt::BindingType::StorageTexture { .. } => { let start = entry.resource_index; @@ -1815,10 +1823,11 @@ impl crate::Device for super::Device { )); writes.push( write - .dst_binding(entry.binding) + .dst_binding(next_binding) .descriptor_type(conv::map_binding_type(layout.ty)) .image_info(local_image_infos), ); + next_binding += 1; } wgt::BindingType::Buffer { .. } => { let start = entry.resource_index; @@ -1837,10 +1846,11 @@ impl crate::Device for super::Device { )); writes.push( write - .dst_binding(entry.binding) + .dst_binding(next_binding) .descriptor_type(conv::map_binding_type(layout.ty)) .buffer_info(local_buffer_infos), ); + next_binding += 1; } wgt::BindingType::AccelerationStructure { .. } => { let start = entry.resource_index; @@ -1867,11 +1877,12 @@ impl crate::Device for super::Device { writes.push( write - .dst_binding(entry.binding) + .dst_binding(next_binding) .descriptor_type(conv::map_binding_type(layout.ty)) .descriptor_count(entry.count) .push_next(local_acceleration_structure_infos), ); + next_binding += 1; } wgt::BindingType::ExternalTexture => unimplemented!(), } @@ -2033,7 +2044,7 @@ impl crate::Device for super::Device { compiled_vs = Some(self.compile_stage( vertex_stage, naga::ShaderStage::Vertex, - &desc.layout.binding_arrays, + &desc.layout.binding_map, )?); stages.push(compiled_vs.as_ref().unwrap().create_info); } @@ -2045,14 +2056,14 @@ impl crate::Device for super::Device { compiled_ts = Some(self.compile_stage( t, naga::ShaderStage::Task, - &desc.layout.binding_arrays, + &desc.layout.binding_map, )?); stages.push(compiled_ts.as_ref().unwrap().create_info); } compiled_ms = Some(self.compile_stage( mesh_stage, naga::ShaderStage::Mesh, - &desc.layout.binding_arrays, + &desc.layout.binding_map, )?); stages.push(compiled_ms.as_ref().unwrap().create_info); } @@ -2062,7 +2073,7 @@ impl crate::Device for super::Device { let compiled = self.compile_stage( stage, naga::ShaderStage::Fragment, - &desc.layout.binding_arrays, + &desc.layout.binding_map, )?; stages.push(compiled.create_info); Some(compiled) @@ -2270,7 +2281,7 @@ impl crate::Device for super::Device { let compiled = self.compile_stage( &desc.stage, naga::ShaderStage::Compute, - &desc.layout.binding_arrays, + &desc.layout.binding_map, )?; let vk_infos = [{ diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index f94fed3a38e..c449f0f9c2c 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -1001,14 +1001,25 @@ pub struct Sampler { impl crate::DynSampler for Sampler {} +/// Information about a binding within a specific BindGroupLayout / BindGroup. +/// This will be used to construct a [`naga::back::spv::BindingInfo`], where +/// the descriptor set value will be taken from the index of the group. +#[derive(Copy, Clone, Debug)] +struct BindingInfo { + binding: u32, + binding_array_size: Option, +} + #[derive(Debug)] pub struct BindGroupLayout { raw: vk::DescriptorSetLayout, desc_count: gpu_descriptor::DescriptorTotalCount, /// Sorted list of entries. entries: Box<[wgt::BindGroupLayoutEntry]>, - /// Map of binding index to size, - binding_arrays: Vec<(u32, NonZeroU32)>, + /// Map of original binding index to remapped binding index and optional + /// array size. + binding_map: Vec<(u32, BindingInfo)>, + contains_binding_arrays: bool, } impl crate::DynBindGroupLayout for BindGroupLayout {} @@ -1016,7 +1027,7 @@ impl crate::DynBindGroupLayout for BindGroupLayout {} #[derive(Debug)] pub struct PipelineLayout { raw: vk::PipelineLayout, - binding_arrays: naga::back::spv::BindingMap, + binding_map: naga::back::spv::BindingMap, } impl crate::DynPipelineLayout for PipelineLayout {} From d2ee4b8be5355d45c29baf2f401e2e761e59942c Mon Sep 17 00:00:00 2001 From: Cai Bear Date: Wed, 24 Sep 2025 09:03:58 -0700 Subject: [PATCH 221/303] Fix #8151. (#8215) --- naga/src/front/spv/mod.rs | 6 ++ naga/tests/in/spv/8151-barrier-reorder.spvasm | 63 +++++++++++++++++++ .../out/wgsl/spv-8151-barrier-reorder.wgsl | 30 +++++++++ 3 files changed, 99 insertions(+) create mode 100644 naga/tests/in/spv/8151-barrier-reorder.spvasm create mode 100644 naga/tests/out/wgsl/spv-8151-barrier-reorder.wgsl diff --git a/naga/src/front/spv/mod.rs b/naga/src/front/spv/mod.rs index 960437ece58..2e54c74a213 100644 --- a/naga/src/front/spv/mod.rs +++ b/naga/src/front/spv/mod.rs @@ -3869,7 +3869,10 @@ impl> Frontend { crate::Barrier::TEXTURE, semantics & spirv::MemorySemantics::IMAGE_MEMORY.bits() != 0, ); + + block.extend(emitter.finish(ctx.expressions)); block.push(crate::Statement::ControlBarrier(flags), span); + emitter.start(ctx.expressions); } else { log::warn!("Unsupported barrier execution scope: {exec_scope}"); } @@ -3911,7 +3914,10 @@ impl> Frontend { crate::Barrier::TEXTURE, semantics & spirv::MemorySemantics::IMAGE_MEMORY.bits() != 0, ); + + block.extend(emitter.finish(ctx.expressions)); block.push(crate::Statement::MemoryBarrier(flags), span); + emitter.start(ctx.expressions); } Op::CopyObject => { inst.expect(4)?; diff --git a/naga/tests/in/spv/8151-barrier-reorder.spvasm b/naga/tests/in/spv/8151-barrier-reorder.spvasm new file mode 100644 index 00000000000..733e4d74414 --- /dev/null +++ b/naga/tests/in/spv/8151-barrier-reorder.spvasm @@ -0,0 +1,63 @@ +; SPIR-V +; Version: 1.3 +; Generator: Google rspirv; 0 +; Bound: 45 +; Schema: 0 + OpCapability Shader + OpCapability VulkanMemoryModel + OpExtension "SPV_KHR_vulkan_memory_model" + OpMemoryModel Logical Vulkan + OpEntryPoint GLCompute %1 "barrier_reorder_bug" %gl_LocalInvocationID + OpExecutionMode %1 LocalSize 2 1 1 + OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId + OpDecorate %_runtimearr_uint ArrayStride 4 + OpDecorate %_struct_8 Block + OpMemberDecorate %_struct_8 0 Offset 0 + OpDecorate %5 Binding 0 + OpDecorate %5 DescriptorSet 0 + %uint = OpTypeInt 32 0 + %v3uint = OpTypeVector %uint 3 +%_ptr_Input_v3uint = OpTypePointer Input %v3uint + %void = OpTypeVoid + %13 = OpTypeFunction %void +%gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input +%_runtimearr_uint = OpTypeRuntimeArray %uint + %_struct_8 = OpTypeStruct %_runtimearr_uint +%_ptr_StorageBuffer__struct_8 = OpTypePointer StorageBuffer %_struct_8 + %5 = OpVariable %_ptr_StorageBuffer__struct_8 StorageBuffer + %uint_0 = OpConstant %uint 0 + %bool = OpTypeBool +%_ptr_Workgroup_uint = OpTypePointer Workgroup %uint + %6 = OpVariable %_ptr_Workgroup_uint Workgroup + %uint_1 = OpConstant %uint 1 + %uint_2 = OpConstant %uint 2 + %uint_264 = OpConstant %uint 264 +%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint + %1 = OpFunction %void None %13 + %23 = OpLabel + %24 = OpLoad %v3uint %gl_LocalInvocationID + %27 = OpCompositeExtract %uint %24 0 + %28 = OpIEqual %bool %27 %uint_0 + OpSelectionMerge %29 None + OpBranchConditional %28 %30 %31 + %30 = OpLabel + OpStore %6 %uint_1 + OpBranch %29 + %31 = OpLabel + OpBranch %29 + %29 = OpLabel + OpControlBarrier %uint_2 %uint_2 %uint_264 + %32 = OpLoad %uint %6 + OpControlBarrier %uint_2 %uint_2 %uint_264 + %39 = OpInBoundsAccessChain %_ptr_StorageBuffer_uint %5 %uint_0 %27 + OpStore %39 %32 + OpSelectionMerge %42 None + OpBranchConditional %28 %43 %44 + %43 = OpLabel + OpStore %6 %uint_2 + OpBranch %42 + %44 = OpLabel + OpBranch %42 + %42 = OpLabel + OpReturn + OpFunctionEnd diff --git a/naga/tests/out/wgsl/spv-8151-barrier-reorder.wgsl b/naga/tests/out/wgsl/spv-8151-barrier-reorder.wgsl new file mode 100644 index 00000000000..4ba429bb811 --- /dev/null +++ b/naga/tests/out/wgsl/spv-8151-barrier-reorder.wgsl @@ -0,0 +1,30 @@ +struct type_3 { + member: array, +} + +var global: vec3; +@group(0) @binding(0) +var global_1: type_3; +var global_2: u32; + +fn function() { + let _e6 = global; + let _e8 = (_e6.x == 0u); + if _e8 { + global_2 = 1u; + } + workgroupBarrier(); + let _e9 = global_2; + workgroupBarrier(); + global_1.member[_e6.x] = _e9; + if _e8 { + global_2 = 2u; + } + return; +} + +@compute @workgroup_size(2, 1, 1) +fn barrier_reorder_bug(@builtin(local_invocation_id) param: vec3) { + global = param; + function(); +} From 084431b548eb204a20c6008e6f4d8acfa789357c Mon Sep 17 00:00:00 2001 From: Sam <16504129+sagudev@users.noreply.github.com> Date: Wed, 24 Sep 2025 20:23:25 +0200 Subject: [PATCH 222/303] [naga] Implement atan2 in const (#8222) Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> --- cts_runner/test.lst | 2 ++ naga/src/proc/constant_evaluator.rs | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 20fb875f348..827bf01119f 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -134,6 +134,8 @@ fails-if(metal) webgpu:api,operation,uncapturederror:iff_uncaptured:* //FAIL: webgpu:api,operation,uncapturederror:onuncapturederror_order_wrt_addEventListener // There are also two unimplemented SKIPs in uncapturederror not enumerated here. webgpu:api,validation,encoding,queries,general:occlusion_query,query_type:* +webgpu:shader,execution,expression,call,builtin,atan2:f16:* +webgpu:shader,execution,expression,call,builtin,atan2:f32:* webgpu:shader,execution,expression,call,builtin,textureSample:sampled_1d_coords:* webgpu:shader,execution,expression,call,builtin,textureSampleBaseClampToEdge:2d_coords:stage="c";textureType="texture_2d";* webgpu:shader,execution,flow_control,return:* diff --git a/naga/src/proc/constant_evaluator.rs b/naga/src/proc/constant_evaluator.rs index 5aa9baaa961..f5a5d25ca87 100644 --- a/naga/src/proc/constant_evaluator.rs +++ b/naga/src/proc/constant_evaluator.rs @@ -1178,6 +1178,11 @@ impl<'a> ConstantEvaluator<'a> { crate::MathFunction::Atan => { component_wise_float!(self, span, [arg], |e| { Ok([e.atan()]) }) } + crate::MathFunction::Atan2 => { + component_wise_float!(self, span, [arg, arg1.unwrap()], |y, x| { + Ok([y.atan2(x)]) + }) + } crate::MathFunction::Asinh => { component_wise_float!(self, span, [arg], |e| { Ok([e.asinh()]) }) } @@ -1346,8 +1351,7 @@ impl<'a> ConstantEvaluator<'a> { crate::MathFunction::Cross => self.cross_product(arg, arg1.unwrap(), span), // unimplemented - crate::MathFunction::Atan2 - | crate::MathFunction::Modf + crate::MathFunction::Modf | crate::MathFunction::Frexp | crate::MathFunction::Ldexp | crate::MathFunction::Dot From b2b76e6bfc150db80c2d93e5a3812990ad7f26b9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 24 Sep 2025 20:50:01 +0000 Subject: [PATCH 223/303] chore(deps): update rust crate hashbrown to 0.16 (#8194) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Connor Fitzgerald --- .deny.toml | 5 ----- Cargo.lock | 56 +++++++++++++++++++++++++++++++++++++++--------------- Cargo.toml | 2 +- 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/.deny.toml b/.deny.toml index b95868d767d..f730a23c215 100644 --- a/.deny.toml +++ b/.deny.toml @@ -32,13 +32,8 @@ skip = [ # cargo-metadata uses old version. Only used for infrastructure. { name = "toml", version = "0.8.23" }, { name = "ordered-float", version = "2.10.1" }, - # criterion uses an old version - { name = "itertools", version = "0.10.5" }, # bindgen (used by deno) uses old version { name = "itertools", version = "0.13.0" }, - # loom (used by tracy-client) uses old `matchers` crate - { name = "regex-automata", version = "0.1.10" }, - { name = "regex-syntax", version = "0.6.29" }, # Strum uses an old version { name = "heck", version = "0.4.0" }, # Deno uses an old version diff --git a/Cargo.lock b/Cargo.lock index 42da5cf0d78..5d091f5d60d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1527,6 +1527,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "foreign-types" version = "0.5.0" @@ -1884,7 +1890,7 @@ checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" dependencies = [ "bitflags 2.9.4", "gpu-descriptor-types", - "hashbrown", + "hashbrown 0.15.5", ] [[package]] @@ -1927,7 +1933,16 @@ checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", "equivalent", - "foldhash", + "foldhash 0.1.5", +] + +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +dependencies = [ + "foldhash 0.2.0", "serde", ] @@ -2111,14 +2126,15 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.11.0" +version = "2.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" dependencies = [ "arbitrary", "equivalent", - "hashbrown", + "hashbrown 0.16.0", "serde", + "serde_core", ] [[package]] @@ -2524,7 +2540,7 @@ dependencies = [ "diff", "env_logger", "half", - "hashbrown", + "hashbrown 0.16.0", "hexf-parse", "hlsl-snapshots", "indexmap", @@ -3171,7 +3187,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54acf3a685220b533e437e264e4d932cfbdc4cc7ec0cd232ed73c08d03b8a7ca" dependencies = [ "fixedbitset 0.5.7", - "hashbrown", + "hashbrown 0.15.5", "indexmap", ] @@ -3735,10 +3751,11 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.226" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd" dependencies = [ + "serde_core", "serde_derive", ] @@ -3763,11 +3780,20 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_core" +version = "1.0.226" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba2ba63999edb9dac981fb34b3e5c0d111a69b0924e253ed29d83f7c99e966a4" +dependencies = [ + "serde_derive", +] + [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.226" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "8db53ae22f34573731bafa1db20f04027b2d25e02d8205921b569171699cdb33" dependencies = [ "proc-macro2", "quote", @@ -4936,7 +4962,7 @@ dependencies = [ "cfg-if", "cfg_aliases 0.2.1", "document-features", - "hashbrown", + "hashbrown 0.16.0", "js-sys", "log", "naga", @@ -4982,7 +5008,7 @@ dependencies = [ "bytemuck", "cfg_aliases 0.2.1", "document-features", - "hashbrown", + "hashbrown 0.16.0", "indexmap", "log", "naga", @@ -5115,7 +5141,7 @@ dependencies = [ "gpu-alloc", "gpu-allocator", "gpu-descriptor", - "hashbrown", + "hashbrown 0.16.0", "js-sys", "khronos-egl", "libc", @@ -5154,7 +5180,7 @@ dependencies = [ "anyhow", "bitflags 2.9.4", "env_logger", - "hashbrown", + "hashbrown 0.16.0", "pico-args", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index 5614a5fb4ba..77ee766159b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -123,7 +123,7 @@ getrandom = "0.3" glam = "0.30" glob = "0.3" half = { version = "2.5", default-features = false } # We require 2.5 to have `Arbitrary` support. -hashbrown = { version = "0.15", default-features = false, features = [ +hashbrown = { version = "0.16", default-features = false, features = [ "default-hasher", "inline-more", ] } From 6ef8e1f1033d3585667fdb348e114c3c043257ed Mon Sep 17 00:00:00 2001 From: Jay McCarthy Date: Wed, 24 Sep 2025 15:16:47 -0600 Subject: [PATCH 224/303] Expose raw handles (#8174) Co-authored-by: Connor Fitzgerald --- wgpu-hal/src/vulkan/adapter.rs | 8 ++++++++ wgpu-hal/src/vulkan/mod.rs | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 4371c653018..9c007bf6ef9 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -129,6 +129,10 @@ pub struct PhysicalDeviceFeatures { } impl PhysicalDeviceFeatures { + pub fn get_core(&self) -> vk::PhysicalDeviceFeatures { + self.core + } + /// Add the members of `self` into `info.enabled_features` and its `p_next` chain. pub fn add_to_device_create<'a>( &'a mut self, @@ -1859,6 +1863,10 @@ impl super::Adapter { self.raw } + pub fn get_physical_device_features(&self) -> &PhysicalDeviceFeatures { + &self.phd_features + } + pub fn physical_device_capabilities(&self) -> &PhysicalDeviceProperties { &self.phd_capabilities } diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index c449f0f9c2c..c24217d2f78 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -462,6 +462,10 @@ pub struct Surface { } impl Surface { + pub unsafe fn raw_handle(&self) -> vk::SurfaceKHR { + self.raw + } + /// Get the raw Vulkan swapchain associated with this surface. /// /// Returns [`None`] if the surface is not configured. From 81f02f26f243ffb76bafd5868f8b72fb134151f5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 24 Sep 2025 17:47:32 -0400 Subject: [PATCH 225/303] chore(deps): update rust crate ron to 0.11 (#8196) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- player/tests/player/main.rs | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5d091f5d60d..e09db4ad27e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3592,9 +3592,9 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" [[package]] name = "ron" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f" +checksum = "db09040cc89e461f1a265139777a2bde7f8d8c67c4936f700c63ce3e2904d468" dependencies = [ "base64", "bitflags 2.9.4", diff --git a/Cargo.toml b/Cargo.toml index 77ee766159b..621317feb0c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -174,7 +174,7 @@ rayon = "1.3" regex-lite = "0.1" renderdoc-sys = "1" rspirv = "0.12" -ron = "0.10" +ron = "0.11" # NOTE: rustc-hash v2 is a completely different hasher with different performance characteristics # see discussion here (including with some other alternatives): https://github.com/gfx-rs/wgpu/issues/6999 # (using default-features = false to support no-std build, avoiding any extra features that may require std::collections) diff --git a/player/tests/player/main.rs b/player/tests/player/main.rs index e50e4368d08..3f57829183d 100644 --- a/player/tests/player/main.rs +++ b/player/tests/player/main.rs @@ -76,8 +76,7 @@ impl Test<'_> { _ => unreachable!(), }; let string = read_to_string(&path).unwrap().replace("Noop", backend_name); - ron::de::from_str(&string) - .unwrap_or_else(|e| panic!("{path:?}:{} {}", e.position.line, e.code)) + ron::de::from_str(&string).unwrap_or_else(|e| panic!("{path:?}:{} {}", e.span, e.code)) } fn run( From 4566e566778b18c88244b966a628b99d67112a87 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 24 Sep 2025 22:18:05 +0000 Subject: [PATCH 226/303] chore(deps): update rust crate encase to 0.12 (#8228) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Connor Fitzgerald --- Cargo.lock | 18 +++++++++--------- Cargo.toml | 4 ++-- examples/features/Cargo.toml | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e09db4ad27e..9b10a5d11a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1351,30 +1351,29 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "encase" -version = "0.11.2" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02ba239319a4f60905966390f5e52799d868103a533bb7e27822792332504ddd" +checksum = "6e3e0ff2ee0b7aa97428308dd9e1e42369cb22f5fb8dc1c55546637443a60f1e" dependencies = [ "const_panic", "encase_derive", - "glam", "thiserror 2.0.16", ] [[package]] name = "encase_derive" -version = "0.11.2" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5223d6c647f09870553224f6e37261fe5567bc5a4f4cf13ed337476e79990f2f" +checksum = "a4d90c5d7d527c6cb8a3b114efd26a6304d9ab772656e73d8f4e32b1f3d601a2" dependencies = [ "encase_derive_impl", ] [[package]] name = "encase_derive_impl" -version = "0.11.2" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1796db3d892515842ca2dfb11124c4bb4a9e58d9f2c5c1072e5bca1b2334507b" +checksum = "c8bad72d8308f7a382de2391ec978ddd736e0103846b965d7e2a63a75768af30" dependencies = [ "proc-macro2", "quote", @@ -1763,11 +1762,12 @@ dependencies = [ [[package]] name = "glam" -version = "0.30.5" +version = "0.30.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2d1aab06663bdce00d6ca5e5ed586ec8d18033a771906c993a1e3755b368d85" +checksum = "e12d847aeb25f41be4c0ec9587d624e9cd631bc007a8fd7ce3f5851e064c6460" dependencies = [ "bytemuck", + "encase", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 621317feb0c..7379a6b594b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -114,13 +114,13 @@ codespan-reporting = { version = "0.12", default-features = false } ctor = "0.5" diff = "0.1" document-features = "0.2.10" -encase = "0.11" +encase = "0.12" env_logger = { version = "0.11", default-features = false } fern = "0.7" flume = "0.11" futures-lite = "2" getrandom = "0.3" -glam = "0.30" +glam = "0.30.7" glob = "0.3" half = { version = "2.5", default-features = false } # We require 2.5 to have `Arbitrary` support. hashbrown = { version = "0.16", default-features = false, features = [ diff --git a/examples/features/Cargo.toml b/examples/features/Cargo.toml index 85c777f48b7..54998b467e1 100644 --- a/examples/features/Cargo.toml +++ b/examples/features/Cargo.toml @@ -33,10 +33,10 @@ webgpu = ["wgpu/webgpu"] [dependencies] bytemuck.workspace = true cfg-if.workspace = true -encase = { workspace = true, features = ["glam"] } +encase = { workspace = true } flume.workspace = true getrandom = { workspace = true, features = ["wasm_js"] } -glam = { workspace = true, features = ["bytemuck"] } +glam = { workspace = true, features = ["bytemuck", "encase"] } ktx2.workspace = true log.workspace = true nanorand = { workspace = true, features = ["getrandom"] } From 1f10d0ce8a25e69d2c5f7c4b45bb47d5a744c291 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 24 Sep 2025 19:42:24 -0700 Subject: [PATCH 227/303] [naga] Don't report shader errors as their own source (#8258) --- CHANGELOG.md | 1 + naga/src/error.rs | 2 +- naga/src/front/glsl/error.rs | 6 +----- naga/src/front/wgsl/error.rs | 6 +----- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c22134b2b6f..a0f60c9ac2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -197,6 +197,7 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). - Add f16 IO polyfill on Vulkan backend to enable SHADER_F16 use without requiring `storageInputOutput16`. By @cryvosh in [#7884](https://github.com/gfx-rs/wgpu/pull/7884). - For custom Naga backend authors: `naga::proc::Namer` now accepts reserved keywords using two new dedicated types, `proc::{KeywordSet, CaseInsensitiveKeywordSet}`. By @kpreid in [#8136](https://github.com/gfx-rs/wgpu/pull/8136). - **BREAKING**: Previously the WGSL storage-texture format `rg11b10float` was incorrectly accepted and generated by naga, but now only accepts the the correct name `rg11b10ufloat` instead. By @ErikWDev in [#8219](https://github.com/gfx-rs/wgpu/pull/8219). +- The [`source()`](https://doc.rust-lang.org/std/error/trait.Error.html#method.source) method of `ShaderError` no longer reports the error as its own source. By @andyleiserson in [#8258](https://github.com/gfx-rs/wgpu/pull/8258). #### DX12 diff --git a/naga/src/error.rs b/naga/src/error.rs index a4855606731..282cb6c88c5 100644 --- a/naga/src/error.rs +++ b/naga/src/error.rs @@ -134,7 +134,7 @@ where E: Error + 'static, { fn source(&self) -> Option<&(dyn Error + 'static)> { - Some(&self.inner) + self.inner.source() } } diff --git a/naga/src/front/glsl/error.rs b/naga/src/front/glsl/error.rs index 1fb15ef0390..9c9e58549fc 100644 --- a/naga/src/front/glsl/error.rs +++ b/naga/src/front/glsl/error.rs @@ -198,11 +198,7 @@ impl core::fmt::Display for ParseErrors { } } -impl core::error::Error for ParseErrors { - fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { - None - } -} +impl core::error::Error for ParseErrors {} impl From> for ParseErrors { fn from(errors: Vec) -> Self { diff --git a/naga/src/front/wgsl/error.rs b/naga/src/front/wgsl/error.rs index 1cdf53f37dc..17dab5cb0ea 100644 --- a/naga/src/front/wgsl/error.rs +++ b/naga/src/front/wgsl/error.rs @@ -127,11 +127,7 @@ impl core::fmt::Display for ParseError { } } -impl core::error::Error for ParseError { - fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { - None - } -} +impl core::error::Error for ParseError {} #[derive(Copy, Clone, Debug, PartialEq)] pub enum ExpectedToken<'a> { From 05cc6dca82fe5f5890299abf7cde6f1cd2907a26 Mon Sep 17 00:00:00 2001 From: Magnus <85136135+SupaMaggie70Incorporated@users.noreply.github.com> Date: Wed, 24 Sep 2025 22:24:56 -0500 Subject: [PATCH 228/303] [hal/dx12] Mesh Shaders (#8110) * Features and draw commands added * Tried to implement the pipeline creation (completely untested) * Fixed clippy issues * Fixed something I think * A little bit of work on the mesh shader example (currently doesn't work on dx12) * Reached a new kind of error state * Fixed an alignment issue * DirectX 12 mesh shaders working :party: * Removed stupid change and updated changelog * Fixed typo * Added backends option to example framework * Removed silly no write fragment shader from tests to see if anything breaks * Tried to make mesh shader tests run elsewhere too * Removed printlns and checked that dx12 mesh shader tests run * Documented very strange issue * I'm so lost * Fixed stupid typos * Fixed all issues * Removed unnecessary example stuff, updated tests * Updated typos.toml * Updated limits * Apply suggestion from @cwfitzgerald Co-authored-by: Connor Fitzgerald * Apply suggestion from @cwfitzgerald Co-authored-by: Connor Fitzgerald * Removed supported backends, made example & tests always pass the filename to shader compilers * Removed excessive bools in test params * Added new tests to the list * I'm a sinner for this one (unused import) * Replaced random stuff with test params hashing * Updated typos.toml * Updated -Fo typo thing * Actually fixed typo issue this time * Update CHANGELOG.md Co-authored-by: Connor Fitzgerald * Update tests/tests/wgpu-gpu/mesh_shader/mod.rs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update wgpu-hal/src/dx12/mod.rs Co-authored-by: Connor Fitzgerald * Addressed comments * Lmao --------- Co-authored-by: Connor Fitzgerald Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- CHANGELOG.md | 1 + examples/features/src/framework.rs | 4 +- examples/features/src/mesh_shader/mod.rs | 70 +++- examples/features/src/mesh_shader/shader.hlsl | 53 +++ examples/features/src/mesh_shader/shader.mesh | 6 +- examples/features/src/mesh_shader/shader.task | 2 +- naga/src/back/hlsl/mod.rs | 3 +- tests/src/run.rs | 1 + tests/tests/wgpu-gpu/mesh_shader/basic.hlsl | 41 +++ tests/tests/wgpu-gpu/mesh_shader/mod.rs | 208 ++++++++--- .../tests/wgpu-gpu/mesh_shader/no-write.frag | 7 - typos.toml | 3 + wgpu-hal/src/dx12/adapter.rs | 27 +- wgpu-hal/src/dx12/command.rs | 70 +++- wgpu-hal/src/dx12/device.rs | 336 +++++++++++------- wgpu-hal/src/dx12/mod.rs | 114 ++++++ 16 files changed, 730 insertions(+), 216 deletions(-) create mode 100644 examples/features/src/mesh_shader/shader.hlsl create mode 100644 tests/tests/wgpu-gpu/mesh_shader/basic.hlsl delete mode 100644 tests/tests/wgpu-gpu/mesh_shader/no-write.frag diff --git a/CHANGELOG.md b/CHANGELOG.md index a0f60c9ac2d..8c138ac1dfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -202,6 +202,7 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). #### DX12 - Allow disabling waiting for latency waitable object. By @marcpabst in [#7400](https://github.com/gfx-rs/wgpu/pull/7400) +- Add mesh shader support, including to the example. By @SupaMaggie70Incorporated in [#8110](https://github.com/gfx-rs/wgpu/issues/8110) ### Bug Fixes diff --git a/examples/features/src/framework.rs b/examples/features/src/framework.rs index 994eba8746e..02e92a1319d 100644 --- a/examples/features/src/framework.rs +++ b/examples/features/src/framework.rs @@ -268,9 +268,9 @@ impl ExampleContext { async fn init_async(surface: &mut SurfaceWrapper, window: Arc) -> Self { log::info!("Initializing wgpu..."); - let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor::from_env_or_default()); + let instance_descriptor = wgpu::InstanceDescriptor::from_env_or_default(); + let instance = wgpu::Instance::new(&instance_descriptor); surface.pre_adapter(&instance, window); - let adapter = get_adapter_with_capabilities_or_from_env( &instance, &E::required_features(), diff --git a/examples/features/src/mesh_shader/mod.rs b/examples/features/src/mesh_shader/mod.rs index 675150f5106..50ddff39a07 100644 --- a/examples/features/src/mesh_shader/mod.rs +++ b/examples/features/src/mesh_shader/mod.rs @@ -1,15 +1,13 @@ -use std::{io::Write, process::Stdio}; +use std::process::Stdio; // Same as in mesh shader tests -fn compile_glsl( - device: &wgpu::Device, - data: &[u8], - shader_stage: &'static str, -) -> wgpu::ShaderModule { +fn compile_glsl(device: &wgpu::Device, shader_stage: &'static str) -> wgpu::ShaderModule { let cmd = std::process::Command::new("glslc") .args([ - &format!("-fshader-stage={shader_stage}"), - "-", + &format!( + "{}/src/mesh_shader/shader.{shader_stage}", + env!("CARGO_MANIFEST_DIR") + ), "-o", "-", "--target-env=vulkan1.2", @@ -19,8 +17,6 @@ fn compile_glsl( .stdout(Stdio::piped()) .spawn() .expect("Failed to call glslc"); - cmd.stdin.as_ref().unwrap().write_all(data).unwrap(); - println!("{shader_stage}"); let output = cmd.wait_with_output().expect("Error waiting for glslc"); assert!(output.status.success()); unsafe { @@ -32,6 +28,38 @@ fn compile_glsl( }) } } +fn compile_hlsl(device: &wgpu::Device, entry: &str, stage_str: &str) -> wgpu::ShaderModule { + let out_path = format!( + "{}/src/mesh_shader/shader.{stage_str}.cso", + env!("CARGO_MANIFEST_DIR") + ); + let cmd = std::process::Command::new("dxc") + .args([ + "-T", + &format!("{stage_str}_6_5"), + "-E", + entry, + &format!("{}/src/mesh_shader/shader.hlsl", env!("CARGO_MANIFEST_DIR")), + "-Fo", + &out_path, + ]) + .output() + .unwrap(); + if !cmd.status.success() { + panic!("DXC failed:\n{}", String::from_utf8(cmd.stderr).unwrap()); + } + let file = std::fs::read(&out_path).unwrap(); + std::fs::remove_file(out_path).unwrap(); + unsafe { + device.create_shader_module_passthrough(wgpu::ShaderModuleDescriptorPassthrough { + entry_point: entry.to_owned(), + label: None, + num_workgroups: (1, 1, 1), + dxil: Some(std::borrow::Cow::Owned(file)), + ..Default::default() + }) + } +} pub struct Example { pipeline: wgpu::RenderPipeline, @@ -39,20 +67,30 @@ pub struct Example { impl crate::framework::Example for Example { fn init( config: &wgpu::SurfaceConfiguration, - _adapter: &wgpu::Adapter, + adapter: &wgpu::Adapter, device: &wgpu::Device, _queue: &wgpu::Queue, ) -> Self { + let (ts, ms, fs) = if adapter.get_info().backend == wgpu::Backend::Vulkan { + ( + compile_glsl(device, "task"), + compile_glsl(device, "mesh"), + compile_glsl(device, "frag"), + ) + } else if adapter.get_info().backend == wgpu::Backend::Dx12 { + ( + compile_hlsl(device, "Task", "as"), + compile_hlsl(device, "Mesh", "ms"), + compile_hlsl(device, "Frag", "ps"), + ) + } else { + panic!("Example can only run on vulkan or dx12"); + }; let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: None, bind_group_layouts: &[], push_constant_ranges: &[], }); - let (ts, ms, fs) = ( - compile_glsl(device, include_bytes!("shader.task"), "task"), - compile_glsl(device, include_bytes!("shader.mesh"), "mesh"), - compile_glsl(device, include_bytes!("shader.frag"), "frag"), - ); let pipeline = device.create_mesh_pipeline(&wgpu::MeshPipelineDescriptor { label: None, layout: Some(&pipeline_layout), diff --git a/examples/features/src/mesh_shader/shader.hlsl b/examples/features/src/mesh_shader/shader.hlsl new file mode 100644 index 00000000000..e70961f2d71 --- /dev/null +++ b/examples/features/src/mesh_shader/shader.hlsl @@ -0,0 +1,53 @@ +struct OutVertex { + float4 Position : SV_POSITION; + float4 Color: COLOR; +}; +struct OutPrimitive { + float4 ColorMask : COLOR_MASK : PRIMITIVE; + bool CullPrimitive: SV_CullPrimitive; +}; +struct InVertex { + float4 Color: COLOR; +}; +struct InPrimitive { + float4 ColorMask : COLOR_MASK : PRIMITIVE; +}; +struct PayloadData { + float4 ColorMask; + bool Visible; +}; + + +static const float4 positions[3] = {float4(0., 1.0, 0., 1.0), float4(-1.0, -1.0, 0., 1.0), float4(1.0, -1.0, 0., 1.0)}; +static const float4 colors[3] = {float4(0., 1., 0., 1.), float4(0., 0., 1., 1.), float4(1., 0., 0., 1.)}; + +groupshared PayloadData outPayload; + +[numthreads(1, 1, 1)] +void Task() { + outPayload.ColorMask = float4(1.0, 1.0, 0.0, 1.0); + outPayload.Visible = true; + DispatchMesh(3, 1, 1, outPayload); +} + +[outputtopology("triangle")] +[numthreads(1, 1, 1)] +void Mesh(out indices uint3 triangles[1], out vertices OutVertex vertices[3], out primitives OutPrimitive primitives[1], in payload PayloadData payload) { + SetMeshOutputCounts(3, 1); + + vertices[0].Position = positions[0]; + vertices[1].Position = positions[1]; + vertices[2].Position = positions[2]; + + vertices[0].Color = colors[0] * payload.ColorMask; + vertices[1].Color = colors[1] * payload.ColorMask; + vertices[2].Color = colors[2] * payload.ColorMask; + + triangles[0] = uint3(0, 1, 2); + primitives[0].ColorMask = float4(1.0, 0.0, 0.0, 1.0); + primitives[0].CullPrimitive = !payload.Visible; +} + +float4 Frag(InVertex vertex, InPrimitive primitive) : SV_Target { + return vertex.Color * primitive.ColorMask; +} diff --git a/examples/features/src/mesh_shader/shader.mesh b/examples/features/src/mesh_shader/shader.mesh index 7d350e8ce77..c2579670d30 100644 --- a/examples/features/src/mesh_shader/shader.mesh +++ b/examples/features/src/mesh_shader/shader.mesh @@ -20,18 +20,18 @@ vertexOutput[]; layout(location = 1) perprimitiveEXT out PrimitiveOutput { vec4 colorMask; } primitiveOutput[]; -shared uint sharedData; - layout(triangles, max_vertices = 3, max_primitives = 1) out; void main() { - sharedData = 5; SetMeshOutputsEXT(3, 1); + gl_MeshVerticesEXT[0].gl_Position = positions[0]; gl_MeshVerticesEXT[1].gl_Position = positions[1]; gl_MeshVerticesEXT[2].gl_Position = positions[2]; + vertexOutput[0].color = colors[0] * payloadData.colorMask; vertexOutput[1].color = colors[1] * payloadData.colorMask; vertexOutput[2].color = colors[2] * payloadData.colorMask; + gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationIndex] = uvec3(0, 1, 2); primitiveOutput[0].colorMask = vec4(1.0, 0.0, 1.0, 1.0); gl_MeshPrimitivesEXT[0].gl_CullPrimitiveEXT = !payloadData.visible; diff --git a/examples/features/src/mesh_shader/shader.task b/examples/features/src/mesh_shader/shader.task index 6c766bc83ae..04cdef2d5c2 100644 --- a/examples/features/src/mesh_shader/shader.task +++ b/examples/features/src/mesh_shader/shader.task @@ -1,7 +1,7 @@ #version 450 #extension GL_EXT_mesh_shader : require -layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in; +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; struct TaskPayload { vec4 colorMask; diff --git a/naga/src/back/hlsl/mod.rs b/naga/src/back/hlsl/mod.rs index 8df06cf1323..c7747eb3fac 100644 --- a/naga/src/back/hlsl/mod.rs +++ b/naga/src/back/hlsl/mod.rs @@ -283,7 +283,8 @@ impl crate::ShaderStage { Self::Vertex => "vs", Self::Fragment => "ps", Self::Compute => "cs", - Self::Task | Self::Mesh => unreachable!(), + Self::Task => "as", + Self::Mesh => "ms", } } } diff --git a/tests/src/run.rs b/tests/src/run.rs index ceeb8aca0ba..e066371d2e0 100644 --- a/tests/src/run.rs +++ b/tests/src/run.rs @@ -12,6 +12,7 @@ use crate::{ GpuTestConfiguration, }; +#[derive(Hash)] /// Parameters and resources handed to the test function. pub struct TestingContext { pub instance: Instance, diff --git a/tests/tests/wgpu-gpu/mesh_shader/basic.hlsl b/tests/tests/wgpu-gpu/mesh_shader/basic.hlsl new file mode 100644 index 00000000000..89a7276d3c0 --- /dev/null +++ b/tests/tests/wgpu-gpu/mesh_shader/basic.hlsl @@ -0,0 +1,41 @@ +struct OutVertex { + float4 Position : SV_POSITION; + float4 Color: COLOR; +}; +struct InVertex { + float4 Color: COLOR; +}; + + +static const float4 positions[3] = {float4(0., 1.0, 0., 1.0), float4(-1.0, -1.0, 0., 1.0), float4(1.0, -1.0, 0., 1.0)}; +static const float4 colors[3] = {float4(0., 1., 0., 1.), float4(0., 0., 1., 1.), float4(1., 0., 0., 1.)}; + +struct EmptyPayload { + uint _nullField; +}; +groupshared EmptyPayload _emptyPayload; + +[numthreads(4, 1, 1)] +void Task() { + DispatchMesh(1, 1, 1, _emptyPayload); +} + +[outputtopology("triangle")] +[numthreads(1, 1, 1)] +void Mesh(out indices uint3 triangles[1], out vertices OutVertex vertices[3], in payload EmptyPayload _emptyPayload) { + SetMeshOutputCounts(3, 1); + + vertices[0].Position = positions[0]; + vertices[1].Position = positions[1]; + vertices[2].Position = positions[2]; + + vertices[0].Color = colors[0]; + vertices[1].Color = colors[1]; + vertices[2].Color = colors[2]; + + triangles[0] = uint3(0, 1, 2); +} + +float4 Frag(InVertex vertex) : SV_Target { + return vertex.Color; +} diff --git a/tests/tests/wgpu-gpu/mesh_shader/mod.rs b/tests/tests/wgpu-gpu/mesh_shader/mod.rs index 23e2c6ccda5..13771a1fb45 100644 --- a/tests/tests/wgpu-gpu/mesh_shader/mod.rs +++ b/tests/tests/wgpu-gpu/mesh_shader/mod.rs @@ -1,4 +1,7 @@ -use std::{io::Write, process::Stdio}; +use std::{ + hash::{DefaultHasher, Hash, Hasher}, + process::Stdio, +}; use wgpu::util::DeviceExt; use wgpu_test::{ @@ -14,19 +17,19 @@ pub fn all_tests(tests: &mut Vec) { MESH_DRAW_INDIRECT, MESH_MULTI_DRAW_INDIRECT, MESH_MULTI_DRAW_INDIRECT_COUNT, + MESH_PIPELINE_BASIC_MESH_NO_DRAW, + MESH_PIPELINE_BASIC_TASK_MESH_FRAG_NO_DRAW, ]); } // Same as in mesh shader example -fn compile_glsl( - device: &wgpu::Device, - data: &[u8], - shader_stage: &'static str, -) -> wgpu::ShaderModule { +fn compile_glsl(device: &wgpu::Device, shader_stage: &'static str) -> wgpu::ShaderModule { let cmd = std::process::Command::new("glslc") .args([ - &format!("-fshader-stage={shader_stage}"), - "-", + &format!( + "{}/tests/wgpu-gpu/mesh_shader/basic.{shader_stage}", + env!("CARGO_MANIFEST_DIR") + ), "-o", "-", "--target-env=vulkan1.2", @@ -36,8 +39,6 @@ fn compile_glsl( .stdout(Stdio::piped()) .spawn() .expect("Failed to call glslc"); - cmd.stdin.as_ref().unwrap().write_all(data).unwrap(); - println!("{shader_stage}"); let output = cmd.wait_with_output().expect("Error waiting for glslc"); assert!(output.status.success()); unsafe { @@ -50,6 +51,70 @@ fn compile_glsl( } } +fn compile_hlsl( + device: &wgpu::Device, + entry: &str, + stage_str: &str, + test_name: &str, +) -> wgpu::ShaderModule { + // Each test needs its own files + let out_path = format!( + "{}/tests/wgpu-gpu/mesh_shader/{test_name}.{stage_str}.cso", + env!("CARGO_MANIFEST_DIR") + ); + let cmd = std::process::Command::new("dxc") + .args([ + "-T", + &format!("{stage_str}_6_5"), + "-E", + entry, + &format!( + "{}/tests/wgpu-gpu/mesh_shader/basic.hlsl", + env!("CARGO_MANIFEST_DIR") + ), + "-Fo", + &out_path, + ]) + .output() + .unwrap(); + if !cmd.status.success() { + panic!("DXC failed:\n{}", String::from_utf8(cmd.stderr).unwrap()); + } + let file = std::fs::read(&out_path).unwrap(); + std::fs::remove_file(out_path).unwrap(); + unsafe { + device.create_shader_module_passthrough(wgpu::ShaderModuleDescriptorPassthrough { + entry_point: entry.to_owned(), + label: None, + num_workgroups: (1, 1, 1), + dxil: Some(std::borrow::Cow::Owned(file)), + ..Default::default() + }) + } +} + +fn get_shaders( + device: &wgpu::Device, + backend: wgpu::Backend, + test_name: &str, +) -> (wgpu::ShaderModule, wgpu::ShaderModule, wgpu::ShaderModule) { + if backend == wgpu::Backend::Vulkan { + ( + compile_glsl(device, "task"), + compile_glsl(device, "mesh"), + compile_glsl(device, "frag"), + ) + } else if backend == wgpu::Backend::Dx12 { + ( + compile_hlsl(device, "Task", "as", test_name), + compile_hlsl(device, "Mesh", "ms", test_name), + compile_hlsl(device, "Frag", "ps", test_name), + ) + } else { + unreachable!() + } +} + fn create_depth( device: &wgpu::Device, ) -> (wgpu::Texture, wgpu::TextureView, wgpu::DepthStencilState) { @@ -79,18 +144,30 @@ fn create_depth( (depth_texture, depth_view, state) } -fn mesh_pipeline_build( - ctx: &TestingContext, - task: Option<&[u8]>, - mesh: &[u8], - frag: Option<&[u8]>, +struct MeshPipelineTestInfo { + use_task: bool, + use_frag: bool, draw: bool, -) { +} + +fn hash_testing_context(ctx: &TestingContext) -> u64 { + let mut hasher = DefaultHasher::new(); + ctx.hash(&mut hasher); + hasher.finish() +} + +fn mesh_pipeline_build(ctx: &TestingContext, info: MeshPipelineTestInfo) { + let backend = ctx.adapter.get_info().backend; + if backend != wgpu::Backend::Vulkan && backend != wgpu::Backend::Dx12 { + return; + } let device = &ctx.device; let (_depth_image, depth_view, depth_state) = create_depth(device); - let task = task.map(|t| compile_glsl(device, t, "task")); - let mesh = compile_glsl(device, mesh, "mesh"); - let frag = frag.map(|f| compile_glsl(device, f, "frag")); + + let test_hash = hash_testing_context(ctx).to_string(); + let (task, mesh, frag) = get_shaders(device, backend, &test_hash); + let task = if info.use_task { Some(task) } else { None }; + let frag = if info.use_frag { Some(frag) } else { None }; let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: None, bind_group_layouts: &[], @@ -124,7 +201,7 @@ fn mesh_pipeline_build( multiview: None, cache: None, }); - if draw { + if info.draw { let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); { @@ -160,11 +237,14 @@ pub enum DrawType { } fn mesh_draw(ctx: &TestingContext, draw_type: DrawType) { + let backend = ctx.adapter.get_info().backend; + if backend != wgpu::Backend::Vulkan && backend != wgpu::Backend::Dx12 { + return; + } let device = &ctx.device; let (_depth_image, depth_view, depth_state) = create_depth(device); - let task = compile_glsl(device, BASIC_TASK, "task"); - let mesh = compile_glsl(device, BASIC_MESH, "mesh"); - let frag = compile_glsl(device, NO_WRITE_FRAG, "frag"); + let test_hash = hash_testing_context(ctx).to_string(); + let (task, mesh, frag) = get_shaders(device, backend, &test_hash); let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: None, bind_group_layouts: &[], @@ -256,11 +336,6 @@ fn mesh_draw(ctx: &TestingContext, draw_type: DrawType) { ctx.device.poll(wgpu::PollType::Wait).unwrap(); } -const BASIC_TASK: &[u8] = include_bytes!("basic.task"); -const BASIC_MESH: &[u8] = include_bytes!("basic.mesh"); -//const BASIC_FRAG: &[u8] = include_bytes!("basic.frag.spv"); -const NO_WRITE_FRAG: &[u8] = include_bytes!("no-write.frag"); - fn default_gpu_test_config(draw_type: DrawType) -> GpuTestConfiguration { GpuTestConfiguration::new().parameters( TestParameters::default() @@ -279,47 +354,92 @@ fn default_gpu_test_config(draw_type: DrawType) -> GpuTestConfiguration { ) } -// Mesh pipeline configs #[gpu_test] -static MESH_PIPELINE_BASIC_MESH: GpuTestConfiguration = default_gpu_test_config(DrawType::Standard) - .run_sync(|ctx| { - mesh_pipeline_build(&ctx, None, BASIC_MESH, None, true); +pub static MESH_PIPELINE_BASIC_MESH: GpuTestConfiguration = + default_gpu_test_config(DrawType::Standard).run_sync(|ctx| { + mesh_pipeline_build( + &ctx, + MeshPipelineTestInfo { + use_task: false, + use_frag: false, + draw: true, + }, + ); + }); +#[gpu_test] +pub static MESH_PIPELINE_BASIC_TASK_MESH: GpuTestConfiguration = + default_gpu_test_config(DrawType::Standard).run_sync(|ctx| { + mesh_pipeline_build( + &ctx, + MeshPipelineTestInfo { + use_task: true, + use_frag: false, + draw: true, + }, + ); + }); +#[gpu_test] +pub static MESH_PIPELINE_BASIC_MESH_FRAG: GpuTestConfiguration = + default_gpu_test_config(DrawType::Standard).run_sync(|ctx| { + mesh_pipeline_build( + &ctx, + MeshPipelineTestInfo { + use_task: false, + use_frag: true, + draw: true, + }, + ); }); #[gpu_test] -static MESH_PIPELINE_BASIC_TASK_MESH: GpuTestConfiguration = +pub static MESH_PIPELINE_BASIC_TASK_MESH_FRAG: GpuTestConfiguration = default_gpu_test_config(DrawType::Standard).run_sync(|ctx| { - mesh_pipeline_build(&ctx, Some(BASIC_TASK), BASIC_MESH, None, true); + mesh_pipeline_build( + &ctx, + MeshPipelineTestInfo { + use_task: true, + use_frag: true, + draw: true, + }, + ); }); #[gpu_test] -static MESH_PIPELINE_BASIC_MESH_FRAG: GpuTestConfiguration = +pub static MESH_PIPELINE_BASIC_MESH_NO_DRAW: GpuTestConfiguration = default_gpu_test_config(DrawType::Standard).run_sync(|ctx| { - mesh_pipeline_build(&ctx, None, BASIC_MESH, Some(NO_WRITE_FRAG), true); + mesh_pipeline_build( + &ctx, + MeshPipelineTestInfo { + use_task: false, + use_frag: false, + draw: false, + }, + ); }); #[gpu_test] -static MESH_PIPELINE_BASIC_TASK_MESH_FRAG: GpuTestConfiguration = +pub static MESH_PIPELINE_BASIC_TASK_MESH_FRAG_NO_DRAW: GpuTestConfiguration = default_gpu_test_config(DrawType::Standard).run_sync(|ctx| { mesh_pipeline_build( &ctx, - Some(BASIC_TASK), - BASIC_MESH, - Some(NO_WRITE_FRAG), - true, + MeshPipelineTestInfo { + use_task: true, + use_frag: true, + draw: false, + }, ); }); // Mesh draw #[gpu_test] -static MESH_DRAW_INDIRECT: GpuTestConfiguration = default_gpu_test_config(DrawType::Indirect) +pub static MESH_DRAW_INDIRECT: GpuTestConfiguration = default_gpu_test_config(DrawType::Indirect) .run_sync(|ctx| { mesh_draw(&ctx, DrawType::Indirect); }); #[gpu_test] -static MESH_MULTI_DRAW_INDIRECT: GpuTestConfiguration = +pub static MESH_MULTI_DRAW_INDIRECT: GpuTestConfiguration = default_gpu_test_config(DrawType::MultiIndirect).run_sync(|ctx| { mesh_draw(&ctx, DrawType::MultiIndirect); }); #[gpu_test] -static MESH_MULTI_DRAW_INDIRECT_COUNT: GpuTestConfiguration = +pub static MESH_MULTI_DRAW_INDIRECT_COUNT: GpuTestConfiguration = default_gpu_test_config(DrawType::MultiIndirectCount).run_sync(|ctx| { mesh_draw(&ctx, DrawType::MultiIndirectCount); }); diff --git a/tests/tests/wgpu-gpu/mesh_shader/no-write.frag b/tests/tests/wgpu-gpu/mesh_shader/no-write.frag deleted file mode 100644 index d0512bb0fad..00000000000 --- a/tests/tests/wgpu-gpu/mesh_shader/no-write.frag +++ /dev/null @@ -1,7 +0,0 @@ -#version 450 -#extension GL_EXT_mesh_shader : require - -in VertexInput { layout(location = 0) vec4 color; } -vertexInput; - -void main() {} \ No newline at end of file diff --git a/typos.toml b/typos.toml index d93e1f8ecdc..f5efa9df29f 100644 --- a/typos.toml +++ b/typos.toml @@ -20,6 +20,9 @@ extend-exclude = [ lod = "lod" metalness = "metalness" +# A DXC command line argument +Fo = "Fo" + # Usernames Healthire = "Healthire" REASY = "REASY" diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index 6dce0ce97f0..140dcf60a80 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -528,6 +528,22 @@ impl super::Adapter { wgt::Features::SHADER_INT64_ATOMIC_ALL_OPS | wgt::Features::SHADER_INT64_ATOMIC_MIN_MAX, atomic_int64_on_typed_resource_supported, ); + let mesh_shader_supported = { + let mut features7 = Direct3D12::D3D12_FEATURE_DATA_D3D12_OPTIONS7::default(); + unsafe { + device.CheckFeatureSupport( + Direct3D12::D3D12_FEATURE_D3D12_OPTIONS7, + <*mut _>::cast(&mut features7), + size_of_val(&features7) as u32, + ) + } + .is_ok() + && features7.MeshShaderTier != Direct3D12::D3D12_MESH_SHADER_TIER_NOT_SUPPORTED + }; + features.set( + wgt::Features::EXPERIMENTAL_MESH_SHADER, + mesh_shader_supported, + ); // TODO: Determine if IPresentationManager is supported let presentation_timer = auxil::dxgi::time::PresentationTimer::new_dxgi(); @@ -648,10 +664,15 @@ impl super::Adapter { max_buffer_size: i32::MAX as u64, max_non_sampler_bindings: 1_000_000, - max_task_workgroup_total_count: 0, - max_task_workgroups_per_dimension: 0, + // Source: https://microsoft.github.io/DirectX-Specs/d3d/MeshShader.html#dispatchmesh-api + max_task_workgroup_total_count: 2u32.pow(22), + // Technically it says "64k" but I highly doubt they want 65536 for compute and exactly 64,000 for task workgroups + max_task_workgroups_per_dimension: + Direct3D12::D3D12_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION, + // Multiview not supported by WGPU yet max_mesh_multiview_count: 0, - max_mesh_output_layers: 0, + // This seems to be right, and I can't find anything to suggest it would be less than the 2048 provided here + max_mesh_output_layers: Direct3D12::D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION, max_blas_primitive_count: if supports_ray_tracing { 1 << 29 // 2^29 diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index edfea952ed2..2454f82ef88 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -1228,11 +1228,16 @@ impl crate::CommandEncoder for super::CommandEncoder { } unsafe fn draw_mesh_tasks( &mut self, - _group_count_x: u32, - _group_count_y: u32, - _group_count_z: u32, + group_count_x: u32, + group_count_y: u32, + group_count_z: u32, ) { - unreachable!() + self.prepare_dispatch([group_count_x, group_count_y, group_count_z]); + let cmd_list6: Direct3D12::ID3D12GraphicsCommandList6 = + self.list.as_ref().unwrap().cast().unwrap(); + unsafe { + cmd_list6.DispatchMesh(group_count_x, group_count_y, group_count_z); + } } unsafe fn draw_indirect( &mut self, @@ -1314,11 +1319,36 @@ impl crate::CommandEncoder for super::CommandEncoder { } unsafe fn draw_mesh_tasks_indirect( &mut self, - _buffer: &::Buffer, - _offset: wgt::BufferAddress, - _draw_count: u32, + buffer: &::Buffer, + offset: wgt::BufferAddress, + draw_count: u32, ) { - unreachable!() + if self + .pass + .layout + .special_constants + .as_ref() + .and_then(|sc| sc.indirect_cmd_signatures.as_ref()) + .is_some() + { + self.update_root_elements(); + } else { + self.prepare_dispatch([0; 3]); + } + + let cmd_list6: Direct3D12::ID3D12GraphicsCommandList6 = + self.list.as_ref().unwrap().cast().unwrap(); + let cmd_signature = &self + .pass + .layout + .special_constants + .as_ref() + .and_then(|sc| sc.indirect_cmd_signatures.as_ref()) + .unwrap_or_else(|| &self.shared.cmd_signatures) + .draw_mesh; + unsafe { + cmd_list6.ExecuteIndirect(cmd_signature, draw_count, &buffer.resource, offset, None, 0); + } } unsafe fn draw_indirect_count( &mut self, @@ -1362,13 +1392,25 @@ impl crate::CommandEncoder for super::CommandEncoder { } unsafe fn draw_mesh_tasks_indirect_count( &mut self, - _buffer: &::Buffer, - _offset: wgt::BufferAddress, - _count_buffer: &::Buffer, - _count_offset: wgt::BufferAddress, - _max_count: u32, + buffer: &::Buffer, + offset: wgt::BufferAddress, + count_buffer: &::Buffer, + count_offset: wgt::BufferAddress, + max_count: u32, ) { - unreachable!() + self.prepare_dispatch([0; 3]); + let cmd_list6: Direct3D12::ID3D12GraphicsCommandList6 = + self.list.as_ref().unwrap().cast().unwrap(); + unsafe { + cmd_list6.ExecuteIndirect( + &self.shared.cmd_signatures.draw_mesh, + max_count, + &buffer.resource, + offset, + &count_buffer.resource, + count_offset, + ); + } } // compute diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 27628a19a82..2b5b43cdaa2 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -140,6 +140,16 @@ impl super::Device { }], 0, )?, + draw_mesh: Self::create_command_signature( + &raw, + None, + size_of::(), + &[Direct3D12::D3D12_INDIRECT_ARGUMENT_DESC { + Type: Direct3D12::D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH, + ..Default::default() + }], + 0, + )?, dispatch: Self::create_command_signature( &raw, None, @@ -1394,6 +1404,19 @@ impl crate::Device for super::Device { ], 0, )?, + draw_mesh: Self::create_command_signature( + &self.raw, + Some(&raw), + special_constant_buffer_args_len + size_of::(), + &[ + constant_indirect_argument_desc, + Direct3D12::D3D12_INDIRECT_ARGUMENT_DESC { + Type: Direct3D12::D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH, + ..Default::default() + }, + ], + 0, + )?, dispatch: Self::create_command_signature( &self.raw, Some(&raw), @@ -1825,60 +1848,10 @@ impl crate::Device for super::Device { super::PipelineCache, >, ) -> Result { + let mut shader_stages = wgt::ShaderStages::empty(); + let root_signature = + unsafe { borrow_optional_interface_temporarily(&desc.layout.shared.signature) }; let (topology_class, topology) = conv::map_topology(desc.primitive.topology); - let mut shader_stages = wgt::ShaderStages::VERTEX; - - let (vertex_stage_desc, vertex_buffers_desc) = match &desc.vertex_processor { - crate::VertexProcessor::Standard { - vertex_buffers, - vertex_stage, - } => (vertex_stage, *vertex_buffers), - crate::VertexProcessor::Mesh { .. } => unreachable!(), - }; - - let blob_vs = self.load_shader( - vertex_stage_desc, - desc.layout, - naga::ShaderStage::Vertex, - desc.fragment_stage.as_ref(), - )?; - let blob_fs = match desc.fragment_stage { - Some(ref stage) => { - shader_stages |= wgt::ShaderStages::FRAGMENT; - Some(self.load_shader(stage, desc.layout, naga::ShaderStage::Fragment, None)?) - } - None => None, - }; - - let mut vertex_strides = [None; crate::MAX_VERTEX_BUFFERS]; - let mut input_element_descs = Vec::new(); - for (i, (stride, vbuf)) in vertex_strides - .iter_mut() - .zip(vertex_buffers_desc) - .enumerate() - { - *stride = NonZeroU32::new(vbuf.array_stride as u32); - let (slot_class, step_rate) = match vbuf.step_mode { - wgt::VertexStepMode::Vertex => { - (Direct3D12::D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0) - } - wgt::VertexStepMode::Instance => { - (Direct3D12::D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1) - } - }; - for attribute in vbuf.attributes { - input_element_descs.push(Direct3D12::D3D12_INPUT_ELEMENT_DESC { - SemanticName: windows::core::PCSTR(NAGA_LOCATION_SEMANTIC.as_ptr()), - SemanticIndex: attribute.shader_location, - Format: auxil::dxgi::conv::map_vertex_format(attribute.format), - InputSlot: i as u32, - AlignedByteOffset: attribute.offset as u32, - InputSlotClass: slot_class, - InstanceDataStepRate: step_rate, - }); - } - } - let mut rtv_formats = [Dxgi::Common::DXGI_FORMAT_UNKNOWN; Direct3D12::D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT as usize]; for (rtv_format, ct) in rtv_formats.iter_mut().zip(desc.color_targets) { @@ -1893,7 +1866,7 @@ impl crate::Device for super::Device { .map(|ds| ds.bias) .unwrap_or_default(); - let raw_rasterizer = Direct3D12::D3D12_RASTERIZER_DESC { + let rasterizer_state = Direct3D12::D3D12_RASTERIZER_DESC { FillMode: conv::map_polygon_mode(desc.primitive.polygon_mode), CullMode: match desc.primitive.cull_mode { None => Direct3D12::D3D12_CULL_MODE_NONE, @@ -1917,80 +1890,193 @@ impl crate::Device for super::Device { Direct3D12::D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF }, }; + let blob_fs = match desc.fragment_stage { + Some(ref stage) => { + shader_stages |= wgt::ShaderStages::FRAGMENT; + Some(self.load_shader(stage, desc.layout, naga::ShaderStage::Fragment, None)?) + } + None => None, + }; + let pixel_shader = match &blob_fs { + Some(shader) => shader.create_native_shader(), + None => Direct3D12::D3D12_SHADER_BYTECODE::default(), + }; + let mut vertex_strides = [None; crate::MAX_VERTEX_BUFFERS]; + let stream_output = Direct3D12::D3D12_STREAM_OUTPUT_DESC { + pSODeclaration: ptr::null(), + NumEntries: 0, + pBufferStrides: ptr::null(), + NumStrides: 0, + RasterizedStream: 0, + }; + let blend_state = Direct3D12::D3D12_BLEND_DESC { + AlphaToCoverageEnable: Foundation::BOOL::from( + desc.multisample.alpha_to_coverage_enabled, + ), + IndependentBlendEnable: true.into(), + RenderTarget: conv::map_render_targets(desc.color_targets), + }; + let depth_stencil_state = match desc.depth_stencil { + Some(ref ds) => conv::map_depth_stencil(ds), + None => Default::default(), + }; + let dsv_format = desc + .depth_stencil + .as_ref() + .map_or(Dxgi::Common::DXGI_FORMAT_UNKNOWN, |ds| { + auxil::dxgi::conv::map_texture_format(ds.format) + }); + let sample_desc = Dxgi::Common::DXGI_SAMPLE_DESC { + Count: desc.multisample.count, + Quality: 0, + }; + let cached_pso = Direct3D12::D3D12_CACHED_PIPELINE_STATE { + pCachedBlob: ptr::null(), + CachedBlobSizeInBytes: 0, + }; + let flags = Direct3D12::D3D12_PIPELINE_STATE_FLAG_NONE; - let raw_desc = Direct3D12::D3D12_GRAPHICS_PIPELINE_STATE_DESC { - pRootSignature: unsafe { - borrow_optional_interface_temporarily(&desc.layout.shared.signature) - }, - VS: blob_vs.create_native_shader(), - PS: match &blob_fs { - Some(shader) => shader.create_native_shader(), - None => Direct3D12::D3D12_SHADER_BYTECODE::default(), - }, - GS: Direct3D12::D3D12_SHADER_BYTECODE::default(), - DS: Direct3D12::D3D12_SHADER_BYTECODE::default(), - HS: Direct3D12::D3D12_SHADER_BYTECODE::default(), - StreamOutput: Direct3D12::D3D12_STREAM_OUTPUT_DESC { - pSODeclaration: ptr::null(), - NumEntries: 0, - pBufferStrides: ptr::null(), - NumStrides: 0, - RasterizedStream: 0, - }, - BlendState: Direct3D12::D3D12_BLEND_DESC { - AlphaToCoverageEnable: Foundation::BOOL::from( - desc.multisample.alpha_to_coverage_enabled, - ), - IndependentBlendEnable: true.into(), - RenderTarget: conv::map_render_targets(desc.color_targets), - }, - SampleMask: desc.multisample.mask as u32, - RasterizerState: raw_rasterizer, - DepthStencilState: match desc.depth_stencil { - Some(ref ds) => conv::map_depth_stencil(ds), - None => Default::default(), - }, - InputLayout: Direct3D12::D3D12_INPUT_LAYOUT_DESC { - pInputElementDescs: if input_element_descs.is_empty() { - ptr::null() - } else { - input_element_descs.as_ptr() - }, - NumElements: input_element_descs.len() as u32, - }, - IBStripCutValue: match desc.primitive.strip_index_format { - Some(wgt::IndexFormat::Uint16) => { - Direct3D12::D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF + let raw: Direct3D12::ID3D12PipelineState = match &desc.vertex_processor { + &crate::VertexProcessor::Standard { + vertex_buffers, + ref vertex_stage, + } => { + shader_stages |= wgt::ShaderStages::VERTEX; + let blob_vs = self.load_shader( + vertex_stage, + desc.layout, + naga::ShaderStage::Vertex, + desc.fragment_stage.as_ref(), + )?; + + let mut input_element_descs = Vec::new(); + for (i, (stride, vbuf)) in vertex_strides.iter_mut().zip(vertex_buffers).enumerate() + { + *stride = NonZeroU32::new(vbuf.array_stride as u32); + let (slot_class, step_rate) = match vbuf.step_mode { + wgt::VertexStepMode::Vertex => { + (Direct3D12::D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0) + } + wgt::VertexStepMode::Instance => { + (Direct3D12::D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 1) + } + }; + for attribute in vbuf.attributes { + input_element_descs.push(Direct3D12::D3D12_INPUT_ELEMENT_DESC { + SemanticName: windows::core::PCSTR(NAGA_LOCATION_SEMANTIC.as_ptr()), + SemanticIndex: attribute.shader_location, + Format: auxil::dxgi::conv::map_vertex_format(attribute.format), + InputSlot: i as u32, + AlignedByteOffset: attribute.offset as u32, + InputSlotClass: slot_class, + InstanceDataStepRate: step_rate, + }); + } + } + let raw_desc = Direct3D12::D3D12_GRAPHICS_PIPELINE_STATE_DESC { + pRootSignature: root_signature, + VS: blob_vs.create_native_shader(), + PS: pixel_shader, + GS: Direct3D12::D3D12_SHADER_BYTECODE::default(), + DS: Direct3D12::D3D12_SHADER_BYTECODE::default(), + HS: Direct3D12::D3D12_SHADER_BYTECODE::default(), + StreamOutput: stream_output, + BlendState: blend_state, + SampleMask: desc.multisample.mask as u32, + RasterizerState: rasterizer_state, + DepthStencilState: depth_stencil_state, + InputLayout: Direct3D12::D3D12_INPUT_LAYOUT_DESC { + pInputElementDescs: if input_element_descs.is_empty() { + ptr::null() + } else { + input_element_descs.as_ptr() + }, + NumElements: input_element_descs.len() as u32, + }, + IBStripCutValue: match desc.primitive.strip_index_format { + Some(wgt::IndexFormat::Uint16) => { + Direct3D12::D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF + } + Some(wgt::IndexFormat::Uint32) => { + Direct3D12::D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF + } + None => Direct3D12::D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED, + }, + PrimitiveTopologyType: topology_class, + NumRenderTargets: desc.color_targets.len() as u32, + RTVFormats: rtv_formats, + DSVFormat: dsv_format, + SampleDesc: sample_desc, + NodeMask: 0, + CachedPSO: cached_pso, + Flags: flags, + }; + unsafe { + profiling::scope!("ID3D12Device::CreateGraphicsPipelineState"); + self.raw.CreateGraphicsPipelineState(&raw_desc) } - Some(wgt::IndexFormat::Uint32) => { - Direct3D12::D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF + } + crate::VertexProcessor::Mesh { + task_stage, + mesh_stage, + } => { + let blob_ts = if let Some(ts) = task_stage { + shader_stages |= wgt::ShaderStages::TASK; + Some(self.load_shader( + ts, + desc.layout, + naga::ShaderStage::Task, + desc.fragment_stage.as_ref(), + )?) + } else { + None + }; + let task_shader = if let Some(ts) = &blob_ts { + ts.create_native_shader() + } else { + Default::default() + }; + shader_stages |= wgt::ShaderStages::MESH; + let blob_ms = self.load_shader( + mesh_stage, + desc.layout, + naga::ShaderStage::Mesh, + desc.fragment_stage.as_ref(), + )?; + let desc = super::MeshShaderPipelineStateStream { + root_signature: root_signature + .as_ref() + .map(|a| a.as_raw().cast()) + .unwrap_or(ptr::null_mut()), + task_shader, + pixel_shader, + mesh_shader: blob_ms.create_native_shader(), + blend_state, + sample_mask: desc.multisample.mask as u32, + rasterizer_state, + depth_stencil_state, + primitive_topology_type: topology_class, + rtv_formats: Direct3D12::D3D12_RT_FORMAT_ARRAY { + RTFormats: rtv_formats, + NumRenderTargets: desc.color_targets.len() as u32, + }, + dsv_format, + sample_desc, + node_mask: 0, + cached_pso, + flags, + }; + let mut raw_desc = unsafe { desc.to_bytes() }; + let stream_desc = Direct3D12::D3D12_PIPELINE_STATE_STREAM_DESC { + SizeInBytes: raw_desc.len(), + pPipelineStateSubobjectStream: raw_desc.as_mut_ptr().cast(), + }; + let device: Direct3D12::ID3D12Device2 = self.raw.cast().unwrap(); + unsafe { + profiling::scope!("ID3D12Device2::CreatePipelineState"); + device.CreatePipelineState(&stream_desc) } - None => Direct3D12::D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED, - }, - PrimitiveTopologyType: topology_class, - NumRenderTargets: desc.color_targets.len() as u32, - RTVFormats: rtv_formats, - DSVFormat: desc - .depth_stencil - .as_ref() - .map_or(Dxgi::Common::DXGI_FORMAT_UNKNOWN, |ds| { - auxil::dxgi::conv::map_texture_format(ds.format) - }), - SampleDesc: Dxgi::Common::DXGI_SAMPLE_DESC { - Count: desc.multisample.count, - Quality: 0, - }, - NodeMask: 0, - CachedPSO: Direct3D12::D3D12_CACHED_PIPELINE_STATE { - pCachedBlob: ptr::null(), - CachedBlobSizeInBytes: 0, - }, - Flags: Direct3D12::D3D12_PIPELINE_STATE_FLAG_NONE, - }; - - let raw: Direct3D12::ID3D12PipelineState = { - profiling::scope!("ID3D12Device::CreateGraphicsPipelineState"); - unsafe { self.raw.CreateGraphicsPipelineState(&raw_desc) } + } } .map_err(|err| crate::PipelineError::Linkage(shader_stages, err.to_string()))?; diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index b355582ab1f..00bde82396c 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -660,6 +660,7 @@ struct Idler { struct CommandSignatures { draw: Direct3D12::ID3D12CommandSignature, draw_indexed: Direct3D12::ID3D12CommandSignature, + draw_mesh: Direct3D12::ID3D12CommandSignature, dispatch: Direct3D12::ID3D12CommandSignature, } @@ -1600,3 +1601,116 @@ pub enum ShaderModuleSource { DxilPassthrough(DxilPassthroughShader), HlslPassthrough(HlslPassthroughShader), } + +#[repr(C)] +#[derive(Debug)] +struct MeshShaderPipelineStateStream { + root_signature: *mut Direct3D12::ID3D12RootSignature, + task_shader: Direct3D12::D3D12_SHADER_BYTECODE, + mesh_shader: Direct3D12::D3D12_SHADER_BYTECODE, + pixel_shader: Direct3D12::D3D12_SHADER_BYTECODE, + blend_state: Direct3D12::D3D12_BLEND_DESC, + sample_mask: u32, + rasterizer_state: Direct3D12::D3D12_RASTERIZER_DESC, + depth_stencil_state: Direct3D12::D3D12_DEPTH_STENCIL_DESC, + primitive_topology_type: Direct3D12::D3D12_PRIMITIVE_TOPOLOGY_TYPE, + rtv_formats: Direct3D12::D3D12_RT_FORMAT_ARRAY, + dsv_format: Dxgi::Common::DXGI_FORMAT, + sample_desc: Dxgi::Common::DXGI_SAMPLE_DESC, + node_mask: u32, + cached_pso: Direct3D12::D3D12_CACHED_PIPELINE_STATE, + flags: Direct3D12::D3D12_PIPELINE_STATE_FLAGS, +} +impl MeshShaderPipelineStateStream { + /// # Safety + /// + /// Returned bytes contain pointers into this struct, for them to be valid, + /// this struct may be at the same location. As if `as_bytes<'a>(&'a self) -> Vec + 'a` + pub unsafe fn to_bytes(&self) -> Vec { + use Direct3D12::*; + let mut bytes = Vec::new(); + + macro_rules! push_subobject { + ($subobject_type:expr, $data:expr) => {{ + // Ensure 8-byte alignment for the subobject start + let alignment = 8; + let aligned_length = bytes.len().next_multiple_of(alignment); + bytes.resize(aligned_length, 0); + + // Append the type tag (u32) + let tag: u32 = $subobject_type.0 as u32; + bytes.extend_from_slice(&tag.to_ne_bytes()); + + // Align the data + let obj_align = align_of_val(&$data); + let data_start = bytes.len().next_multiple_of(obj_align); + bytes.resize(data_start, 0); + + // Append the data itself + #[allow(clippy::ptr_as_ptr, trivial_casts)] + let data_ptr = &$data as *const _ as *const u8; + let data_size = size_of_val(&$data); + let slice = unsafe { core::slice::from_raw_parts(data_ptr, data_size) }; + bytes.extend_from_slice(slice); + }}; + } + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE, + self.root_signature + ); + if !self.task_shader.pShaderBytecode.is_null() { + push_subobject!(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_AS, self.task_shader); + } + push_subobject!(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MS, self.mesh_shader); + if !self.pixel_shader.pShaderBytecode.is_null() { + push_subobject!(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PS, self.pixel_shader); + } + push_subobject!(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_BLEND, self.blend_state); + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_MASK, + self.sample_mask + ); + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER, + self.rasterizer_state + ); + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL, + self.depth_stencil_state + ); + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY, + self.primitive_topology_type + ); + if self.rtv_formats.NumRenderTargets != 0 { + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS, + self.rtv_formats + ); + } + if self.dsv_format != Dxgi::Common::DXGI_FORMAT_UNKNOWN { + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT, + self.dsv_format + ); + } + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_DESC, + self.sample_desc + ); + if self.node_mask != 0 { + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_NODE_MASK, + self.node_mask + ); + } + if !self.cached_pso.pCachedBlob.is_null() { + push_subobject!( + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CACHED_PSO, + self.cached_pso + ); + } + push_subobject!(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_FLAGS, self.flags); + bytes + } +} From 2f7ebf1401abcc8a3cd53c32ab71a3a0794c1f5e Mon Sep 17 00:00:00 2001 From: Nils Hasenbanck Date: Thu, 25 Sep 2025 14:25:04 +0200 Subject: [PATCH 229/303] (Naga) Add support for Descriptor Runtime Indexing when ingesting SPIR-V (#8256) --- CHANGELOG.md | 1 + naga/src/front/spv/mod.rs | 2 + .../tests/in/spv/binding-arrays.runtime.slang | 19 ++++++ .../in/spv/binding-arrays.runtime.spvasm | 60 +++++++++++++++++++ naga/tests/in/spv/binding-arrays.runtime.toml | 4 ++ .../out/wgsl/spv-binding-arrays.runtime.wgsl | 24 ++++++++ 6 files changed, 110 insertions(+) create mode 100644 naga/tests/in/spv/binding-arrays.runtime.slang create mode 100644 naga/tests/in/spv/binding-arrays.runtime.spvasm create mode 100644 naga/tests/in/spv/binding-arrays.runtime.toml create mode 100644 naga/tests/out/wgsl/spv-binding-arrays.runtime.wgsl diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c138ac1dfc..f57189c3b98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -198,6 +198,7 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). - For custom Naga backend authors: `naga::proc::Namer` now accepts reserved keywords using two new dedicated types, `proc::{KeywordSet, CaseInsensitiveKeywordSet}`. By @kpreid in [#8136](https://github.com/gfx-rs/wgpu/pull/8136). - **BREAKING**: Previously the WGSL storage-texture format `rg11b10float` was incorrectly accepted and generated by naga, but now only accepts the the correct name `rg11b10ufloat` instead. By @ErikWDev in [#8219](https://github.com/gfx-rs/wgpu/pull/8219). - The [`source()`](https://doc.rust-lang.org/std/error/trait.Error.html#method.source) method of `ShaderError` no longer reports the error as its own source. By @andyleiserson in [#8258](https://github.com/gfx-rs/wgpu/pull/8258). +- naga correctly ingests SPIR-V that use descriptor runtime indexing, which in turn is correctly converted into WGSLs binding array. By @hasenbanck in [8256](https://github.com/gfx-rs/wgpu/pull/8256). #### DX12 diff --git a/naga/src/front/spv/mod.rs b/naga/src/front/spv/mod.rs index 2e54c74a213..803e52553dc 100644 --- a/naga/src/front/spv/mod.rs +++ b/naga/src/front/spv/mod.rs @@ -82,6 +82,7 @@ pub const SUPPORTED_CAPABILITIES: &[spirv::Capability] = &[ spirv::Capability::GroupNonUniformBallot, spirv::Capability::GroupNonUniformShuffle, spirv::Capability::GroupNonUniformShuffleRelative, + spirv::Capability::RuntimeDescriptorArray, // tricky ones spirv::Capability::UniformBufferArrayDynamicIndexing, spirv::Capability::StorageBufferArrayDynamicIndexing, @@ -90,6 +91,7 @@ pub const SUPPORTED_EXTENSIONS: &[&str] = &[ "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_vulkan_memory_model", "SPV_KHR_multiview", + "SPV_EXT_descriptor_indexing", "SPV_EXT_shader_atomic_float_add", "SPV_KHR_16bit_storage", ]; diff --git a/naga/tests/in/spv/binding-arrays.runtime.slang b/naga/tests/in/spv/binding-arrays.runtime.slang new file mode 100644 index 00000000000..6230fc9ced9 --- /dev/null +++ b/naga/tests/in/spv/binding-arrays.runtime.slang @@ -0,0 +1,19 @@ +// Compiled with: +// slangc -target spirv -profile spirv_1_5 -o naga/tests/in/spv/binding-arrays.runtime.spv naga/tests/in/spv/binding-arrays.runtime.slang +// Disassembled with: +// spirv-dis naga/tests/in/spv/binding-arrays.runtime.spv -o naga/tests/in/spv/binding-arrays.runtime.spvasm + +#language slang 2026 + +[[vk::binding(0, 0)]] var textures: Texture2D[]; +[[vk::binding(1, 0)]] var linear_sampler: SamplerState; + +struct VertexOutput { + var texture_coordinates: float2; + var texture_index: uint; +}; + +[[shader("pixel")]] +func main(input: VertexOutput) -> float4 { + return textures[input.texture_index].Sample(linear_sampler, input.texture_coordinates); +} diff --git a/naga/tests/in/spv/binding-arrays.runtime.spvasm b/naga/tests/in/spv/binding-arrays.runtime.spvasm new file mode 100644 index 00000000000..41fc2db6d62 --- /dev/null +++ b/naga/tests/in/spv/binding-arrays.runtime.spvasm @@ -0,0 +1,60 @@ +; SPIR-V +; Version: 1.5 +; Generator: Khronos Slang Compiler; 0 +; Bound: 33 +; Schema: 0 + OpCapability RuntimeDescriptorArray + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %textures %linear_sampler %entryPointParam_main %input_texture_coordinates %input_texture_index + OpExecutionMode %main OriginUpperLeft + OpSource Slang 1 + OpName %input_texture_coordinates "input.texture_coordinates" + OpName %input_texture_index "input.texture_index" + OpName %textures "textures" + OpName %linear_sampler "linear_sampler" + OpName %sampledImage "sampledImage" + OpName %sampled "sampled" + OpName %entryPointParam_main "entryPointParam_main" + OpName %main "main" + OpDecorate %input_texture_coordinates Location 0 + OpDecorate %input_texture_index Location 1 + OpDecorate %input_texture_index Flat + OpDecorate %textures Binding 0 + OpDecorate %textures DescriptorSet 0 + OpDecorate %linear_sampler Binding 1 + OpDecorate %linear_sampler DescriptorSet 0 + OpDecorate %entryPointParam_main Location 0 + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 +%_ptr_Input_v2float = OpTypePointer Input %v2float + %uint = OpTypeInt 32 0 +%_ptr_Input_uint = OpTypePointer Input %uint + %15 = OpTypeImage %float 2D 2 0 0 1 Unknown +%_runtimearr_15 = OpTypeRuntimeArray %15 +%_ptr_UniformConstant__runtimearr_15 = OpTypePointer UniformConstant %_runtimearr_15 +%_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15 + %22 = OpTypeSampler +%_ptr_UniformConstant_22 = OpTypePointer UniformConstant %22 + %26 = OpTypeSampledImage %15 + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float +%input_texture_coordinates = OpVariable %_ptr_Input_v2float Input +%input_texture_index = OpVariable %_ptr_Input_uint Input + %textures = OpVariable %_ptr_UniformConstant__runtimearr_15 UniformConstant +%linear_sampler = OpVariable %_ptr_UniformConstant_22 UniformConstant +%entryPointParam_main = OpVariable %_ptr_Output_v4float Output + %main = OpFunction %void None %3 + %4 = OpLabel + %7 = OpLoad %v2float %input_texture_coordinates + %11 = OpLoad %uint %input_texture_index + %19 = OpAccessChain %_ptr_UniformConstant_15 %textures %11 + %21 = OpLoad %15 %19 + %23 = OpLoad %22 %linear_sampler +%sampledImage = OpSampledImage %26 %21 %23 + %sampled = OpImageSampleImplicitLod %v4float %sampledImage %7 None + OpStore %entryPointParam_main %sampled + OpReturn + OpFunctionEnd diff --git a/naga/tests/in/spv/binding-arrays.runtime.toml b/naga/tests/in/spv/binding-arrays.runtime.toml new file mode 100644 index 00000000000..fd5664c637a --- /dev/null +++ b/naga/tests/in/spv/binding-arrays.runtime.toml @@ -0,0 +1,4 @@ +god_mode = true + +[spv-in] +adjust_coordinate_space = true diff --git a/naga/tests/out/wgsl/spv-binding-arrays.runtime.wgsl b/naga/tests/out/wgsl/spv-binding-arrays.runtime.wgsl new file mode 100644 index 00000000000..d3d1ebd0fff --- /dev/null +++ b/naga/tests/out/wgsl/spv-binding-arrays.runtime.wgsl @@ -0,0 +1,24 @@ +var inputtexture_coordinates_1: vec2; +var inputtexture_index_1: u32; +@group(0) @binding(0) +var textures: binding_array>; +@group(0) @binding(1) +var linear_sampler: sampler; +var entryPointParam_main: vec4; + +fn main_1() { + let _e5 = inputtexture_coordinates_1; + let _e6 = inputtexture_index_1; + let _e8 = textureSample(textures[_e6], linear_sampler, _e5); + entryPointParam_main = _e8; + return; +} + +@fragment +fn main(@location(0) inputtexture_coordinates: vec2, @location(1) @interpolate(flat) inputtexture_index: u32) -> @location(0) vec4 { + inputtexture_coordinates_1 = inputtexture_coordinates; + inputtexture_index_1 = inputtexture_index; + main_1(); + let _e5 = entryPointParam_main; + return _e5; +} From 990aef977e58c83e7b6d18c5f9a72ae1b343ea6b Mon Sep 17 00:00:00 2001 From: Xiaopeng Li Date: Thu, 25 Sep 2025 20:27:54 +0800 Subject: [PATCH 230/303] Expose external memory of vulkan texture (#8257) --- wgpu-hal/src/vulkan/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index c24217d2f78..e5b2dd49a91 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -963,6 +963,13 @@ impl Texture { pub unsafe fn raw_handle(&self) -> vk::Image { self.raw } + + /// # Safety + /// + /// - The external memory must not be manually freed + pub unsafe fn external_memory(&self) -> Option { + self.external_memory + } } #[derive(Debug)] From 1967900565e9c08d68daabd5b98c4b28bed8b8f4 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Thu, 25 Sep 2025 11:22:51 -0700 Subject: [PATCH 231/303] Encode commands on finish (#8220) Co-authored-by: Andreas Reich --- CHANGELOG.md | 1 + deno_webgpu/queue.rs | 2 +- tests/tests/wgpu-gpu/life_cycle.rs | 20 +- wgpu-core/src/command/clear.rs | 113 ++-- wgpu-core/src/command/compute.rs | 170 +++--- wgpu-core/src/command/encoder.rs | 35 +- wgpu-core/src/command/encoder_command.rs | 75 ++- wgpu-core/src/command/mod.rs | 495 ++++++++++++---- wgpu-core/src/command/pass.rs | 16 +- wgpu-core/src/command/query.rs | 161 +++--- wgpu-core/src/command/ray_tracing.rs | 329 ++++++----- wgpu-core/src/command/render.rs | 241 ++++---- wgpu-core/src/command/transfer.rs | 540 ++++++++---------- wgpu-core/src/command/transition_resources.rs | 104 ++-- wgpu-core/src/ray_tracing.rs | 52 +- wgpu-types/src/lib.rs | 4 +- wgpu/src/backend/wgpu_core.rs | 4 +- 17 files changed, 1367 insertions(+), 995 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f57189c3b98..fb156281c0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -170,6 +170,7 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). #### General +- Command encoding now happens when `CommandEncoder::finish` is called, not when the individual operations are requested. This does not affect the API, but may affect performance characteristics. By @andyleiserson in [#8220](https://github.com/gfx-rs/wgpu/pull/8220). - Prevent resources for acceleration structures being created if acceleration structures are not enabled. By @Vecvec in [#8036](https://github.com/gfx-rs/wgpu/pull/8036). - Validate that each `push_debug_group` pairs with exactly one `pop_debug_group`. By @andyleiserson in [#8048](https://github.com/gfx-rs/wgpu/pull/8048). - `set_viewport` now requires that the supplied minimum depth value is less than the maximum depth value. By @andyleiserson in [#8040](https://github.com/gfx-rs/wgpu/pull/8040). diff --git a/deno_webgpu/queue.rs b/deno_webgpu/queue.rs index 59dbffe461b..87fea8bac6a 100644 --- a/deno_webgpu/queue.rs +++ b/deno_webgpu/queue.rs @@ -140,7 +140,7 @@ impl GPUQueue { #[webidl] data_layout: GPUTexelCopyBufferLayout, #[webidl] size: GPUExtent3D, ) { - let destination = wgpu_core::command::TexelCopyTextureInfo { + let destination = wgpu_types::TexelCopyTextureInfo { texture: destination.texture.id, mip_level: destination.mip_level, origin: destination.origin.into(), diff --git a/tests/tests/wgpu-gpu/life_cycle.rs b/tests/tests/wgpu-gpu/life_cycle.rs index c7c5786b979..8fd628663c5 100644 --- a/tests/tests/wgpu-gpu/life_cycle.rs +++ b/tests/tests/wgpu-gpu/life_cycle.rs @@ -1,7 +1,5 @@ -use wgpu::{util::DeviceExt, Backends}; -use wgpu_test::{ - fail, gpu_test, FailureCase, GpuTestConfiguration, GpuTestInitializer, TestParameters, -}; +use wgpu::util::DeviceExt; +use wgpu_test::{fail, gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters}; pub fn all_tests(vec: &mut Vec) { vec.extend([ @@ -118,12 +116,7 @@ static TEXTURE_DESTROY: GpuTestConfiguration = GpuTestConfiguration::new() // submission fails gracefully. #[gpu_test] static BUFFER_DESTROY_BEFORE_SUBMIT: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters( - // https://github.com/gfx-rs/wgpu/issues/7854 - TestParameters::default() - .skip(FailureCase::backend_adapter(Backends::VULKAN, "llvmpipe")) - .enable_noop(), - ) + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { let buffer_source = ctx .device @@ -160,12 +153,7 @@ static BUFFER_DESTROY_BEFORE_SUBMIT: GpuTestConfiguration = GpuTestConfiguration // submission fails gracefully. #[gpu_test] static TEXTURE_DESTROY_BEFORE_SUBMIT: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters( - // https://github.com/gfx-rs/wgpu/issues/7854 - TestParameters::default() - .skip(FailureCase::backend_adapter(Backends::VULKAN, "llvmpipe")) - .enable_noop(), - ) + .parameters(TestParameters::default().enable_noop()) .run_sync(|ctx| { let descriptor = wgpu::TextureDescriptor { label: None, diff --git a/wgpu-core/src/command/clear.rs b/wgpu-core/src/command/clear.rs index 04d800e670e..5c8838f69e5 100644 --- a/wgpu-core/src/command/clear.rs +++ b/wgpu-core/src/command/clear.rs @@ -5,7 +5,7 @@ use core::ops::Range; use crate::command::Command as TraceCommand; use crate::{ api_log, - command::{CommandBufferMutable, CommandEncoder, EncoderStateError}, + command::{encoder::EncodingState, ArcCommand, EncoderStateError}, device::{DeviceError, MissingFeatures}, get_lowest_common_denom, global::Global, @@ -13,7 +13,7 @@ use crate::{ id::{BufferId, CommandEncoderId, TextureId}, init_tracker::{MemoryInitKind, TextureInitRange}, resource::{ - DestroyedResourceError, InvalidResourceError, Labeled, MissingBufferUsageError, + Buffer, DestroyedResourceError, InvalidResourceError, Labeled, MissingBufferUsageError, ParentDevice, RawResourceAccess, ResourceErrorIdent, Texture, TextureClearMode, }, snatch::SnatchGuard, @@ -118,8 +118,18 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), ClearError> { - clear_buffer(cmd_buf_data, hub, &cmd_enc, dst, offset, size) + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::ClearBuffer { dst, offset, size }); + } + + cmd_buf_data.push_with(|| -> Result<_, ClearError> { + Ok(ArcCommand::ClearBuffer { + dst: self.resolve_buffer_id(dst)?, + offset, + size, + }) }) } @@ -136,38 +146,38 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), ClearError> { - clear_texture_cmd(cmd_buf_data, hub, &cmd_enc, dst, subresource_range) + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::ClearTexture { + dst, + subresource_range: *subresource_range, + }); + } + + cmd_buf_data.push_with(|| -> Result<_, ClearError> { + Ok(ArcCommand::ClearTexture { + dst: self.resolve_texture_id(dst)?, + subresource_range: *subresource_range, + }) }) } } pub(super) fn clear_buffer( - cmd_buf_data: &mut CommandBufferMutable, - hub: &crate::hub::Hub, - cmd_enc: &Arc, - dst: BufferId, + state: &mut EncodingState, + dst_buffer: Arc, offset: BufferAddress, size: Option, ) -> Result<(), ClearError> { - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::ClearBuffer { dst, offset, size }); - } - - cmd_enc.device.check_is_valid()?; - - let dst_buffer = hub.buffers.get(dst).get()?; + dst_buffer.same_device(state.device)?; - dst_buffer.same_device_as(cmd_enc.as_ref())?; - - let dst_pending = cmd_buf_data - .trackers + let dst_pending = state + .tracker .buffers .set_single(&dst_buffer, wgt::BufferUses::COPY_DST); - let snatch_guard = dst_buffer.device.snatchable_lock.read(); - let dst_raw = dst_buffer.try_raw(&snatch_guard)?; + let dst_raw = dst_buffer.try_raw(state.snatch_guard)?; dst_buffer.check_usage(BufferUsages::COPY_DST)?; // Check if offset & size are valid. @@ -200,20 +210,19 @@ pub(super) fn clear_buffer( } // Mark dest as initialized. - cmd_buf_data.buffer_memory_init_actions.extend( - dst_buffer.initialization_status.read().create_action( + state + .buffer_memory_init_actions + .extend(dst_buffer.initialization_status.read().create_action( &dst_buffer, offset..end_offset, MemoryInitKind::ImplicitlyInitialized, - ), - ); + )); // actual hal barrier & operation - let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); - let cmd_buf_raw = cmd_buf_data.encoder.open()?; + let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, state.snatch_guard)); unsafe { - cmd_buf_raw.transition_buffers(dst_barrier.as_slice()); - cmd_buf_raw.clear_buffer(dst_raw, offset..end_offset); + state.raw_encoder.transition_buffers(dst_barrier.as_slice()); + state.raw_encoder.clear_buffer(dst_raw, offset..end_offset); } Ok(()) @@ -227,30 +236,15 @@ pub(super) fn clear_buffer( /// this function, is a lower-level function that encodes a texture clear /// operation without validating it. pub(super) fn clear_texture_cmd( - cmd_buf_data: &mut CommandBufferMutable, - hub: &crate::hub::Hub, - cmd_enc: &Arc, - dst: TextureId, + state: &mut EncodingState, + dst_texture: Arc, subresource_range: &ImageSubresourceRange, ) -> Result<(), ClearError> { - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::ClearTexture { - dst, - subresource_range: *subresource_range, - }); - } - - cmd_enc.device.check_is_valid()?; - - cmd_enc + dst_texture.same_device(state.device)?; + state .device .require_features(wgt::Features::CLEAR_TEXTURE)?; - let dst_texture = hub.textures.get(dst).get()?; - - dst_texture.same_device_as(cmd_enc.as_ref())?; - // Check if subresource aspects are valid. let clear_aspects = hal::FormatAspects::new(dst_texture.desc.format, subresource_range.aspect); if clear_aspects.is_empty() { @@ -283,23 +277,18 @@ pub(super) fn clear_texture_cmd( }); } - let device = &cmd_enc.device; - device.check_is_valid()?; - let (encoder, tracker) = cmd_buf_data.open_encoder_and_tracker()?; - - let snatch_guard = device.snatchable_lock.read(); clear_texture( &dst_texture, TextureInitRange { mip_range: subresource_mip_range, layer_range: subresource_layer_range, }, - encoder, - &mut tracker.textures, - &device.alignments, - device.zero_buffer.as_ref(), - &snatch_guard, - device.instance_flags, + state.raw_encoder, + &mut state.tracker.textures, + &state.device.alignments, + state.device.zero_buffer.as_ref(), + state.snatch_guard, + state.device.instance_flags, )?; Ok(()) diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index dd0258797a1..515ca76e8f6 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -5,13 +5,8 @@ use wgt::{ }; use alloc::{borrow::Cow, boxed::Box, sync::Arc, vec::Vec}; -use core::{fmt, str}; +use core::{convert::Infallible, fmt, str}; -use crate::command::{ - encoder::EncodingState, pass, CommandBufferMutable, CommandEncoder, DebugGroupError, - EncoderStateError, PassStateError, TimestampWritesError, -}; -use crate::resource::DestroyedResourceError; use crate::{binding_model::BindError, resource::RawResourceAccess}; use crate::{ binding_model::{LateMinBufferBindingSizeMismatch, PushConstantUploadError}, @@ -35,6 +30,14 @@ use crate::{ track::{ResourceUsageCompatibilityError, Tracker, TrackerIndex}, Label, }; +use crate::{command::InnerCommandEncoder, resource::DestroyedResourceError}; +use crate::{ + command::{ + encoder::EncodingState, pass, ArcCommand, CommandEncoder, DebugGroupError, + EncoderStateError, PassStateError, TimestampWritesError, + }, + device::Device, +}; pub type ComputeBasePass = BasePass; @@ -254,10 +257,10 @@ impl WebGpuError for ComputePassError { } } -struct State<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { +struct State<'scope, 'snatch_guard, 'cmd_enc> { pipeline: Option>, - pass: pass::PassState<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder>, + pass: pass::PassState<'scope, 'snatch_guard, 'cmd_enc>, active_query: Option<(Arc, u32)>, @@ -266,9 +269,7 @@ struct State<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { intermediate_trackers: Tracker, } -impl<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> - State<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> -{ +impl<'scope, 'snatch_guard, 'cmd_enc> State<'scope, 'snatch_guard, 'cmd_enc> { fn is_ready(&self) -> Result<(), DispatchError> { if let Some(pipeline) = self.pipeline.as_ref() { self.pass.binder.check_compatibility(pipeline.as_ref())?; @@ -428,7 +429,7 @@ impl Global { pub fn compute_pass_end_with_unresolved_commands( &self, encoder_id: id::CommandEncoderId, - base: BasePass, + base: BasePass, timestamp_writes: Option<&PassTimestampWrites>, ) { #[cfg(feature = "trace")] @@ -494,57 +495,58 @@ impl Global { let cmd_enc = pass.parent.take().ok_or(EncoderStateError::Ended)?; let mut cmd_buf_data = cmd_enc.data.lock(); - if let Some(err) = pass.base.error.take() { - if matches!( - err, - ComputePassError { - inner: ComputePassErrorInner::EncoderState(EncoderStateError::Ended), - scope: _, - } - ) { - // If the encoder was already finished at time of pass creation, - // then it was not put in the locked state, so we need to - // generate a validation error here due to the encoder not being - // locked. The encoder already has a copy of the error. - return Err(EncoderStateError::Ended); - } else { - // If the pass is invalid, invalidate the parent encoder and return. - // Since we do not track the state of an invalid encoder, it is not - // necessary to unlock it. - cmd_buf_data.invalidate(err); - return Ok(()); - } + cmd_buf_data.unlock_encoder()?; + + let base = pass.base.take(); + + if matches!( + base, + Err(ComputePassError { + inner: ComputePassErrorInner::EncoderState(EncoderStateError::Ended), + scope: _, + }) + ) { + // If the encoder was already finished at time of pass creation, + // then it was not put in the locked state, so we need to + // generate a validation error here and now due to the encoder not + // being locked. The encoder already holds an error from when the + // pass was opened, or earlier. + // + // All other errors are propagated to the encoder within `push_with`, + // and will be reported later. + return Err(EncoderStateError::Ended); } - cmd_buf_data.unlock_and_record(|cmd_buf_data| -> Result<(), ComputePassError> { - encode_compute_pass(cmd_buf_data, &cmd_enc, pass) + cmd_buf_data.push_with(|| -> Result<_, ComputePassError> { + Ok(ArcCommand::RunComputePass { + pass: base?, + timestamp_writes: pass.timestamp_writes.take(), + }) }) } } -fn encode_compute_pass( - cmd_buf_data: &mut CommandBufferMutable, - cmd_enc: &Arc, - pass: &mut ComputePass, +pub(super) fn encode_compute_pass( + parent_state: &mut EncodingState, + mut base: BasePass, + mut timestamp_writes: Option, ) -> Result<(), ComputePassError> { let pass_scope = PassErrorScope::Pass; - let device = &cmd_enc.device; - device.check_is_valid().map_pass_err(pass_scope)?; - - let base = &mut pass.base; - - let encoder = &mut cmd_buf_data.encoder; + let device = parent_state.device; // We automatically keep extending command buffers over time, and because // we want to insert a command buffer _before_ what we're about to record, // we need to make sure to close the previous one. - encoder.close_if_open().map_pass_err(pass_scope)?; - let raw_encoder = encoder + parent_state + .raw_encoder + .close_if_open() + .map_pass_err(pass_scope)?; + let raw_encoder = parent_state + .raw_encoder .open_pass(base.label.as_deref()) .map_pass_err(pass_scope)?; - let snatch_guard = device.snatchable_lock.read(); let mut debug_scope_depth = 0; let mut state = State { @@ -554,23 +556,20 @@ fn encode_compute_pass( base: EncodingState { device, raw_encoder, - tracker: &mut cmd_buf_data.trackers, - buffer_memory_init_actions: &mut cmd_buf_data.buffer_memory_init_actions, - texture_memory_actions: &mut cmd_buf_data.texture_memory_actions, - as_actions: &mut cmd_buf_data.as_actions, - indirect_draw_validation_resources: &mut cmd_buf_data - .indirect_draw_validation_resources, - snatch_guard: &snatch_guard, + tracker: parent_state.tracker, + buffer_memory_init_actions: parent_state.buffer_memory_init_actions, + texture_memory_actions: parent_state.texture_memory_actions, + as_actions: parent_state.as_actions, + temp_resources: parent_state.temp_resources, + indirect_draw_validation_resources: parent_state.indirect_draw_validation_resources, + snatch_guard: parent_state.snatch_guard, debug_scope_depth: &mut debug_scope_depth, }, binder: Binder::new(), temp_offsets: Vec::new(), dynamic_offset_count: 0, - pending_discard_init_fixups: SurfacesInDiscardState::new(), - scope: device.new_usage_scope(), - string_offset: 0, }, active_query: None, @@ -580,7 +579,7 @@ fn encode_compute_pass( intermediate_trackers: Tracker::new(), }; - let indices = &state.pass.base.device.tracker_indices; + let indices = &device.tracker_indices; state .pass .base @@ -595,10 +594,8 @@ fn encode_compute_pass( .set_size(indices.textures.size()); let timestamp_writes: Option> = - if let Some(tw) = pass.timestamp_writes.take() { - tw.query_set - .same_device_as(cmd_enc.as_ref()) - .map_pass_err(pass_scope)?; + if let Some(tw) = timestamp_writes.take() { + tw.query_set.same_device(device).map_pass_err(pass_scope)?; let query_set = state .pass @@ -658,7 +655,7 @@ fn encode_compute_pass( let scope = PassErrorScope::SetBindGroup; pass::set_bind_group::( &mut state.pass, - cmd_enc.as_ref(), + device, &base.dynamic_offsets, index, num_dynamic_offsets, @@ -669,7 +666,7 @@ fn encode_compute_pass( } ArcComputeCommand::SetPipeline(pipeline) => { let scope = PassErrorScope::SetPipelineCompute; - set_pipeline(&mut state, cmd_enc.as_ref(), pipeline).map_pass_err(scope)?; + set_pipeline(&mut state, device, pipeline).map_pass_err(scope)?; } ArcComputeCommand::SetPushConstant { offset, @@ -699,8 +696,7 @@ fn encode_compute_pass( } ArcComputeCommand::DispatchIndirect { buffer, offset } => { let scope = PassErrorScope::Dispatch { indirect: true }; - dispatch_indirect(&mut state, cmd_enc.as_ref(), buffer, offset) - .map_pass_err(scope)?; + dispatch_indirect(&mut state, device, buffer, offset).map_pass_err(scope)?; } ArcComputeCommand::PushDebugGroup { color: _, len } => { pass::push_debug_group(&mut state.pass, &base.string_data, len); @@ -720,8 +716,8 @@ fn encode_compute_pass( let scope = PassErrorScope::WriteTimestamp; pass::write_timestamp::( &mut state.pass, - cmd_enc.as_ref(), - None, + device, + None, // compute passes do not attempt to coalesce query resets query_set, query_index, ) @@ -736,7 +732,7 @@ fn encode_compute_pass( query_set, state.pass.base.raw_encoder, &mut state.pass.base.tracker.query_sets, - cmd_enc.as_ref(), + device, query_index, None, &mut state.active_query, @@ -763,23 +759,22 @@ fn encode_compute_pass( } let State { - pass: - pass::PassState { - base: EncodingState { tracker, .. }, - pending_discard_init_fixups, - .. - }, + pass: pass::PassState { + pending_discard_init_fixups, + .. + }, intermediate_trackers, .. } = state; // Stop the current command encoder. - encoder.close().map_pass_err(pass_scope)?; + parent_state.raw_encoder.close().map_pass_err(pass_scope)?; // Create a new command encoder, which we will insert _before_ the body of the compute pass. // // Use that buffer to insert barriers and clear discarded images. - let transit = encoder + let transit = parent_state + .raw_encoder .open_pass(hal_label( Some("(wgpu internal) Pre Pass"), device.instance_flags, @@ -788,28 +783,31 @@ fn encode_compute_pass( fixup_discarded_surfaces( pending_discard_init_fixups.into_iter(), transit, - &mut tracker.textures, + &mut parent_state.tracker.textures, device, - &snatch_guard, + parent_state.snatch_guard, ); CommandEncoder::insert_barriers_from_tracker( transit, - tracker, + parent_state.tracker, &intermediate_trackers, - &snatch_guard, + parent_state.snatch_guard, ); // Close the command encoder, and swap it with the previous. - encoder.close_and_swap().map_pass_err(pass_scope)?; + parent_state + .raw_encoder + .close_and_swap() + .map_pass_err(pass_scope)?; Ok(()) } fn set_pipeline( state: &mut State, - cmd_enc: &CommandEncoder, + device: &Arc, pipeline: Arc, ) -> Result<(), ComputePassErrorInner> { - pipeline.same_device_as(cmd_enc)?; + pipeline.same_device(device)?; state.pipeline = Some(pipeline.clone()); @@ -886,11 +884,11 @@ fn dispatch(state: &mut State, groups: [u32; 3]) -> Result<(), ComputePassErrorI fn dispatch_indirect( state: &mut State, - cmd_enc: &CommandEncoder, + device: &Arc, buffer: Arc, offset: u64, ) -> Result<(), ComputePassErrorInner> { - buffer.same_device_as(cmd_enc)?; + buffer.same_device(device)?; state.is_ready()?; diff --git a/wgpu-core/src/command/encoder.rs b/wgpu-core/src/command/encoder.rs index 4d0455e1892..19222c6e3ad 100644 --- a/wgpu-core/src/command/encoder.rs +++ b/wgpu-core/src/command/encoder.rs @@ -1,22 +1,45 @@ use alloc::{sync::Arc, vec::Vec}; use crate::{ - command::memory_init::CommandBufferTextureMemoryActions, device::Device, - init_tracker::BufferInitTrackerAction, ray_tracing::AsAction, snatch::SnatchGuard, + command::memory_init::CommandBufferTextureMemoryActions, + device::{queue::TempResource, Device}, + init_tracker::BufferInitTrackerAction, + ray_tracing::AsAction, + snatch::SnatchGuard, track::Tracker, }; -/// State applicable when encoding commands onto a compute pass, or onto a -/// render pass, or directly with a command encoder. -pub(crate) struct EncodingState<'snatch_guard, 'cmd_enc, 'raw_encoder> { +/// State applicable when encoding commands onto a compute pass, render pass, or +/// directly to a command encoder. +/// +/// Most encoding routines just want to receive an open encoder, write +/// command(s) to it, and leave it open for whatever is next. In this case the +/// `E` type parameter has the default value of `dyn hal::DynCommandEncoder`. To +/// avoid confusion about encoder state, we set the convention that _the encoder +/// in an `EncodingState` holding a bare HAL reference must always be open_. +/// +/// Compute and render passes are more complicated. Because they record a +/// command buffer for a housekeeping pre-pass which is inserted before the pass +/// itself, the first thing they will do is close and reopen the encoder if it +/// is already open. Unnecessary empty HAL passes can be avoided by passing them +/// the encoder in whatever state it happens to be. In this case, `E` is +/// `InnerCommandEncoder`, which tracks the state of the encoder. The callee +/// (the render or compute pass) will open and close the encoder as necessary. +/// +/// This structure is not supported by cbindgen because it contains a trait +/// object reference. +/// +/// cbindgen:ignore +pub(crate) struct EncodingState<'snatch_guard, 'cmd_enc, E: ?Sized = dyn hal::DynCommandEncoder> { pub(crate) device: &'cmd_enc Arc, - pub(crate) raw_encoder: &'raw_encoder mut dyn hal::DynCommandEncoder, + pub(crate) raw_encoder: &'cmd_enc mut E, pub(crate) tracker: &'cmd_enc mut Tracker, pub(crate) buffer_memory_init_actions: &'cmd_enc mut Vec, pub(crate) texture_memory_actions: &'cmd_enc mut CommandBufferTextureMemoryActions, pub(crate) as_actions: &'cmd_enc mut Vec, + pub(crate) temp_resources: &'cmd_enc mut Vec, pub(crate) indirect_draw_validation_resources: &'cmd_enc mut crate::indirect_validation::DrawResources, diff --git a/wgpu-core/src/command/encoder_command.rs b/wgpu-core/src/command/encoder_command.rs index 058caed025c..092228099bc 100644 --- a/wgpu-core/src/command/encoder_command.rs +++ b/wgpu-core/src/command/encoder_command.rs @@ -1,8 +1,11 @@ use core::convert::Infallible; -use alloc::{string::String, vec::Vec}; +use alloc::{string::String, sync::Arc, vec::Vec}; -use crate::id; +use crate::{ + id, + resource::{Buffer, QuerySet, Texture}, +}; #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -68,3 +71,71 @@ pub enum Command { tlas: Vec, }, } + +#[derive(Clone, Debug)] +pub enum ArcCommand { + CopyBufferToBuffer { + src: Arc, + src_offset: wgt::BufferAddress, + dst: Arc, + dst_offset: wgt::BufferAddress, + size: Option, + }, + CopyBufferToTexture { + src: wgt::TexelCopyBufferInfo>, + dst: wgt::TexelCopyTextureInfo>, + size: wgt::Extent3d, + }, + CopyTextureToBuffer { + src: wgt::TexelCopyTextureInfo>, + dst: wgt::TexelCopyBufferInfo>, + size: wgt::Extent3d, + }, + CopyTextureToTexture { + src: wgt::TexelCopyTextureInfo>, + dst: wgt::TexelCopyTextureInfo>, + size: wgt::Extent3d, + }, + ClearBuffer { + dst: Arc, + offset: wgt::BufferAddress, + size: Option, + }, + ClearTexture { + dst: Arc, + subresource_range: wgt::ImageSubresourceRange, + }, + WriteTimestamp { + query_set: Arc, + query_index: u32, + }, + ResolveQuerySet { + query_set: Arc, + start_query: u32, + query_count: u32, + destination: Arc, + destination_offset: wgt::BufferAddress, + }, + PushDebugGroup(String), + PopDebugGroup, + InsertDebugMarker(String), + RunComputePass { + pass: super::BasePass, + timestamp_writes: Option, + }, + RunRenderPass { + pass: super::BasePass, + color_attachments: super::ArcRenderPassColorAttachmentArray, + depth_stencil_attachment: Option, + timestamp_writes: Option, + occlusion_query_set: Option>, + }, + BuildAccelerationStructures { + blas: Vec, + tlas: Vec, + }, + TransitionResources { + buffer_transitions: Vec>>, + texture_transitions: Vec>>, + }, +} diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 29b1c7da267..887c19fb357 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -1,3 +1,13 @@ +//! # Command Encoding +//! +//! TODO: High-level description of command encoding. +//! +//! The convention in this module is that functions accepting a [`&mut dyn +//! hal::DynCommandEncoder`] are low-level helpers and may assume the encoder is +//! in the open state, ready to encode commands. Encoders that are not open +//! should be nested within some other container that provides additional +//! state tracking, like [`InnerCommandEncoder`]. + mod allocator; mod bind; mod bundle; @@ -19,22 +29,37 @@ mod transfer; mod transition_resources; use alloc::{borrow::ToOwned as _, boxed::Box, string::String, sync::Arc, vec::Vec}; +use core::convert::Infallible; use core::mem::{self, ManuallyDrop}; use core::ops; pub(crate) use self::clear::clear_texture; pub use self::{ - bundle::*, clear::ClearError, compute::*, compute_command::ComputeCommand, draw::*, - encoder_command::Command, query::*, render::*, render_command::RenderCommand, transfer::*, + bundle::*, + clear::ClearError, + compute::*, + compute_command::{ArcComputeCommand, ComputeCommand}, + draw::*, + encoder_command::{ArcCommand, Command}, + query::*, + render::*, + render_command::{ArcRenderCommand, RenderCommand}, + transfer::*, }; pub(crate) use allocator::CommandAllocator; pub(crate) use timestamp_writes::ArcPassTimestampWrites; pub use timestamp_writes::PassTimestampWrites; -use self::memory_init::CommandBufferTextureMemoryActions; +use self::{ + clear::{clear_buffer, clear_texture_cmd}, + memory_init::CommandBufferTextureMemoryActions, + ray_tracing::build_acceleration_structures, + transition_resources::transition_resources, +}; use crate::binding_model::BindingError; +use crate::command::encoder::EncodingState; use crate::command::transition_resources::TransitionResourcesError; use crate::device::queue::TempResource; use crate::device::{Device, DeviceError, MissingFeatures}; @@ -123,12 +148,21 @@ pub(crate) enum CommandEncoderStatus { } impl CommandEncoderStatus { - /// Record commands using the supplied closure. + #[cfg(feature = "trace")] + fn trace(&mut self) -> Option<&mut Vec> { + match self { + Self::Recording(cmd_buf_data) => cmd_buf_data.trace_commands.as_mut(), + _ => None, + } + } + + /// Push a command provided by a closure onto the encoder. /// /// If the encoder is in the [`Self::Recording`] state, calls the closure to - /// record commands. If the closure returns an error, stores that error in - /// the encoder for later reporting when `finish()` is called. Returns - /// `Ok(())` even if the closure returned an error. + /// obtain a command, and pushes it onto the encoder. If the closure returns + /// an error, stores that error in the encoder for later reporting when + /// `finish()` is called. Returns `Ok(())` even if the closure returned an + /// error. /// /// If the encoder is not in the [`Self::Recording`] state, the closure will /// not be called and nothing will be recorded. The encoder will be @@ -137,7 +171,51 @@ impl CommandEncoderStatus { /// returns `Ok(())`. /// /// [ves]: https://www.w3.org/TR/webgpu/#abstract-opdef-validate-the-encoder-state - fn record_with< + fn push_with Result, E: Clone + Into>( + &mut self, + f: F, + ) -> Result<(), EncoderStateError> { + match self { + Self::Recording(cmd_buf_data) => { + match f() { + Ok(cmd) => cmd_buf_data.commands.push(cmd), + Err(err) => { + self.invalidate(err); + } + } + Ok(()) + } + Self::Locked(_) => { + // Invalidate the encoder and do not record anything, but do not + // return an immediate validation error. + self.invalidate(EncoderStateError::Locked); + Ok(()) + } + // Encoder is ended. Invalidate the encoder, do not record anything, + // and return an immediate validation error. + Self::Finished(_) => Err(self.invalidate(EncoderStateError::Ended)), + Self::Consumed => Err(EncoderStateError::Ended), + // Encoder is already invalid. Do not record anything, but do not + // return an immediate validation error. + Self::Error(_) => Ok(()), + Self::Transitioning => unreachable!(), + } + } + + /// Call a closure with the inner command buffer structure. + /// + /// If the encoder is in the [`Self::Recording`] state, calls the provided + /// closure. If the closure returns an error, stores that error in the + /// encoder for later reporting when `finish()` is called. Returns `Ok(())` + /// even if the closure returned an error. + /// + /// If the encoder is not in the [`Self::Recording`] state, the closure will + /// not be called. The encoder will be invalidated (if it is not already). + /// If the error is a [validation error that should be raised + /// immediately][ves], returns it in `Err`, otherwise, returns `Ok(())`. + /// + /// [ves]: https://www.w3.org/TR/webgpu/#abstract-opdef-validate-the-encoder-state + fn with_buffer< F: FnOnce(&mut CommandBufferMutable) -> Result<(), E>, E: Clone + Into, >( @@ -193,7 +271,7 @@ impl CommandEncoderStatus { } } - #[cfg(feature = "trace")] + #[cfg(all(feature = "trace", any(feature = "serde", feature = "replay")))] fn get_inner(&mut self) -> &mut CommandBufferMutable { match self { Self::Locked(inner) | Self::Finished(inner) | Self::Recording(inner) => inner, @@ -210,7 +288,7 @@ impl CommandEncoderStatus { /// Locks the encoder by putting it in the [`Self::Locked`] state. /// /// Render or compute passes call this on start. At the end of the pass, - /// they call [`Self::unlock_and_record`] to put the [`CommandBuffer`] back + /// they call [`Self::unlock_encoder`] to put the [`CommandBuffer`] back /// into the [`Self::Recording`] state. fn lock_encoder(&mut self) -> Result<(), EncoderStateError> { match mem::replace(self, Self::Transitioning) { @@ -238,32 +316,19 @@ impl CommandEncoderStatus { } } - /// Unlocks the [`CommandBuffer`] and puts it back into the - /// [`Self::Recording`] state, then records commands using the supplied - /// closure. + /// Unlocks the encoder and puts it back into the [`Self::Recording`] state. /// /// This function is the unlocking counterpart to [`Self::lock_encoder`]. It /// is only valid to call this function if the encoder is in the /// [`Self::Locked`] state. /// - /// If the closure returns an error, stores that error in the encoder for - /// later reporting when `finish()` is called. Returns `Ok(())` even if the - /// closure returned an error. - /// - /// If the encoder is not in the [`Self::Locked`] state, the closure will - /// not be called and nothing will be recorded. If a validation error should - /// be raised immediately, returns it in `Err`, otherwise, returns `Ok(())`. - fn unlock_and_record< - F: FnOnce(&mut CommandBufferMutable) -> Result<(), E>, - E: Clone + Into, - >( - &mut self, - f: F, - ) -> Result<(), EncoderStateError> { + /// If the encoder is in a state other than [`Self::Locked`] and a + /// validation error should be raised immediately, returns it in `Err`, + /// otherwise, stores the error in the encoder and returns `Ok(())`. + fn unlock_encoder(&mut self) -> Result<(), EncoderStateError> { match mem::replace(self, Self::Transitioning) { Self::Locked(inner) => { *self = Self::Recording(inner); - RecordingGuard { inner: self }.record(f); Ok(()) } st @ Self::Finished(_) => { @@ -279,8 +344,8 @@ impl CommandEncoderStatus { Err(EncoderStateError::Ended) } st @ Self::Error(_) => { - // Encoder is invalid. Do not record anything, but do not - // return an immediate validation error. + // Encoder is already invalid. The error will be reported by + // `CommandEncoder.finish`. *self = st; Ok(()) } @@ -292,18 +357,10 @@ impl CommandEncoderStatus { // Replace our state with `Consumed`, and return either the inner // state or an error, to be transferred to the command buffer. match mem::replace(self, Self::Consumed) { - Self::Recording(mut inner) => { - if let Err(err) = inner.encoder.close_if_open() { - Self::Error(err.into()) - } else if inner.debug_scope_depth > 0 { - Self::Error(CommandEncoderError::DebugGroupError( - DebugGroupError::MissingPop, - )) - } else { - // Note: if we want to stop tracking the swapchain texture view, - // this is the place to do it. - Self::Finished(inner) - } + Self::Recording(inner) => { + // Nothing should have opened the encoder yet. + assert!(!inner.encoder.is_open); + Self::Finished(inner) } Self::Consumed | Self::Finished(_) => Self::Error(EncoderStateError::Ended.into()), Self::Locked(_) => Self::Error(EncoderStateError::Locked.into()), @@ -574,6 +631,22 @@ impl InnerCommandEncoder { Ok(()) } + /// If the command encoder is not open, begin recording a new command buffer. + /// + /// If the command encoder was already open, does nothing. + /// + /// In both cases, returns a reference to the raw encoder. + fn open_if_closed(&mut self) -> Result<&mut dyn hal::DynCommandEncoder, DeviceError> { + if !self.is_open { + self.is_open = true; + let hal_label = hal_label(Some(self.label.as_str()), self.device.instance_flags); + unsafe { self.raw.begin_encoding(hal_label) } + .map_err(|e| self.device.handle_hal_error(e))?; + } + + Ok(self.raw.as_mut()) + } + /// Begin recording a new command buffer, if we haven't already. /// /// The underlying hal encoder is put in the "recording" state. @@ -588,7 +661,7 @@ impl InnerCommandEncoder { Ok(self.raw.as_mut()) } - /// Begin recording a new command buffer for a render pass, with + /// Begin recording a new command buffer for a render or compute pass, with /// its own label. /// /// The underlying hal encoder is put in the "recording" state. @@ -661,22 +734,13 @@ pub struct CommandBufferMutable { indirect_draw_validation_resources: crate::indirect_validation::DrawResources, - debug_scope_depth: u32, + pub(crate) commands: Vec, #[cfg(feature = "trace")] pub(crate) trace_commands: Option>, } impl CommandBufferMutable { - pub(crate) fn open_encoder_and_tracker( - &mut self, - ) -> Result<(&mut dyn hal::DynCommandEncoder, &mut Tracker), DeviceError> { - let encoder = self.encoder.open()?; - let tracker = &mut self.trackers; - - Ok((encoder, tracker)) - } - pub(crate) fn into_baked_commands(self) -> BakedCommands { BakedCommands { encoder: self.encoder, @@ -735,7 +799,7 @@ impl CommandEncoder { temp_resources: Default::default(), indirect_draw_validation_resources: crate::indirect_validation::DrawResources::new(device.clone()), - debug_scope_depth: 0, + commands: Vec::new(), #[cfg(feature = "trace")] trace_commands: if device.trace.lock().is_some() { Some(Vec::new()) @@ -883,6 +947,10 @@ pub struct BasePass { pub error: Option, /// The stream of commands. + /// + /// The commands are moved out of this vector when the pass is ended (i.e. + /// at the same time that `parent` is taken out of the + /// `ComputePass`/`RenderPass`). pub commands: Vec, /// Dynamic offsets consumed by [`SetBindGroup`] commands in `commands`. @@ -926,6 +994,26 @@ impl BasePass { push_constant_data: Vec::new(), } } + + /// Takes the commands from the pass, or returns an error if the pass is + /// invalid. + /// + /// This is called when the pass is ended, at the same time that the + /// `parent` member of the `ComputePass` or `RenderPass` containing the pass + /// is taken. + fn take(&mut self) -> Result, E> { + match self.error.as_ref() { + Some(err) => Err(err.clone()), + None => Ok(BasePass { + label: self.label.clone(), + error: None, + commands: mem::take(&mut self.commands), + dynamic_offsets: mem::take(&mut self.dynamic_offsets), + string_data: mem::take(&mut self.string_data), + push_constant_data: mem::take(&mut self.push_constant_data), + }), + } + } } /// Checks the state of a [`compute::ComputePass`] or [`render::RenderPass`] and @@ -1169,20 +1257,21 @@ impl Global { &self, buffer_id: Id, ) -> Result, InvalidResourceError> { - let hub = &self.hub; - let buffer = hub.buffers.get(buffer_id).get()?; + self.hub.buffers.get(buffer_id).get() + } - Ok(buffer) + fn resolve_texture_id( + &self, + texture_id: Id, + ) -> Result, InvalidResourceError> { + self.hub.textures.get(texture_id).get() } fn resolve_query_set( &self, query_set_id: Id, ) -> Result, InvalidResourceError> { - let hub = &self.hub; - let query_set = hub.query_sets.get(query_set_id).get()?; - - Ok(query_set) + self.hub.query_sets.get(query_set_id).get() } pub fn command_encoder_finish( @@ -1196,14 +1285,196 @@ impl Global { let hub = &self.hub; let cmd_enc = hub.command_encoders.get(encoder_id); + let mut cmd_enc_status = cmd_enc.data.lock(); - let data = cmd_enc.data.lock().finish(); + let res = match cmd_enc_status.finish() { + CommandEncoderStatus::Finished(cmd_buf_data) => Ok(cmd_buf_data), + CommandEncoderStatus::Error(err) => Err(err), + _ => unreachable!(), + }; - // Errors related to destroyed resources are not reported until the - // command buffer is submitted. - let error = match data { - CommandEncoderStatus::Error(ref e) if !e.is_destroyed_error() => Some(e.clone()), - _ => None, + let res = res.and_then(|mut cmd_buf_data| { + cmd_enc.device.check_is_valid()?; + let snatch_guard = cmd_enc.device.snatchable_lock.read(); + let mut debug_scope_depth = 0; + + let mut commands = mem::take(&mut cmd_buf_data.commands); + for command in commands.drain(..) { + if matches!( + command, + ArcCommand::RunRenderPass { .. } | ArcCommand::RunComputePass { .. } + ) { + // Compute passes and render passes can accept either an + // open or closed encoder. This state object holds an + // `InnerCommandEncoder`. See the documentation of + // [`EncodingState`]. + let mut state = EncodingState { + device: &cmd_enc.device, + raw_encoder: &mut cmd_buf_data.encoder, + tracker: &mut cmd_buf_data.trackers, + buffer_memory_init_actions: &mut cmd_buf_data.buffer_memory_init_actions, + texture_memory_actions: &mut cmd_buf_data.texture_memory_actions, + as_actions: &mut cmd_buf_data.as_actions, + temp_resources: &mut cmd_buf_data.temp_resources, + indirect_draw_validation_resources: &mut cmd_buf_data + .indirect_draw_validation_resources, + snatch_guard: &snatch_guard, + debug_scope_depth: &mut debug_scope_depth, + }; + + match command { + ArcCommand::RunRenderPass { + pass, + color_attachments, + depth_stencil_attachment, + timestamp_writes, + occlusion_query_set, + } => { + encode_render_pass( + &mut state, + pass, + color_attachments, + depth_stencil_attachment, + timestamp_writes, + occlusion_query_set, + )?; + } + ArcCommand::RunComputePass { + pass, + timestamp_writes, + } => { + encode_compute_pass(&mut state, pass, timestamp_writes)?; + } + _ => unreachable!(), + } + } else { + // All the other non-pass encoding routines assume the + // encoder is open, so open it if necessary. This state + // object holds an `&mut dyn hal::DynCommandEncoder`. By + // convention, a bare HAL encoder reference in + // [`EncodingState`] must always be an open encoder. + let raw_encoder = cmd_buf_data.encoder.open_if_closed()?; + let mut state = EncodingState { + device: &cmd_enc.device, + raw_encoder, + tracker: &mut cmd_buf_data.trackers, + buffer_memory_init_actions: &mut cmd_buf_data.buffer_memory_init_actions, + texture_memory_actions: &mut cmd_buf_data.texture_memory_actions, + as_actions: &mut cmd_buf_data.as_actions, + temp_resources: &mut cmd_buf_data.temp_resources, + indirect_draw_validation_resources: &mut cmd_buf_data + .indirect_draw_validation_resources, + snatch_guard: &snatch_guard, + debug_scope_depth: &mut debug_scope_depth, + }; + match command { + ArcCommand::CopyBufferToBuffer { + src, + src_offset, + dst, + dst_offset, + size, + } => { + copy_buffer_to_buffer( + &mut state, &src, src_offset, &dst, dst_offset, size, + )?; + } + ArcCommand::CopyBufferToTexture { src, dst, size } => { + copy_buffer_to_texture(&mut state, &src, &dst, &size)?; + } + ArcCommand::CopyTextureToBuffer { src, dst, size } => { + copy_texture_to_buffer(&mut state, &src, &dst, &size)?; + } + ArcCommand::CopyTextureToTexture { src, dst, size } => { + copy_texture_to_texture(&mut state, &src, &dst, &size)?; + } + ArcCommand::ClearBuffer { dst, offset, size } => { + clear_buffer(&mut state, dst, offset, size)?; + } + ArcCommand::ClearTexture { + dst, + subresource_range, + } => { + clear_texture_cmd(&mut state, dst, &subresource_range)?; + } + ArcCommand::WriteTimestamp { + query_set, + query_index, + } => { + write_timestamp(&mut state, query_set, query_index)?; + } + ArcCommand::ResolveQuerySet { + query_set, + start_query, + query_count, + destination, + destination_offset, + } => { + resolve_query_set( + &mut state, + query_set, + start_query, + query_count, + destination, + destination_offset, + )?; + } + ArcCommand::PushDebugGroup(label) => { + push_debug_group(&mut state, &label)?; + } + ArcCommand::PopDebugGroup => { + pop_debug_group(&mut state)?; + } + ArcCommand::InsertDebugMarker(label) => { + insert_debug_marker(&mut state, &label)?; + } + ArcCommand::BuildAccelerationStructures { blas, tlas } => { + build_acceleration_structures(&mut state, blas, tlas)?; + } + ArcCommand::TransitionResources { + buffer_transitions, + texture_transitions, + } => { + transition_resources( + &mut state, + buffer_transitions, + texture_transitions, + )?; + } + ArcCommand::RunComputePass { .. } | ArcCommand::RunRenderPass { .. } => { + unreachable!() + } + } + } + } + + if debug_scope_depth > 0 { + Err(CommandEncoderError::DebugGroupError( + DebugGroupError::MissingPop, + ))?; + } + + // Close the encoder, unless it was closed already by a render or compute pass. + cmd_buf_data.encoder.close_if_open()?; + + // Note: if we want to stop tracking the swapchain texture view, + // this is the place to do it. + + Ok(cmd_buf_data) + }); + + let (data, error) = match res { + Err(e) => { + if e.is_destroyed_error() { + // Errors related to destroyed resources are not reported until the + // command buffer is submitted. + (CommandEncoderStatus::Error(e.clone()), None) + } else { + (CommandEncoderStatus::Error(e.clone()), Some(e)) + } + } + + Ok(data) => (CommandEncoderStatus::Finished(data), None), }; let cmd_buf = CommandBuffer { @@ -1229,8 +1500,14 @@ impl Global { let cmd_enc = hub.command_encoders.get(encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - push_debug_group(cmd_buf_data, &cmd_enc, label) + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::PushDebugGroup(label.to_owned())); + } + + cmd_buf_data.push_with(|| -> Result<_, CommandEncoderError> { + Ok(ArcCommand::PushDebugGroup(label.to_owned())) }) } @@ -1246,8 +1523,14 @@ impl Global { let cmd_enc = hub.command_encoders.get(encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - insert_debug_marker(cmd_buf_data, &cmd_enc, label) + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::InsertDebugMarker(label.to_owned())); + } + + cmd_buf_data.push_with(|| -> Result<_, CommandEncoderError> { + Ok(ArcCommand::InsertDebugMarker(label.to_owned())) }) } @@ -1262,9 +1545,14 @@ impl Global { let cmd_enc = hub.command_encoders.get(encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - pop_debug_group(cmd_buf_data, &cmd_enc) - }) + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::PopDebugGroup); + } + + cmd_buf_data + .push_with(|| -> Result<_, CommandEncoderError> { Ok(ArcCommand::PopDebugGroup) }) } fn validate_pass_timestamp_writes( @@ -1320,84 +1608,49 @@ impl Global { } pub(crate) fn push_debug_group( - cmd_buf_data: &mut CommandBufferMutable, - cmd_enc: &Arc, + state: &mut EncodingState, label: &str, ) -> Result<(), CommandEncoderError> { - cmd_buf_data.debug_scope_depth += 1; - - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::PushDebugGroup(label.to_owned())); - } - - cmd_enc.device.check_is_valid()?; + *state.debug_scope_depth += 1; - let cmd_buf_raw = cmd_buf_data.encoder.open()?; - if !cmd_enc + if !state .device .instance_flags .contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) { - unsafe { - cmd_buf_raw.begin_debug_marker(label); - } + unsafe { state.raw_encoder.begin_debug_marker(label) }; } Ok(()) } pub(crate) fn insert_debug_marker( - cmd_buf_data: &mut CommandBufferMutable, - cmd_enc: &Arc, + state: &mut EncodingState, label: &str, ) -> Result<(), CommandEncoderError> { - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::InsertDebugMarker(label.to_owned())); - } - - cmd_enc.device.check_is_valid()?; - - if !cmd_enc + if !state .device .instance_flags .contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) { - let cmd_buf_raw = cmd_buf_data.encoder.open()?; - unsafe { - cmd_buf_raw.insert_debug_marker(label); - } + unsafe { state.raw_encoder.insert_debug_marker(label) }; } Ok(()) } -pub(crate) fn pop_debug_group( - cmd_buf_data: &mut CommandBufferMutable, - cmd_enc: &Arc, -) -> Result<(), CommandEncoderError> { - if cmd_buf_data.debug_scope_depth == 0 { +pub(crate) fn pop_debug_group(state: &mut EncodingState) -> Result<(), CommandEncoderError> { + if *state.debug_scope_depth == 0 { return Err(DebugGroupError::InvalidPop.into()); } - cmd_buf_data.debug_scope_depth -= 1; - - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::PopDebugGroup); - } + *state.debug_scope_depth -= 1; - cmd_enc.device.check_is_valid()?; - - let cmd_buf_raw = cmd_buf_data.encoder.open()?; - if !cmd_enc + if !state .device .instance_flags .contains(wgt::InstanceFlags::DISCARD_HAL_LABELS) { - unsafe { - cmd_buf_raw.end_debug_marker(); - } + unsafe { state.raw_encoder.end_debug_marker() }; } Ok(()) diff --git a/wgpu-core/src/command/pass.rs b/wgpu-core/src/command/pass.rs index 52eb15bf082..58b7b9ad077 100644 --- a/wgpu-core/src/command/pass.rs +++ b/wgpu-core/src/command/pass.rs @@ -4,8 +4,8 @@ use crate::binding_model::{BindError, BindGroup, PushConstantUploadError}; use crate::command::bind::Binder; use crate::command::encoder::EncodingState; use crate::command::memory_init::SurfacesInDiscardState; -use crate::command::{CommandEncoder, DebugGroupError, QueryResetMap, QueryUseError}; -use crate::device::{DeviceError, MissingFeatures}; +use crate::command::{DebugGroupError, QueryResetMap, QueryUseError}; +use crate::device::{Device, DeviceError, MissingFeatures}; use crate::pipeline::LateSizedBufferGroup; use crate::ray_tracing::AsAction; use crate::resource::{DestroyedResourceError, Labeled, ParentDevice, QuerySet}; @@ -41,8 +41,8 @@ impl WebGpuError for InvalidValuesOffset { } } -pub(crate) struct PassState<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { - pub(crate) base: EncodingState<'snatch_guard, 'cmd_enc, 'raw_encoder>, +pub(crate) struct PassState<'scope, 'snatch_guard, 'cmd_enc> { + pub(crate) base: EncodingState<'snatch_guard, 'cmd_enc>, /// Immediate texture inits required because of prior discards. Need to /// be inserted before texture reads. @@ -61,7 +61,7 @@ pub(crate) struct PassState<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { pub(crate) fn set_bind_group( state: &mut PassState, - cmd_enc: &CommandEncoder, + device: &Arc, dynamic_offsets: &[DynamicOffset], index: u32, num_dynamic_offsets: usize, @@ -108,7 +108,7 @@ where let bind_group = bind_group.unwrap(); let bind_group = state.base.tracker.bind_groups.insert_single(bind_group); - bind_group.same_device_as(cmd_enc)?; + bind_group.same_device(device)?; bind_group.validate_dynamic_bindings(index, &state.temp_offsets)?; @@ -271,7 +271,7 @@ where pub(crate) fn write_timestamp( state: &mut PassState, - cmd_enc: &CommandEncoder, + device: &Arc, pending_query_resets: Option<&mut QueryResetMap>, query_set: Arc, query_index: u32, @@ -284,7 +284,7 @@ where query_set.error_ident() ); - query_set.same_device_as(cmd_enc)?; + query_set.same_device(device)?; state .base diff --git a/wgpu-core/src/command/query.rs b/wgpu-core/src/command/query.rs index 694b41525d2..3e4ed7889f1 100644 --- a/wgpu-core/src/command/query.rs +++ b/wgpu-core/src/command/query.rs @@ -4,14 +4,14 @@ use core::{iter, mem}; #[cfg(feature = "trace")] use crate::command::Command as TraceCommand; use crate::{ - command::{CommandBufferMutable, CommandEncoder, EncoderStateError}, - device::{DeviceError, MissingFeatures}, + command::{encoder::EncodingState, ArcCommand, EncoderStateError}, + device::{Device, DeviceError, MissingFeatures}, global::Global, id, init_tracker::MemoryInitKind, resource::{ - DestroyedResourceError, InvalidResourceError, MissingBufferUsageError, ParentDevice, - QuerySet, RawResourceAccess, Trackable, + Buffer, DestroyedResourceError, InvalidResourceError, MissingBufferUsageError, + ParentDevice, QuerySet, RawResourceAccess, Trackable, }, track::{StatelessTracker, TrackerIndex}, FastHashMap, @@ -307,12 +307,12 @@ pub(super) fn validate_and_begin_pipeline_statistics_query( query_set: Arc, raw_encoder: &mut dyn hal::DynCommandEncoder, tracker: &mut StatelessTracker, - cmd_enc: &CommandEncoder, + device: &Arc, query_index: u32, reset_state: Option<&mut QueryResetMap>, active_query: &mut Option<(Arc, u32)>, ) -> Result<(), QueryUseError> { - query_set.same_device_as(cmd_enc)?; + query_set.same_device(device)?; let needs_reset = reset_state.is_none(); query_set.validate_query( @@ -365,8 +365,20 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), QueryError> { - write_timestamp(cmd_buf_data, hub, &cmd_enc, query_set_id, query_index) + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::WriteTimestamp { + query_set_id, + query_index, + }); + } + + cmd_buf_data.push_with(|| -> Result<_, QueryError> { + Ok(ArcCommand::WriteTimestamp { + query_set: self.resolve_query_set(query_set_id)?, + query_index, + }) }) } @@ -383,97 +395,70 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), QueryError> { - resolve_query_set( - cmd_buf_data, - hub, - &cmd_enc, + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::ResolveQuerySet { query_set_id, start_query, query_count, destination, destination_offset, - ) + }); + } + + cmd_buf_data.push_with(|| -> Result<_, QueryError> { + Ok(ArcCommand::ResolveQuerySet { + query_set: self.resolve_query_set(query_set_id)?, + start_query, + query_count, + destination: self.resolve_buffer_id(destination)?, + destination_offset, + }) }) } } pub(super) fn write_timestamp( - cmd_buf_data: &mut CommandBufferMutable, - hub: &crate::hub::Hub, - cmd_enc: &Arc, - query_set_id: id::QuerySetId, + state: &mut EncodingState, + query_set: Arc, query_index: u32, ) -> Result<(), QueryError> { - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::WriteTimestamp { - query_set_id, - query_index, - }); - } - - cmd_enc.device.check_is_valid()?; - - cmd_enc + state .device .require_features(wgt::Features::TIMESTAMP_QUERY_INSIDE_ENCODERS)?; - let raw_encoder = cmd_buf_data.encoder.open()?; + query_set.same_device(state.device)?; - let query_set = hub.query_sets.get(query_set_id).get()?; - query_set.same_device_as(cmd_enc.as_ref())?; + query_set.validate_and_write_timestamp(state.raw_encoder, query_index, None)?; - query_set.validate_and_write_timestamp(raw_encoder, query_index, None)?; - - cmd_buf_data.trackers.query_sets.insert_single(query_set); + state.tracker.query_sets.insert_single(query_set); Ok(()) } pub(super) fn resolve_query_set( - cmd_buf_data: &mut CommandBufferMutable, - hub: &crate::hub::Hub, - cmd_enc: &Arc, - query_set_id: id::QuerySetId, + state: &mut EncodingState, + query_set: Arc, start_query: u32, query_count: u32, - destination: id::BufferId, + dst_buffer: Arc, destination_offset: BufferAddress, ) -> Result<(), QueryError> { - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::ResolveQuerySet { - query_set_id, - start_query, - query_count, - destination, - destination_offset, - }); - } - - cmd_enc.device.check_is_valid()?; - if destination_offset % wgt::QUERY_RESOLVE_BUFFER_ALIGNMENT != 0 { return Err(QueryError::Resolve(ResolveError::BufferOffsetAlignment)); } - let query_set = hub.query_sets.get(query_set_id).get()?; + query_set.same_device(state.device)?; + dst_buffer.same_device(state.device)?; - query_set.same_device_as(cmd_enc.as_ref())?; + dst_buffer.check_destroyed(state.snatch_guard)?; - let dst_buffer = hub.buffers.get(destination).get()?; - - dst_buffer.same_device_as(cmd_enc.as_ref())?; - - let snatch_guard = dst_buffer.device.snatchable_lock.read(); - dst_buffer.check_destroyed(&snatch_guard)?; - - let dst_pending = cmd_buf_data - .trackers + let dst_pending = state + .tracker .buffers .set_single(&dst_buffer, wgt::BufferUses::COPY_DST); - let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); + let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, state.snatch_guard)); dst_buffer .check_usage(wgt::BufferUsages::QUERY_RESOLVE) @@ -517,19 +502,18 @@ pub(super) fn resolve_query_set( })?; // TODO(https://github.com/gfx-rs/wgpu/issues/3993): Need to track initialization state. - cmd_buf_data.buffer_memory_init_actions.extend( - dst_buffer.initialization_status.read().create_action( + state + .buffer_memory_init_actions + .extend(dst_buffer.initialization_status.read().create_action( &dst_buffer, buffer_start_offset..buffer_end_offset, MemoryInitKind::ImplicitlyInitialized, - ), - ); + )); - let raw_dst_buffer = dst_buffer.try_raw(&snatch_guard)?; - let raw_encoder = cmd_buf_data.encoder.open()?; + let raw_dst_buffer = dst_buffer.try_raw(state.snatch_guard)?; unsafe { - raw_encoder.transition_buffers(dst_barrier.as_slice()); - raw_encoder.copy_query_results( + state.raw_encoder.transition_buffers(dst_barrier.as_slice()); + state.raw_encoder.copy_query_results( query_set.raw(), start_query..end_query, raw_dst_buffer, @@ -540,26 +524,21 @@ pub(super) fn resolve_query_set( if matches!(query_set.desc.ty, wgt::QueryType::Timestamp) { // Timestamp normalization is only needed for timestamps. - cmd_enc - .device - .timestamp_normalizer - .get() - .unwrap() - .normalize( - &snatch_guard, - raw_encoder, - &mut cmd_buf_data.trackers.buffers, - dst_buffer - .timestamp_normalization_bind_group - .get(&snatch_guard) - .unwrap(), - &dst_buffer, - destination_offset, - query_count, - ); + state.device.timestamp_normalizer.get().unwrap().normalize( + state.snatch_guard, + state.raw_encoder, + &mut state.tracker.buffers, + dst_buffer + .timestamp_normalization_bind_group + .get(state.snatch_guard) + .unwrap(), + &dst_buffer, + destination_offset, + query_count, + ); } - cmd_buf_data.trackers.query_sets.insert_single(query_set); + state.tracker.query_sets.insert_single(query_set); Ok(()) } diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 6e7f553e84b..9f1c0066776 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -1,4 +1,4 @@ -use alloc::{boxed::Box, sync::Arc, vec::Vec}; +use alloc::{sync::Arc, vec::Vec}; use core::{ cmp::max, num::NonZeroU64, @@ -11,34 +11,39 @@ use crate::{ command::CommandBufferMutable, device::queue::TempResource, global::Global, - hub::Hub, id::CommandEncoderId, init_tracker::MemoryInitKind, ray_tracing::{ - BlasBuildEntry, BlasGeometries, BlasTriangleGeometry, BuildAccelerationStructureError, - TlasInstance, TlasPackage, TraceBlasBuildEntry, TraceBlasGeometries, - TraceBlasTriangleGeometry, TraceTlasInstance, TraceTlasPackage, + BlasBuildEntry, BlasGeometries, BuildAccelerationStructureError, TlasPackage, + TraceBlasBuildEntry, TraceBlasGeometries, TraceBlasTriangleGeometry, TraceTlasInstance, + TraceTlasPackage, }, resource::{Blas, BlasCompactState, Buffer, Labeled, StagingBuffer, Tlas}, scratch::ScratchBuffer, snatch::SnatchGuard, track::PendingTransition, }; +use crate::{command::EncoderStateError, device::resource::CommandIndices}; use crate::{ - command::CommandEncoder, - ray_tracing::{AsAction, AsBuild, TlasBuild, ValidateAsActionsError}, + command::{encoder::EncodingState, ArcCommand}, + ray_tracing::{ + ArcBlasBuildEntry, ArcBlasGeometries, ArcBlasTriangleGeometry, ArcTlasInstance, + ArcTlasPackage, AsAction, AsBuild, BlasTriangleGeometryInfo, TlasBuild, + ValidateAsActionsError, + }, + resource::InvalidResourceError, + track::Tracker, }; -use crate::{command::EncoderStateError, device::resource::CommandIndices}; use crate::{lock::RwLockWriteGuard, resource::RawResourceAccess}; use crate::id::{BlasId, TlasId}; -struct TriangleBufferStore<'a> { +struct TriangleBufferStore { vertex_buffer: Arc, vertex_transition: Option>, index_buffer_transition: Option<(Arc, Option>)>, transform_buffer_transition: Option<(Arc, Option>)>, - geometry: BlasTriangleGeometry<'a>, + geometry: BlasTriangleGeometryInfo, ending_blas: Option>, } @@ -60,6 +65,14 @@ struct TlasStore<'a> { } impl Global { + fn resolve_blas_id(&self, blas_id: BlasId) -> Result, InvalidResourceError> { + self.hub.blas_s.get(blas_id).get() + } + + fn resolve_tlas_id(&self, tlas_id: TlasId) -> Result, InvalidResourceError> { + self.hub.tlas_s.get(tlas_id).get() + } + pub fn command_encoder_mark_acceleration_structures_built( &self, command_encoder_id: CommandEncoderId, @@ -73,7 +86,7 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with( + cmd_buf_data.with_buffer( |cmd_buf_data| -> Result<(), BuildAccelerationStructureError> { let device = &cmd_enc.device; device.check_is_valid()?; @@ -161,115 +174,118 @@ impl Global { .collect(); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| { - let blas_iter = trace_blas.iter().map(|blas_entry| { - let geometries = match &blas_entry.geometries { - TraceBlasGeometries::TriangleGeometries(triangle_geometries) => { - let iter = triangle_geometries.iter().map(|tg| BlasTriangleGeometry { - size: &tg.size, - vertex_buffer: tg.vertex_buffer, - index_buffer: tg.index_buffer, - transform_buffer: tg.transform_buffer, - first_vertex: tg.first_vertex, - vertex_stride: tg.vertex_stride, - first_index: tg.first_index, - transform_buffer_offset: tg.transform_buffer_offset, - }); - BlasGeometries::TriangleGeometries(Box::new(iter)) - } - }; - BlasBuildEntry { - blas_id: blas_entry.blas_id, - geometries, - } + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(crate::command::Command::BuildAccelerationStructures { + blas: trace_blas.clone(), + tlas: trace_tlas.clone(), }); + } - let tlas_iter = trace_tlas.iter().map(|tlas_package| { - let instances = tlas_package.instances.iter().map(|instance| { - instance.as_ref().map(|instance| TlasInstance { - blas_id: instance.blas_id, - transform: &instance.transform, - custom_data: instance.custom_data, - mask: instance.mask, + cmd_buf_data.push_with(|| -> Result<_, BuildAccelerationStructureError> { + let blas = trace_blas + .iter() + .map(|blas_entry| { + let geometries = match &blas_entry.geometries { + TraceBlasGeometries::TriangleGeometries(triangle_geometries) => { + let tri_geo = triangle_geometries + .iter() + .map(|tg| { + Ok(ArcBlasTriangleGeometry { + size: tg.size.clone(), + vertex_buffer: self.resolve_buffer_id(tg.vertex_buffer)?, + index_buffer: tg + .index_buffer + .map(|id| self.resolve_buffer_id(id)) + .transpose()?, + transform_buffer: tg + .transform_buffer + .map(|id| self.resolve_buffer_id(id)) + .transpose()?, + first_vertex: tg.first_vertex, + vertex_stride: tg.vertex_stride, + first_index: tg.first_index, + transform_buffer_offset: tg.transform_buffer_offset, + }) + }) + .collect::>()?; + ArcBlasGeometries::TriangleGeometries(tri_geo) + } + }; + Ok(ArcBlasBuildEntry { + blas: self.resolve_blas_id(blas_entry.blas_id)?, + geometries, }) - }); - TlasPackage { - tlas_id: tlas_package.tlas_id, - instances: Box::new(instances), - lowest_unmodified: tlas_package.lowest_unmodified, - } - }); + }) + .collect::>()?; + + let tlas = trace_tlas + .iter() + .map(|tlas_package| { + let instances = tlas_package + .instances + .iter() + .map(|instance| { + instance + .as_ref() + .map(|instance| { + Ok(ArcTlasInstance { + blas: self.resolve_blas_id(instance.blas_id)?, + transform: instance.transform, + custom_data: instance.custom_data, + mask: instance.mask, + }) + }) + .transpose() + }) + .collect::>()?; + Ok(ArcTlasPackage { + tlas: self.resolve_tlas_id(tlas_package.tlas_id)?, + instances, + lowest_unmodified: tlas_package.lowest_unmodified, + }) + }) + .collect::>()?; - build_acceleration_structures( - cmd_buf_data, - hub, - &cmd_enc, - trace_blas.clone(), - trace_tlas.clone(), - blas_iter, - tlas_iter, - ) + Ok(ArcCommand::BuildAccelerationStructures { blas, tlas }) }) } } -pub(crate) fn build_acceleration_structures<'a>( - cmd_buf_data: &'a mut CommandBufferMutable, - hub: &'a Hub, - cmd_enc: &'a Arc, - trace_blas: Vec, - trace_tlas: Vec, - blas_iter: impl Iterator>, - tlas_iter: impl Iterator>, +pub(crate) fn build_acceleration_structures( + state: &mut EncodingState, + blas: Vec, + tlas: Vec, ) -> Result<(), BuildAccelerationStructureError> { - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(crate::command::Command::BuildAccelerationStructures { - blas: trace_blas, - tlas: trace_tlas, - }); - } - #[cfg(not(feature = "trace"))] - { - let _ = trace_blas; - let _ = trace_tlas; - } - - let device = &cmd_enc.device; - device.check_is_valid()?; - device.require_features(Features::EXPERIMENTAL_RAY_QUERY)?; + state + .device + .require_features(Features::EXPERIMENTAL_RAY_QUERY)?; let mut build_command = AsBuild::default(); let mut buf_storage = Vec::new(); iter_blas( - blas_iter, - cmd_buf_data, + blas.into_iter(), + state.tracker, &mut build_command, &mut buf_storage, - hub, )?; - let snatch_guard = device.snatchable_lock.read(); let mut input_barriers = Vec::>::new(); let mut scratch_buffer_blas_size = 0; let mut blas_storage = Vec::new(); iter_buffers( + state, &mut buf_storage, - &snatch_guard, &mut input_barriers, - cmd_buf_data, &mut scratch_buffer_blas_size, &mut blas_storage, - hub, - device.alignments.ray_tracing_scratch_buffer_alignment, )?; - let mut tlas_lock_store = Vec::<(Option, Arc)>::new(); - - for package in tlas_iter { - let tlas = hub.tlas_s.get(package.tlas_id).get()?; - - cmd_buf_data.trackers.tlas_s.insert_single(tlas.clone()); + let mut tlas_lock_store = Vec::<(Option, Arc)>::new(); + for package in tlas.into_iter() { + let tlas = package.tlas.clone(); + state.tracker.tlas_s.insert_single(tlas.clone()); tlas_lock_store.push((Some(package), tlas)) } @@ -283,7 +299,7 @@ pub(crate) fn build_acceleration_structures<'a>( let scratch_buffer_offset = scratch_buffer_tlas_size; scratch_buffer_tlas_size += align_to( tlas.size_info.build_scratch_size as u32, - device.alignments.ray_tracing_scratch_buffer_alignment, + state.device.alignments.ray_tracing_scratch_buffer_alignment, ) as u64; let first_byte_index = instance_buffer_staging_source.len(); @@ -291,19 +307,18 @@ pub(crate) fn build_acceleration_structures<'a>( let mut dependencies = Vec::new(); let mut instance_count = 0; - for instance in package.instances.flatten() { + for instance in package.instances.into_iter().flatten() { if instance.custom_data >= (1u32 << 24u32) { return Err(BuildAccelerationStructureError::TlasInvalidCustomIndex( tlas.error_ident(), )); } - let blas = hub.blas_s.get(instance.blas_id).get()?; - - cmd_buf_data.trackers.blas_s.insert_single(blas.clone()); + let blas = &instance.blas; + state.tracker.blas_s.insert_single(blas.clone()); - instance_buffer_staging_source.extend(device.raw().tlas_instance_to_bytes( + instance_buffer_staging_source.extend(state.device.raw().tlas_instance_to_bytes( hal::TlasInstance { - transform: *instance.transform, + transform: instance.transform, custom_data: instance.custom_data, mask: instance.mask, blas_address: blas.handle, @@ -366,7 +381,7 @@ pub(crate) fn build_acceleration_structures<'a>( return Ok(()); }; - let scratch_buffer = ScratchBuffer::new(device, scratch_size)?; + let scratch_buffer = ScratchBuffer::new(state.device, scratch_size)?; let scratch_buffer_barrier = hal::BufferBarrier:: { buffer: scratch_buffer.raw(), @@ -396,7 +411,7 @@ pub(crate) fn build_acceleration_structures<'a>( mode: hal::AccelerationStructureBuildMode::Build, flags: tlas.flags, source_acceleration_structure: None, - destination_acceleration_structure: tlas.try_raw(&snatch_guard)?, + destination_acceleration_structure: tlas.try_raw(state.snatch_guard)?, scratch_buffer: scratch_buffer.raw(), scratch_buffer_offset: *scratch_buffer_offset, }) @@ -405,7 +420,7 @@ pub(crate) fn build_acceleration_structures<'a>( let blas_present = !blas_storage.is_empty(); let tlas_present = !tlas_storage.is_empty(); - let cmd_buf_raw = cmd_buf_data.encoder.open()?; + let raw_encoder = &mut state.raw_encoder; let mut blas_s_compactable = Vec::new(); let mut descriptors = Vec::new(); @@ -414,13 +429,13 @@ pub(crate) fn build_acceleration_structures<'a>( descriptors.push(map_blas( storage, scratch_buffer.raw(), - &snatch_guard, + state.snatch_guard, &mut blas_s_compactable, )?); } build_blas( - cmd_buf_raw, + *raw_encoder, blas_present, tlas_present, input_barriers, @@ -432,7 +447,7 @@ pub(crate) fn build_acceleration_structures<'a>( if tlas_present { let staging_buffer = if !instance_buffer_staging_source.is_empty() { let mut staging_buffer = StagingBuffer::new( - device, + state.device, wgt::BufferSize::new(instance_buffer_staging_source.len() as u64).unwrap(), )?; staging_buffer.write(&instance_buffer_staging_source); @@ -444,7 +459,7 @@ pub(crate) fn build_acceleration_structures<'a>( unsafe { if let Some(ref staging_buffer) = staging_buffer { - cmd_buf_raw.transition_buffers(&[hal::BufferBarrier:: { + raw_encoder.transition_buffers(&[hal::BufferBarrier:: { buffer: staging_buffer.raw(), usage: hal::StateTransition { from: BufferUses::MAP_WRITE, @@ -472,7 +487,7 @@ pub(crate) fn build_acceleration_structures<'a>( }, }); unsafe { - cmd_buf_raw.transition_buffers(&[hal::BufferBarrier:: { + raw_encoder.transition_buffers(&[hal::BufferBarrier:: { buffer: tlas.instance_buffer.as_ref(), usage: hal::StateTransition { from: BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT, @@ -484,9 +499,7 @@ pub(crate) fn build_acceleration_structures<'a>( dst_offset: 0, size, }; - cmd_buf_raw.copy_buffer_to_buffer( - // the range whose size we just checked end is at (at that point in time) instance_buffer_staging_source.len() - // and since instance_buffer_staging_source doesn't shrink we can un wrap this without a panic + raw_encoder.copy_buffer_to_buffer( staging_buffer.as_ref().unwrap().raw(), tlas.instance_buffer.as_ref(), &[temp], @@ -495,11 +508,11 @@ pub(crate) fn build_acceleration_structures<'a>( } unsafe { - cmd_buf_raw.transition_buffers(&instance_buffer_barriers); + raw_encoder.transition_buffers(&instance_buffer_barriers); - cmd_buf_raw.build_acceleration_structures(&tlas_descriptors); + raw_encoder.build_acceleration_structures(&tlas_descriptors); - cmd_buf_raw.place_acceleration_structure_barrier(hal::AccelerationStructureBarrier { + raw_encoder.place_acceleration_structure_barrier(hal::AccelerationStructureBarrier { usage: hal::StateTransition { from: hal::AccelerationStructureUses::BUILD_OUTPUT, to: hal::AccelerationStructureUses::SHADER_INPUT, @@ -508,17 +521,17 @@ pub(crate) fn build_acceleration_structures<'a>( } if let Some(staging_buffer) = staging_buffer { - cmd_buf_data + state .temp_resources .push(TempResource::StagingBuffer(staging_buffer)); } } - cmd_buf_data + state .temp_resources .push(TempResource::ScratchBuffer(scratch_buffer)); - cmd_buf_data.as_actions.push(AsAction::Build(build_command)); + state.as_actions.push(AsAction::Build(build_command)); Ok(()) } @@ -600,23 +613,22 @@ impl CommandBufferMutable { } ///iterates over the blas iterator, and it's geometry, pushing the buffers into a storage vector (and also some validation). -fn iter_blas<'a>( - blas_iter: impl Iterator>, - cmd_buf_data: &mut CommandBufferMutable, +fn iter_blas( + blas_iter: impl Iterator, + tracker: &mut Tracker, build_command: &mut AsBuild, - buf_storage: &mut Vec>, - hub: &Hub, + buf_storage: &mut Vec, ) -> Result<(), BuildAccelerationStructureError> { let mut temp_buffer = Vec::new(); for entry in blas_iter { - let blas = hub.blas_s.get(entry.blas_id).get()?; - cmd_buf_data.trackers.blas_s.insert_single(blas.clone()); + let blas = &entry.blas; + tracker.blas_s.insert_single(blas.clone()); build_command.blas_s_built.push(blas.clone()); match entry.geometries { - BlasGeometries::TriangleGeometries(triangle_geometries) => { - for (i, mesh) in triangle_geometries.enumerate() { + ArcBlasGeometries::TriangleGeometries(triangle_geometries) => { + for (i, mesh) in triangle_geometries.into_iter().enumerate() { let size_desc = match &blas.sizes { wgt::BlasGeometrySizeDescriptors::Triangles { descriptors } => descriptors, }; @@ -715,13 +727,12 @@ fn iter_blas<'a>( blas.error_ident(), )); } - let vertex_buffer = hub.buffers.get(mesh.vertex_buffer).get()?; - let vertex_pending = cmd_buf_data.trackers.buffers.set_single( + let vertex_buffer = mesh.vertex_buffer.clone(); + let vertex_pending = tracker.buffers.set_single( &vertex_buffer, BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ); - let index_data = if let Some(index_id) = mesh.index_buffer { - let index_buffer = hub.buffers.get(index_id).get()?; + let index_data = if let Some(index_buffer) = mesh.index_buffer { if mesh.first_index.is_none() || mesh.size.index_count.is_none() || mesh.size.index_count.is_none() @@ -730,7 +741,7 @@ fn iter_blas<'a>( index_buffer.error_ident(), )); } - let data = cmd_buf_data.trackers.buffers.set_single( + let data = tracker.buffers.set_single( &index_buffer, BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ); @@ -738,7 +749,7 @@ fn iter_blas<'a>( } else { None }; - let transform_data = if let Some(transform_id) = mesh.transform_buffer { + let transform_data = if let Some(transform_buffer) = mesh.transform_buffer { if !blas .flags .contains(wgt::AccelerationStructureFlags::USE_TRANSFORM) @@ -747,13 +758,12 @@ fn iter_blas<'a>( blas.error_ident(), )); } - let transform_buffer = hub.buffers.get(transform_id).get()?; if mesh.transform_buffer_offset.is_none() { return Err(BuildAccelerationStructureError::MissingAssociatedData( transform_buffer.error_ident(), )); } - let data = cmd_buf_data.trackers.buffers.set_single( + let data = tracker.buffers.set_single( &transform_buffer, BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, ); @@ -774,13 +784,19 @@ fn iter_blas<'a>( vertex_transition: vertex_pending, index_buffer_transition: index_data, transform_buffer_transition: transform_data, - geometry: mesh, + geometry: BlasTriangleGeometryInfo { + size: mesh.size, + first_vertex: mesh.first_vertex, + vertex_stride: mesh.vertex_stride, + first_index: mesh.first_index, + transform_buffer_offset: mesh.transform_buffer_offset, + }, ending_blas: None, }); } if let Some(last) = temp_buffer.last_mut() { - last.ending_blas = Some(blas); + last.ending_blas = Some(blas.clone()); buf_storage.append(&mut temp_buffer); } } @@ -790,29 +806,30 @@ fn iter_blas<'a>( } /// Iterates over the buffers generated in [iter_blas], convert the barriers into hal barriers, and the triangles into [hal::AccelerationStructureEntries] (and also some validation). -fn iter_buffers<'a, 'b>( - buf_storage: &'a mut Vec>, - snatch_guard: &'a SnatchGuard, - input_barriers: &mut Vec>, - cmd_buf_data: &mut CommandBufferMutable, +/// +/// `'buffers` is the lifetime of `&dyn hal::DynBuffer` in our working data, +/// i.e., needs to span until `build_acceleration_structures` finishes encoding. +/// `'snatch_guard` is the lifetime of the snatch lock acquisition. +fn iter_buffers<'snatch_guard: 'buffers, 'buffers>( + state: &mut EncodingState<'snatch_guard, '_>, + buf_storage: &'buffers mut Vec, + input_barriers: &mut Vec>, scratch_buffer_blas_size: &mut u64, - blas_storage: &mut Vec>, - hub: &Hub, - ray_tracing_scratch_buffer_alignment: u32, + blas_storage: &mut Vec>, ) -> Result<(), BuildAccelerationStructureError> { let mut triangle_entries = Vec::>::new(); for buf in buf_storage { let mesh = &buf.geometry; let vertex_buffer = { - let vertex_buffer = buf.vertex_buffer.as_ref(); - let vertex_raw = vertex_buffer.try_raw(snatch_guard)?; + let vertex_raw = buf.vertex_buffer.as_ref().try_raw(state.snatch_guard)?; + let vertex_buffer = &buf.vertex_buffer; vertex_buffer.check_usage(BufferUsages::BLAS_INPUT)?; if let Some(barrier) = buf .vertex_transition .take() - .map(|pending| pending.into_hal(vertex_buffer, snatch_guard)) + .map(|pending| pending.into_hal(buf.vertex_buffer.as_ref(), state.snatch_guard)) { input_barriers.push(barrier); } @@ -826,9 +843,9 @@ fn iter_buffers<'a, 'b>( )); } let vertex_buffer_offset = mesh.first_vertex as u64 * mesh.vertex_stride; - cmd_buf_data.buffer_memory_init_actions.extend( + state.buffer_memory_init_actions.extend( vertex_buffer.initialization_status.read().create_action( - &hub.buffers.get(mesh.vertex_buffer).get()?, + vertex_buffer, vertex_buffer_offset ..(vertex_buffer_offset + mesh.size.vertex_count as u64 * mesh.vertex_stride), @@ -840,12 +857,12 @@ fn iter_buffers<'a, 'b>( let index_buffer = if let Some((ref mut index_buffer, ref mut index_pending)) = buf.index_buffer_transition { - let index_raw = index_buffer.try_raw(snatch_guard)?; + let index_raw = index_buffer.try_raw(state.snatch_guard)?; index_buffer.check_usage(BufferUsages::BLAS_INPUT)?; if let Some(barrier) = index_pending .take() - .map(|pending| pending.into_hal(index_buffer, snatch_guard)) + .map(|pending| pending.into_hal(index_buffer, state.snatch_guard)) { input_barriers.push(barrier); } @@ -867,7 +884,7 @@ fn iter_buffers<'a, 'b>( )); } - cmd_buf_data.buffer_memory_init_actions.extend( + state.buffer_memory_init_actions.extend( index_buffer.initialization_status.read().create_action( index_buffer, offset..(offset + index_buffer_size), @@ -886,12 +903,12 @@ fn iter_buffers<'a, 'b>( transform_buffer.error_ident(), )); } - let transform_raw = transform_buffer.try_raw(snatch_guard)?; + let transform_raw = transform_buffer.try_raw(state.snatch_guard)?; transform_buffer.check_usage(BufferUsages::BLAS_INPUT)?; if let Some(barrier) = transform_pending .take() - .map(|pending| pending.into_hal(transform_buffer, snatch_guard)) + .map(|pending| pending.into_hal(transform_buffer, state.snatch_guard)) { input_barriers.push(barrier); } @@ -912,7 +929,7 @@ fn iter_buffers<'a, 'b>( 48 + offset, )); } - cmd_buf_data.buffer_memory_init_actions.extend( + state.buffer_memory_init_actions.extend( transform_buffer.initialization_status.read().create_action( transform_buffer, offset..(offset + 48), @@ -952,7 +969,7 @@ fn iter_buffers<'a, 'b>( let scratch_buffer_offset = *scratch_buffer_blas_size; *scratch_buffer_blas_size += align_to( blas.size_info.build_scratch_size as u32, - ray_tracing_scratch_buffer_alignment, + state.device.alignments.ray_tracing_scratch_buffer_alignment, ) as u64; blas_storage.push(BlasStore { diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index bf19edf7921..51db9634ea4 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -1,5 +1,6 @@ use alloc::{borrow::Cow, sync::Arc, vec::Vec}; -use core::{fmt, num::NonZeroU32, ops::Range, str}; +use core::{convert::Infallible, fmt, num::NonZeroU32, ops::Range, str}; +use smallvec::SmallVec; use arrayvec::ArrayVec; use thiserror::Error; @@ -11,8 +12,8 @@ use wgt::{ use crate::command::{ encoder::EncodingState, pass, pass_base, pass_try, validate_and_begin_occlusion_query, - validate_and_begin_pipeline_statistics_query, CommandBufferMutable, DebugGroupError, - EncoderStateError, InnerCommandEncoder, PassStateError, TimestampWritesError, + validate_and_begin_pipeline_statistics_query, ArcCommand, DebugGroupError, EncoderStateError, + InnerCommandEncoder, PassStateError, TimestampWritesError, }; use crate::pipeline::{RenderPipeline, VertexStep}; use crate::resource::RawResourceAccess; @@ -117,7 +118,7 @@ impl PassChannel> { } } -#[derive(Debug)] +#[derive(Clone, Debug)] pub enum ResolvedPassChannel { ReadOnly, Operational(wgt::Operations), @@ -180,6 +181,11 @@ pub struct RenderPassColorAttachment { pub type ArcRenderPassColorAttachment = RenderPassColorAttachment>; +// Avoid allocation in the common case that there is only one color attachment, +// but don't bloat `ArcCommand::RunRenderPass` excessively. +pub type ArcRenderPassColorAttachmentArray = + SmallVec<[Option>>; 1]>; + impl ArcRenderPassColorAttachment { fn hal_ops(&self) -> hal::AttachmentOps { load_hal_ops(self.load_op) | store_hal_ops(self.store_op) @@ -207,7 +213,7 @@ pub struct RenderPassDepthStencilAttachment { } /// Describes a depth/stencil attachment to a render pass. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct ArcRenderPassDepthStencilAttachment { /// The view to use as an attachment. pub view: Arc, @@ -494,7 +500,7 @@ impl VertexState { } } -struct State<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { +struct State<'scope, 'snatch_guard, 'cmd_enc> { pipeline_flags: PipelineFlags, blend_constant: OptionalState, stencil_reference: u32, @@ -504,15 +510,13 @@ struct State<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> { info: RenderPassInfo, - pass: pass::PassState<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder>, + pass: pass::PassState<'scope, 'snatch_guard, 'cmd_enc>, active_occlusion_query: Option<(Arc, u32)>, active_pipeline_statistics_query: Option<(Arc, u32)>, } -impl<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> - State<'scope, 'snatch_guard, 'cmd_enc, 'raw_encoder> -{ +impl<'scope, 'snatch_guard, 'cmd_enc> State<'scope, 'snatch_guard, 'cmd_enc> { fn is_ready(&self, family: DrawCommandFamily) -> Result<(), DrawError> { if let Some(pipeline) = self.pipeline.as_ref() { self.pass.binder.check_compatibility(pipeline.as_ref())?; @@ -953,14 +957,11 @@ impl RenderPassInfo { fn start( device: &Arc, hal_label: Option<&str>, - color_attachments: ArrayVec< - Option, - { hal::MAX_COLOR_ATTACHMENTS }, - >, + color_attachments: &[Option], mut depth_stencil_attachment: Option, mut timestamp_writes: Option, mut occlusion_query_set: Option>, - encoder: &mut InnerCommandEncoder, + encoder: &mut dyn hal::DynCommandEncoder, trackers: &mut Tracker, texture_memory_actions: &mut CommandBufferTextureMemoryActions, pending_query_resets: &mut QueryResetMap, @@ -1422,7 +1423,6 @@ impl RenderPassInfo { }; unsafe { encoder - .raw .begin_render_pass(&hal_desc) .map_err(|e| device.handle_hal_error(e))?; }; @@ -1438,9 +1438,9 @@ impl RenderPassInfo { if let Some(at) = depth_stencil_attachment.take() { trackers.views.insert_single(at.view.clone()); } - for at in color_attachments.into_iter().flatten() { + for at in color_attachments.iter().flatten() { trackers.views.insert_single(at.view.clone()); - if let Some(resolve_target) = at.resolve_target { + if let Some(resolve_target) = at.resolve_target.clone() { trackers.views.insert_single(resolve_target); } } @@ -1740,7 +1740,7 @@ impl Global { pub fn render_pass_end_with_unresolved_commands( &self, encoder_id: id::CommandEncoderId, - base: BasePass, + base: BasePass, color_attachments: &[Option], depth_stencil_attachment: Option<&RenderPassDepthStencilAttachment>, timestamp_writes: Option<&PassTimestampWrites>, @@ -1815,87 +1815,97 @@ impl Global { let cmd_enc = pass.parent.take().ok_or(EncoderStateError::Ended)?; let mut cmd_buf_data = cmd_enc.data.lock(); - if let Some(err) = pass.base.error.take() { - if matches!( - err, - RenderPassError { - inner: RenderPassErrorInner::EncoderState(EncoderStateError::Ended), - scope: _, - } - ) { - // If the encoder was already finished at time of pass creation, - // then it was not put in the locked state, so we need to - // generate a validation error here due to the encoder not being - // locked. The encoder already has a copy of the error. - return Err(EncoderStateError::Ended); - } else { - // If the pass is invalid, invalidate the parent encoder and return. - // Since we do not track the state of an invalid encoder, it is not - // necessary to unlock it. - cmd_buf_data.invalidate(err); - return Ok(()); - } + cmd_buf_data.unlock_encoder()?; + + let base = pass.base.take(); + + if matches!( + base, + Err(RenderPassError { + inner: RenderPassErrorInner::EncoderState(EncoderStateError::Ended), + scope: _, + }) + ) { + // If the encoder was already finished at time of pass creation, + // then it was not put in the locked state, so we need to + // generate a validation error here and now due to the encoder not + // being locked. The encoder already holds an error from when the + // pass was opened, or earlier. + // + // All other errors are propagated to the encoder within `push_with`, + // and will be reported later. + return Err(EncoderStateError::Ended); } - cmd_buf_data.unlock_and_record(|cmd_buf_data| -> Result<(), RenderPassError> { - encode_render_pass(cmd_buf_data, &cmd_enc, pass) + cmd_buf_data.push_with(|| -> Result<_, RenderPassError> { + Ok(ArcCommand::RunRenderPass { + pass: base?, + color_attachments: SmallVec::from(pass.color_attachments.as_slice()), + depth_stencil_attachment: pass.depth_stencil_attachment.take(), + timestamp_writes: pass.timestamp_writes.take(), + occlusion_query_set: pass.occlusion_query_set.take(), + }) }) } } -fn encode_render_pass( - cmd_buf_data: &mut CommandBufferMutable, - cmd_enc: &Arc, - pass: &mut RenderPass, +pub(super) fn encode_render_pass( + parent_state: &mut EncodingState, + mut base: BasePass, + color_attachments: ArcRenderPassColorAttachmentArray, + mut depth_stencil_attachment: Option, + mut timestamp_writes: Option, + occlusion_query_set: Option>, ) -> Result<(), RenderPassError> { let pass_scope = PassErrorScope::Pass; - let device = &cmd_enc.device; - device.check_is_valid().map_pass_err(pass_scope)?; - let snatch_guard = &device.snatchable_lock.read(); - - let base = &mut pass.base; + let device = parent_state.device; let mut indirect_draw_validation_batcher = crate::indirect_validation::DrawBatcher::new(); - let (scope, pending_discard_init_fixups, mut pending_query_resets) = { - let encoder = &mut cmd_buf_data.encoder; - let tracker = &mut cmd_buf_data.trackers; - let buffer_memory_init_actions = &mut cmd_buf_data.buffer_memory_init_actions; - let texture_memory_actions = &mut cmd_buf_data.texture_memory_actions; - - // We automatically keep extending command buffers over time, and because - // we want to insert a command buffer _before_ what we're about to record, - // we need to make sure to close the previous one. - encoder.close_if_open().map_pass_err(pass_scope)?; - encoder - .open_pass(base.label.as_deref()) - .map_pass_err(pass_scope)?; + // We automatically keep extending command buffers over time, and because + // we want to insert a command buffer _before_ what we're about to record, + // we need to make sure to close the previous one. + parent_state + .raw_encoder + .close_if_open() + .map_pass_err(pass_scope)?; + let raw_encoder = parent_state + .raw_encoder + .open_pass(base.label.as_deref()) + .map_pass_err(pass_scope)?; + let (scope, pending_discard_init_fixups, mut pending_query_resets) = { let mut pending_query_resets = QueryResetMap::new(); let mut pending_discard_init_fixups = SurfacesInDiscardState::new(); let info = RenderPassInfo::start( device, hal_label(base.label.as_deref(), device.instance_flags), - pass.color_attachments.take(), - pass.depth_stencil_attachment.take(), - pass.timestamp_writes.take(), + &color_attachments, + depth_stencil_attachment.take(), + timestamp_writes.take(), // Still needed down the line. // TODO(wumpf): by restructuring the code, we could get rid of some of this Arc clone. - pass.occlusion_query_set.clone(), - encoder, - tracker, - texture_memory_actions, + occlusion_query_set.clone(), + raw_encoder, + parent_state.tracker, + parent_state.texture_memory_actions, &mut pending_query_resets, &mut pending_discard_init_fixups, - snatch_guard, + parent_state.snatch_guard, ) .map_pass_err(pass_scope)?; let indices = &device.tracker_indices; - tracker.buffers.set_size(indices.buffers.size()); - tracker.textures.set_size(indices.textures.size()); + parent_state + .tracker + .buffers + .set_size(indices.buffers.size()); + parent_state + .tracker + .textures + .set_size(indices.textures.size()); let mut debug_scope_depth = 0; @@ -1912,14 +1922,15 @@ fn encode_render_pass( pass: pass::PassState { base: EncodingState { device, - raw_encoder: encoder.raw.as_mut(), - tracker, - buffer_memory_init_actions, - texture_memory_actions, - as_actions: &mut cmd_buf_data.as_actions, - indirect_draw_validation_resources: &mut cmd_buf_data + raw_encoder, + tracker: parent_state.tracker, + buffer_memory_init_actions: parent_state.buffer_memory_init_actions, + texture_memory_actions: parent_state.texture_memory_actions, + as_actions: parent_state.as_actions, + temp_resources: parent_state.temp_resources, + indirect_draw_validation_resources: parent_state .indirect_draw_validation_resources, - snatch_guard, + snatch_guard: parent_state.snatch_guard, debug_scope_depth: &mut debug_scope_depth, }, pending_discard_init_fixups, @@ -1946,7 +1957,7 @@ fn encode_render_pass( let scope = PassErrorScope::SetBindGroup; pass::set_bind_group::( &mut state.pass, - cmd_enc.as_ref(), + device, &base.dynamic_offsets, index, num_dynamic_offsets, @@ -1957,7 +1968,7 @@ fn encode_render_pass( } ArcRenderCommand::SetPipeline(pipeline) => { let scope = PassErrorScope::SetPipelineRender; - set_pipeline(&mut state, cmd_enc, pipeline).map_pass_err(scope)?; + set_pipeline(&mut state, device, pipeline).map_pass_err(scope)?; } ArcRenderCommand::SetIndexBuffer { buffer, @@ -1966,7 +1977,7 @@ fn encode_render_pass( size, } => { let scope = PassErrorScope::SetIndexBuffer; - set_index_buffer(&mut state, cmd_enc, buffer, index_format, offset, size) + set_index_buffer(&mut state, device, buffer, index_format, offset, size) .map_pass_err(scope)?; } ArcRenderCommand::SetVertexBuffer { @@ -1976,7 +1987,7 @@ fn encode_render_pass( size, } => { let scope = PassErrorScope::SetVertexBuffer; - set_vertex_buffer(&mut state, cmd_enc, slot, buffer, offset, size) + set_vertex_buffer(&mut state, device, slot, buffer, offset, size) .map_pass_err(scope)?; } ArcRenderCommand::SetBlendConstant(ref color) => { @@ -2087,7 +2098,7 @@ fn encode_render_pass( multi_draw_indirect( &mut state, &mut indirect_draw_validation_batcher, - cmd_enc, + device, buffer, offset, count, @@ -2109,7 +2120,7 @@ fn encode_render_pass( }; multi_draw_indirect_count( &mut state, - cmd_enc, + device, buffer, offset, count_buffer, @@ -2137,7 +2148,7 @@ fn encode_render_pass( let scope = PassErrorScope::WriteTimestamp; pass::write_timestamp::( &mut state.pass, - cmd_enc.as_ref(), + device, Some(&mut pending_query_resets), query_set, query_index, @@ -2148,8 +2159,7 @@ fn encode_render_pass( api_log!("RenderPass::begin_occlusion_query {query_index}"); let scope = PassErrorScope::BeginOcclusionQuery; - let query_set = pass - .occlusion_query_set + let query_set = occlusion_query_set .clone() .ok_or(RenderPassErrorInner::MissingOcclusionQuerySet) .map_pass_err(scope)?; @@ -2188,7 +2198,7 @@ fn encode_render_pass( query_set, state.pass.base.raw_encoder, &mut state.pass.base.tracker.query_sets, - cmd_enc.as_ref(), + device, query_index, Some(&mut pending_query_resets), &mut state.active_pipeline_statistics_query, @@ -2210,7 +2220,7 @@ fn encode_render_pass( execute_bundle( &mut state, &mut indirect_draw_validation_batcher, - cmd_enc, + device, bundle, ) .map_pass_err(scope)?; @@ -2240,12 +2250,12 @@ fn encode_render_pass( let pending_discard_init_fixups = state.pass.pending_discard_init_fixups; - encoder.close().map_pass_err(pass_scope)?; + parent_state.raw_encoder.close().map_pass_err(pass_scope)?; (trackers, pending_discard_init_fixups, pending_query_resets) }; - let encoder = &mut cmd_buf_data.encoder; - let tracker = &mut cmd_buf_data.trackers; + let encoder = &mut parent_state.raw_encoder; + let tracker = &mut parent_state.tracker; { let transit = encoder @@ -2259,22 +2269,27 @@ fn encode_render_pass( pending_discard_init_fixups.into_iter(), transit, &mut tracker.textures, - &cmd_enc.device, - snatch_guard, + device, + parent_state.snatch_guard, ); pending_query_resets.reset_queries(transit); - CommandEncoder::insert_barriers_from_scope(transit, tracker, &scope, snatch_guard); + CommandEncoder::insert_barriers_from_scope( + transit, + tracker, + &scope, + parent_state.snatch_guard, + ); if let Some(ref indirect_validation) = device.indirect_validation { indirect_validation .draw .inject_validation_pass( device, - snatch_guard, - &mut cmd_buf_data.indirect_draw_validation_resources, - &mut cmd_buf_data.temp_resources, + parent_state.snatch_guard, + parent_state.indirect_draw_validation_resources, + parent_state.temp_resources, transit, indirect_draw_validation_batcher, ) @@ -2289,7 +2304,7 @@ fn encode_render_pass( fn set_pipeline( state: &mut State, - cmd_enc: &Arc, + device: &Arc, pipeline: Arc, ) -> Result<(), RenderPassErrorInner> { api_log!("RenderPass::set_pipeline {}", pipeline.error_ident()); @@ -2304,7 +2319,7 @@ fn set_pipeline( .insert_single(pipeline) .clone(); - pipeline.same_device_as(cmd_enc.as_ref())?; + pipeline.same_device(device)?; state .info @@ -2359,7 +2374,7 @@ fn set_pipeline( // This function is duplicative of `bundle::set_index_buffer`. fn set_index_buffer( state: &mut State, - cmd_enc: &Arc, + device: &Arc, buffer: Arc, index_format: IndexFormat, offset: u64, @@ -2373,7 +2388,7 @@ fn set_index_buffer( .buffers .merge_single(&buffer, wgt::BufferUses::INDEX)?; - buffer.same_device_as(cmd_enc.as_ref())?; + buffer.same_device(device)?; buffer.check_usage(BufferUsages::INDEX)?; @@ -2411,7 +2426,7 @@ fn set_index_buffer( // This function is duplicative of `render::set_vertex_buffer`. fn set_vertex_buffer( state: &mut State, - cmd_enc: &Arc, + device: &Arc, slot: u32, buffer: Arc, offset: u64, @@ -2428,7 +2443,7 @@ fn set_vertex_buffer( .buffers .merge_single(&buffer, wgt::BufferUses::VERTEX)?; - buffer.same_device_as(cmd_enc.as_ref())?; + buffer.same_device(device)?; let max_vertex_buffers = state.pass.base.device.limits.max_vertex_buffers; if slot >= max_vertex_buffers { @@ -2688,7 +2703,7 @@ fn draw_mesh_tasks( fn multi_draw_indirect( state: &mut State, indirect_draw_validation_batcher: &mut crate::indirect_validation::DrawBatcher, - cmd_enc: &Arc, + device: &Arc, indirect_buffer: Arc, offset: u64, count: u32, @@ -2707,7 +2722,7 @@ fn multi_draw_indirect( .device .require_downlevel_flags(wgt::DownlevelFlags::INDIRECT_EXECUTION)?; - indirect_buffer.same_device_as(cmd_enc.as_ref())?; + indirect_buffer.same_device(device)?; indirect_buffer.check_usage(BufferUsages::INDIRECT)?; indirect_buffer.check_destroyed(state.pass.base.snatch_guard)?; @@ -2866,7 +2881,7 @@ fn multi_draw_indirect( fn multi_draw_indirect_count( state: &mut State, - cmd_enc: &Arc, + device: &Arc, indirect_buffer: Arc, offset: u64, count_buffer: Arc, @@ -2895,8 +2910,8 @@ fn multi_draw_indirect_count( .device .require_downlevel_flags(wgt::DownlevelFlags::INDIRECT_EXECUTION)?; - indirect_buffer.same_device_as(cmd_enc.as_ref())?; - count_buffer.same_device_as(cmd_enc.as_ref())?; + indirect_buffer.same_device(device)?; + count_buffer.same_device(device)?; state .pass @@ -2989,14 +3004,14 @@ fn multi_draw_indirect_count( fn execute_bundle( state: &mut State, indirect_draw_validation_batcher: &mut crate::indirect_validation::DrawBatcher, - cmd_enc: &Arc, + device: &Arc, bundle: Arc, ) -> Result<(), RenderPassErrorInner> { api_log!("RenderPass::execute_bundle {}", bundle.error_ident()); let bundle = state.pass.base.tracker.bundles.insert_single(bundle); - bundle.same_device_as(cmd_enc.as_ref())?; + bundle.same_device(device)?; state .info diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index b14831ff5d0..7c631d3a462 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -12,10 +12,12 @@ use wgt::{ use crate::command::Command as TraceCommand; use crate::{ api_log, - command::{clear_texture, CommandEncoderError, EncoderStateError}, - device::{Device, MissingDownlevelFlags}, + command::{ + clear_texture, encoder::EncodingState, ArcCommand, CommandEncoderError, EncoderStateError, + }, + device::MissingDownlevelFlags, global::Global, - id::{BufferId, CommandEncoderId}, + id::{BufferId, CommandEncoderId, TextureId}, init_tracker::{ has_copy_partial_init_tracker_coverage, MemoryInitKind, TextureInitRange, TextureInitTrackerAction, @@ -24,13 +26,12 @@ use crate::{ Buffer, MissingBufferUsageError, MissingTextureUsageError, ParentDevice, RawResourceAccess, Texture, TextureErrorDimension, }, - snatch::SnatchGuard, }; -use super::{ClearError, CommandBufferMutable}; +use super::ClearError; -use super::TexelCopyBufferInfo; -use super::TexelCopyTextureInfo; +type TexelCopyBufferInfo = wgt::TexelCopyBufferInfo; +type TexelCopyTextureInfo = wgt::TexelCopyTextureInfo>; #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum CopySide { @@ -629,13 +630,11 @@ pub(crate) fn validate_copy_within_same_texture( } fn handle_texture_init( + state: &mut EncodingState, init_kind: MemoryInitKind, - cmd_buf_data: &mut CommandBufferMutable, - device: &Device, copy_texture: &TexelCopyTextureInfo, copy_size: &Extent3d, texture: &Arc, - snatch_guard: &SnatchGuard<'_>, ) -> Result<(), ClearError> { let init_action = TextureInitTrackerAction { texture: texture.clone(), @@ -648,13 +647,12 @@ fn handle_texture_init( }; // Register the init action. - let immediate_inits = cmd_buf_data + let immediate_inits = state .texture_memory_actions .register_init_action(&{ init_action }); // In rare cases we may need to insert an init operation immediately onto the command buffer. if !immediate_inits.is_empty() { - let cmd_buf_raw = cmd_buf_data.encoder.open()?; for init in immediate_inits { clear_texture( &init.texture, @@ -662,12 +660,12 @@ fn handle_texture_init( mip_range: init.mip_level..(init.mip_level + 1), layer_range: init.layer..(init.layer + 1), }, - cmd_buf_raw, - &mut cmd_buf_data.trackers.textures, - &device.alignments, - device.zero_buffer.as_ref(), - snatch_guard, - device.instance_flags, + state.raw_encoder, + &mut state.tracker.textures, + &state.device.alignments, + state.device.zero_buffer.as_ref(), + state.snatch_guard, + state.device.instance_flags, )?; } } @@ -680,21 +678,17 @@ fn handle_texture_init( /// Ensure the source texture of a transfer is in the right initialization /// state, and record the state for after the transfer operation. fn handle_src_texture_init( - cmd_buf_data: &mut CommandBufferMutable, - device: &Device, + state: &mut EncodingState, source: &TexelCopyTextureInfo, copy_size: &Extent3d, texture: &Arc, - snatch_guard: &SnatchGuard<'_>, ) -> Result<(), TransferError> { handle_texture_init( + state, MemoryInitKind::NeedsInitializedMemory, - cmd_buf_data, - device, source, copy_size, texture, - snatch_guard, )?; Ok(()) } @@ -704,12 +698,10 @@ fn handle_src_texture_init( /// Ensure the destination texture of a transfer is in the right initialization /// state, and record the state for after the transfer operation. fn handle_dst_texture_init( - cmd_buf_data: &mut CommandBufferMutable, - device: &Device, - destination: &TexelCopyTextureInfo, + state: &mut EncodingState, + destination: &wgt::TexelCopyTextureInfo>, copy_size: &Extent3d, texture: &Arc, - snatch_guard: &SnatchGuard<'_>, ) -> Result<(), TransferError> { // Attention: If we don't write full texture subresources, we need to a full // clear first since we don't track subrects. This means that in rare cases @@ -725,15 +717,7 @@ fn handle_dst_texture_init( MemoryInitKind::ImplicitlyInitialized }; - handle_texture_init( - dst_init_kind, - cmd_buf_data, - device, - destination, - copy_size, - texture, - snatch_guard, - )?; + handle_texture_init(state, dst_init_kind, destination, copy_size, texture)?; Ok(()) } @@ -742,9 +726,8 @@ fn handle_dst_texture_init( /// Ensures that the transfer will not read from uninitialized memory, and updates /// the initialization state information to reflect the transfer. fn handle_buffer_init( - cmd_buf_data: &mut CommandBufferMutable, - info: &TexelCopyBufferInfo, - buffer: &Arc, + state: &mut EncodingState, + info: &wgt::TexelCopyBufferInfo>, direction: CopySide, required_buffer_bytes_in_copy: BufferAddress, is_contiguous: bool, @@ -752,6 +735,7 @@ fn handle_buffer_init( const ALIGN_SIZE: BufferAddress = wgt::COPY_BUFFER_ALIGNMENT; const ALIGN_MASK: BufferAddress = wgt::COPY_BUFFER_ALIGNMENT - 1; + let buffer = &info.buffer; let start = info.layout.offset; let end = info.layout.offset + required_buffer_bytes_in_copy; if !is_contiguous || direction == CopySide::Source { @@ -767,13 +751,13 @@ fn handle_buffer_init( // Adjust the start/end outwards to 4B alignment. let aligned_start = start & !ALIGN_MASK; let aligned_end = (end + ALIGN_MASK) & !ALIGN_MASK; - cmd_buf_data.buffer_memory_init_actions.extend( - buffer.initialization_status.read().create_action( + state + .buffer_memory_init_actions + .extend(buffer.initialization_status.read().create_action( buffer, aligned_start..aligned_end, MemoryInitKind::NeedsInitializedMemory, - ), - ); + )); } else { // If the transfer will write a contiguous region of the buffer, then we // don't need to initialize that region. @@ -787,7 +771,7 @@ fn handle_buffer_init( let aligned_start = (start + ALIGN_MASK) & !ALIGN_MASK; let aligned_end = end & !ALIGN_MASK; if aligned_start != start { - cmd_buf_data.buffer_memory_init_actions.extend( + state.buffer_memory_init_actions.extend( buffer.initialization_status.read().create_action( buffer, aligned_start - ALIGN_SIZE..aligned_start, @@ -796,7 +780,7 @@ fn handle_buffer_init( ); } if aligned_start != aligned_end { - cmd_buf_data.buffer_memory_init_actions.extend( + state.buffer_memory_init_actions.extend( buffer.initialization_status.read().create_action( buffer, aligned_start..aligned_end, @@ -810,7 +794,7 @@ fn handle_buffer_init( // final size of the buffer. The final size of the buffer is not // readily available, but was rounded up to COPY_BUFFER_ALIGNMENT, // so no overrun is possible. - cmd_buf_data.buffer_memory_init_actions.extend( + state.buffer_memory_init_actions.extend( buffer.initialization_status.read().create_action( buffer, aligned_end..aligned_end + ALIGN_SIZE, @@ -840,17 +824,26 @@ impl Global { let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - copy_buffer_to_buffer( - cmd_buf_data, - hub, - &cmd_enc, - source, - source_offset, - destination, - destination_offset, + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::CopyBufferToBuffer { + src: source, + src_offset: source_offset, + dst: destination, + dst_offset: destination_offset, size, - ) + }); + } + + cmd_buf_data.push_with(|| -> Result<_, CommandEncoderError> { + Ok(ArcCommand::CopyBufferToBuffer { + src: self.resolve_buffer_id(source)?, + src_offset: source_offset, + dst: self.resolve_buffer_id(destination)?, + dst_offset: destination_offset, + size, + }) }) } @@ -858,7 +851,7 @@ impl Global { &self, command_encoder_id: CommandEncoderId, source: &TexelCopyBufferInfo, - destination: &TexelCopyTextureInfo, + destination: &wgt::TexelCopyTextureInfo, copy_size: &Extent3d, ) -> Result<(), EncoderStateError> { profiling::scope!("CommandEncoder::copy_buffer_to_texture"); @@ -868,19 +861,39 @@ impl Global { destination.texture ); - let hub = &self.hub; - - let cmd_enc = hub.command_encoders.get(command_encoder_id); + let cmd_enc = self.hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - copy_buffer_to_texture(cmd_buf_data, hub, &cmd_enc, source, destination, copy_size) + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::CopyBufferToTexture { + src: *source, + dst: *destination, + size: *copy_size, + }); + } + + cmd_buf_data.push_with(|| -> Result<_, CommandEncoderError> { + Ok(ArcCommand::CopyBufferToTexture { + src: wgt::TexelCopyBufferInfo::> { + buffer: self.resolve_buffer_id(source.buffer)?, + layout: source.layout, + }, + dst: wgt::TexelCopyTextureInfo::> { + texture: self.resolve_texture_id(destination.texture)?, + mip_level: destination.mip_level, + origin: destination.origin, + aspect: destination.aspect, + }, + size: *copy_size, + }) }) } pub fn command_encoder_copy_texture_to_buffer( &self, command_encoder_id: CommandEncoderId, - source: &TexelCopyTextureInfo, + source: &wgt::TexelCopyTextureInfo, destination: &TexelCopyBufferInfo, copy_size: &Extent3d, ) -> Result<(), EncoderStateError> { @@ -891,20 +904,40 @@ impl Global { destination.buffer ); - let hub = &self.hub; - - let cmd_enc = hub.command_encoders.get(command_encoder_id); + let cmd_enc = self.hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - copy_texture_to_buffer(cmd_buf_data, hub, &cmd_enc, source, destination, copy_size) + + #[cfg(feature = "trace")] + if let Some(list) = cmd_buf_data.trace() { + list.push(TraceCommand::CopyTextureToBuffer { + src: *source, + dst: *destination, + size: *copy_size, + }); + } + + cmd_buf_data.push_with(|| -> Result<_, CommandEncoderError> { + Ok(ArcCommand::CopyTextureToBuffer { + src: wgt::TexelCopyTextureInfo::> { + texture: self.resolve_texture_id(source.texture)?, + mip_level: source.mip_level, + origin: source.origin, + aspect: source.aspect, + }, + dst: wgt::TexelCopyBufferInfo::> { + buffer: self.resolve_buffer_id(destination.buffer)?, + layout: destination.layout, + }, + size: *copy_size, + }) }) } pub fn command_encoder_copy_texture_to_texture( &self, command_encoder_id: CommandEncoderId, - source: &TexelCopyTextureInfo, - destination: &TexelCopyTextureInfo, + source: &wgt::TexelCopyTextureInfo, + destination: &wgt::TexelCopyTextureInfo, copy_size: &Extent3d, ) -> Result<(), EncoderStateError> { profiling::scope!("CommandEncoder::copy_texture_to_texture"); @@ -914,76 +947,76 @@ impl Global { destination.texture ); - let hub = &self.hub; - - let cmd_enc = hub.command_encoders.get(command_encoder_id); + let cmd_enc = self.hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - copy_texture_to_texture(cmd_buf_data, hub, &cmd_enc, source, destination, copy_size) + + #[cfg(feature = "trace")] + if let Some(ref mut list) = cmd_buf_data.trace() { + list.push(TraceCommand::CopyTextureToTexture { + src: *source, + dst: *destination, + size: *copy_size, + }); + } + + cmd_buf_data.push_with(|| -> Result<_, CommandEncoderError> { + Ok(ArcCommand::CopyTextureToTexture { + src: wgt::TexelCopyTextureInfo { + texture: self.resolve_texture_id(source.texture)?, + mip_level: source.mip_level, + origin: source.origin, + aspect: source.aspect, + }, + dst: wgt::TexelCopyTextureInfo { + texture: self.resolve_texture_id(destination.texture)?, + mip_level: destination.mip_level, + origin: destination.origin, + aspect: destination.aspect, + }, + size: *copy_size, + }) }) } } -fn copy_buffer_to_buffer( - cmd_buf_data: &mut CommandBufferMutable, - hub: &crate::hub::Hub, - cmd_enc: &Arc, - source: BufferId, +pub(super) fn copy_buffer_to_buffer( + state: &mut EncodingState, + src_buffer: &Arc, source_offset: BufferAddress, - destination: BufferId, + dst_buffer: &Arc, destination_offset: BufferAddress, size: Option, ) -> Result<(), CommandEncoderError> { - let device = &cmd_enc.device; - device.check_is_valid()?; - - if source == destination { + if src_buffer.is_equal(dst_buffer) { return Err(TransferError::SameSourceDestinationBuffer.into()); } - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::CopyBufferToBuffer { - src: source, - src_offset: source_offset, - dst: destination, - dst_offset: destination_offset, - size, - }); - } - - let snatch_guard = device.snatchable_lock.read(); - - let src_buffer = hub.buffers.get(source).get()?; + src_buffer.same_device(state.device)?; - src_buffer.same_device_as(cmd_enc.as_ref())?; - - let src_pending = cmd_buf_data - .trackers + let src_pending = state + .tracker .buffers - .set_single(&src_buffer, wgt::BufferUses::COPY_SRC); + .set_single(src_buffer, wgt::BufferUses::COPY_SRC); - let src_raw = src_buffer.try_raw(&snatch_guard)?; + let src_raw = src_buffer.try_raw(state.snatch_guard)?; src_buffer .check_usage(BufferUsages::COPY_SRC) .map_err(TransferError::MissingBufferUsage)?; // expecting only a single barrier - let src_barrier = src_pending.map(|pending| pending.into_hal(&src_buffer, &snatch_guard)); - - let dst_buffer = hub.buffers.get(destination).get()?; + let src_barrier = src_pending.map(|pending| pending.into_hal(src_buffer, state.snatch_guard)); - dst_buffer.same_device_as(cmd_enc.as_ref())?; + dst_buffer.same_device(state.device)?; - let dst_pending = cmd_buf_data - .trackers + let dst_pending = state + .tracker .buffers - .set_single(&dst_buffer, wgt::BufferUses::COPY_DST); + .set_single(dst_buffer, wgt::BufferUses::COPY_DST); - let dst_raw = dst_buffer.try_raw(&snatch_guard)?; + let dst_raw = dst_buffer.try_raw(state.snatch_guard)?; dst_buffer .check_usage(BufferUsages::COPY_DST) .map_err(TransferError::MissingBufferUsage)?; - let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); + let dst_barrier = dst_pending.map(|pending| pending.into_hal(dst_buffer, state.snatch_guard)); let (size, source_end_offset) = match size { Some(size) => (size, source_offset + size), @@ -999,7 +1032,8 @@ fn copy_buffer_to_buffer( if destination_offset % wgt::COPY_BUFFER_ALIGNMENT != 0 { return Err(TransferError::UnalignedBufferOffset(destination_offset).into()); } - if !device + if !state + .device .downlevel .flags .contains(wgt::DownlevelFlags::UNRESTRICTED_INDEX_BUFFER) @@ -1046,64 +1080,51 @@ fn copy_buffer_to_buffer( } // Make sure source is initialized memory and mark dest as initialized. - cmd_buf_data.buffer_memory_init_actions.extend( - dst_buffer.initialization_status.read().create_action( - &dst_buffer, + state + .buffer_memory_init_actions + .extend(dst_buffer.initialization_status.read().create_action( + dst_buffer, destination_offset..(destination_offset + size), MemoryInitKind::ImplicitlyInitialized, - ), - ); - cmd_buf_data.buffer_memory_init_actions.extend( - src_buffer.initialization_status.read().create_action( - &src_buffer, + )); + state + .buffer_memory_init_actions + .extend(src_buffer.initialization_status.read().create_action( + src_buffer, source_offset..(source_offset + size), MemoryInitKind::NeedsInitializedMemory, - ), - ); + )); let region = hal::BufferCopy { src_offset: source_offset, dst_offset: destination_offset, size: wgt::BufferSize::new(size).unwrap(), }; - let cmd_buf_raw = cmd_buf_data.encoder.open()?; let barriers = src_barrier .into_iter() .chain(dst_barrier) .collect::>(); unsafe { - cmd_buf_raw.transition_buffers(&barriers); - cmd_buf_raw.copy_buffer_to_buffer(src_raw, dst_raw, &[region]); + state.raw_encoder.transition_buffers(&barriers); + state + .raw_encoder + .copy_buffer_to_buffer(src_raw, dst_raw, &[region]); } Ok(()) } -fn copy_buffer_to_texture( - cmd_buf_data: &mut CommandBufferMutable, - hub: &crate::hub::Hub, - cmd_enc: &Arc, - source: &TexelCopyBufferInfo, - destination: &TexelCopyTextureInfo, +pub(super) fn copy_buffer_to_texture( + state: &mut EncodingState, + source: &wgt::TexelCopyBufferInfo>, + destination: &wgt::TexelCopyTextureInfo>, copy_size: &Extent3d, ) -> Result<(), CommandEncoderError> { - let device = &cmd_enc.device; - device.check_is_valid()?; - - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::CopyBufferToTexture { - src: *source, - dst: *destination, - size: *copy_size, - }); - } - - let dst_texture = hub.textures.get(destination.texture).get()?; - let src_buffer = hub.buffers.get(source.buffer).get()?; + let dst_texture = &destination.texture; + let src_buffer = &source.buffer; - dst_texture.same_device_as(cmd_enc.as_ref())?; - src_buffer.same_device_as(cmd_enc.as_ref())?; + dst_texture.same_device(state.device)?; + src_buffer.same_device(state.device)?; let (hal_copy_size, array_layer_count) = validate_texture_copy_range( destination, @@ -1112,12 +1133,10 @@ fn copy_buffer_to_texture( copy_size, )?; - let (dst_range, dst_base) = extract_texture_selector(destination, copy_size, &dst_texture)?; - - let snatch_guard = device.snatchable_lock.read(); + let (dst_range, dst_base) = extract_texture_selector(destination, copy_size, dst_texture)?; - let src_raw = src_buffer.try_raw(&snatch_guard)?; - let dst_raw = dst_texture.try_raw(&snatch_guard)?; + let src_raw = src_buffer.try_raw(state.snatch_guard)?; + let dst_raw = dst_texture.try_raw(state.snatch_guard)?; if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth_or_array_layers == 0 { log::trace!("Ignoring copy_buffer_to_texture of size 0"); @@ -1127,30 +1146,23 @@ fn copy_buffer_to_texture( // Handle texture init *before* dealing with barrier transitions so we // have an easier time inserting "immediate-inits" that may be required // by prior discards in rare cases. - handle_dst_texture_init( - cmd_buf_data, - device, - destination, - copy_size, - &dst_texture, - &snatch_guard, - )?; + handle_dst_texture_init(state, destination, copy_size, dst_texture)?; - let src_pending = cmd_buf_data - .trackers + let src_pending = state + .tracker .buffers - .set_single(&src_buffer, wgt::BufferUses::COPY_SRC); + .set_single(src_buffer, wgt::BufferUses::COPY_SRC); src_buffer .check_usage(BufferUsages::COPY_SRC) .map_err(TransferError::MissingBufferUsage)?; - let src_barrier = src_pending.map(|pending| pending.into_hal(&src_buffer, &snatch_guard)); + let src_barrier = src_pending.map(|pending| pending.into_hal(src_buffer, state.snatch_guard)); - let dst_pending = cmd_buf_data.trackers.textures.set_single( - &dst_texture, - dst_range, - wgt::TextureUses::COPY_DST, - ); + let dst_pending = + state + .tracker + .textures + .set_single(dst_texture, dst_range, wgt::TextureUses::COPY_DST); dst_texture .check_usage(TextureUsages::COPY_DST) .map_err(TransferError::MissingTextureUsage)?; @@ -1179,15 +1191,15 @@ fn copy_buffer_to_texture( )?; if dst_texture.desc.format.is_depth_stencil_format() { - device + state + .device .require_downlevel_flags(wgt::DownlevelFlags::DEPTH_TEXTURE_AND_BUFFER_COPIES) .map_err(TransferError::from)?; } handle_buffer_init( - cmd_buf_data, + state, source, - &src_buffer, CopySide::Source, required_buffer_bytes_in_copy, is_contiguous, @@ -1207,50 +1219,35 @@ fn copy_buffer_to_texture( }) .collect::>(); - let cmd_buf_raw = cmd_buf_data.encoder.open()?; unsafe { - cmd_buf_raw.transition_textures(&dst_barrier); - cmd_buf_raw.transition_buffers(src_barrier.as_slice()); - cmd_buf_raw.copy_buffer_to_texture(src_raw, dst_raw, ®ions); + state.raw_encoder.transition_textures(&dst_barrier); + state.raw_encoder.transition_buffers(src_barrier.as_slice()); + state + .raw_encoder + .copy_buffer_to_texture(src_raw, dst_raw, ®ions); } Ok(()) } -fn copy_texture_to_buffer( - cmd_buf_data: &mut CommandBufferMutable, - hub: &crate::hub::Hub, - cmd_enc: &Arc, +pub(super) fn copy_texture_to_buffer( + state: &mut EncodingState, source: &TexelCopyTextureInfo, - destination: &TexelCopyBufferInfo, + destination: &wgt::TexelCopyBufferInfo>, copy_size: &Extent3d, ) -> Result<(), CommandEncoderError> { - let device = &cmd_enc.device; - device.check_is_valid()?; - - #[cfg(feature = "trace")] - if let Some(list) = cmd_buf_data.trace_commands.as_mut() { - list.push(TraceCommand::CopyTextureToBuffer { - src: *source, - dst: *destination, - size: *copy_size, - }); - } - - let src_texture = hub.textures.get(source.texture).get()?; - let dst_buffer = hub.buffers.get(destination.buffer).get()?; + let src_texture = &source.texture; + let dst_buffer = &destination.buffer; - src_texture.same_device_as(cmd_enc.as_ref())?; - dst_buffer.same_device_as(cmd_enc.as_ref())?; + src_texture.same_device(state.device)?; + dst_buffer.same_device(state.device)?; let (hal_copy_size, array_layer_count) = validate_texture_copy_range(source, &src_texture.desc, CopySide::Source, copy_size)?; - let (src_range, src_base) = extract_texture_selector(source, copy_size, &src_texture)?; + let (src_range, src_base) = extract_texture_selector(source, copy_size, src_texture)?; - let snatch_guard = device.snatchable_lock.read(); - - let src_raw = src_texture.try_raw(&snatch_guard)?; + let src_raw = src_texture.try_raw(state.snatch_guard)?; src_texture .check_usage(TextureUsages::COPY_SRC) .map_err(TransferError::MissingTextureUsage)?; @@ -1284,12 +1281,13 @@ fn copy_texture_to_buffer( )?; if src_texture.desc.format.is_depth_stencil_format() { - device + state + .device .require_downlevel_flags(wgt::DownlevelFlags::DEPTH_TEXTURE_AND_BUFFER_COPIES) .map_err(TransferError::from)?; } - let dst_raw = dst_buffer.try_raw(&snatch_guard)?; + let dst_raw = dst_buffer.try_raw(state.snatch_guard)?; dst_buffer .check_usage(BufferUsages::COPY_DST) .map_err(TransferError::MissingBufferUsage)?; @@ -1302,35 +1300,27 @@ fn copy_texture_to_buffer( // Handle texture init *before* dealing with barrier transitions so we // have an easier time inserting "immediate-inits" that may be required // by prior discards in rare cases. - handle_src_texture_init( - cmd_buf_data, - device, - source, - copy_size, - &src_texture, - &snatch_guard, - )?; + handle_src_texture_init(state, source, copy_size, src_texture)?; - let src_pending = cmd_buf_data.trackers.textures.set_single( - &src_texture, - src_range, - wgt::TextureUses::COPY_SRC, - ); + let src_pending = + state + .tracker + .textures + .set_single(src_texture, src_range, wgt::TextureUses::COPY_SRC); let src_barrier = src_pending .map(|pending| pending.into_hal(src_raw)) .collect::>(); - let dst_pending = cmd_buf_data - .trackers + let dst_pending = state + .tracker .buffers - .set_single(&dst_buffer, wgt::BufferUses::COPY_DST); + .set_single(dst_buffer, wgt::BufferUses::COPY_DST); - let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); + let dst_barrier = dst_pending.map(|pending| pending.into_hal(dst_buffer, state.snatch_guard)); handle_buffer_init( - cmd_buf_data, + state, destination, - &dst_buffer, CopySide::Destination, required_buffer_bytes_in_copy, is_contiguous, @@ -1349,43 +1339,31 @@ fn copy_texture_to_buffer( } }) .collect::>(); - let cmd_buf_raw = cmd_buf_data.encoder.open()?; unsafe { - cmd_buf_raw.transition_buffers(dst_barrier.as_slice()); - cmd_buf_raw.transition_textures(&src_barrier); - cmd_buf_raw.copy_texture_to_buffer(src_raw, wgt::TextureUses::COPY_SRC, dst_raw, ®ions); + state.raw_encoder.transition_buffers(dst_barrier.as_slice()); + state.raw_encoder.transition_textures(&src_barrier); + state.raw_encoder.copy_texture_to_buffer( + src_raw, + wgt::TextureUses::COPY_SRC, + dst_raw, + ®ions, + ); } Ok(()) } -fn copy_texture_to_texture( - cmd_buf_data: &mut CommandBufferMutable, - hub: &crate::hub::Hub, - cmd_enc: &Arc, +pub(super) fn copy_texture_to_texture( + state: &mut EncodingState, source: &TexelCopyTextureInfo, destination: &TexelCopyTextureInfo, copy_size: &Extent3d, ) -> Result<(), CommandEncoderError> { - let device = &cmd_enc.device; - device.check_is_valid()?; - - let snatch_guard = device.snatchable_lock.read(); - - #[cfg(feature = "trace")] - if let Some(ref mut list) = cmd_buf_data.trace_commands { - list.push(TraceCommand::CopyTextureToTexture { - src: *source, - dst: *destination, - size: *copy_size, - }); - } + let src_texture = &source.texture; + let dst_texture = &destination.texture; - let src_texture = hub.textures.get(source.texture).get()?; - let dst_texture = hub.textures.get(destination.texture).get()?; - - src_texture.same_device_as(cmd_enc.as_ref())?; - dst_texture.same_device_as(cmd_enc.as_ref())?; + src_texture.same_device(state.device)?; + dst_texture.same_device(state.device)?; // src and dst texture format must be copy-compatible // https://gpuweb.github.io/gpuweb/#copy-compatible @@ -1407,7 +1385,7 @@ fn copy_texture_to_texture( copy_size, )?; - if Arc::as_ptr(&src_texture) == Arc::as_ptr(&dst_texture) { + if Arc::as_ptr(src_texture) == Arc::as_ptr(dst_texture) { validate_copy_within_same_texture( source, destination, @@ -1416,8 +1394,8 @@ fn copy_texture_to_texture( )?; } - let (src_range, src_tex_base) = extract_texture_selector(source, copy_size, &src_texture)?; - let (dst_range, dst_tex_base) = extract_texture_selector(destination, copy_size, &dst_texture)?; + let (src_range, src_tex_base) = extract_texture_selector(source, copy_size, src_texture)?; + let (dst_range, dst_tex_base) = extract_texture_selector(destination, copy_size, dst_texture)?; let src_texture_aspects = hal::FormatAspects::from(src_texture.desc.format); let dst_texture_aspects = hal::FormatAspects::from(dst_texture.desc.format); if src_tex_base.aspect != src_texture_aspects { @@ -1438,28 +1416,14 @@ fn copy_texture_to_texture( // Handle texture init *before* dealing with barrier transitions so we // have an easier time inserting "immediate-inits" that may be required // by prior discards in rare cases. - handle_src_texture_init( - cmd_buf_data, - device, - source, - copy_size, - &src_texture, - &snatch_guard, - )?; - handle_dst_texture_init( - cmd_buf_data, - device, - destination, - copy_size, - &dst_texture, - &snatch_guard, - )?; + handle_src_texture_init(state, source, copy_size, src_texture)?; + handle_dst_texture_init(state, destination, copy_size, dst_texture)?; - let src_raw = src_texture.try_raw(&snatch_guard)?; + let src_raw = src_texture.try_raw(state.snatch_guard)?; src_texture .check_usage(TextureUsages::COPY_SRC) .map_err(TransferError::MissingTextureUsage)?; - let dst_raw = dst_texture.try_raw(&snatch_guard)?; + let dst_raw = dst_texture.try_raw(state.snatch_guard)?; dst_texture .check_usage(TextureUsages::COPY_DST) .map_err(TransferError::MissingTextureUsage)?; @@ -1469,11 +1433,11 @@ fn copy_texture_to_texture( return Ok(()); } - let src_pending = cmd_buf_data.trackers.textures.set_single( - &src_texture, - src_range, - wgt::TextureUses::COPY_SRC, - ); + let src_pending = + state + .tracker + .textures + .set_single(src_texture, src_range, wgt::TextureUses::COPY_SRC); //TODO: try to avoid this the collection. It's needed because both // `src_pending` and `dst_pending` try to hold `trackers.textures` mutably. @@ -1481,11 +1445,11 @@ fn copy_texture_to_texture( .map(|pending| pending.into_hal(src_raw)) .collect(); - let dst_pending = cmd_buf_data.trackers.textures.set_single( - &dst_texture, - dst_range, - wgt::TextureUses::COPY_DST, - ); + let dst_pending = + state + .tracker + .textures + .set_single(dst_texture, dst_range, wgt::TextureUses::COPY_DST); barriers.extend(dst_pending.map(|pending| pending.into_hal(dst_raw))); let hal_copy_size = hal::CopyExtent { @@ -1520,10 +1484,14 @@ fn copy_texture_to_texture( } else { regions.collect::>() }; - let cmd_buf_raw = cmd_buf_data.encoder.open()?; unsafe { - cmd_buf_raw.transition_textures(&barriers); - cmd_buf_raw.copy_texture_to_texture(src_raw, wgt::TextureUses::COPY_SRC, dst_raw, ®ions); + state.raw_encoder.transition_textures(&barriers); + state.raw_encoder.copy_texture_to_texture( + src_raw, + wgt::TextureUses::COPY_SRC, + dst_raw, + ®ions, + ); } Ok(()) diff --git a/wgpu-core/src/command/transition_resources.rs b/wgpu-core/src/command/transition_resources.rs index 3b4dfe83bde..9b6abb196fd 100644 --- a/wgpu-core/src/command/transition_resources.rs +++ b/wgpu-core/src/command/transition_resources.rs @@ -1,12 +1,14 @@ +use alloc::{sync::Arc, vec::Vec}; + use thiserror::Error; use wgt::error::{ErrorType, WebGpuError}; use crate::{ - command::{CommandEncoder, CommandEncoderError, EncoderStateError}, + command::{encoder::EncodingState, ArcCommand, CommandEncoder, EncoderStateError}, device::DeviceError, global::Global, id::{BufferId, CommandEncoderId, TextureId}, - resource::{InvalidResourceError, ParentDevice}, + resource::{Buffer, InvalidResourceError, ParentDevice, Texture}, track::ResourceUsageCompatibilityError, }; @@ -24,52 +26,70 @@ impl Global { // Lock command encoder for recording let cmd_enc = hub.command_encoders.get(command_encoder_id); let mut cmd_buf_data = cmd_enc.data.lock(); - cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> { - // Get and lock device - let device = &cmd_enc.device; - device.check_is_valid()?; - let snatch_guard = &device.snatchable_lock.read(); - - let mut usage_scope = device.new_usage_scope(); - let indices = &device.tracker_indices; - usage_scope.buffers.set_size(indices.buffers.size()); - usage_scope.textures.set_size(indices.textures.size()); + cmd_buf_data.push_with(|| -> Result<_, TransitionResourcesError> { + Ok(ArcCommand::TransitionResources { + buffer_transitions: buffer_transitions + .map(|t| { + Ok(wgt::BufferTransition { + buffer: self.resolve_buffer_id(t.buffer)?, + state: t.state, + }) + }) + .collect::>()?, + texture_transitions: texture_transitions + .map(|t| { + Ok(wgt::TextureTransition { + texture: self.resolve_texture_id(t.texture)?, + selector: t.selector, + state: t.state, + }) + }) + .collect::>()?, + }) + }) + } +} - // Process buffer transitions - for buffer_transition in buffer_transitions { - let buffer = hub.buffers.get(buffer_transition.buffer).get()?; - buffer.same_device_as(cmd_enc.as_ref())?; +pub(crate) fn transition_resources( + state: &mut EncodingState, + buffer_transitions: Vec>>, + texture_transitions: Vec>>, +) -> Result<(), TransitionResourcesError> { + let mut usage_scope = state.device.new_usage_scope(); + let indices = &state.device.tracker_indices; + usage_scope.buffers.set_size(indices.buffers.size()); + usage_scope.textures.set_size(indices.textures.size()); - usage_scope - .buffers - .merge_single(&buffer, buffer_transition.state)?; - } + // Process buffer transitions + for buffer_transition in buffer_transitions { + buffer_transition.buffer.same_device(state.device)?; - // Process texture transitions - for texture_transition in texture_transitions { - let texture = hub.textures.get(texture_transition.texture).get()?; - texture.same_device_as(cmd_enc.as_ref())?; + usage_scope + .buffers + .merge_single(&buffer_transition.buffer, buffer_transition.state)?; + } - unsafe { - usage_scope.textures.merge_single( - &texture, - texture_transition.selector, - texture_transition.state, - ) - }?; - } + // Process texture transitions + for texture_transition in texture_transitions { + texture_transition.texture.same_device(state.device)?; - // Record any needed barriers based on tracker data - let cmd_buf_raw = cmd_buf_data.encoder.open()?; - CommandEncoder::insert_barriers_from_scope( - cmd_buf_raw, - &mut cmd_buf_data.trackers, - &usage_scope, - snatch_guard, - ); - Ok(()) - }) + unsafe { + usage_scope.textures.merge_single( + &texture_transition.texture, + texture_transition.selector, + texture_transition.state, + ) + }?; } + + // Record any needed barriers based on tracker data + CommandEncoder::insert_barriers_from_scope( + state.raw_encoder, + state.tracker, + &usage_scope, + state.snatch_guard, + ); + Ok(()) } /// Error encountered while attempting to perform [`Global::command_encoder_transition_resources`]. diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index 3518375d885..29165667815 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -21,7 +21,7 @@ use crate::{ device::{DeviceError, MissingFeatures}, id::{BlasId, BufferId, TlasId}, resource::{ - Blas, BlasCompactCallback, BlasPrepareCompactResult, DestroyedResourceError, + Blas, BlasCompactCallback, BlasPrepareCompactResult, Buffer, DestroyedResourceError, InvalidResourceError, MissingBufferUsageError, ResourceErrorIdent, Tlas, }, }; @@ -304,6 +304,7 @@ pub(crate) enum AsAction { UseTlas(Arc), } +/// Like [`BlasTriangleGeometry`], but with owned data. #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct TraceBlasTriangleGeometry { @@ -347,6 +348,55 @@ pub struct TraceTlasPackage { pub lowest_unmodified: u32, } +/// Like [`BlasTriangleGeometry`], but with `Arc`s. +#[derive(Debug, Clone)] +pub struct ArcBlasTriangleGeometry { + pub size: wgt::BlasTriangleGeometrySizeDescriptor, + pub vertex_buffer: Arc, + pub index_buffer: Option>, + pub transform_buffer: Option>, + pub first_vertex: u32, + pub vertex_stride: BufferAddress, + pub first_index: Option, + pub transform_buffer_offset: Option, +} + +/// [`BlasTriangleGeometry`], without the resources. +#[derive(Debug, Clone)] +pub struct BlasTriangleGeometryInfo { + pub size: wgt::BlasTriangleGeometrySizeDescriptor, + pub first_vertex: u32, + pub vertex_stride: BufferAddress, + pub first_index: Option, + pub transform_buffer_offset: Option, +} + +#[derive(Debug, Clone)] +pub enum ArcBlasGeometries { + TriangleGeometries(Vec), +} + +#[derive(Debug, Clone)] +pub struct ArcBlasBuildEntry { + pub blas: Arc, + pub geometries: ArcBlasGeometries, +} + +#[derive(Debug, Clone)] +pub struct ArcTlasInstance { + pub blas: Arc, + pub transform: [f32; 12], + pub custom_data: u32, + pub mask: u8, +} + +#[derive(Debug, Clone)] +pub struct ArcTlasPackage { + pub tlas: Arc, + pub instances: Vec>, + pub lowest_unmodified: u32, +} + #[derive(Clone, Debug, Error)] pub enum BlasPrepareCompactError { #[error(transparent)] diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 7674c0a95d8..aba8542c520 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -5365,7 +5365,7 @@ bitflags::bitflags! { } /// A buffer transition for use with `CommandEncoder::transition_resources`. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct BufferTransition { /// The buffer to transition. pub buffer: T, @@ -5668,7 +5668,7 @@ bitflags::bitflags! { } /// A texture transition for use with `CommandEncoder::transition_resources`. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct TextureTransition { /// The texture to transition. pub texture: T, diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index b39e846efe3..074b1239029 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -397,8 +397,8 @@ fn map_buffer_copy_view( fn map_texture_copy_view( view: crate::TexelCopyTextureInfo<'_>, -) -> wgc::command::TexelCopyTextureInfo { - wgc::command::TexelCopyTextureInfo { +) -> wgt::TexelCopyTextureInfo { + wgt::TexelCopyTextureInfo { texture: view.texture.inner.as_core().id, mip_level: view.mip_level, origin: view.origin, From b3423dc6c491eea1389c76a6b3f040db60cd6d9c Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Wed, 17 Sep 2025 16:47:26 -0400 Subject: [PATCH 232/303] =?UTF-8?q?chore:=20update=20min.=20req.=20for=20`?= =?UTF-8?q?smallvec`=200.13.1=20=E2=86=92=200.14?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 7379a6b594b..89324c3d930 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -182,7 +182,7 @@ rustc-hash = { version = "1.1", default-features = false } serde_json = "1.0.143" serde = { version = "1.0.219", default-features = false } shell-words = "1" -smallvec = "1.13.1" +smallvec = "1.14" spirv = "0.3" static_assertions = "1.1" strum = { version = "0.27", default-features = false, features = ["derive"] } From 1f88dfa6e0242de7bfd34618542384c199bc1cca Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Wed, 17 Sep 2025 16:51:36 -0400 Subject: [PATCH 233/303] style: `Cargo.toml`: strip trailing whitespace --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 89324c3d930..b4250fecc37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -169,7 +169,7 @@ pp-rs = "0.2.1" profiling = { version = "1.0.1", default-features = false } quote = "1.0.38" raw-window-handle = { version = "0.6.2", default-features = false } -rwh_05 = { version = "0.5.2", package = "raw-window-handle" } # temporary compatibility for glutin-winit +rwh_05 = { version = "0.5.2", package = "raw-window-handle" } # temporary compatibility for glutin-winit rayon = "1.3" regex-lite = "0.1" renderdoc-sys = "1" From 157134293c0e18159ee2dc350c995a9324d00c14 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Wed, 17 Sep 2025 16:58:06 -0400 Subject: [PATCH 234/303] chore: ignore `rustc-hash` 1.1.0 in `cargo-deny` check for dupes --- .deny.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/.deny.toml b/.deny.toml index f730a23c215..15a168aa093 100644 --- a/.deny.toml +++ b/.deny.toml @@ -5,6 +5,7 @@ skip-tree = [ { name = "winit", version = "0.29" }, { name = "rustc_version", version = "0.2.3" }, { name = "miniz_oxide", version = "0.7.4" }, + { name = "rustc-hash", version = "1.1.0" }, # introduced by Deno, to be investigated { name = "strum_macros", version = "0.25.3" }, From 9aeb5a4079f4539b6b77eb0141acbe654f247aae Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Wed, 17 Sep 2025 17:06:35 -0400 Subject: [PATCH 235/303] chore: update min. req. for `libc` to 0.2.171 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index b4250fecc37..0671e327fd8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -135,7 +135,7 @@ indicatif = "0.18" itertools = { version = "0.14" } jobserver = "0.1" ktx2 = "0.4" -libc = { version = "0.2.168", default-features = false } +libc = { version = "0.2.171", default-features = false } # See https://github.com/rust-fuzz/libfuzzer/issues/126 libfuzzer-sys = ">0.4.0,<=0.4.7" libloading = "0.8" From a6c71911a81e63b0e01da6c8ae14b95c248fe0c5 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Wed, 17 Sep 2025 17:09:26 -0400 Subject: [PATCH 236/303] chore: update min. req. for `tokio` to 1.45.1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 0671e327fd8..9a813ba14dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -244,7 +244,7 @@ deno_webidl = "0.192.0" deno_webgpu = { version = "0.157.0", path = "./deno_webgpu" } deno_unsync = "0.4.2" deno_error = "0.5.5" -tokio = "1.39" +tokio = "1.45.1" termcolor = "1.1.3" # android dependencies From 5093585d5bee6d092e87683aa2723ca1e55f4ab9 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Wed, 17 Sep 2025 17:12:23 -0400 Subject: [PATCH 237/303] chore: update min. req. for `indexmap` to 2.8 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 9a813ba14dd..81b4b6212b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -130,7 +130,7 @@ hashbrown = { version = "0.16", default-features = false, features = [ heck = "0.5" hexf-parse = "0.2" image = { version = "0.25", default-features = false, features = ["png"] } -indexmap = { version = "2.7", default-features = false } +indexmap = { version = "2.8", default-features = false } indicatif = "0.18" itertools = { version = "0.14" } jobserver = "0.1" From 099a95ba64c17beb13ce0e21cec9145d7154e24b Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Wed, 17 Sep 2025 17:20:19 -0400 Subject: [PATCH 238/303] =?UTF-8?q?chore:=20update=20min.=20req.=20for=20`?= =?UTF-8?q?strum`=200.27=20=E2=86=92=200.27.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 81b4b6212b3..c79994842bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -185,7 +185,7 @@ shell-words = "1" smallvec = "1.14" spirv = "0.3" static_assertions = "1.1" -strum = { version = "0.27", default-features = false, features = ["derive"] } +strum = { version = "0.27.1", default-features = false, features = ["derive"] } syn = "2.0.98" toml = "0.9.0" trybuild = "1" From e714cb0339e5177b83715646c16c03bf33511c1f Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 17 Sep 2025 11:46:34 -0400 Subject: [PATCH 239/303] [deno] Format with Deno's rustfmt config --- deno_webgpu/adapter.rs | 726 +++++++------- deno_webgpu/bind_group.rs | 122 +-- deno_webgpu/bind_group_layout.rs | 178 ++-- deno_webgpu/buffer.rs | 397 ++++---- deno_webgpu/byow.rs | 533 +++++----- deno_webgpu/command_buffer.rs | 38 +- deno_webgpu/command_encoder.rs | 765 +++++++------- deno_webgpu/compute_pass.rs | 379 +++---- deno_webgpu/compute_pipeline.rs | 76 +- deno_webgpu/device.rs | 1614 +++++++++++++++--------------- deno_webgpu/error.rs | 423 ++++---- deno_webgpu/lib.rs | 276 ++--- deno_webgpu/pipeline_layout.rs | 41 +- deno_webgpu/query_set.rs | 98 +- deno_webgpu/queue.rs | 282 +++--- deno_webgpu/render_bundle.rs | 706 ++++++------- deno_webgpu/render_pass.rs | 848 ++++++++-------- deno_webgpu/render_pipeline.rs | 750 +++++++------- deno_webgpu/rustfmt.toml | 3 + deno_webgpu/sampler.rs | 156 +-- deno_webgpu/shader.rs | 273 ++--- deno_webgpu/surface.rs | 326 +++--- deno_webgpu/texture.rs | 1135 ++++++++++----------- deno_webgpu/webidl.rs | 1038 ++++++++++--------- 24 files changed, 5705 insertions(+), 5478 deletions(-) create mode 100644 deno_webgpu/rustfmt.toml diff --git a/deno_webgpu/adapter.rs b/deno_webgpu/adapter.rs index fe0b6de4f62..ca6cb2f788b 100644 --- a/deno_webgpu/adapter.rs +++ b/deno_webgpu/adapter.rs @@ -20,194 +20,197 @@ use crate::Instance; #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPURequestAdapterOptions { - pub power_preference: Option, - #[webidl(default = false)] - pub force_fallback_adapter: bool, + pub power_preference: Option, + #[webidl(default = false)] + pub force_fallback_adapter: bool, } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUPowerPreference { - LowPower, - HighPerformance, + LowPower, + HighPerformance, } #[derive(WebIDL)] #[webidl(dictionary)] struct GPUDeviceDescriptor { - #[webidl(default = String::new())] - label: String, - - #[webidl(default = vec![])] - required_features: Vec, - #[webidl(default = Default::default())] - #[options(enforce_range = true)] - required_limits: indexmap::IndexMap>, + #[webidl(default = String::new())] + label: String, + + #[webidl(default = vec![])] + required_features: Vec, + #[webidl(default = Default::default())] + #[options(enforce_range = true)] + required_limits: indexmap::IndexMap>, } pub struct GPUAdapter { - pub instance: Instance, - pub id: wgpu_core::id::AdapterId, + pub instance: Instance, + pub id: wgpu_core::id::AdapterId, - pub features: SameObject, - pub limits: SameObject, - pub info: Rc>, + pub features: SameObject, + pub limits: SameObject, + pub info: Rc>, } impl Drop for GPUAdapter { - fn drop(&mut self) { - self.instance.adapter_drop(self.id); - } + fn drop(&mut self) { + self.instance.adapter_drop(self.id); + } } impl GarbageCollected for GPUAdapter {} #[op2] impl GPUAdapter { - #[getter] - #[global] - fn info(&self, scope: &mut v8::HandleScope) -> v8::Global { - self.info.get(scope, |_| { - let info = self.instance.adapter_get_info(self.id); - let limits = self.instance.adapter_limits(self.id); - - GPUAdapterInfo { - info, - subgroup_min_size: limits.min_subgroup_size, - subgroup_max_size: limits.max_subgroup_size, - } - }) - } - - #[getter] - #[global] - fn features(&self, scope: &mut v8::HandleScope) -> v8::Global { - self.features.get(scope, |scope| { - let features = self.instance.adapter_features(self.id); - // Only expose WebGPU features, not wgpu native-only features - let features = features & wgpu_types::Features::all_webgpu_mask(); - let features = features_to_feature_names(features); - GPUSupportedFeatures::new(scope, features) - }) - } - #[getter] - #[global] - fn limits(&self, scope: &mut v8::HandleScope) -> v8::Global { - self.limits.get(scope, |_| { - let adapter_limits = self.instance.adapter_limits(self.id); - GPUSupportedLimits(adapter_limits) - }) - } - #[getter] - fn is_fallback_adapter(&self) -> bool { - // TODO(lucacasonato): report correctly from wgpu - false - } - - #[async_method(fake)] - #[global] - fn request_device( - &self, - state: &mut OpState, - scope: &mut v8::HandleScope, - #[webidl] descriptor: GPUDeviceDescriptor, - ) -> Result, CreateDeviceError> { - let features = self.instance.adapter_features(self.id); - let supported_features = features_to_feature_names(features); - #[allow(clippy::disallowed_types)] - let required_features = descriptor - .required_features - .iter() - .cloned() - .collect::>(); - - if !required_features.is_subset(&supported_features) { - return Err(CreateDeviceError::RequiredFeaturesNotASubset); - } - - // When support for compatibility mode is added, this will need to look - // at whether the adapter is "compatibility-defaulting" or - // "core-defaulting", and choose the appropriate set of defaults. - // - // Support for compatibility mode is tracked in - // https://github.com/gfx-rs/wgpu/issues/8124. - let required_limits = serde_json::from_value::(serde_json::to_value( - descriptor.required_limits, - )?)? - .or_better_values_from(&wgpu_types::Limits::default()); - - let trace = std::env::var_os("DENO_WEBGPU_TRACE") - .map(|path| wgpu_types::Trace::Directory(std::path::PathBuf::from(path))) - .unwrap_or_default(); - - let wgpu_descriptor = wgpu_types::DeviceDescriptor { - label: crate::transform_label(descriptor.label.clone()), - required_features: super::webidl::feature_names_to_features( - descriptor.required_features, - ), - required_limits, - experimental_features: wgpu_types::ExperimentalFeatures::disabled(), - memory_hints: Default::default(), - trace, - }; - - let (device, queue) = - self.instance - .adapter_request_device(self.id, &wgpu_descriptor, None, None)?; - - let spawner = state.borrow::().clone(); - let lost_resolver = v8::PromiseResolver::new(scope).unwrap(); - let lost_promise = lost_resolver.get_promise(scope); - let device = GPUDevice { - instance: self.instance.clone(), - id: device, - queue, - label: descriptor.label, - queue_obj: SameObject::new(), - adapter_info: self.info.clone(), - error_handler: Rc::new(super::error::DeviceErrorHandler::new( - v8::Global::new(scope, lost_resolver), - spawner, - )), - adapter: self.id, - lost_promise: v8::Global::new(scope, lost_promise), - limits: SameObject::new(), - features: SameObject::new(), - }; - let device = deno_core::cppgc::make_cppgc_object(scope, device); - let weak_device = v8::Weak::new(scope, device); - let event_target_setup = state.borrow::(); - let webidl_brand = v8::Local::new(scope, event_target_setup.brand.clone()); - device.set(scope, webidl_brand, webidl_brand); - let set_event_target_data = - v8::Local::new(scope, event_target_setup.set_event_target_data.clone()) - .cast::(); - let null = v8::null(scope); - set_event_target_data.call(scope, null.into(), &[device.into()]); - - // Now that the device is fully constructed, give the error handler a - // weak reference to it. - let device = device.cast::(); - deno_core::cppgc::try_unwrap_cppgc_object::(scope, device) - .unwrap() - .error_handler - .set_device(weak_device); - - Ok(v8::Global::new(scope, device)) - } + #[getter] + #[global] + fn info(&self, scope: &mut v8::HandleScope) -> v8::Global { + self.info.get(scope, |_| { + let info = self.instance.adapter_get_info(self.id); + let limits = self.instance.adapter_limits(self.id); + + GPUAdapterInfo { + info, + subgroup_min_size: limits.min_subgroup_size, + subgroup_max_size: limits.max_subgroup_size, + } + }) + } + + #[getter] + #[global] + fn features(&self, scope: &mut v8::HandleScope) -> v8::Global { + self.features.get(scope, |scope| { + let features = self.instance.adapter_features(self.id); + // Only expose WebGPU features, not wgpu native-only features + let features = features & wgpu_types::Features::all_webgpu_mask(); + let features = features_to_feature_names(features); + GPUSupportedFeatures::new(scope, features) + }) + } + #[getter] + #[global] + fn limits(&self, scope: &mut v8::HandleScope) -> v8::Global { + self.limits.get(scope, |_| { + let adapter_limits = self.instance.adapter_limits(self.id); + GPUSupportedLimits(adapter_limits) + }) + } + #[getter] + fn is_fallback_adapter(&self) -> bool { + // TODO(lucacasonato): report correctly from wgpu + false + } + + #[async_method(fake)] + #[global] + fn request_device( + &self, + state: &mut OpState, + scope: &mut v8::HandleScope, + #[webidl] descriptor: GPUDeviceDescriptor, + ) -> Result, CreateDeviceError> { + let features = self.instance.adapter_features(self.id); + let supported_features = features_to_feature_names(features); + #[allow(clippy::disallowed_types)] + let required_features = descriptor + .required_features + .iter() + .cloned() + .collect::>(); + + if !required_features.is_subset(&supported_features) { + return Err(CreateDeviceError::RequiredFeaturesNotASubset); + } + + // When support for compatibility mode is added, this will need to look + // at whether the adapter is "compatibility-defaulting" or + // "core-defaulting", and choose the appropriate set of defaults. + // + // Support for compatibility mode is tracked in + // https://github.com/gfx-rs/wgpu/issues/8124. + let required_limits = serde_json::from_value::( + serde_json::to_value(descriptor.required_limits)?, + )? + .or_better_values_from(&wgpu_types::Limits::default()); + + let trace = std::env::var_os("DENO_WEBGPU_TRACE") + .map(|path| wgpu_types::Trace::Directory(std::path::PathBuf::from(path))) + .unwrap_or_default(); + + let wgpu_descriptor = wgpu_types::DeviceDescriptor { + label: crate::transform_label(descriptor.label.clone()), + required_features: super::webidl::feature_names_to_features( + descriptor.required_features, + ), + required_limits, + experimental_features: wgpu_types::ExperimentalFeatures::disabled(), + memory_hints: Default::default(), + trace, + }; + + let (device, queue) = self.instance.adapter_request_device( + self.id, + &wgpu_descriptor, + None, + None, + )?; + + let spawner = state.borrow::().clone(); + let lost_resolver = v8::PromiseResolver::new(scope).unwrap(); + let lost_promise = lost_resolver.get_promise(scope); + let device = GPUDevice { + instance: self.instance.clone(), + id: device, + queue, + label: descriptor.label, + queue_obj: SameObject::new(), + adapter_info: self.info.clone(), + error_handler: Rc::new(super::error::DeviceErrorHandler::new( + v8::Global::new(scope, lost_resolver), + spawner, + )), + adapter: self.id, + lost_promise: v8::Global::new(scope, lost_promise), + limits: SameObject::new(), + features: SameObject::new(), + }; + let device = deno_core::cppgc::make_cppgc_object(scope, device); + let weak_device = v8::Weak::new(scope, device); + let event_target_setup = state.borrow::(); + let webidl_brand = v8::Local::new(scope, event_target_setup.brand.clone()); + device.set(scope, webidl_brand, webidl_brand); + let set_event_target_data = + v8::Local::new(scope, event_target_setup.set_event_target_data.clone()) + .cast::(); + let null = v8::null(scope); + set_event_target_data.call(scope, null.into(), &[device.into()]); + + // Now that the device is fully constructed, give the error handler a + // weak reference to it. + let device = device.cast::(); + deno_core::cppgc::try_unwrap_cppgc_object::(scope, device) + .unwrap() + .error_handler + .set_device(weak_device); + + Ok(v8::Global::new(scope, device)) + } } #[derive(Debug, thiserror::Error, deno_error::JsError)] pub enum CreateDeviceError { - #[class(type)] - #[error("requiredFeatures must be a subset of the adapter features")] - RequiredFeaturesNotASubset, - #[class(inherit)] - #[error(transparent)] - Serde(#[from] serde_json::Error), - #[class("DOMExceptionOperationError")] - #[error(transparent)] - Device(#[from] wgpu_core::instance::RequestDeviceError), + #[class(type)] + #[error("requiredFeatures must be a subset of the adapter features")] + RequiredFeaturesNotASubset, + #[class(inherit)] + #[error(transparent)] + Serde(#[from] serde_json::Error), + #[class("DOMExceptionOperationError")] + #[error(transparent)] + Device(#[from] wgpu_core::instance::RequestDeviceError), } pub struct GPUSupportedLimits(pub wgpu_types::Limits); @@ -216,155 +219,155 @@ impl GarbageCollected for GPUSupportedLimits {} #[op2] impl GPUSupportedLimits { - #[getter] - fn maxTextureDimension1D(&self) -> u32 { - self.0.max_texture_dimension_1d - } - - #[getter] - fn maxTextureDimension2D(&self) -> u32 { - self.0.max_texture_dimension_2d - } - - #[getter] - fn maxTextureDimension3D(&self) -> u32 { - self.0.max_texture_dimension_3d - } - - #[getter] - fn maxTextureArrayLayers(&self) -> u32 { - self.0.max_texture_array_layers - } - - #[getter] - fn maxBindGroups(&self) -> u32 { - self.0.max_bind_groups - } - - // TODO(@crowlKats): support max_bind_groups_plus_vertex_buffers - - #[getter] - fn maxBindingsPerBindGroup(&self) -> u32 { - self.0.max_bindings_per_bind_group - } - - #[getter] - fn maxDynamicUniformBuffersPerPipelineLayout(&self) -> u32 { - self.0.max_dynamic_uniform_buffers_per_pipeline_layout - } - - #[getter] - fn maxDynamicStorageBuffersPerPipelineLayout(&self) -> u32 { - self.0.max_dynamic_storage_buffers_per_pipeline_layout - } - - #[getter] - fn maxSampledTexturesPerShaderStage(&self) -> u32 { - self.0.max_sampled_textures_per_shader_stage - } - - #[getter] - fn maxSamplersPerShaderStage(&self) -> u32 { - self.0.max_samplers_per_shader_stage - } - - #[getter] - fn maxStorageBuffersPerShaderStage(&self) -> u32 { - self.0.max_storage_buffers_per_shader_stage - } - - #[getter] - fn maxStorageTexturesPerShaderStage(&self) -> u32 { - self.0.max_storage_textures_per_shader_stage - } - - #[getter] - fn maxUniformBuffersPerShaderStage(&self) -> u32 { - self.0.max_uniform_buffers_per_shader_stage - } - - #[getter] - fn maxUniformBufferBindingSize(&self) -> u32 { - self.0.max_uniform_buffer_binding_size - } - - #[getter] - fn maxStorageBufferBindingSize(&self) -> u32 { - self.0.max_storage_buffer_binding_size - } - - #[getter] - fn minUniformBufferOffsetAlignment(&self) -> u32 { - self.0.min_uniform_buffer_offset_alignment - } - - #[getter] - fn minStorageBufferOffsetAlignment(&self) -> u32 { - self.0.min_storage_buffer_offset_alignment - } - - #[getter] - fn maxVertexBuffers(&self) -> u32 { - self.0.max_vertex_buffers - } - - #[getter] - #[number] - fn maxBufferSize(&self) -> u64 { - self.0.max_buffer_size - } - - #[getter] - fn maxVertexAttributes(&self) -> u32 { - self.0.max_vertex_attributes - } - - #[getter] - fn maxVertexBufferArrayStride(&self) -> u32 { - self.0.max_vertex_buffer_array_stride - } - - // TODO(@crowlKats): support max_inter_stage_shader_variables - - #[getter] - fn maxColorAttachments(&self) -> u32 { - self.0.max_color_attachments - } - - #[getter] - fn maxColorAttachmentBytesPerSample(&self) -> u32 { - self.0.max_color_attachment_bytes_per_sample - } - - #[getter] - fn maxComputeWorkgroupStorageSize(&self) -> u32 { - self.0.max_compute_workgroup_storage_size - } - - #[getter] - fn maxComputeInvocationsPerWorkgroup(&self) -> u32 { - self.0.max_compute_invocations_per_workgroup - } - - #[getter] - fn maxComputeWorkgroupSizeX(&self) -> u32 { - self.0.max_compute_workgroup_size_x - } - - #[getter] - fn maxComputeWorkgroupSizeY(&self) -> u32 { - self.0.max_compute_workgroup_size_y - } - - #[getter] - fn maxComputeWorkgroupSizeZ(&self) -> u32 { - self.0.max_compute_workgroup_size_z - } - - #[getter] - fn maxComputeWorkgroupsPerDimension(&self) -> u32 { - self.0.max_compute_workgroups_per_dimension - } + #[getter] + fn maxTextureDimension1D(&self) -> u32 { + self.0.max_texture_dimension_1d + } + + #[getter] + fn maxTextureDimension2D(&self) -> u32 { + self.0.max_texture_dimension_2d + } + + #[getter] + fn maxTextureDimension3D(&self) -> u32 { + self.0.max_texture_dimension_3d + } + + #[getter] + fn maxTextureArrayLayers(&self) -> u32 { + self.0.max_texture_array_layers + } + + #[getter] + fn maxBindGroups(&self) -> u32 { + self.0.max_bind_groups + } + + // TODO(@crowlKats): support max_bind_groups_plus_vertex_buffers + + #[getter] + fn maxBindingsPerBindGroup(&self) -> u32 { + self.0.max_bindings_per_bind_group + } + + #[getter] + fn maxDynamicUniformBuffersPerPipelineLayout(&self) -> u32 { + self.0.max_dynamic_uniform_buffers_per_pipeline_layout + } + + #[getter] + fn maxDynamicStorageBuffersPerPipelineLayout(&self) -> u32 { + self.0.max_dynamic_storage_buffers_per_pipeline_layout + } + + #[getter] + fn maxSampledTexturesPerShaderStage(&self) -> u32 { + self.0.max_sampled_textures_per_shader_stage + } + + #[getter] + fn maxSamplersPerShaderStage(&self) -> u32 { + self.0.max_samplers_per_shader_stage + } + + #[getter] + fn maxStorageBuffersPerShaderStage(&self) -> u32 { + self.0.max_storage_buffers_per_shader_stage + } + + #[getter] + fn maxStorageTexturesPerShaderStage(&self) -> u32 { + self.0.max_storage_textures_per_shader_stage + } + + #[getter] + fn maxUniformBuffersPerShaderStage(&self) -> u32 { + self.0.max_uniform_buffers_per_shader_stage + } + + #[getter] + fn maxUniformBufferBindingSize(&self) -> u32 { + self.0.max_uniform_buffer_binding_size + } + + #[getter] + fn maxStorageBufferBindingSize(&self) -> u32 { + self.0.max_storage_buffer_binding_size + } + + #[getter] + fn minUniformBufferOffsetAlignment(&self) -> u32 { + self.0.min_uniform_buffer_offset_alignment + } + + #[getter] + fn minStorageBufferOffsetAlignment(&self) -> u32 { + self.0.min_storage_buffer_offset_alignment + } + + #[getter] + fn maxVertexBuffers(&self) -> u32 { + self.0.max_vertex_buffers + } + + #[getter] + #[number] + fn maxBufferSize(&self) -> u64 { + self.0.max_buffer_size + } + + #[getter] + fn maxVertexAttributes(&self) -> u32 { + self.0.max_vertex_attributes + } + + #[getter] + fn maxVertexBufferArrayStride(&self) -> u32 { + self.0.max_vertex_buffer_array_stride + } + + // TODO(@crowlKats): support max_inter_stage_shader_variables + + #[getter] + fn maxColorAttachments(&self) -> u32 { + self.0.max_color_attachments + } + + #[getter] + fn maxColorAttachmentBytesPerSample(&self) -> u32 { + self.0.max_color_attachment_bytes_per_sample + } + + #[getter] + fn maxComputeWorkgroupStorageSize(&self) -> u32 { + self.0.max_compute_workgroup_storage_size + } + + #[getter] + fn maxComputeInvocationsPerWorkgroup(&self) -> u32 { + self.0.max_compute_invocations_per_workgroup + } + + #[getter] + fn maxComputeWorkgroupSizeX(&self) -> u32 { + self.0.max_compute_workgroup_size_x + } + + #[getter] + fn maxComputeWorkgroupSizeY(&self) -> u32 { + self.0.max_compute_workgroup_size_y + } + + #[getter] + fn maxComputeWorkgroupSizeZ(&self) -> u32 { + self.0.max_compute_workgroup_size_z + } + + #[getter] + fn maxComputeWorkgroupsPerDimension(&self) -> u32 { + self.0.max_compute_workgroups_per_dimension + } } pub struct GPUSupportedFeatures(v8::Global); @@ -372,69 +375,72 @@ pub struct GPUSupportedFeatures(v8::Global); impl GarbageCollected for GPUSupportedFeatures {} impl GPUSupportedFeatures { - #[allow(clippy::disallowed_types)] - pub fn new(scope: &mut v8::HandleScope, features: HashSet) -> Self { - let set = v8::Set::new(scope); - - for feature in features { - let key = v8::String::new(scope, feature.as_str()).unwrap(); - set.add(scope, key.into()); - } + #[allow(clippy::disallowed_types)] + pub fn new( + scope: &mut v8::HandleScope, + features: HashSet, + ) -> Self { + let set = v8::Set::new(scope); - Self(v8::Global::new(scope, >::from(set))) + for feature in features { + let key = v8::String::new(scope, feature.as_str()).unwrap(); + set.add(scope, key.into()); } + + Self(v8::Global::new(scope, >::from(set))) + } } #[op2] impl GPUSupportedFeatures { - #[global] - #[symbol("setlike_set")] - fn set(&self) -> v8::Global { - self.0.clone() - } + #[global] + #[symbol("setlike_set")] + fn set(&self) -> v8::Global { + self.0.clone() + } } pub struct GPUAdapterInfo { - pub info: wgpu_types::AdapterInfo, - pub subgroup_min_size: u32, - pub subgroup_max_size: u32, + pub info: wgpu_types::AdapterInfo, + pub subgroup_min_size: u32, + pub subgroup_max_size: u32, } impl GarbageCollected for GPUAdapterInfo {} #[op2] impl GPUAdapterInfo { - #[getter] - #[string] - fn vendor(&self) -> String { - self.info.vendor.to_string() - } - - #[getter] - #[string] - fn architecture(&self) -> &'static str { - "" // TODO: wgpu#2170 - } - - #[getter] - #[string] - fn device(&self) -> String { - self.info.device.to_string() - } - - #[getter] - #[string] - fn description(&self) -> String { - self.info.name.clone() - } - - #[getter] - fn subgroup_min_size(&self) -> u32 { - self.subgroup_min_size - } - - #[getter] - fn subgroup_max_size(&self) -> u32 { - self.subgroup_max_size - } + #[getter] + #[string] + fn vendor(&self) -> String { + self.info.vendor.to_string() + } + + #[getter] + #[string] + fn architecture(&self) -> &'static str { + "" // TODO: wgpu#2170 + } + + #[getter] + #[string] + fn device(&self) -> String { + self.info.device.to_string() + } + + #[getter] + #[string] + fn description(&self) -> String { + self.info.name.clone() + } + + #[getter] + fn subgroup_min_size(&self) -> u32 { + self.subgroup_min_size + } + + #[getter] + fn subgroup_max_size(&self) -> u32 { + self.subgroup_max_size + } } diff --git a/deno_webgpu/bind_group.rs b/deno_webgpu/bind_group.rs index f147c217801..80efba6efdd 100644 --- a/deno_webgpu/bind_group.rs +++ b/deno_webgpu/bind_group.rs @@ -20,97 +20,103 @@ use crate::texture::GPUTextureView; use crate::Instance; pub struct GPUBindGroup { - pub instance: Instance, - pub id: wgpu_core::id::BindGroupId, - pub label: String, + pub instance: Instance, + pub id: wgpu_core::id::BindGroupId, + pub label: String, } impl Drop for GPUBindGroup { - fn drop(&mut self) { - self.instance.bind_group_drop(self.id); - } + fn drop(&mut self) { + self.instance.bind_group_drop(self.id); + } } impl WebIdlInterfaceConverter for GPUBindGroup { - const NAME: &'static str = "GPUBindGroup"; + const NAME: &'static str = "GPUBindGroup"; } impl GarbageCollected for GPUBindGroup {} #[op2] impl GPUBindGroup { - #[getter] - #[string] - fn label(&self) -> String { - self.label.clone() - } - #[setter] - #[string] - fn label(&self, #[webidl] _label: String) { - // TODO(@crowlKats): no-op, needs wpgu to implement changing the label - } + #[getter] + #[string] + fn label(&self) -> String { + self.label.clone() + } + #[setter] + #[string] + fn label(&self, #[webidl] _label: String) { + // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUBindGroupDescriptor { - #[webidl(default = String::new())] - pub label: String, + #[webidl(default = String::new())] + pub label: String, - pub layout: Ptr, - pub entries: Vec, + pub layout: Ptr, + pub entries: Vec, } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUBindGroupEntry { - #[options(enforce_range = true)] - pub binding: u32, - pub resource: GPUBindingResource, + #[options(enforce_range = true)] + pub binding: u32, + pub resource: GPUBindingResource, } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUBufferBinding { - pub buffer: Ptr, - #[webidl(default = 0)] - #[options(enforce_range = true)] - pub offset: u64, - #[options(enforce_range = true)] - pub size: Option, + pub buffer: Ptr, + #[webidl(default = 0)] + #[options(enforce_range = true)] + pub offset: u64, + #[options(enforce_range = true)] + pub size: Option, } pub(crate) enum GPUBindingResource { - Sampler(Ptr), - TextureView(Ptr), - BufferBinding(GPUBufferBinding), + Sampler(Ptr), + TextureView(Ptr), + BufferBinding(GPUBufferBinding), } impl<'a> WebIdlConverter<'a> for GPUBindingResource { - type Options = (); + type Options = (); - fn convert<'b>( - scope: &mut HandleScope<'a>, - value: Local<'a, Value>, - prefix: Cow<'static, str>, - context: ContextFn<'b>, - options: &Self::Options, - ) -> Result { - >::convert(scope, value, prefix.clone(), context.borrowed(), options) - .map(Self::Sampler) - .or_else(|_| { - >::convert( - scope, - value, - prefix.clone(), - context.borrowed(), - options, - ) - .map(Self::TextureView) - }) - .or_else(|_| { - GPUBufferBinding::convert(scope, value, prefix, context, options) - .map(Self::BufferBinding) - }) - } + fn convert<'b>( + scope: &mut HandleScope<'a>, + value: Local<'a, Value>, + prefix: Cow<'static, str>, + context: ContextFn<'b>, + options: &Self::Options, + ) -> Result { + >::convert( + scope, + value, + prefix.clone(), + context.borrowed(), + options, + ) + .map(Self::Sampler) + .or_else(|_| { + >::convert( + scope, + value, + prefix.clone(), + context.borrowed(), + options, + ) + .map(Self::TextureView) + }) + .or_else(|_| { + GPUBufferBinding::convert(scope, value, prefix, context, options) + .map(Self::BufferBinding) + }) + } } diff --git a/deno_webgpu/bind_group_layout.rs b/deno_webgpu/bind_group_layout.rs index 319f626e72e..3ebe594620e 100644 --- a/deno_webgpu/bind_group_layout.rs +++ b/deno_webgpu/bind_group_layout.rs @@ -8,169 +8,173 @@ use crate::texture::GPUTextureViewDimension; use crate::Instance; pub struct GPUBindGroupLayout { - pub instance: Instance, - pub id: wgpu_core::id::BindGroupLayoutId, - pub label: String, + pub instance: Instance, + pub id: wgpu_core::id::BindGroupLayoutId, + pub label: String, } impl Drop for GPUBindGroupLayout { - fn drop(&mut self) { - self.instance.bind_group_layout_drop(self.id); - } + fn drop(&mut self) { + self.instance.bind_group_layout_drop(self.id); + } } impl deno_core::webidl::WebIdlInterfaceConverter for GPUBindGroupLayout { - const NAME: &'static str = "GPUBindGroupLayout"; + const NAME: &'static str = "GPUBindGroupLayout"; } impl GarbageCollected for GPUBindGroupLayout {} #[op2] impl GPUBindGroupLayout { - #[getter] - #[string] - fn label(&self) -> String { - self.label.clone() - } - #[setter] - #[string] - fn label(&self, #[webidl] _label: String) { - // TODO(@crowlKats): no-op, needs wpgu to implement changing the label - } + #[getter] + #[string] + fn label(&self) -> String { + self.label.clone() + } + #[setter] + #[string] + fn label(&self, #[webidl] _label: String) { + // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUBindGroupLayoutDescriptor { - #[webidl(default = String::new())] - pub label: String, - pub entries: Vec, + #[webidl(default = String::new())] + pub label: String, + pub entries: Vec, } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUBindGroupLayoutEntry { - #[options(enforce_range = true)] - pub binding: u32, - #[options(enforce_range = true)] - pub visibility: u32, - pub buffer: Option, - pub sampler: Option, - pub texture: Option, - pub storage_texture: Option, + #[options(enforce_range = true)] + pub binding: u32, + #[options(enforce_range = true)] + pub visibility: u32, + pub buffer: Option, + pub sampler: Option, + pub texture: Option, + pub storage_texture: Option, } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUBufferBindingLayout { - #[webidl(default = GPUBufferBindingType::Uniform)] - pub r#type: GPUBufferBindingType, - #[webidl(default = false)] - pub has_dynamic_offset: bool, - #[webidl(default = 0)] - pub min_binding_size: u64, + #[webidl(default = GPUBufferBindingType::Uniform)] + pub r#type: GPUBufferBindingType, + #[webidl(default = false)] + pub has_dynamic_offset: bool, + #[webidl(default = 0)] + pub min_binding_size: u64, } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUBufferBindingType { - Uniform, - Storage, - ReadOnlyStorage, + Uniform, + Storage, + ReadOnlyStorage, } impl From for wgpu_types::BufferBindingType { - fn from(value: GPUBufferBindingType) -> Self { - match value { - GPUBufferBindingType::Uniform => Self::Uniform, - GPUBufferBindingType::Storage => Self::Storage { read_only: false }, - GPUBufferBindingType::ReadOnlyStorage => Self::Storage { read_only: true }, - } + fn from(value: GPUBufferBindingType) -> Self { + match value { + GPUBufferBindingType::Uniform => Self::Uniform, + GPUBufferBindingType::Storage => Self::Storage { read_only: false }, + GPUBufferBindingType::ReadOnlyStorage => { + Self::Storage { read_only: true } + } } + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUSamplerBindingLayout { - #[webidl(default = GPUSamplerBindingType::Filtering)] - pub r#type: GPUSamplerBindingType, + #[webidl(default = GPUSamplerBindingType::Filtering)] + pub r#type: GPUSamplerBindingType, } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUSamplerBindingType { - Filtering, - NonFiltering, - Comparison, + Filtering, + NonFiltering, + Comparison, } impl From for wgpu_types::SamplerBindingType { - fn from(value: GPUSamplerBindingType) -> Self { - match value { - GPUSamplerBindingType::Filtering => Self::Filtering, - GPUSamplerBindingType::NonFiltering => Self::NonFiltering, - GPUSamplerBindingType::Comparison => Self::Comparison, - } + fn from(value: GPUSamplerBindingType) -> Self { + match value { + GPUSamplerBindingType::Filtering => Self::Filtering, + GPUSamplerBindingType::NonFiltering => Self::NonFiltering, + GPUSamplerBindingType::Comparison => Self::Comparison, } + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUTextureBindingLayout { - #[webidl(default = GPUTextureSampleType::Float)] - pub sample_type: GPUTextureSampleType, - #[webidl(default = GPUTextureViewDimension::D2)] - pub view_dimension: GPUTextureViewDimension, - #[webidl(default = false)] - pub multisampled: bool, + #[webidl(default = GPUTextureSampleType::Float)] + pub sample_type: GPUTextureSampleType, + #[webidl(default = GPUTextureViewDimension::D2)] + pub view_dimension: GPUTextureViewDimension, + #[webidl(default = false)] + pub multisampled: bool, } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUTextureSampleType { - Float, - UnfilterableFloat, - Depth, - Sint, - Uint, + Float, + UnfilterableFloat, + Depth, + Sint, + Uint, } impl From for wgpu_types::TextureSampleType { - fn from(value: GPUTextureSampleType) -> Self { - match value { - GPUTextureSampleType::Float => Self::Float { filterable: true }, - GPUTextureSampleType::UnfilterableFloat => Self::Float { filterable: false }, - GPUTextureSampleType::Depth => Self::Depth, - GPUTextureSampleType::Sint => Self::Sint, - GPUTextureSampleType::Uint => Self::Uint, - } + fn from(value: GPUTextureSampleType) -> Self { + match value { + GPUTextureSampleType::Float => Self::Float { filterable: true }, + GPUTextureSampleType::UnfilterableFloat => { + Self::Float { filterable: false } + } + GPUTextureSampleType::Depth => Self::Depth, + GPUTextureSampleType::Sint => Self::Sint, + GPUTextureSampleType::Uint => Self::Uint, } + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUStorageTextureBindingLayout { - #[webidl(default = GPUStorageTextureAccess::WriteOnly)] - pub access: GPUStorageTextureAccess, - pub format: super::texture::GPUTextureFormat, - #[webidl(default = GPUTextureViewDimension::D2)] - pub view_dimension: GPUTextureViewDimension, + #[webidl(default = GPUStorageTextureAccess::WriteOnly)] + pub access: GPUStorageTextureAccess, + pub format: super::texture::GPUTextureFormat, + #[webidl(default = GPUTextureViewDimension::D2)] + pub view_dimension: GPUTextureViewDimension, } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUStorageTextureAccess { - WriteOnly, - ReadOnly, - ReadWrite, + WriteOnly, + ReadOnly, + ReadWrite, } impl From for wgpu_types::StorageTextureAccess { - fn from(value: GPUStorageTextureAccess) -> Self { - match value { - GPUStorageTextureAccess::WriteOnly => Self::WriteOnly, - GPUStorageTextureAccess::ReadOnly => Self::ReadOnly, - GPUStorageTextureAccess::ReadWrite => Self::ReadWrite, - } + fn from(value: GPUStorageTextureAccess) -> Self { + match value { + GPUStorageTextureAccess::WriteOnly => Self::WriteOnly, + GPUStorageTextureAccess::ReadOnly => Self::ReadOnly, + GPUStorageTextureAccess::ReadWrite => Self::ReadWrite, } + } } diff --git a/deno_webgpu/buffer.rs b/deno_webgpu/buffer.rs index 6b9d12483f5..0f0e4990504 100644 --- a/deno_webgpu/buffer.rs +++ b/deno_webgpu/buffer.rs @@ -18,240 +18,245 @@ use crate::Instance; #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUBufferDescriptor { - #[webidl(default = String::new())] - pub label: String, - - pub size: u64, - #[options(enforce_range = true)] - pub usage: u32, - #[webidl(default = false)] - pub mapped_at_creation: bool, + #[webidl(default = String::new())] + pub label: String, + + pub size: u64, + #[options(enforce_range = true)] + pub usage: u32, + #[webidl(default = false)] + pub mapped_at_creation: bool, } #[derive(Debug, thiserror::Error, deno_error::JsError)] pub enum BufferError { - #[class(generic)] - #[error(transparent)] - Canceled(#[from] oneshot::Canceled), - #[class("DOMExceptionOperationError")] - #[error(transparent)] - Access(#[from] wgpu_core::resource::BufferAccessError), - #[class("DOMExceptionOperationError")] - #[error("{0}")] - Operation(&'static str), - #[class(inherit)] - #[error(transparent)] - Other(#[from] JsErrorBox), + #[class(generic)] + #[error(transparent)] + Canceled(#[from] oneshot::Canceled), + #[class("DOMExceptionOperationError")] + #[error(transparent)] + Access(#[from] wgpu_core::resource::BufferAccessError), + #[class("DOMExceptionOperationError")] + #[error("{0}")] + Operation(&'static str), + #[class(inherit)] + #[error(transparent)] + Other(#[from] JsErrorBox), } pub struct GPUBuffer { - pub instance: Instance, - pub error_handler: super::error::ErrorHandler, + pub instance: Instance, + pub error_handler: super::error::ErrorHandler, - pub id: wgpu_core::id::BufferId, - pub device: wgpu_core::id::DeviceId, + pub id: wgpu_core::id::BufferId, + pub device: wgpu_core::id::DeviceId, - pub label: String, + pub label: String, - pub size: u64, - pub usage: u32, + pub size: u64, + pub usage: u32, - pub map_state: RefCell<&'static str>, - pub map_mode: RefCell>, + pub map_state: RefCell<&'static str>, + pub map_mode: RefCell>, - pub mapped_js_buffers: RefCell>>, + pub mapped_js_buffers: RefCell>>, } impl Drop for GPUBuffer { - fn drop(&mut self) { - self.instance.buffer_drop(self.id); - } + fn drop(&mut self) { + self.instance.buffer_drop(self.id); + } } impl WebIdlInterfaceConverter for GPUBuffer { - const NAME: &'static str = "GPUBuffer"; + const NAME: &'static str = "GPUBuffer"; } impl GarbageCollected for GPUBuffer {} #[op2] impl GPUBuffer { - #[getter] - #[string] - fn label(&self) -> String { - self.label.clone() - } - #[setter] - #[string] - fn label(&self, #[webidl] _label: String) { - // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + #[getter] + #[string] + fn label(&self) -> String { + self.label.clone() + } + #[setter] + #[string] + fn label(&self, #[webidl] _label: String) { + // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } + + #[getter] + #[number] + fn size(&self) -> u64 { + self.size + } + #[getter] + fn usage(&self) -> u32 { + self.usage + } + + #[getter] + #[string] + fn map_state(&self) -> &'static str { + *self.map_state.borrow() + } + + #[async_method] + async fn map_async( + &self, + #[webidl(options(enforce_range = true))] mode: u32, + #[webidl(default = 0)] offset: u64, + #[webidl] size: Option, + ) -> Result<(), BufferError> { + let read_mode = (mode & 0x0001) == 0x0001; + let write_mode = (mode & 0x0002) == 0x0002; + if (read_mode && write_mode) || (!read_mode && !write_mode) { + return Err(BufferError::Operation( + "exactly one of READ or WRITE map mode must be set", + )); } - #[getter] - #[number] - fn size(&self) -> u64 { - self.size - } - #[getter] - fn usage(&self) -> u32 { - self.usage - } + let mode = if read_mode { + MapMode::Read + } else { + assert!(write_mode); + MapMode::Write + }; - #[getter] - #[string] - fn map_state(&self) -> &'static str { - *self.map_state.borrow() + { + *self.map_state.borrow_mut() = "pending"; } - #[async_method] - async fn map_async( - &self, - #[webidl(options(enforce_range = true))] mode: u32, - #[webidl(default = 0)] offset: u64, - #[webidl] size: Option, - ) -> Result<(), BufferError> { - let read_mode = (mode & 0x0001) == 0x0001; - let write_mode = (mode & 0x0002) == 0x0002; - if (read_mode && write_mode) || (!read_mode && !write_mode) { - return Err(BufferError::Operation( - "exactly one of READ or WRITE map mode must be set", - )); - } - - let mode = if read_mode { - MapMode::Read - } else { - assert!(write_mode); - MapMode::Write - }; - - { - *self.map_state.borrow_mut() = "pending"; - } - - let (sender, receiver) = oneshot::channel::(); + let (sender, receiver) = + oneshot::channel::(); + + { + let callback = Box::new(move |status| { + sender.send(status).unwrap(); + }); + + let err = self + .instance + .buffer_map_async( + self.id, + offset, + size, + wgpu_core::resource::BufferMapOperation { + host: mode, + callback: Some(callback), + }, + ) + .err(); + + if err.is_some() { + self.error_handler.push_error(err); + return Err(BufferError::Operation("validation error occurred")); + } + } + let done = Rc::new(RefCell::new(false)); + let done_ = done.clone(); + let device_poll_fut = async move { + while !*done.borrow() { { - let callback = Box::new(move |status| { - sender.send(status).unwrap(); - }); - - let err = self - .instance - .buffer_map_async( - self.id, - offset, - size, - wgpu_core::resource::BufferMapOperation { - host: mode, - callback: Some(callback), - }, - ) - .err(); - - if err.is_some() { - self.error_handler.push_error(err); - return Err(BufferError::Operation("validation error occurred")); - } + self + .instance + .device_poll(self.device, wgpu_types::PollType::wait()) + .unwrap(); } - - let done = Rc::new(RefCell::new(false)); - let done_ = done.clone(); - let device_poll_fut = async move { - while !*done.borrow() { - { - self.instance - .device_poll(self.device, wgpu_types::PollType::wait()) - .unwrap(); - } - tokio::time::sleep(Duration::from_millis(10)).await; - } - Ok::<(), BufferError>(()) - }; - - let receiver_fut = async move { - receiver.await??; - let mut done = done_.borrow_mut(); - *done = true; - Ok::<(), BufferError>(()) - }; - - tokio::try_join!(device_poll_fut, receiver_fut)?; - - *self.map_state.borrow_mut() = "mapped"; - *self.map_mode.borrow_mut() = Some(mode); - - Ok(()) + tokio::time::sleep(Duration::from_millis(10)).await; + } + Ok::<(), BufferError>(()) + }; + + let receiver_fut = async move { + receiver.await??; + let mut done = done_.borrow_mut(); + *done = true; + Ok::<(), BufferError>(()) + }; + + tokio::try_join!(device_poll_fut, receiver_fut)?; + + *self.map_state.borrow_mut() = "mapped"; + *self.map_mode.borrow_mut() = Some(mode); + + Ok(()) + } + + fn get_mapped_range<'s>( + &self, + scope: &mut v8::HandleScope<'s>, + #[webidl(default = 0)] offset: u64, + #[webidl] size: Option, + ) -> Result, BufferError> { + let (slice_pointer, range_size) = self + .instance + .buffer_get_mapped_range(self.id, offset, size) + .map_err(BufferError::Access)?; + + let mode = self.map_mode.borrow(); + let mode = mode.as_ref().unwrap(); + + let bs = if mode == &MapMode::Write { + unsafe extern "C" fn noop_deleter_callback( + _data: *mut std::ffi::c_void, + _byte_length: usize, + _deleter_data: *mut std::ffi::c_void, + ) { + } + + // SAFETY: creating a backing store from the pointer and length provided by wgpu + unsafe { + v8::ArrayBuffer::new_backing_store_from_ptr( + slice_pointer.as_ptr() as _, + range_size as usize, + noop_deleter_callback, + std::ptr::null_mut(), + ) + } + } else { + // SAFETY: creating a vector from the pointer and length provided by wgpu + let slice = unsafe { + std::slice::from_raw_parts(slice_pointer.as_ptr(), range_size as usize) + }; + v8::ArrayBuffer::new_backing_store_from_vec(slice.to_vec()) + }; + + let shared_bs = bs.make_shared(); + let ab = v8::ArrayBuffer::with_backing_store(scope, &shared_bs); + + if mode == &MapMode::Write { + self + .mapped_js_buffers + .borrow_mut() + .push(v8::Global::new(scope, ab)); } - fn get_mapped_range<'s>( - &self, - scope: &mut v8::HandleScope<'s>, - #[webidl(default = 0)] offset: u64, - #[webidl] size: Option, - ) -> Result, BufferError> { - let (slice_pointer, range_size) = self - .instance - .buffer_get_mapped_range(self.id, offset, size) - .map_err(BufferError::Access)?; - - let mode = self.map_mode.borrow(); - let mode = mode.as_ref().unwrap(); - - let bs = if mode == &MapMode::Write { - unsafe extern "C" fn noop_deleter_callback( - _data: *mut std::ffi::c_void, - _byte_length: usize, - _deleter_data: *mut std::ffi::c_void, - ) { - } - - // SAFETY: creating a backing store from the pointer and length provided by wgpu - unsafe { - v8::ArrayBuffer::new_backing_store_from_ptr( - slice_pointer.as_ptr() as _, - range_size as usize, - noop_deleter_callback, - std::ptr::null_mut(), - ) - } - } else { - // SAFETY: creating a vector from the pointer and length provided by wgpu - let slice = - unsafe { std::slice::from_raw_parts(slice_pointer.as_ptr(), range_size as usize) }; - v8::ArrayBuffer::new_backing_store_from_vec(slice.to_vec()) - }; - - let shared_bs = bs.make_shared(); - let ab = v8::ArrayBuffer::with_backing_store(scope, &shared_bs); - - if mode == &MapMode::Write { - self.mapped_js_buffers - .borrow_mut() - .push(v8::Global::new(scope, ab)); - } + Ok(ab) + } - Ok(ab) + #[nofast] + fn unmap(&self, scope: &mut v8::HandleScope) -> Result<(), BufferError> { + for ab in self.mapped_js_buffers.replace(vec![]) { + let ab = ab.open(scope); + ab.detach(None); } - #[nofast] - fn unmap(&self, scope: &mut v8::HandleScope) -> Result<(), BufferError> { - for ab in self.mapped_js_buffers.replace(vec![]) { - let ab = ab.open(scope); - ab.detach(None); - } - - self.instance - .buffer_unmap(self.id) - .map_err(BufferError::Access)?; + self + .instance + .buffer_unmap(self.id) + .map_err(BufferError::Access)?; - *self.map_state.borrow_mut() = "unmapped"; + *self.map_state.borrow_mut() = "unmapped"; - Ok(()) - } + Ok(()) + } - #[fast] - fn destroy(&self) { - self.instance.buffer_destroy(self.id); - } + #[fast] + fn destroy(&self) { + self.instance.buffer_destroy(self.id); + } } diff --git a/deno_webgpu/byow.rs b/deno_webgpu/byow.rs index bfce74abfdc..1079bed2228 100644 --- a/deno_webgpu/byow.rs +++ b/deno_webgpu/byow.rs @@ -3,10 +3,10 @@ use std::cell::RefCell; use std::ffi::c_void; #[cfg(any( - target_os = "linux", - target_os = "macos", - target_os = "freebsd", - target_os = "openbsd" + target_os = "linux", + target_os = "macos", + target_os = "freebsd", + target_os = "openbsd" ))] use std::ptr::NonNull; @@ -24,305 +24,326 @@ use crate::surface::GPUCanvasContext; #[derive(Debug, thiserror::Error, deno_error::JsError)] pub enum ByowError { - #[class(type)] - #[error("Cannot create surface outside of WebGPU context. Did you forget to call `navigator.gpu.requestAdapter()`?")] - WebGPUNotInitiated, - #[class(type)] - #[error("Invalid parameters")] - InvalidParameters, - #[class(generic)] - #[error(transparent)] - CreateSurface(wgpu_core::instance::CreateSurfaceError), - #[cfg(target_os = "windows")] - #[class(type)] - #[error("Invalid system on Windows")] - InvalidSystem, - #[cfg(target_os = "macos")] - #[class(type)] - #[error("Invalid system on macOS")] - InvalidSystem, - #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"))] - #[class(type)] - #[error("Invalid system on Linux/BSD")] - InvalidSystem, - #[cfg(any( - target_os = "windows", - target_os = "linux", - target_os = "freebsd", - target_os = "openbsd" - ))] - #[class(type)] - #[error("window is null")] - NullWindow, - #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"))] - #[class(type)] - #[error("display is null")] - NullDisplay, - #[cfg(target_os = "macos")] - #[class(type)] - #[error("ns_view is null")] - NSViewDisplay, + #[class(type)] + #[error( + "Cannot create surface outside of WebGPU context. Did you forget to call `navigator.gpu.requestAdapter()`?" + )] + WebGPUNotInitiated, + #[class(type)] + #[error("Invalid parameters")] + InvalidParameters, + #[class(generic)] + #[error(transparent)] + CreateSurface(wgpu_core::instance::CreateSurfaceError), + #[cfg(target_os = "windows")] + #[class(type)] + #[error("Invalid system on Windows")] + InvalidSystem, + #[cfg(target_os = "macos")] + #[class(type)] + #[error("Invalid system on macOS")] + InvalidSystem, + #[cfg(any( + target_os = "linux", + target_os = "freebsd", + target_os = "openbsd" + ))] + #[class(type)] + #[error("Invalid system on Linux/BSD")] + InvalidSystem, + #[cfg(any( + target_os = "windows", + target_os = "linux", + target_os = "freebsd", + target_os = "openbsd" + ))] + #[class(type)] + #[error("window is null")] + NullWindow, + #[cfg(any( + target_os = "linux", + target_os = "freebsd", + target_os = "openbsd" + ))] + #[class(type)] + #[error("display is null")] + NullDisplay, + #[cfg(target_os = "macos")] + #[class(type)] + #[error("ns_view is null")] + NSViewDisplay, } // TODO(@littledivy): This will extend `OffscreenCanvas` when we add it. pub struct UnsafeWindowSurface { - pub id: wgpu_core::id::SurfaceId, - pub width: RefCell, - pub height: RefCell, + pub id: wgpu_core::id::SurfaceId, + pub width: RefCell, + pub height: RefCell, - pub context: SameObject, + pub context: SameObject, } impl GarbageCollected for UnsafeWindowSurface {} #[op2] impl UnsafeWindowSurface { - #[constructor] - #[cppgc] - fn new( - state: &mut OpState, - #[from_v8] options: UnsafeWindowSurfaceOptions, - ) -> Result { - let instance = state - .try_borrow::() - .ok_or(ByowError::WebGPUNotInitiated)?; - - // Security note: - // - // The `window_handle` and `display_handle` options are pointers to - // platform-specific window handles. - // - // The code below works under the assumption that: - // - // - handles can only be created by the FFI interface which - // enforces --allow-ffi. - // - // - `*const c_void` deserizalizes null and v8::External. - // - // - Only FFI can export v8::External to user code. - if options.window_handle.is_null() { - return Err(ByowError::InvalidParameters); - } - - let (win_handle, display_handle) = raw_window( - options.system, - options.window_handle, - options.display_handle, - )?; - - // SAFETY: see above comment - let id = unsafe { - instance - .instance_create_surface(display_handle, win_handle, None) - .map_err(ByowError::CreateSurface)? - }; - - Ok(UnsafeWindowSurface { - id, - width: RefCell::new(options.width), - height: RefCell::new(options.height), - context: SameObject::new(), - }) + #[constructor] + #[cppgc] + fn new( + state: &mut OpState, + #[from_v8] options: UnsafeWindowSurfaceOptions, + ) -> Result { + let instance = state + .try_borrow::() + .ok_or(ByowError::WebGPUNotInitiated)?; + + // Security note: + // + // The `window_handle` and `display_handle` options are pointers to + // platform-specific window handles. + // + // The code below works under the assumption that: + // + // - handles can only be created by the FFI interface which + // enforces --allow-ffi. + // + // - `*const c_void` deserizalizes null and v8::External. + // + // - Only FFI can export v8::External to user code. + if options.window_handle.is_null() { + return Err(ByowError::InvalidParameters); } - #[global] - fn get_context( - &self, - #[this] this: v8::Global, - scope: &mut v8::HandleScope, - ) -> v8::Global { - self.context.get(scope, |_| GPUCanvasContext { - surface_id: self.id, - width: self.width.clone(), - height: self.height.clone(), - config: RefCell::new(None), - texture: RefCell::new(None), - canvas: this, - }) - } + let (win_handle, display_handle) = raw_window( + options.system, + options.window_handle, + options.display_handle, + )?; + + // SAFETY: see above comment + let id = unsafe { + instance + .instance_create_surface(display_handle, win_handle, None) + .map_err(ByowError::CreateSurface)? + }; - #[nofast] - fn present(&self, scope: &mut v8::HandleScope) -> Result<(), JsErrorBox> { - let Some(context) = self.context.try_unwrap(scope) else { - return Err(JsErrorBox::type_error("getContext was never called")); - }; + Ok(UnsafeWindowSurface { + id, + width: RefCell::new(options.width), + height: RefCell::new(options.height), + context: SameObject::new(), + }) + } + + #[global] + fn get_context( + &self, + #[this] this: v8::Global, + scope: &mut v8::HandleScope, + ) -> v8::Global { + self.context.get(scope, |_| GPUCanvasContext { + surface_id: self.id, + width: self.width.clone(), + height: self.height.clone(), + config: RefCell::new(None), + texture: RefCell::new(None), + canvas: this, + }) + } + + #[nofast] + fn present(&self, scope: &mut v8::HandleScope) -> Result<(), JsErrorBox> { + let Some(context) = self.context.try_unwrap(scope) else { + return Err(JsErrorBox::type_error("getContext was never called")); + }; - context.present().map_err(JsErrorBox::from_err) - } + context.present().map_err(JsErrorBox::from_err) + } } struct UnsafeWindowSurfaceOptions { - system: UnsafeWindowSurfaceSystem, - window_handle: *const c_void, - display_handle: *const c_void, - width: u32, - height: u32, + system: UnsafeWindowSurfaceSystem, + window_handle: *const c_void, + display_handle: *const c_void, + width: u32, + height: u32, } #[derive(Eq, PartialEq)] enum UnsafeWindowSurfaceSystem { - Cocoa, - Win32, - X11, - Wayland, + Cocoa, + Win32, + X11, + Wayland, } impl<'a> FromV8<'a> for UnsafeWindowSurfaceOptions { - type Error = JsErrorBox; - - fn from_v8( - scope: &mut v8::HandleScope<'a>, - value: Local<'a, Value>, - ) -> Result { - let obj = value - .try_cast::() - .map_err(|_| JsErrorBox::type_error("is not an object"))?; - - let key = v8::String::new(scope, "system").unwrap(); - let val = obj - .get(scope, key.into()) - .ok_or_else(|| JsErrorBox::type_error("missing field 'system'"))?; - let s = String::from_v8(scope, val).unwrap(); - let system = match s.as_str() { - "cocoa" => UnsafeWindowSurfaceSystem::Cocoa, - "win32" => UnsafeWindowSurfaceSystem::Win32, - "x11" => UnsafeWindowSurfaceSystem::X11, - "wayland" => UnsafeWindowSurfaceSystem::Wayland, - _ => return Err(JsErrorBox::type_error(format!("Invalid system kind '{s}'"))), - }; - - let key = v8::String::new(scope, "windowHandle").unwrap(); - let val = obj - .get(scope, key.into()) - .ok_or_else(|| JsErrorBox::type_error("missing field 'windowHandle'"))?; - let Some(window_handle) = deno_core::_ops::to_external_option(&val) else { - return Err(JsErrorBox::type_error("expected external")); - }; - - let key = v8::String::new(scope, "displayHandle").unwrap(); - let val = obj - .get(scope, key.into()) - .ok_or_else(|| JsErrorBox::type_error("missing field 'displayHandle'"))?; - let Some(display_handle) = deno_core::_ops::to_external_option(&val) else { - return Err(JsErrorBox::type_error("expected external")); - }; - - let key = v8::String::new(scope, "width").unwrap(); - let val = obj - .get(scope, key.into()) - .ok_or_else(|| JsErrorBox::type_error("missing field 'width'"))?; - let width = deno_core::convert::Number::::from_v8(scope, val)?.0; - - let key = v8::String::new(scope, "height").unwrap(); - let val = obj - .get(scope, key.into()) - .ok_or_else(|| JsErrorBox::type_error("missing field 'height'"))?; - let height = deno_core::convert::Number::::from_v8(scope, val)?.0; - - Ok(Self { - system, - window_handle, - display_handle, - width, - height, - }) - } + type Error = JsErrorBox; + + fn from_v8( + scope: &mut v8::HandleScope<'a>, + value: Local<'a, Value>, + ) -> Result { + let obj = value + .try_cast::() + .map_err(|_| JsErrorBox::type_error("is not an object"))?; + + let key = v8::String::new(scope, "system").unwrap(); + let val = obj + .get(scope, key.into()) + .ok_or_else(|| JsErrorBox::type_error("missing field 'system'"))?; + let s = String::from_v8(scope, val).unwrap(); + let system = match s.as_str() { + "cocoa" => UnsafeWindowSurfaceSystem::Cocoa, + "win32" => UnsafeWindowSurfaceSystem::Win32, + "x11" => UnsafeWindowSurfaceSystem::X11, + "wayland" => UnsafeWindowSurfaceSystem::Wayland, + _ => { + return Err(JsErrorBox::type_error(format!( + "Invalid system kind '{s}'" + ))); + } + }; + + let key = v8::String::new(scope, "windowHandle").unwrap(); + let val = obj + .get(scope, key.into()) + .ok_or_else(|| JsErrorBox::type_error("missing field 'windowHandle'"))?; + let Some(window_handle) = deno_core::_ops::to_external_option(&val) else { + return Err(JsErrorBox::type_error("expected external")); + }; + + let key = v8::String::new(scope, "displayHandle").unwrap(); + let val = obj + .get(scope, key.into()) + .ok_or_else(|| JsErrorBox::type_error("missing field 'displayHandle'"))?; + let Some(display_handle) = deno_core::_ops::to_external_option(&val) else { + return Err(JsErrorBox::type_error("expected external")); + }; + + let key = v8::String::new(scope, "width").unwrap(); + let val = obj + .get(scope, key.into()) + .ok_or_else(|| JsErrorBox::type_error("missing field 'width'"))?; + let width = deno_core::convert::Number::::from_v8(scope, val)?.0; + + let key = v8::String::new(scope, "height").unwrap(); + let val = obj + .get(scope, key.into()) + .ok_or_else(|| JsErrorBox::type_error("missing field 'height'"))?; + let height = deno_core::convert::Number::::from_v8(scope, val)?.0; + + Ok(Self { + system, + window_handle, + display_handle, + width, + height, + }) + } } type RawHandles = ( - raw_window_handle::RawWindowHandle, - raw_window_handle::RawDisplayHandle, + raw_window_handle::RawWindowHandle, + raw_window_handle::RawDisplayHandle, ); #[cfg(target_os = "macos")] fn raw_window( - system: UnsafeWindowSurfaceSystem, - _ns_window: *const c_void, - ns_view: *const c_void, + system: UnsafeWindowSurfaceSystem, + _ns_window: *const c_void, + ns_view: *const c_void, ) -> Result { - if system != UnsafeWindowSurfaceSystem::Cocoa { - return Err(ByowError::InvalidSystem); - } - - let win_handle = - raw_window_handle::RawWindowHandle::AppKit(raw_window_handle::AppKitWindowHandle::new( - NonNull::new(ns_view as *mut c_void).ok_or(ByowError::NSViewDisplay)?, - )); - - let display_handle = - raw_window_handle::RawDisplayHandle::AppKit(raw_window_handle::AppKitDisplayHandle::new()); - Ok((win_handle, display_handle)) + if system != UnsafeWindowSurfaceSystem::Cocoa { + return Err(ByowError::InvalidSystem); + } + + let win_handle = raw_window_handle::RawWindowHandle::AppKit( + raw_window_handle::AppKitWindowHandle::new( + NonNull::new(ns_view as *mut c_void).ok_or(ByowError::NSViewDisplay)?, + ), + ); + + let display_handle = raw_window_handle::RawDisplayHandle::AppKit( + raw_window_handle::AppKitDisplayHandle::new(), + ); + Ok((win_handle, display_handle)) } #[cfg(target_os = "windows")] fn raw_window( - system: UnsafeWindowSurfaceSystem, - window: *const c_void, - hinstance: *const c_void, + system: UnsafeWindowSurfaceSystem, + window: *const c_void, + hinstance: *const c_void, ) -> Result { - use raw_window_handle::WindowsDisplayHandle; - if system != UnsafeWindowSurfaceSystem::Win32 { - return Err(ByowError::InvalidSystem); - } - - let win_handle = { - let mut handle = raw_window_handle::Win32WindowHandle::new( - std::num::NonZeroIsize::new(window as isize).ok_or(ByowError::NullWindow)?, - ); - handle.hinstance = std::num::NonZeroIsize::new(hinstance as isize); - - raw_window_handle::RawWindowHandle::Win32(handle) - }; - - let display_handle = raw_window_handle::RawDisplayHandle::Windows(WindowsDisplayHandle::new()); - Ok((win_handle, display_handle)) + use raw_window_handle::WindowsDisplayHandle; + if system != UnsafeWindowSurfaceSystem::Win32 { + return Err(ByowError::InvalidSystem); + } + + let win_handle = { + let mut handle = raw_window_handle::Win32WindowHandle::new( + std::num::NonZeroIsize::new(window as isize) + .ok_or(ByowError::NullWindow)?, + ); + handle.hinstance = std::num::NonZeroIsize::new(hinstance as isize); + + raw_window_handle::RawWindowHandle::Win32(handle) + }; + + let display_handle = + raw_window_handle::RawDisplayHandle::Windows(WindowsDisplayHandle::new()); + Ok((win_handle, display_handle)) } #[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"))] fn raw_window( - system: UnsafeWindowSurfaceSystem, - window: *const c_void, - display: *const c_void, + system: UnsafeWindowSurfaceSystem, + window: *const c_void, + display: *const c_void, ) -> Result { - let (win_handle, display_handle); - if system == UnsafeWindowSurfaceSystem::X11 { - win_handle = raw_window_handle::RawWindowHandle::Xlib( - raw_window_handle::XlibWindowHandle::new(window as *mut c_void as _), - ); - - display_handle = raw_window_handle::RawDisplayHandle::Xlib( - raw_window_handle::XlibDisplayHandle::new(NonNull::new(display as *mut c_void), 0), - ); - } else if system == UnsafeWindowSurfaceSystem::Wayland { - win_handle = raw_window_handle::RawWindowHandle::Wayland( - raw_window_handle::WaylandWindowHandle::new( - NonNull::new(window as *mut c_void).ok_or(ByowError::NullWindow)?, - ), - ); - - display_handle = raw_window_handle::RawDisplayHandle::Wayland( - raw_window_handle::WaylandDisplayHandle::new( - NonNull::new(display as *mut c_void).ok_or(ByowError::NullDisplay)?, - ), - ); - } else { - return Err(ByowError::InvalidSystem); - } - - Ok((win_handle, display_handle)) + let (win_handle, display_handle); + if system == UnsafeWindowSurfaceSystem::X11 { + win_handle = raw_window_handle::RawWindowHandle::Xlib( + raw_window_handle::XlibWindowHandle::new(window as *mut c_void as _), + ); + + display_handle = raw_window_handle::RawDisplayHandle::Xlib( + raw_window_handle::XlibDisplayHandle::new( + NonNull::new(display as *mut c_void), + 0, + ), + ); + } else if system == UnsafeWindowSurfaceSystem::Wayland { + win_handle = raw_window_handle::RawWindowHandle::Wayland( + raw_window_handle::WaylandWindowHandle::new( + NonNull::new(window as *mut c_void).ok_or(ByowError::NullWindow)?, + ), + ); + + display_handle = raw_window_handle::RawDisplayHandle::Wayland( + raw_window_handle::WaylandDisplayHandle::new( + NonNull::new(display as *mut c_void).ok_or(ByowError::NullDisplay)?, + ), + ); + } else { + return Err(ByowError::InvalidSystem); + } + + Ok((win_handle, display_handle)) } #[cfg(not(any( - target_os = "macos", - target_os = "windows", - target_os = "linux", - target_os = "freebsd", - target_os = "openbsd", + target_os = "macos", + target_os = "windows", + target_os = "linux", + target_os = "freebsd", + target_os = "openbsd", )))] fn raw_window( - _system: UnsafeWindowSurfaceSystem, - _window: *const c_void, - _display: *const c_void, + _system: UnsafeWindowSurfaceSystem, + _window: *const c_void, + _display: *const c_void, ) -> Result { - Err(deno_error::JsErrorBox::type_error("Unsupported platform")) + Err(deno_error::JsErrorBox::type_error("Unsupported platform")) } diff --git a/deno_webgpu/command_buffer.rs b/deno_webgpu/command_buffer.rs index b89795d6545..d03311376c4 100644 --- a/deno_webgpu/command_buffer.rs +++ b/deno_webgpu/command_buffer.rs @@ -7,40 +7,40 @@ use deno_core::WebIDL; use crate::Instance; pub struct GPUCommandBuffer { - pub instance: Instance, - pub id: wgpu_core::id::CommandBufferId, - pub label: String, + pub instance: Instance, + pub id: wgpu_core::id::CommandBufferId, + pub label: String, } impl Drop for GPUCommandBuffer { - fn drop(&mut self) { - self.instance.command_buffer_drop(self.id); - } + fn drop(&mut self) { + self.instance.command_buffer_drop(self.id); + } } impl deno_core::webidl::WebIdlInterfaceConverter for GPUCommandBuffer { - const NAME: &'static str = "GPUCommandBuffer"; + const NAME: &'static str = "GPUCommandBuffer"; } impl GarbageCollected for GPUCommandBuffer {} #[op2] impl GPUCommandBuffer { - #[getter] - #[string] - fn label(&self) -> String { - self.label.clone() - } - #[setter] - #[string] - fn label(&self, #[webidl] _label: String) { - // TODO(@crowlKats): no-op, needs wpgu to implement changing the label - } + #[getter] + #[string] + fn label(&self) -> String { + self.label.clone() + } + #[setter] + #[string] + fn label(&self, #[webidl] _label: String) { + // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUCommandBufferDescriptor { - #[webidl(default = String::new())] - pub label: String, + #[webidl(default = String::new())] + pub label: String, } diff --git a/deno_webgpu/command_encoder.rs b/deno_webgpu/command_encoder.rs index 0106b0c0c8d..91a4146da7a 100644 --- a/deno_webgpu/command_encoder.rs +++ b/deno_webgpu/command_encoder.rs @@ -23,61 +23,61 @@ use crate::webidl::GPUExtent3D; use crate::Instance; pub struct GPUCommandEncoder { - pub instance: Instance, - pub error_handler: super::error::ErrorHandler, + pub instance: Instance, + pub error_handler: super::error::ErrorHandler, - pub id: wgpu_core::id::CommandEncoderId, - pub label: String, + pub id: wgpu_core::id::CommandEncoderId, + pub label: String, } impl Drop for GPUCommandEncoder { - fn drop(&mut self) { - self.instance.command_encoder_drop(self.id); - } + fn drop(&mut self) { + self.instance.command_encoder_drop(self.id); + } } impl GarbageCollected for GPUCommandEncoder {} #[op2] impl GPUCommandEncoder { - #[getter] - #[string] - fn label(&self) -> String { - self.label.clone() - } - #[setter] - #[string] - fn label(&self, #[webidl] _label: String) { - // TODO(@crowlKats): no-op, needs wpgu to implement changing the label - } - - #[required(1)] - #[cppgc] - fn begin_render_pass( - &self, - #[webidl] descriptor: crate::render_pass::GPURenderPassDescriptor, - ) -> Result { - let color_attachments = Cow::Owned( - descriptor - .color_attachments - .into_iter() - .map(|attachment| { - attachment.into_option().map(|attachment| { - wgpu_core::command::RenderPassColorAttachment { - view: attachment.view.id, - depth_slice: attachment.depth_slice, - resolve_target: attachment.resolve_target.map(|target| target.id), - load_op: attachment - .load_op - .with_default_value(attachment.clear_value.map(Into::into)), - store_op: attachment.store_op.into(), - } - }) - }) - .collect::>(), - ); + #[getter] + #[string] + fn label(&self) -> String { + self.label.clone() + } + #[setter] + #[string] + fn label(&self, #[webidl] _label: String) { + // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } + + #[required(1)] + #[cppgc] + fn begin_render_pass( + &self, + #[webidl] descriptor: crate::render_pass::GPURenderPassDescriptor, + ) -> Result { + let color_attachments = Cow::Owned( + descriptor + .color_attachments + .into_iter() + .map(|attachment| { + attachment.into_option().map(|attachment| { + wgpu_core::command::RenderPassColorAttachment { + view: attachment.view.id, + depth_slice: attachment.depth_slice, + resolve_target: attachment.resolve_target.map(|target| target.id), + load_op: attachment + .load_op + .with_default_value(attachment.clear_value.map(Into::into)), + store_op: attachment.store_op.into(), + } + }) + }) + .collect::>(), + ); - let depth_stencil_attachment = descriptor + let depth_stencil_attachment = descriptor .depth_stencil_attachment .map(|attachment| { if attachment @@ -111,359 +111,366 @@ impl GPUCommandEncoder { }) .transpose()?; - let timestamp_writes = descriptor.timestamp_writes.map(|timestamp_writes| { - wgpu_core::command::PassTimestampWrites { - query_set: timestamp_writes.query_set.id, - beginning_of_pass_write_index: timestamp_writes.beginning_of_pass_write_index, - end_of_pass_write_index: timestamp_writes.end_of_pass_write_index, - } - }); - - let wgpu_descriptor = wgpu_core::command::RenderPassDescriptor { - label: crate::transform_label(descriptor.label.clone()), - color_attachments, - depth_stencil_attachment: depth_stencil_attachment.as_ref(), - timestamp_writes: timestamp_writes.as_ref(), - occlusion_query_set: descriptor.occlusion_query_set.map(|query_set| query_set.id), - }; - - let (render_pass, err) = self - .instance - .command_encoder_begin_render_pass(self.id, &wgpu_descriptor); - - self.error_handler.push_error(err); - - Ok(GPURenderPassEncoder { - instance: self.instance.clone(), - error_handler: self.error_handler.clone(), - render_pass: RefCell::new(render_pass), - label: descriptor.label, - }) - } - - #[cppgc] - fn begin_compute_pass( - &self, - #[webidl] descriptor: crate::compute_pass::GPUComputePassDescriptor, - ) -> GPUComputePassEncoder { - let timestamp_writes = descriptor.timestamp_writes.map(|timestamp_writes| { - wgpu_core::command::PassTimestampWrites { - query_set: timestamp_writes.query_set.id, - beginning_of_pass_write_index: timestamp_writes.beginning_of_pass_write_index, - end_of_pass_write_index: timestamp_writes.end_of_pass_write_index, - } - }); - - let wgpu_descriptor = wgpu_core::command::ComputePassDescriptor { - label: crate::transform_label(descriptor.label.clone()), - timestamp_writes, - }; - - let (compute_pass, err) = self - .instance - .command_encoder_begin_compute_pass(self.id, &wgpu_descriptor); - - self.error_handler.push_error(err); - - GPUComputePassEncoder { - instance: self.instance.clone(), - error_handler: self.error_handler.clone(), - compute_pass: RefCell::new(compute_pass), - label: descriptor.label, + let timestamp_writes = + descriptor.timestamp_writes.map(|timestamp_writes| { + wgpu_core::command::PassTimestampWrites { + query_set: timestamp_writes.query_set.id, + beginning_of_pass_write_index: timestamp_writes + .beginning_of_pass_write_index, + end_of_pass_write_index: timestamp_writes.end_of_pass_write_index, } - } - - #[required(2)] - fn copy_buffer_to_buffer<'a>( - &self, - scope: &mut v8::HandleScope<'a>, - #[webidl] source: Ptr, - arg2: v8::Local<'a, v8::Value>, - arg3: v8::Local<'a, v8::Value>, - arg4: v8::Local<'a, v8::Value>, - arg5: v8::Local<'a, v8::Value>, - ) -> Result<(), WebIdlError> { - let prefix = "Failed to execute 'GPUCommandEncoder.copyBufferToBuffer'"; - let int_options = IntOptions { - clamp: false, - enforce_range: true, - }; - - let source_offset: BufferAddress; - let destination: Ptr; - let destination_offset: BufferAddress; - let size: Option; - // Note that the last argument to either overload of `copy_buffer_to_buffer` - // is optional, so `arg5.is_undefined()` would not work here. - if arg4.is_undefined() { - // 3-argument overload - source_offset = 0; - destination = Ptr::::convert( - scope, - arg2, - Cow::Borrowed(prefix), - (|| Cow::Borrowed("destination")).into(), - &(), - )?; - destination_offset = 0; - size = >::convert( - scope, - arg3, - Cow::Borrowed(prefix), - (|| Cow::Borrowed("size")).into(), - &int_options, - )?; - } else { - // 5-argument overload - source_offset = u64::convert( - scope, - arg2, - Cow::Borrowed(prefix), - (|| Cow::Borrowed("sourceOffset")).into(), - &int_options, - )?; - destination = Ptr::::convert( - scope, - arg3, - Cow::Borrowed(prefix), - (|| Cow::Borrowed("destination")).into(), - &(), - )?; - destination_offset = u64::convert( - scope, - arg4, - Cow::Borrowed(prefix), - (|| Cow::Borrowed("destinationOffset")).into(), - &int_options, - )?; - size = >::convert( - scope, - arg5, - Cow::Borrowed(prefix), - (|| Cow::Borrowed("size")).into(), - &int_options, - )?; + }); + + let wgpu_descriptor = wgpu_core::command::RenderPassDescriptor { + label: crate::transform_label(descriptor.label.clone()), + color_attachments, + depth_stencil_attachment: depth_stencil_attachment.as_ref(), + timestamp_writes: timestamp_writes.as_ref(), + occlusion_query_set: descriptor + .occlusion_query_set + .map(|query_set| query_set.id), + }; + + let (render_pass, err) = self + .instance + .command_encoder_begin_render_pass(self.id, &wgpu_descriptor); + + self.error_handler.push_error(err); + + Ok(GPURenderPassEncoder { + instance: self.instance.clone(), + error_handler: self.error_handler.clone(), + render_pass: RefCell::new(render_pass), + label: descriptor.label, + }) + } + + #[cppgc] + fn begin_compute_pass( + &self, + #[webidl] descriptor: crate::compute_pass::GPUComputePassDescriptor, + ) -> GPUComputePassEncoder { + let timestamp_writes = + descriptor.timestamp_writes.map(|timestamp_writes| { + wgpu_core::command::PassTimestampWrites { + query_set: timestamp_writes.query_set.id, + beginning_of_pass_write_index: timestamp_writes + .beginning_of_pass_write_index, + end_of_pass_write_index: timestamp_writes.end_of_pass_write_index, } + }); - let err = self - .instance - .command_encoder_copy_buffer_to_buffer( - self.id, - source.id, - source_offset, - destination.id, - destination_offset, - size, - ) - .err(); - - self.error_handler.push_error(err); - - Ok(()) - } - - #[required(3)] - fn copy_buffer_to_texture( - &self, - #[webidl] source: GPUTexelCopyBufferInfo, - #[webidl] destination: GPUTexelCopyTextureInfo, - #[webidl] copy_size: GPUExtent3D, - ) { - let source = TexelCopyBufferInfo { - buffer: source.buffer.id, - layout: wgpu_types::TexelCopyBufferLayout { - offset: source.offset, - bytes_per_row: source.bytes_per_row, - rows_per_image: source.rows_per_image, - }, - }; - let destination = wgpu_types::TexelCopyTextureInfo { - texture: destination.texture.id, - mip_level: destination.mip_level, - origin: destination.origin.into(), - aspect: destination.aspect.into(), - }; - - let err = self - .instance - .command_encoder_copy_buffer_to_texture( - self.id, - &source, - &destination, - ©_size.into(), - ) - .err(); - - self.error_handler.push_error(err); - } + let wgpu_descriptor = wgpu_core::command::ComputePassDescriptor { + label: crate::transform_label(descriptor.label.clone()), + timestamp_writes, + }; - #[required(3)] - fn copy_texture_to_buffer( - &self, - #[webidl] source: GPUTexelCopyTextureInfo, - #[webidl] destination: GPUTexelCopyBufferInfo, - #[webidl] copy_size: GPUExtent3D, - ) { - let source = wgpu_types::TexelCopyTextureInfo { - texture: source.texture.id, - mip_level: source.mip_level, - origin: source.origin.into(), - aspect: source.aspect.into(), - }; - let destination = TexelCopyBufferInfo { - buffer: destination.buffer.id, - layout: wgpu_types::TexelCopyBufferLayout { - offset: destination.offset, - bytes_per_row: destination.bytes_per_row, - rows_per_image: destination.rows_per_image, - }, - }; - - let err = self - .instance - .command_encoder_copy_texture_to_buffer( - self.id, - &source, - &destination, - ©_size.into(), - ) - .err(); - - self.error_handler.push_error(err); - } + let (compute_pass, err) = self + .instance + .command_encoder_begin_compute_pass(self.id, &wgpu_descriptor); - #[required(3)] - fn copy_texture_to_texture( - &self, - #[webidl] source: GPUTexelCopyTextureInfo, - #[webidl] destination: GPUTexelCopyTextureInfo, - #[webidl] copy_size: GPUExtent3D, - ) { - let source = wgpu_types::TexelCopyTextureInfo { - texture: source.texture.id, - mip_level: source.mip_level, - origin: source.origin.into(), - aspect: source.aspect.into(), - }; - let destination = wgpu_types::TexelCopyTextureInfo { - texture: destination.texture.id, - mip_level: destination.mip_level, - origin: destination.origin.into(), - aspect: destination.aspect.into(), - }; - - let err = self - .instance - .command_encoder_copy_texture_to_texture( - self.id, - &source, - &destination, - ©_size.into(), - ) - .err(); - - self.error_handler.push_error(err); - } + self.error_handler.push_error(err); - #[required(1)] - fn clear_buffer( - &self, - #[webidl] buffer: Ptr, - #[webidl(default = 0, options(enforce_range = true))] offset: u64, - #[webidl(options(enforce_range = true))] size: Option, - ) { - let err = self - .instance - .command_encoder_clear_buffer(self.id, buffer.id, offset, size) - .err(); - self.error_handler.push_error(err); + GPUComputePassEncoder { + instance: self.instance.clone(), + error_handler: self.error_handler.clone(), + compute_pass: RefCell::new(compute_pass), + label: descriptor.label, } - - #[required(5)] - fn resolve_query_set( - &self, - #[webidl] query_set: Ptr, - #[webidl(options(enforce_range = true))] first_query: u32, - #[webidl(options(enforce_range = true))] query_count: u32, - #[webidl] destination: Ptr, - #[webidl(options(enforce_range = true))] destination_offset: u64, - ) { - let err = self - .instance - .command_encoder_resolve_query_set( - self.id, - query_set.id, - first_query, - query_count, - destination.id, - destination_offset, - ) - .err(); - - self.error_handler.push_error(err); - } - - #[cppgc] - fn finish( - &self, - #[webidl] descriptor: crate::command_buffer::GPUCommandBufferDescriptor, - ) -> GPUCommandBuffer { - let wgpu_descriptor = wgpu_types::CommandBufferDescriptor { - label: crate::transform_label(descriptor.label.clone()), - }; - - let (id, err) = self - .instance - .command_encoder_finish(self.id, &wgpu_descriptor, None); - - self.error_handler.push_error(err); - - GPUCommandBuffer { - instance: self.instance.clone(), - id, - label: descriptor.label, - } - } - - fn push_debug_group(&self, #[webidl] group_label: String) { - let err = self - .instance - .command_encoder_push_debug_group(self.id, &group_label) - .err(); - self.error_handler.push_error(err); - } - - #[fast] - fn pop_debug_group(&self) { - let err = self.instance.command_encoder_pop_debug_group(self.id).err(); - self.error_handler.push_error(err); + } + + #[required(2)] + fn copy_buffer_to_buffer<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + #[webidl] source: Ptr, + arg2: v8::Local<'a, v8::Value>, + arg3: v8::Local<'a, v8::Value>, + arg4: v8::Local<'a, v8::Value>, + arg5: v8::Local<'a, v8::Value>, + ) -> Result<(), WebIdlError> { + let prefix = "Failed to execute 'GPUCommandEncoder.copyBufferToBuffer'"; + let int_options = IntOptions { + clamp: false, + enforce_range: true, + }; + + let source_offset: BufferAddress; + let destination: Ptr; + let destination_offset: BufferAddress; + let size: Option; + // Note that the last argument to either overload of `copy_buffer_to_buffer` + // is optional, so `arg5.is_undefined()` would not work here. + if arg4.is_undefined() { + // 3-argument overload + source_offset = 0; + destination = Ptr::::convert( + scope, + arg2, + Cow::Borrowed(prefix), + (|| Cow::Borrowed("destination")).into(), + &(), + )?; + destination_offset = 0; + size = >::convert( + scope, + arg3, + Cow::Borrowed(prefix), + (|| Cow::Borrowed("size")).into(), + &int_options, + )?; + } else { + // 5-argument overload + source_offset = u64::convert( + scope, + arg2, + Cow::Borrowed(prefix), + (|| Cow::Borrowed("sourceOffset")).into(), + &int_options, + )?; + destination = Ptr::::convert( + scope, + arg3, + Cow::Borrowed(prefix), + (|| Cow::Borrowed("destination")).into(), + &(), + )?; + destination_offset = u64::convert( + scope, + arg4, + Cow::Borrowed(prefix), + (|| Cow::Borrowed("destinationOffset")).into(), + &int_options, + )?; + size = >::convert( + scope, + arg5, + Cow::Borrowed(prefix), + (|| Cow::Borrowed("size")).into(), + &int_options, + )?; } - fn insert_debug_marker(&self, #[webidl] marker_label: String) { - let err = self - .instance - .command_encoder_insert_debug_marker(self.id, &marker_label) - .err(); - self.error_handler.push_error(err); + let err = self + .instance + .command_encoder_copy_buffer_to_buffer( + self.id, + source.id, + source_offset, + destination.id, + destination_offset, + size, + ) + .err(); + + self.error_handler.push_error(err); + + Ok(()) + } + + #[required(3)] + fn copy_buffer_to_texture( + &self, + #[webidl] source: GPUTexelCopyBufferInfo, + #[webidl] destination: GPUTexelCopyTextureInfo, + #[webidl] copy_size: GPUExtent3D, + ) { + let source = TexelCopyBufferInfo { + buffer: source.buffer.id, + layout: wgpu_types::TexelCopyBufferLayout { + offset: source.offset, + bytes_per_row: source.bytes_per_row, + rows_per_image: source.rows_per_image, + }, + }; + let destination = wgpu_types::TexelCopyTextureInfo { + texture: destination.texture.id, + mip_level: destination.mip_level, + origin: destination.origin.into(), + aspect: destination.aspect.into(), + }; + + let err = self + .instance + .command_encoder_copy_buffer_to_texture( + self.id, + &source, + &destination, + ©_size.into(), + ) + .err(); + + self.error_handler.push_error(err); + } + + #[required(3)] + fn copy_texture_to_buffer( + &self, + #[webidl] source: GPUTexelCopyTextureInfo, + #[webidl] destination: GPUTexelCopyBufferInfo, + #[webidl] copy_size: GPUExtent3D, + ) { + let source = wgpu_types::TexelCopyTextureInfo { + texture: source.texture.id, + mip_level: source.mip_level, + origin: source.origin.into(), + aspect: source.aspect.into(), + }; + let destination = TexelCopyBufferInfo { + buffer: destination.buffer.id, + layout: wgpu_types::TexelCopyBufferLayout { + offset: destination.offset, + bytes_per_row: destination.bytes_per_row, + rows_per_image: destination.rows_per_image, + }, + }; + + let err = self + .instance + .command_encoder_copy_texture_to_buffer( + self.id, + &source, + &destination, + ©_size.into(), + ) + .err(); + + self.error_handler.push_error(err); + } + + #[required(3)] + fn copy_texture_to_texture( + &self, + #[webidl] source: GPUTexelCopyTextureInfo, + #[webidl] destination: GPUTexelCopyTextureInfo, + #[webidl] copy_size: GPUExtent3D, + ) { + let source = wgpu_types::TexelCopyTextureInfo { + texture: source.texture.id, + mip_level: source.mip_level, + origin: source.origin.into(), + aspect: source.aspect.into(), + }; + let destination = wgpu_types::TexelCopyTextureInfo { + texture: destination.texture.id, + mip_level: destination.mip_level, + origin: destination.origin.into(), + aspect: destination.aspect.into(), + }; + + let err = self + .instance + .command_encoder_copy_texture_to_texture( + self.id, + &source, + &destination, + ©_size.into(), + ) + .err(); + + self.error_handler.push_error(err); + } + + #[required(1)] + fn clear_buffer( + &self, + #[webidl] buffer: Ptr, + #[webidl(default = 0, options(enforce_range = true))] offset: u64, + #[webidl(options(enforce_range = true))] size: Option, + ) { + let err = self + .instance + .command_encoder_clear_buffer(self.id, buffer.id, offset, size) + .err(); + self.error_handler.push_error(err); + } + + #[required(5)] + fn resolve_query_set( + &self, + #[webidl] query_set: Ptr, + #[webidl(options(enforce_range = true))] first_query: u32, + #[webidl(options(enforce_range = true))] query_count: u32, + #[webidl] destination: Ptr, + #[webidl(options(enforce_range = true))] destination_offset: u64, + ) { + let err = self + .instance + .command_encoder_resolve_query_set( + self.id, + query_set.id, + first_query, + query_count, + destination.id, + destination_offset, + ) + .err(); + + self.error_handler.push_error(err); + } + + #[cppgc] + fn finish( + &self, + #[webidl] descriptor: crate::command_buffer::GPUCommandBufferDescriptor, + ) -> GPUCommandBuffer { + let wgpu_descriptor = wgpu_types::CommandBufferDescriptor { + label: crate::transform_label(descriptor.label.clone()), + }; + + let (id, err) = + self + .instance + .command_encoder_finish(self.id, &wgpu_descriptor, None); + + self.error_handler.push_error(err); + + GPUCommandBuffer { + instance: self.instance.clone(), + id, + label: descriptor.label, } + } + + fn push_debug_group(&self, #[webidl] group_label: String) { + let err = self + .instance + .command_encoder_push_debug_group(self.id, &group_label) + .err(); + self.error_handler.push_error(err); + } + + #[fast] + fn pop_debug_group(&self) { + let err = self.instance.command_encoder_pop_debug_group(self.id).err(); + self.error_handler.push_error(err); + } + + fn insert_debug_marker(&self, #[webidl] marker_label: String) { + let err = self + .instance + .command_encoder_insert_debug_marker(self.id, &marker_label) + .err(); + self.error_handler.push_error(err); + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUCommandEncoderDescriptor { - #[webidl(default = String::new())] - pub label: String, + #[webidl(default = String::new())] + pub label: String, } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUTexelCopyBufferInfo { - pub buffer: Ptr, - #[webidl(default = 0)] - #[options(enforce_range = true)] - offset: u64, - #[options(enforce_range = true)] - bytes_per_row: Option, - #[options(enforce_range = true)] - rows_per_image: Option, + pub buffer: Ptr, + #[webidl(default = 0)] + #[options(enforce_range = true)] + offset: u64, + #[options(enforce_range = true)] + bytes_per_row: Option, + #[options(enforce_range = true)] + rows_per_image: Option, } diff --git a/deno_webgpu/compute_pass.rs b/deno_webgpu/compute_pass.rs index 4cd060818f0..f9c837ed339 100644 --- a/deno_webgpu/compute_pass.rs +++ b/deno_webgpu/compute_pass.rs @@ -16,205 +16,218 @@ use deno_core::WebIDL; use crate::Instance; pub struct GPUComputePassEncoder { - pub instance: Instance, - pub error_handler: super::error::ErrorHandler, + pub instance: Instance, + pub error_handler: super::error::ErrorHandler, - pub compute_pass: RefCell, - pub label: String, + pub compute_pass: RefCell, + pub label: String, } impl GarbageCollected for GPUComputePassEncoder {} #[op2] impl GPUComputePassEncoder { - #[getter] - #[string] - fn label(&self) -> String { - self.label.clone() - } - #[setter] - #[string] - fn label(&self, #[webidl] _label: String) { - // TODO(@crowlKats): no-op, needs wpgu to implement changing the label - } - - fn set_pipeline(&self, #[webidl] pipeline: Ptr) { - let err = self - .instance - .compute_pass_set_pipeline(&mut self.compute_pass.borrow_mut(), pipeline.id) - .err(); - self.error_handler.push_error(err); - } - - fn dispatch_workgroups( - &self, - #[webidl(options(enforce_range = true))] work_group_count_x: u32, - #[webidl(default = 1, options(enforce_range = true))] work_group_count_y: u32, - #[webidl(default = 1, options(enforce_range = true))] work_group_count_z: u32, - ) { - let err = self - .instance - .compute_pass_dispatch_workgroups( - &mut self.compute_pass.borrow_mut(), - work_group_count_x, - work_group_count_y, - work_group_count_z, - ) - .err(); - self.error_handler.push_error(err); - } - - fn dispatch_workgroups_indirect( - &self, - #[webidl] indirect_buffer: Ptr, - #[webidl(options(enforce_range = true))] indirect_offset: u64, - ) { - let err = self - .instance - .compute_pass_dispatch_workgroups_indirect( - &mut self.compute_pass.borrow_mut(), - indirect_buffer.id, - indirect_offset, - ) - .err(); - self.error_handler.push_error(err); - } - - #[fast] - fn end(&self) { - let err = self - .instance - .compute_pass_end(&mut self.compute_pass.borrow_mut()) - .err(); - self.error_handler.push_error(err); - } - - fn push_debug_group(&self, #[webidl] group_label: String) { - let err = self - .instance - .compute_pass_push_debug_group( - &mut self.compute_pass.borrow_mut(), - &group_label, - 0, // wgpu#975 - ) - .err(); - self.error_handler.push_error(err); - } - - #[fast] - fn pop_debug_group(&self) { - let err = self - .instance - .compute_pass_pop_debug_group(&mut self.compute_pass.borrow_mut()) - .err(); - self.error_handler.push_error(err); - } - - fn insert_debug_marker(&self, #[webidl] marker_label: String) { - let err = self - .instance - .compute_pass_insert_debug_marker( - &mut self.compute_pass.borrow_mut(), - &marker_label, - 0, // wgpu#975 - ) - .err(); - self.error_handler.push_error(err); - } - - fn set_bind_group<'a>( - &self, - scope: &mut v8::HandleScope<'a>, - #[webidl(options(enforce_range = true))] index: u32, - #[webidl] bind_group: Nullable>, - dynamic_offsets: v8::Local<'a, v8::Value>, - dynamic_offsets_data_start: v8::Local<'a, v8::Value>, - dynamic_offsets_data_length: v8::Local<'a, v8::Value>, - ) -> Result<(), WebIdlError> { - const PREFIX: &str = "Failed to execute 'setBindGroup' on 'GPUComputePassEncoder'"; - let err = if let Ok(uint_32) = dynamic_offsets.try_cast::() { - let start = u64::convert( - scope, - dynamic_offsets_data_start, - Cow::Borrowed(PREFIX), - (|| Cow::Borrowed("Argument 4")).into(), - &IntOptions { - clamp: false, - enforce_range: true, - }, - )? as usize; - let len = u32::convert( - scope, - dynamic_offsets_data_length, - Cow::Borrowed(PREFIX), - (|| Cow::Borrowed("Argument 5")).into(), - &IntOptions { - clamp: false, - enforce_range: true, - }, - )? as usize; - - let ab = uint_32.buffer(scope).unwrap(); - let ptr = ab.data().unwrap(); - let ab_len = ab.byte_length() / 4; - - // SAFETY: compute_pass_set_bind_group internally calls extend_from_slice with this slice - let data = unsafe { std::slice::from_raw_parts(ptr.as_ptr() as _, ab_len) }; - - let offsets = &data[start..(start + len)]; - - self.instance - .compute_pass_set_bind_group( - &mut self.compute_pass.borrow_mut(), - index, - bind_group.into_option().map(|bind_group| bind_group.id), - offsets, - ) - .err() - } else { - let offsets = >>::convert( - scope, - dynamic_offsets, - Cow::Borrowed(PREFIX), - (|| Cow::Borrowed("Argument 3")).into(), - &IntOptions { - clamp: false, - enforce_range: true, - }, - )? - .unwrap_or_default(); - - self.instance - .compute_pass_set_bind_group( - &mut self.compute_pass.borrow_mut(), - index, - bind_group.into_option().map(|bind_group| bind_group.id), - &offsets, - ) - .err() - }; - - self.error_handler.push_error(err); - - Ok(()) - } + #[getter] + #[string] + fn label(&self) -> String { + self.label.clone() + } + #[setter] + #[string] + fn label(&self, #[webidl] _label: String) { + // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } + + fn set_pipeline( + &self, + #[webidl] pipeline: Ptr, + ) { + let err = self + .instance + .compute_pass_set_pipeline( + &mut self.compute_pass.borrow_mut(), + pipeline.id, + ) + .err(); + self.error_handler.push_error(err); + } + + fn dispatch_workgroups( + &self, + #[webidl(options(enforce_range = true))] work_group_count_x: u32, + #[webidl(default = 1, options(enforce_range = true))] + work_group_count_y: u32, + #[webidl(default = 1, options(enforce_range = true))] + work_group_count_z: u32, + ) { + let err = self + .instance + .compute_pass_dispatch_workgroups( + &mut self.compute_pass.borrow_mut(), + work_group_count_x, + work_group_count_y, + work_group_count_z, + ) + .err(); + self.error_handler.push_error(err); + } + + fn dispatch_workgroups_indirect( + &self, + #[webidl] indirect_buffer: Ptr, + #[webidl(options(enforce_range = true))] indirect_offset: u64, + ) { + let err = self + .instance + .compute_pass_dispatch_workgroups_indirect( + &mut self.compute_pass.borrow_mut(), + indirect_buffer.id, + indirect_offset, + ) + .err(); + self.error_handler.push_error(err); + } + + #[fast] + fn end(&self) { + let err = self + .instance + .compute_pass_end(&mut self.compute_pass.borrow_mut()) + .err(); + self.error_handler.push_error(err); + } + + fn push_debug_group(&self, #[webidl] group_label: String) { + let err = self + .instance + .compute_pass_push_debug_group( + &mut self.compute_pass.borrow_mut(), + &group_label, + 0, // wgpu#975 + ) + .err(); + self.error_handler.push_error(err); + } + + #[fast] + fn pop_debug_group(&self) { + let err = self + .instance + .compute_pass_pop_debug_group(&mut self.compute_pass.borrow_mut()) + .err(); + self.error_handler.push_error(err); + } + + fn insert_debug_marker(&self, #[webidl] marker_label: String) { + let err = self + .instance + .compute_pass_insert_debug_marker( + &mut self.compute_pass.borrow_mut(), + &marker_label, + 0, // wgpu#975 + ) + .err(); + self.error_handler.push_error(err); + } + + fn set_bind_group<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + #[webidl(options(enforce_range = true))] index: u32, + #[webidl] bind_group: Nullable>, + dynamic_offsets: v8::Local<'a, v8::Value>, + dynamic_offsets_data_start: v8::Local<'a, v8::Value>, + dynamic_offsets_data_length: v8::Local<'a, v8::Value>, + ) -> Result<(), WebIdlError> { + const PREFIX: &str = + "Failed to execute 'setBindGroup' on 'GPUComputePassEncoder'"; + let err = if let Ok(uint_32) = dynamic_offsets.try_cast::() + { + let start = u64::convert( + scope, + dynamic_offsets_data_start, + Cow::Borrowed(PREFIX), + (|| Cow::Borrowed("Argument 4")).into(), + &IntOptions { + clamp: false, + enforce_range: true, + }, + )? as usize; + let len = u32::convert( + scope, + dynamic_offsets_data_length, + Cow::Borrowed(PREFIX), + (|| Cow::Borrowed("Argument 5")).into(), + &IntOptions { + clamp: false, + enforce_range: true, + }, + )? as usize; + + let ab = uint_32.buffer(scope).unwrap(); + let ptr = ab.data().unwrap(); + let ab_len = ab.byte_length() / 4; + + // SAFETY: compute_pass_set_bind_group internally calls extend_from_slice with this slice + let data = + unsafe { std::slice::from_raw_parts(ptr.as_ptr() as _, ab_len) }; + + let offsets = &data[start..(start + len)]; + + self + .instance + .compute_pass_set_bind_group( + &mut self.compute_pass.borrow_mut(), + index, + bind_group.into_option().map(|bind_group| bind_group.id), + offsets, + ) + .err() + } else { + let offsets = >>::convert( + scope, + dynamic_offsets, + Cow::Borrowed(PREFIX), + (|| Cow::Borrowed("Argument 3")).into(), + &IntOptions { + clamp: false, + enforce_range: true, + }, + )? + .unwrap_or_default(); + + self + .instance + .compute_pass_set_bind_group( + &mut self.compute_pass.borrow_mut(), + index, + bind_group.into_option().map(|bind_group| bind_group.id), + &offsets, + ) + .err() + }; + + self.error_handler.push_error(err); + + Ok(()) + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUComputePassDescriptor { - #[webidl(default = String::new())] - pub label: String, + #[webidl(default = String::new())] + pub label: String, - pub timestamp_writes: Option, + pub timestamp_writes: Option, } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUComputePassTimestampWrites { - pub query_set: Ptr, - #[options(enforce_range = true)] - pub beginning_of_pass_write_index: Option, - #[options(enforce_range = true)] - pub end_of_pass_write_index: Option, + pub query_set: Ptr, + #[options(enforce_range = true)] + pub beginning_of_pass_write_index: Option, + #[options(enforce_range = true)] + pub end_of_pass_write_index: Option, } diff --git a/deno_webgpu/compute_pipeline.rs b/deno_webgpu/compute_pipeline.rs index eb29686bce5..456ec9fb45c 100644 --- a/deno_webgpu/compute_pipeline.rs +++ b/deno_webgpu/compute_pipeline.rs @@ -13,70 +13,70 @@ use crate::webidl::GPUPipelineLayoutOrGPUAutoLayoutMode; use crate::Instance; pub struct GPUComputePipeline { - pub instance: Instance, - pub error_handler: super::error::ErrorHandler, + pub instance: Instance, + pub error_handler: super::error::ErrorHandler, - pub id: wgpu_core::id::ComputePipelineId, - pub label: String, + pub id: wgpu_core::id::ComputePipelineId, + pub label: String, } impl Drop for GPUComputePipeline { - fn drop(&mut self) { - self.instance.compute_pipeline_drop(self.id); - } + fn drop(&mut self) { + self.instance.compute_pipeline_drop(self.id); + } } impl WebIdlInterfaceConverter for GPUComputePipeline { - const NAME: &'static str = "GPUComputePipeline"; + const NAME: &'static str = "GPUComputePipeline"; } impl GarbageCollected for GPUComputePipeline {} #[op2] impl GPUComputePipeline { - #[getter] - #[string] - fn label(&self) -> String { - self.label.clone() - } - #[setter] - #[string] - fn label(&self, #[webidl] _label: String) { - // TODO(@crowlKats): no-op, needs wpgu to implement changing the label - } + #[getter] + #[string] + fn label(&self) -> String { + self.label.clone() + } + #[setter] + #[string] + fn label(&self, #[webidl] _label: String) { + // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } - #[cppgc] - fn get_bind_group_layout(&self, #[webidl] index: u32) -> GPUBindGroupLayout { - let (id, err) = self - .instance - .compute_pipeline_get_bind_group_layout(self.id, index, None); + #[cppgc] + fn get_bind_group_layout(&self, #[webidl] index: u32) -> GPUBindGroupLayout { + let (id, err) = self + .instance + .compute_pipeline_get_bind_group_layout(self.id, index, None); - self.error_handler.push_error(err); + self.error_handler.push_error(err); - // TODO(wgpu): needs to support retrieving the label - GPUBindGroupLayout { - instance: self.instance.clone(), - id, - label: "".to_string(), - } + // TODO(wgpu): needs to support retrieving the label + GPUBindGroupLayout { + instance: self.instance.clone(), + id, + label: "".to_string(), } + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUComputePipelineDescriptor { - #[webidl(default = String::new())] - pub label: String, + #[webidl(default = String::new())] + pub label: String, - pub compute: GPUProgrammableStage, - pub layout: GPUPipelineLayoutOrGPUAutoLayoutMode, + pub compute: GPUProgrammableStage, + pub layout: GPUPipelineLayoutOrGPUAutoLayoutMode, } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUProgrammableStage { - pub module: Ptr, - pub entry_point: Option, - #[webidl(default = Default::default())] - pub constants: IndexMap, + pub module: Ptr, + pub entry_point: Option, + #[webidl(default = Default::default())] + pub constants: IndexMap, } diff --git a/deno_webgpu/device.rs b/deno_webgpu/device.rs index 07915431756..6b96532656b 100644 --- a/deno_webgpu/device.rs +++ b/deno_webgpu/device.rs @@ -39,31 +39,31 @@ use crate::webidl::features_to_feature_names; use crate::Instance; pub struct GPUDevice { - pub instance: Instance, - pub id: wgpu_core::id::DeviceId, - pub adapter: wgpu_core::id::AdapterId, - pub queue: wgpu_core::id::QueueId, + pub instance: Instance, + pub id: wgpu_core::id::DeviceId, + pub adapter: wgpu_core::id::AdapterId, + pub queue: wgpu_core::id::QueueId, - pub label: String, + pub label: String, - pub features: SameObject, - pub limits: SameObject, - pub adapter_info: Rc>, + pub features: SameObject, + pub limits: SameObject, + pub adapter_info: Rc>, - pub queue_obj: SameObject, + pub queue_obj: SameObject, - pub error_handler: super::error::ErrorHandler, - pub lost_promise: v8::Global, + pub error_handler: super::error::ErrorHandler, + pub lost_promise: v8::Global, } impl Drop for GPUDevice { - fn drop(&mut self) { - self.instance.device_drop(self.id); - } + fn drop(&mut self) { + self.instance.device_drop(self.id); + } } impl WebIdlInterfaceConverter for GPUDevice { - const NAME: &'static str = "GPUDevice"; + const NAME: &'static str = "GPUDevice"; } impl GarbageCollected for GPUDevice {} @@ -71,803 +71,849 @@ impl GarbageCollected for GPUDevice {} // EventTarget is extended in JS #[op2] impl GPUDevice { - #[getter] - #[string] - fn label(&self) -> String { - self.label.clone() - } - #[setter] - #[string] - fn label(&self, #[webidl] _label: String) { - // TODO(@crowlKats): no-op, needs wpgu to implement changing the label - } - - #[getter] - #[global] - fn features(&self, scope: &mut v8::HandleScope) -> v8::Global { - self.features.get(scope, |scope| { - let features = self.instance.device_features(self.id); - let features = features_to_feature_names(features); - GPUSupportedFeatures::new(scope, features) - }) - } - - #[getter] - #[global] - fn limits(&self, scope: &mut v8::HandleScope) -> v8::Global { - self.limits.get(scope, |_| { - let limits = self.instance.device_limits(self.id); - GPUSupportedLimits(limits) - }) - } - - #[getter] - #[global] - fn adapter_info(&self, scope: &mut v8::HandleScope) -> v8::Global { - self.adapter_info.get(scope, |_| { - let info = self.instance.adapter_get_info(self.adapter); - let limits = self.instance.adapter_limits(self.adapter); - - GPUAdapterInfo { - info, - subgroup_min_size: limits.min_subgroup_size, - subgroup_max_size: limits.max_subgroup_size, - } - }) - } - - #[getter] - #[global] - fn queue(&self, scope: &mut v8::HandleScope) -> v8::Global { - self.queue_obj.get(scope, |_| GPUQueue { - id: self.queue, - device: self.id, - error_handler: self.error_handler.clone(), - instance: self.instance.clone(), - label: self.label.clone(), - }) - } - - #[fast] - fn destroy(&self) { - self.instance.device_destroy(self.id); - self.error_handler - .push_error(Some(GPUError::Lost(GPUDeviceLostReason::Destroyed))); - } - - #[required(1)] - #[cppgc] - fn create_buffer(&self, #[webidl] descriptor: super::buffer::GPUBufferDescriptor) -> GPUBuffer { - // Validation of the usage needs to happen on the device timeline, so - // don't raise an error immediately if it isn't valid. wgpu will - // reject `BufferUsages::empty()`. - let usage = wgpu_types::BufferUsages::from_bits(descriptor.usage) - .unwrap_or(wgpu_types::BufferUsages::empty()); - - let wgpu_descriptor = wgpu_core::resource::BufferDescriptor { - label: crate::transform_label(descriptor.label.clone()), - size: descriptor.size, - usage, - mapped_at_creation: descriptor.mapped_at_creation, - }; - - let (id, err) = self - .instance - .device_create_buffer(self.id, &wgpu_descriptor, None); - - self.error_handler.push_error(err); - - GPUBuffer { - instance: self.instance.clone(), - error_handler: self.error_handler.clone(), - id, - device: self.id, - label: descriptor.label, - size: descriptor.size, - usage: descriptor.usage, - map_state: RefCell::new(if descriptor.mapped_at_creation { - "mapped" - } else { - "unmapped" - }), - map_mode: RefCell::new(if descriptor.mapped_at_creation { - Some(wgpu_core::device::HostMap::Write) - } else { - None - }), - mapped_js_buffers: RefCell::new(vec![]), + #[getter] + #[string] + fn label(&self) -> String { + self.label.clone() + } + #[setter] + #[string] + fn label(&self, #[webidl] _label: String) { + // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } + + #[getter] + #[global] + fn features(&self, scope: &mut v8::HandleScope) -> v8::Global { + self.features.get(scope, |scope| { + let features = self.instance.device_features(self.id); + let features = features_to_feature_names(features); + GPUSupportedFeatures::new(scope, features) + }) + } + + #[getter] + #[global] + fn limits(&self, scope: &mut v8::HandleScope) -> v8::Global { + self.limits.get(scope, |_| { + let limits = self.instance.device_limits(self.id); + GPUSupportedLimits(limits) + }) + } + + #[getter] + #[global] + fn adapter_info( + &self, + scope: &mut v8::HandleScope, + ) -> v8::Global { + self.adapter_info.get(scope, |_| { + let info = self.instance.adapter_get_info(self.adapter); + let limits = self.instance.adapter_limits(self.adapter); + + GPUAdapterInfo { + info, + subgroup_min_size: limits.min_subgroup_size, + subgroup_max_size: limits.max_subgroup_size, + } + }) + } + + #[getter] + #[global] + fn queue(&self, scope: &mut v8::HandleScope) -> v8::Global { + self.queue_obj.get(scope, |_| GPUQueue { + id: self.queue, + device: self.id, + error_handler: self.error_handler.clone(), + instance: self.instance.clone(), + label: self.label.clone(), + }) + } + + #[fast] + fn destroy(&self) { + self.instance.device_destroy(self.id); + self + .error_handler + .push_error(Some(GPUError::Lost(GPUDeviceLostReason::Destroyed))); + } + + #[required(1)] + #[cppgc] + fn create_buffer( + &self, + #[webidl] descriptor: super::buffer::GPUBufferDescriptor, + ) -> GPUBuffer { + // Validation of the usage needs to happen on the device timeline, so + // don't raise an error immediately if it isn't valid. wgpu will + // reject `BufferUsages::empty()`. + let usage = wgpu_types::BufferUsages::from_bits(descriptor.usage) + .unwrap_or(wgpu_types::BufferUsages::empty()); + + let wgpu_descriptor = wgpu_core::resource::BufferDescriptor { + label: crate::transform_label(descriptor.label.clone()), + size: descriptor.size, + usage, + mapped_at_creation: descriptor.mapped_at_creation, + }; + + let (id, err) = + self + .instance + .device_create_buffer(self.id, &wgpu_descriptor, None); + + self.error_handler.push_error(err); + + GPUBuffer { + instance: self.instance.clone(), + error_handler: self.error_handler.clone(), + id, + device: self.id, + label: descriptor.label, + size: descriptor.size, + usage: descriptor.usage, + map_state: RefCell::new(if descriptor.mapped_at_creation { + "mapped" + } else { + "unmapped" + }), + map_mode: RefCell::new(if descriptor.mapped_at_creation { + Some(wgpu_core::device::HostMap::Write) + } else { + None + }), + mapped_js_buffers: RefCell::new(vec![]), + } + } + + #[required(1)] + #[cppgc] + fn create_texture( + &self, + #[webidl] descriptor: super::texture::GPUTextureDescriptor, + ) -> Result { + let wgpu_descriptor = wgpu_core::resource::TextureDescriptor { + label: crate::transform_label(descriptor.label.clone()), + size: descriptor.size.into(), + mip_level_count: descriptor.mip_level_count, + sample_count: descriptor.sample_count, + dimension: descriptor.dimension.clone().into(), + format: descriptor.format.clone().into(), + usage: wgpu_types::TextureUsages::from_bits(descriptor.usage) + .ok_or_else(|| JsErrorBox::type_error("usage is not valid"))?, + view_formats: descriptor + .view_formats + .into_iter() + .map(Into::into) + .collect(), + }; + + let (id, err) = + self + .instance + .device_create_texture(self.id, &wgpu_descriptor, None); + + self.error_handler.push_error(err); + + Ok(GPUTexture { + instance: self.instance.clone(), + error_handler: self.error_handler.clone(), + id, + label: descriptor.label, + size: wgpu_descriptor.size, + mip_level_count: wgpu_descriptor.mip_level_count, + sample_count: wgpu_descriptor.sample_count, + dimension: descriptor.dimension, + format: descriptor.format, + usage: descriptor.usage, + }) + } + + #[cppgc] + fn create_sampler( + &self, + #[webidl] descriptor: super::sampler::GPUSamplerDescriptor, + ) -> Result { + let wgpu_descriptor = wgpu_core::resource::SamplerDescriptor { + label: crate::transform_label(descriptor.label.clone()), + address_modes: [ + descriptor.address_mode_u.into(), + descriptor.address_mode_v.into(), + descriptor.address_mode_w.into(), + ], + mag_filter: descriptor.mag_filter.into(), + min_filter: descriptor.min_filter.into(), + mipmap_filter: descriptor.mipmap_filter.into(), + lod_min_clamp: descriptor.lod_min_clamp, + lod_max_clamp: descriptor.lod_max_clamp, + compare: descriptor.compare.map(Into::into), + anisotropy_clamp: descriptor.max_anisotropy, + border_color: None, + }; + + let (id, err) = + self + .instance + .device_create_sampler(self.id, &wgpu_descriptor, None); + + self.error_handler.push_error(err); + + Ok(GPUSampler { + instance: self.instance.clone(), + id, + label: descriptor.label, + }) + } + + #[required(1)] + #[cppgc] + fn create_bind_group_layout( + &self, + #[webidl] + descriptor: super::bind_group_layout::GPUBindGroupLayoutDescriptor, + ) -> Result { + let mut entries = Vec::with_capacity(descriptor.entries.len()); + + for entry in descriptor.entries { + let n_entries = [ + entry.buffer.is_some(), + entry.sampler.is_some(), + entry.texture.is_some(), + entry.storage_texture.is_some(), + ] + .into_iter() + .filter(|t| *t) + .count(); + + if n_entries != 1 { + return Err(JsErrorBox::type_error( + "Only one of 'buffer', 'sampler', 'texture' and 'storageTexture' may be specified", + )); + } + + let ty = if let Some(buffer) = entry.buffer { + BindingType::Buffer { + ty: buffer.r#type.into(), + has_dynamic_offset: buffer.has_dynamic_offset, + min_binding_size: NonZeroU64::new(buffer.min_binding_size), } - } - - #[required(1)] - #[cppgc] - fn create_texture( - &self, - #[webidl] descriptor: super::texture::GPUTextureDescriptor, - ) -> Result { - let wgpu_descriptor = wgpu_core::resource::TextureDescriptor { - label: crate::transform_label(descriptor.label.clone()), - size: descriptor.size.into(), - mip_level_count: descriptor.mip_level_count, - sample_count: descriptor.sample_count, - dimension: descriptor.dimension.clone().into(), - format: descriptor.format.clone().into(), - usage: wgpu_types::TextureUsages::from_bits(descriptor.usage) - .ok_or_else(|| JsErrorBox::type_error("usage is not valid"))?, - view_formats: descriptor - .view_formats - .into_iter() - .map(Into::into) - .collect(), - }; - - let (id, err) = self - .instance - .device_create_texture(self.id, &wgpu_descriptor, None); - - self.error_handler.push_error(err); - - Ok(GPUTexture { - instance: self.instance.clone(), - error_handler: self.error_handler.clone(), - id, - label: descriptor.label, - size: wgpu_descriptor.size, - mip_level_count: wgpu_descriptor.mip_level_count, - sample_count: wgpu_descriptor.sample_count, - dimension: descriptor.dimension, - format: descriptor.format, - usage: descriptor.usage, - }) - } - - #[cppgc] - fn create_sampler( - &self, - #[webidl] descriptor: super::sampler::GPUSamplerDescriptor, - ) -> Result { - let wgpu_descriptor = wgpu_core::resource::SamplerDescriptor { - label: crate::transform_label(descriptor.label.clone()), - address_modes: [ - descriptor.address_mode_u.into(), - descriptor.address_mode_v.into(), - descriptor.address_mode_w.into(), - ], - mag_filter: descriptor.mag_filter.into(), - min_filter: descriptor.min_filter.into(), - mipmap_filter: descriptor.mipmap_filter.into(), - lod_min_clamp: descriptor.lod_min_clamp, - lod_max_clamp: descriptor.lod_max_clamp, - compare: descriptor.compare.map(Into::into), - anisotropy_clamp: descriptor.max_anisotropy, - border_color: None, - }; - - let (id, err) = self - .instance - .device_create_sampler(self.id, &wgpu_descriptor, None); - - self.error_handler.push_error(err); - - Ok(GPUSampler { - instance: self.instance.clone(), - id, - label: descriptor.label, - }) - } - - #[required(1)] - #[cppgc] - fn create_bind_group_layout( - &self, - #[webidl] descriptor: super::bind_group_layout::GPUBindGroupLayoutDescriptor, - ) -> Result { - let mut entries = Vec::with_capacity(descriptor.entries.len()); - - for entry in descriptor.entries { - let n_entries = [ - entry.buffer.is_some(), - entry.sampler.is_some(), - entry.texture.is_some(), - entry.storage_texture.is_some(), - ] - .into_iter() - .filter(|t| *t) - .count(); - - if n_entries != 1 { - return Err(JsErrorBox::type_error("Only one of 'buffer', 'sampler', 'texture' and 'storageTexture' may be specified")); - } - - let ty = if let Some(buffer) = entry.buffer { - BindingType::Buffer { - ty: buffer.r#type.into(), - has_dynamic_offset: buffer.has_dynamic_offset, - min_binding_size: NonZeroU64::new(buffer.min_binding_size), - } - } else if let Some(sampler) = entry.sampler { - BindingType::Sampler(sampler.r#type.into()) - } else if let Some(texture) = entry.texture { - BindingType::Texture { - sample_type: texture.sample_type.into(), - view_dimension: texture.view_dimension.into(), - multisampled: texture.multisampled, - } - } else if let Some(storage_texture) = entry.storage_texture { - BindingType::StorageTexture { - access: storage_texture.access.into(), - format: storage_texture.format.into(), - view_dimension: storage_texture.view_dimension.into(), - } - } else { - unreachable!() - }; - - entries.push(wgpu_types::BindGroupLayoutEntry { - binding: entry.binding, - visibility: wgpu_types::ShaderStages::from_bits(entry.visibility) - .ok_or_else(|| JsErrorBox::type_error("usage is not valid"))?, - ty, - count: None, // native-only - }); + } else if let Some(sampler) = entry.sampler { + BindingType::Sampler(sampler.r#type.into()) + } else if let Some(texture) = entry.texture { + BindingType::Texture { + sample_type: texture.sample_type.into(), + view_dimension: texture.view_dimension.into(), + multisampled: texture.multisampled, } - - let wgpu_descriptor = wgpu_core::binding_model::BindGroupLayoutDescriptor { - label: crate::transform_label(descriptor.label.clone()), - entries: Cow::Owned(entries), - }; - - let (id, err) = - self.instance - .device_create_bind_group_layout(self.id, &wgpu_descriptor, None); - - self.error_handler.push_error(err); - - Ok(GPUBindGroupLayout { - instance: self.instance.clone(), - id, - label: descriptor.label, - }) - } - - #[required(1)] - #[cppgc] - fn create_pipeline_layout( - &self, - #[webidl] descriptor: super::pipeline_layout::GPUPipelineLayoutDescriptor, - ) -> GPUPipelineLayout { - let bind_group_layouts = descriptor - .bind_group_layouts - .into_iter() - .map(|bind_group_layout| bind_group_layout.id) - .collect(); - - let wgpu_descriptor = wgpu_core::binding_model::PipelineLayoutDescriptor { - label: crate::transform_label(descriptor.label.clone()), - bind_group_layouts: Cow::Owned(bind_group_layouts), - push_constant_ranges: Default::default(), - }; - - let (id, err) = - self.instance - .device_create_pipeline_layout(self.id, &wgpu_descriptor, None); - - self.error_handler.push_error(err); - - GPUPipelineLayout { - instance: self.instance.clone(), - id, - label: descriptor.label, + } else if let Some(storage_texture) = entry.storage_texture { + BindingType::StorageTexture { + access: storage_texture.access.into(), + format: storage_texture.format.into(), + view_dimension: storage_texture.view_dimension.into(), } - } - - #[required(1)] - #[cppgc] - fn create_bind_group( - &self, - #[webidl] descriptor: super::bind_group::GPUBindGroupDescriptor, - ) -> GPUBindGroup { - let entries = descriptor - .entries - .into_iter() - .map(|entry| wgpu_core::binding_model::BindGroupEntry { - binding: entry.binding, - resource: match entry.resource { - GPUBindingResource::Sampler(sampler) => BindingResource::Sampler(sampler.id), - GPUBindingResource::TextureView(texture_view) => { - BindingResource::TextureView(texture_view.id) - } - GPUBindingResource::BufferBinding(buffer_binding) => { - BindingResource::Buffer(wgpu_core::binding_model::BufferBinding { - buffer: buffer_binding.buffer.id, - offset: buffer_binding.offset, - size: buffer_binding.size.and_then(NonZeroU64::new), - }) - } - }, + } else { + unreachable!() + }; + + entries.push(wgpu_types::BindGroupLayoutEntry { + binding: entry.binding, + visibility: wgpu_types::ShaderStages::from_bits(entry.visibility) + .ok_or_else(|| JsErrorBox::type_error("usage is not valid"))?, + ty, + count: None, // native-only + }); + } + + let wgpu_descriptor = wgpu_core::binding_model::BindGroupLayoutDescriptor { + label: crate::transform_label(descriptor.label.clone()), + entries: Cow::Owned(entries), + }; + + let (id, err) = self.instance.device_create_bind_group_layout( + self.id, + &wgpu_descriptor, + None, + ); + + self.error_handler.push_error(err); + + Ok(GPUBindGroupLayout { + instance: self.instance.clone(), + id, + label: descriptor.label, + }) + } + + #[required(1)] + #[cppgc] + fn create_pipeline_layout( + &self, + #[webidl] descriptor: super::pipeline_layout::GPUPipelineLayoutDescriptor, + ) -> GPUPipelineLayout { + let bind_group_layouts = descriptor + .bind_group_layouts + .into_iter() + .map(|bind_group_layout| bind_group_layout.id) + .collect(); + + let wgpu_descriptor = wgpu_core::binding_model::PipelineLayoutDescriptor { + label: crate::transform_label(descriptor.label.clone()), + bind_group_layouts: Cow::Owned(bind_group_layouts), + push_constant_ranges: Default::default(), + }; + + let (id, err) = self.instance.device_create_pipeline_layout( + self.id, + &wgpu_descriptor, + None, + ); + + self.error_handler.push_error(err); + + GPUPipelineLayout { + instance: self.instance.clone(), + id, + label: descriptor.label, + } + } + + #[required(1)] + #[cppgc] + fn create_bind_group( + &self, + #[webidl] descriptor: super::bind_group::GPUBindGroupDescriptor, + ) -> GPUBindGroup { + let entries = descriptor + .entries + .into_iter() + .map(|entry| wgpu_core::binding_model::BindGroupEntry { + binding: entry.binding, + resource: match entry.resource { + GPUBindingResource::Sampler(sampler) => { + BindingResource::Sampler(sampler.id) + } + GPUBindingResource::TextureView(texture_view) => { + BindingResource::TextureView(texture_view.id) + } + GPUBindingResource::BufferBinding(buffer_binding) => { + BindingResource::Buffer(wgpu_core::binding_model::BufferBinding { + buffer: buffer_binding.buffer.id, + offset: buffer_binding.offset, + size: buffer_binding.size.and_then(NonZeroU64::new), }) - .collect::>(); - - let wgpu_descriptor = wgpu_core::binding_model::BindGroupDescriptor { - label: crate::transform_label(descriptor.label.clone()), - layout: descriptor.layout.id, - entries: Cow::Owned(entries), - }; - - let (id, err) = self - .instance - .device_create_bind_group(self.id, &wgpu_descriptor, None); - - self.error_handler.push_error(err); - - GPUBindGroup { - instance: self.instance.clone(), - id, - label: descriptor.label, + } + }, + }) + .collect::>(); + + let wgpu_descriptor = wgpu_core::binding_model::BindGroupDescriptor { + label: crate::transform_label(descriptor.label.clone()), + layout: descriptor.layout.id, + entries: Cow::Owned(entries), + }; + + let (id, err) = + self + .instance + .device_create_bind_group(self.id, &wgpu_descriptor, None); + + self.error_handler.push_error(err); + + GPUBindGroup { + instance: self.instance.clone(), + id, + label: descriptor.label, + } + } + + #[required(1)] + #[cppgc] + fn create_shader_module( + &self, + scope: &mut v8::HandleScope<'_>, + #[webidl] descriptor: super::shader::GPUShaderModuleDescriptor, + ) -> GPUShaderModule { + let wgpu_descriptor = wgpu_core::pipeline::ShaderModuleDescriptor { + label: crate::transform_label(descriptor.label.clone()), + runtime_checks: wgpu_types::ShaderRuntimeChecks::default(), + }; + + let (id, err) = self.instance.device_create_shader_module( + self.id, + &wgpu_descriptor, + wgpu_core::pipeline::ShaderModuleSource::Wgsl(Cow::Borrowed( + &descriptor.code, + )), + None, + ); + + let compilation_info = + GPUCompilationInfo::new(scope, err.iter(), &descriptor.code); + let compilation_info = make_cppgc_object(scope, compilation_info); + let compilation_info = v8::Global::new(scope, compilation_info); + self.error_handler.push_error(err); + + GPUShaderModule { + instance: self.instance.clone(), + id, + label: descriptor.label, + compilation_info, + } + } + + #[required(1)] + #[cppgc] + fn create_compute_pipeline( + &self, + #[webidl] descriptor: super::compute_pipeline::GPUComputePipelineDescriptor, + ) -> GPUComputePipeline { + self.new_compute_pipeline(descriptor) + } + + #[required(1)] + #[cppgc] + fn create_render_pipeline( + &self, + #[webidl] descriptor: super::render_pipeline::GPURenderPipelineDescriptor, + ) -> Result { + self.new_render_pipeline(descriptor) + } + + #[async_method] + #[required(1)] + #[cppgc] + async fn create_compute_pipeline_async( + &self, + #[webidl] descriptor: super::compute_pipeline::GPUComputePipelineDescriptor, + ) -> GPUComputePipeline { + self.new_compute_pipeline(descriptor) + } + + #[async_method] + #[required(1)] + #[cppgc] + async fn create_render_pipeline_async( + &self, + #[webidl] descriptor: super::render_pipeline::GPURenderPipelineDescriptor, + ) -> Result { + self.new_render_pipeline(descriptor) + } + + #[cppgc] + fn create_command_encoder( + &self, + #[webidl] descriptor: Option< + super::command_encoder::GPUCommandEncoderDescriptor, + >, + ) -> GPUCommandEncoder { + let label = descriptor.map(|d| d.label).unwrap_or_default(); + let wgpu_descriptor = wgpu_types::CommandEncoderDescriptor { + label: Some(Cow::Owned(label.clone())), + }; + + let (id, err) = self.instance.device_create_command_encoder( + self.id, + &wgpu_descriptor, + None, + ); + + self.error_handler.push_error(err); + + GPUCommandEncoder { + instance: self.instance.clone(), + error_handler: self.error_handler.clone(), + id, + label, + } + } + + #[required(1)] + #[cppgc] + fn create_render_bundle_encoder( + &self, + #[webidl] + descriptor: super::render_bundle::GPURenderBundleEncoderDescriptor, + ) -> GPURenderBundleEncoder { + let wgpu_descriptor = wgpu_core::command::RenderBundleEncoderDescriptor { + label: crate::transform_label(descriptor.label.clone()), + color_formats: Cow::Owned( + descriptor + .color_formats + .into_iter() + .map(|format| format.into_option().map(Into::into)) + .collect::>(), + ), + depth_stencil: descriptor.depth_stencil_format.map(|format| { + wgpu_types::RenderBundleDepthStencil { + format: format.into(), + depth_read_only: descriptor.depth_read_only, + stencil_read_only: descriptor.stencil_read_only, } - } - - #[required(1)] - #[cppgc] - fn create_shader_module( - &self, - scope: &mut v8::HandleScope<'_>, - #[webidl] descriptor: super::shader::GPUShaderModuleDescriptor, - ) -> GPUShaderModule { - let wgpu_descriptor = wgpu_core::pipeline::ShaderModuleDescriptor { - label: crate::transform_label(descriptor.label.clone()), - runtime_checks: wgpu_types::ShaderRuntimeChecks::default(), - }; - - let (id, err) = self.instance.device_create_shader_module( - self.id, - &wgpu_descriptor, - wgpu_core::pipeline::ShaderModuleSource::Wgsl(Cow::Borrowed(&descriptor.code)), - None, - ); - - let compilation_info = GPUCompilationInfo::new(scope, err.iter(), &descriptor.code); - let compilation_info = make_cppgc_object(scope, compilation_info); - let compilation_info = v8::Global::new(scope, compilation_info); - self.error_handler.push_error(err); - - GPUShaderModule { - instance: self.instance.clone(), - id, - label: descriptor.label, - compilation_info, - } - } - - #[required(1)] - #[cppgc] - fn create_compute_pipeline( - &self, - #[webidl] descriptor: super::compute_pipeline::GPUComputePipelineDescriptor, - ) -> GPUComputePipeline { - self.new_compute_pipeline(descriptor) - } - - #[required(1)] - #[cppgc] - fn create_render_pipeline( - &self, - #[webidl] descriptor: super::render_pipeline::GPURenderPipelineDescriptor, - ) -> Result { - self.new_render_pipeline(descriptor) - } - - #[async_method] - #[required(1)] - #[cppgc] - async fn create_compute_pipeline_async( - &self, - #[webidl] descriptor: super::compute_pipeline::GPUComputePipelineDescriptor, - ) -> GPUComputePipeline { - self.new_compute_pipeline(descriptor) - } - - #[async_method] - #[required(1)] - #[cppgc] - async fn create_render_pipeline_async( - &self, - #[webidl] descriptor: super::render_pipeline::GPURenderPipelineDescriptor, - ) -> Result { - self.new_render_pipeline(descriptor) - } - - #[cppgc] - fn create_command_encoder( - &self, - #[webidl] descriptor: Option, - ) -> GPUCommandEncoder { - let label = descriptor.map(|d| d.label).unwrap_or_default(); - let wgpu_descriptor = wgpu_types::CommandEncoderDescriptor { - label: Some(Cow::Owned(label.clone())), - }; - - let (id, err) = - self.instance - .device_create_command_encoder(self.id, &wgpu_descriptor, None); - - self.error_handler.push_error(err); - - GPUCommandEncoder { - instance: self.instance.clone(), - error_handler: self.error_handler.clone(), - id, - label, - } - } - - #[required(1)] - #[cppgc] - fn create_render_bundle_encoder( - &self, - #[webidl] descriptor: super::render_bundle::GPURenderBundleEncoderDescriptor, - ) -> GPURenderBundleEncoder { - let wgpu_descriptor = wgpu_core::command::RenderBundleEncoderDescriptor { - label: crate::transform_label(descriptor.label.clone()), - color_formats: Cow::Owned( - descriptor - .color_formats - .into_iter() - .map(|format| format.into_option().map(Into::into)) - .collect::>(), - ), - depth_stencil: descriptor.depth_stencil_format.map(|format| { - wgpu_types::RenderBundleDepthStencil { - format: format.into(), - depth_read_only: descriptor.depth_read_only, - stencil_read_only: descriptor.stencil_read_only, - } - }), - sample_count: descriptor.sample_count, - multiview: None, - }; - - let res = wgpu_core::command::RenderBundleEncoder::new(&wgpu_descriptor, self.id, None); - let (encoder, err) = match res { - Ok(encoder) => (encoder, None), - Err(e) => ( - wgpu_core::command::RenderBundleEncoder::dummy(self.id), - Some(e), - ), - }; - - self.error_handler.push_error(err); - - GPURenderBundleEncoder { - instance: self.instance.clone(), - error_handler: self.error_handler.clone(), - encoder: RefCell::new(Some(encoder)), - label: descriptor.label, - } - } - - #[required(1)] - #[cppgc] - fn create_query_set( - &self, - #[webidl] descriptor: crate::query_set::GPUQuerySetDescriptor, - ) -> GPUQuerySet { - let wgpu_descriptor = wgpu_core::resource::QuerySetDescriptor { - label: crate::transform_label(descriptor.label.clone()), - ty: descriptor.r#type.clone().into(), - count: descriptor.count, - }; - - let (id, err) = self - .instance - .device_create_query_set(self.id, &wgpu_descriptor, None); - - self.error_handler.push_error(err); - - GPUQuerySet { - instance: self.instance.clone(), - id, - r#type: descriptor.r#type, - count: descriptor.count, - label: descriptor.label, - } - } - - #[getter] - #[global] - fn lost(&self) -> v8::Global { - self.lost_promise.clone() - } - - #[required(1)] - fn push_error_scope(&self, #[webidl] filter: super::error::GPUErrorFilter) { - self.error_handler - .scopes - .lock() - .unwrap() - .push((filter, vec![])); - } - - #[async_method(fake)] - #[global] - fn pop_error_scope( - &self, - scope: &mut v8::HandleScope, - ) -> Result, JsErrorBox> { - if self.error_handler.is_lost.get().is_some() { - let val = v8::null(scope).cast::(); - return Ok(v8::Global::new(scope, val)); - } - - let Some((_, errors)) = self.error_handler.scopes.lock().unwrap().pop() else { - return Err(JsErrorBox::new( - "DOMExceptionOperationError", - "There are no error scopes on the error scope stack", - )); - }; - - let val = if let Some(err) = errors.into_iter().next() { - deno_core::error::to_v8_error(scope, &err) - } else { - v8::null(scope).into() - }; - - Ok(v8::Global::new(scope, val)) - } - - #[fast] - fn start_capture(&self) { - unsafe { - self.instance - .device_start_graphics_debugger_capture(self.id) - }; - } - #[fast] - fn stop_capture(&self) { - self.instance - .device_poll(self.id, wgpu_types::PollType::wait()) - .unwrap(); - unsafe { self.instance.device_stop_graphics_debugger_capture(self.id) }; - } + }), + sample_count: descriptor.sample_count, + multiview: None, + }; + + let res = wgpu_core::command::RenderBundleEncoder::new( + &wgpu_descriptor, + self.id, + None, + ); + let (encoder, err) = match res { + Ok(encoder) => (encoder, None), + Err(e) => ( + wgpu_core::command::RenderBundleEncoder::dummy(self.id), + Some(e), + ), + }; + + self.error_handler.push_error(err); + + GPURenderBundleEncoder { + instance: self.instance.clone(), + error_handler: self.error_handler.clone(), + encoder: RefCell::new(Some(encoder)), + label: descriptor.label, + } + } + + #[required(1)] + #[cppgc] + fn create_query_set( + &self, + #[webidl] descriptor: crate::query_set::GPUQuerySetDescriptor, + ) -> GPUQuerySet { + let wgpu_descriptor = wgpu_core::resource::QuerySetDescriptor { + label: crate::transform_label(descriptor.label.clone()), + ty: descriptor.r#type.clone().into(), + count: descriptor.count, + }; + + let (id, err) = + self + .instance + .device_create_query_set(self.id, &wgpu_descriptor, None); + + self.error_handler.push_error(err); + + GPUQuerySet { + instance: self.instance.clone(), + id, + r#type: descriptor.r#type, + count: descriptor.count, + label: descriptor.label, + } + } + + #[getter] + #[global] + fn lost(&self) -> v8::Global { + self.lost_promise.clone() + } + + #[required(1)] + fn push_error_scope(&self, #[webidl] filter: super::error::GPUErrorFilter) { + self + .error_handler + .scopes + .lock() + .unwrap() + .push((filter, vec![])); + } + + #[async_method(fake)] + #[global] + fn pop_error_scope( + &self, + scope: &mut v8::HandleScope, + ) -> Result, JsErrorBox> { + if self.error_handler.is_lost.get().is_some() { + let val = v8::null(scope).cast::(); + return Ok(v8::Global::new(scope, val)); + } + + let Some((_, errors)) = self.error_handler.scopes.lock().unwrap().pop() + else { + return Err(JsErrorBox::new( + "DOMExceptionOperationError", + "There are no error scopes on the error scope stack", + )); + }; + + let val = if let Some(err) = errors.into_iter().next() { + deno_core::error::to_v8_error(scope, &err) + } else { + v8::null(scope).into() + }; + + Ok(v8::Global::new(scope, val)) + } + + #[fast] + fn start_capture(&self) { + unsafe { + self + .instance + .device_start_graphics_debugger_capture(self.id) + }; + } + #[fast] + fn stop_capture(&self) { + self + .instance + .device_poll(self.id, wgpu_types::PollType::wait()) + .unwrap(); + unsafe { self.instance.device_stop_graphics_debugger_capture(self.id) }; + } } impl GPUDevice { - fn new_compute_pipeline( - &self, - descriptor: super::compute_pipeline::GPUComputePipelineDescriptor, - ) -> GPUComputePipeline { - let wgpu_descriptor = wgpu_core::pipeline::ComputePipelineDescriptor { - label: crate::transform_label(descriptor.label.clone()), - layout: descriptor.layout.into(), - stage: ProgrammableStageDescriptor { - module: descriptor.compute.module.id, - entry_point: descriptor.compute.entry_point.map(Into::into), - constants: descriptor.compute.constants.into_iter().collect(), - zero_initialize_workgroup_memory: true, - }, - cache: None, - }; - - let (id, err) = - self.instance - .device_create_compute_pipeline(self.id, &wgpu_descriptor, None); - - self.error_handler.push_error(err); - - GPUComputePipeline { - instance: self.instance.clone(), - error_handler: self.error_handler.clone(), - id, - label: descriptor.label.clone(), - } - } - - fn new_render_pipeline( - &self, - descriptor: super::render_pipeline::GPURenderPipelineDescriptor, - ) -> Result { - let vertex = wgpu_core::pipeline::VertexState { - stage: ProgrammableStageDescriptor { - module: descriptor.vertex.module.id, - entry_point: descriptor.vertex.entry_point.map(Into::into), - constants: descriptor.vertex.constants.into_iter().collect(), - zero_initialize_workgroup_memory: true, - }, - buffers: Cow::Owned( - descriptor - .vertex - .buffers + fn new_compute_pipeline( + &self, + descriptor: super::compute_pipeline::GPUComputePipelineDescriptor, + ) -> GPUComputePipeline { + let wgpu_descriptor = wgpu_core::pipeline::ComputePipelineDescriptor { + label: crate::transform_label(descriptor.label.clone()), + layout: descriptor.layout.into(), + stage: ProgrammableStageDescriptor { + module: descriptor.compute.module.id, + entry_point: descriptor.compute.entry_point.map(Into::into), + constants: descriptor.compute.constants.into_iter().collect(), + zero_initialize_workgroup_memory: true, + }, + cache: None, + }; + + let (id, err) = self.instance.device_create_compute_pipeline( + self.id, + &wgpu_descriptor, + None, + ); + + self.error_handler.push_error(err); + + GPUComputePipeline { + instance: self.instance.clone(), + error_handler: self.error_handler.clone(), + id, + label: descriptor.label.clone(), + } + } + + fn new_render_pipeline( + &self, + descriptor: super::render_pipeline::GPURenderPipelineDescriptor, + ) -> Result { + let vertex = wgpu_core::pipeline::VertexState { + stage: ProgrammableStageDescriptor { + module: descriptor.vertex.module.id, + entry_point: descriptor.vertex.entry_point.map(Into::into), + constants: descriptor.vertex.constants.into_iter().collect(), + zero_initialize_workgroup_memory: true, + }, + buffers: Cow::Owned( + descriptor + .vertex + .buffers + .into_iter() + .map(|b| { + b.into_option().map_or_else( + wgpu_core::pipeline::VertexBufferLayout::default, + |layout| wgpu_core::pipeline::VertexBufferLayout { + array_stride: layout.array_stride, + step_mode: layout.step_mode.into(), + attributes: Cow::Owned( + layout + .attributes .into_iter() - .map(|b| { - b.into_option().map_or_else( - wgpu_core::pipeline::VertexBufferLayout::default, - |layout| wgpu_core::pipeline::VertexBufferLayout { - array_stride: layout.array_stride, - step_mode: layout.step_mode.into(), - attributes: Cow::Owned( - layout - .attributes - .into_iter() - .map(|attr| wgpu_types::VertexAttribute { - format: attr.format.into(), - offset: attr.offset, - shader_location: attr.shader_location, - }) - .collect(), - ), - }, - ) + .map(|attr| wgpu_types::VertexAttribute { + format: attr.format.into(), + offset: attr.offset, + shader_location: attr.shader_location, }) .collect(), - ), - }; - - let primitive = wgpu_types::PrimitiveState { - topology: descriptor.primitive.topology.into(), - strip_index_format: descriptor.primitive.strip_index_format.map(Into::into), - front_face: descriptor.primitive.front_face.into(), - cull_mode: descriptor.primitive.cull_mode.into(), - unclipped_depth: descriptor.primitive.unclipped_depth, - polygon_mode: Default::default(), - conservative: false, - }; - - let depth_stencil = descriptor.depth_stencil.map(|depth_stencil| { - let front = wgpu_types::StencilFaceState { - compare: depth_stencil.stencil_front.compare.into(), - fail_op: depth_stencil.stencil_front.fail_op.into(), - depth_fail_op: depth_stencil.stencil_front.depth_fail_op.into(), - pass_op: depth_stencil.stencil_front.pass_op.into(), - }; - let back = wgpu_types::StencilFaceState { - compare: depth_stencil.stencil_back.compare.into(), - fail_op: depth_stencil.stencil_back.fail_op.into(), - depth_fail_op: depth_stencil.stencil_back.depth_fail_op.into(), - pass_op: depth_stencil.stencil_back.pass_op.into(), - }; - - wgpu_types::DepthStencilState { - format: depth_stencil.format.into(), - depth_write_enabled: depth_stencil.depth_write_enabled.unwrap_or_default(), - depth_compare: depth_stencil - .depth_compare - .map(Into::into) - .unwrap_or(wgpu_types::CompareFunction::Never), // TODO(wgpu): should be optional here - stencil: wgpu_types::StencilState { - front, - back, - read_mask: depth_stencil.stencil_read_mask, - write_mask: depth_stencil.stencil_write_mask, - }, - bias: wgpu_types::DepthBiasState { - constant: depth_stencil.depth_bias, - slope_scale: depth_stencil.depth_bias_slope_scale, - clamp: depth_stencil.depth_bias_clamp, - }, - } - }); - - let multisample = wgpu_types::MultisampleState { - count: descriptor.multisample.count, - mask: descriptor.multisample.mask as u64, - alpha_to_coverage_enabled: descriptor.multisample.alpha_to_coverage_enabled, - }; - - let fragment = descriptor - .fragment - .map(|fragment| { - Ok::<_, JsErrorBox>(wgpu_core::pipeline::FragmentState { - stage: ProgrammableStageDescriptor { - module: fragment.module.id, - entry_point: fragment.entry_point.map(Into::into), - constants: fragment.constants.into_iter().collect(), - zero_initialize_workgroup_memory: true, - }, - targets: Cow::Owned( - fragment - .targets - .into_iter() - .map(|target| { - target - .into_option() - .map(|target| { - Ok(wgpu_types::ColorTargetState { - format: target.format.into(), - blend: target.blend.map(|blend| { - wgpu_types::BlendState { - color: wgpu_types::BlendComponent { - src_factor: blend.color.src_factor.into(), - dst_factor: blend.color.dst_factor.into(), - operation: blend.color.operation.into(), - }, - alpha: wgpu_types::BlendComponent { - src_factor: blend.alpha.src_factor.into(), - dst_factor: blend.alpha.dst_factor.into(), - operation: blend.alpha.operation.into(), - }, - } - }), - write_mask: wgpu_types::ColorWrites::from_bits( - target.write_mask, - ) - .ok_or_else(|| { - JsErrorBox::type_error("usage is not valid") - })?, - }) - }) - .transpose() - }) - .collect::>()?, - ), - }) - }) - .transpose()?; - - let wgpu_descriptor = wgpu_core::pipeline::RenderPipelineDescriptor { - label: crate::transform_label(descriptor.label.clone()), - layout: descriptor.layout.into(), - vertex, - primitive, - depth_stencil, - multisample, - fragment, - cache: None, - multiview: None, - }; - - let (id, err) = - self.instance - .device_create_render_pipeline(self.id, &wgpu_descriptor, None); - - self.error_handler.push_error(err); - - Ok(GPURenderPipeline { - instance: self.instance.clone(), - error_handler: self.error_handler.clone(), - id, - label: descriptor.label, + ), + }, + ) + }) + .collect(), + ), + }; + + let primitive = wgpu_types::PrimitiveState { + topology: descriptor.primitive.topology.into(), + strip_index_format: descriptor + .primitive + .strip_index_format + .map(Into::into), + front_face: descriptor.primitive.front_face.into(), + cull_mode: descriptor.primitive.cull_mode.into(), + unclipped_depth: descriptor.primitive.unclipped_depth, + polygon_mode: Default::default(), + conservative: false, + }; + + let depth_stencil = descriptor.depth_stencil.map(|depth_stencil| { + let front = wgpu_types::StencilFaceState { + compare: depth_stencil.stencil_front.compare.into(), + fail_op: depth_stencil.stencil_front.fail_op.into(), + depth_fail_op: depth_stencil.stencil_front.depth_fail_op.into(), + pass_op: depth_stencil.stencil_front.pass_op.into(), + }; + let back = wgpu_types::StencilFaceState { + compare: depth_stencil.stencil_back.compare.into(), + fail_op: depth_stencil.stencil_back.fail_op.into(), + depth_fail_op: depth_stencil.stencil_back.depth_fail_op.into(), + pass_op: depth_stencil.stencil_back.pass_op.into(), + }; + + wgpu_types::DepthStencilState { + format: depth_stencil.format.into(), + depth_write_enabled: depth_stencil + .depth_write_enabled + .unwrap_or_default(), + depth_compare: depth_stencil + .depth_compare + .map(Into::into) + .unwrap_or(wgpu_types::CompareFunction::Never), // TODO(wgpu): should be optional here + stencil: wgpu_types::StencilState { + front, + back, + read_mask: depth_stencil.stencil_read_mask, + write_mask: depth_stencil.stencil_write_mask, + }, + bias: wgpu_types::DepthBiasState { + constant: depth_stencil.depth_bias, + slope_scale: depth_stencil.depth_bias_slope_scale, + clamp: depth_stencil.depth_bias_clamp, + }, + } + }); + + let multisample = wgpu_types::MultisampleState { + count: descriptor.multisample.count, + mask: descriptor.multisample.mask as u64, + alpha_to_coverage_enabled: descriptor + .multisample + .alpha_to_coverage_enabled, + }; + + let fragment = descriptor + .fragment + .map(|fragment| { + Ok::<_, JsErrorBox>(wgpu_core::pipeline::FragmentState { + stage: ProgrammableStageDescriptor { + module: fragment.module.id, + entry_point: fragment.entry_point.map(Into::into), + constants: fragment.constants.into_iter().collect(), + zero_initialize_workgroup_memory: true, + }, + targets: Cow::Owned( + fragment + .targets + .into_iter() + .map(|target| { + target + .into_option() + .map(|target| { + Ok(wgpu_types::ColorTargetState { + format: target.format.into(), + blend: target.blend.map(|blend| wgpu_types::BlendState { + color: wgpu_types::BlendComponent { + src_factor: blend.color.src_factor.into(), + dst_factor: blend.color.dst_factor.into(), + operation: blend.color.operation.into(), + }, + alpha: wgpu_types::BlendComponent { + src_factor: blend.alpha.src_factor.into(), + dst_factor: blend.alpha.dst_factor.into(), + operation: blend.alpha.operation.into(), + }, + }), + write_mask: wgpu_types::ColorWrites::from_bits( + target.write_mask, + ) + .ok_or_else(|| { + JsErrorBox::type_error("usage is not valid") + })?, + }) + }) + .transpose() + }) + .collect::>()?, + ), }) - } + }) + .transpose()?; + + let wgpu_descriptor = wgpu_core::pipeline::RenderPipelineDescriptor { + label: crate::transform_label(descriptor.label.clone()), + layout: descriptor.layout.into(), + vertex, + primitive, + depth_stencil, + multisample, + fragment, + cache: None, + multiview: None, + }; + + let (id, err) = self.instance.device_create_render_pipeline( + self.id, + &wgpu_descriptor, + None, + ); + + self.error_handler.push_error(err); + + Ok(GPURenderPipeline { + instance: self.instance.clone(), + error_handler: self.error_handler.clone(), + id, + label: descriptor.label, + }) + } } #[derive(Clone, Debug, Default, Hash, Eq, PartialEq)] pub enum GPUDeviceLostReason { - #[default] - Unknown, - Destroyed, + #[default] + Unknown, + Destroyed, } impl From for GPUDeviceLostReason { - fn from(value: wgpu_types::DeviceLostReason) -> Self { - match value { - wgpu_types::DeviceLostReason::Unknown => Self::Unknown, - wgpu_types::DeviceLostReason::Destroyed => Self::Destroyed, - } + fn from(value: wgpu_types::DeviceLostReason) -> Self { + match value { + wgpu_types::DeviceLostReason::Unknown => Self::Unknown, + wgpu_types::DeviceLostReason::Destroyed => Self::Destroyed, } + } } #[derive(Default)] pub struct GPUDeviceLostInfo { - pub reason: GPUDeviceLostReason, + pub reason: GPUDeviceLostReason, } impl GarbageCollected for GPUDeviceLostInfo {} #[op2] impl GPUDeviceLostInfo { - #[getter] - #[string] - fn reason(&self) -> &'static str { - use GPUDeviceLostReason::*; - match self.reason { - Unknown => "unknown", - Destroyed => "destroyed", - } - } - - #[getter] - #[string] - fn message(&self) -> &'static str { - "device was lost" - } + #[getter] + #[string] + fn reason(&self) -> &'static str { + use GPUDeviceLostReason::*; + match self.reason { + Unknown => "unknown", + Destroyed => "destroyed", + } + } + + #[getter] + #[string] + fn message(&self) -> &'static str { + "device was lost" + } } diff --git a/deno_webgpu/error.rs b/deno_webgpu/error.rs index 7047d19f9b6..2f727f2cc4d 100644 --- a/deno_webgpu/error.rs +++ b/deno_webgpu/error.rs @@ -44,324 +44,331 @@ use crate::device::GPUDeviceLostReason; pub type ErrorHandler = std::rc::Rc; pub struct DeviceErrorHandler { - pub is_lost: OnceLock<()>, - pub scopes: Mutex)>>, - lost_resolver: Mutex>>, - spawner: V8TaskSpawner, + pub is_lost: OnceLock<()>, + pub scopes: Mutex)>>, + lost_resolver: Mutex>>, + spawner: V8TaskSpawner, - // The error handler is constructed before the device. A weak - // reference to the device is placed here with `set_device` - // after the device is constructed. - device: OnceLock>, + // The error handler is constructed before the device. A weak + // reference to the device is placed here with `set_device` + // after the device is constructed. + device: OnceLock>, } impl DeviceErrorHandler { - pub fn new(lost_resolver: v8::Global, spawner: V8TaskSpawner) -> Self { - Self { - is_lost: Default::default(), - scopes: Mutex::new(vec![]), - lost_resolver: Mutex::new(Some(lost_resolver)), - device: OnceLock::new(), - spawner, - } - } + pub fn new( + lost_resolver: v8::Global, + spawner: V8TaskSpawner, + ) -> Self { + Self { + is_lost: Default::default(), + scopes: Mutex::new(vec![]), + lost_resolver: Mutex::new(Some(lost_resolver)), + device: OnceLock::new(), + spawner, + } + } + + pub fn set_device(&self, device: v8::Weak) { + self.device.set(device).unwrap() + } + + pub fn push_error>(&self, err: Option) { + let Some(err) = err else { + return; + }; + + if self.is_lost.get().is_some() { + return; + } + + let err = err.into(); + + if let GPUError::Lost(reason) = err { + let _ = self.is_lost.set(()); + if let Some(resolver) = self.lost_resolver.lock().unwrap().take() { + self.spawner.spawn(move |scope| { + let resolver = v8::Local::new(scope, resolver); + let info = make_cppgc_object(scope, GPUDeviceLostInfo { reason }); + let info = v8::Local::new(scope, info); + resolver.resolve(scope, info.into()); + }); + } + + return; + } + + let error_filter = match err { + GPUError::Lost(_) => unreachable!(), + GPUError::Validation(_) => GPUErrorFilter::Validation, + GPUError::OutOfMemory => GPUErrorFilter::OutOfMemory, + GPUError::Internal => GPUErrorFilter::Internal, + }; + + let mut scopes = self.scopes.lock().unwrap(); + let scope = scopes + .iter_mut() + .rfind(|(filter, _)| filter == &error_filter); + + if let Some(scope) = scope { + scope.1.push(err); + } else { + let device = self + .device + .get() + .expect("set_device was not called") + .clone(); + self.spawner.spawn(move |scope| { + let state = JsRuntime::op_state_from(&*scope); + let Some(device) = device.to_local(scope) else { + // The device has already gone away, so we don't have + // anywhere to report the error. + return; + }; + let key = v8::String::new(scope, "dispatchEvent").unwrap(); + let val = device.get(scope, key.into()).unwrap(); + let func = + v8::Global::new(scope, val.try_cast::().unwrap()); + let device = v8::Global::new(scope, device.cast::()); + let error_event_class = + state.borrow().borrow::().0.clone(); - pub fn set_device(&self, device: v8::Weak) { - self.device.set(device).unwrap() - } + let error = deno_core::error::to_v8_error(scope, &err); - pub fn push_error>(&self, err: Option) { - let Some(err) = err else { - return; - }; + let error_event_class = + v8::Local::new(scope, error_event_class.clone()); + let constructor = + v8::Local::::try_from(error_event_class).unwrap(); + let kind = v8::String::new(scope, "uncapturederror").unwrap(); - if self.is_lost.get().is_some() { - return; - } - - let err = err.into(); - - if let GPUError::Lost(reason) = err { - let _ = self.is_lost.set(()); - if let Some(resolver) = self.lost_resolver.lock().unwrap().take() { - self.spawner.spawn(move |scope| { - let resolver = v8::Local::new(scope, resolver); - let info = make_cppgc_object(scope, GPUDeviceLostInfo { reason }); - let info = v8::Local::new(scope, info); - resolver.resolve(scope, info.into()); - }); - } - - return; - } - - let error_filter = match err { - GPUError::Lost(_) => unreachable!(), - GPUError::Validation(_) => GPUErrorFilter::Validation, - GPUError::OutOfMemory => GPUErrorFilter::OutOfMemory, - GPUError::Internal => GPUErrorFilter::Internal, - }; + let obj = v8::Object::new(scope); + let key = v8::String::new(scope, "error").unwrap(); + obj.set(scope, key.into(), error); - let mut scopes = self.scopes.lock().unwrap(); - let scope = scopes - .iter_mut() - .rfind(|(filter, _)| filter == &error_filter); - - if let Some(scope) = scope { - scope.1.push(err); - } else { - let device = self - .device - .get() - .expect("set_device was not called") - .clone(); - self.spawner.spawn(move |scope| { - let state = JsRuntime::op_state_from(&*scope); - let Some(device) = device.to_local(scope) else { - // The device has already gone away, so we don't have - // anywhere to report the error. - return; - }; - let key = v8::String::new(scope, "dispatchEvent").unwrap(); - let val = device.get(scope, key.into()).unwrap(); - let func = v8::Global::new(scope, val.try_cast::().unwrap()); - let device = v8::Global::new(scope, device.cast::()); - let error_event_class = state.borrow().borrow::().0.clone(); - - let error = deno_core::error::to_v8_error(scope, &err); - - let error_event_class = v8::Local::new(scope, error_event_class.clone()); - let constructor = v8::Local::::try_from(error_event_class).unwrap(); - let kind = v8::String::new(scope, "uncapturederror").unwrap(); - - let obj = v8::Object::new(scope); - let key = v8::String::new(scope, "error").unwrap(); - obj.set(scope, key.into(), error); - - let event = constructor - .new_instance(scope, &[kind.into(), obj.into()]) - .unwrap(); - - let recv = v8::Local::new(scope, device); - func.open(scope).call(scope, recv, &[event.into()]); - }); - } + let event = constructor + .new_instance(scope, &[kind.into(), obj.into()]) + .unwrap(); + + let recv = v8::Local::new(scope, device); + func.open(scope).call(scope, recv, &[event.into()]); + }); } + } } #[derive(deno_core::WebIDL, Eq, PartialEq)] #[webidl(enum)] pub enum GPUErrorFilter { - Validation, - OutOfMemory, - Internal, + Validation, + OutOfMemory, + Internal, } #[derive(Debug, deno_error::JsError)] pub enum GPUError { - // TODO(@crowlKats): consider adding an unreachable value that uses unreachable!() - #[class("UNREACHABLE")] - Lost(GPUDeviceLostReason), - #[class("GPUValidationError")] - Validation(String), - #[class("GPUOutOfMemoryError")] - OutOfMemory, - #[class("GPUInternalError")] - Internal, + // TODO(@crowlKats): consider adding an unreachable value that uses unreachable!() + #[class("UNREACHABLE")] + Lost(GPUDeviceLostReason), + #[class("GPUValidationError")] + Validation(String), + #[class("GPUOutOfMemoryError")] + OutOfMemory, + #[class("GPUInternalError")] + Internal, } impl Display for GPUError { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - GPUError::Lost(_) => Ok(()), - GPUError::Validation(s) => f.write_str(s), - GPUError::OutOfMemory => f.write_str("not enough memory left"), - GPUError::Internal => Ok(()), - } + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + GPUError::Lost(_) => Ok(()), + GPUError::Validation(s) => f.write_str(s), + GPUError::OutOfMemory => f.write_str("not enough memory left"), + GPUError::Internal => Ok(()), } + } } impl std::error::Error for GPUError {} impl GPUError { - fn from_webgpu(e: impl WebGpuError) -> Self { - match e.webgpu_error_type() { - ErrorType::Internal => GPUError::Internal, - ErrorType::DeviceLost => GPUError::Lost(GPUDeviceLostReason::Unknown), // TODO: this variant should be ignored, register the lost callback instead. - ErrorType::OutOfMemory => GPUError::OutOfMemory, - ErrorType::Validation => GPUError::Validation(fmt_err(&e)), - } + fn from_webgpu(e: impl WebGpuError) -> Self { + match e.webgpu_error_type() { + ErrorType::Internal => GPUError::Internal, + ErrorType::DeviceLost => GPUError::Lost(GPUDeviceLostReason::Unknown), // TODO: this variant should be ignored, register the lost callback instead. + ErrorType::OutOfMemory => GPUError::OutOfMemory, + ErrorType::Validation => GPUError::Validation(fmt_err(&e)), } + } } fn fmt_err(err: &(dyn std::error::Error + 'static)) -> String { - let mut output = err.to_string(); + let mut output = err.to_string(); - let mut e = err.source(); - while let Some(source) = e { - output.push_str(&format!(": {source}")); - e = source.source(); - } + let mut e = err.source(); + while let Some(source) = e { + output.push_str(&format!(": {source}")); + e = source.source(); + } - if output.is_empty() { - output.push_str("validation error"); - } + if output.is_empty() { + output.push_str("validation error"); + } - output + output } impl From for GPUError { - fn from(err: EncoderStateError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: EncoderStateError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: PassStateError) -> Self { - GPUError::Validation(fmt_err(&err)) - } + fn from(err: PassStateError) -> Self { + GPUError::Validation(fmt_err(&err)) + } } impl From for GPUError { - fn from(err: CreateBufferError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: CreateBufferError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: DeviceError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: DeviceError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: BufferAccessError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: BufferAccessError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: CreateBindGroupLayoutError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: CreateBindGroupLayoutError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: CreatePipelineLayoutError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: CreatePipelineLayoutError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: CreateBindGroupError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: CreateBindGroupError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: RenderBundleError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: RenderBundleError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: CreateRenderBundleError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: CreateRenderBundleError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: CommandEncoderError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: CommandEncoderError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: QueryError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: QueryError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: ComputePassError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: ComputePassError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: CreateComputePipelineError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: CreateComputePipelineError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: GetBindGroupLayoutError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: GetBindGroupLayoutError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: CreateRenderPipelineError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: CreateRenderPipelineError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: RenderPassError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: RenderPassError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: CreateSamplerError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: CreateSamplerError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: CreateShaderModuleError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: CreateShaderModuleError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: CreateTextureError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: CreateTextureError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: CreateTextureViewError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: CreateTextureViewError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: CreateQuerySetError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: CreateQuerySetError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: QueueSubmitError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: QueueSubmitError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: QueueWriteError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: QueueWriteError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: ClearError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: ClearError) -> Self { + GPUError::from_webgpu(err) + } } impl From for GPUError { - fn from(err: ConfigureSurfaceError) -> Self { - GPUError::from_webgpu(err) - } + fn from(err: ConfigureSurfaceError) -> Self { + GPUError::from_webgpu(err) + } } diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index 8b39160b264..27f04ba5af3 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -42,85 +42,85 @@ pub const UNSTABLE_FEATURE_NAME: &str = "webgpu"; #[allow(clippy::print_stdout)] pub fn print_linker_flags(name: &str) { - if cfg!(windows) { - // these dls load slowly, so delay loading them - let dlls = [ - // webgpu - "d3dcompiler_47", - "OPENGL32", - // network related functions - "iphlpapi", - ]; - for dll in dlls { - println!("cargo:rustc-link-arg-bin={name}=/delayload:{dll}.dll"); - } - // enable delay loading - println!("cargo:rustc-link-arg-bin={name}=delayimp.lib"); + if cfg!(windows) { + // these dls load slowly, so delay loading them + let dlls = [ + // webgpu + "d3dcompiler_47", + "OPENGL32", + // network related functions + "iphlpapi", + ]; + for dll in dlls { + println!("cargo:rustc-link-arg-bin={name}=/delayload:{dll}.dll"); } + // enable delay loading + println!("cargo:rustc-link-arg-bin={name}=delayimp.lib"); + } } pub type Instance = Arc; deno_core::extension!( - deno_webgpu, - deps = [deno_webidl, deno_web], - ops = [op_create_gpu], - objects = [ - GPU, - adapter::GPUAdapter, - adapter::GPUAdapterInfo, - bind_group::GPUBindGroup, - bind_group_layout::GPUBindGroupLayout, - buffer::GPUBuffer, - command_buffer::GPUCommandBuffer, - command_encoder::GPUCommandEncoder, - compute_pass::GPUComputePassEncoder, - compute_pipeline::GPUComputePipeline, - device::GPUDevice, - device::GPUDeviceLostInfo, - pipeline_layout::GPUPipelineLayout, - query_set::GPUQuerySet, - queue::GPUQueue, - render_bundle::GPURenderBundle, - render_bundle::GPURenderBundleEncoder, - render_pass::GPURenderPassEncoder, - render_pipeline::GPURenderPipeline, - sampler::GPUSampler, - shader::GPUCompilationInfo, - shader::GPUCompilationMessage, - shader::GPUShaderModule, - adapter::GPUSupportedFeatures, - adapter::GPUSupportedLimits, - texture::GPUTexture, - texture::GPUTextureView, - texture::GPUExternalTexture, - byow::UnsafeWindowSurface, - surface::GPUCanvasContext, - ], - esm = ["00_init.js", "02_surface.js"], - lazy_loaded_esm = ["01_webgpu.js"], + deno_webgpu, + deps = [deno_webidl, deno_web], + ops = [op_create_gpu], + objects = [ + GPU, + adapter::GPUAdapter, + adapter::GPUAdapterInfo, + bind_group::GPUBindGroup, + bind_group_layout::GPUBindGroupLayout, + buffer::GPUBuffer, + command_buffer::GPUCommandBuffer, + command_encoder::GPUCommandEncoder, + compute_pass::GPUComputePassEncoder, + compute_pipeline::GPUComputePipeline, + device::GPUDevice, + device::GPUDeviceLostInfo, + pipeline_layout::GPUPipelineLayout, + query_set::GPUQuerySet, + queue::GPUQueue, + render_bundle::GPURenderBundle, + render_bundle::GPURenderBundleEncoder, + render_pass::GPURenderPassEncoder, + render_pipeline::GPURenderPipeline, + sampler::GPUSampler, + shader::GPUCompilationInfo, + shader::GPUCompilationMessage, + shader::GPUShaderModule, + adapter::GPUSupportedFeatures, + adapter::GPUSupportedLimits, + texture::GPUTexture, + texture::GPUTextureView, + texture::GPUExternalTexture, + byow::UnsafeWindowSurface, + surface::GPUCanvasContext, + ], + esm = ["00_init.js", "02_surface.js"], + lazy_loaded_esm = ["01_webgpu.js"], ); #[op2] #[cppgc] pub fn op_create_gpu( - state: &mut OpState, - scope: &mut v8::HandleScope, - webidl_brand: v8::Local, - set_event_target_data: v8::Local, - error_event_class: v8::Local, + state: &mut OpState, + scope: &mut v8::HandleScope, + webidl_brand: v8::Local, + set_event_target_data: v8::Local, + error_event_class: v8::Local, ) -> GPU { - state.put(EventTargetSetup { - brand: v8::Global::new(scope, webidl_brand), - set_event_target_data: v8::Global::new(scope, set_event_target_data), - }); - state.put(ErrorEventClass(v8::Global::new(scope, error_event_class))); - GPU + state.put(EventTargetSetup { + brand: v8::Global::new(scope, webidl_brand), + set_event_target_data: v8::Global::new(scope, set_event_target_data), + }); + state.put(ErrorEventClass(v8::Global::new(scope, error_event_class))); + GPU } struct EventTargetSetup { - brand: v8::Global, - set_event_target_data: v8::Global, + brand: v8::Global, + set_event_target_data: v8::Global, } struct ErrorEventClass(v8::Global); @@ -130,83 +130,83 @@ impl GarbageCollected for GPU {} #[op2] impl GPU { - #[async_method] - #[cppgc] - async fn request_adapter( - &self, - state: Rc>, - #[webidl] options: adapter::GPURequestAdapterOptions, - ) -> Option { - let mut state = state.borrow_mut(); - - let backends = std::env::var("DENO_WEBGPU_BACKEND").map_or_else( - |_| wgpu_types::Backends::all(), - |s| wgpu_types::Backends::from_comma_list(&s), - ); - let instance = if let Some(instance) = state.try_borrow::() { - instance - } else { - state.put(Arc::new(wgpu_core::global::Global::new( - "webgpu", - &wgpu_types::InstanceDescriptor { - backends, - flags: wgpu_types::InstanceFlags::from_build_config(), - memory_budget_thresholds: wgpu_types::MemoryBudgetThresholds { - for_resource_creation: Some(97), - for_device_loss: Some(99), - }, - backend_options: wgpu_types::BackendOptions { - dx12: wgpu_types::Dx12BackendOptions { - shader_compiler: wgpu_types::Dx12Compiler::Fxc, - ..Default::default() - }, - gl: wgpu_types::GlBackendOptions::default(), - noop: wgpu_types::NoopBackendOptions::default(), - }, - }, - ))); - state.borrow::() - }; - - let descriptor = wgpu_core::instance::RequestAdapterOptions { - power_preference: options - .power_preference - .map(|pp| match pp { - adapter::GPUPowerPreference::LowPower => PowerPreference::LowPower, - adapter::GPUPowerPreference::HighPerformance => { - PowerPreference::HighPerformance - } - }) - .unwrap_or_default(), - force_fallback_adapter: options.force_fallback_adapter, - compatible_surface: None, // windowless - }; - let id = instance.request_adapter(&descriptor, backends, None).ok()?; - - Some(adapter::GPUAdapter { - instance: instance.clone(), - features: SameObject::new(), - limits: SameObject::new(), - info: Rc::new(SameObject::new()), - id, + #[async_method] + #[cppgc] + async fn request_adapter( + &self, + state: Rc>, + #[webidl] options: adapter::GPURequestAdapterOptions, + ) -> Option { + let mut state = state.borrow_mut(); + + let backends = std::env::var("DENO_WEBGPU_BACKEND").map_or_else( + |_| wgpu_types::Backends::all(), + |s| wgpu_types::Backends::from_comma_list(&s), + ); + let instance = if let Some(instance) = state.try_borrow::() { + instance + } else { + state.put(Arc::new(wgpu_core::global::Global::new( + "webgpu", + &wgpu_types::InstanceDescriptor { + backends, + flags: wgpu_types::InstanceFlags::from_build_config(), + memory_budget_thresholds: wgpu_types::MemoryBudgetThresholds { + for_resource_creation: Some(97), + for_device_loss: Some(99), + }, + backend_options: wgpu_types::BackendOptions { + dx12: wgpu_types::Dx12BackendOptions { + shader_compiler: wgpu_types::Dx12Compiler::Fxc, + ..Default::default() + }, + gl: wgpu_types::GlBackendOptions::default(), + noop: wgpu_types::NoopBackendOptions::default(), + }, + }, + ))); + state.borrow::() + }; + + let descriptor = wgpu_core::instance::RequestAdapterOptions { + power_preference: options + .power_preference + .map(|pp| match pp { + adapter::GPUPowerPreference::LowPower => PowerPreference::LowPower, + adapter::GPUPowerPreference::HighPerformance => { + PowerPreference::HighPerformance + } }) + .unwrap_or_default(), + force_fallback_adapter: options.force_fallback_adapter, + compatible_surface: None, // windowless + }; + let id = instance.request_adapter(&descriptor, backends, None).ok()?; + + Some(adapter::GPUAdapter { + instance: instance.clone(), + features: SameObject::new(), + limits: SameObject::new(), + info: Rc::new(SameObject::new()), + id, + }) + } + + #[string] + fn getPreferredCanvasFormat(&self) -> &'static str { + // https://github.com/mozilla/gecko-dev/blob/b75080bb8b11844d18cb5f9ac6e68a866ef8e243/dom/webgpu/Instance.h#L42-L47 + if cfg!(target_os = "android") { + texture::GPUTextureFormat::Rgba8unorm.as_str() + } else { + texture::GPUTextureFormat::Bgra8unorm.as_str() } - - #[string] - fn getPreferredCanvasFormat(&self) -> &'static str { - // https://github.com/mozilla/gecko-dev/blob/b75080bb8b11844d18cb5f9ac6e68a866ef8e243/dom/webgpu/Instance.h#L42-L47 - if cfg!(target_os = "android") { - texture::GPUTextureFormat::Rgba8unorm.as_str() - } else { - texture::GPUTextureFormat::Bgra8unorm.as_str() - } - } + } } fn transform_label<'a>(label: String) -> Option> { - if label.is_empty() { - None - } else { - Some(std::borrow::Cow::Owned(label)) - } + if label.is_empty() { + None + } else { + Some(std::borrow::Cow::Owned(label)) + } } diff --git a/deno_webgpu/pipeline_layout.rs b/deno_webgpu/pipeline_layout.rs index c785eea7334..4f507cf71be 100644 --- a/deno_webgpu/pipeline_layout.rs +++ b/deno_webgpu/pipeline_layout.rs @@ -9,42 +9,43 @@ use deno_core::WebIDL; use crate::Instance; pub struct GPUPipelineLayout { - pub instance: Instance, - pub id: wgpu_core::id::PipelineLayoutId, - pub label: String, + pub instance: Instance, + pub id: wgpu_core::id::PipelineLayoutId, + pub label: String, } impl Drop for GPUPipelineLayout { - fn drop(&mut self) { - self.instance.pipeline_layout_drop(self.id); - } + fn drop(&mut self) { + self.instance.pipeline_layout_drop(self.id); + } } impl WebIdlInterfaceConverter for GPUPipelineLayout { - const NAME: &'static str = "GPUPipelineLayout"; + const NAME: &'static str = "GPUPipelineLayout"; } impl GarbageCollected for GPUPipelineLayout {} #[op2] impl GPUPipelineLayout { - #[getter] - #[string] - fn label(&self) -> String { - self.label.clone() - } - #[setter] - #[string] - fn label(&self, #[webidl] _label: String) { - // TODO(@crowlKats): no-op, needs wpgu to implement changing the label - } + #[getter] + #[string] + fn label(&self) -> String { + self.label.clone() + } + #[setter] + #[string] + fn label(&self, #[webidl] _label: String) { + // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUPipelineLayoutDescriptor { - #[webidl(default = String::new())] - pub label: String, + #[webidl(default = String::new())] + pub label: String, - pub bind_group_layouts: Vec>, + pub bind_group_layouts: + Vec>, } diff --git a/deno_webgpu/query_set.rs b/deno_webgpu/query_set.rs index fd6502559f5..f2657c7d54b 100644 --- a/deno_webgpu/query_set.rs +++ b/deno_webgpu/query_set.rs @@ -9,82 +9,82 @@ use deno_error::JsErrorBox; use crate::Instance; pub struct GPUQuerySet { - pub instance: Instance, - pub id: wgpu_core::id::QuerySetId, - pub r#type: GPUQueryType, - pub count: u32, - pub label: String, + pub instance: Instance, + pub id: wgpu_core::id::QuerySetId, + pub r#type: GPUQueryType, + pub count: u32, + pub label: String, } impl Drop for GPUQuerySet { - fn drop(&mut self) { - self.instance.query_set_drop(self.id); - } + fn drop(&mut self) { + self.instance.query_set_drop(self.id); + } } impl WebIdlInterfaceConverter for GPUQuerySet { - const NAME: &'static str = "GPUQuerySet"; + const NAME: &'static str = "GPUQuerySet"; } impl GarbageCollected for GPUQuerySet {} #[op2] impl GPUQuerySet { - #[getter] - #[string] - fn label(&self) -> String { - self.label.clone() - } - #[setter] - #[string] - fn label(&self, #[webidl] _label: String) { - // TODO(@crowlKats): no-op, needs wpgu to implement changing the label - } + #[getter] + #[string] + fn label(&self) -> String { + self.label.clone() + } + #[setter] + #[string] + fn label(&self, #[webidl] _label: String) { + // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } - #[fast] - fn destroy(&self) -> Result<(), JsErrorBox> { - // TODO(https://github.com/gfx-rs/wgpu/issues/6495): Destroy the query - // set. Until that is supported, it is okay to do nothing here, the - // query set will be garbage collected and dropped eventually. - Ok(()) - } + #[fast] + fn destroy(&self) -> Result<(), JsErrorBox> { + // TODO(https://github.com/gfx-rs/wgpu/issues/6495): Destroy the query + // set. Until that is supported, it is okay to do nothing here, the + // query set will be garbage collected and dropped eventually. + Ok(()) + } - // Naming this `type` or `r#type` does not work. - // https://github.com/gfx-rs/wgpu/issues/7778 - #[getter] - #[string] - fn ty(&self) -> &'static str { - self.r#type.as_str() - } + // Naming this `type` or `r#type` does not work. + // https://github.com/gfx-rs/wgpu/issues/7778 + #[getter] + #[string] + fn ty(&self) -> &'static str { + self.r#type.as_str() + } - #[getter] - fn count(&self) -> u32 { - self.count - } + #[getter] + fn count(&self) -> u32 { + self.count + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUQuerySetDescriptor { - #[webidl(default = String::new())] - pub label: String, + #[webidl(default = String::new())] + pub label: String, - pub r#type: GPUQueryType, - #[options(enforce_range = true)] - pub count: u32, + pub r#type: GPUQueryType, + #[options(enforce_range = true)] + pub count: u32, } #[derive(WebIDL, Clone)] #[webidl(enum)] pub(crate) enum GPUQueryType { - Occlusion, - Timestamp, + Occlusion, + Timestamp, } impl From for wgpu_types::QueryType { - fn from(value: GPUQueryType) -> Self { - match value { - GPUQueryType::Occlusion => Self::Occlusion, - GPUQueryType::Timestamp => Self::Timestamp, - } + fn from(value: GPUQueryType) -> Self { + match value { + GPUQueryType::Occlusion => Self::Occlusion, + GPUQueryType::Timestamp => Self::Timestamp, } + } } diff --git a/deno_webgpu/queue.rs b/deno_webgpu/queue.rs index 87fea8bac6a..1fa78a25a0c 100644 --- a/deno_webgpu/queue.rs +++ b/deno_webgpu/queue.rs @@ -21,168 +21,178 @@ use crate::webidl::GPUOrigin3D; use crate::Instance; pub struct GPUQueue { - pub instance: Instance, - pub error_handler: super::error::ErrorHandler, + pub instance: Instance, + pub error_handler: super::error::ErrorHandler, - pub label: String, + pub label: String, - pub id: wgpu_core::id::QueueId, - pub device: wgpu_core::id::DeviceId, + pub id: wgpu_core::id::QueueId, + pub device: wgpu_core::id::DeviceId, } impl Drop for GPUQueue { - fn drop(&mut self) { - self.instance.queue_drop(self.id); - } + fn drop(&mut self) { + self.instance.queue_drop(self.id); + } } impl GarbageCollected for GPUQueue {} #[op2] impl GPUQueue { - #[getter] - #[string] - fn label(&self) -> String { - self.label.clone() - } - #[setter] - #[string] - fn label(&self, #[webidl] _label: String) { - // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + #[getter] + #[string] + fn label(&self) -> String { + self.label.clone() + } + #[setter] + #[string] + fn label(&self, #[webidl] _label: String) { + // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } + + #[required(1)] + fn submit( + &self, + scope: &mut v8::HandleScope, + #[webidl] command_buffers: Vec>, + ) -> Result, JsErrorBox> { + let ids = command_buffers + .into_iter() + .map(|cb| cb.id) + .collect::>(); + + let err = self.instance.queue_submit(self.id, &ids).err(); + + if let Some((_, err)) = err { + self.error_handler.push_error(Some(err)); } - #[required(1)] - fn submit( - &self, - scope: &mut v8::HandleScope, - #[webidl] command_buffers: Vec>, - ) -> Result, JsErrorBox> { - let ids = command_buffers - .into_iter() - .map(|cb| cb.id) - .collect::>(); - - let err = self.instance.queue_submit(self.id, &ids).err(); - - if let Some((_, err)) = err { - self.error_handler.push_error(Some(err)); - } + Ok(v8::undefined(scope).into()) + } - Ok(v8::undefined(scope).into()) - } + #[async_method] + async fn on_submitted_work_done(&self) -> Result<(), JsErrorBox> { + let (sender, receiver) = oneshot::channel::<()>(); - #[async_method] - async fn on_submitted_work_done(&self) -> Result<(), JsErrorBox> { - let (sender, receiver) = oneshot::channel::<()>(); - - let callback = Box::new(move || { - sender.send(()).unwrap(); - }); - - self.instance - .queue_on_submitted_work_done(self.id, callback); - - let done = Rc::new(RefCell::new(false)); - let done_ = done.clone(); - let device_poll_fut = async move { - while !*done.borrow() { - { - self.instance - .device_poll(self.device, wgpu_types::PollType::wait()) - .unwrap(); - } - tokio::time::sleep(Duration::from_millis(10)).await; - } - Ok::<(), JsErrorBox>(()) - }; - - let receiver_fut = async move { - receiver - .await - .map_err(|e| JsErrorBox::generic(e.to_string()))?; - let mut done = done_.borrow_mut(); - *done = true; - Ok::<(), JsErrorBox>(()) - }; - - tokio::try_join!(device_poll_fut, receiver_fut)?; - - Ok(()) - } + let callback = Box::new(move || { + sender.send(()).unwrap(); + }); - #[required(3)] - fn write_buffer( - &self, - #[webidl] buffer: Ptr, - #[webidl(options(enforce_range = true))] buffer_offset: u64, - #[anybuffer] buf: &[u8], - #[webidl(default = 0, options(enforce_range = true))] data_offset: u64, - #[webidl(options(enforce_range = true))] size: Option, - ) { - let data = match size { - Some(size) => &buf[(data_offset as usize)..((data_offset + size) as usize)], - None => &buf[(data_offset as usize)..], - }; - - let err = self - .instance - .queue_write_buffer(self.id, buffer.id, buffer_offset, data) - .err(); + self + .instance + .queue_on_submitted_work_done(self.id, callback); - self.error_handler.push_error(err); - } - - #[required(4)] - fn write_texture( - &self, - #[webidl] destination: GPUTexelCopyTextureInfo, - #[anybuffer] buf: &[u8], - #[webidl] data_layout: GPUTexelCopyBufferLayout, - #[webidl] size: GPUExtent3D, - ) { - let destination = wgpu_types::TexelCopyTextureInfo { - texture: destination.texture.id, - mip_level: destination.mip_level, - origin: destination.origin.into(), - aspect: destination.aspect.into(), - }; - - let data_layout = wgpu_types::TexelCopyBufferLayout { - offset: data_layout.offset, - bytes_per_row: data_layout.bytes_per_row, - rows_per_image: data_layout.rows_per_image, - }; - - let err = self + let done = Rc::new(RefCell::new(false)); + let done_ = done.clone(); + let device_poll_fut = async move { + while !*done.borrow() { + { + self .instance - .queue_write_texture(self.id, &destination, buf, &data_layout, &size.into()) - .err(); - - self.error_handler.push_error(err); - } + .device_poll(self.device, wgpu_types::PollType::wait()) + .unwrap(); + } + tokio::time::sleep(Duration::from_millis(10)).await; + } + Ok::<(), JsErrorBox>(()) + }; + + let receiver_fut = async move { + receiver + .await + .map_err(|e| JsErrorBox::generic(e.to_string()))?; + let mut done = done_.borrow_mut(); + *done = true; + Ok::<(), JsErrorBox>(()) + }; + + tokio::try_join!(device_poll_fut, receiver_fut)?; + + Ok(()) + } + + #[required(3)] + fn write_buffer( + &self, + #[webidl] buffer: Ptr, + #[webidl(options(enforce_range = true))] buffer_offset: u64, + #[anybuffer] buf: &[u8], + #[webidl(default = 0, options(enforce_range = true))] data_offset: u64, + #[webidl(options(enforce_range = true))] size: Option, + ) { + let data = match size { + Some(size) => { + &buf[(data_offset as usize)..((data_offset + size) as usize)] + } + None => &buf[(data_offset as usize)..], + }; + + let err = self + .instance + .queue_write_buffer(self.id, buffer.id, buffer_offset, data) + .err(); + + self.error_handler.push_error(err); + } + + #[required(4)] + fn write_texture( + &self, + #[webidl] destination: GPUTexelCopyTextureInfo, + #[anybuffer] buf: &[u8], + #[webidl] data_layout: GPUTexelCopyBufferLayout, + #[webidl] size: GPUExtent3D, + ) { + let destination = wgpu_types::TexelCopyTextureInfo { + texture: destination.texture.id, + mip_level: destination.mip_level, + origin: destination.origin.into(), + aspect: destination.aspect.into(), + }; + + let data_layout = wgpu_types::TexelCopyBufferLayout { + offset: data_layout.offset, + bytes_per_row: data_layout.bytes_per_row, + rows_per_image: data_layout.rows_per_image, + }; + + let err = self + .instance + .queue_write_texture( + self.id, + &destination, + buf, + &data_layout, + &size.into(), + ) + .err(); + + self.error_handler.push_error(err); + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUTexelCopyTextureInfo { - pub texture: Ptr, - #[webidl(default = 0)] - #[options(enforce_range = true)] - pub mip_level: u32, - #[webidl(default = Default::default())] - pub origin: GPUOrigin3D, - #[webidl(default = GPUTextureAspect::All)] - pub aspect: GPUTextureAspect, + pub texture: Ptr, + #[webidl(default = 0)] + #[options(enforce_range = true)] + pub mip_level: u32, + #[webidl(default = Default::default())] + pub origin: GPUOrigin3D, + #[webidl(default = GPUTextureAspect::All)] + pub aspect: GPUTextureAspect, } #[derive(WebIDL)] #[webidl(dictionary)] struct GPUTexelCopyBufferLayout { - #[webidl(default = 0)] - #[options(enforce_range = true)] - offset: u64, - #[options(enforce_range = true)] - bytes_per_row: Option, - #[options(enforce_range = true)] - rows_per_image: Option, + #[webidl(default = 0)] + #[options(enforce_range = true)] + offset: u64, + #[options(enforce_range = true)] + bytes_per_row: Option, + #[options(enforce_range = true)] + rows_per_image: Option, } diff --git a/deno_webgpu/render_bundle.rs b/deno_webgpu/render_bundle.rs index da31929d84a..6f3aea74fac 100644 --- a/deno_webgpu/render_bundle.rs +++ b/deno_webgpu/render_bundle.rs @@ -20,396 +20,412 @@ use crate::buffer::GPUBuffer; use crate::texture::GPUTextureFormat; use crate::Instance; -fn c_string_truncated_at_first_nul>>(src: T) -> std::ffi::CString { - std::ffi::CString::new(src).unwrap_or_else(|err| { - let nul_pos = err.nul_position(); - std::ffi::CString::new(err.into_vec().split_at(nul_pos).0).unwrap() - }) +fn c_string_truncated_at_first_nul>>( + src: T, +) -> std::ffi::CString { + std::ffi::CString::new(src).unwrap_or_else(|err| { + let nul_pos = err.nul_position(); + std::ffi::CString::new(err.into_vec().split_at(nul_pos).0).unwrap() + }) } pub struct GPURenderBundleEncoder { - pub instance: Instance, - pub error_handler: super::error::ErrorHandler, + pub instance: Instance, + pub error_handler: super::error::ErrorHandler, - pub encoder: RefCell>, - pub label: String, + pub encoder: RefCell>, + pub label: String, } impl GarbageCollected for GPURenderBundleEncoder {} #[op2] impl GPURenderBundleEncoder { - #[getter] - #[string] - fn label(&self) -> String { - self.label.clone() + #[getter] + #[string] + fn label(&self) -> String { + self.label.clone() + } + #[setter] + #[string] + fn label(&self, #[webidl] _label: String) { + // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } + + #[cppgc] + fn finish( + &self, + #[webidl] descriptor: GPURenderBundleDescriptor, + ) -> GPURenderBundle { + let wgpu_descriptor = wgpu_core::command::RenderBundleDescriptor { + label: crate::transform_label(descriptor.label.clone()), + }; + + let (id, err) = self.instance.render_bundle_encoder_finish( + self.encoder.borrow_mut().take().unwrap(), + &wgpu_descriptor, + None, + ); + + self.error_handler.push_error(err); + + GPURenderBundle { + instance: self.instance.clone(), + id, + label: descriptor.label.clone(), } - #[setter] - #[string] - fn label(&self, #[webidl] _label: String) { - // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } + + fn push_debug_group( + &self, + #[webidl] group_label: String, + ) -> Result<(), JsErrorBox> { + let mut encoder = self.encoder.borrow_mut(); + let encoder = encoder.as_mut().ok_or_else(|| { + JsErrorBox::generic("Encoder has already been finished") + })?; + + let label = c_string_truncated_at_first_nul(group_label); + // SAFETY: the string the raw pointer points to lives longer than the below + // function invocation. + unsafe { + wgpu_core::command::bundle_ffi::wgpu_render_bundle_push_debug_group( + encoder, + label.as_ptr(), + ); } - #[cppgc] - fn finish(&self, #[webidl] descriptor: GPURenderBundleDescriptor) -> GPURenderBundle { - let wgpu_descriptor = wgpu_core::command::RenderBundleDescriptor { - label: crate::transform_label(descriptor.label.clone()), - }; - - let (id, err) = self.instance.render_bundle_encoder_finish( - self.encoder.borrow_mut().take().unwrap(), - &wgpu_descriptor, - None, - ); - - self.error_handler.push_error(err); - - GPURenderBundle { - instance: self.instance.clone(), - id, - label: descriptor.label.clone(), - } - } - - fn push_debug_group(&self, #[webidl] group_label: String) -> Result<(), JsErrorBox> { - let mut encoder = self.encoder.borrow_mut(); - let encoder = encoder - .as_mut() - .ok_or_else(|| JsErrorBox::generic("Encoder has already been finished"))?; - - let label = c_string_truncated_at_first_nul(group_label); - // SAFETY: the string the raw pointer points to lives longer than the below - // function invocation. - unsafe { - wgpu_core::command::bundle_ffi::wgpu_render_bundle_push_debug_group( - encoder, - label.as_ptr(), - ); - } - - Ok(()) - } - - #[fast] - fn pop_debug_group(&self) -> Result<(), JsErrorBox> { - let mut encoder = self.encoder.borrow_mut(); - let encoder = encoder - .as_mut() - .ok_or_else(|| JsErrorBox::generic("Encoder has already been finished"))?; - wgpu_core::command::bundle_ffi::wgpu_render_bundle_pop_debug_group(encoder); - Ok(()) + Ok(()) + } + + #[fast] + fn pop_debug_group(&self) -> Result<(), JsErrorBox> { + let mut encoder = self.encoder.borrow_mut(); + let encoder = encoder.as_mut().ok_or_else(|| { + JsErrorBox::generic("Encoder has already been finished") + })?; + wgpu_core::command::bundle_ffi::wgpu_render_bundle_pop_debug_group(encoder); + Ok(()) + } + + fn insert_debug_marker( + &self, + #[webidl] marker_label: String, + ) -> Result<(), JsErrorBox> { + let mut encoder = self.encoder.borrow_mut(); + let encoder = encoder.as_mut().ok_or_else(|| { + JsErrorBox::generic("Encoder has already been finished") + })?; + + let label = c_string_truncated_at_first_nul(marker_label); + // SAFETY: the string the raw pointer points to lives longer than the below + // function invocation. + unsafe { + wgpu_core::command::bundle_ffi::wgpu_render_bundle_insert_debug_marker( + encoder, + label.as_ptr(), + ); } - - fn insert_debug_marker(&self, #[webidl] marker_label: String) -> Result<(), JsErrorBox> { - let mut encoder = self.encoder.borrow_mut(); - let encoder = encoder - .as_mut() - .ok_or_else(|| JsErrorBox::generic("Encoder has already been finished"))?; - - let label = c_string_truncated_at_first_nul(marker_label); - // SAFETY: the string the raw pointer points to lives longer than the below - // function invocation. - unsafe { - wgpu_core::command::bundle_ffi::wgpu_render_bundle_insert_debug_marker( - encoder, - label.as_ptr(), - ); - } - Ok(()) - } - - fn set_bind_group<'a>( - &self, - scope: &mut v8::HandleScope<'a>, - #[webidl(options(enforce_range = true))] index: u32, - #[webidl] bind_group: Nullable>, - dynamic_offsets: v8::Local<'a, v8::Value>, - dynamic_offsets_data_start: v8::Local<'a, v8::Value>, - dynamic_offsets_data_length: v8::Local<'a, v8::Value>, - ) -> Result<(), SetBindGroupError> { - let mut encoder = self.encoder.borrow_mut(); - let encoder = encoder - .as_mut() - .ok_or_else(|| JsErrorBox::generic("Encoder has already been finished"))?; - - const PREFIX: &str = "Failed to execute 'setBindGroup' on 'GPUComputePassEncoder'"; - if let Ok(uint_32) = dynamic_offsets.try_cast::() { - let start = u64::convert( - scope, - dynamic_offsets_data_start, - Cow::Borrowed(PREFIX), - (|| Cow::Borrowed("Argument 4")).into(), - &IntOptions { - clamp: false, - enforce_range: true, - }, - )? as usize; - let len = u32::convert( - scope, - dynamic_offsets_data_length, - Cow::Borrowed(PREFIX), - (|| Cow::Borrowed("Argument 5")).into(), - &IntOptions { - clamp: false, - enforce_range: true, - }, - )? as usize; - - let ab = uint_32.buffer(scope).unwrap(); - let ptr = ab.data().unwrap(); - let ab_len = ab.byte_length() / 4; - - // SAFETY: created from an array buffer, slice is dropped at end of function call - let data = unsafe { std::slice::from_raw_parts(ptr.as_ptr() as _, ab_len) }; - - let offsets = &data[start..(start + len)]; - - // SAFETY: wgpu FFI call - unsafe { - wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_bind_group( - encoder, - index, - bind_group.into_option().map(|bind_group| bind_group.id), - offsets.as_ptr(), - offsets.len(), - ); - } - } else { - let offsets = >>::convert( - scope, - dynamic_offsets, - Cow::Borrowed(PREFIX), - (|| Cow::Borrowed("Argument 3")).into(), - &IntOptions { - clamp: false, - enforce_range: true, - }, - )? - .unwrap_or_default(); - - // SAFETY: wgpu FFI call - unsafe { - wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_bind_group( - encoder, - index, - bind_group.into_option().map(|bind_group| bind_group.id), - offsets.as_ptr(), - offsets.len(), - ); - } - } - - Ok(()) - } - - fn set_pipeline( - &self, - #[webidl] pipeline: Ptr, - ) -> Result<(), JsErrorBox> { - let mut encoder = self.encoder.borrow_mut(); - let encoder = encoder - .as_mut() - .ok_or_else(|| JsErrorBox::generic("Encoder has already been finished"))?; - - wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_pipeline(encoder, pipeline.id); - Ok(()) - } - - #[required(2)] - fn set_index_buffer( - &self, - #[webidl] buffer: Ptr, - #[webidl] index_format: crate::render_pipeline::GPUIndexFormat, - #[webidl(default = 0, options(enforce_range = true))] offset: u64, - #[webidl(options(enforce_range = true))] size: Option, - ) -> Result<(), JsErrorBox> { - let mut encoder = self.encoder.borrow_mut(); - let encoder = encoder - .as_mut() - .ok_or_else(|| JsErrorBox::generic("Encoder has already been finished"))?; - - encoder.set_index_buffer( - buffer.id, - index_format.into(), - offset, - size.and_then(NonZeroU64::new), + Ok(()) + } + + fn set_bind_group<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + #[webidl(options(enforce_range = true))] index: u32, + #[webidl] bind_group: Nullable>, + dynamic_offsets: v8::Local<'a, v8::Value>, + dynamic_offsets_data_start: v8::Local<'a, v8::Value>, + dynamic_offsets_data_length: v8::Local<'a, v8::Value>, + ) -> Result<(), SetBindGroupError> { + let mut encoder = self.encoder.borrow_mut(); + let encoder = encoder.as_mut().ok_or_else(|| { + JsErrorBox::generic("Encoder has already been finished") + })?; + + const PREFIX: &str = + "Failed to execute 'setBindGroup' on 'GPUComputePassEncoder'"; + if let Ok(uint_32) = dynamic_offsets.try_cast::() { + let start = u64::convert( + scope, + dynamic_offsets_data_start, + Cow::Borrowed(PREFIX), + (|| Cow::Borrowed("Argument 4")).into(), + &IntOptions { + clamp: false, + enforce_range: true, + }, + )? as usize; + let len = u32::convert( + scope, + dynamic_offsets_data_length, + Cow::Borrowed(PREFIX), + (|| Cow::Borrowed("Argument 5")).into(), + &IntOptions { + clamp: false, + enforce_range: true, + }, + )? as usize; + + let ab = uint_32.buffer(scope).unwrap(); + let ptr = ab.data().unwrap(); + let ab_len = ab.byte_length() / 4; + + // SAFETY: created from an array buffer, slice is dropped at end of function call + let data = + unsafe { std::slice::from_raw_parts(ptr.as_ptr() as _, ab_len) }; + + let offsets = &data[start..(start + len)]; + + // SAFETY: wgpu FFI call + unsafe { + wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_bind_group( + encoder, + index, + bind_group.into_option().map(|bind_group| bind_group.id), + offsets.as_ptr(), + offsets.len(), ); - Ok(()) - } - - #[required(2)] - fn set_vertex_buffer( - &self, - #[webidl(options(enforce_range = true))] slot: u32, - #[webidl] buffer: Ptr, // TODO(wgpu): support nullable buffer - #[webidl(default = 0, options(enforce_range = true))] offset: u64, - #[webidl(options(enforce_range = true))] size: Option, - ) -> Result<(), JsErrorBox> { - let mut encoder = self.encoder.borrow_mut(); - let encoder = encoder - .as_mut() - .ok_or_else(|| JsErrorBox::generic("Encoder has already been finished"))?; - - wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_vertex_buffer( - encoder, - slot, - buffer.id, - offset, - size.and_then(NonZeroU64::new), - ); - Ok(()) - } - - #[required(1)] - fn draw( - &self, - #[webidl(options(enforce_range = true))] vertex_count: u32, - #[webidl(default = 1, options(enforce_range = true))] instance_count: u32, - #[webidl(default = 0, options(enforce_range = true))] first_vertex: u32, - #[webidl(default = 0, options(enforce_range = true))] first_instance: u32, - ) -> Result<(), JsErrorBox> { - let mut encoder = self.encoder.borrow_mut(); - let encoder = encoder - .as_mut() - .ok_or_else(|| JsErrorBox::generic("Encoder has already been finished"))?; - - wgpu_core::command::bundle_ffi::wgpu_render_bundle_draw( - encoder, - vertex_count, - instance_count, - first_vertex, - first_instance, + } + } else { + let offsets = >>::convert( + scope, + dynamic_offsets, + Cow::Borrowed(PREFIX), + (|| Cow::Borrowed("Argument 3")).into(), + &IntOptions { + clamp: false, + enforce_range: true, + }, + )? + .unwrap_or_default(); + + // SAFETY: wgpu FFI call + unsafe { + wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_bind_group( + encoder, + index, + bind_group.into_option().map(|bind_group| bind_group.id), + offsets.as_ptr(), + offsets.len(), ); - Ok(()) + } } - #[required(1)] - fn draw_indexed( - &self, - #[webidl(options(enforce_range = true))] index_count: u32, - #[webidl(default = 1, options(enforce_range = true))] instance_count: u32, - #[webidl(default = 0, options(enforce_range = true))] first_index: u32, - #[webidl(default = 0, options(enforce_range = true))] base_vertex: i32, - #[webidl(default = 0, options(enforce_range = true))] first_instance: u32, - ) -> Result<(), JsErrorBox> { - let mut encoder = self.encoder.borrow_mut(); - let encoder = encoder - .as_mut() - .ok_or_else(|| JsErrorBox::generic("Encoder has already been finished"))?; - - wgpu_core::command::bundle_ffi::wgpu_render_bundle_draw_indexed( - encoder, - index_count, - instance_count, - first_index, - base_vertex, - first_instance, - ); - Ok(()) - } - - #[required(2)] - fn draw_indirect( - &self, - #[webidl] indirect_buffer: Ptr, - #[webidl(options(enforce_range = true))] indirect_offset: u64, - ) -> Result<(), JsErrorBox> { - let mut encoder = self.encoder.borrow_mut(); - let encoder = encoder - .as_mut() - .ok_or_else(|| JsErrorBox::generic("Encoder has already been finished"))?; - - wgpu_core::command::bundle_ffi::wgpu_render_bundle_draw_indirect( - encoder, - indirect_buffer.id, - indirect_offset, - ); - Ok(()) - } - - #[required(2)] - fn draw_indexed_indirect( - &self, - #[webidl] indirect_buffer: Ptr, - #[webidl(options(enforce_range = true))] indirect_offset: u64, - ) -> Result<(), JsErrorBox> { - let mut encoder = self.encoder.borrow_mut(); - let encoder = encoder - .as_mut() - .ok_or_else(|| JsErrorBox::generic("Encoder has already been finished"))?; - - wgpu_core::command::bundle_ffi::wgpu_render_bundle_draw_indexed_indirect( - encoder, - indirect_buffer.id, - indirect_offset, - ); - Ok(()) - } + Ok(()) + } + + fn set_pipeline( + &self, + #[webidl] pipeline: Ptr, + ) -> Result<(), JsErrorBox> { + let mut encoder = self.encoder.borrow_mut(); + let encoder = encoder.as_mut().ok_or_else(|| { + JsErrorBox::generic("Encoder has already been finished") + })?; + + wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_pipeline( + encoder, + pipeline.id, + ); + Ok(()) + } + + #[required(2)] + fn set_index_buffer( + &self, + #[webidl] buffer: Ptr, + #[webidl] index_format: crate::render_pipeline::GPUIndexFormat, + #[webidl(default = 0, options(enforce_range = true))] offset: u64, + #[webidl(options(enforce_range = true))] size: Option, + ) -> Result<(), JsErrorBox> { + let mut encoder = self.encoder.borrow_mut(); + let encoder = encoder.as_mut().ok_or_else(|| { + JsErrorBox::generic("Encoder has already been finished") + })?; + + encoder.set_index_buffer( + buffer.id, + index_format.into(), + offset, + size.and_then(NonZeroU64::new), + ); + Ok(()) + } + + #[required(2)] + fn set_vertex_buffer( + &self, + #[webidl(options(enforce_range = true))] slot: u32, + #[webidl] buffer: Ptr, // TODO(wgpu): support nullable buffer + #[webidl(default = 0, options(enforce_range = true))] offset: u64, + #[webidl(options(enforce_range = true))] size: Option, + ) -> Result<(), JsErrorBox> { + let mut encoder = self.encoder.borrow_mut(); + let encoder = encoder.as_mut().ok_or_else(|| { + JsErrorBox::generic("Encoder has already been finished") + })?; + + wgpu_core::command::bundle_ffi::wgpu_render_bundle_set_vertex_buffer( + encoder, + slot, + buffer.id, + offset, + size.and_then(NonZeroU64::new), + ); + Ok(()) + } + + #[required(1)] + fn draw( + &self, + #[webidl(options(enforce_range = true))] vertex_count: u32, + #[webidl(default = 1, options(enforce_range = true))] instance_count: u32, + #[webidl(default = 0, options(enforce_range = true))] first_vertex: u32, + #[webidl(default = 0, options(enforce_range = true))] first_instance: u32, + ) -> Result<(), JsErrorBox> { + let mut encoder = self.encoder.borrow_mut(); + let encoder = encoder.as_mut().ok_or_else(|| { + JsErrorBox::generic("Encoder has already been finished") + })?; + + wgpu_core::command::bundle_ffi::wgpu_render_bundle_draw( + encoder, + vertex_count, + instance_count, + first_vertex, + first_instance, + ); + Ok(()) + } + + #[required(1)] + fn draw_indexed( + &self, + #[webidl(options(enforce_range = true))] index_count: u32, + #[webidl(default = 1, options(enforce_range = true))] instance_count: u32, + #[webidl(default = 0, options(enforce_range = true))] first_index: u32, + #[webidl(default = 0, options(enforce_range = true))] base_vertex: i32, + #[webidl(default = 0, options(enforce_range = true))] first_instance: u32, + ) -> Result<(), JsErrorBox> { + let mut encoder = self.encoder.borrow_mut(); + let encoder = encoder.as_mut().ok_or_else(|| { + JsErrorBox::generic("Encoder has already been finished") + })?; + + wgpu_core::command::bundle_ffi::wgpu_render_bundle_draw_indexed( + encoder, + index_count, + instance_count, + first_index, + base_vertex, + first_instance, + ); + Ok(()) + } + + #[required(2)] + fn draw_indirect( + &self, + #[webidl] indirect_buffer: Ptr, + #[webidl(options(enforce_range = true))] indirect_offset: u64, + ) -> Result<(), JsErrorBox> { + let mut encoder = self.encoder.borrow_mut(); + let encoder = encoder.as_mut().ok_or_else(|| { + JsErrorBox::generic("Encoder has already been finished") + })?; + + wgpu_core::command::bundle_ffi::wgpu_render_bundle_draw_indirect( + encoder, + indirect_buffer.id, + indirect_offset, + ); + Ok(()) + } + + #[required(2)] + fn draw_indexed_indirect( + &self, + #[webidl] indirect_buffer: Ptr, + #[webidl(options(enforce_range = true))] indirect_offset: u64, + ) -> Result<(), JsErrorBox> { + let mut encoder = self.encoder.borrow_mut(); + let encoder = encoder.as_mut().ok_or_else(|| { + JsErrorBox::generic("Encoder has already been finished") + })?; + + wgpu_core::command::bundle_ffi::wgpu_render_bundle_draw_indexed_indirect( + encoder, + indirect_buffer.id, + indirect_offset, + ); + Ok(()) + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPURenderBundleEncoderDescriptor { - #[webidl(default = String::new())] - pub label: String, - - pub color_formats: Vec>, - pub depth_stencil_format: Option, - #[webidl(default = 1)] - #[options(enforce_range = true)] - pub sample_count: u32, - - #[webidl(default = false)] - pub depth_read_only: bool, - #[webidl(default = false)] - pub stencil_read_only: bool, + #[webidl(default = String::new())] + pub label: String, + + pub color_formats: Vec>, + pub depth_stencil_format: Option, + #[webidl(default = 1)] + #[options(enforce_range = true)] + pub sample_count: u32, + + #[webidl(default = false)] + pub depth_read_only: bool, + #[webidl(default = false)] + pub stencil_read_only: bool, } #[derive(Debug, thiserror::Error, deno_error::JsError)] enum SetBindGroupError { - #[class(inherit)] - #[error(transparent)] - WebIDL(#[from] WebIdlError), - #[class(inherit)] - #[error(transparent)] - Other(#[from] JsErrorBox), + #[class(inherit)] + #[error(transparent)] + WebIDL(#[from] WebIdlError), + #[class(inherit)] + #[error(transparent)] + Other(#[from] JsErrorBox), } pub struct GPURenderBundle { - pub instance: Instance, - pub id: wgpu_core::id::RenderBundleId, - pub label: String, + pub instance: Instance, + pub id: wgpu_core::id::RenderBundleId, + pub label: String, } impl Drop for GPURenderBundle { - fn drop(&mut self) { - self.instance.render_bundle_drop(self.id); - } + fn drop(&mut self) { + self.instance.render_bundle_drop(self.id); + } } impl WebIdlInterfaceConverter for GPURenderBundle { - const NAME: &'static str = "GPURenderBundle"; + const NAME: &'static str = "GPURenderBundle"; } impl GarbageCollected for GPURenderBundle {} #[op2] impl GPURenderBundle { - #[getter] - #[string] - fn label(&self) -> String { - self.label.clone() - } - #[setter] - #[string] - fn label(&self, #[webidl] _label: String) { - // TODO(@crowlKats): no-op, needs wpgu to implement changing the label - } + #[getter] + #[string] + fn label(&self) -> String { + self.label.clone() + } + #[setter] + #[string] + fn label(&self, #[webidl] _label: String) { + // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPURenderBundleDescriptor { - #[webidl(default = String::new())] - pub label: String, + #[webidl(default = String::new())] + pub label: String, } diff --git a/deno_webgpu/render_pass.rs b/deno_webgpu/render_pass.rs index 97f1bd8e860..d3d8e669283 100644 --- a/deno_webgpu/render_pass.rs +++ b/deno_webgpu/render_pass.rs @@ -21,456 +21,490 @@ use crate::webidl::GPUColor; use crate::Instance; pub struct GPURenderPassEncoder { - pub instance: Instance, - pub error_handler: super::error::ErrorHandler, + pub instance: Instance, + pub error_handler: super::error::ErrorHandler, - pub render_pass: RefCell, - pub label: String, + pub render_pass: RefCell, + pub label: String, } impl GarbageCollected for GPURenderPassEncoder {} #[op2] impl GPURenderPassEncoder { - #[getter] - #[string] - fn label(&self) -> String { - self.label.clone() - } - #[setter] - #[string] - fn label(&self, #[webidl] _label: String) { - // TODO(@crowlKats): no-op, needs wpgu to implement changing the label - } - - #[required(6)] - fn set_viewport( - &self, - #[webidl] x: f32, - #[webidl] y: f32, - #[webidl] width: f32, - #[webidl] height: f32, - #[webidl] min_depth: f32, - #[webidl] max_depth: f32, - ) { - let err = self - .instance - .render_pass_set_viewport( - &mut self.render_pass.borrow_mut(), - x, - y, - width, - height, - min_depth, - max_depth, - ) - .err(); - self.error_handler.push_error(err); - } - - #[required(4)] - fn set_scissor_rect( - &self, - #[webidl(options(enforce_range = true))] x: u32, - #[webidl(options(enforce_range = true))] y: u32, - #[webidl(options(enforce_range = true))] width: u32, - #[webidl(options(enforce_range = true))] height: u32, - ) { - let err = self - .instance - .render_pass_set_scissor_rect(&mut self.render_pass.borrow_mut(), x, y, width, height) - .err(); - self.error_handler.push_error(err); - } - - #[required(1)] - fn set_blend_constant(&self, #[webidl] color: GPUColor) { - let err = self - .instance - .render_pass_set_blend_constant(&mut self.render_pass.borrow_mut(), color.into()) - .err(); - self.error_handler.push_error(err); - } - - #[required(1)] - fn set_stencil_reference(&self, #[webidl(options(enforce_range = true))] reference: u32) { - let err = self - .instance - .render_pass_set_stencil_reference(&mut self.render_pass.borrow_mut(), reference) - .err(); - self.error_handler.push_error(err); - } - - #[required(1)] - fn begin_occlusion_query(&self, #[webidl(options(enforce_range = true))] query_index: u32) { - let err = self - .instance - .render_pass_begin_occlusion_query(&mut self.render_pass.borrow_mut(), query_index) - .err(); - self.error_handler.push_error(err); - } - - #[fast] - fn end_occlusion_query(&self) { - let err = self - .instance - .render_pass_end_occlusion_query(&mut self.render_pass.borrow_mut()) - .err(); - self.error_handler.push_error(err); - } - - #[required(1)] - fn execute_bundles(&self, #[webidl] bundles: Vec>) { - let err = self - .instance - .render_pass_execute_bundles( - &mut self.render_pass.borrow_mut(), - &bundles - .into_iter() - .map(|bundle| bundle.id) - .collect::>(), - ) - .err(); - self.error_handler.push_error(err); - } - - #[fast] - fn end(&self) { - let err = self - .instance - .render_pass_end(&mut self.render_pass.borrow_mut()) - .err(); - self.error_handler.push_error(err); - } - - fn push_debug_group(&self, #[webidl] group_label: String) { - let err = self - .instance - .render_pass_push_debug_group( - &mut self.render_pass.borrow_mut(), - &group_label, - 0, // wgpu#975 - ) - .err(); - self.error_handler.push_error(err); - } - - #[fast] - fn pop_debug_group(&self) { - let err = self - .instance - .render_pass_pop_debug_group(&mut self.render_pass.borrow_mut()) - .err(); - self.error_handler.push_error(err); - } - - fn insert_debug_marker(&self, #[webidl] marker_label: String) { - let err = self - .instance - .render_pass_insert_debug_marker( - &mut self.render_pass.borrow_mut(), - &marker_label, - 0, // wgpu#975 - ) - .err(); - self.error_handler.push_error(err); - } - - fn set_bind_group<'a>( - &self, - scope: &mut v8::HandleScope<'a>, - #[webidl(options(enforce_range = true))] index: u32, - #[webidl] bind_group: Nullable>, - dynamic_offsets: v8::Local<'a, v8::Value>, - dynamic_offsets_data_start: v8::Local<'a, v8::Value>, - dynamic_offsets_data_length: v8::Local<'a, v8::Value>, - ) -> Result<(), WebIdlError> { - const PREFIX: &str = "Failed to execute 'setBindGroup' on 'GPUComputePassEncoder'"; - - let err = if let Ok(uint_32) = dynamic_offsets.try_cast::() { - let start = u64::convert( - scope, - dynamic_offsets_data_start, - Cow::Borrowed(PREFIX), - (|| Cow::Borrowed("Argument 4")).into(), - &IntOptions { - clamp: false, - enforce_range: true, - }, - )? as usize; - let len = u32::convert( - scope, - dynamic_offsets_data_length, - Cow::Borrowed(PREFIX), - (|| Cow::Borrowed("Argument 5")).into(), - &IntOptions { - clamp: false, - enforce_range: true, - }, - )? as usize; - - let ab = uint_32.buffer(scope).unwrap(); - let ptr = ab.data().unwrap(); - let ab_len = ab.byte_length() / 4; - - // SAFETY: created from an array buffer, slice is dropped at end of function call - let data = unsafe { std::slice::from_raw_parts(ptr.as_ptr() as _, ab_len) }; - - let offsets = &data[start..(start + len)]; - - self.instance - .render_pass_set_bind_group( - &mut self.render_pass.borrow_mut(), - index, - bind_group.into_option().map(|bind_group| bind_group.id), - offsets, - ) - .err() - } else { - let offsets = >>::convert( - scope, - dynamic_offsets, - Cow::Borrowed(PREFIX), - (|| Cow::Borrowed("Argument 3")).into(), - &IntOptions { - clamp: false, - enforce_range: true, - }, - )? - .unwrap_or_default(); - - self.instance - .render_pass_set_bind_group( - &mut self.render_pass.borrow_mut(), - index, - bind_group.into_option().map(|bind_group| bind_group.id), - &offsets, - ) - .err() - }; - - self.error_handler.push_error(err); - - Ok(()) - } - - fn set_pipeline(&self, #[webidl] pipeline: Ptr) { - let err = self - .instance - .render_pass_set_pipeline(&mut self.render_pass.borrow_mut(), pipeline.id) - .err(); - self.error_handler.push_error(err); - } - - #[required(2)] - fn set_index_buffer( - &self, - #[webidl] buffer: Ptr, - #[webidl] index_format: crate::render_pipeline::GPUIndexFormat, - #[webidl(default = 0, options(enforce_range = true))] offset: u64, - #[webidl(options(enforce_range = true))] size: Option, - ) { - let err = self - .instance - .render_pass_set_index_buffer( - &mut self.render_pass.borrow_mut(), - buffer.id, - index_format.into(), - offset, - size.and_then(NonZeroU64::new), - ) - .err(); - self.error_handler.push_error(err); - } - - #[required(2)] - fn set_vertex_buffer( - &self, - #[webidl(options(enforce_range = true))] slot: u32, - #[webidl] buffer: Ptr, // TODO(wgpu): support nullable buffer - #[webidl(default = 0, options(enforce_range = true))] offset: u64, - #[webidl(options(enforce_range = true))] size: Option, - ) { - let err = self - .instance - .render_pass_set_vertex_buffer( - &mut self.render_pass.borrow_mut(), - slot, - buffer.id, - offset, - size.and_then(NonZeroU64::new), - ) - .err(); - self.error_handler.push_error(err); - } - - #[required(1)] - fn draw( - &self, - #[webidl(options(enforce_range = true))] vertex_count: u32, - #[webidl(default = 1, options(enforce_range = true))] instance_count: u32, - #[webidl(default = 0, options(enforce_range = true))] first_vertex: u32, - #[webidl(default = 0, options(enforce_range = true))] first_instance: u32, - ) { - let err = self - .instance - .render_pass_draw( - &mut self.render_pass.borrow_mut(), - vertex_count, - instance_count, - first_vertex, - first_instance, - ) - .err(); - self.error_handler.push_error(err); - } - - #[required(1)] - fn draw_indexed( - &self, - #[webidl(options(enforce_range = true))] index_count: u32, - #[webidl(default = 1, options(enforce_range = true))] instance_count: u32, - #[webidl(default = 0, options(enforce_range = true))] first_index: u32, - #[webidl(default = 0, options(enforce_range = true))] base_vertex: i32, - #[webidl(default = 0, options(enforce_range = true))] first_instance: u32, - ) { - let err = self - .instance - .render_pass_draw_indexed( - &mut self.render_pass.borrow_mut(), - index_count, - instance_count, - first_index, - base_vertex, - first_instance, - ) - .err(); - self.error_handler.push_error(err); - } - - #[required(2)] - fn draw_indirect( - &self, - #[webidl] indirect_buffer: Ptr, - #[webidl(options(enforce_range = true))] indirect_offset: u64, - ) { - let err = self - .instance - .render_pass_draw_indirect( - &mut self.render_pass.borrow_mut(), - indirect_buffer.id, - indirect_offset, - ) - .err(); - self.error_handler.push_error(err); - } - - #[required(2)] - fn draw_indexed_indirect( - &self, - #[webidl] indirect_buffer: Ptr, - #[webidl(options(enforce_range = true))] indirect_offset: u64, - ) { - let err = self - .instance - .render_pass_draw_indexed_indirect( - &mut self.render_pass.borrow_mut(), - indirect_buffer.id, - indirect_offset, - ) - .err(); - self.error_handler.push_error(err); - } + #[getter] + #[string] + fn label(&self) -> String { + self.label.clone() + } + #[setter] + #[string] + fn label(&self, #[webidl] _label: String) { + // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } + + #[required(6)] + fn set_viewport( + &self, + #[webidl] x: f32, + #[webidl] y: f32, + #[webidl] width: f32, + #[webidl] height: f32, + #[webidl] min_depth: f32, + #[webidl] max_depth: f32, + ) { + let err = self + .instance + .render_pass_set_viewport( + &mut self.render_pass.borrow_mut(), + x, + y, + width, + height, + min_depth, + max_depth, + ) + .err(); + self.error_handler.push_error(err); + } + + #[required(4)] + fn set_scissor_rect( + &self, + #[webidl(options(enforce_range = true))] x: u32, + #[webidl(options(enforce_range = true))] y: u32, + #[webidl(options(enforce_range = true))] width: u32, + #[webidl(options(enforce_range = true))] height: u32, + ) { + let err = self + .instance + .render_pass_set_scissor_rect( + &mut self.render_pass.borrow_mut(), + x, + y, + width, + height, + ) + .err(); + self.error_handler.push_error(err); + } + + #[required(1)] + fn set_blend_constant(&self, #[webidl] color: GPUColor) { + let err = self + .instance + .render_pass_set_blend_constant( + &mut self.render_pass.borrow_mut(), + color.into(), + ) + .err(); + self.error_handler.push_error(err); + } + + #[required(1)] + fn set_stencil_reference( + &self, + #[webidl(options(enforce_range = true))] reference: u32, + ) { + let err = self + .instance + .render_pass_set_stencil_reference( + &mut self.render_pass.borrow_mut(), + reference, + ) + .err(); + self.error_handler.push_error(err); + } + + #[required(1)] + fn begin_occlusion_query( + &self, + #[webidl(options(enforce_range = true))] query_index: u32, + ) { + let err = self + .instance + .render_pass_begin_occlusion_query( + &mut self.render_pass.borrow_mut(), + query_index, + ) + .err(); + self.error_handler.push_error(err); + } + + #[fast] + fn end_occlusion_query(&self) { + let err = self + .instance + .render_pass_end_occlusion_query(&mut self.render_pass.borrow_mut()) + .err(); + self.error_handler.push_error(err); + } + + #[required(1)] + fn execute_bundles(&self, #[webidl] bundles: Vec>) { + let err = self + .instance + .render_pass_execute_bundles( + &mut self.render_pass.borrow_mut(), + &bundles + .into_iter() + .map(|bundle| bundle.id) + .collect::>(), + ) + .err(); + self.error_handler.push_error(err); + } + + #[fast] + fn end(&self) { + let err = self + .instance + .render_pass_end(&mut self.render_pass.borrow_mut()) + .err(); + self.error_handler.push_error(err); + } + + fn push_debug_group(&self, #[webidl] group_label: String) { + let err = self + .instance + .render_pass_push_debug_group( + &mut self.render_pass.borrow_mut(), + &group_label, + 0, // wgpu#975 + ) + .err(); + self.error_handler.push_error(err); + } + + #[fast] + fn pop_debug_group(&self) { + let err = self + .instance + .render_pass_pop_debug_group(&mut self.render_pass.borrow_mut()) + .err(); + self.error_handler.push_error(err); + } + + fn insert_debug_marker(&self, #[webidl] marker_label: String) { + let err = self + .instance + .render_pass_insert_debug_marker( + &mut self.render_pass.borrow_mut(), + &marker_label, + 0, // wgpu#975 + ) + .err(); + self.error_handler.push_error(err); + } + + fn set_bind_group<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + #[webidl(options(enforce_range = true))] index: u32, + #[webidl] bind_group: Nullable>, + dynamic_offsets: v8::Local<'a, v8::Value>, + dynamic_offsets_data_start: v8::Local<'a, v8::Value>, + dynamic_offsets_data_length: v8::Local<'a, v8::Value>, + ) -> Result<(), WebIdlError> { + const PREFIX: &str = + "Failed to execute 'setBindGroup' on 'GPUComputePassEncoder'"; + + let err = if let Ok(uint_32) = dynamic_offsets.try_cast::() + { + let start = u64::convert( + scope, + dynamic_offsets_data_start, + Cow::Borrowed(PREFIX), + (|| Cow::Borrowed("Argument 4")).into(), + &IntOptions { + clamp: false, + enforce_range: true, + }, + )? as usize; + let len = u32::convert( + scope, + dynamic_offsets_data_length, + Cow::Borrowed(PREFIX), + (|| Cow::Borrowed("Argument 5")).into(), + &IntOptions { + clamp: false, + enforce_range: true, + }, + )? as usize; + + let ab = uint_32.buffer(scope).unwrap(); + let ptr = ab.data().unwrap(); + let ab_len = ab.byte_length() / 4; + + // SAFETY: created from an array buffer, slice is dropped at end of function call + let data = + unsafe { std::slice::from_raw_parts(ptr.as_ptr() as _, ab_len) }; + + let offsets = &data[start..(start + len)]; + + self + .instance + .render_pass_set_bind_group( + &mut self.render_pass.borrow_mut(), + index, + bind_group.into_option().map(|bind_group| bind_group.id), + offsets, + ) + .err() + } else { + let offsets = >>::convert( + scope, + dynamic_offsets, + Cow::Borrowed(PREFIX), + (|| Cow::Borrowed("Argument 3")).into(), + &IntOptions { + clamp: false, + enforce_range: true, + }, + )? + .unwrap_or_default(); + + self + .instance + .render_pass_set_bind_group( + &mut self.render_pass.borrow_mut(), + index, + bind_group.into_option().map(|bind_group| bind_group.id), + &offsets, + ) + .err() + }; + + self.error_handler.push_error(err); + + Ok(()) + } + + fn set_pipeline( + &self, + #[webidl] pipeline: Ptr, + ) { + let err = self + .instance + .render_pass_set_pipeline(&mut self.render_pass.borrow_mut(), pipeline.id) + .err(); + self.error_handler.push_error(err); + } + + #[required(2)] + fn set_index_buffer( + &self, + #[webidl] buffer: Ptr, + #[webidl] index_format: crate::render_pipeline::GPUIndexFormat, + #[webidl(default = 0, options(enforce_range = true))] offset: u64, + #[webidl(options(enforce_range = true))] size: Option, + ) { + let err = self + .instance + .render_pass_set_index_buffer( + &mut self.render_pass.borrow_mut(), + buffer.id, + index_format.into(), + offset, + size.and_then(NonZeroU64::new), + ) + .err(); + self.error_handler.push_error(err); + } + + #[required(2)] + fn set_vertex_buffer( + &self, + #[webidl(options(enforce_range = true))] slot: u32, + #[webidl] buffer: Ptr, // TODO(wgpu): support nullable buffer + #[webidl(default = 0, options(enforce_range = true))] offset: u64, + #[webidl(options(enforce_range = true))] size: Option, + ) { + let err = self + .instance + .render_pass_set_vertex_buffer( + &mut self.render_pass.borrow_mut(), + slot, + buffer.id, + offset, + size.and_then(NonZeroU64::new), + ) + .err(); + self.error_handler.push_error(err); + } + + #[required(1)] + fn draw( + &self, + #[webidl(options(enforce_range = true))] vertex_count: u32, + #[webidl(default = 1, options(enforce_range = true))] instance_count: u32, + #[webidl(default = 0, options(enforce_range = true))] first_vertex: u32, + #[webidl(default = 0, options(enforce_range = true))] first_instance: u32, + ) { + let err = self + .instance + .render_pass_draw( + &mut self.render_pass.borrow_mut(), + vertex_count, + instance_count, + first_vertex, + first_instance, + ) + .err(); + self.error_handler.push_error(err); + } + + #[required(1)] + fn draw_indexed( + &self, + #[webidl(options(enforce_range = true))] index_count: u32, + #[webidl(default = 1, options(enforce_range = true))] instance_count: u32, + #[webidl(default = 0, options(enforce_range = true))] first_index: u32, + #[webidl(default = 0, options(enforce_range = true))] base_vertex: i32, + #[webidl(default = 0, options(enforce_range = true))] first_instance: u32, + ) { + let err = self + .instance + .render_pass_draw_indexed( + &mut self.render_pass.borrow_mut(), + index_count, + instance_count, + first_index, + base_vertex, + first_instance, + ) + .err(); + self.error_handler.push_error(err); + } + + #[required(2)] + fn draw_indirect( + &self, + #[webidl] indirect_buffer: Ptr, + #[webidl(options(enforce_range = true))] indirect_offset: u64, + ) { + let err = self + .instance + .render_pass_draw_indirect( + &mut self.render_pass.borrow_mut(), + indirect_buffer.id, + indirect_offset, + ) + .err(); + self.error_handler.push_error(err); + } + + #[required(2)] + fn draw_indexed_indirect( + &self, + #[webidl] indirect_buffer: Ptr, + #[webidl(options(enforce_range = true))] indirect_offset: u64, + ) { + let err = self + .instance + .render_pass_draw_indexed_indirect( + &mut self.render_pass.borrow_mut(), + indirect_buffer.id, + indirect_offset, + ) + .err(); + self.error_handler.push_error(err); + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPURenderPassDescriptor { - #[webidl(default = String::new())] - pub label: String, - - pub color_attachments: Vec>, - pub depth_stencil_attachment: Option, - pub occlusion_query_set: Option>, - pub timestamp_writes: Option, - /*#[webidl(default = 50000000)] - #[options(enforce_range = true)] - pub max_draw_count: u64,*/ + #[webidl(default = String::new())] + pub label: String, + + pub color_attachments: Vec>, + pub depth_stencil_attachment: Option, + pub occlusion_query_set: Option>, + pub timestamp_writes: Option, + /*#[webidl(default = 50000000)] + #[options(enforce_range = true)] + pub max_draw_count: u64,*/ } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPURenderPassColorAttachment { - pub view: Ptr, - #[options(enforce_range = true)] - pub depth_slice: Option, - pub resolve_target: Option>, - pub clear_value: Option, - pub load_op: GPULoadOp, - pub store_op: GPUStoreOp, + pub view: Ptr, + #[options(enforce_range = true)] + pub depth_slice: Option, + pub resolve_target: Option>, + pub clear_value: Option, + pub load_op: GPULoadOp, + pub store_op: GPUStoreOp, } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPULoadOp { - Load, - Clear, + Load, + Clear, } impl GPULoadOp { - pub fn with_default_value(self, val: Option) -> wgpu_core::command::LoadOp { - match self { - GPULoadOp::Load => wgpu_core::command::LoadOp::Load, - GPULoadOp::Clear => wgpu_core::command::LoadOp::Clear(val.unwrap_or_default()), - } + pub fn with_default_value( + self, + val: Option, + ) -> wgpu_core::command::LoadOp { + match self { + GPULoadOp::Load => wgpu_core::command::LoadOp::Load, + GPULoadOp::Clear => { + wgpu_core::command::LoadOp::Clear(val.unwrap_or_default()) + } } + } - pub fn with_value(self, val: V) -> wgpu_core::command::LoadOp { - match self { - GPULoadOp::Load => wgpu_core::command::LoadOp::Load, - GPULoadOp::Clear => wgpu_core::command::LoadOp::Clear(val), - } + pub fn with_value(self, val: V) -> wgpu_core::command::LoadOp { + match self { + GPULoadOp::Load => wgpu_core::command::LoadOp::Load, + GPULoadOp::Clear => wgpu_core::command::LoadOp::Clear(val), } + } } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUStoreOp { - Store, - Discard, + Store, + Discard, } impl From for wgpu_core::command::StoreOp { - fn from(value: GPUStoreOp) -> Self { - match value { - GPUStoreOp::Store => Self::Store, - GPUStoreOp::Discard => Self::Discard, - } + fn from(value: GPUStoreOp) -> Self { + match value { + GPUStoreOp::Store => Self::Store, + GPUStoreOp::Discard => Self::Discard, } + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPURenderPassDepthStencilAttachment { - pub view: Ptr, - pub depth_clear_value: Option, - pub depth_load_op: Option, - pub depth_store_op: Option, - #[webidl(default = false)] - pub depth_read_only: bool, - #[webidl(default = 0)] - #[options(enforce_range = true)] - pub stencil_clear_value: u32, - pub stencil_load_op: Option, - pub stencil_store_op: Option, - #[webidl(default = false)] - pub stencil_read_only: bool, + pub view: Ptr, + pub depth_clear_value: Option, + pub depth_load_op: Option, + pub depth_store_op: Option, + #[webidl(default = false)] + pub depth_read_only: bool, + #[webidl(default = 0)] + #[options(enforce_range = true)] + pub stencil_clear_value: u32, + pub stencil_load_op: Option, + pub stencil_store_op: Option, + #[webidl(default = false)] + pub stencil_read_only: bool, } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPURenderPassTimestampWrites { - pub query_set: Ptr, - #[options(enforce_range = true)] - pub beginning_of_pass_write_index: Option, - #[options(enforce_range = true)] - pub end_of_pass_write_index: Option, + pub query_set: Ptr, + #[options(enforce_range = true)] + pub beginning_of_pass_write_index: Option, + #[options(enforce_range = true)] + pub end_of_pass_write_index: Option, } diff --git a/deno_webgpu/render_pipeline.rs b/deno_webgpu/render_pipeline.rs index 1088b95ff47..5b85efb9dfb 100644 --- a/deno_webgpu/render_pipeline.rs +++ b/deno_webgpu/render_pipeline.rs @@ -16,535 +16,535 @@ use crate::webidl::GPUPipelineLayoutOrGPUAutoLayoutMode; use crate::Instance; pub struct GPURenderPipeline { - pub instance: Instance, - pub error_handler: super::error::ErrorHandler, + pub instance: Instance, + pub error_handler: super::error::ErrorHandler, - pub id: wgpu_core::id::RenderPipelineId, - pub label: String, + pub id: wgpu_core::id::RenderPipelineId, + pub label: String, } impl Drop for GPURenderPipeline { - fn drop(&mut self) { - self.instance.render_pipeline_drop(self.id); - } + fn drop(&mut self) { + self.instance.render_pipeline_drop(self.id); + } } impl WebIdlInterfaceConverter for GPURenderPipeline { - const NAME: &'static str = "GPURenderPipeline"; + const NAME: &'static str = "GPURenderPipeline"; } impl GarbageCollected for GPURenderPipeline {} #[op2] impl GPURenderPipeline { - #[getter] - #[string] - fn label(&self) -> String { - self.label.clone() - } - #[setter] - #[string] - fn label(&self, #[webidl] _label: String) { - // TODO(@crowlKats): no-op, needs wpgu to implement changing the label - } - - #[cppgc] - fn get_bind_group_layout(&self, #[webidl] index: u32) -> GPUBindGroupLayout { - let (id, err) = self - .instance - .render_pipeline_get_bind_group_layout(self.id, index, None); - - self.error_handler.push_error(err); - - // TODO(wgpu): needs to add a way to retrieve the label - GPUBindGroupLayout { - instance: self.instance.clone(), - id, - label: "".to_string(), - } + #[getter] + #[string] + fn label(&self) -> String { + self.label.clone() + } + #[setter] + #[string] + fn label(&self, #[webidl] _label: String) { + // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } + + #[cppgc] + fn get_bind_group_layout(&self, #[webidl] index: u32) -> GPUBindGroupLayout { + let (id, err) = self + .instance + .render_pipeline_get_bind_group_layout(self.id, index, None); + + self.error_handler.push_error(err); + + // TODO(wgpu): needs to add a way to retrieve the label + GPUBindGroupLayout { + instance: self.instance.clone(), + id, + label: "".to_string(), } + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPURenderPipelineDescriptor { - #[webidl(default = String::new())] - pub label: String, + #[webidl(default = String::new())] + pub label: String, - pub layout: GPUPipelineLayoutOrGPUAutoLayoutMode, - pub vertex: GPUVertexState, - pub primitive: GPUPrimitiveState, - pub depth_stencil: Option, - pub multisample: GPUMultisampleState, - pub fragment: Option, + pub layout: GPUPipelineLayoutOrGPUAutoLayoutMode, + pub vertex: GPUVertexState, + pub primitive: GPUPrimitiveState, + pub depth_stencil: Option, + pub multisample: GPUMultisampleState, + pub fragment: Option, } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUMultisampleState { - #[webidl(default = 1)] - #[options(enforce_range = true)] - pub count: u32, - #[webidl(default = 0xFFFFFFFF)] - #[options(enforce_range = true)] - pub mask: u32, - #[webidl(default = false)] - pub alpha_to_coverage_enabled: bool, + #[webidl(default = 1)] + #[options(enforce_range = true)] + pub count: u32, + #[webidl(default = 0xFFFFFFFF)] + #[options(enforce_range = true)] + pub mask: u32, + #[webidl(default = false)] + pub alpha_to_coverage_enabled: bool, } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUDepthStencilState { - pub format: GPUTextureFormat, - pub depth_write_enabled: Option, - pub depth_compare: Option, - pub stencil_front: GPUStencilFaceState, - pub stencil_back: GPUStencilFaceState, - #[webidl(default = 0xFFFFFFFF)] - #[options(enforce_range = true)] - pub stencil_read_mask: u32, - #[webidl(default = 0xFFFFFFFF)] - #[options(enforce_range = true)] - pub stencil_write_mask: u32, - #[webidl(default = 0)] - #[options(enforce_range = true)] - pub depth_bias: i32, - #[webidl(default = 0.0)] - pub depth_bias_slope_scale: f32, - #[webidl(default = 0.0)] - pub depth_bias_clamp: f32, + pub format: GPUTextureFormat, + pub depth_write_enabled: Option, + pub depth_compare: Option, + pub stencil_front: GPUStencilFaceState, + pub stencil_back: GPUStencilFaceState, + #[webidl(default = 0xFFFFFFFF)] + #[options(enforce_range = true)] + pub stencil_read_mask: u32, + #[webidl(default = 0xFFFFFFFF)] + #[options(enforce_range = true)] + pub stencil_write_mask: u32, + #[webidl(default = 0)] + #[options(enforce_range = true)] + pub depth_bias: i32, + #[webidl(default = 0.0)] + pub depth_bias_slope_scale: f32, + #[webidl(default = 0.0)] + pub depth_bias_clamp: f32, } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUStencilFaceState { - #[webidl(default = GPUCompareFunction::Always)] - pub compare: GPUCompareFunction, - #[webidl(default = GPUStencilOperation::Keep)] - pub fail_op: GPUStencilOperation, - #[webidl(default = GPUStencilOperation::Keep)] - pub depth_fail_op: GPUStencilOperation, - #[webidl(default = GPUStencilOperation::Keep)] - pub pass_op: GPUStencilOperation, + #[webidl(default = GPUCompareFunction::Always)] + pub compare: GPUCompareFunction, + #[webidl(default = GPUStencilOperation::Keep)] + pub fail_op: GPUStencilOperation, + #[webidl(default = GPUStencilOperation::Keep)] + pub depth_fail_op: GPUStencilOperation, + #[webidl(default = GPUStencilOperation::Keep)] + pub pass_op: GPUStencilOperation, } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUStencilOperation { - Keep, - Zero, - Replace, - Invert, - IncrementClamp, - DecrementClamp, - IncrementWrap, - DecrementWrap, + Keep, + Zero, + Replace, + Invert, + IncrementClamp, + DecrementClamp, + IncrementWrap, + DecrementWrap, } impl From for wgpu_types::StencilOperation { - fn from(value: GPUStencilOperation) -> Self { - match value { - GPUStencilOperation::Keep => Self::Keep, - GPUStencilOperation::Zero => Self::Zero, - GPUStencilOperation::Replace => Self::Replace, - GPUStencilOperation::Invert => Self::Invert, - GPUStencilOperation::IncrementClamp => Self::IncrementClamp, - GPUStencilOperation::DecrementClamp => Self::DecrementClamp, - GPUStencilOperation::IncrementWrap => Self::IncrementWrap, - GPUStencilOperation::DecrementWrap => Self::DecrementWrap, - } + fn from(value: GPUStencilOperation) -> Self { + match value { + GPUStencilOperation::Keep => Self::Keep, + GPUStencilOperation::Zero => Self::Zero, + GPUStencilOperation::Replace => Self::Replace, + GPUStencilOperation::Invert => Self::Invert, + GPUStencilOperation::IncrementClamp => Self::IncrementClamp, + GPUStencilOperation::DecrementClamp => Self::DecrementClamp, + GPUStencilOperation::IncrementWrap => Self::IncrementWrap, + GPUStencilOperation::DecrementWrap => Self::DecrementWrap, } + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUVertexState { - pub module: Ptr, - pub entry_point: Option, - #[webidl(default = Default::default())] - pub constants: IndexMap, - #[webidl(default = vec![])] - pub buffers: Vec>, + pub module: Ptr, + pub entry_point: Option, + #[webidl(default = Default::default())] + pub constants: IndexMap, + #[webidl(default = vec![])] + pub buffers: Vec>, } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUFragmentState { - pub module: Ptr, - pub entry_point: Option, - #[webidl(default = Default::default())] - pub constants: IndexMap, - pub targets: Vec>, + pub module: Ptr, + pub entry_point: Option, + #[webidl(default = Default::default())] + pub constants: IndexMap, + pub targets: Vec>, } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUColorTargetState { - pub format: GPUTextureFormat, - pub blend: Option, - #[webidl(default = 0xF)] - #[options(enforce_range = true)] - pub write_mask: u32, + pub format: GPUTextureFormat, + pub blend: Option, + #[webidl(default = 0xF)] + #[options(enforce_range = true)] + pub write_mask: u32, } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUBlendState { - pub color: GPUBlendComponent, - pub alpha: GPUBlendComponent, + pub color: GPUBlendComponent, + pub alpha: GPUBlendComponent, } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUBlendComponent { - #[webidl(default = GPUBlendOperation::Add)] - pub operation: GPUBlendOperation, - #[webidl(default = GPUBlendFactor::One)] - pub src_factor: GPUBlendFactor, - #[webidl(default = GPUBlendFactor::Zero)] - pub dst_factor: GPUBlendFactor, + #[webidl(default = GPUBlendOperation::Add)] + pub operation: GPUBlendOperation, + #[webidl(default = GPUBlendFactor::One)] + pub src_factor: GPUBlendFactor, + #[webidl(default = GPUBlendFactor::Zero)] + pub dst_factor: GPUBlendFactor, } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUBlendOperation { - Add, - Subtract, - ReverseSubtract, - Min, - Max, + Add, + Subtract, + ReverseSubtract, + Min, + Max, } impl From for wgpu_types::BlendOperation { - fn from(value: GPUBlendOperation) -> Self { - match value { - GPUBlendOperation::Add => Self::Add, - GPUBlendOperation::Subtract => Self::Subtract, - GPUBlendOperation::ReverseSubtract => Self::ReverseSubtract, - GPUBlendOperation::Min => Self::Min, - GPUBlendOperation::Max => Self::Max, - } + fn from(value: GPUBlendOperation) -> Self { + match value { + GPUBlendOperation::Add => Self::Add, + GPUBlendOperation::Subtract => Self::Subtract, + GPUBlendOperation::ReverseSubtract => Self::ReverseSubtract, + GPUBlendOperation::Min => Self::Min, + GPUBlendOperation::Max => Self::Max, } + } } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUBlendFactor { - #[webidl(rename = "zero")] - Zero, - #[webidl(rename = "one")] - One, - #[webidl(rename = "src")] - Src, - #[webidl(rename = "one-minus-src")] - OneMinusSrc, - #[webidl(rename = "src-alpha")] - SrcAlpha, - #[webidl(rename = "one-minus-src-alpha")] - OneMinusSrcAlpha, - #[webidl(rename = "dst")] - Dst, - #[webidl(rename = "one-minus-dst")] - OneMinusDst, - #[webidl(rename = "dst-alpha")] - DstAlpha, - #[webidl(rename = "one-minus-dst-alpha")] - OneMinusDstAlpha, - #[webidl(rename = "src-alpha-saturated")] - SrcAlphaSaturated, - #[webidl(rename = "constant")] - Constant, - #[webidl(rename = "one-minus-constant")] - OneMinusConstant, - #[webidl(rename = "src1")] - Src1, - #[webidl(rename = "one-minus-src1")] - OneMinusSrc1, - #[webidl(rename = "src1-alpha")] - Src1Alpha, - #[webidl(rename = "one-minus-src1-alpha")] - OneMinusSrc1Alpha, + #[webidl(rename = "zero")] + Zero, + #[webidl(rename = "one")] + One, + #[webidl(rename = "src")] + Src, + #[webidl(rename = "one-minus-src")] + OneMinusSrc, + #[webidl(rename = "src-alpha")] + SrcAlpha, + #[webidl(rename = "one-minus-src-alpha")] + OneMinusSrcAlpha, + #[webidl(rename = "dst")] + Dst, + #[webidl(rename = "one-minus-dst")] + OneMinusDst, + #[webidl(rename = "dst-alpha")] + DstAlpha, + #[webidl(rename = "one-minus-dst-alpha")] + OneMinusDstAlpha, + #[webidl(rename = "src-alpha-saturated")] + SrcAlphaSaturated, + #[webidl(rename = "constant")] + Constant, + #[webidl(rename = "one-minus-constant")] + OneMinusConstant, + #[webidl(rename = "src1")] + Src1, + #[webidl(rename = "one-minus-src1")] + OneMinusSrc1, + #[webidl(rename = "src1-alpha")] + Src1Alpha, + #[webidl(rename = "one-minus-src1-alpha")] + OneMinusSrc1Alpha, } impl From for wgpu_types::BlendFactor { - fn from(value: GPUBlendFactor) -> Self { - match value { - GPUBlendFactor::Zero => Self::Zero, - GPUBlendFactor::One => Self::One, - GPUBlendFactor::Src => Self::Src, - GPUBlendFactor::OneMinusSrc => Self::OneMinusSrc, - GPUBlendFactor::SrcAlpha => Self::SrcAlpha, - GPUBlendFactor::OneMinusSrcAlpha => Self::OneMinusSrcAlpha, - GPUBlendFactor::Dst => Self::Dst, - GPUBlendFactor::OneMinusDst => Self::OneMinusDst, - GPUBlendFactor::DstAlpha => Self::DstAlpha, - GPUBlendFactor::OneMinusDstAlpha => Self::OneMinusDstAlpha, - GPUBlendFactor::SrcAlphaSaturated => Self::SrcAlphaSaturated, - GPUBlendFactor::Constant => Self::Constant, - GPUBlendFactor::OneMinusConstant => Self::OneMinusConstant, - GPUBlendFactor::Src1 => Self::Src1, - GPUBlendFactor::OneMinusSrc1 => Self::OneMinusSrc1, - GPUBlendFactor::Src1Alpha => Self::Src1Alpha, - GPUBlendFactor::OneMinusSrc1Alpha => Self::OneMinusSrc1Alpha, - } + fn from(value: GPUBlendFactor) -> Self { + match value { + GPUBlendFactor::Zero => Self::Zero, + GPUBlendFactor::One => Self::One, + GPUBlendFactor::Src => Self::Src, + GPUBlendFactor::OneMinusSrc => Self::OneMinusSrc, + GPUBlendFactor::SrcAlpha => Self::SrcAlpha, + GPUBlendFactor::OneMinusSrcAlpha => Self::OneMinusSrcAlpha, + GPUBlendFactor::Dst => Self::Dst, + GPUBlendFactor::OneMinusDst => Self::OneMinusDst, + GPUBlendFactor::DstAlpha => Self::DstAlpha, + GPUBlendFactor::OneMinusDstAlpha => Self::OneMinusDstAlpha, + GPUBlendFactor::SrcAlphaSaturated => Self::SrcAlphaSaturated, + GPUBlendFactor::Constant => Self::Constant, + GPUBlendFactor::OneMinusConstant => Self::OneMinusConstant, + GPUBlendFactor::Src1 => Self::Src1, + GPUBlendFactor::OneMinusSrc1 => Self::OneMinusSrc1, + GPUBlendFactor::Src1Alpha => Self::Src1Alpha, + GPUBlendFactor::OneMinusSrc1Alpha => Self::OneMinusSrc1Alpha, } + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUPrimitiveState { - #[webidl(default = GPUPrimitiveTopology::TriangleList)] - pub topology: GPUPrimitiveTopology, - pub strip_index_format: Option, - #[webidl(default = GPUFrontFace::Ccw)] - pub front_face: GPUFrontFace, - #[webidl(default = GPUCullMode::None)] - pub cull_mode: GPUCullMode, - #[webidl(default = false)] - pub unclipped_depth: bool, + #[webidl(default = GPUPrimitiveTopology::TriangleList)] + pub topology: GPUPrimitiveTopology, + pub strip_index_format: Option, + #[webidl(default = GPUFrontFace::Ccw)] + pub front_face: GPUFrontFace, + #[webidl(default = GPUCullMode::None)] + pub cull_mode: GPUCullMode, + #[webidl(default = false)] + pub unclipped_depth: bool, } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUPrimitiveTopology { - PointList, - LineList, - LineStrip, - TriangleList, - TriangleStrip, + PointList, + LineList, + LineStrip, + TriangleList, + TriangleStrip, } impl From for wgpu_types::PrimitiveTopology { - fn from(value: GPUPrimitiveTopology) -> Self { - match value { - GPUPrimitiveTopology::PointList => Self::PointList, - GPUPrimitiveTopology::LineList => Self::LineList, - GPUPrimitiveTopology::LineStrip => Self::LineStrip, - GPUPrimitiveTopology::TriangleList => Self::TriangleList, - GPUPrimitiveTopology::TriangleStrip => Self::TriangleStrip, - } + fn from(value: GPUPrimitiveTopology) -> Self { + match value { + GPUPrimitiveTopology::PointList => Self::PointList, + GPUPrimitiveTopology::LineList => Self::LineList, + GPUPrimitiveTopology::LineStrip => Self::LineStrip, + GPUPrimitiveTopology::TriangleList => Self::TriangleList, + GPUPrimitiveTopology::TriangleStrip => Self::TriangleStrip, } + } } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUIndexFormat { - #[webidl(rename = "uint16")] - Uint16, - #[webidl(rename = "uint32")] - Uint32, + #[webidl(rename = "uint16")] + Uint16, + #[webidl(rename = "uint32")] + Uint32, } impl From for wgpu_types::IndexFormat { - fn from(value: GPUIndexFormat) -> Self { - match value { - GPUIndexFormat::Uint16 => Self::Uint16, - GPUIndexFormat::Uint32 => Self::Uint32, - } + fn from(value: GPUIndexFormat) -> Self { + match value { + GPUIndexFormat::Uint16 => Self::Uint16, + GPUIndexFormat::Uint32 => Self::Uint32, } + } } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUFrontFace { - Ccw, - Cw, + Ccw, + Cw, } impl From for wgpu_types::FrontFace { - fn from(value: GPUFrontFace) -> Self { - match value { - GPUFrontFace::Ccw => Self::Ccw, - GPUFrontFace::Cw => Self::Cw, - } + fn from(value: GPUFrontFace) -> Self { + match value { + GPUFrontFace::Ccw => Self::Ccw, + GPUFrontFace::Cw => Self::Cw, } + } } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUCullMode { - None, - Front, - Back, + None, + Front, + Back, } impl From for Option { - fn from(value: GPUCullMode) -> Self { - match value { - GPUCullMode::None => None, - GPUCullMode::Front => Some(wgpu_types::Face::Front), - GPUCullMode::Back => Some(wgpu_types::Face::Back), - } + fn from(value: GPUCullMode) -> Self { + match value { + GPUCullMode::None => None, + GPUCullMode::Front => Some(wgpu_types::Face::Front), + GPUCullMode::Back => Some(wgpu_types::Face::Back), } + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUVertexBufferLayout { - #[options(enforce_range = true)] - pub array_stride: u64, - #[webidl(default = GPUVertexStepMode::Vertex)] - pub step_mode: GPUVertexStepMode, - pub attributes: Vec, + #[options(enforce_range = true)] + pub array_stride: u64, + #[webidl(default = GPUVertexStepMode::Vertex)] + pub step_mode: GPUVertexStepMode, + pub attributes: Vec, } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUVertexStepMode { - Vertex, - Instance, + Vertex, + Instance, } impl From for wgpu_types::VertexStepMode { - fn from(value: GPUVertexStepMode) -> Self { - match value { - GPUVertexStepMode::Vertex => Self::Vertex, - GPUVertexStepMode::Instance => Self::Instance, - } + fn from(value: GPUVertexStepMode) -> Self { + match value { + GPUVertexStepMode::Vertex => Self::Vertex, + GPUVertexStepMode::Instance => Self::Instance, } + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUVertexAttribute { - pub format: GPUVertexFormat, - #[options(enforce_range = true)] - pub offset: u64, - #[options(enforce_range = true)] - pub shader_location: u32, + pub format: GPUVertexFormat, + #[options(enforce_range = true)] + pub offset: u64, + #[options(enforce_range = true)] + pub shader_location: u32, } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUVertexFormat { - #[webidl(rename = "uint8")] - Uint8, - #[webidl(rename = "uint8x2")] - Uint8x2, - #[webidl(rename = "uint8x4")] - Uint8x4, - #[webidl(rename = "sint8")] - Sint8, - #[webidl(rename = "sint8x2")] - Sint8x2, - #[webidl(rename = "sint8x4")] - Sint8x4, - #[webidl(rename = "unorm8")] - Unorm8, - #[webidl(rename = "unorm8x2")] - Unorm8x2, - #[webidl(rename = "unorm8x4")] - Unorm8x4, - #[webidl(rename = "snorm8")] - Snorm8, - #[webidl(rename = "snorm8x2")] - Snorm8x2, - #[webidl(rename = "snorm8x4")] - Snorm8x4, - #[webidl(rename = "uint16")] - Uint16, - #[webidl(rename = "uint16x2")] - Uint16x2, - #[webidl(rename = "uint16x4")] - Uint16x4, - #[webidl(rename = "sint16")] - Sint16, - #[webidl(rename = "sint16x2")] - Sint16x2, - #[webidl(rename = "sint16x4")] - Sint16x4, - #[webidl(rename = "unorm16")] - Unorm16, - #[webidl(rename = "unorm16x2")] - Unorm16x2, - #[webidl(rename = "unorm16x4")] - Unorm16x4, - #[webidl(rename = "snorm16")] - Snorm16, - #[webidl(rename = "snorm16x2")] - Snorm16x2, - #[webidl(rename = "snorm16x4")] - Snorm16x4, - #[webidl(rename = "float16")] - Float16, - #[webidl(rename = "float16x2")] - Float16x2, - #[webidl(rename = "float16x4")] - Float16x4, - #[webidl(rename = "float32")] - Float32, - #[webidl(rename = "float32x2")] - Float32x2, - #[webidl(rename = "float32x3")] - Float32x3, - #[webidl(rename = "float32x4")] - Float32x4, - #[webidl(rename = "uint32")] - Uint32, - #[webidl(rename = "uint32x2")] - Uint32x2, - #[webidl(rename = "uint32x3")] - Uint32x3, - #[webidl(rename = "uint32x4")] - Uint32x4, - #[webidl(rename = "sint32")] - Sint32, - #[webidl(rename = "sint32x2")] - Sint32x2, - #[webidl(rename = "sint32x3")] - Sint32x3, - #[webidl(rename = "sint32x4")] - Sint32x4, - #[webidl(rename = "unorm10-10-10-2")] - Unorm1010102, - #[webidl(rename = "unorm8x4-bgra")] - Unorm8x4Bgra, + #[webidl(rename = "uint8")] + Uint8, + #[webidl(rename = "uint8x2")] + Uint8x2, + #[webidl(rename = "uint8x4")] + Uint8x4, + #[webidl(rename = "sint8")] + Sint8, + #[webidl(rename = "sint8x2")] + Sint8x2, + #[webidl(rename = "sint8x4")] + Sint8x4, + #[webidl(rename = "unorm8")] + Unorm8, + #[webidl(rename = "unorm8x2")] + Unorm8x2, + #[webidl(rename = "unorm8x4")] + Unorm8x4, + #[webidl(rename = "snorm8")] + Snorm8, + #[webidl(rename = "snorm8x2")] + Snorm8x2, + #[webidl(rename = "snorm8x4")] + Snorm8x4, + #[webidl(rename = "uint16")] + Uint16, + #[webidl(rename = "uint16x2")] + Uint16x2, + #[webidl(rename = "uint16x4")] + Uint16x4, + #[webidl(rename = "sint16")] + Sint16, + #[webidl(rename = "sint16x2")] + Sint16x2, + #[webidl(rename = "sint16x4")] + Sint16x4, + #[webidl(rename = "unorm16")] + Unorm16, + #[webidl(rename = "unorm16x2")] + Unorm16x2, + #[webidl(rename = "unorm16x4")] + Unorm16x4, + #[webidl(rename = "snorm16")] + Snorm16, + #[webidl(rename = "snorm16x2")] + Snorm16x2, + #[webidl(rename = "snorm16x4")] + Snorm16x4, + #[webidl(rename = "float16")] + Float16, + #[webidl(rename = "float16x2")] + Float16x2, + #[webidl(rename = "float16x4")] + Float16x4, + #[webidl(rename = "float32")] + Float32, + #[webidl(rename = "float32x2")] + Float32x2, + #[webidl(rename = "float32x3")] + Float32x3, + #[webidl(rename = "float32x4")] + Float32x4, + #[webidl(rename = "uint32")] + Uint32, + #[webidl(rename = "uint32x2")] + Uint32x2, + #[webidl(rename = "uint32x3")] + Uint32x3, + #[webidl(rename = "uint32x4")] + Uint32x4, + #[webidl(rename = "sint32")] + Sint32, + #[webidl(rename = "sint32x2")] + Sint32x2, + #[webidl(rename = "sint32x3")] + Sint32x3, + #[webidl(rename = "sint32x4")] + Sint32x4, + #[webidl(rename = "unorm10-10-10-2")] + Unorm1010102, + #[webidl(rename = "unorm8x4-bgra")] + Unorm8x4Bgra, } impl From for wgpu_types::VertexFormat { - fn from(value: GPUVertexFormat) -> Self { - match value { - GPUVertexFormat::Uint8 => Self::Uint8, - GPUVertexFormat::Uint8x2 => Self::Uint8x2, - GPUVertexFormat::Uint8x4 => Self::Uint8x4, - GPUVertexFormat::Sint8 => Self::Sint8, - GPUVertexFormat::Sint8x2 => Self::Sint8x2, - GPUVertexFormat::Sint8x4 => Self::Sint8x4, - GPUVertexFormat::Unorm8 => Self::Unorm8, - GPUVertexFormat::Unorm8x2 => Self::Unorm8x2, - GPUVertexFormat::Unorm8x4 => Self::Unorm8x4, - GPUVertexFormat::Snorm8 => Self::Snorm8, - GPUVertexFormat::Snorm8x2 => Self::Snorm8x2, - GPUVertexFormat::Snorm8x4 => Self::Snorm8x4, - GPUVertexFormat::Uint16 => Self::Uint16, - GPUVertexFormat::Uint16x2 => Self::Uint16x2, - GPUVertexFormat::Uint16x4 => Self::Uint16x4, - GPUVertexFormat::Sint16 => Self::Sint16, - GPUVertexFormat::Sint16x2 => Self::Sint16x2, - GPUVertexFormat::Sint16x4 => Self::Sint16x4, - GPUVertexFormat::Unorm16 => Self::Unorm16, - GPUVertexFormat::Unorm16x2 => Self::Unorm16x2, - GPUVertexFormat::Unorm16x4 => Self::Unorm16x4, - GPUVertexFormat::Snorm16 => Self::Snorm16, - GPUVertexFormat::Snorm16x2 => Self::Snorm16x2, - GPUVertexFormat::Snorm16x4 => Self::Snorm16x4, - GPUVertexFormat::Float16 => Self::Float16, - GPUVertexFormat::Float16x2 => Self::Float16x2, - GPUVertexFormat::Float16x4 => Self::Float16x4, - GPUVertexFormat::Float32 => Self::Float32, - GPUVertexFormat::Float32x2 => Self::Float32x2, - GPUVertexFormat::Float32x3 => Self::Float32x3, - GPUVertexFormat::Float32x4 => Self::Float32x4, - GPUVertexFormat::Uint32 => Self::Uint32, - GPUVertexFormat::Uint32x2 => Self::Uint32x2, - GPUVertexFormat::Uint32x3 => Self::Uint32x3, - GPUVertexFormat::Uint32x4 => Self::Uint32x4, - GPUVertexFormat::Sint32 => Self::Sint32, - GPUVertexFormat::Sint32x2 => Self::Sint32x2, - GPUVertexFormat::Sint32x3 => Self::Sint32x3, - GPUVertexFormat::Sint32x4 => Self::Sint32x4, - GPUVertexFormat::Unorm1010102 => Self::Unorm10_10_10_2, - GPUVertexFormat::Unorm8x4Bgra => Self::Unorm8x4Bgra, - } + fn from(value: GPUVertexFormat) -> Self { + match value { + GPUVertexFormat::Uint8 => Self::Uint8, + GPUVertexFormat::Uint8x2 => Self::Uint8x2, + GPUVertexFormat::Uint8x4 => Self::Uint8x4, + GPUVertexFormat::Sint8 => Self::Sint8, + GPUVertexFormat::Sint8x2 => Self::Sint8x2, + GPUVertexFormat::Sint8x4 => Self::Sint8x4, + GPUVertexFormat::Unorm8 => Self::Unorm8, + GPUVertexFormat::Unorm8x2 => Self::Unorm8x2, + GPUVertexFormat::Unorm8x4 => Self::Unorm8x4, + GPUVertexFormat::Snorm8 => Self::Snorm8, + GPUVertexFormat::Snorm8x2 => Self::Snorm8x2, + GPUVertexFormat::Snorm8x4 => Self::Snorm8x4, + GPUVertexFormat::Uint16 => Self::Uint16, + GPUVertexFormat::Uint16x2 => Self::Uint16x2, + GPUVertexFormat::Uint16x4 => Self::Uint16x4, + GPUVertexFormat::Sint16 => Self::Sint16, + GPUVertexFormat::Sint16x2 => Self::Sint16x2, + GPUVertexFormat::Sint16x4 => Self::Sint16x4, + GPUVertexFormat::Unorm16 => Self::Unorm16, + GPUVertexFormat::Unorm16x2 => Self::Unorm16x2, + GPUVertexFormat::Unorm16x4 => Self::Unorm16x4, + GPUVertexFormat::Snorm16 => Self::Snorm16, + GPUVertexFormat::Snorm16x2 => Self::Snorm16x2, + GPUVertexFormat::Snorm16x4 => Self::Snorm16x4, + GPUVertexFormat::Float16 => Self::Float16, + GPUVertexFormat::Float16x2 => Self::Float16x2, + GPUVertexFormat::Float16x4 => Self::Float16x4, + GPUVertexFormat::Float32 => Self::Float32, + GPUVertexFormat::Float32x2 => Self::Float32x2, + GPUVertexFormat::Float32x3 => Self::Float32x3, + GPUVertexFormat::Float32x4 => Self::Float32x4, + GPUVertexFormat::Uint32 => Self::Uint32, + GPUVertexFormat::Uint32x2 => Self::Uint32x2, + GPUVertexFormat::Uint32x3 => Self::Uint32x3, + GPUVertexFormat::Uint32x4 => Self::Uint32x4, + GPUVertexFormat::Sint32 => Self::Sint32, + GPUVertexFormat::Sint32x2 => Self::Sint32x2, + GPUVertexFormat::Sint32x3 => Self::Sint32x3, + GPUVertexFormat::Sint32x4 => Self::Sint32x4, + GPUVertexFormat::Unorm1010102 => Self::Unorm10_10_10_2, + GPUVertexFormat::Unorm8x4Bgra => Self::Unorm8x4Bgra, } + } } diff --git a/deno_webgpu/rustfmt.toml b/deno_webgpu/rustfmt.toml new file mode 100644 index 00000000000..9bb8d9d4584 --- /dev/null +++ b/deno_webgpu/rustfmt.toml @@ -0,0 +1,3 @@ +max_width = 80 +tab_spaces = 2 +edition = "2021" diff --git a/deno_webgpu/sampler.rs b/deno_webgpu/sampler.rs index 46c08bc7455..997d2acde25 100644 --- a/deno_webgpu/sampler.rs +++ b/deno_webgpu/sampler.rs @@ -8,127 +8,127 @@ use deno_core::WebIDL; use crate::Instance; pub struct GPUSampler { - pub instance: Instance, - pub id: wgpu_core::id::SamplerId, - pub label: String, + pub instance: Instance, + pub id: wgpu_core::id::SamplerId, + pub label: String, } impl Drop for GPUSampler { - fn drop(&mut self) { - self.instance.sampler_drop(self.id); - } + fn drop(&mut self) { + self.instance.sampler_drop(self.id); + } } impl WebIdlInterfaceConverter for GPUSampler { - const NAME: &'static str = "GPUSampler"; + const NAME: &'static str = "GPUSampler"; } impl GarbageCollected for GPUSampler {} #[op2] impl GPUSampler { - #[getter] - #[string] - fn label(&self) -> String { - self.label.clone() - } - #[setter] - #[string] - fn label(&self, #[webidl] _label: String) { - // TODO(@crowlKats): no-op, needs wpgu to implement changing the label - } + #[getter] + #[string] + fn label(&self) -> String { + self.label.clone() + } + #[setter] + #[string] + fn label(&self, #[webidl] _label: String) { + // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(super) struct GPUSamplerDescriptor { - #[webidl(default = String::new())] - pub label: String, - - #[webidl(default = GPUAddressMode::ClampToEdge)] - pub address_mode_u: GPUAddressMode, - #[webidl(default = GPUAddressMode::ClampToEdge)] - pub address_mode_v: GPUAddressMode, - #[webidl(default = GPUAddressMode::ClampToEdge)] - pub address_mode_w: GPUAddressMode, - #[webidl(default = GPUFilterMode::Nearest)] - pub mag_filter: GPUFilterMode, - #[webidl(default = GPUFilterMode::Nearest)] - pub min_filter: GPUFilterMode, - #[webidl(default = GPUFilterMode::Nearest)] - pub mipmap_filter: GPUFilterMode, - - #[webidl(default = 0.0)] - pub lod_min_clamp: f32, - #[webidl(default = 32.0)] - pub lod_max_clamp: f32, - - pub compare: Option, - - #[webidl(default = 1)] - #[options(clamp = true)] - pub max_anisotropy: u16, + #[webidl(default = String::new())] + pub label: String, + + #[webidl(default = GPUAddressMode::ClampToEdge)] + pub address_mode_u: GPUAddressMode, + #[webidl(default = GPUAddressMode::ClampToEdge)] + pub address_mode_v: GPUAddressMode, + #[webidl(default = GPUAddressMode::ClampToEdge)] + pub address_mode_w: GPUAddressMode, + #[webidl(default = GPUFilterMode::Nearest)] + pub mag_filter: GPUFilterMode, + #[webidl(default = GPUFilterMode::Nearest)] + pub min_filter: GPUFilterMode, + #[webidl(default = GPUFilterMode::Nearest)] + pub mipmap_filter: GPUFilterMode, + + #[webidl(default = 0.0)] + pub lod_min_clamp: f32, + #[webidl(default = 32.0)] + pub lod_max_clamp: f32, + + pub compare: Option, + + #[webidl(default = 1)] + #[options(clamp = true)] + pub max_anisotropy: u16, } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUAddressMode { - ClampToEdge, - Repeat, - MirrorRepeat, + ClampToEdge, + Repeat, + MirrorRepeat, } impl From for wgpu_types::AddressMode { - fn from(value: GPUAddressMode) -> Self { - match value { - GPUAddressMode::ClampToEdge => Self::ClampToEdge, - GPUAddressMode::Repeat => Self::Repeat, - GPUAddressMode::MirrorRepeat => Self::MirrorRepeat, - } + fn from(value: GPUAddressMode) -> Self { + match value { + GPUAddressMode::ClampToEdge => Self::ClampToEdge, + GPUAddressMode::Repeat => Self::Repeat, + GPUAddressMode::MirrorRepeat => Self::MirrorRepeat, } + } } // Same as GPUMipmapFilterMode #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUFilterMode { - Nearest, - Linear, + Nearest, + Linear, } impl From for wgpu_types::FilterMode { - fn from(value: GPUFilterMode) -> Self { - match value { - GPUFilterMode::Nearest => Self::Nearest, - GPUFilterMode::Linear => Self::Linear, - } + fn from(value: GPUFilterMode) -> Self { + match value { + GPUFilterMode::Nearest => Self::Nearest, + GPUFilterMode::Linear => Self::Linear, } + } } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUCompareFunction { - Never, - Less, - Equal, - LessEqual, - Greater, - NotEqual, - GreaterEqual, - Always, + Never, + Less, + Equal, + LessEqual, + Greater, + NotEqual, + GreaterEqual, + Always, } impl From for wgpu_types::CompareFunction { - fn from(value: GPUCompareFunction) -> Self { - match value { - GPUCompareFunction::Never => Self::Never, - GPUCompareFunction::Less => Self::Less, - GPUCompareFunction::Equal => Self::Equal, - GPUCompareFunction::LessEqual => Self::LessEqual, - GPUCompareFunction::Greater => Self::Greater, - GPUCompareFunction::NotEqual => Self::NotEqual, - GPUCompareFunction::GreaterEqual => Self::GreaterEqual, - GPUCompareFunction::Always => Self::Always, - } + fn from(value: GPUCompareFunction) -> Self { + match value { + GPUCompareFunction::Never => Self::Never, + GPUCompareFunction::Less => Self::Less, + GPUCompareFunction::Equal => Self::Equal, + GPUCompareFunction::LessEqual => Self::LessEqual, + GPUCompareFunction::Greater => Self::Greater, + GPUCompareFunction::NotEqual => Self::NotEqual, + GPUCompareFunction::GreaterEqual => Self::GreaterEqual, + GPUCompareFunction::Always => Self::Always, } + } } diff --git a/deno_webgpu/shader.rs b/deno_webgpu/shader.rs index 43563f89573..ab19c15c73d 100644 --- a/deno_webgpu/shader.rs +++ b/deno_webgpu/shader.rs @@ -11,193 +11,198 @@ use wgpu_core::pipeline; use crate::Instance; pub struct GPUShaderModule { - pub instance: Instance, - pub id: wgpu_core::id::ShaderModuleId, - pub label: String, - pub compilation_info: v8::Global, + pub instance: Instance, + pub id: wgpu_core::id::ShaderModuleId, + pub label: String, + pub compilation_info: v8::Global, } impl Drop for GPUShaderModule { - fn drop(&mut self) { - self.instance.shader_module_drop(self.id); - } + fn drop(&mut self) { + self.instance.shader_module_drop(self.id); + } } impl WebIdlInterfaceConverter for GPUShaderModule { - const NAME: &'static str = "GPUShaderModule"; + const NAME: &'static str = "GPUShaderModule"; } impl GarbageCollected for GPUShaderModule {} #[op2] impl GPUShaderModule { - #[getter] - #[string] - fn label(&self) -> String { - self.label.clone() - } - #[setter] - #[string] - fn label(&self, #[webidl] _label: String) { - // TODO(@crowlKats): no-op, needs wpgu to implement changing the label - } - - fn get_compilation_info<'a>( - &self, - scope: &mut v8::HandleScope<'a>, - ) -> v8::Local<'a, v8::Promise> { - let resolver = v8::PromiseResolver::new(scope).unwrap(); - let info = v8::Local::new(scope, self.compilation_info.clone()); - resolver.resolve(scope, info.into()).unwrap(); - resolver.get_promise(scope) - } + #[getter] + #[string] + fn label(&self) -> String { + self.label.clone() + } + #[setter] + #[string] + fn label(&self, #[webidl] _label: String) { + // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } + + fn get_compilation_info<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + ) -> v8::Local<'a, v8::Promise> { + let resolver = v8::PromiseResolver::new(scope).unwrap(); + let info = v8::Local::new(scope, self.compilation_info.clone()); + resolver.resolve(scope, info.into()).unwrap(); + resolver.get_promise(scope) + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUShaderModuleDescriptor { - #[webidl(default = String::new())] - pub label: String, + #[webidl(default = String::new())] + pub label: String, - pub code: String, + pub code: String, } pub struct GPUCompilationMessage { - message: String, - r#type: GPUCompilationMessageType, - line_num: u64, - line_pos: u64, - offset: u64, - length: u64, + message: String, + r#type: GPUCompilationMessageType, + line_num: u64, + line_pos: u64, + offset: u64, + length: u64, } impl GarbageCollected for GPUCompilationMessage {} #[op2] impl GPUCompilationMessage { - #[getter] - #[string] - fn message(&self) -> String { - self.message.clone() - } + #[getter] + #[string] + fn message(&self) -> String { + self.message.clone() + } + + // Naming this `type` or `r#type` does not work. + // https://github.com/gfx-rs/wgpu/issues/7778 + #[getter] + #[string] + fn ty(&self) -> &'static str { + self.r#type.as_str() + } + + #[getter] + #[number] + fn line_num(&self) -> u64 { + self.line_num + } + + #[getter] + #[number] + fn line_pos(&self) -> u64 { + self.line_pos + } + + #[getter] + #[number] + fn offset(&self) -> u64 { + self.offset + } + + #[getter] + #[number] + fn length(&self) -> u64 { + self.length + } +} - // Naming this `type` or `r#type` does not work. - // https://github.com/gfx-rs/wgpu/issues/7778 - #[getter] - #[string] - fn ty(&self) -> &'static str { - self.r#type.as_str() - } +impl GPUCompilationMessage { + fn new(error: &pipeline::CreateShaderModuleError, source: &str) -> Self { + let message = error.to_string(); - #[getter] - #[number] - fn line_num(&self) -> u64 { - self.line_num - } + let loc = match error { + pipeline::CreateShaderModuleError::Parsing(e) => e.inner.location(source), + pipeline::CreateShaderModuleError::Validation(e) => { + e.inner.location(source) + } + _ => None, + }; - #[getter] - #[number] - fn line_pos(&self) -> u64 { - self.line_pos - } + match loc { + Some(loc) => { + let len_utf16 = |s: &str| s.chars().map(|c| c.len_utf16() as u64).sum(); - #[getter] - #[number] - fn offset(&self) -> u64 { - self.offset - } + let start = loc.offset as usize; - #[getter] - #[number] - fn length(&self) -> u64 { - self.length - } -} + // Naga reports a `line_pos` using UTF-8 bytes, so we cannot use it. + let line_start = + source[0..start].rfind('\n').map(|pos| pos + 1).unwrap_or(0); + let line_pos = len_utf16(&source[line_start..start]) + 1; -impl GPUCompilationMessage { - fn new(error: &pipeline::CreateShaderModuleError, source: &str) -> Self { - let message = error.to_string(); - - let loc = match error { - pipeline::CreateShaderModuleError::Parsing(e) => e.inner.location(source), - pipeline::CreateShaderModuleError::Validation(e) => e.inner.location(source), - _ => None, - }; - - match loc { - Some(loc) => { - let len_utf16 = |s: &str| s.chars().map(|c| c.len_utf16() as u64).sum(); - - let start = loc.offset as usize; - - // Naga reports a `line_pos` using UTF-8 bytes, so we cannot use it. - let line_start = source[0..start].rfind('\n').map(|pos| pos + 1).unwrap_or(0); - let line_pos = len_utf16(&source[line_start..start]) + 1; - - Self { - message, - r#type: GPUCompilationMessageType::Error, - line_num: loc.line_number.into(), - line_pos, - offset: len_utf16(&source[0..start]), - length: len_utf16(&source[start..start + loc.length as usize]), - } - } - _ => Self { - message, - r#type: GPUCompilationMessageType::Error, - line_num: 0, - line_pos: 0, - offset: 0, - length: 0, - }, + Self { + message, + r#type: GPUCompilationMessageType::Error, + line_num: loc.line_number.into(), + line_pos, + offset: len_utf16(&source[0..start]), + length: len_utf16(&source[start..start + loc.length as usize]), } + } + _ => Self { + message, + r#type: GPUCompilationMessageType::Error, + line_num: 0, + line_pos: 0, + offset: 0, + length: 0, + }, } + } } pub struct GPUCompilationInfo { - messages: v8::Global, + messages: v8::Global, } impl GarbageCollected for GPUCompilationInfo {} #[op2] impl GPUCompilationInfo { - #[getter] - #[global] - fn messages(&self) -> v8::Global { - self.messages.clone() - } + #[getter] + #[global] + fn messages(&self) -> v8::Global { + self.messages.clone() + } } impl GPUCompilationInfo { - pub fn new<'args, 'scope>( - scope: &mut v8::HandleScope<'scope>, - messages: impl ExactSizeIterator, - source: &'args str, - ) -> Self { - let array = v8::Array::new(scope, messages.len().try_into().unwrap()); - for (i, message) in messages.enumerate() { - let message_object = - make_cppgc_object(scope, GPUCompilationMessage::new(message, source)); - array.set_index(scope, i.try_into().unwrap(), message_object.into()); - } + pub fn new<'args, 'scope>( + scope: &mut v8::HandleScope<'scope>, + messages: impl ExactSizeIterator< + Item = &'args pipeline::CreateShaderModuleError, + >, + source: &'args str, + ) -> Self { + let array = v8::Array::new(scope, messages.len().try_into().unwrap()); + for (i, message) in messages.enumerate() { + let message_object = + make_cppgc_object(scope, GPUCompilationMessage::new(message, source)); + array.set_index(scope, i.try_into().unwrap(), message_object.into()); + } - let object: v8::Local = array.into(); - object - .set_integrity_level(scope, v8::IntegrityLevel::Frozen) - .unwrap(); + let object: v8::Local = array.into(); + object + .set_integrity_level(scope, v8::IntegrityLevel::Frozen) + .unwrap(); - Self { - messages: v8::Global::new(scope, object), - } + Self { + messages: v8::Global::new(scope, object), } + } } #[derive(WebIDL, Clone)] #[webidl(enum)] pub(crate) enum GPUCompilationMessageType { - Error, - Warning, - Info, + Error, + Warning, + Info, } diff --git a/deno_webgpu/surface.rs b/deno_webgpu/surface.rs index 8c8445a9a4f..74a382a927f 100644 --- a/deno_webgpu/surface.rs +++ b/deno_webgpu/surface.rs @@ -2,12 +2,12 @@ use std::cell::RefCell; -use deno_core::op2; -use deno_core::v8; use deno_core::GarbageCollected; use deno_core::WebIDL; use deno_core::_ops::make_cppgc_object; use deno_core::cppgc::Ptr; +use deno_core::op2; +use deno_core::v8; use deno_error::JsErrorBox; use wgpu_types::SurfaceStatus; @@ -17,213 +17,217 @@ use crate::texture::GPUTextureFormat; #[derive(Debug, thiserror::Error, deno_error::JsError)] pub enum SurfaceError { - #[class("DOMExceptionInvalidStateError")] - #[error("Context is not configured")] - UnconfiguredContext, - #[class(generic)] - #[error("Invalid Surface Status")] - InvalidStatus, - #[class(generic)] - #[error(transparent)] - Surface(#[from] wgpu_core::present::SurfaceError), + #[class("DOMExceptionInvalidStateError")] + #[error("Context is not configured")] + UnconfiguredContext, + #[class(generic)] + #[error("Invalid Surface Status")] + InvalidStatus, + #[class(generic)] + #[error(transparent)] + Surface(#[from] wgpu_core::present::SurfaceError), } pub struct Configuration { - pub device: Ptr, - pub usage: u32, - pub format: GPUTextureFormat, + pub device: Ptr, + pub usage: u32, + pub format: GPUTextureFormat, } pub struct GPUCanvasContext { - pub surface_id: wgpu_core::id::SurfaceId, - pub width: RefCell, - pub height: RefCell, + pub surface_id: wgpu_core::id::SurfaceId, + pub width: RefCell, + pub height: RefCell, - pub config: RefCell>, - pub texture: RefCell>>, + pub config: RefCell>, + pub texture: RefCell>>, - pub canvas: v8::Global, + pub canvas: v8::Global, } impl GarbageCollected for GPUCanvasContext {} #[op2] impl GPUCanvasContext { - #[getter] - #[global] - fn canvas(&self) -> v8::Global { - self.canvas.clone() + #[getter] + #[global] + fn canvas(&self) -> v8::Global { + self.canvas.clone() + } + + fn configure( + &self, + #[webidl] configuration: GPUCanvasConfiguration, + ) -> Result<(), JsErrorBox> { + let usage = wgpu_types::TextureUsages::from_bits(configuration.usage) + .ok_or_else(|| JsErrorBox::type_error("usage is not valid"))?; + let format = configuration.format.clone().into(); + let conf = wgpu_types::SurfaceConfiguration { + usage, + format, + width: *self.width.borrow(), + height: *self.height.borrow(), + present_mode: configuration + .present_mode + .map(Into::into) + .unwrap_or_default(), + alpha_mode: configuration.alpha_mode.into(), + view_formats: configuration + .view_formats + .into_iter() + .map(Into::into) + .collect(), + desired_maximum_frame_latency: 2, + }; + + let device = configuration.device; + + let err = + device + .instance + .surface_configure(self.surface_id, device.id, &conf); + + device.error_handler.push_error(err); + + self.config.borrow_mut().replace(Configuration { + device, + usage: configuration.usage, + format: configuration.format, + }); + + Ok(()) + } + + #[fast] + fn unconfigure(&self) { + *self.config.borrow_mut() = None; + } + + #[global] + fn get_current_texture( + &self, + scope: &mut v8::HandleScope, + ) -> Result, SurfaceError> { + let config = self.config.borrow(); + let Some(config) = config.as_ref() else { + return Err(SurfaceError::UnconfiguredContext); + }; + + { + if let Some(obj) = self.texture.borrow().as_ref() { + return Ok(obj.clone()); + } } - fn configure(&self, #[webidl] configuration: GPUCanvasConfiguration) -> Result<(), JsErrorBox> { - let usage = wgpu_types::TextureUsages::from_bits(configuration.usage) - .ok_or_else(|| JsErrorBox::type_error("usage is not valid"))?; - let format = configuration.format.clone().into(); - let conf = wgpu_types::SurfaceConfiguration { - usage, - format, + let output = config + .device + .instance + .surface_get_current_texture(self.surface_id, None)?; + + match output.status { + SurfaceStatus::Good | SurfaceStatus::Suboptimal => { + let id = output.texture.unwrap(); + + let texture = GPUTexture { + instance: config.device.instance.clone(), + error_handler: config.device.error_handler.clone(), + id, + label: "".to_string(), + size: wgpu_types::Extent3d { width: *self.width.borrow(), height: *self.height.borrow(), - present_mode: configuration - .present_mode - .map(Into::into) - .unwrap_or_default(), - alpha_mode: configuration.alpha_mode.into(), - view_formats: configuration - .view_formats - .into_iter() - .map(Into::into) - .collect(), - desired_maximum_frame_latency: 2, - }; - - let device = configuration.device; - - let err = device - .instance - .surface_configure(self.surface_id, device.id, &conf); - - device.error_handler.push_error(err); - - self.config.borrow_mut().replace(Configuration { - device, - usage: configuration.usage, - format: configuration.format, - }); - - Ok(()) - } - - #[fast] - fn unconfigure(&self) { - *self.config.borrow_mut() = None; - } - - #[global] - fn get_current_texture( - &self, - scope: &mut v8::HandleScope, - ) -> Result, SurfaceError> { - let config = self.config.borrow(); - let Some(config) = config.as_ref() else { - return Err(SurfaceError::UnconfiguredContext); + depth_or_array_layers: 1, + }, + mip_level_count: 0, + sample_count: 0, + dimension: crate::texture::GPUTextureDimension::D2, + format: config.format.clone(), + usage: config.usage, }; + let obj = make_cppgc_object(scope, texture); + let obj = v8::Global::new(scope, obj); + *self.texture.borrow_mut() = Some(obj.clone()); - { - if let Some(obj) = self.texture.borrow().as_ref() { - return Ok(obj.clone()); - } - } - - let output = config - .device - .instance - .surface_get_current_texture(self.surface_id, None)?; - - match output.status { - SurfaceStatus::Good | SurfaceStatus::Suboptimal => { - let id = output.texture.unwrap(); - - let texture = GPUTexture { - instance: config.device.instance.clone(), - error_handler: config.device.error_handler.clone(), - id, - label: "".to_string(), - size: wgpu_types::Extent3d { - width: *self.width.borrow(), - height: *self.height.borrow(), - depth_or_array_layers: 1, - }, - mip_level_count: 0, - sample_count: 0, - dimension: crate::texture::GPUTextureDimension::D2, - format: config.format.clone(), - usage: config.usage, - }; - let obj = make_cppgc_object(scope, texture); - let obj = v8::Global::new(scope, obj); - *self.texture.borrow_mut() = Some(obj.clone()); - - Ok(obj) - } - _ => Err(SurfaceError::InvalidStatus), - } + Ok(obj) + } + _ => Err(SurfaceError::InvalidStatus), } + } } impl GPUCanvasContext { - pub fn present(&self) -> Result<(), SurfaceError> { - let config = self.config.borrow(); - let Some(config) = config.as_ref() else { - return Err(SurfaceError::UnconfiguredContext); - }; + pub fn present(&self) -> Result<(), SurfaceError> { + let config = self.config.borrow(); + let Some(config) = config.as_ref() else { + return Err(SurfaceError::UnconfiguredContext); + }; - config.device.instance.surface_present(self.surface_id)?; + config.device.instance.surface_present(self.surface_id)?; - Ok(()) - } + Ok(()) + } } #[derive(WebIDL)] #[webidl(dictionary)] struct GPUCanvasConfiguration { - device: Ptr, - format: GPUTextureFormat, - #[webidl(default = wgpu_types::TextureUsages::RENDER_ATTACHMENT.bits())] - #[options(enforce_range = true)] - usage: u32, - #[webidl(default = GPUCanvasAlphaMode::Opaque)] - alpha_mode: GPUCanvasAlphaMode, - - // Extended from spec - present_mode: Option, - #[webidl(default = vec![])] - view_formats: Vec, + device: Ptr, + format: GPUTextureFormat, + #[webidl(default = wgpu_types::TextureUsages::RENDER_ATTACHMENT.bits())] + #[options(enforce_range = true)] + usage: u32, + #[webidl(default = GPUCanvasAlphaMode::Opaque)] + alpha_mode: GPUCanvasAlphaMode, + + // Extended from spec + present_mode: Option, + #[webidl(default = vec![])] + view_formats: Vec, } #[derive(WebIDL)] #[webidl(enum)] enum GPUCanvasAlphaMode { - Opaque, - Premultiplied, + Opaque, + Premultiplied, } impl From for wgpu_types::CompositeAlphaMode { - fn from(value: GPUCanvasAlphaMode) -> Self { - match value { - GPUCanvasAlphaMode::Opaque => Self::Opaque, - GPUCanvasAlphaMode::Premultiplied => Self::PreMultiplied, - } + fn from(value: GPUCanvasAlphaMode) -> Self { + match value { + GPUCanvasAlphaMode::Opaque => Self::Opaque, + GPUCanvasAlphaMode::Premultiplied => Self::PreMultiplied, } + } } // Extended from spec #[derive(WebIDL)] #[webidl(enum)] enum GPUPresentMode { - #[webidl(rename = "autoVsync")] - AutoVsync, - #[webidl(rename = "autoNoVsync")] - AutoNoVsync, - #[webidl(rename = "fifo")] - Fifo, - #[webidl(rename = "fifoRelaxed")] - FifoRelaxed, - #[webidl(rename = "immediate")] - Immediate, - #[webidl(rename = "mailbox")] - Mailbox, + #[webidl(rename = "autoVsync")] + AutoVsync, + #[webidl(rename = "autoNoVsync")] + AutoNoVsync, + #[webidl(rename = "fifo")] + Fifo, + #[webidl(rename = "fifoRelaxed")] + FifoRelaxed, + #[webidl(rename = "immediate")] + Immediate, + #[webidl(rename = "mailbox")] + Mailbox, } impl From for wgpu_types::PresentMode { - fn from(value: GPUPresentMode) -> Self { - match value { - GPUPresentMode::AutoVsync => Self::AutoVsync, - GPUPresentMode::AutoNoVsync => Self::AutoNoVsync, - GPUPresentMode::Fifo => Self::Fifo, - GPUPresentMode::FifoRelaxed => Self::FifoRelaxed, - GPUPresentMode::Immediate => Self::Immediate, - GPUPresentMode::Mailbox => Self::Mailbox, - } + fn from(value: GPUPresentMode) -> Self { + match value { + GPUPresentMode::AutoVsync => Self::AutoVsync, + GPUPresentMode::AutoNoVsync => Self::AutoNoVsync, + GPUPresentMode::Fifo => Self::Fifo, + GPUPresentMode::FifoRelaxed => Self::FifoRelaxed, + GPUPresentMode::Immediate => Self::Immediate, + GPUPresentMode::Mailbox => Self::Mailbox, } + } } diff --git a/deno_webgpu/texture.rs b/deno_webgpu/texture.rs index 7a7af62c59f..aa36069e60e 100644 --- a/deno_webgpu/texture.rs +++ b/deno_webgpu/texture.rs @@ -18,228 +18,229 @@ use crate::Instance; #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUTextureDescriptor { - #[webidl(default = String::new())] - pub label: String, - - pub size: super::webidl::GPUExtent3D, - #[webidl(default = 1)] - #[options(enforce_range = true)] - pub mip_level_count: u32, - #[webidl(default = 1)] - #[options(enforce_range = true)] - pub sample_count: u32, - #[webidl(default = GPUTextureDimension::D2)] - pub dimension: GPUTextureDimension, - pub format: GPUTextureFormat, - #[options(enforce_range = true)] - pub usage: u32, - #[webidl(default = vec![])] - pub view_formats: Vec, + #[webidl(default = String::new())] + pub label: String, + + pub size: super::webidl::GPUExtent3D, + #[webidl(default = 1)] + #[options(enforce_range = true)] + pub mip_level_count: u32, + #[webidl(default = 1)] + #[options(enforce_range = true)] + pub sample_count: u32, + #[webidl(default = GPUTextureDimension::D2)] + pub dimension: GPUTextureDimension, + pub format: GPUTextureFormat, + #[options(enforce_range = true)] + pub usage: u32, + #[webidl(default = vec![])] + pub view_formats: Vec, } pub struct GPUTexture { - pub instance: Instance, - pub error_handler: super::error::ErrorHandler, + pub instance: Instance, + pub error_handler: super::error::ErrorHandler, - pub id: wgpu_core::id::TextureId, + pub id: wgpu_core::id::TextureId, - pub label: String, + pub label: String, - pub size: Extent3d, - pub mip_level_count: u32, - pub sample_count: u32, - pub dimension: GPUTextureDimension, - pub format: GPUTextureFormat, - pub usage: u32, + pub size: Extent3d, + pub mip_level_count: u32, + pub sample_count: u32, + pub dimension: GPUTextureDimension, + pub format: GPUTextureFormat, + pub usage: u32, } impl Drop for GPUTexture { - fn drop(&mut self) { - self.instance.texture_drop(self.id); - } + fn drop(&mut self) { + self.instance.texture_drop(self.id); + } } impl WebIdlInterfaceConverter for GPUTexture { - const NAME: &'static str = "GPUTexture"; + const NAME: &'static str = "GPUTexture"; } impl GarbageCollected for GPUTexture {} #[op2] impl GPUTexture { - #[getter] - #[string] - fn label(&self) -> String { - self.label.clone() - } - #[setter] - #[string] - fn label(&self, #[webidl] _label: String) { - // TODO(@crowlKats): no-op, needs wpgu to implement changing the label - } - - #[getter] - fn width(&self) -> u32 { - self.size.width - } - #[getter] - fn height(&self) -> u32 { - self.size.height - } - #[getter] - fn depth_or_array_layers(&self) -> u32 { - self.size.depth_or_array_layers - } - #[getter] - fn mip_level_count(&self) -> u32 { - self.mip_level_count - } - #[getter] - fn sample_count(&self) -> u32 { - self.sample_count - } - #[getter] - #[string] - fn dimension(&self) -> &'static str { - self.dimension.as_str() - } - #[getter] - #[string] - fn format(&self) -> &'static str { - self.format.as_str() - } - #[getter] - fn usage(&self) -> u32 { - self.usage - } - #[fast] - fn destroy(&self) { - self.instance.texture_destroy(self.id); - } - - #[cppgc] - fn create_view( - &self, - #[webidl] descriptor: GPUTextureViewDescriptor, - ) -> Result { - let wgpu_descriptor = wgpu_core::resource::TextureViewDescriptor { - label: crate::transform_label(descriptor.label.clone()), - format: descriptor.format.map(Into::into), - dimension: descriptor.dimension.map(Into::into), - usage: Some( - wgpu_types::TextureUsages::from_bits(descriptor.usage) - .ok_or_else(|| JsErrorBox::type_error("usage is not valid"))?, - ), - range: wgpu_types::ImageSubresourceRange { - aspect: descriptor.aspect.into(), - base_mip_level: descriptor.base_mip_level, - mip_level_count: descriptor.mip_level_count, - base_array_layer: descriptor.base_array_layer, - array_layer_count: descriptor.array_layer_count, - }, - }; - - let (id, err) = self - .instance - .texture_create_view(self.id, &wgpu_descriptor, None); - - self.error_handler.push_error(err); - - Ok(GPUTextureView { - instance: self.instance.clone(), - id, - label: descriptor.label, - }) - } + #[getter] + #[string] + fn label(&self) -> String { + self.label.clone() + } + #[setter] + #[string] + fn label(&self, #[webidl] _label: String) { + // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } + + #[getter] + fn width(&self) -> u32 { + self.size.width + } + #[getter] + fn height(&self) -> u32 { + self.size.height + } + #[getter] + fn depth_or_array_layers(&self) -> u32 { + self.size.depth_or_array_layers + } + #[getter] + fn mip_level_count(&self) -> u32 { + self.mip_level_count + } + #[getter] + fn sample_count(&self) -> u32 { + self.sample_count + } + #[getter] + #[string] + fn dimension(&self) -> &'static str { + self.dimension.as_str() + } + #[getter] + #[string] + fn format(&self) -> &'static str { + self.format.as_str() + } + #[getter] + fn usage(&self) -> u32 { + self.usage + } + #[fast] + fn destroy(&self) { + self.instance.texture_destroy(self.id); + } + + #[cppgc] + fn create_view( + &self, + #[webidl] descriptor: GPUTextureViewDescriptor, + ) -> Result { + let wgpu_descriptor = wgpu_core::resource::TextureViewDescriptor { + label: crate::transform_label(descriptor.label.clone()), + format: descriptor.format.map(Into::into), + dimension: descriptor.dimension.map(Into::into), + usage: Some( + wgpu_types::TextureUsages::from_bits(descriptor.usage) + .ok_or_else(|| JsErrorBox::type_error("usage is not valid"))?, + ), + range: wgpu_types::ImageSubresourceRange { + aspect: descriptor.aspect.into(), + base_mip_level: descriptor.base_mip_level, + mip_level_count: descriptor.mip_level_count, + base_array_layer: descriptor.base_array_layer, + array_layer_count: descriptor.array_layer_count, + }, + }; + + let (id, err) = + self + .instance + .texture_create_view(self.id, &wgpu_descriptor, None); + + self.error_handler.push_error(err); + + Ok(GPUTextureView { + instance: self.instance.clone(), + id, + label: descriptor.label, + }) + } } #[derive(WebIDL)] #[webidl(dictionary)] struct GPUTextureViewDescriptor { - #[webidl(default = String::new())] - label: String, - - format: Option, - dimension: Option, - #[webidl(default = 0)] - #[options(enforce_range = true)] - usage: u32, - #[webidl(default = GPUTextureAspect::All)] - aspect: GPUTextureAspect, - #[webidl(default = 0)] - #[options(enforce_range = true)] - base_mip_level: u32, - #[options(enforce_range = true)] - mip_level_count: Option, - #[webidl(default = 0)] - #[options(enforce_range = true)] - base_array_layer: u32, - #[options(enforce_range = true)] - array_layer_count: Option, + #[webidl(default = String::new())] + label: String, + + format: Option, + dimension: Option, + #[webidl(default = 0)] + #[options(enforce_range = true)] + usage: u32, + #[webidl(default = GPUTextureAspect::All)] + aspect: GPUTextureAspect, + #[webidl(default = 0)] + #[options(enforce_range = true)] + base_mip_level: u32, + #[options(enforce_range = true)] + mip_level_count: Option, + #[webidl(default = 0)] + #[options(enforce_range = true)] + base_array_layer: u32, + #[options(enforce_range = true)] + array_layer_count: Option, } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUTextureViewDimension { - #[webidl(rename = "1d")] - D1, - #[webidl(rename = "2d")] - D2, - #[webidl(rename = "2d-array")] - D2Array, - #[webidl(rename = "cube")] - Cube, - #[webidl(rename = "cube-array")] - CubeArray, - #[webidl(rename = "3d")] - D3, + #[webidl(rename = "1d")] + D1, + #[webidl(rename = "2d")] + D2, + #[webidl(rename = "2d-array")] + D2Array, + #[webidl(rename = "cube")] + Cube, + #[webidl(rename = "cube-array")] + CubeArray, + #[webidl(rename = "3d")] + D3, } impl From for TextureViewDimension { - fn from(value: GPUTextureViewDimension) -> Self { - match value { - GPUTextureViewDimension::D1 => Self::D1, - GPUTextureViewDimension::D2 => Self::D2, - GPUTextureViewDimension::D3 => Self::D3, - GPUTextureViewDimension::D2Array => Self::D2Array, - GPUTextureViewDimension::Cube => Self::Cube, - GPUTextureViewDimension::CubeArray => Self::CubeArray, - } + fn from(value: GPUTextureViewDimension) -> Self { + match value { + GPUTextureViewDimension::D1 => Self::D1, + GPUTextureViewDimension::D2 => Self::D2, + GPUTextureViewDimension::D3 => Self::D3, + GPUTextureViewDimension::D2Array => Self::D2Array, + GPUTextureViewDimension::Cube => Self::Cube, + GPUTextureViewDimension::CubeArray => Self::CubeArray, } + } } #[derive(WebIDL)] #[webidl(enum)] pub enum GPUTextureAspect { - All, - StencilOnly, - DepthOnly, + All, + StencilOnly, + DepthOnly, } impl From for TextureAspect { - fn from(value: GPUTextureAspect) -> Self { - match value { - GPUTextureAspect::All => Self::All, - GPUTextureAspect::StencilOnly => Self::StencilOnly, - GPUTextureAspect::DepthOnly => Self::DepthOnly, - } + fn from(value: GPUTextureAspect) -> Self { + match value { + GPUTextureAspect::All => Self::All, + GPUTextureAspect::StencilOnly => Self::StencilOnly, + GPUTextureAspect::DepthOnly => Self::DepthOnly, } + } } pub struct GPUTextureView { - pub instance: Instance, - pub id: wgpu_core::id::TextureViewId, - pub label: String, + pub instance: Instance, + pub id: wgpu_core::id::TextureViewId, + pub label: String, } impl Drop for GPUTextureView { - fn drop(&mut self) { - let _ = self.instance.texture_view_drop(self.id); - } + fn drop(&mut self) { + let _ = self.instance.texture_view_drop(self.id); + } } impl WebIdlInterfaceConverter for GPUTextureView { - const NAME: &'static str = "GPUTextureView"; + const NAME: &'static str = "GPUTextureView"; } impl GarbageCollected for GPUTextureView {} @@ -247,424 +248,424 @@ impl GarbageCollected for GPUTextureView {} #[op2] impl GPUTextureView { - #[getter] - #[string] - fn label(&self) -> String { - self.label.clone() - } - #[setter] - #[string] - fn label(&self, #[webidl] _label: String) { - // TODO(@crowlKats): no-op, needs wpgu to implement changing the label - } + #[getter] + #[string] + fn label(&self) -> String { + self.label.clone() + } + #[setter] + #[string] + fn label(&self, #[webidl] _label: String) { + // TODO(@crowlKats): no-op, needs wpgu to implement changing the label + } } #[derive(WebIDL, Clone)] #[webidl(enum)] pub enum GPUTextureDimension { - #[webidl(rename = "1d")] - D1, - #[webidl(rename = "2d")] - D2, - #[webidl(rename = "3d")] - D3, + #[webidl(rename = "1d")] + D1, + #[webidl(rename = "2d")] + D2, + #[webidl(rename = "3d")] + D3, } impl From for TextureDimension { - fn from(value: GPUTextureDimension) -> Self { - match value { - GPUTextureDimension::D1 => Self::D1, - GPUTextureDimension::D2 => Self::D2, - GPUTextureDimension::D3 => Self::D3, - } + fn from(value: GPUTextureDimension) -> Self { + match value { + GPUTextureDimension::D1 => Self::D1, + GPUTextureDimension::D2 => Self::D2, + GPUTextureDimension::D3 => Self::D3, } + } } #[derive(WebIDL, Clone)] #[webidl(enum)] pub(crate) enum GPUTextureFormat { - #[webidl(rename = "r8unorm")] - R8unorm, - #[webidl(rename = "r8snorm")] - R8snorm, - #[webidl(rename = "r8uint")] - R8uint, - #[webidl(rename = "r8sint")] - R8sint, - #[webidl(rename = "r16uint")] - R16uint, - #[webidl(rename = "r16sint")] - R16sint, - #[webidl(rename = "r16float")] - R16float, - #[webidl(rename = "rg8unorm")] - Rg8unorm, - #[webidl(rename = "rg8snorm")] - Rg8snorm, - #[webidl(rename = "rg8uint")] - Rg8uint, - #[webidl(rename = "rg8sint")] - Rg8sint, - #[webidl(rename = "r32uint")] - R32uint, - #[webidl(rename = "r32sint")] - R32sint, - #[webidl(rename = "r32float")] - R32float, - #[webidl(rename = "rg16uint")] - Rg16uint, - #[webidl(rename = "rg16sint")] - Rg16sint, - #[webidl(rename = "rg16float")] - Rg16float, - #[webidl(rename = "rgba8unorm")] - Rgba8unorm, - #[webidl(rename = "rgba8unorm-srgb")] - Rgba8unormSrgb, - #[webidl(rename = "rgba8snorm")] - Rgba8snorm, - #[webidl(rename = "rgba8uint")] - Rgba8uint, - #[webidl(rename = "rgba8sint")] - Rgba8sint, - #[webidl(rename = "bgra8unorm")] - Bgra8unorm, - #[webidl(rename = "bgra8unorm-srgb")] - Bgra8unormSrgb, - #[webidl(rename = "rgb9e5ufloat")] - Rgb9e5ufloat, - #[webidl(rename = "rgb10a2uint")] - Rgb10a2uint, - #[webidl(rename = "rgb10a2unorm")] - Rgb10a2unorm, - #[webidl(rename = "rg11b10ufloat")] - Rg11b10ufloat, - #[webidl(rename = "rg32uint")] - Rg32uint, - #[webidl(rename = "rg32sint")] - Rg32sint, - #[webidl(rename = "rg32float")] - Rg32float, - #[webidl(rename = "rgba16uint")] - Rgba16uint, - #[webidl(rename = "rgba16sint")] - Rgba16sint, - #[webidl(rename = "rgba16float")] - Rgba16float, - #[webidl(rename = "rgba32uint")] - Rgba32uint, - #[webidl(rename = "rgba32sint")] - Rgba32sint, - #[webidl(rename = "rgba32float")] - Rgba32float, - #[webidl(rename = "stencil8")] - Stencil8, - #[webidl(rename = "depth16unorm")] - Depth16unorm, - #[webidl(rename = "depth24plus")] - Depth24plus, - #[webidl(rename = "depth24plus-stencil8")] - Depth24plusStencil8, - #[webidl(rename = "depth32float")] - Depth32float, - #[webidl(rename = "depth32float-stencil8")] - Depth32floatStencil8, - #[webidl(rename = "bc1-rgba-unorm")] - Bc1RgbaUnorm, - #[webidl(rename = "bc1-rgba-unorm-srgb")] - Bc1RgbaUnormSrgb, - #[webidl(rename = "bc2-rgba-unorm")] - Bc2RgbaUnorm, - #[webidl(rename = "bc2-rgba-unorm-srgb")] - Bc2RgbaUnormSrgb, - #[webidl(rename = "bc3-rgba-unorm")] - Bc3RgbaUnorm, - #[webidl(rename = "bc3-rgba-unorm-srgb")] - Bc3RgbaUnormSrgb, - #[webidl(rename = "bc4-r-unorm")] - Bc4RUnorm, - #[webidl(rename = "bc4-r-snorm")] - Bc4RSnorm, - #[webidl(rename = "bc5-rg-unorm")] - Bc5RgUnorm, - #[webidl(rename = "bc5-rg-snorm")] - Bc5RgSnorm, - #[webidl(rename = "bc6h-rgb-ufloat")] - Bc6hRgbUfloat, - #[webidl(rename = "bc6h-rgb-float")] - Bc6hRgbFloat, - #[webidl(rename = "bc7-rgba-unorm")] - Bc7RgbaUnorm, - #[webidl(rename = "bc7-rgba-unorm-srgb")] - Bc7RgbaUnormSrgb, - #[webidl(rename = "etc2-rgb8unorm")] - Etc2Rgb8unorm, - #[webidl(rename = "etc2-rgb8unorm-srgb")] - Etc2Rgb8unormSrgb, - #[webidl(rename = "etc2-rgb8a1unorm")] - Etc2Rgb8a1unorm, - #[webidl(rename = "etc2-rgb8a1unorm-srgb")] - Etc2Rgb8a1unormSrgb, - #[webidl(rename = "etc2-rgba8unorm")] - Etc2Rgba8unorm, - #[webidl(rename = "etc2-rgba8unorm-srgb")] - Etc2Rgba8unormSrgb, - #[webidl(rename = "eac-r11unorm")] - EacR11unorm, - #[webidl(rename = "eac-r11snorm")] - EacR11snorm, - #[webidl(rename = "eac-rg11unorm")] - EacRg11unorm, - #[webidl(rename = "eac-rg11snorm")] - EacRg11snorm, - #[webidl(rename = "astc-4x4-unorm")] - Astc4x4Unorm, - #[webidl(rename = "astc-4x4-unorm-srgb")] - Astc4x4UnormSrgb, - #[webidl(rename = "astc-5x4-unorm")] - Astc5x4Unorm, - #[webidl(rename = "astc-5x4-unorm-srgb")] - Astc5x4UnormSrgb, - #[webidl(rename = "astc-5x5-unorm")] - Astc5x5Unorm, - #[webidl(rename = "astc-5x5-unorm-srgb")] - Astc5x5UnormSrgb, - #[webidl(rename = "astc-6x5-unorm")] - Astc6x5Unorm, - #[webidl(rename = "astc-6x5-unorm-srgb")] - Astc6x5UnormSrgb, - #[webidl(rename = "astc-6x6-unorm")] - Astc6x6Unorm, - #[webidl(rename = "astc-6x6-unorm-srgb")] - Astc6x6UnormSrgb, - #[webidl(rename = "astc-8x5-unorm")] - Astc8x5Unorm, - #[webidl(rename = "astc-8x5-unorm-srgb")] - Astc8x5UnormSrgb, - #[webidl(rename = "astc-8x6-unorm")] - Astc8x6Unorm, - #[webidl(rename = "astc-8x6-unorm-srgb")] - Astc8x6UnormSrgb, - #[webidl(rename = "astc-8x8-unorm")] - Astc8x8Unorm, - #[webidl(rename = "astc-8x8-unorm-srgb")] - Astc8x8UnormSrgb, - #[webidl(rename = "astc-10x5-unorm")] - Astc10x5Unorm, - #[webidl(rename = "astc-10x5-unorm-srgb")] - Astc10x5UnormSrgb, - #[webidl(rename = "astc-10x6-unorm")] - Astc10x6Unorm, - #[webidl(rename = "astc-10x6-unorm-srgb")] - Astc10x6UnormSrgb, - #[webidl(rename = "astc-10x8-unorm")] - Astc10x8Unorm, - #[webidl(rename = "astc-10x8-unorm-srgb")] - Astc10x8UnormSrgb, - #[webidl(rename = "astc-10x10-unorm")] - Astc10x10Unorm, - #[webidl(rename = "astc-10x10-unorm-srgb")] - Astc10x10UnormSrgb, - #[webidl(rename = "astc-12x10-unorm")] - Astc12x10Unorm, - #[webidl(rename = "astc-12x10-unorm-srgb")] - Astc12x10UnormSrgb, - #[webidl(rename = "astc-12x12-unorm")] - Astc12x12Unorm, - #[webidl(rename = "astc-12x12-unorm-srgb")] - Astc12x12UnormSrgb, + #[webidl(rename = "r8unorm")] + R8unorm, + #[webidl(rename = "r8snorm")] + R8snorm, + #[webidl(rename = "r8uint")] + R8uint, + #[webidl(rename = "r8sint")] + R8sint, + #[webidl(rename = "r16uint")] + R16uint, + #[webidl(rename = "r16sint")] + R16sint, + #[webidl(rename = "r16float")] + R16float, + #[webidl(rename = "rg8unorm")] + Rg8unorm, + #[webidl(rename = "rg8snorm")] + Rg8snorm, + #[webidl(rename = "rg8uint")] + Rg8uint, + #[webidl(rename = "rg8sint")] + Rg8sint, + #[webidl(rename = "r32uint")] + R32uint, + #[webidl(rename = "r32sint")] + R32sint, + #[webidl(rename = "r32float")] + R32float, + #[webidl(rename = "rg16uint")] + Rg16uint, + #[webidl(rename = "rg16sint")] + Rg16sint, + #[webidl(rename = "rg16float")] + Rg16float, + #[webidl(rename = "rgba8unorm")] + Rgba8unorm, + #[webidl(rename = "rgba8unorm-srgb")] + Rgba8unormSrgb, + #[webidl(rename = "rgba8snorm")] + Rgba8snorm, + #[webidl(rename = "rgba8uint")] + Rgba8uint, + #[webidl(rename = "rgba8sint")] + Rgba8sint, + #[webidl(rename = "bgra8unorm")] + Bgra8unorm, + #[webidl(rename = "bgra8unorm-srgb")] + Bgra8unormSrgb, + #[webidl(rename = "rgb9e5ufloat")] + Rgb9e5ufloat, + #[webidl(rename = "rgb10a2uint")] + Rgb10a2uint, + #[webidl(rename = "rgb10a2unorm")] + Rgb10a2unorm, + #[webidl(rename = "rg11b10ufloat")] + Rg11b10ufloat, + #[webidl(rename = "rg32uint")] + Rg32uint, + #[webidl(rename = "rg32sint")] + Rg32sint, + #[webidl(rename = "rg32float")] + Rg32float, + #[webidl(rename = "rgba16uint")] + Rgba16uint, + #[webidl(rename = "rgba16sint")] + Rgba16sint, + #[webidl(rename = "rgba16float")] + Rgba16float, + #[webidl(rename = "rgba32uint")] + Rgba32uint, + #[webidl(rename = "rgba32sint")] + Rgba32sint, + #[webidl(rename = "rgba32float")] + Rgba32float, + #[webidl(rename = "stencil8")] + Stencil8, + #[webidl(rename = "depth16unorm")] + Depth16unorm, + #[webidl(rename = "depth24plus")] + Depth24plus, + #[webidl(rename = "depth24plus-stencil8")] + Depth24plusStencil8, + #[webidl(rename = "depth32float")] + Depth32float, + #[webidl(rename = "depth32float-stencil8")] + Depth32floatStencil8, + #[webidl(rename = "bc1-rgba-unorm")] + Bc1RgbaUnorm, + #[webidl(rename = "bc1-rgba-unorm-srgb")] + Bc1RgbaUnormSrgb, + #[webidl(rename = "bc2-rgba-unorm")] + Bc2RgbaUnorm, + #[webidl(rename = "bc2-rgba-unorm-srgb")] + Bc2RgbaUnormSrgb, + #[webidl(rename = "bc3-rgba-unorm")] + Bc3RgbaUnorm, + #[webidl(rename = "bc3-rgba-unorm-srgb")] + Bc3RgbaUnormSrgb, + #[webidl(rename = "bc4-r-unorm")] + Bc4RUnorm, + #[webidl(rename = "bc4-r-snorm")] + Bc4RSnorm, + #[webidl(rename = "bc5-rg-unorm")] + Bc5RgUnorm, + #[webidl(rename = "bc5-rg-snorm")] + Bc5RgSnorm, + #[webidl(rename = "bc6h-rgb-ufloat")] + Bc6hRgbUfloat, + #[webidl(rename = "bc6h-rgb-float")] + Bc6hRgbFloat, + #[webidl(rename = "bc7-rgba-unorm")] + Bc7RgbaUnorm, + #[webidl(rename = "bc7-rgba-unorm-srgb")] + Bc7RgbaUnormSrgb, + #[webidl(rename = "etc2-rgb8unorm")] + Etc2Rgb8unorm, + #[webidl(rename = "etc2-rgb8unorm-srgb")] + Etc2Rgb8unormSrgb, + #[webidl(rename = "etc2-rgb8a1unorm")] + Etc2Rgb8a1unorm, + #[webidl(rename = "etc2-rgb8a1unorm-srgb")] + Etc2Rgb8a1unormSrgb, + #[webidl(rename = "etc2-rgba8unorm")] + Etc2Rgba8unorm, + #[webidl(rename = "etc2-rgba8unorm-srgb")] + Etc2Rgba8unormSrgb, + #[webidl(rename = "eac-r11unorm")] + EacR11unorm, + #[webidl(rename = "eac-r11snorm")] + EacR11snorm, + #[webidl(rename = "eac-rg11unorm")] + EacRg11unorm, + #[webidl(rename = "eac-rg11snorm")] + EacRg11snorm, + #[webidl(rename = "astc-4x4-unorm")] + Astc4x4Unorm, + #[webidl(rename = "astc-4x4-unorm-srgb")] + Astc4x4UnormSrgb, + #[webidl(rename = "astc-5x4-unorm")] + Astc5x4Unorm, + #[webidl(rename = "astc-5x4-unorm-srgb")] + Astc5x4UnormSrgb, + #[webidl(rename = "astc-5x5-unorm")] + Astc5x5Unorm, + #[webidl(rename = "astc-5x5-unorm-srgb")] + Astc5x5UnormSrgb, + #[webidl(rename = "astc-6x5-unorm")] + Astc6x5Unorm, + #[webidl(rename = "astc-6x5-unorm-srgb")] + Astc6x5UnormSrgb, + #[webidl(rename = "astc-6x6-unorm")] + Astc6x6Unorm, + #[webidl(rename = "astc-6x6-unorm-srgb")] + Astc6x6UnormSrgb, + #[webidl(rename = "astc-8x5-unorm")] + Astc8x5Unorm, + #[webidl(rename = "astc-8x5-unorm-srgb")] + Astc8x5UnormSrgb, + #[webidl(rename = "astc-8x6-unorm")] + Astc8x6Unorm, + #[webidl(rename = "astc-8x6-unorm-srgb")] + Astc8x6UnormSrgb, + #[webidl(rename = "astc-8x8-unorm")] + Astc8x8Unorm, + #[webidl(rename = "astc-8x8-unorm-srgb")] + Astc8x8UnormSrgb, + #[webidl(rename = "astc-10x5-unorm")] + Astc10x5Unorm, + #[webidl(rename = "astc-10x5-unorm-srgb")] + Astc10x5UnormSrgb, + #[webidl(rename = "astc-10x6-unorm")] + Astc10x6Unorm, + #[webidl(rename = "astc-10x6-unorm-srgb")] + Astc10x6UnormSrgb, + #[webidl(rename = "astc-10x8-unorm")] + Astc10x8Unorm, + #[webidl(rename = "astc-10x8-unorm-srgb")] + Astc10x8UnormSrgb, + #[webidl(rename = "astc-10x10-unorm")] + Astc10x10Unorm, + #[webidl(rename = "astc-10x10-unorm-srgb")] + Astc10x10UnormSrgb, + #[webidl(rename = "astc-12x10-unorm")] + Astc12x10Unorm, + #[webidl(rename = "astc-12x10-unorm-srgb")] + Astc12x10UnormSrgb, + #[webidl(rename = "astc-12x12-unorm")] + Astc12x12Unorm, + #[webidl(rename = "astc-12x12-unorm-srgb")] + Astc12x12UnormSrgb, } impl From for TextureFormat { - fn from(value: GPUTextureFormat) -> Self { - match value { - GPUTextureFormat::R8unorm => Self::R8Unorm, - GPUTextureFormat::R8snorm => Self::R8Snorm, - GPUTextureFormat::R8uint => Self::R8Uint, - GPUTextureFormat::R8sint => Self::R8Sint, - GPUTextureFormat::R16uint => Self::R16Uint, - GPUTextureFormat::R16sint => Self::R16Sint, - GPUTextureFormat::R16float => Self::R16Float, - GPUTextureFormat::Rg8unorm => Self::Rg8Unorm, - GPUTextureFormat::Rg8snorm => Self::Rg8Snorm, - GPUTextureFormat::Rg8uint => Self::Rg8Uint, - GPUTextureFormat::Rg8sint => Self::Rg8Sint, - GPUTextureFormat::R32uint => Self::R32Uint, - GPUTextureFormat::R32sint => Self::R32Sint, - GPUTextureFormat::R32float => Self::R32Float, - GPUTextureFormat::Rg16uint => Self::Rg16Uint, - GPUTextureFormat::Rg16sint => Self::Rg16Sint, - GPUTextureFormat::Rg16float => Self::Rg16Float, - GPUTextureFormat::Rgba8unorm => Self::Rgba8Unorm, - GPUTextureFormat::Rgba8unormSrgb => Self::Rgba8UnormSrgb, - GPUTextureFormat::Rgba8snorm => Self::Rgba8Snorm, - GPUTextureFormat::Rgba8uint => Self::Rgba8Uint, - GPUTextureFormat::Rgba8sint => Self::Rgba8Sint, - GPUTextureFormat::Bgra8unorm => Self::Bgra8Unorm, - GPUTextureFormat::Bgra8unormSrgb => Self::Bgra8UnormSrgb, - GPUTextureFormat::Rgb9e5ufloat => Self::Rgb9e5Ufloat, - GPUTextureFormat::Rgb10a2uint => Self::Rgb10a2Uint, - GPUTextureFormat::Rgb10a2unorm => Self::Rgb10a2Unorm, - GPUTextureFormat::Rg11b10ufloat => Self::Rg11b10Ufloat, - GPUTextureFormat::Rg32uint => Self::Rg32Uint, - GPUTextureFormat::Rg32sint => Self::Rg32Sint, - GPUTextureFormat::Rg32float => Self::Rg32Float, - GPUTextureFormat::Rgba16uint => Self::Rgba16Uint, - GPUTextureFormat::Rgba16sint => Self::Rgba16Sint, - GPUTextureFormat::Rgba16float => Self::Rgba16Float, - GPUTextureFormat::Rgba32uint => Self::Rgba32Uint, - GPUTextureFormat::Rgba32sint => Self::Rgba32Sint, - GPUTextureFormat::Rgba32float => Self::Rgba32Float, - GPUTextureFormat::Stencil8 => Self::Stencil8, - GPUTextureFormat::Depth16unorm => Self::Depth16Unorm, - GPUTextureFormat::Depth24plus => Self::Depth24Plus, - GPUTextureFormat::Depth24plusStencil8 => Self::Depth24PlusStencil8, - GPUTextureFormat::Depth32float => Self::Depth32Float, - GPUTextureFormat::Depth32floatStencil8 => Self::Depth32FloatStencil8, - GPUTextureFormat::Bc1RgbaUnorm => Self::Bc1RgbaUnorm, - GPUTextureFormat::Bc1RgbaUnormSrgb => Self::Bc1RgbaUnormSrgb, - GPUTextureFormat::Bc2RgbaUnorm => Self::Bc2RgbaUnorm, - GPUTextureFormat::Bc2RgbaUnormSrgb => Self::Bc2RgbaUnormSrgb, - GPUTextureFormat::Bc3RgbaUnorm => Self::Bc3RgbaUnorm, - GPUTextureFormat::Bc3RgbaUnormSrgb => Self::Bc3RgbaUnormSrgb, - GPUTextureFormat::Bc4RUnorm => Self::Bc4RUnorm, - GPUTextureFormat::Bc4RSnorm => Self::Bc4RSnorm, - GPUTextureFormat::Bc5RgUnorm => Self::Bc5RgUnorm, - GPUTextureFormat::Bc5RgSnorm => Self::Bc5RgSnorm, - GPUTextureFormat::Bc6hRgbUfloat => Self::Bc6hRgbUfloat, - GPUTextureFormat::Bc6hRgbFloat => Self::Bc6hRgbFloat, - GPUTextureFormat::Bc7RgbaUnorm => Self::Bc7RgbaUnorm, - GPUTextureFormat::Bc7RgbaUnormSrgb => Self::Bc7RgbaUnormSrgb, - GPUTextureFormat::Etc2Rgb8unorm => Self::Etc2Rgb8Unorm, - GPUTextureFormat::Etc2Rgb8unormSrgb => Self::Etc2Rgb8UnormSrgb, - GPUTextureFormat::Etc2Rgb8a1unorm => Self::Etc2Rgb8A1Unorm, - GPUTextureFormat::Etc2Rgb8a1unormSrgb => Self::Etc2Rgb8A1UnormSrgb, - GPUTextureFormat::Etc2Rgba8unorm => Self::Etc2Rgba8Unorm, - GPUTextureFormat::Etc2Rgba8unormSrgb => Self::Etc2Rgba8UnormSrgb, - GPUTextureFormat::EacR11unorm => Self::EacR11Unorm, - GPUTextureFormat::EacR11snorm => Self::EacR11Snorm, - GPUTextureFormat::EacRg11unorm => Self::EacRg11Unorm, - GPUTextureFormat::EacRg11snorm => Self::EacRg11Snorm, - GPUTextureFormat::Astc4x4Unorm => Self::Astc { - block: AstcBlock::B4x4, - channel: AstcChannel::Unorm, - }, - GPUTextureFormat::Astc4x4UnormSrgb => Self::Astc { - block: AstcBlock::B4x4, - channel: AstcChannel::UnormSrgb, - }, - GPUTextureFormat::Astc5x4Unorm => Self::Astc { - block: AstcBlock::B5x4, - channel: AstcChannel::Unorm, - }, - GPUTextureFormat::Astc5x4UnormSrgb => Self::Astc { - block: AstcBlock::B5x4, - channel: AstcChannel::UnormSrgb, - }, - GPUTextureFormat::Astc5x5Unorm => Self::Astc { - block: AstcBlock::B5x5, - channel: AstcChannel::Unorm, - }, - GPUTextureFormat::Astc5x5UnormSrgb => Self::Astc { - block: AstcBlock::B5x5, - channel: AstcChannel::UnormSrgb, - }, - GPUTextureFormat::Astc6x5Unorm => Self::Astc { - block: AstcBlock::B6x5, - channel: AstcChannel::Unorm, - }, - GPUTextureFormat::Astc6x5UnormSrgb => Self::Astc { - block: AstcBlock::B6x5, - channel: AstcChannel::UnormSrgb, - }, - GPUTextureFormat::Astc6x6Unorm => Self::Astc { - block: AstcBlock::B6x6, - channel: AstcChannel::Unorm, - }, - GPUTextureFormat::Astc6x6UnormSrgb => Self::Astc { - block: AstcBlock::B6x6, - channel: AstcChannel::UnormSrgb, - }, - GPUTextureFormat::Astc8x5Unorm => Self::Astc { - block: AstcBlock::B8x5, - channel: AstcChannel::Unorm, - }, - GPUTextureFormat::Astc8x5UnormSrgb => Self::Astc { - block: AstcBlock::B8x5, - channel: AstcChannel::UnormSrgb, - }, - GPUTextureFormat::Astc8x6Unorm => Self::Astc { - block: AstcBlock::B8x6, - channel: AstcChannel::Unorm, - }, - GPUTextureFormat::Astc8x6UnormSrgb => Self::Astc { - block: AstcBlock::B8x6, - channel: AstcChannel::UnormSrgb, - }, - GPUTextureFormat::Astc8x8Unorm => Self::Astc { - block: AstcBlock::B8x8, - channel: AstcChannel::Unorm, - }, - GPUTextureFormat::Astc8x8UnormSrgb => Self::Astc { - block: AstcBlock::B8x8, - channel: AstcChannel::UnormSrgb, - }, - GPUTextureFormat::Astc10x5Unorm => Self::Astc { - block: AstcBlock::B10x5, - channel: AstcChannel::Unorm, - }, - GPUTextureFormat::Astc10x5UnormSrgb => Self::Astc { - block: AstcBlock::B10x5, - channel: AstcChannel::UnormSrgb, - }, - GPUTextureFormat::Astc10x6Unorm => Self::Astc { - block: AstcBlock::B10x6, - channel: AstcChannel::Unorm, - }, - GPUTextureFormat::Astc10x6UnormSrgb => Self::Astc { - block: AstcBlock::B10x6, - channel: AstcChannel::UnormSrgb, - }, - GPUTextureFormat::Astc10x8Unorm => Self::Astc { - block: AstcBlock::B10x8, - channel: AstcChannel::Unorm, - }, - GPUTextureFormat::Astc10x8UnormSrgb => Self::Astc { - block: AstcBlock::B10x8, - channel: AstcChannel::UnormSrgb, - }, - GPUTextureFormat::Astc10x10Unorm => Self::Astc { - block: AstcBlock::B10x10, - channel: AstcChannel::Unorm, - }, - GPUTextureFormat::Astc10x10UnormSrgb => Self::Astc { - block: AstcBlock::B10x10, - channel: AstcChannel::UnormSrgb, - }, - GPUTextureFormat::Astc12x10Unorm => Self::Astc { - block: AstcBlock::B12x10, - channel: AstcChannel::Unorm, - }, - GPUTextureFormat::Astc12x10UnormSrgb => Self::Astc { - block: AstcBlock::B12x10, - channel: AstcChannel::UnormSrgb, - }, - GPUTextureFormat::Astc12x12Unorm => Self::Astc { - block: AstcBlock::B12x12, - channel: AstcChannel::Unorm, - }, - GPUTextureFormat::Astc12x12UnormSrgb => Self::Astc { - block: AstcBlock::B12x12, - channel: AstcChannel::UnormSrgb, - }, - } + fn from(value: GPUTextureFormat) -> Self { + match value { + GPUTextureFormat::R8unorm => Self::R8Unorm, + GPUTextureFormat::R8snorm => Self::R8Snorm, + GPUTextureFormat::R8uint => Self::R8Uint, + GPUTextureFormat::R8sint => Self::R8Sint, + GPUTextureFormat::R16uint => Self::R16Uint, + GPUTextureFormat::R16sint => Self::R16Sint, + GPUTextureFormat::R16float => Self::R16Float, + GPUTextureFormat::Rg8unorm => Self::Rg8Unorm, + GPUTextureFormat::Rg8snorm => Self::Rg8Snorm, + GPUTextureFormat::Rg8uint => Self::Rg8Uint, + GPUTextureFormat::Rg8sint => Self::Rg8Sint, + GPUTextureFormat::R32uint => Self::R32Uint, + GPUTextureFormat::R32sint => Self::R32Sint, + GPUTextureFormat::R32float => Self::R32Float, + GPUTextureFormat::Rg16uint => Self::Rg16Uint, + GPUTextureFormat::Rg16sint => Self::Rg16Sint, + GPUTextureFormat::Rg16float => Self::Rg16Float, + GPUTextureFormat::Rgba8unorm => Self::Rgba8Unorm, + GPUTextureFormat::Rgba8unormSrgb => Self::Rgba8UnormSrgb, + GPUTextureFormat::Rgba8snorm => Self::Rgba8Snorm, + GPUTextureFormat::Rgba8uint => Self::Rgba8Uint, + GPUTextureFormat::Rgba8sint => Self::Rgba8Sint, + GPUTextureFormat::Bgra8unorm => Self::Bgra8Unorm, + GPUTextureFormat::Bgra8unormSrgb => Self::Bgra8UnormSrgb, + GPUTextureFormat::Rgb9e5ufloat => Self::Rgb9e5Ufloat, + GPUTextureFormat::Rgb10a2uint => Self::Rgb10a2Uint, + GPUTextureFormat::Rgb10a2unorm => Self::Rgb10a2Unorm, + GPUTextureFormat::Rg11b10ufloat => Self::Rg11b10Ufloat, + GPUTextureFormat::Rg32uint => Self::Rg32Uint, + GPUTextureFormat::Rg32sint => Self::Rg32Sint, + GPUTextureFormat::Rg32float => Self::Rg32Float, + GPUTextureFormat::Rgba16uint => Self::Rgba16Uint, + GPUTextureFormat::Rgba16sint => Self::Rgba16Sint, + GPUTextureFormat::Rgba16float => Self::Rgba16Float, + GPUTextureFormat::Rgba32uint => Self::Rgba32Uint, + GPUTextureFormat::Rgba32sint => Self::Rgba32Sint, + GPUTextureFormat::Rgba32float => Self::Rgba32Float, + GPUTextureFormat::Stencil8 => Self::Stencil8, + GPUTextureFormat::Depth16unorm => Self::Depth16Unorm, + GPUTextureFormat::Depth24plus => Self::Depth24Plus, + GPUTextureFormat::Depth24plusStencil8 => Self::Depth24PlusStencil8, + GPUTextureFormat::Depth32float => Self::Depth32Float, + GPUTextureFormat::Depth32floatStencil8 => Self::Depth32FloatStencil8, + GPUTextureFormat::Bc1RgbaUnorm => Self::Bc1RgbaUnorm, + GPUTextureFormat::Bc1RgbaUnormSrgb => Self::Bc1RgbaUnormSrgb, + GPUTextureFormat::Bc2RgbaUnorm => Self::Bc2RgbaUnorm, + GPUTextureFormat::Bc2RgbaUnormSrgb => Self::Bc2RgbaUnormSrgb, + GPUTextureFormat::Bc3RgbaUnorm => Self::Bc3RgbaUnorm, + GPUTextureFormat::Bc3RgbaUnormSrgb => Self::Bc3RgbaUnormSrgb, + GPUTextureFormat::Bc4RUnorm => Self::Bc4RUnorm, + GPUTextureFormat::Bc4RSnorm => Self::Bc4RSnorm, + GPUTextureFormat::Bc5RgUnorm => Self::Bc5RgUnorm, + GPUTextureFormat::Bc5RgSnorm => Self::Bc5RgSnorm, + GPUTextureFormat::Bc6hRgbUfloat => Self::Bc6hRgbUfloat, + GPUTextureFormat::Bc6hRgbFloat => Self::Bc6hRgbFloat, + GPUTextureFormat::Bc7RgbaUnorm => Self::Bc7RgbaUnorm, + GPUTextureFormat::Bc7RgbaUnormSrgb => Self::Bc7RgbaUnormSrgb, + GPUTextureFormat::Etc2Rgb8unorm => Self::Etc2Rgb8Unorm, + GPUTextureFormat::Etc2Rgb8unormSrgb => Self::Etc2Rgb8UnormSrgb, + GPUTextureFormat::Etc2Rgb8a1unorm => Self::Etc2Rgb8A1Unorm, + GPUTextureFormat::Etc2Rgb8a1unormSrgb => Self::Etc2Rgb8A1UnormSrgb, + GPUTextureFormat::Etc2Rgba8unorm => Self::Etc2Rgba8Unorm, + GPUTextureFormat::Etc2Rgba8unormSrgb => Self::Etc2Rgba8UnormSrgb, + GPUTextureFormat::EacR11unorm => Self::EacR11Unorm, + GPUTextureFormat::EacR11snorm => Self::EacR11Snorm, + GPUTextureFormat::EacRg11unorm => Self::EacRg11Unorm, + GPUTextureFormat::EacRg11snorm => Self::EacRg11Snorm, + GPUTextureFormat::Astc4x4Unorm => Self::Astc { + block: AstcBlock::B4x4, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc4x4UnormSrgb => Self::Astc { + block: AstcBlock::B4x4, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc5x4Unorm => Self::Astc { + block: AstcBlock::B5x4, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc5x4UnormSrgb => Self::Astc { + block: AstcBlock::B5x4, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc5x5Unorm => Self::Astc { + block: AstcBlock::B5x5, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc5x5UnormSrgb => Self::Astc { + block: AstcBlock::B5x5, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc6x5Unorm => Self::Astc { + block: AstcBlock::B6x5, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc6x5UnormSrgb => Self::Astc { + block: AstcBlock::B6x5, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc6x6Unorm => Self::Astc { + block: AstcBlock::B6x6, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc6x6UnormSrgb => Self::Astc { + block: AstcBlock::B6x6, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc8x5Unorm => Self::Astc { + block: AstcBlock::B8x5, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc8x5UnormSrgb => Self::Astc { + block: AstcBlock::B8x5, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc8x6Unorm => Self::Astc { + block: AstcBlock::B8x6, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc8x6UnormSrgb => Self::Astc { + block: AstcBlock::B8x6, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc8x8Unorm => Self::Astc { + block: AstcBlock::B8x8, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc8x8UnormSrgb => Self::Astc { + block: AstcBlock::B8x8, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc10x5Unorm => Self::Astc { + block: AstcBlock::B10x5, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc10x5UnormSrgb => Self::Astc { + block: AstcBlock::B10x5, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc10x6Unorm => Self::Astc { + block: AstcBlock::B10x6, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc10x6UnormSrgb => Self::Astc { + block: AstcBlock::B10x6, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc10x8Unorm => Self::Astc { + block: AstcBlock::B10x8, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc10x8UnormSrgb => Self::Astc { + block: AstcBlock::B10x8, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc10x10Unorm => Self::Astc { + block: AstcBlock::B10x10, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc10x10UnormSrgb => Self::Astc { + block: AstcBlock::B10x10, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc12x10Unorm => Self::Astc { + block: AstcBlock::B12x10, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc12x10UnormSrgb => Self::Astc { + block: AstcBlock::B12x10, + channel: AstcChannel::UnormSrgb, + }, + GPUTextureFormat::Astc12x12Unorm => Self::Astc { + block: AstcBlock::B12x12, + channel: AstcChannel::Unorm, + }, + GPUTextureFormat::Astc12x12UnormSrgb => Self::Astc { + block: AstcBlock::B12x12, + channel: AstcChannel::UnormSrgb, + }, } + } } pub struct GPUExternalTexture {} impl WebIdlInterfaceConverter for GPUExternalTexture { - const NAME: &'static str = "GPUExternalTexture"; + const NAME: &'static str = "GPUExternalTexture"; } impl GarbageCollected for GPUExternalTexture {} diff --git a/deno_webgpu/webidl.rs b/deno_webgpu/webidl.rs index 2f521f47f23..0322dcfe419 100644 --- a/deno_webgpu/webidl.rs +++ b/deno_webgpu/webidl.rs @@ -17,428 +17,459 @@ use deno_error::JsErrorBox; #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUExtent3DDict { - #[options(enforce_range = true)] - width: u32, - #[webidl(default = 1)] - #[options(enforce_range = true)] - height: u32, - #[webidl(default = 1)] - #[options(enforce_range = true)] - depth_or_array_layers: u32, + #[options(enforce_range = true)] + width: u32, + #[webidl(default = 1)] + #[options(enforce_range = true)] + height: u32, + #[webidl(default = 1)] + #[options(enforce_range = true)] + depth_or_array_layers: u32, } pub(crate) enum GPUExtent3D { - Dict(GPUExtent3DDict), - Sequence((u32, u32, u32)), + Dict(GPUExtent3DDict), + Sequence((u32, u32, u32)), } impl<'a> WebIdlConverter<'a> for GPUExtent3D { - type Options = (); - - fn convert<'b>( - scope: &mut v8::HandleScope<'a>, - value: v8::Local<'a, v8::Value>, - prefix: Cow<'static, str>, - context: ContextFn<'b>, - options: &Self::Options, - ) -> Result { - if value.is_null_or_undefined() { - return Ok(GPUExtent3D::Dict(GPUExtent3DDict::convert( - scope, - value, - prefix, - context.borrowed(), - options, - )?)); - } - if let Ok(obj) = value.try_cast::() { - let iter = v8::Symbol::get_iterator(scope); - if let Some(iter) = obj.get(scope, iter.into()) { - if !iter.is_undefined() { - let conv = >::convert( - scope, - value, - prefix.clone(), - context.borrowed(), - &IntOptions { - clamp: false, - enforce_range: true, - }, - )?; - if conv.is_empty() || conv.len() > 3 { - return Err(WebIdlError::other(prefix, context, JsErrorBox::type_error(format!("A sequence of number used as a GPUExtent3D must have between 1 and 3 elements, received {} elements", conv.len())))); - } - - let mut iter = conv.into_iter(); - return Ok(GPUExtent3D::Sequence(( - iter.next().unwrap(), - iter.next().unwrap_or(1), - iter.next().unwrap_or(1), - ))); - } - } - - return Ok(GPUExtent3D::Dict(GPUExtent3DDict::convert( - scope, value, prefix, context, options, - )?)); + type Options = (); + + fn convert<'b>( + scope: &mut v8::HandleScope<'a>, + value: v8::Local<'a, v8::Value>, + prefix: Cow<'static, str>, + context: ContextFn<'b>, + options: &Self::Options, + ) -> Result { + if value.is_null_or_undefined() { + return Ok(GPUExtent3D::Dict(GPUExtent3DDict::convert( + scope, + value, + prefix, + context.borrowed(), + options, + )?)); + } + if let Ok(obj) = value.try_cast::() { + let iter = v8::Symbol::get_iterator(scope); + if let Some(iter) = obj.get(scope, iter.into()) { + if !iter.is_undefined() { + let conv = >::convert( + scope, + value, + prefix.clone(), + context.borrowed(), + &IntOptions { + clamp: false, + enforce_range: true, + }, + )?; + if conv.is_empty() || conv.len() > 3 { + return Err(WebIdlError::other( + prefix, + context, + JsErrorBox::type_error(format!( + "A sequence of number used as a GPUExtent3D must have between 1 and 3 elements, received {} elements", + conv.len() + )), + )); + } + + let mut iter = conv.into_iter(); + return Ok(GPUExtent3D::Sequence(( + iter.next().unwrap(), + iter.next().unwrap_or(1), + iter.next().unwrap_or(1), + ))); } + } - Err(WebIdlError::new( - prefix, - context, - WebIdlErrorKind::ConvertToConverterType( - "sequence or GPUExtent3DDict", - ), - )) + return Ok(GPUExtent3D::Dict(GPUExtent3DDict::convert( + scope, value, prefix, context, options, + )?)); } + + Err(WebIdlError::new( + prefix, + context, + WebIdlErrorKind::ConvertToConverterType( + "sequence or GPUExtent3DDict", + ), + )) + } } impl From for wgpu_types::Extent3d { - fn from(value: GPUExtent3D) -> Self { - match value { - GPUExtent3D::Dict(dict) => Self { - width: dict.width, - height: dict.height, - depth_or_array_layers: dict.depth_or_array_layers, - }, - GPUExtent3D::Sequence((width, height, depth)) => Self { - width, - height, - depth_or_array_layers: depth, - }, - } - } + fn from(value: GPUExtent3D) -> Self { + match value { + GPUExtent3D::Dict(dict) => Self { + width: dict.width, + height: dict.height, + depth_or_array_layers: dict.depth_or_array_layers, + }, + GPUExtent3D::Sequence((width, height, depth)) => Self { + width, + height, + depth_or_array_layers: depth, + }, + } + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUOrigin3DDict { - #[webidl(default = 0)] - #[options(enforce_range = true)] - x: u32, - #[webidl(default = 0)] - #[options(enforce_range = true)] - y: u32, - #[webidl(default = 0)] - #[options(enforce_range = true)] - z: u32, + #[webidl(default = 0)] + #[options(enforce_range = true)] + x: u32, + #[webidl(default = 0)] + #[options(enforce_range = true)] + y: u32, + #[webidl(default = 0)] + #[options(enforce_range = true)] + z: u32, } pub(crate) enum GPUOrigin3D { - Dict(GPUOrigin3DDict), - Sequence((u32, u32, u32)), + Dict(GPUOrigin3DDict), + Sequence((u32, u32, u32)), } impl Default for GPUOrigin3D { - fn default() -> Self { - GPUOrigin3D::Sequence((0, 0, 0)) - } + fn default() -> Self { + GPUOrigin3D::Sequence((0, 0, 0)) + } } impl<'a> WebIdlConverter<'a> for GPUOrigin3D { - type Options = (); - - fn convert<'b>( - scope: &mut v8::HandleScope<'a>, - value: v8::Local<'a, v8::Value>, - prefix: Cow<'static, str>, - context: ContextFn<'b>, - options: &Self::Options, - ) -> Result { - if value.is_null_or_undefined() { - return Ok(GPUOrigin3D::Dict(GPUOrigin3DDict::convert( - scope, - value, - prefix, - context.borrowed(), - options, - )?)); - } - if let Ok(obj) = value.try_cast::() { - let iter = v8::Symbol::get_iterator(scope); - if let Some(iter) = obj.get(scope, iter.into()) { - if !iter.is_undefined() { - let conv = >::convert( - scope, - value, - prefix.clone(), - context.borrowed(), - &IntOptions { - clamp: false, - enforce_range: true, - }, - )?; - if conv.len() > 3 { - return Err(WebIdlError::other(prefix, context, JsErrorBox::type_error(format!("A sequence of number used as a GPUOrigin3D must have at most 3 elements, received {} elements", conv.len())))); - } - - let mut iter = conv.into_iter(); - return Ok(GPUOrigin3D::Sequence(( - iter.next().unwrap_or(0), - iter.next().unwrap_or(0), - iter.next().unwrap_or(0), - ))); - } - } - - return Ok(GPUOrigin3D::Dict(GPUOrigin3DDict::convert( - scope, value, prefix, context, options, - )?)); + type Options = (); + + fn convert<'b>( + scope: &mut v8::HandleScope<'a>, + value: v8::Local<'a, v8::Value>, + prefix: Cow<'static, str>, + context: ContextFn<'b>, + options: &Self::Options, + ) -> Result { + if value.is_null_or_undefined() { + return Ok(GPUOrigin3D::Dict(GPUOrigin3DDict::convert( + scope, + value, + prefix, + context.borrowed(), + options, + )?)); + } + if let Ok(obj) = value.try_cast::() { + let iter = v8::Symbol::get_iterator(scope); + if let Some(iter) = obj.get(scope, iter.into()) { + if !iter.is_undefined() { + let conv = >::convert( + scope, + value, + prefix.clone(), + context.borrowed(), + &IntOptions { + clamp: false, + enforce_range: true, + }, + )?; + if conv.len() > 3 { + return Err(WebIdlError::other( + prefix, + context, + JsErrorBox::type_error(format!( + "A sequence of number used as a GPUOrigin3D must have at most 3 elements, received {} elements", + conv.len() + )), + )); + } + + let mut iter = conv.into_iter(); + return Ok(GPUOrigin3D::Sequence(( + iter.next().unwrap_or(0), + iter.next().unwrap_or(0), + iter.next().unwrap_or(0), + ))); } + } - Err(WebIdlError::new( - prefix, - context, - WebIdlErrorKind::ConvertToConverterType( - "sequence or GPUOrigin3DDict", - ), - )) + return Ok(GPUOrigin3D::Dict(GPUOrigin3DDict::convert( + scope, value, prefix, context, options, + )?)); } + + Err(WebIdlError::new( + prefix, + context, + WebIdlErrorKind::ConvertToConverterType( + "sequence or GPUOrigin3DDict", + ), + )) + } } impl From for wgpu_types::Origin3d { - fn from(value: GPUOrigin3D) -> Self { - match value { - GPUOrigin3D::Dict(dict) => Self { - x: dict.x, - y: dict.y, - z: dict.z, - }, - GPUOrigin3D::Sequence((x, y, z)) => Self { x, y, z }, - } - } + fn from(value: GPUOrigin3D) -> Self { + match value { + GPUOrigin3D::Dict(dict) => Self { + x: dict.x, + y: dict.y, + z: dict.z, + }, + GPUOrigin3D::Sequence((x, y, z)) => Self { x, y, z }, + } + } } #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPUColorDict { - r: f64, - g: f64, - b: f64, - a: f64, + r: f64, + g: f64, + b: f64, + a: f64, } pub(crate) enum GPUColor { - Dict(GPUColorDict), - Sequence((f64, f64, f64, f64)), + Dict(GPUColorDict), + Sequence((f64, f64, f64, f64)), } impl<'a> WebIdlConverter<'a> for GPUColor { - type Options = (); - - fn convert<'b>( - scope: &mut v8::HandleScope<'a>, - value: v8::Local<'a, v8::Value>, - prefix: Cow<'static, str>, - context: ContextFn<'b>, - options: &Self::Options, - ) -> Result { - if value.is_null_or_undefined() { - return Ok(GPUColor::Dict(GPUColorDict::convert( - scope, - value, - prefix, - context.borrowed(), - options, - )?)); - } - if let Ok(obj) = value.try_cast::() { - let iter = v8::Symbol::get_iterator(scope); - if let Some(iter) = obj.get(scope, iter.into()) { - if !iter.is_undefined() { - let conv = >::convert( - scope, - value, - prefix.clone(), - context.borrowed(), - options, - )?; - if conv.len() != 4 { - return Err(WebIdlError::other(prefix, context, JsErrorBox::type_error(format!("A sequence of number used as a GPUColor must have exactly 4 elements, received {} elements", conv.len())))); - } - - let mut iter = conv.into_iter(); - return Ok(GPUColor::Sequence(( - iter.next().unwrap(), - iter.next().unwrap(), - iter.next().unwrap(), - iter.next().unwrap(), - ))); - } - } - - return Ok(GPUColor::Dict(GPUColorDict::convert( - scope, value, prefix, context, options, - )?)); + type Options = (); + + fn convert<'b>( + scope: &mut v8::HandleScope<'a>, + value: v8::Local<'a, v8::Value>, + prefix: Cow<'static, str>, + context: ContextFn<'b>, + options: &Self::Options, + ) -> Result { + if value.is_null_or_undefined() { + return Ok(GPUColor::Dict(GPUColorDict::convert( + scope, + value, + prefix, + context.borrowed(), + options, + )?)); + } + if let Ok(obj) = value.try_cast::() { + let iter = v8::Symbol::get_iterator(scope); + if let Some(iter) = obj.get(scope, iter.into()) { + if !iter.is_undefined() { + let conv = >::convert( + scope, + value, + prefix.clone(), + context.borrowed(), + options, + )?; + if conv.len() != 4 { + return Err(WebIdlError::other( + prefix, + context, + JsErrorBox::type_error(format!( + "A sequence of number used as a GPUColor must have exactly 4 elements, received {} elements", + conv.len() + )), + )); + } + + let mut iter = conv.into_iter(); + return Ok(GPUColor::Sequence(( + iter.next().unwrap(), + iter.next().unwrap(), + iter.next().unwrap(), + iter.next().unwrap(), + ))); } + } - Err(WebIdlError::new( - prefix, - context, - WebIdlErrorKind::ConvertToConverterType( - "sequence or GPUOrigin3DDict", - ), - )) + return Ok(GPUColor::Dict(GPUColorDict::convert( + scope, value, prefix, context, options, + )?)); } + + Err(WebIdlError::new( + prefix, + context, + WebIdlErrorKind::ConvertToConverterType( + "sequence or GPUOrigin3DDict", + ), + )) + } } impl From for wgpu_types::Color { - fn from(value: GPUColor) -> Self { - match value { - GPUColor::Dict(dict) => Self { - r: dict.r, - g: dict.g, - b: dict.b, - a: dict.a, - }, - GPUColor::Sequence((r, g, b, a)) => Self { r, g, b, a }, - } - } + fn from(value: GPUColor) -> Self { + match value { + GPUColor::Dict(dict) => Self { + r: dict.r, + g: dict.g, + b: dict.b, + a: dict.a, + }, + GPUColor::Sequence((r, g, b, a)) => Self { r, g, b, a }, + } + } } #[derive(WebIDL)] #[webidl(enum)] pub(crate) enum GPUAutoLayoutMode { - Auto, + Auto, } pub(crate) enum GPUPipelineLayoutOrGPUAutoLayoutMode { - PipelineLayout(Ptr), - AutoLayoutMode(GPUAutoLayoutMode), + PipelineLayout(Ptr), + AutoLayoutMode(GPUAutoLayoutMode), } -impl From for Option { - fn from(value: GPUPipelineLayoutOrGPUAutoLayoutMode) -> Self { - match value { - GPUPipelineLayoutOrGPUAutoLayoutMode::PipelineLayout(layout) => Some(layout.id), - GPUPipelineLayoutOrGPUAutoLayoutMode::AutoLayoutMode(GPUAutoLayoutMode::Auto) => None, - } - } +impl From + for Option +{ + fn from(value: GPUPipelineLayoutOrGPUAutoLayoutMode) -> Self { + match value { + GPUPipelineLayoutOrGPUAutoLayoutMode::PipelineLayout(layout) => { + Some(layout.id) + } + GPUPipelineLayoutOrGPUAutoLayoutMode::AutoLayoutMode( + GPUAutoLayoutMode::Auto, + ) => None, + } + } } impl<'a> WebIdlConverter<'a> for GPUPipelineLayoutOrGPUAutoLayoutMode { - type Options = (); - - fn convert<'b>( - scope: &mut v8::HandleScope<'a>, - value: v8::Local<'a, v8::Value>, - prefix: Cow<'static, str>, - context: ContextFn<'b>, - options: &Self::Options, - ) -> Result { - if value.is_object() { - Ok(Self::PipelineLayout(WebIdlConverter::convert( - scope, value, prefix, context, options, - )?)) - } else { - Ok(Self::AutoLayoutMode(WebIdlConverter::convert( - scope, value, prefix, context, options, - )?)) - } - } + type Options = (); + + fn convert<'b>( + scope: &mut v8::HandleScope<'a>, + value: v8::Local<'a, v8::Value>, + prefix: Cow<'static, str>, + context: ContextFn<'b>, + options: &Self::Options, + ) -> Result { + if value.is_object() { + Ok(Self::PipelineLayout(WebIdlConverter::convert( + scope, value, prefix, context, options, + )?)) + } else { + Ok(Self::AutoLayoutMode(WebIdlConverter::convert( + scope, value, prefix, context, options, + )?)) + } + } } #[derive(WebIDL, Clone, Hash, Eq, PartialEq)] #[webidl(enum)] pub enum GPUFeatureName { - #[webidl(rename = "depth-clip-control")] - DepthClipControl, - #[webidl(rename = "timestamp-query")] - TimestampQuery, - #[webidl(rename = "indirect-first-instance")] - IndirectFirstInstance, - #[webidl(rename = "shader-f16")] - ShaderF16, - #[webidl(rename = "depth32float-stencil8")] - Depth32floatStencil8, - #[webidl(rename = "texture-compression-bc")] - TextureCompressionBc, - #[webidl(rename = "texture-compression-bc-sliced-3d")] - TextureCompressionBcSliced3d, - #[webidl(rename = "texture-compression-etc2")] - TextureCompressionEtc2, - #[webidl(rename = "texture-compression-astc")] - TextureCompressionAstc, - #[webidl(rename = "texture-compression-astc-sliced-3d")] - TextureCompressionAstcSliced3d, - #[webidl(rename = "rg11b10ufloat-renderable")] - Rg11b10ufloatRenderable, - #[webidl(rename = "bgra8unorm-storage")] - Bgra8unormStorage, - #[webidl(rename = "float32-filterable")] - Float32Filterable, - #[webidl(rename = "dual-source-blending")] - DualSourceBlending, - #[webidl(rename = "subgroups")] - Subgroups, - - // extended from spec - #[webidl(rename = "texture-format-16-bit-norm")] - TextureFormat16BitNorm, - #[webidl(rename = "texture-compression-astc-hdr")] - TextureCompressionAstcHdr, - #[webidl(rename = "texture-adapter-specific-format-features")] - TextureAdapterSpecificFormatFeatures, - #[webidl(rename = "pipeline-statistics-query")] - PipelineStatisticsQuery, - #[webidl(rename = "timestamp-query-inside-passes")] - TimestampQueryInsidePasses, - #[webidl(rename = "mappable-primary-buffers")] - MappablePrimaryBuffers, - #[webidl(rename = "texture-binding-array")] - TextureBindingArray, - #[webidl(rename = "buffer-binding-array")] - BufferBindingArray, - #[webidl(rename = "storage-resource-binding-array")] - StorageResourceBindingArray, - #[webidl(rename = "sampled-texture-and-storage-buffer-array-non-uniform-indexing")] - SampledTextureAndStorageBufferArrayNonUniformIndexing, - #[webidl(rename = "storage-texture-array-non-uniform-indexing")] - StorageTextureArrayNonUniformIndexing, - #[webidl(rename = "uniform-buffer-binding-arrays")] - UniformBufferBindingArrays, - #[webidl(rename = "partially-bound-binding-array")] - PartiallyBoundBindingArray, - #[webidl(rename = "multi-draw-indirect-count")] - MultiDrawIndirectCount, - #[webidl(rename = "push-constants")] - PushConstants, - #[webidl(rename = "address-mode-clamp-to-zero")] - AddressModeClampToZero, - #[webidl(rename = "address-mode-clamp-to-border")] - AddressModeClampToBorder, - #[webidl(rename = "polygon-mode-line")] - PolygonModeLine, - #[webidl(rename = "polygon-mode-point")] - PolygonModePoint, - #[webidl(rename = "conservative-rasterization")] - ConservativeRasterization, - #[webidl(rename = "vertex-writable-storage")] - VertexWritableStorage, - #[webidl(rename = "clear-texture")] - ClearTexture, - #[webidl(rename = "multiview")] - Multiview, - #[webidl(rename = "vertex-attribute-64-bit")] - VertexAttribute64Bit, - #[webidl(rename = "shader-f64")] - ShaderF64, - #[webidl(rename = "shader-i16")] - ShaderI16, - #[webidl(rename = "shader-primitive-index")] - ShaderPrimitiveIndex, - #[webidl(rename = "shader-early-depth-test")] - ShaderEarlyDepthTest, - #[webidl(rename = "passthrough-shaders")] - PassthroughShaders, + #[webidl(rename = "depth-clip-control")] + DepthClipControl, + #[webidl(rename = "timestamp-query")] + TimestampQuery, + #[webidl(rename = "indirect-first-instance")] + IndirectFirstInstance, + #[webidl(rename = "shader-f16")] + ShaderF16, + #[webidl(rename = "depth32float-stencil8")] + Depth32floatStencil8, + #[webidl(rename = "texture-compression-bc")] + TextureCompressionBc, + #[webidl(rename = "texture-compression-bc-sliced-3d")] + TextureCompressionBcSliced3d, + #[webidl(rename = "texture-compression-etc2")] + TextureCompressionEtc2, + #[webidl(rename = "texture-compression-astc")] + TextureCompressionAstc, + #[webidl(rename = "texture-compression-astc-sliced-3d")] + TextureCompressionAstcSliced3d, + #[webidl(rename = "rg11b10ufloat-renderable")] + Rg11b10ufloatRenderable, + #[webidl(rename = "bgra8unorm-storage")] + Bgra8unormStorage, + #[webidl(rename = "float32-filterable")] + Float32Filterable, + #[webidl(rename = "dual-source-blending")] + DualSourceBlending, + #[webidl(rename = "subgroups")] + Subgroups, + + // extended from spec + #[webidl(rename = "texture-format-16-bit-norm")] + TextureFormat16BitNorm, + #[webidl(rename = "texture-compression-astc-hdr")] + TextureCompressionAstcHdr, + #[webidl(rename = "texture-adapter-specific-format-features")] + TextureAdapterSpecificFormatFeatures, + #[webidl(rename = "pipeline-statistics-query")] + PipelineStatisticsQuery, + #[webidl(rename = "timestamp-query-inside-passes")] + TimestampQueryInsidePasses, + #[webidl(rename = "mappable-primary-buffers")] + MappablePrimaryBuffers, + #[webidl(rename = "texture-binding-array")] + TextureBindingArray, + #[webidl(rename = "buffer-binding-array")] + BufferBindingArray, + #[webidl(rename = "storage-resource-binding-array")] + StorageResourceBindingArray, + #[webidl( + rename = "sampled-texture-and-storage-buffer-array-non-uniform-indexing" + )] + SampledTextureAndStorageBufferArrayNonUniformIndexing, + #[webidl(rename = "storage-texture-array-non-uniform-indexing")] + StorageTextureArrayNonUniformIndexing, + #[webidl(rename = "uniform-buffer-binding-arrays")] + UniformBufferBindingArrays, + #[webidl(rename = "partially-bound-binding-array")] + PartiallyBoundBindingArray, + #[webidl(rename = "multi-draw-indirect-count")] + MultiDrawIndirectCount, + #[webidl(rename = "push-constants")] + PushConstants, + #[webidl(rename = "address-mode-clamp-to-zero")] + AddressModeClampToZero, + #[webidl(rename = "address-mode-clamp-to-border")] + AddressModeClampToBorder, + #[webidl(rename = "polygon-mode-line")] + PolygonModeLine, + #[webidl(rename = "polygon-mode-point")] + PolygonModePoint, + #[webidl(rename = "conservative-rasterization")] + ConservativeRasterization, + #[webidl(rename = "vertex-writable-storage")] + VertexWritableStorage, + #[webidl(rename = "clear-texture")] + ClearTexture, + #[webidl(rename = "multiview")] + Multiview, + #[webidl(rename = "vertex-attribute-64-bit")] + VertexAttribute64Bit, + #[webidl(rename = "shader-f64")] + ShaderF64, + #[webidl(rename = "shader-i16")] + ShaderI16, + #[webidl(rename = "shader-primitive-index")] + ShaderPrimitiveIndex, + #[webidl(rename = "shader-early-depth-test")] + ShaderEarlyDepthTest, + #[webidl(rename = "passthrough-shaders")] + PassthroughShaders, } -pub fn feature_names_to_features(names: Vec) -> wgpu_types::Features { - use wgpu_types::Features; - let mut features = Features::empty(); +pub fn feature_names_to_features( + names: Vec, +) -> wgpu_types::Features { + use wgpu_types::Features; + let mut features = Features::empty(); - for name in names { - #[rustfmt::skip] + for name in names { + #[rustfmt::skip] let feature = match name { GPUFeatureName::DepthClipControl => Features::DEPTH_CLIP_CONTROL, GPUFeatureName::TimestampQuery => Features::TIMESTAMP_QUERY, @@ -485,160 +516,167 @@ pub fn feature_names_to_features(names: Vec) -> wgpu_types::Feat GPUFeatureName::ShaderEarlyDepthTest => Features::SHADER_EARLY_DEPTH_TEST, GPUFeatureName::PassthroughShaders => Features::EXPERIMENTAL_PASSTHROUGH_SHADERS, }; - features.set(feature, true); - } + features.set(feature, true); + } - features + features } #[allow(clippy::disallowed_types)] -pub fn features_to_feature_names(features: wgpu_types::Features) -> HashSet { - use GPUFeatureName::*; - let mut return_features = HashSet::new(); - - // api - if features.contains(wgpu_types::Features::DEPTH_CLIP_CONTROL) { - return_features.insert(DepthClipControl); - } - if features.contains(wgpu_types::Features::TIMESTAMP_QUERY) { - return_features.insert(TimestampQuery); - } - if features.contains(wgpu_types::Features::INDIRECT_FIRST_INSTANCE) { - return_features.insert(IndirectFirstInstance); - } - // shader - if features.contains(wgpu_types::Features::SHADER_F16) { - return_features.insert(ShaderF16); - } - // texture formats - if features.contains(wgpu_types::Features::DEPTH32FLOAT_STENCIL8) { - return_features.insert(Depth32floatStencil8); - } - if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_BC) { - return_features.insert(TextureCompressionBc); - } - if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_BC_SLICED_3D) { - return_features.insert(TextureCompressionBcSliced3d); - } - if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ETC2) { - return_features.insert(TextureCompressionEtc2); - } - if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC) { - return_features.insert(TextureCompressionAstc); - } - if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_SLICED_3D) { - return_features.insert(TextureCompressionAstcSliced3d); - } - if features.contains(wgpu_types::Features::RG11B10UFLOAT_RENDERABLE) { - return_features.insert(Rg11b10ufloatRenderable); - } - if features.contains(wgpu_types::Features::BGRA8UNORM_STORAGE) { - return_features.insert(Bgra8unormStorage); - } - if features.contains(wgpu_types::Features::FLOAT32_FILTERABLE) { - return_features.insert(Float32Filterable); - } - if features.contains(wgpu_types::Features::DUAL_SOURCE_BLENDING) { - return_features.insert(DualSourceBlending); - } - if features.contains(wgpu_types::Features::SUBGROUP) { - return_features.insert(Subgroups); - } - - // extended from spec - - // texture formats - if features.contains(wgpu_types::Features::TEXTURE_FORMAT_16BIT_NORM) { - return_features.insert(TextureFormat16BitNorm); - } - if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_HDR) { - return_features.insert(TextureCompressionAstcHdr); - } - if features.contains(wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES) { - return_features.insert(TextureAdapterSpecificFormatFeatures); - } - // api - if features.contains(wgpu_types::Features::PIPELINE_STATISTICS_QUERY) { - return_features.insert(PipelineStatisticsQuery); - } - if features.contains(wgpu_types::Features::TIMESTAMP_QUERY_INSIDE_PASSES) { - return_features.insert(TimestampQueryInsidePasses); - } - if features.contains(wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS) { - return_features.insert(MappablePrimaryBuffers); - } - if features.contains(wgpu_types::Features::TEXTURE_BINDING_ARRAY) { - return_features.insert(TextureBindingArray); - } - if features.contains(wgpu_types::Features::BUFFER_BINDING_ARRAY) { - return_features.insert(BufferBindingArray); - } - if features.contains(wgpu_types::Features::STORAGE_RESOURCE_BINDING_ARRAY) { - return_features.insert(StorageResourceBindingArray); - } - if features.contains( +pub fn features_to_feature_names( + features: wgpu_types::Features, +) -> HashSet { + use GPUFeatureName::*; + let mut return_features = HashSet::new(); + + // api + if features.contains(wgpu_types::Features::DEPTH_CLIP_CONTROL) { + return_features.insert(DepthClipControl); + } + if features.contains(wgpu_types::Features::TIMESTAMP_QUERY) { + return_features.insert(TimestampQuery); + } + if features.contains(wgpu_types::Features::INDIRECT_FIRST_INSTANCE) { + return_features.insert(IndirectFirstInstance); + } + // shader + if features.contains(wgpu_types::Features::SHADER_F16) { + return_features.insert(ShaderF16); + } + // texture formats + if features.contains(wgpu_types::Features::DEPTH32FLOAT_STENCIL8) { + return_features.insert(Depth32floatStencil8); + } + if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_BC) { + return_features.insert(TextureCompressionBc); + } + if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_BC_SLICED_3D) { + return_features.insert(TextureCompressionBcSliced3d); + } + if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ETC2) { + return_features.insert(TextureCompressionEtc2); + } + if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC) { + return_features.insert(TextureCompressionAstc); + } + if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_SLICED_3D) + { + return_features.insert(TextureCompressionAstcSliced3d); + } + if features.contains(wgpu_types::Features::RG11B10UFLOAT_RENDERABLE) { + return_features.insert(Rg11b10ufloatRenderable); + } + if features.contains(wgpu_types::Features::BGRA8UNORM_STORAGE) { + return_features.insert(Bgra8unormStorage); + } + if features.contains(wgpu_types::Features::FLOAT32_FILTERABLE) { + return_features.insert(Float32Filterable); + } + if features.contains(wgpu_types::Features::DUAL_SOURCE_BLENDING) { + return_features.insert(DualSourceBlending); + } + if features.contains(wgpu_types::Features::SUBGROUP) { + return_features.insert(Subgroups); + } + + // extended from spec + + // texture formats + if features.contains(wgpu_types::Features::TEXTURE_FORMAT_16BIT_NORM) { + return_features.insert(TextureFormat16BitNorm); + } + if features.contains(wgpu_types::Features::TEXTURE_COMPRESSION_ASTC_HDR) { + return_features.insert(TextureCompressionAstcHdr); + } + if features + .contains(wgpu_types::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES) + { + return_features.insert(TextureAdapterSpecificFormatFeatures); + } + // api + if features.contains(wgpu_types::Features::PIPELINE_STATISTICS_QUERY) { + return_features.insert(PipelineStatisticsQuery); + } + if features.contains(wgpu_types::Features::TIMESTAMP_QUERY_INSIDE_PASSES) { + return_features.insert(TimestampQueryInsidePasses); + } + if features.contains(wgpu_types::Features::MAPPABLE_PRIMARY_BUFFERS) { + return_features.insert(MappablePrimaryBuffers); + } + if features.contains(wgpu_types::Features::TEXTURE_BINDING_ARRAY) { + return_features.insert(TextureBindingArray); + } + if features.contains(wgpu_types::Features::BUFFER_BINDING_ARRAY) { + return_features.insert(BufferBindingArray); + } + if features.contains(wgpu_types::Features::STORAGE_RESOURCE_BINDING_ARRAY) { + return_features.insert(StorageResourceBindingArray); + } + if features.contains( wgpu_types::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, ) { return_features.insert(SampledTextureAndStorageBufferArrayNonUniformIndexing); } - if features.contains(wgpu_types::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING) { - return_features.insert(StorageTextureArrayNonUniformIndexing); - } - if features.contains(wgpu_types::Features::UNIFORM_BUFFER_BINDING_ARRAYS) { - return_features.insert(UniformBufferBindingArrays); - } - if features.contains(wgpu_types::Features::PARTIALLY_BOUND_BINDING_ARRAY) { - return_features.insert(PartiallyBoundBindingArray); - } - if features.contains(wgpu_types::Features::MULTI_DRAW_INDIRECT_COUNT) { - return_features.insert(MultiDrawIndirectCount); - } - if features.contains(wgpu_types::Features::PUSH_CONSTANTS) { - return_features.insert(PushConstants); - } - if features.contains(wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_ZERO) { - return_features.insert(AddressModeClampToZero); - } - if features.contains(wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_BORDER) { - return_features.insert(AddressModeClampToBorder); - } - if features.contains(wgpu_types::Features::POLYGON_MODE_LINE) { - return_features.insert(PolygonModeLine); - } - if features.contains(wgpu_types::Features::POLYGON_MODE_POINT) { - return_features.insert(PolygonModePoint); - } - if features.contains(wgpu_types::Features::CONSERVATIVE_RASTERIZATION) { - return_features.insert(ConservativeRasterization); - } - if features.contains(wgpu_types::Features::VERTEX_WRITABLE_STORAGE) { - return_features.insert(VertexWritableStorage); - } - if features.contains(wgpu_types::Features::CLEAR_TEXTURE) { - return_features.insert(ClearTexture); - } - if features.contains(wgpu_types::Features::MULTIVIEW) { - return_features.insert(Multiview); - } - if features.contains(wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT) { - return_features.insert(VertexAttribute64Bit); - } - // shader - if features.contains(wgpu_types::Features::SHADER_F64) { - return_features.insert(ShaderF64); - } - if features.contains(wgpu_types::Features::SHADER_I16) { - return_features.insert(ShaderI16); - } - if features.contains(wgpu_types::Features::SHADER_PRIMITIVE_INDEX) { - return_features.insert(ShaderPrimitiveIndex); - } - if features.contains(wgpu_types::Features::SHADER_EARLY_DEPTH_TEST) { - return_features.insert(ShaderEarlyDepthTest); - } - if features.contains(wgpu_types::Features::EXPERIMENTAL_PASSTHROUGH_SHADERS) { - return_features.insert(PassthroughShaders); - } - - return_features + if features + .contains(wgpu_types::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING) + { + return_features.insert(StorageTextureArrayNonUniformIndexing); + } + if features.contains(wgpu_types::Features::UNIFORM_BUFFER_BINDING_ARRAYS) { + return_features.insert(UniformBufferBindingArrays); + } + if features.contains(wgpu_types::Features::PARTIALLY_BOUND_BINDING_ARRAY) { + return_features.insert(PartiallyBoundBindingArray); + } + if features.contains(wgpu_types::Features::MULTI_DRAW_INDIRECT_COUNT) { + return_features.insert(MultiDrawIndirectCount); + } + if features.contains(wgpu_types::Features::PUSH_CONSTANTS) { + return_features.insert(PushConstants); + } + if features.contains(wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_ZERO) { + return_features.insert(AddressModeClampToZero); + } + if features.contains(wgpu_types::Features::ADDRESS_MODE_CLAMP_TO_BORDER) { + return_features.insert(AddressModeClampToBorder); + } + if features.contains(wgpu_types::Features::POLYGON_MODE_LINE) { + return_features.insert(PolygonModeLine); + } + if features.contains(wgpu_types::Features::POLYGON_MODE_POINT) { + return_features.insert(PolygonModePoint); + } + if features.contains(wgpu_types::Features::CONSERVATIVE_RASTERIZATION) { + return_features.insert(ConservativeRasterization); + } + if features.contains(wgpu_types::Features::VERTEX_WRITABLE_STORAGE) { + return_features.insert(VertexWritableStorage); + } + if features.contains(wgpu_types::Features::CLEAR_TEXTURE) { + return_features.insert(ClearTexture); + } + if features.contains(wgpu_types::Features::MULTIVIEW) { + return_features.insert(Multiview); + } + if features.contains(wgpu_types::Features::VERTEX_ATTRIBUTE_64BIT) { + return_features.insert(VertexAttribute64Bit); + } + // shader + if features.contains(wgpu_types::Features::SHADER_F64) { + return_features.insert(ShaderF64); + } + if features.contains(wgpu_types::Features::SHADER_I16) { + return_features.insert(ShaderI16); + } + if features.contains(wgpu_types::Features::SHADER_PRIMITIVE_INDEX) { + return_features.insert(ShaderPrimitiveIndex); + } + if features.contains(wgpu_types::Features::SHADER_EARLY_DEPTH_TEST) { + return_features.insert(ShaderEarlyDepthTest); + } + if features.contains(wgpu_types::Features::EXPERIMENTAL_PASSTHROUGH_SHADERS) { + return_features.insert(PassthroughShaders); + } + + return_features } From 99a6fdd803d444ca9326011e2d62e0693c5f1a84 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 17 Sep 2025 11:54:32 -0400 Subject: [PATCH 240/303] [deno] move `isFallbackAdapter` from `GPUAdapter` to `GPUAdapterInfo` Also fixes `Deno.privateCustomInspect`, which was defined as static methods of the classes and was not working properly. (cherry picked from denoland/deno#28650) --- cts_runner/src/bootstrap.js | 4 - deno_webgpu/01_webgpu.js | 185 ++++++++++++++++++++++++------------ deno_webgpu/adapter.rs | 12 ++- 3 files changed, 132 insertions(+), 69 deletions(-) diff --git a/cts_runner/src/bootstrap.js b/cts_runner/src/bootstrap.js index e322a6d62dc..220a7201384 100644 --- a/cts_runner/src/bootstrap.js +++ b/cts_runner/src/bootstrap.js @@ -138,10 +138,6 @@ class Navigator { constructor() { webidl.illegalConstructor(); } - - [Symbol.for("Deno.customInspect")](inspect) { - return `${this.constructor.name} ${inspect({})}`; - } } const NavigatorPrototype = Navigator.prototype; diff --git a/deno_webgpu/01_webgpu.js b/deno_webgpu/01_webgpu.js index 5345a2e624f..81958d39922 100644 --- a/deno_webgpu/01_webgpu.js +++ b/deno_webgpu/01_webgpu.js @@ -57,9 +57,10 @@ import { import { DOMException } from "ext:deno_web/01_dom_exception.js"; import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; -const customInspect = SymbolFor("Deno.privateCustomInspect"); +const privateCustomInspect = SymbolFor("Deno.privateCustomInspect"); const _message = Symbol("[[message]]"); const illegalConstructorKey = Symbol("illegalConstructorKey"); + class GPUError { constructor(key = null) { if (key !== illegalConstructorKey) { @@ -73,7 +74,7 @@ class GPUError { return this[_message]; } - [customInspect](inspect, inspectOptions) { + [privateCustomInspect](inspect, inspectOptions) { return inspect( createFilteredInspectProxy({ object: this, @@ -170,14 +171,16 @@ class GPUUncapturedErrorEvent extends Event { } const GPUUncapturedErrorEventPrototype = GPUUncapturedErrorEvent.prototype; -ObjectDefineProperty(GPU, customInspect, { +const GPUPrototype = GPU.prototype; +ObjectDefineProperty(GPUPrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return `${this.constructor.name} ${inspect({}, inspectOptions)}`; }, }); -ObjectDefineProperty(GPUAdapter, customInspect, { +const GPUAdapterPrototype = GPUAdapter.prototype; +ObjectDefineProperty(GPUAdapterPrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -188,16 +191,15 @@ ObjectDefineProperty(GPUAdapter, customInspect, { "features", "limits", "info", - "isFallbackAdapter", ], }), inspectOptions, ); }, }); -const GPUAdapterPrototype = GPUAdapter.prototype; -ObjectDefineProperty(GPUAdapterInfo, customInspect, { +const GPUAdapterInfoPrototype = GPUAdapterInfo.prototype; +ObjectDefineProperty(GPUAdapterInfoPrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -209,15 +211,19 @@ ObjectDefineProperty(GPUAdapterInfo, customInspect, { "architecture", "device", "description", + "subgroupMinSize", + "subgroupMaxSize", + "isFallbackAdapter", ], }), inspectOptions, ); }, }); -const GPUAdapterInfoPrototype = GPUAdapterInfo.prototype; -ObjectDefineProperty(GPUSupportedFeatures, customInspect, { +const GPUSupportedFeaturesPrototype = GPUSupportedFeatures.prototype; +webidl.setlikeObjectWrap(GPUSupportedFeaturesPrototype, true); +ObjectDefineProperty(GPUSupportedFeaturesPrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { if (ObjectPrototypeIsPrototypeOf(GPUSupportedFeaturesPrototype, this)) { @@ -229,10 +235,61 @@ ObjectDefineProperty(GPUSupportedFeatures, customInspect, { } }, }); -const GPUSupportedFeaturesPrototype = GPUSupportedFeatures.prototype; -webidl.setlikeObjectWrap(GPUSupportedFeaturesPrototype, true); -ObjectDefineProperty(GPUDeviceLostInfo, customInspect, { +const GPUSupportedLimitsPrototype = GPUSupportedLimits.prototype; +ObjectDefineProperty(GPUSupportedLimitsPrototype, privateCustomInspect, { + __proto__: null, + value(inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf( + GPUSupportedLimitsPrototype, + this, + ), + keys: [ + "maxTextureDimension1D", + "maxTextureDimension2D", + "maxTextureDimension3D", + "maxTextureArrayLayers", + "maxBindGroups", + // TODO(@crowlKats): support max_bind_groups_plus_vertex_buffers + // "maxBindGroupsPlusVertexBuffers", + "maxBindingsPerBindGroup", + "maxDynamicUniformBuffersPerPipelineLayout", + "maxDynamicStorageBuffersPerPipelineLayout", + "maxSampledTexturesPerShaderStage", + "maxSamplersPerShaderStage", + "maxStorageBuffersPerShaderStage", + "maxStorageTexturesPerShaderStage", + "maxUniformBuffersPerShaderStage", + "maxUniformBufferBindingSize", + "maxStorageBufferBindingSize", + "minUniformBufferOffsetAlignment", + "minStorageBufferOffsetAlignment", + "maxVertexBuffers", + "maxBufferSize", + "maxVertexAttributes", + "maxVertexBufferArrayStride", + // TODO(@crowlKats): support max_inter_stage_shader_variables + // "maxInterStageShaderVariables", + "maxColorAttachments", + "maxColorAttachmentBytesPerSample", + "maxComputeWorkgroupStorageSize", + "maxComputeInvocationsPerWorkgroup", + "maxComputeWorkgroupSizeX", + "maxComputeWorkgroupSizeY", + "maxComputeWorkgroupSizeZ", + "maxComputeWorkgroupsPerDimension", + ], + }), + inspectOptions, + ); + }, +}); + +const GPUDeviceLostInfoPrototype = GPUDeviceLostInfo.prototype; +ObjectDefineProperty(GPUDeviceLostInfoPrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -251,9 +308,11 @@ ObjectDefineProperty(GPUDeviceLostInfo, customInspect, { ); }, }); -const GPUDeviceLostInfoPrototype = GPUDeviceLostInfo.prototype; -ObjectDefineProperty(GPUDevice, customInspect, { +const GPUDevicePrototype = GPUDevice.prototype; +ObjectSetPrototypeOf(GPUDevicePrototype, EventTargetPrototype); +defineEventHandler(GPUDevicePrototype, "uncapturederror"); +ObjectDefineProperty(GPUDevicePrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -274,11 +333,9 @@ ObjectDefineProperty(GPUDevice, customInspect, { ); }, }); -const GPUDevicePrototype = GPUDevice.prototype; -ObjectSetPrototypeOf(GPUDevicePrototype, EventTargetPrototype); -defineEventHandler(GPUDevice.prototype, "uncapturederror"); -ObjectDefineProperty(GPUQueue, customInspect, { +const GPUQueuePrototype = GPUQueue.prototype; +ObjectDefineProperty(GPUQueuePrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -293,9 +350,9 @@ ObjectDefineProperty(GPUQueue, customInspect, { ); }, }); -const GPUQueuePrototype = GPUQueue.prototype; -ObjectDefineProperty(GPUBuffer, customInspect, { +const GPUBufferPrototype = GPUBuffer.prototype; +ObjectDefineProperty(GPUBufferPrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -313,7 +370,6 @@ ObjectDefineProperty(GPUBuffer, customInspect, { ); }, }); -const GPUBufferPrototype = GPUBuffer.prototype; class GPUBufferUsage { constructor() { @@ -365,7 +421,8 @@ class GPUMapMode { } } -ObjectDefineProperty(GPUTexture, customInspect, { +const GPUTexturePrototype = GPUTexture.prototype; +ObjectDefineProperty(GPUTexturePrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -388,7 +445,6 @@ ObjectDefineProperty(GPUTexture, customInspect, { ); }, }); -const GPUTexturePrototype = GPUTexture.prototype; class GPUTextureUsage { constructor() { @@ -412,7 +468,8 @@ class GPUTextureUsage { } } -ObjectDefineProperty(GPUTextureView, customInspect, { +const GPUTextureViewPrototype = GPUTextureView.prototype; +ObjectDefineProperty(GPUTextureViewPrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -427,20 +484,29 @@ ObjectDefineProperty(GPUTextureView, customInspect, { ); }, }); -const GPUTextureViewPrototype = GPUTextureView.prototype; -ObjectDefineProperty(GPUSampler, customInspect, { +const GPUSamplerPrototype = GPUSampler.prototype; +ObjectDefineProperty(GPUSamplerPrototype, privateCustomInspect, { __proto__: null, - value(inspect) { - return `${this.constructor.name} ${ - inspect({ - label: this.label, - }) - }`; + value(inspect, inspectOptions) { + return inspect( + createFilteredInspectProxy({ + object: this, + evaluate: ObjectPrototypeIsPrototypeOf( + GPUSamplerPrototype, + this, + ), + keys: [ + "label", + ], + }), + inspectOptions, + ); }, }); -ObjectDefineProperty(GPUBindGroupLayout, customInspect, { +const GPUBindGroupLayoutPrototype = GPUBindGroupLayout.prototype; +ObjectDefineProperty(GPUBindGroupLayout, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -458,9 +524,9 @@ ObjectDefineProperty(GPUBindGroupLayout, customInspect, { ); }, }); -const GPUBindGroupLayoutPrototype = GPUBindGroupLayout.prototype; -ObjectDefineProperty(GPUPipelineLayout, customInspect, { +const GPUPipelineLayoutPrototype = GPUPipelineLayout.prototype; +ObjectDefineProperty(GPUPipelineLayoutPrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -478,9 +544,9 @@ ObjectDefineProperty(GPUPipelineLayout, customInspect, { ); }, }); -const GPUPipelineLayoutPrototype = GPUPipelineLayout.prototype; -ObjectDefineProperty(GPUBindGroup, customInspect, { +const GPUBindGroupPrototype = GPUBindGroup.prototype; +ObjectDefineProperty(GPUBindGroupPrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -495,9 +561,9 @@ ObjectDefineProperty(GPUBindGroup, customInspect, { ); }, }); -const GPUBindGroupPrototype = GPUBindGroup.prototype; -ObjectDefineProperty(GPUShaderModule, customInspect, { +const GPUShaderModulePrototype = GPUShaderModule.prototype; +ObjectDefineProperty(GPUShaderModulePrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -512,9 +578,8 @@ ObjectDefineProperty(GPUShaderModule, customInspect, { ); }, }); -const GPUShaderModulePrototype = GPUShaderModule.prototype; -ObjectDefineProperty(GPUCompilationInfo, customInspect, { +ObjectDefineProperty(GPUCompilationInfo, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -534,7 +599,7 @@ ObjectDefineProperty(GPUCompilationInfo, customInspect, { }); const GPUCompilationInfoPrototype = GPUCompilationInfo.prototype; -ObjectDefineProperty(GPUCompilationMessage, customInspect, { +ObjectDefineProperty(GPUCompilationMessage, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -584,7 +649,8 @@ class GPUShaderStage { } } -ObjectDefineProperty(GPUComputePipeline, customInspect, { +const GPUComputePipelinePrototype = GPUComputePipeline.prototype; +ObjectDefineProperty(GPUComputePipelinePrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -602,9 +668,9 @@ ObjectDefineProperty(GPUComputePipeline, customInspect, { ); }, }); -const GPUComputePipelinePrototype = GPUComputePipeline.prototype; -ObjectDefineProperty(GPURenderPipeline, customInspect, { +const GPURenderPipelinePrototype = GPURenderPipeline.prototype; +ObjectDefineProperty(GPURenderPipelinePrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -622,7 +688,6 @@ ObjectDefineProperty(GPURenderPipeline, customInspect, { ); }, }); -const GPURenderPipelinePrototype = GPURenderPipeline.prototype; class GPUColorWrite { constructor() { @@ -646,7 +711,8 @@ class GPUColorWrite { } } -ObjectDefineProperty(GPUCommandEncoder, customInspect, { +const GPUCommandEncoderPrototype = GPUCommandEncoder.prototype; +ObjectDefineProperty(GPUCommandEncoderPrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -664,9 +730,9 @@ ObjectDefineProperty(GPUCommandEncoder, customInspect, { ); }, }); -const GPUCommandEncoderPrototype = GPUCommandEncoder.prototype; -ObjectDefineProperty(GPURenderPassEncoder, customInspect, { +const GPURenderPassEncoderPrototype = GPURenderPassEncoder.prototype; +ObjectDefineProperty(GPURenderPassEncoderPrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -684,9 +750,9 @@ ObjectDefineProperty(GPURenderPassEncoder, customInspect, { ); }, }); -const GPURenderPassEncoderPrototype = GPURenderPassEncoder.prototype; -ObjectDefineProperty(GPUComputePassEncoder, customInspect, { +const GPUComputePassEncoderPrototype = GPUComputePassEncoder.prototype; +ObjectDefineProperty(GPUComputePassEncoderPrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -704,9 +770,9 @@ ObjectDefineProperty(GPUComputePassEncoder, customInspect, { ); }, }); -const GPUComputePassEncoderPrototype = GPUComputePassEncoder.prototype; -ObjectDefineProperty(GPUCommandBuffer, customInspect, { +const GPUCommandBufferPrototype = GPUCommandBuffer.prototype; +ObjectDefineProperty(GPUCommandBufferPrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -721,9 +787,9 @@ ObjectDefineProperty(GPUCommandBuffer, customInspect, { ); }, }); -const GPUCommandBufferPrototype = GPUCommandBuffer.prototype; -ObjectDefineProperty(GPURenderBundleEncoder, customInspect, { +const GPURenderBundleEncoderPrototype = GPURenderBundleEncoder.prototype; +ObjectDefineProperty(GPURenderBundleEncoderPrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -741,9 +807,9 @@ ObjectDefineProperty(GPURenderBundleEncoder, customInspect, { ); }, }); -const GPURenderBundleEncoderPrototype = GPURenderBundleEncoder.prototype; -ObjectDefineProperty(GPURenderBundle, customInspect, { +const GPURenderBundlePrototype = GPURenderBundle.prototype; +ObjectDefineProperty(GPURenderBundlePrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -758,9 +824,9 @@ ObjectDefineProperty(GPURenderBundle, customInspect, { ); }, }); -const GPURenderBundlePrototype = GPURenderBundle.prototype; -ObjectDefineProperty(GPUQuerySet, customInspect, { +const GPUQuerySetPrototype = GPUQuerySet.prototype; +ObjectDefineProperty(GPUQuerySetPrototype, privateCustomInspect, { __proto__: null, value(inspect, inspectOptions) { return inspect( @@ -777,7 +843,6 @@ ObjectDefineProperty(GPUQuerySet, customInspect, { ); }, }); -const GPUQuerySetPrototype = GPUQuerySet.prototype; // Naming it `type` or `r#type` in Rust does not work. // https://github.com/gfx-rs/wgpu/issues/7778 ObjectDefineProperty(GPUQuerySet.prototype, "type", { diff --git a/deno_webgpu/adapter.rs b/deno_webgpu/adapter.rs index ca6cb2f788b..5d1463c1aa6 100644 --- a/deno_webgpu/adapter.rs +++ b/deno_webgpu/adapter.rs @@ -90,6 +90,7 @@ impl GPUAdapter { GPUSupportedFeatures::new(scope, features) }) } + #[getter] #[global] fn limits(&self, scope: &mut v8::HandleScope) -> v8::Global { @@ -98,11 +99,6 @@ impl GPUAdapter { GPUSupportedLimits(adapter_limits) }) } - #[getter] - fn is_fallback_adapter(&self) -> bool { - // TODO(lucacasonato): report correctly from wgpu - false - } #[async_method(fake)] #[global] @@ -443,4 +439,10 @@ impl GPUAdapterInfo { fn subgroup_max_size(&self) -> u32 { self.subgroup_max_size } + + #[getter] + fn is_fallback_adapter(&self) -> bool { + // TODO(lucacasonato): report correctly from wgpu + false + } } From 48097412fc3394177370261dd663f42989afdeed Mon Sep 17 00:00:00 2001 From: chirsz Date: Wed, 17 Sep 2025 13:50:45 -0400 Subject: [PATCH 241/303] [deno] release current texture of surface after present (cherry picked from denoland/deno#28691) --- deno_webgpu/surface.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/deno_webgpu/surface.rs b/deno_webgpu/surface.rs index 74a382a927f..aab7d916a9f 100644 --- a/deno_webgpu/surface.rs +++ b/deno_webgpu/surface.rs @@ -164,6 +164,9 @@ impl GPUCanvasContext { config.device.instance.surface_present(self.surface_id)?; + // next `get_current_texture` call would get a new texture + *self.texture.borrow_mut() = None; + Ok(()) } } From 190050e2960035e23d7c29eb95e2a37bf783070c Mon Sep 17 00:00:00 2001 From: Leo Kettmeir Date: Wed, 17 Sep 2025 14:03:25 -0400 Subject: [PATCH 242/303] [deno] add `deviceStartCapture` and `deviceStopCapture` This is achieved by adding a new `Deno.webgpu` namespace which will be used for non-spec functionality, which for now will be marked as unstable (cherry picked from denoland/deno#28192) --- deno_webgpu/01_webgpu.js | 16 ++++++++++++++++ deno_webgpu/device.rs | 18 ++++++++++++++++++ deno_webgpu/lib.rs | 6 +++++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/deno_webgpu/01_webgpu.js b/deno_webgpu/01_webgpu.js index 81958d39922..c958f189e16 100644 --- a/deno_webgpu/01_webgpu.js +++ b/deno_webgpu/01_webgpu.js @@ -37,6 +37,8 @@ import { GPUTextureView, GPUExternalTexture, op_create_gpu, + op_webgpu_device_start_capture, + op_webgpu_device_stop_capture, } from "ext:core/ops"; const { ObjectDefineProperty, @@ -884,6 +886,19 @@ webidl.converters["GPUUncapturedErrorEventInit"] = webidl dictMembersGPUUncapturedErrorEventInit, ); +function deviceStartCapture(device) { + op_webgpu_device_start_capture(device); +} + +function deviceStopCapture(device) { + op_webgpu_device_stop_capture(device); +} + +const denoNsWebGPU = { + deviceStartCapture, + deviceStopCapture, +}; + let gpu; function initGPU() { if (!gpu) { @@ -896,6 +911,7 @@ function initGPU() { } export { + denoNsWebGPU, GPU, gpu, GPUAdapter, diff --git a/deno_webgpu/device.rs b/deno_webgpu/device.rs index 6b96532656b..ee99ace3676 100644 --- a/deno_webgpu/device.rs +++ b/deno_webgpu/device.rs @@ -917,3 +917,21 @@ impl GPUDeviceLostInfo { "device was lost" } } + +#[op2(fast)] +pub fn op_webgpu_device_start_capture(#[cppgc] device: &GPUDevice) { + unsafe { + device + .instance + .device_start_graphics_debugger_capture(device.id); + } +} + +#[op2(fast)] +pub fn op_webgpu_device_stop_capture(#[cppgc] device: &GPUDevice) { + unsafe { + device + .instance + .device_stop_graphics_debugger_capture(device.id); + } +} diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index 27f04ba5af3..d529ca84860 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -64,7 +64,11 @@ pub type Instance = Arc; deno_core::extension!( deno_webgpu, deps = [deno_webidl, deno_web], - ops = [op_create_gpu], + ops = [ + op_create_gpu, + device::op_webgpu_device_start_capture, + device::op_webgpu_device_stop_capture, + ], objects = [ GPU, adapter::GPUAdapter, From 3ebae1bf3b53c3176a66a4297c5c11803a81aa62 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 17 Sep 2025 14:09:21 -0400 Subject: [PATCH 243/303] Update to deno 2.2.12 --- Cargo.lock | 231 +++++++++++------------------------------ Cargo.toml | 14 +-- deno_webgpu/Cargo.toml | 2 +- 3 files changed, 70 insertions(+), 177 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9b10a5d11a0..877c766278e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -316,22 +316,13 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "base64-simd" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "781dd20c3aff0bd194fe7d2a977dd92f21c173891f3a03b677359e5fa457e5d5" -dependencies = [ - "simd-abstraction", -] - [[package]] name = "base64-simd" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" dependencies = [ - "outref 0.5.2", + "outref", "vsimd", ] @@ -366,9 +357,9 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.70.1" +version = "0.71.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" +checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" dependencies = [ "bitflags 2.9.4", "cexpr", @@ -379,35 +370,20 @@ dependencies = [ "proc-macro2", "quote", "regex", - "rustc-hash", + "rustc-hash 2.1.1", "shlex", "syn", ] -[[package]] -name = "bit-set" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" -dependencies = [ - "bit-vec 0.6.3", -] - [[package]] name = "bit-set" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" dependencies = [ - "bit-vec 0.8.0", + "bit-vec", ] -[[package]] -name = "bit-vec" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" - [[package]] name = "bit-vec" version = "0.8.0" @@ -575,15 +551,6 @@ dependencies = [ "serde", ] -[[package]] -name = "capacity_builder" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58ec49028cb308564429cd8fac4ef21290067a0afe8f5955330a8d487d0d790c" -dependencies = [ - "itoa", -] - [[package]] name = "capacity_builder" version = "0.5.0" @@ -619,7 +586,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dc1a6f7b5651af85774ae5a34b4e8be397d9cf4bc063b7e6dbd99a841837830" dependencies = [ - "semver 1.0.26", + "semver", "serde", "serde-untagged", "serde-value", @@ -638,7 +605,7 @@ dependencies = [ "camino", "cargo-platform", "cargo-util-schemas", - "semver 1.0.26", + "semver", "serde", "serde_json", "thiserror 2.0.16", @@ -770,7 +737,7 @@ version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn", @@ -1055,26 +1022,26 @@ dependencies = [ [[package]] name = "deno_console" -version = "0.192.0" +version = "0.203.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca40d9ecd49a0320c058eff8ad8b53c83b1b743e3087001afe2e14ec50197d34" +checksum = "999171b0fc7255971eec7adfc49b2bf18832e86e4a86746c3c58633373d16cdb" dependencies = [ "deno_core", ] [[package]] name = "deno_core" -version = "0.338.0" +version = "0.343.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "113f3f08bd5daf99f1a7876c0f99cd8c3c609439fa0b808311ec856a253e95f0" +checksum = "167ae63972f6de58e4a548327f363ebc449930b62a44d9bbd80197564d2c755d" dependencies = [ "anyhow", "az", "bincode 1.3.3", - "bit-set 0.5.3", - "bit-vec 0.6.3", + "bit-set", + "bit-vec", "bytes", - "capacity_builder 0.1.3", + "capacity_builder", "cooked-waker", "deno_core_icudata", "deno_error", @@ -1084,7 +1051,6 @@ dependencies = [ "futures", "indexmap", "libc", - "memoffset", "parking_lot", "percent-encoding", "pin-project", @@ -1109,9 +1075,9 @@ checksum = "fe4dccb6147bb3f3ba0c7a48e993bfeb999d2c2e47a81badee80e2b370c8d695" [[package]] name = "deno_error" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c23dbc46d5804814b08b4675838f9884e3a52916987ec5105af36d42f9911b5" +checksum = "19fae9fe305307b5ef3ee4e8244c79cffcca421ab0ce8634dea0c6b1342f220f" dependencies = [ "deno_error_macro", "libc", @@ -1123,9 +1089,9 @@ dependencies = [ [[package]] name = "deno_error_macro" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "babccedee31ce7e57c3e6dff2cb3ab8d68c49d0df8222fe0d11d628e65192790" +checksum = "5abb2556e91848b66f562451fcbcdee2a3b7c88281828908dcf7cca355f5d997" dependencies = [ "proc-macro2", "quote", @@ -1134,17 +1100,17 @@ dependencies = [ [[package]] name = "deno_ops" -version = "0.214.0" +version = "0.219.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ad885bf882be535f7714c713042129acba6f31a8efb5e6b2298f6e40cab9b16" +checksum = "188e48d180244dae157d8a5126b8fbcecf6458f26a425f1c2f57b5952a1b5ee1" dependencies = [ "indexmap", "proc-macro-rules", "proc-macro2", "quote", "stringcase", - "strum 0.25.0", - "strum_macros 0.25.3", + "strum", + "strum_macros", "syn", "thiserror 2.0.16", ] @@ -1164,11 +1130,11 @@ dependencies = [ [[package]] name = "deno_permissions" -version = "0.52.0" +version = "0.62.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ff15740ddc4626cc7f5d66a113e0f825073476d1e83af9fa693426516d07b7" +checksum = "f7c3c0785bcb458cd010c47d7f77cae26594a5160ebfc4fecb6f9e5ea36483fc" dependencies = [ - "capacity_builder 0.5.0", + "capacity_builder", "deno_core", "deno_error", "deno_path_util", @@ -1207,24 +1173,23 @@ dependencies = [ [[package]] name = "deno_url" -version = "0.192.0" +version = "0.203.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36a705094c7fbbb01338e89c12367da939cf831dd5b202e3a521f75a614a6082" +checksum = "0961e3e844191cac261eba5efdf52e2a5dd3aeeac7ebb09c1bbe3f8b04ef31cd" dependencies = [ "deno_core", "deno_error", - "thiserror 2.0.16", "urlpattern", ] [[package]] name = "deno_web" -version = "0.224.0" +version = "0.234.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ae1ba442b2c4b6116eb75e6e46968840693f2036d035bd45421c4a9beda6186" +checksum = "2ec73d866d485bed1bd520f3a413a94b5c9a69de09d8561697d2bd83a79c795c" dependencies = [ "async-trait", - "base64-simd 0.8.0", + "base64-simd", "bytes", "deno_core", "deno_error", @@ -1240,7 +1205,7 @@ dependencies = [ [[package]] name = "deno_webgpu" -version = "0.157.0" +version = "0.170.0" dependencies = [ "deno_core", "deno_error", @@ -1257,9 +1222,9 @@ dependencies = [ [[package]] name = "deno_webidl" -version = "0.192.0" +version = "0.203.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d2d820d865651e0ce4eca898176577c8693bf2694af32545ab4b9ffb9934fa" +checksum = "cb50836af90d078b1f30f4df0e3398d557a74633b9b4740e10a299a83f12d054" dependencies = [ "deno_core", ] @@ -1388,9 +1353,9 @@ checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] @@ -1946,12 +1911,6 @@ dependencies = [ "serde", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -2446,15 +2405,6 @@ dependencies = [ "libc", ] -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - [[package]] name = "metal" version = "0.32.0" @@ -2532,7 +2482,7 @@ version = "26.0.0" dependencies = [ "arbitrary", "arrayvec", - "bit-set 0.8.0", + "bit-set", "bitflags 2.9.4", "cfg-if", "cfg_aliases 0.2.1", @@ -2554,10 +2504,10 @@ dependencies = [ "pp-rs", "ron", "rspirv", - "rustc-hash", + "rustc-hash 1.1.0", "serde", "spirv", - "strum 0.27.2", + "strum", "thiserror 2.0.16", "unicode-ident", "walkdir", @@ -3105,12 +3055,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "outref" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f222829ae9293e33a9f5e9f440c6760a3d450a64affe1846486b140db81c1f4" - [[package]] name = "outref" version = "0.5.2" @@ -3609,7 +3553,7 @@ version = "0.12.0+sdk-1.3.268.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cf3a93856b6e5946537278df0d3075596371b1950ccff012f02b0f7eafec8d" dependencies = [ - "rustc-hash", + "rustc-hash 1.1.0", "spirv", ] @@ -3632,13 +3576,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] -name = "rustc_version" -version = "0.2.3" +name = "rustc-hash" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustix" @@ -3725,15 +3666,6 @@ dependencies = [ "tiny-skia", ] -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.26" @@ -3743,12 +3675,6 @@ dependencies = [ "serde", ] -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "serde" version = "1.0.226" @@ -3833,9 +3759,9 @@ dependencies = [ [[package]] name = "serde_v8" -version = "0.247.0" +version = "0.252.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12bbfafb7b707cbed49d1eaf48f4aa41b5ff57f813d1a80f77244e6e2fa4507e" +checksum = "84b2d85f46747fad18bbf98ad4b9b13c59e01c85bf8c73182a71fdf638372dfd" dependencies = [ "deno_error", "num-bigint", @@ -3875,15 +3801,6 @@ dependencies = [ "libc", ] -[[package]] -name = "simd-abstraction" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cadb29c57caadc51ff8346233b5cec1d240b68ce55cf1afc764818791876987" -dependencies = [ - "outref 0.1.0", -] - [[package]] name = "simd-adler32" version = "0.3.7" @@ -3982,17 +3899,16 @@ dependencies = [ [[package]] name = "sourcemap" -version = "8.0.1" +version = "9.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "208d40b9e8cad9f93613778ea295ed8f3c2b1824217c6cfc7219d3f6f45b96d4" +checksum = "e22afbcb92ce02d23815b9795523c005cb9d3c214f8b7a66318541c240ea7935" dependencies = [ - "base64-simd 0.7.0", + "base64-simd", "bitvec", "data-encoding", "debugid", "if_chain", - "rustc-hash", - "rustc_version", + "rustc-hash 2.1.1", "serde", "serde_json", "unicode-id-start", @@ -4038,9 +3954,9 @@ checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" [[package]] name = "stringcase" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04028eeb851ed08af6aba5caa29f2d59a13ed168cee4d6bd753aeefcf1d636b0" +checksum = "72abeda133c49d7bddece6c154728f83eec8172380c80ab7096da9487e20d27c" [[package]] name = "strsim" @@ -4048,35 +3964,13 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "strum" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" -dependencies = [ - "strum_macros 0.25.3", -] - [[package]] name = "strum" version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" dependencies = [ - "strum_macros 0.27.2", -] - -[[package]] -name = "strum_macros" -version = "0.25.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn", + "strum_macros", ] [[package]] @@ -4085,7 +3979,7 @@ version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn", @@ -4605,9 +4499,9 @@ dependencies = [ [[package]] name = "v8" -version = "134.5.0" +version = "135.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21c7a224a7eaf3f98c1bad772fbaee56394dce185ef7b19a2e0ca5e3d274165d" +checksum = "171c7d65c2c71e7e02cbef7762787614cab3e9043d58b433ef65b4baa2f4614d" dependencies = [ "bindgen", "bitflags 2.9.4", @@ -4615,7 +4509,6 @@ dependencies = [ "gzip-header", "home", "miniz_oxide 0.7.4", - "once_cell", "paste", "which 6.0.3", ] @@ -5002,8 +4895,8 @@ name = "wgpu-core" version = "26.0.0" dependencies = [ "arrayvec", - "bit-set 0.8.0", - "bit-vec 0.8.0", + "bit-set", + "bit-vec", "bitflags 2.9.4", "bytemuck", "cfg_aliases 0.2.1", @@ -5018,7 +4911,7 @@ dependencies = [ "profiling", "raw-window-handle 0.6.2", "ron", - "rustc-hash", + "rustc-hash 1.1.0", "serde", "smallvec", "thiserror 2.0.16", @@ -5125,7 +5018,7 @@ dependencies = [ "android_system_properties", "arrayvec", "ash", - "bit-set 0.8.0", + "bit-set", "bitflags 2.9.4", "block", "bytemuck", @@ -5162,7 +5055,7 @@ dependencies = [ "raw-window-handle 0.5.2", "raw-window-handle 0.6.2", "renderdoc-sys", - "rustc-hash", + "rustc-hash 1.1.0", "smallvec", "thiserror 2.0.16", "wasm-bindgen", @@ -5191,7 +5084,7 @@ dependencies = [ name = "wgpu-macros" version = "26.0.0" dependencies = [ - "heck 0.5.0", + "heck", "quote", "syn", ] @@ -5226,7 +5119,7 @@ dependencies = [ "profiling", "serde", "serde_json", - "strum 0.27.2", + "strum", "trybuild", "wasm-bindgen", "wasm-bindgen-futures", diff --git a/Cargo.toml b/Cargo.toml index c79994842bc..b2fbb1dc7e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -236,14 +236,14 @@ web-sys = { version = "0.3.77", default-features = false } web-time = "1.1.0" # deno dependencies -deno_console = "0.192.0" -deno_core = "0.338.0" -deno_url = "0.192.0" -deno_web = "0.224.0" -deno_webidl = "0.192.0" -deno_webgpu = { version = "0.157.0", path = "./deno_webgpu" } +deno_console = "0.203.0" +deno_core = "0.343.0" +deno_url = "0.203.0" +deno_web = "0.234.0" +deno_webidl = "0.203.0" +deno_webgpu = { version = "0.170.0", path = "./deno_webgpu" } deno_unsync = "0.4.2" -deno_error = "0.5.5" +deno_error = "0.5.6" tokio = "1.45.1" termcolor = "1.1.3" diff --git a/deno_webgpu/Cargo.toml b/deno_webgpu/Cargo.toml index 08545ef8d2a..ace7ec550cb 100644 --- a/deno_webgpu/Cargo.toml +++ b/deno_webgpu/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_webgpu" -version = "0.157.0" +version = "0.170.0" authors = ["the Deno authors"] edition.workspace = true license = "MIT" From b6b951d4670b6c968088f313b46fd812eb468173 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 17 Sep 2025 14:49:40 -0400 Subject: [PATCH 244/303] Update to deno 2.3.2 (cherry picked from denoland/deno#29166) Co-authored-by: snek --- Cargo.lock | 73 +++++++++++++++----------------- Cargo.toml | 13 +++--- cts_runner/Cargo.toml | 1 + cts_runner/src/main.rs | 19 ++++----- deno_webgpu/Cargo.toml | 2 +- deno_webgpu/adapter.rs | 24 +++++++++-- deno_webgpu/bind_group.rs | 6 ++- deno_webgpu/bind_group_layout.rs | 6 ++- deno_webgpu/buffer.rs | 6 ++- deno_webgpu/byow.rs | 6 ++- deno_webgpu/command_buffer.rs | 6 ++- deno_webgpu/command_encoder.rs | 6 ++- deno_webgpu/compute_pass.rs | 6 ++- deno_webgpu/compute_pipeline.rs | 6 ++- deno_webgpu/device.rs | 12 +++++- deno_webgpu/lib.rs | 6 ++- deno_webgpu/pipeline_layout.rs | 6 ++- deno_webgpu/query_set.rs | 6 ++- deno_webgpu/queue.rs | 6 ++- deno_webgpu/render_bundle.rs | 12 +++++- deno_webgpu/render_pass.rs | 6 ++- deno_webgpu/render_pipeline.rs | 6 ++- deno_webgpu/sampler.rs | 6 ++- deno_webgpu/shader.rs | 18 ++++++-- deno_webgpu/surface.rs | 6 ++- deno_webgpu/texture.rs | 18 ++++++-- 26 files changed, 203 insertions(+), 85 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 877c766278e..e8882bfe614 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,12 +27,6 @@ dependencies = [ "gimli", ] -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "adler2" version = "2.0.1" @@ -304,7 +298,7 @@ dependencies = [ "addr2line", "cfg-if", "libc", - "miniz_oxide 0.8.9", + "miniz_oxide", "object", "rustc-demangle", "windows-targets 0.52.6", @@ -989,6 +983,7 @@ version = "26.0.0" dependencies = [ "deno_console", "deno_core", + "deno_features", "deno_url", "deno_web", "deno_webgpu", @@ -1022,18 +1017,18 @@ dependencies = [ [[package]] name = "deno_console" -version = "0.203.0" +version = "0.205.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "999171b0fc7255971eec7adfc49b2bf18832e86e4a86746c3c58633373d16cdb" +checksum = "f18e4a73bc0dd2a30dfbc14d8c2eb9b7347b7616acb6810d71e7912385c34f89" dependencies = [ "deno_core", ] [[package]] name = "deno_core" -version = "0.343.0" +version = "0.347.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167ae63972f6de58e4a548327f363ebc449930b62a44d9bbd80197564d2c755d" +checksum = "d75ae5562f6ad750bc2007e7b1032ae37115a83fe58b6fbc77331c47744956cc" dependencies = [ "anyhow", "az", @@ -1098,11 +1093,22 @@ dependencies = [ "syn", ] +[[package]] +name = "deno_features" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf0bffbb52e0ad53c50225cdf0c20b24501036c3948264a049487fc5e5c40f57" +dependencies = [ + "deno_core", + "serde", + "serde_json", +] + [[package]] name = "deno_ops" -version = "0.219.0" +version = "0.223.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "188e48d180244dae157d8a5126b8fbcecf6458f26a425f1c2f57b5952a1b5ee1" +checksum = "c5adc7f0795c7547f1b560a07aaea484e8f9cd035318348c6bfd084e0c42dce8" dependencies = [ "indexmap", "proc-macro-rules", @@ -1130,9 +1136,9 @@ dependencies = [ [[package]] name = "deno_permissions" -version = "0.62.0" +version = "0.64.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c3c0785bcb458cd010c47d7f77cae26594a5160ebfc4fecb6f9e5ea36483fc" +checksum = "501f5bb2f44b977eb682c42909df35b980edf5144d3b5f00796e96a67df0055c" dependencies = [ "capacity_builder", "deno_core", @@ -1173,9 +1179,9 @@ dependencies = [ [[package]] name = "deno_url" -version = "0.203.0" +version = "0.205.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0961e3e844191cac261eba5efdf52e2a5dd3aeeac7ebb09c1bbe3f8b04ef31cd" +checksum = "af2813696e113b21c288558151c86a0f60d1afda3458bc76e5d29173fe288c22" dependencies = [ "deno_core", "deno_error", @@ -1184,9 +1190,9 @@ dependencies = [ [[package]] name = "deno_web" -version = "0.234.0" +version = "0.236.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ec73d866d485bed1bd520f3a413a94b5c9a69de09d8561697d2bd83a79c795c" +checksum = "8b0885564bfade3284b26a29cb32a67ba7b75fe329b7f12bc0e26815acf7ae1c" dependencies = [ "async-trait", "base64-simd", @@ -1205,7 +1211,7 @@ dependencies = [ [[package]] name = "deno_webgpu" -version = "0.170.0" +version = "0.171.0" dependencies = [ "deno_core", "deno_error", @@ -1222,9 +1228,9 @@ dependencies = [ [[package]] name = "deno_webidl" -version = "0.203.0" +version = "0.205.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb50836af90d078b1f30f4df0e3398d557a74633b9b4740e10a299a83f12d054" +checksum = "7e4f3a7a4672a071d25e93b5598f4a8a4bfc20f2a8d6900a7a6a7d02264bc6f2" dependencies = [ "deno_core", ] @@ -1470,7 +1476,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ "crc32fast", - "miniz_oxide 0.8.9", + "miniz_oxide", ] [[package]] @@ -2436,15 +2442,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" -dependencies = [ - "adler", -] - [[package]] name = "miniz_oxide" version = "0.8.9" @@ -3232,7 +3229,7 @@ dependencies = [ "crc32fast", "fdeflate", "flate2", - "miniz_oxide 0.8.9", + "miniz_oxide", ] [[package]] @@ -3759,9 +3756,9 @@ dependencies = [ [[package]] name = "serde_v8" -version = "0.252.0" +version = "0.256.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b2d85f46747fad18bbf98ad4b9b13c59e01c85bf8c73182a71fdf638372dfd" +checksum = "69d69b4e574a9ec6bd0222463e50cf8531986d9c657543888e029d54d909b283" dependencies = [ "deno_error", "num-bigint", @@ -4499,16 +4496,16 @@ dependencies = [ [[package]] name = "v8" -version = "135.1.1" +version = "137.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171c7d65c2c71e7e02cbef7762787614cab3e9043d58b433ef65b4baa2f4614d" +checksum = "33995a1fee055ff743281cde33a41f0d618ee0bdbe8bdf6859e11864499c2595" dependencies = [ "bindgen", "bitflags 2.9.4", "fslock", "gzip-header", "home", - "miniz_oxide 0.7.4", + "miniz_oxide", "paste", "which 6.0.3", ] diff --git a/Cargo.toml b/Cargo.toml index b2fbb1dc7e5..22944f2c4a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -236,12 +236,13 @@ web-sys = { version = "0.3.77", default-features = false } web-time = "1.1.0" # deno dependencies -deno_console = "0.203.0" -deno_core = "0.343.0" -deno_url = "0.203.0" -deno_web = "0.234.0" -deno_webidl = "0.203.0" -deno_webgpu = { version = "0.170.0", path = "./deno_webgpu" } +deno_console = "0.205.0" +deno_core = "0.347.0" +deno_features = "0.2.0" +deno_url = "0.205.0" +deno_web = "0.236.0" +deno_webidl = "0.205.0" +deno_webgpu = { version = "0.171.0", path = "./deno_webgpu" } deno_unsync = "0.4.2" deno_error = "0.5.6" tokio = "1.45.1" diff --git a/cts_runner/Cargo.toml b/cts_runner/Cargo.toml index 6b96ae66c30..689297daf30 100644 --- a/cts_runner/Cargo.toml +++ b/cts_runner/Cargo.toml @@ -15,6 +15,7 @@ env_logger.workspace = true [target.'cfg(not(target_arch = "wasm32"))'.dependencies] deno_console.workspace = true deno_core.workspace = true +deno_features.workspace = true deno_url.workspace = true deno_web.workspace = true deno_webidl.workspace = true diff --git a/cts_runner/src/main.rs b/cts_runner/src/main.rs index 157567fe6e7..fed561760d7 100644 --- a/cts_runner/src/main.rs +++ b/cts_runner/src/main.rs @@ -30,23 +30,19 @@ pub async fn run() -> Result<(), AnyError> { .ok_or_else(|| anyhow!("missing specifier in first command line argument"))?; let specifier = resolve_url_or_path(&url, &env::current_dir()?)?; - let mut feature_checker = deno_core::FeatureChecker::default(); - feature_checker.enable_feature(deno_webgpu::UNSTABLE_FEATURE_NAME); - let options = RuntimeOptions { module_loader: Some(Rc::new(deno_core::FsModuleLoader)), extensions: vec![ - deno_webidl::deno_webidl::init_ops_and_esm(), - deno_console::deno_console::init_ops_and_esm(), - deno_url::deno_url::init_ops_and_esm(), - deno_web::deno_web::init_ops_and_esm::( + deno_webidl::deno_webidl::init(), + deno_console::deno_console::init(), + deno_url::deno_url::init(), + deno_web::deno_web::init::( Arc::new(BlobStore::default()), None, ), - deno_webgpu::deno_webgpu::init_ops_and_esm(), - cts_runner::init_ops_and_esm(), + deno_webgpu::deno_webgpu::init(), + cts_runner::init(), ], - feature_checker: Some(Arc::new(feature_checker)), ..Default::default() }; let mut js_runtime = JsRuntime::new(options); @@ -84,6 +80,9 @@ deno_core::extension!( esm_entry_point = "ext:cts_runner/src/bootstrap.js", esm = ["src/bootstrap.js"], state = |state| { + let mut feature_checker = deno_features::FeatureChecker::default(); + feature_checker.enable_feature(deno_webgpu::UNSTABLE_FEATURE_NAME); + state.put(feature_checker); state.put(Permissions {}); } ); diff --git a/deno_webgpu/Cargo.toml b/deno_webgpu/Cargo.toml index ace7ec550cb..1359694550f 100644 --- a/deno_webgpu/Cargo.toml +++ b/deno_webgpu/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_webgpu" -version = "0.170.0" +version = "0.171.0" authors = ["the Deno authors"] edition.workspace = true license = "MIT" diff --git a/deno_webgpu/adapter.rs b/deno_webgpu/adapter.rs index 5d1463c1aa6..e731c228731 100644 --- a/deno_webgpu/adapter.rs +++ b/deno_webgpu/adapter.rs @@ -60,7 +60,11 @@ impl Drop for GPUAdapter { } } -impl GarbageCollected for GPUAdapter {} +impl GarbageCollected for GPUAdapter { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUAdapter" + } +} #[op2] impl GPUAdapter { @@ -211,7 +215,11 @@ pub enum CreateDeviceError { pub struct GPUSupportedLimits(pub wgpu_types::Limits); -impl GarbageCollected for GPUSupportedLimits {} +impl GarbageCollected for GPUSupportedLimits { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUSupportedLimits" + } +} #[op2] impl GPUSupportedLimits { @@ -368,7 +376,11 @@ impl GPUSupportedLimits { pub struct GPUSupportedFeatures(v8::Global); -impl GarbageCollected for GPUSupportedFeatures {} +impl GarbageCollected for GPUSupportedFeatures { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUSupportedFeatures" + } +} impl GPUSupportedFeatures { #[allow(clippy::disallowed_types)] @@ -402,7 +414,11 @@ pub struct GPUAdapterInfo { pub subgroup_max_size: u32, } -impl GarbageCollected for GPUAdapterInfo {} +impl GarbageCollected for GPUAdapterInfo { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUAdapterInfo" + } +} #[op2] impl GPUAdapterInfo { diff --git a/deno_webgpu/bind_group.rs b/deno_webgpu/bind_group.rs index 80efba6efdd..3cd6580563f 100644 --- a/deno_webgpu/bind_group.rs +++ b/deno_webgpu/bind_group.rs @@ -35,7 +35,11 @@ impl WebIdlInterfaceConverter for GPUBindGroup { const NAME: &'static str = "GPUBindGroup"; } -impl GarbageCollected for GPUBindGroup {} +impl GarbageCollected for GPUBindGroup { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUBindGroup" + } +} #[op2] impl GPUBindGroup { diff --git a/deno_webgpu/bind_group_layout.rs b/deno_webgpu/bind_group_layout.rs index 3ebe594620e..7b50e6e05ee 100644 --- a/deno_webgpu/bind_group_layout.rs +++ b/deno_webgpu/bind_group_layout.rs @@ -23,7 +23,11 @@ impl deno_core::webidl::WebIdlInterfaceConverter for GPUBindGroupLayout { const NAME: &'static str = "GPUBindGroupLayout"; } -impl GarbageCollected for GPUBindGroupLayout {} +impl GarbageCollected for GPUBindGroupLayout { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUBindGroupLayout" + } +} #[op2] impl GPUBindGroupLayout { diff --git a/deno_webgpu/buffer.rs b/deno_webgpu/buffer.rs index 0f0e4990504..e2ef511f38f 100644 --- a/deno_webgpu/buffer.rs +++ b/deno_webgpu/buffer.rs @@ -72,7 +72,11 @@ impl WebIdlInterfaceConverter for GPUBuffer { const NAME: &'static str = "GPUBuffer"; } -impl GarbageCollected for GPUBuffer {} +impl GarbageCollected for GPUBuffer { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUBuffer" + } +} #[op2] impl GPUBuffer { diff --git a/deno_webgpu/byow.rs b/deno_webgpu/byow.rs index 1079bed2228..4c2bed9229c 100644 --- a/deno_webgpu/byow.rs +++ b/deno_webgpu/byow.rs @@ -83,7 +83,11 @@ pub struct UnsafeWindowSurface { pub context: SameObject, } -impl GarbageCollected for UnsafeWindowSurface {} +impl GarbageCollected for UnsafeWindowSurface { + fn get_name(&self) -> &'static std::ffi::CStr { + c"UnsafeWindowSurface" + } +} #[op2] impl UnsafeWindowSurface { diff --git a/deno_webgpu/command_buffer.rs b/deno_webgpu/command_buffer.rs index d03311376c4..9b3ad5cfabb 100644 --- a/deno_webgpu/command_buffer.rs +++ b/deno_webgpu/command_buffer.rs @@ -22,7 +22,11 @@ impl deno_core::webidl::WebIdlInterfaceConverter for GPUCommandBuffer { const NAME: &'static str = "GPUCommandBuffer"; } -impl GarbageCollected for GPUCommandBuffer {} +impl GarbageCollected for GPUCommandBuffer { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUCommandBuffer" + } +} #[op2] impl GPUCommandBuffer { diff --git a/deno_webgpu/command_encoder.rs b/deno_webgpu/command_encoder.rs index 91a4146da7a..6587b23d3e1 100644 --- a/deno_webgpu/command_encoder.rs +++ b/deno_webgpu/command_encoder.rs @@ -36,7 +36,11 @@ impl Drop for GPUCommandEncoder { } } -impl GarbageCollected for GPUCommandEncoder {} +impl GarbageCollected for GPUCommandEncoder { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUCommandEncoder" + } +} #[op2] impl GPUCommandEncoder { diff --git a/deno_webgpu/compute_pass.rs b/deno_webgpu/compute_pass.rs index f9c837ed339..9dd617968ec 100644 --- a/deno_webgpu/compute_pass.rs +++ b/deno_webgpu/compute_pass.rs @@ -23,7 +23,11 @@ pub struct GPUComputePassEncoder { pub label: String, } -impl GarbageCollected for GPUComputePassEncoder {} +impl GarbageCollected for GPUComputePassEncoder { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUComputePassEncoder" + } +} #[op2] impl GPUComputePassEncoder { diff --git a/deno_webgpu/compute_pipeline.rs b/deno_webgpu/compute_pipeline.rs index 456ec9fb45c..1803c4b6859 100644 --- a/deno_webgpu/compute_pipeline.rs +++ b/deno_webgpu/compute_pipeline.rs @@ -30,7 +30,11 @@ impl WebIdlInterfaceConverter for GPUComputePipeline { const NAME: &'static str = "GPUComputePipeline"; } -impl GarbageCollected for GPUComputePipeline {} +impl GarbageCollected for GPUComputePipeline { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUComputePipeline" + } +} #[op2] impl GPUComputePipeline { diff --git a/deno_webgpu/device.rs b/deno_webgpu/device.rs index ee99ace3676..186bb13f12d 100644 --- a/deno_webgpu/device.rs +++ b/deno_webgpu/device.rs @@ -66,7 +66,11 @@ impl WebIdlInterfaceConverter for GPUDevice { const NAME: &'static str = "GPUDevice"; } -impl GarbageCollected for GPUDevice {} +impl GarbageCollected for GPUDevice { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUDevice" + } +} // EventTarget is extended in JS #[op2] @@ -897,7 +901,11 @@ pub struct GPUDeviceLostInfo { pub reason: GPUDeviceLostReason, } -impl GarbageCollected for GPUDeviceLostInfo {} +impl GarbageCollected for GPUDeviceLostInfo { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUDeviceLostInfo" + } +} #[op2] impl GPUDeviceLostInfo { diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index d529ca84860..8ab4f5b870a 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -130,7 +130,11 @@ struct ErrorEventClass(v8::Global); pub struct GPU; -impl GarbageCollected for GPU {} +impl GarbageCollected for GPU { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPU" + } +} #[op2] impl GPU { diff --git a/deno_webgpu/pipeline_layout.rs b/deno_webgpu/pipeline_layout.rs index 4f507cf71be..15c9b4d4fc5 100644 --- a/deno_webgpu/pipeline_layout.rs +++ b/deno_webgpu/pipeline_layout.rs @@ -24,7 +24,11 @@ impl WebIdlInterfaceConverter for GPUPipelineLayout { const NAME: &'static str = "GPUPipelineLayout"; } -impl GarbageCollected for GPUPipelineLayout {} +impl GarbageCollected for GPUPipelineLayout { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUPipelineLayout" + } +} #[op2] impl GPUPipelineLayout { diff --git a/deno_webgpu/query_set.rs b/deno_webgpu/query_set.rs index f2657c7d54b..c23186883cb 100644 --- a/deno_webgpu/query_set.rs +++ b/deno_webgpu/query_set.rs @@ -26,7 +26,11 @@ impl WebIdlInterfaceConverter for GPUQuerySet { const NAME: &'static str = "GPUQuerySet"; } -impl GarbageCollected for GPUQuerySet {} +impl GarbageCollected for GPUQuerySet { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUQuerySet" + } +} #[op2] impl GPUQuerySet { diff --git a/deno_webgpu/queue.rs b/deno_webgpu/queue.rs index 1fa78a25a0c..3797293335c 100644 --- a/deno_webgpu/queue.rs +++ b/deno_webgpu/queue.rs @@ -36,7 +36,11 @@ impl Drop for GPUQueue { } } -impl GarbageCollected for GPUQueue {} +impl GarbageCollected for GPUQueue { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUQueue" + } +} #[op2] impl GPUQueue { diff --git a/deno_webgpu/render_bundle.rs b/deno_webgpu/render_bundle.rs index 6f3aea74fac..ba6cb7170dc 100644 --- a/deno_webgpu/render_bundle.rs +++ b/deno_webgpu/render_bundle.rs @@ -37,7 +37,11 @@ pub struct GPURenderBundleEncoder { pub label: String, } -impl GarbageCollected for GPURenderBundleEncoder {} +impl GarbageCollected for GPURenderBundleEncoder { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPURenderBundleEncoder" + } +} #[op2] impl GPURenderBundleEncoder { @@ -407,7 +411,11 @@ impl WebIdlInterfaceConverter for GPURenderBundle { const NAME: &'static str = "GPURenderBundle"; } -impl GarbageCollected for GPURenderBundle {} +impl GarbageCollected for GPURenderBundle { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPURenderBundle" + } +} #[op2] impl GPURenderBundle { diff --git a/deno_webgpu/render_pass.rs b/deno_webgpu/render_pass.rs index d3d8e669283..5cfa576060b 100644 --- a/deno_webgpu/render_pass.rs +++ b/deno_webgpu/render_pass.rs @@ -28,7 +28,11 @@ pub struct GPURenderPassEncoder { pub label: String, } -impl GarbageCollected for GPURenderPassEncoder {} +impl GarbageCollected for GPURenderPassEncoder { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPURenderPassEncoder" + } +} #[op2] impl GPURenderPassEncoder { diff --git a/deno_webgpu/render_pipeline.rs b/deno_webgpu/render_pipeline.rs index 5b85efb9dfb..84f1477fb39 100644 --- a/deno_webgpu/render_pipeline.rs +++ b/deno_webgpu/render_pipeline.rs @@ -33,7 +33,11 @@ impl WebIdlInterfaceConverter for GPURenderPipeline { const NAME: &'static str = "GPURenderPipeline"; } -impl GarbageCollected for GPURenderPipeline {} +impl GarbageCollected for GPURenderPipeline { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPURenderPipeline" + } +} #[op2] impl GPURenderPipeline { diff --git a/deno_webgpu/sampler.rs b/deno_webgpu/sampler.rs index 997d2acde25..2af3f9d4216 100644 --- a/deno_webgpu/sampler.rs +++ b/deno_webgpu/sampler.rs @@ -23,7 +23,11 @@ impl WebIdlInterfaceConverter for GPUSampler { const NAME: &'static str = "GPUSampler"; } -impl GarbageCollected for GPUSampler {} +impl GarbageCollected for GPUSampler { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUSampler" + } +} #[op2] impl GPUSampler { diff --git a/deno_webgpu/shader.rs b/deno_webgpu/shader.rs index ab19c15c73d..b449a6534ab 100644 --- a/deno_webgpu/shader.rs +++ b/deno_webgpu/shader.rs @@ -27,7 +27,11 @@ impl WebIdlInterfaceConverter for GPUShaderModule { const NAME: &'static str = "GPUShaderModule"; } -impl GarbageCollected for GPUShaderModule {} +impl GarbageCollected for GPUShaderModule { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUShaderModule" + } +} #[op2] impl GPUShaderModule { @@ -71,7 +75,11 @@ pub struct GPUCompilationMessage { length: u64, } -impl GarbageCollected for GPUCompilationMessage {} +impl GarbageCollected for GPUCompilationMessage { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUCompilationMessage" + } +} #[op2] impl GPUCompilationMessage { @@ -162,7 +170,11 @@ pub struct GPUCompilationInfo { messages: v8::Global, } -impl GarbageCollected for GPUCompilationInfo {} +impl GarbageCollected for GPUCompilationInfo { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUCompilationInfo" + } +} #[op2] impl GPUCompilationInfo { diff --git a/deno_webgpu/surface.rs b/deno_webgpu/surface.rs index aab7d916a9f..bbecdbc3113 100644 --- a/deno_webgpu/surface.rs +++ b/deno_webgpu/surface.rs @@ -45,7 +45,11 @@ pub struct GPUCanvasContext { pub canvas: v8::Global, } -impl GarbageCollected for GPUCanvasContext {} +impl GarbageCollected for GPUCanvasContext { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUCanvasContext" + } +} #[op2] impl GPUCanvasContext { diff --git a/deno_webgpu/texture.rs b/deno_webgpu/texture.rs index aa36069e60e..af876bc4b01 100644 --- a/deno_webgpu/texture.rs +++ b/deno_webgpu/texture.rs @@ -63,7 +63,11 @@ impl WebIdlInterfaceConverter for GPUTexture { const NAME: &'static str = "GPUTexture"; } -impl GarbageCollected for GPUTexture {} +impl GarbageCollected for GPUTexture { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUTexture" + } +} #[op2] impl GPUTexture { @@ -243,7 +247,11 @@ impl WebIdlInterfaceConverter for GPUTextureView { const NAME: &'static str = "GPUTextureView"; } -impl GarbageCollected for GPUTextureView {} +impl GarbageCollected for GPUTextureView { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUTextureView" + } +} // TODO(@crowlKats): weakref in texture for view #[op2] @@ -668,7 +676,11 @@ impl WebIdlInterfaceConverter for GPUExternalTexture { const NAME: &'static str = "GPUExternalTexture"; } -impl GarbageCollected for GPUExternalTexture {} +impl GarbageCollected for GPUExternalTexture { + fn get_name(&self) -> &'static std::ffi::CStr { + c"GPUExternalTexture" + } +} #[op2] impl GPUExternalTexture {} From eb3bed5f534399fa90aa8a0bf03b2a3c787e7c57 Mon Sep 17 00:00:00 2001 From: chirsz Date: Wed, 17 Sep 2025 15:35:30 -0400 Subject: [PATCH 245/303] [deno] add `resize` method to `UnsafeWindowSurface` (cherry-picked from denoland/deno#29254) --- deno_webgpu/byow.rs | 12 ++++++++++++ deno_webgpu/surface.rs | 24 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/deno_webgpu/byow.rs b/deno_webgpu/byow.rs index 4c2bed9229c..0571a80d7b8 100644 --- a/deno_webgpu/byow.rs +++ b/deno_webgpu/byow.rs @@ -163,6 +163,18 @@ impl UnsafeWindowSurface { context.present().map_err(JsErrorBox::from_err) } + + #[fast] + fn resize(&self, width: u32, height: u32, scope: &mut v8::HandleScope) { + self.width.replace(width); + self.height.replace(height); + + let Some(context) = self.context.try_unwrap(scope) else { + return; + }; + + context.resize_configure(width, height); + } } struct UnsafeWindowSurfaceOptions { diff --git a/deno_webgpu/surface.rs b/deno_webgpu/surface.rs index bbecdbc3113..0a042a95496 100644 --- a/deno_webgpu/surface.rs +++ b/deno_webgpu/surface.rs @@ -32,6 +32,8 @@ pub struct Configuration { pub device: Ptr, pub usage: u32, pub format: GPUTextureFormat, + pub surface_config: + wgpu_types::SurfaceConfiguration>, } pub struct GPUCanvasContext { @@ -97,6 +99,7 @@ impl GPUCanvasContext { device, usage: configuration.usage, format: configuration.format, + surface_config: conf, }); Ok(()) @@ -173,6 +176,27 @@ impl GPUCanvasContext { Ok(()) } + + pub fn resize_configure(&self, width: u32, height: u32) { + self.width.replace(width); + self.height.replace(height); + + let mut config = self.config.borrow_mut(); + let Some(config) = &mut *config else { + return; + }; + + config.surface_config.width = width; + config.surface_config.height = height; + + let err = config.device.instance.surface_configure( + self.surface_id, + config.device.id, + &config.surface_config, + ); + + config.device.error_handler.push_error(err); + } } #[derive(WebIDL)] From 7f30a8d66efcdcc4ad6b55ea6861a665111128e6 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 17 Sep 2025 15:30:13 -0400 Subject: [PATCH 246/303] [deno] Switch rustfmt to edition 2024 --- cts_runner/src/main.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/cts_runner/src/main.rs b/cts_runner/src/main.rs index fed561760d7..cbb88b866f7 100644 --- a/cts_runner/src/main.rs +++ b/cts_runner/src/main.rs @@ -36,10 +36,7 @@ pub async fn run() -> Result<(), AnyError> { deno_webidl::deno_webidl::init(), deno_console::deno_console::init(), deno_url::deno_url::init(), - deno_web::deno_web::init::( - Arc::new(BlobStore::default()), - None, - ), + deno_web::deno_web::init::(Arc::new(BlobStore::default()), None), deno_webgpu::deno_webgpu::init(), cts_runner::init(), ], From ad4f10f60f97ed493539ee968354c42d8888a85b Mon Sep 17 00:00:00 2001 From: cions Date: Wed, 17 Sep 2025 15:35:05 -0400 Subject: [PATCH 247/303] [deno] fix android build (cherry-picked from denoland/deno#30360) --- deno_webgpu/byow.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/deno_webgpu/byow.rs b/deno_webgpu/byow.rs index 0571a80d7b8..c6e6e71688d 100644 --- a/deno_webgpu/byow.rs +++ b/deno_webgpu/byow.rs @@ -24,6 +24,16 @@ use crate::surface::GPUCanvasContext; #[derive(Debug, thiserror::Error, deno_error::JsError)] pub enum ByowError { + #[cfg(not(any( + target_os = "macos", + target_os = "windows", + target_os = "linux", + target_os = "freebsd", + target_os = "openbsd", + )))] + #[class(type)] + #[error("Unsupported platform")] + Unsupported, #[class(type)] #[error( "Cannot create surface outside of WebGPU context. Did you forget to call `navigator.gpu.requestAdapter()`?" @@ -360,6 +370,6 @@ fn raw_window( _system: UnsafeWindowSurfaceSystem, _window: *const c_void, _display: *const c_void, -) -> Result { - Err(deno_error::JsErrorBox::type_error("Unsupported platform")) +) -> Result { + Err(ByowError::Unsupported) } From 492fb59648b313b2bbb31f66e4c90503e9222c5c Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 17 Sep 2025 15:13:44 -0400 Subject: [PATCH 248/303] Update to deno 2.4.5 --- Cargo.lock | 96 +++++++++++++++++++++++++++++------------- Cargo.toml | 18 ++++---- deno_webgpu/Cargo.toml | 2 +- 3 files changed, 77 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e8882bfe614..7ccdeeccbe0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -446,6 +446,16 @@ dependencies = [ "objc2 0.5.2", ] +[[package]] +name = "boxed_error" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17d4f95e880cfd28c4ca5a006cf7f6af52b4bcb7b5866f573b2faa126fb7affb" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "bumpalo" version = "3.19.0" @@ -1017,24 +1027,25 @@ dependencies = [ [[package]] name = "deno_console" -version = "0.205.0" +version = "0.214.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f18e4a73bc0dd2a30dfbc14d8c2eb9b7347b7616acb6810d71e7912385c34f89" +checksum = "74189b98d1245bcef3a7565cbfe5cad4ab3d2ad9393aa48067fab89efe85a99b" dependencies = [ "deno_core", ] [[package]] name = "deno_core" -version = "0.347.0" +version = "0.355.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75ae5562f6ad750bc2007e7b1032ae37115a83fe58b6fbc77331c47744956cc" +checksum = "775d2fde80a2ec3116d179703b38346a931bb9626f4a826148d5fe8631cab29f" dependencies = [ "anyhow", "az", "bincode 1.3.3", "bit-set", "bit-vec", + "boxed_error", "bytes", "capacity_builder", "cooked-waker", @@ -1070,9 +1081,9 @@ checksum = "fe4dccb6147bb3f3ba0c7a48e993bfeb999d2c2e47a81badee80e2b370c8d695" [[package]] name = "deno_error" -version = "0.5.6" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19fae9fe305307b5ef3ee4e8244c79cffcca421ab0ce8634dea0c6b1342f220f" +checksum = "dde60bd153886964234c5012d3d9caf788287f28d81fb24a884436904101ef10" dependencies = [ "deno_error_macro", "libc", @@ -1084,9 +1095,9 @@ dependencies = [ [[package]] name = "deno_error_macro" -version = "0.5.6" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5abb2556e91848b66f562451fcbcdee2a3b7c88281828908dcf7cca355f5d997" +checksum = "409f265785bd946d3006756955aaf40b0e4deb25752eae6a990afe54a31cfd83" dependencies = [ "proc-macro2", "quote", @@ -1095,9 +1106,9 @@ dependencies = [ [[package]] name = "deno_features" -version = "0.2.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf0bffbb52e0ad53c50225cdf0c20b24501036c3948264a049487fc5e5c40f57" +checksum = "ea79a01229bd5f8ee4ba784811f421a90a1ac241da4dc015a3f58380167c9944" dependencies = [ "deno_core", "serde", @@ -1106,9 +1117,9 @@ dependencies = [ [[package]] name = "deno_ops" -version = "0.223.0" +version = "0.231.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5adc7f0795c7547f1b560a07aaea484e8f9cd035318348c6bfd084e0c42dce8" +checksum = "9ca530772bbcbc9ad389ad7bcd86623b2ec555f68a2d062d23cc008915cbe781" dependencies = [ "indexmap", "proc-macro-rules", @@ -1123,9 +1134,9 @@ dependencies = [ [[package]] name = "deno_path_util" -version = "0.3.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c238a664a0a6f1ce0ff2b73c6854811526d00f442a12f878cb8555b23fe13aa3" +checksum = "bfe02936964b2910719bd488841f6e884349360113c7abf6f4c6b28ca9cd7a19" dependencies = [ "deno_error", "percent-encoding", @@ -1136,24 +1147,31 @@ dependencies = [ [[package]] name = "deno_permissions" -version = "0.64.0" +version = "0.73.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501f5bb2f44b977eb682c42909df35b980edf5144d3b5f00796e96a67df0055c" +checksum = "656d8cc364ca906e12fb83d379202983052c6aa3e7420e385559e903d2773f61" dependencies = [ "capacity_builder", - "deno_core", "deno_error", "deno_path_util", "deno_terminal", + "deno_unsync", "fqdn", + "ipnetwork", "libc", "log", + "nix", "once_cell", + "parking_lot", "percent-encoding", "serde", + "serde_json", + "sys_traits", "thiserror 2.0.16", - "which 6.0.3", + "url", + "which 8.0.0", "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -1179,9 +1197,9 @@ dependencies = [ [[package]] name = "deno_url" -version = "0.205.0" +version = "0.214.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af2813696e113b21c288558151c86a0f60d1afda3458bc76e5d29173fe288c22" +checksum = "a4f02fd80dda41f1e278c69170b802004c0094ceef2dde68bc117a69dc5702cf" dependencies = [ "deno_core", "deno_error", @@ -1190,9 +1208,9 @@ dependencies = [ [[package]] name = "deno_web" -version = "0.236.0" +version = "0.245.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b0885564bfade3284b26a29cb32a67ba7b75fe329b7f12bc0e26815acf7ae1c" +checksum = "56fbbfb92fa76a4e0873d1b02f5e9947562e70ac7ec065ba794b08aca3760564" dependencies = [ "async-trait", "base64-simd", @@ -1211,7 +1229,7 @@ dependencies = [ [[package]] name = "deno_webgpu" -version = "0.171.0" +version = "0.181.0" dependencies = [ "deno_core", "deno_error", @@ -1228,9 +1246,9 @@ dependencies = [ [[package]] name = "deno_webidl" -version = "0.205.0" +version = "0.214.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4f3a7a4672a071d25e93b5598f4a8a4bfc20f2a8d6900a7a6a7d02264bc6f2" +checksum = "b29a947a96dc0f672741669470f0260eba20d198436143b40afb9bda97723f07" dependencies = [ "deno_core", ] @@ -2126,6 +2144,15 @@ dependencies = [ "libc", ] +[[package]] +name = "ipnetwork" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e" +dependencies = [ + "serde", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -2654,6 +2681,17 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "nix" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +dependencies = [ + "bitflags 2.9.4", + "cfg-if", + "libc", +] + [[package]] name = "noise" version = "0.9.0" @@ -3756,9 +3794,9 @@ dependencies = [ [[package]] name = "serde_v8" -version = "0.256.0" +version = "0.264.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d69b4e574a9ec6bd0222463e50cf8531986d9c657543888e029d54d909b283" +checksum = "c34707712f3815e73e1c8319bba06e5bc105bb65fe812ea2e7279ffb905f6312" dependencies = [ "deno_error", "num-bigint", @@ -4657,9 +4695,9 @@ dependencies = [ [[package]] name = "wasm_dep_analyzer" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eeee3bdea6257cc36d756fa745a70f9d393571e47d69e0ed97581676a5369ca" +checksum = "a10e6b67c951a84de7029487e0e0a496860dae49f6699edd279d5ff35b8fbf54" dependencies = [ "deno_error", "thiserror 2.0.16", diff --git a/Cargo.toml b/Cargo.toml index 22944f2c4a9..bd58ec379ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -236,15 +236,15 @@ web-sys = { version = "0.3.77", default-features = false } web-time = "1.1.0" # deno dependencies -deno_console = "0.205.0" -deno_core = "0.347.0" -deno_features = "0.2.0" -deno_url = "0.205.0" -deno_web = "0.236.0" -deno_webidl = "0.205.0" -deno_webgpu = { version = "0.171.0", path = "./deno_webgpu" } -deno_unsync = "0.4.2" -deno_error = "0.5.6" +deno_console = "0.214.0" +deno_core = "0.355.0" +deno_features = "0.11.0" +deno_url = "0.214.0" +deno_web = "0.245.0" +deno_webidl = "0.214.0" +deno_webgpu = { version = "0.181.0", path = "./deno_webgpu" } +deno_unsync = "0.4.4" +deno_error = "0.7.0" tokio = "1.45.1" termcolor = "1.1.3" diff --git a/deno_webgpu/Cargo.toml b/deno_webgpu/Cargo.toml index 1359694550f..52df54ec76d 100644 --- a/deno_webgpu/Cargo.toml +++ b/deno_webgpu/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "deno_webgpu" -version = "0.171.0" +version = "0.181.0" authors = ["the Deno authors"] edition.workspace = true license = "MIT" From 67f7a4ea3b1225a9bd8fcde955da10eb389c8322 Mon Sep 17 00:00:00 2001 From: Kenta Moriuchi Date: Wed, 17 Sep 2025 15:05:34 -0400 Subject: [PATCH 249/303] [deno] add illegal constructor errors (cherry-picked from denoland/deno#30500) --- deno_webgpu/adapter.rs | 25 +++++++++++++++++++++++++ deno_webgpu/bind_group.rs | 7 +++++++ deno_webgpu/bind_group_layout.rs | 7 +++++++ deno_webgpu/buffer.rs | 7 +++++++ deno_webgpu/command_buffer.rs | 7 +++++++ deno_webgpu/command_encoder.rs | 7 +++++++ deno_webgpu/compute_pass.rs | 7 +++++++ deno_webgpu/compute_pipeline.rs | 7 +++++++ deno_webgpu/device.rs | 14 +++++++++++++- deno_webgpu/error.rs | 7 +++++++ deno_webgpu/lib.rs | 8 ++++++++ deno_webgpu/pipeline_layout.rs | 7 +++++++ deno_webgpu/query_set.rs | 7 +++++++ deno_webgpu/queue.rs | 7 +++++++ deno_webgpu/render_bundle.rs | 13 +++++++++++++ deno_webgpu/render_pass.rs | 7 +++++++ deno_webgpu/render_pipeline.rs | 7 +++++++ deno_webgpu/sampler.rs | 7 +++++++ deno_webgpu/shader.rs | 7 +++++++ deno_webgpu/surface.rs | 7 +++++++ deno_webgpu/texture.rs | 13 +++++++++++++ 21 files changed, 184 insertions(+), 1 deletion(-) diff --git a/deno_webgpu/adapter.rs b/deno_webgpu/adapter.rs index e731c228731..711a7190c7b 100644 --- a/deno_webgpu/adapter.rs +++ b/deno_webgpu/adapter.rs @@ -13,6 +13,7 @@ use deno_core::V8TaskSpawner; use deno_core::WebIDL; use super::device::GPUDevice; +use crate::error::GPUGenericError; use crate::webidl::features_to_feature_names; use crate::webidl::GPUFeatureName; use crate::Instance; @@ -68,6 +69,12 @@ impl GarbageCollected for GPUAdapter { #[op2] impl GPUAdapter { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[global] fn info(&self, scope: &mut v8::HandleScope) -> v8::Global { @@ -223,6 +230,12 @@ impl GarbageCollected for GPUSupportedLimits { #[op2] impl GPUSupportedLimits { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] fn maxTextureDimension1D(&self) -> u32 { self.0.max_texture_dimension_1d @@ -401,6 +414,12 @@ impl GPUSupportedFeatures { #[op2] impl GPUSupportedFeatures { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[global] #[symbol("setlike_set")] fn set(&self) -> v8::Global { @@ -422,6 +441,12 @@ impl GarbageCollected for GPUAdapterInfo { #[op2] impl GPUAdapterInfo { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn vendor(&self) -> String { diff --git a/deno_webgpu/bind_group.rs b/deno_webgpu/bind_group.rs index 3cd6580563f..d003ede445a 100644 --- a/deno_webgpu/bind_group.rs +++ b/deno_webgpu/bind_group.rs @@ -15,6 +15,7 @@ use deno_core::GarbageCollected; use deno_core::WebIDL; use crate::buffer::GPUBuffer; +use crate::error::GPUGenericError; use crate::sampler::GPUSampler; use crate::texture::GPUTextureView; use crate::Instance; @@ -43,6 +44,12 @@ impl GarbageCollected for GPUBindGroup { #[op2] impl GPUBindGroup { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn label(&self) -> String { diff --git a/deno_webgpu/bind_group_layout.rs b/deno_webgpu/bind_group_layout.rs index 7b50e6e05ee..79b7bbe0bd7 100644 --- a/deno_webgpu/bind_group_layout.rs +++ b/deno_webgpu/bind_group_layout.rs @@ -4,6 +4,7 @@ use deno_core::op2; use deno_core::GarbageCollected; use deno_core::WebIDL; +use crate::error::GPUGenericError; use crate::texture::GPUTextureViewDimension; use crate::Instance; @@ -31,6 +32,12 @@ impl GarbageCollected for GPUBindGroupLayout { #[op2] impl GPUBindGroupLayout { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn label(&self) -> String { diff --git a/deno_webgpu/buffer.rs b/deno_webgpu/buffer.rs index e2ef511f38f..bff429dfec9 100644 --- a/deno_webgpu/buffer.rs +++ b/deno_webgpu/buffer.rs @@ -13,6 +13,7 @@ use deno_core::WebIDL; use deno_error::JsErrorBox; use wgpu_core::device::HostMap as MapMode; +use crate::error::GPUGenericError; use crate::Instance; #[derive(WebIDL)] @@ -80,6 +81,12 @@ impl GarbageCollected for GPUBuffer { #[op2] impl GPUBuffer { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn label(&self) -> String { diff --git a/deno_webgpu/command_buffer.rs b/deno_webgpu/command_buffer.rs index 9b3ad5cfabb..6ad6dbc09bf 100644 --- a/deno_webgpu/command_buffer.rs +++ b/deno_webgpu/command_buffer.rs @@ -4,6 +4,7 @@ use deno_core::op2; use deno_core::GarbageCollected; use deno_core::WebIDL; +use crate::error::GPUGenericError; use crate::Instance; pub struct GPUCommandBuffer { @@ -30,6 +31,12 @@ impl GarbageCollected for GPUCommandBuffer { #[op2] impl GPUCommandBuffer { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn label(&self) -> String { diff --git a/deno_webgpu/command_encoder.rs b/deno_webgpu/command_encoder.rs index 6587b23d3e1..91ea14aea41 100644 --- a/deno_webgpu/command_encoder.rs +++ b/deno_webgpu/command_encoder.rs @@ -16,6 +16,7 @@ use wgpu_types::{BufferAddress, TexelCopyBufferInfo}; use crate::buffer::GPUBuffer; use crate::command_buffer::GPUCommandBuffer; use crate::compute_pass::GPUComputePassEncoder; +use crate::error::GPUGenericError; use crate::queue::GPUTexelCopyTextureInfo; use crate::render_pass::GPULoadOp; use crate::render_pass::GPURenderPassEncoder; @@ -44,6 +45,12 @@ impl GarbageCollected for GPUCommandEncoder { #[op2] impl GPUCommandEncoder { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn label(&self) -> String { diff --git a/deno_webgpu/compute_pass.rs b/deno_webgpu/compute_pass.rs index 9dd617968ec..9fae680fba9 100644 --- a/deno_webgpu/compute_pass.rs +++ b/deno_webgpu/compute_pass.rs @@ -13,6 +13,7 @@ use deno_core::webidl::WebIdlError; use deno_core::GarbageCollected; use deno_core::WebIDL; +use crate::error::GPUGenericError; use crate::Instance; pub struct GPUComputePassEncoder { @@ -31,6 +32,12 @@ impl GarbageCollected for GPUComputePassEncoder { #[op2] impl GPUComputePassEncoder { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn label(&self) -> String { diff --git a/deno_webgpu/compute_pipeline.rs b/deno_webgpu/compute_pipeline.rs index 1803c4b6859..bd7a9695986 100644 --- a/deno_webgpu/compute_pipeline.rs +++ b/deno_webgpu/compute_pipeline.rs @@ -8,6 +8,7 @@ use deno_core::WebIDL; use indexmap::IndexMap; use crate::bind_group_layout::GPUBindGroupLayout; +use crate::error::GPUGenericError; use crate::shader::GPUShaderModule; use crate::webidl::GPUPipelineLayoutOrGPUAutoLayoutMode; use crate::Instance; @@ -38,6 +39,12 @@ impl GarbageCollected for GPUComputePipeline { #[op2] impl GPUComputePipeline { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn label(&self) -> String { diff --git a/deno_webgpu/device.rs b/deno_webgpu/device.rs index 186bb13f12d..aef52607feb 100644 --- a/deno_webgpu/device.rs +++ b/deno_webgpu/device.rs @@ -30,7 +30,7 @@ use crate::adapter::GPUAdapterInfo; use crate::adapter::GPUSupportedFeatures; use crate::adapter::GPUSupportedLimits; use crate::command_encoder::GPUCommandEncoder; -use crate::error::GPUError; +use crate::error::{GPUError, GPUGenericError}; use crate::query_set::GPUQuerySet; use crate::render_bundle::GPURenderBundleEncoder; use crate::render_pipeline::GPURenderPipeline; @@ -75,6 +75,12 @@ impl GarbageCollected for GPUDevice { // EventTarget is extended in JS #[op2] impl GPUDevice { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn label(&self) -> String { @@ -909,6 +915,12 @@ impl GarbageCollected for GPUDeviceLostInfo { #[op2] impl GPUDeviceLostInfo { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn reason(&self) -> &'static str { diff --git a/deno_webgpu/error.rs b/deno_webgpu/error.rs index 2f727f2cc4d..57bfd144512 100644 --- a/deno_webgpu/error.rs +++ b/deno_webgpu/error.rs @@ -372,3 +372,10 @@ impl From for GPUError { GPUError::from_webgpu(err) } } + +#[derive(Debug, thiserror::Error, deno_error::JsError)] +pub enum GPUGenericError { + #[class(type)] + #[error("Illegal constructor")] + InvalidConstructor, +} diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index 8ab4f5b870a..2b6dfcfee4e 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -15,6 +15,8 @@ pub use wgpu_core; pub use wgpu_types; use wgpu_types::PowerPreference; +use crate::error::GPUGenericError; + mod adapter; mod bind_group; mod bind_group_layout; @@ -138,6 +140,12 @@ impl GarbageCollected for GPU { #[op2] impl GPU { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[async_method] #[cppgc] async fn request_adapter( diff --git a/deno_webgpu/pipeline_layout.rs b/deno_webgpu/pipeline_layout.rs index 15c9b4d4fc5..1d71a9902f4 100644 --- a/deno_webgpu/pipeline_layout.rs +++ b/deno_webgpu/pipeline_layout.rs @@ -6,6 +6,7 @@ use deno_core::webidl::WebIdlInterfaceConverter; use deno_core::GarbageCollected; use deno_core::WebIDL; +use crate::error::GPUGenericError; use crate::Instance; pub struct GPUPipelineLayout { @@ -32,6 +33,12 @@ impl GarbageCollected for GPUPipelineLayout { #[op2] impl GPUPipelineLayout { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn label(&self) -> String { diff --git a/deno_webgpu/query_set.rs b/deno_webgpu/query_set.rs index c23186883cb..c726ad6059e 100644 --- a/deno_webgpu/query_set.rs +++ b/deno_webgpu/query_set.rs @@ -6,6 +6,7 @@ use deno_core::GarbageCollected; use deno_core::WebIDL; use deno_error::JsErrorBox; +use crate::error::GPUGenericError; use crate::Instance; pub struct GPUQuerySet { @@ -34,6 +35,12 @@ impl GarbageCollected for GPUQuerySet { #[op2] impl GPUQuerySet { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn label(&self) -> String { diff --git a/deno_webgpu/queue.rs b/deno_webgpu/queue.rs index 3797293335c..89a153c87ec 100644 --- a/deno_webgpu/queue.rs +++ b/deno_webgpu/queue.rs @@ -14,6 +14,7 @@ use deno_error::JsErrorBox; use crate::buffer::GPUBuffer; use crate::command_buffer::GPUCommandBuffer; +use crate::error::GPUGenericError; use crate::texture::GPUTexture; use crate::texture::GPUTextureAspect; use crate::webidl::GPUExtent3D; @@ -44,6 +45,12 @@ impl GarbageCollected for GPUQueue { #[op2] impl GPUQueue { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn label(&self) -> String { diff --git a/deno_webgpu/render_bundle.rs b/deno_webgpu/render_bundle.rs index ba6cb7170dc..4dd19b9a969 100644 --- a/deno_webgpu/render_bundle.rs +++ b/deno_webgpu/render_bundle.rs @@ -17,6 +17,7 @@ use deno_core::WebIDL; use deno_error::JsErrorBox; use crate::buffer::GPUBuffer; +use crate::error::GPUGenericError; use crate::texture::GPUTextureFormat; use crate::Instance; @@ -45,6 +46,12 @@ impl GarbageCollected for GPURenderBundleEncoder { #[op2] impl GPURenderBundleEncoder { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn label(&self) -> String { @@ -419,6 +426,12 @@ impl GarbageCollected for GPURenderBundle { #[op2] impl GPURenderBundle { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn label(&self) -> String { diff --git a/deno_webgpu/render_pass.rs b/deno_webgpu/render_pass.rs index 5cfa576060b..b33b4e2802f 100644 --- a/deno_webgpu/render_pass.rs +++ b/deno_webgpu/render_pass.rs @@ -15,6 +15,7 @@ use deno_core::GarbageCollected; use deno_core::WebIDL; use crate::buffer::GPUBuffer; +use crate::error::GPUGenericError; use crate::render_bundle::GPURenderBundle; use crate::texture::GPUTextureView; use crate::webidl::GPUColor; @@ -36,6 +37,12 @@ impl GarbageCollected for GPURenderPassEncoder { #[op2] impl GPURenderPassEncoder { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn label(&self) -> String { diff --git a/deno_webgpu/render_pipeline.rs b/deno_webgpu/render_pipeline.rs index 84f1477fb39..1a0fc2210b2 100644 --- a/deno_webgpu/render_pipeline.rs +++ b/deno_webgpu/render_pipeline.rs @@ -9,6 +9,7 @@ use deno_core::WebIDL; use indexmap::IndexMap; use crate::bind_group_layout::GPUBindGroupLayout; +use crate::error::GPUGenericError; use crate::sampler::GPUCompareFunction; use crate::shader::GPUShaderModule; use crate::texture::GPUTextureFormat; @@ -41,6 +42,12 @@ impl GarbageCollected for GPURenderPipeline { #[op2] impl GPURenderPipeline { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn label(&self) -> String { diff --git a/deno_webgpu/sampler.rs b/deno_webgpu/sampler.rs index 2af3f9d4216..c6dd44339f3 100644 --- a/deno_webgpu/sampler.rs +++ b/deno_webgpu/sampler.rs @@ -5,6 +5,7 @@ use deno_core::webidl::WebIdlInterfaceConverter; use deno_core::GarbageCollected; use deno_core::WebIDL; +use crate::error::GPUGenericError; use crate::Instance; pub struct GPUSampler { @@ -31,6 +32,12 @@ impl GarbageCollected for GPUSampler { #[op2] impl GPUSampler { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn label(&self) -> String { diff --git a/deno_webgpu/shader.rs b/deno_webgpu/shader.rs index b449a6534ab..2718826f511 100644 --- a/deno_webgpu/shader.rs +++ b/deno_webgpu/shader.rs @@ -8,6 +8,7 @@ use deno_core::GarbageCollected; use deno_core::WebIDL; use wgpu_core::pipeline; +use crate::error::GPUGenericError; use crate::Instance; pub struct GPUShaderModule { @@ -35,6 +36,12 @@ impl GarbageCollected for GPUShaderModule { #[op2] impl GPUShaderModule { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn label(&self) -> String { diff --git a/deno_webgpu/surface.rs b/deno_webgpu/surface.rs index 0a042a95496..0d6e7d07f69 100644 --- a/deno_webgpu/surface.rs +++ b/deno_webgpu/surface.rs @@ -12,6 +12,7 @@ use deno_error::JsErrorBox; use wgpu_types::SurfaceStatus; use crate::device::GPUDevice; +use crate::error::GPUGenericError; use crate::texture::GPUTexture; use crate::texture::GPUTextureFormat; @@ -55,6 +56,12 @@ impl GarbageCollected for GPUCanvasContext { #[op2] impl GPUCanvasContext { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[global] fn canvas(&self) -> v8::Global { diff --git a/deno_webgpu/texture.rs b/deno_webgpu/texture.rs index af876bc4b01..09b4cac3819 100644 --- a/deno_webgpu/texture.rs +++ b/deno_webgpu/texture.rs @@ -13,6 +13,7 @@ use wgpu_types::TextureDimension; use wgpu_types::TextureFormat; use wgpu_types::TextureViewDimension; +use crate::error::GPUGenericError; use crate::Instance; #[derive(WebIDL)] @@ -71,6 +72,12 @@ impl GarbageCollected for GPUTexture { #[op2] impl GPUTexture { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn label(&self) -> String { @@ -256,6 +263,12 @@ impl GarbageCollected for GPUTextureView { #[op2] impl GPUTextureView { + #[constructor] + #[cppgc] + fn constructor(_: bool) -> Result { + Err(GPUGenericError::InvalidConstructor) + } + #[getter] #[string] fn label(&self) -> String { From 5e6c151f9f182b9faa8dde18ae6a5dfb0b862e10 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Wed, 17 Sep 2025 16:47:26 -0400 Subject: [PATCH 250/303] chore: remove `advisories.ignore` entry for RUSTSEC-2025-0056 --- .deny.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.deny.toml b/.deny.toml index 15a168aa093..fd4fb3a8a1a 100644 --- a/.deny.toml +++ b/.deny.toml @@ -50,10 +50,6 @@ ignore = [ # It's a dependency of `metal` (which is to be replaced with `objc2-metal`), and a # transitive dependency of `deno`. https://github.com/gfx-rs/wgpu/issues/7873 "RUSTSEC-2024-0436", - # `adler` crate is no longer maintained https://rustsec.org/advisories/RUSTSEC-2025-0056 - # It's a dependency of `miniz_oxide` 0.7.4, and a transitive dependency of `deno`. - # https://github.com/gfx-rs/wgpu/issues/7961 - "RUSTSEC-2025-0056", ] [licenses] From 5cbab611097961c9cfc4b4efccbc01a5d5f09811 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Thu, 25 Sep 2025 14:12:14 -0400 Subject: [PATCH 251/303] refactor(xtask/cts): move `TEST_LINE_REGEX` to single site of use --- xtask/src/cts.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/xtask/src/cts.rs b/xtask/src/cts.rs index c1b675a3259..18367300bcb 100644 --- a/xtask/src/cts.rs +++ b/xtask/src/cts.rs @@ -50,12 +50,6 @@ const CTS_GIT_URL: &str = "https://github.com/gpuweb/cts.git"; /// Path to default CTS test list. const CTS_DEFAULT_TEST_LIST: &str = "cts_runner/test.lst"; -static TEST_LINE_REGEX: LazyLock = LazyLock::new(|| { - RegexBuilder::new(r#"(?:fails-if\s*\(\s*(?\w+)\s*\)\s+)?(?.*)"#) - .build() - .unwrap() -}); - #[derive(Default)] struct TestLine { pub selector: OsString, @@ -103,6 +97,12 @@ pub fn run_cts( for file in list_files { tests.extend(shell.read_file(file)?.lines().filter_map(|line| { + static TEST_LINE_REGEX: LazyLock = LazyLock::new(|| { + RegexBuilder::new(r#"(?:fails-if\s*\(\s*(?\w+)\s*\)\s+)?(?.*)"#) + .build() + .unwrap() + }); + let trimmed = line.trim(); let is_comment = trimmed.starts_with("//") || trimmed.starts_with("#"); let captures = TEST_LINE_REGEX From 83a0722eb6e8fb4cba94e99bc712844badab699b Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Thu, 25 Sep 2025 14:04:53 -0400 Subject: [PATCH 252/303] =?UTF-8?q?test(cts):=20allow=20comma-separated=20?= =?UTF-8?q?backend=20list=20in=20`fails-if(=E2=80=A6)`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- xtask/src/cts.rs | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/xtask/src/cts.rs b/xtask/src/cts.rs index 18367300bcb..e23952fcddc 100644 --- a/xtask/src/cts.rs +++ b/xtask/src/cts.rs @@ -53,7 +53,7 @@ const CTS_DEFAULT_TEST_LIST: &str = "cts_runner/test.lst"; #[derive(Default)] struct TestLine { pub selector: OsString, - pub fails_if: Option, + pub fails_if: Vec, } pub fn run_cts( @@ -98,9 +98,11 @@ pub fn run_cts( for file in list_files { tests.extend(shell.read_file(file)?.lines().filter_map(|line| { static TEST_LINE_REGEX: LazyLock = LazyLock::new(|| { - RegexBuilder::new(r#"(?:fails-if\s*\(\s*(?\w+)\s*\)\s+)?(?.*)"#) - .build() - .unwrap() + RegexBuilder::new( + r#"(?:fails-if\s*\(\s*(?\w+(?:,\w+)*?)\s*\)\s+)?(?.*)"#, + ) + .build() + .unwrap() }); let trimmed = line.trim(); @@ -110,7 +112,15 @@ pub fn run_cts( .expect("Invalid test line: {trimmed}"); (!trimmed.is_empty() && !is_comment).then(|| TestLine { selector: OsString::from(&captures["selector"]), - fails_if: captures.name("fails_if").map(|m| m.as_str().to_string()), + fails_if: captures + .name("fails_if") + .map(|m| { + m.as_str() + .split_terminator(',') + .map(|m| m.to_string()) + .collect() + }) + .unwrap_or_default(), }) })) } @@ -237,8 +247,8 @@ pub fn run_cts( log::info!("Running CTS"); for test in &tests { - match (&test.fails_if, &running_on_backend) { - (Some(backend), Some(running_on_backend)) if backend == running_on_backend => { + if let Some(running_on_backend) = &running_on_backend { + if test.fails_if.contains(running_on_backend) { log::info!( "Skipping {} on {} backend", test.selector.to_string_lossy(), @@ -246,7 +256,6 @@ pub fn run_cts( ); continue; } - _ => {} } log::info!("Running {}", test.selector.to_string_lossy()); From cac1bf998c5e8e7b3287edaa21531021127bf132 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Thu, 25 Sep 2025 13:08:27 -0400 Subject: [PATCH 253/303] =?UTF-8?q?test(cts):=20add=20`=E2=80=A6,vertex=5F?= =?UTF-8?q?state,correctness:array=5Fstride=5Fzero:*`,=20expect=20fail=20o?= =?UTF-8?q?n=20macOS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cts_runner/test.lst | 1 + 1 file changed, 1 insertion(+) diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 827bf01119f..fd4b7d5220e 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -18,6 +18,7 @@ webgpu:api,operation,compute,basic:memcpy:* webgpu:api,operation,compute_pipeline,overrides:* webgpu:api,operation,device,lost:* webgpu:api,operation,render_pass,storeOp:* +fails-if(metal,vulkan) webgpu:api,operation,vertex_state,correctness:array_stride_zero:* // Presumably vertex pulling, revisit after https://github.com/gfx-rs/wgpu/issues/7981 is fixed. fails-if(metal) webgpu:api,operation,vertex_state,correctness:setVertexBuffer_offset_and_attribute_offset:* fails-if(dx12) webgpu:api,validation,capability_checks,limits,maxBindGroups:setBindGroup,* From 3375284f16e26fb13e873aed685500fbf8c7d0d9 Mon Sep 17 00:00:00 2001 From: Teodor Tanasoaia <28601907+teoxoy@users.noreply.github.com> Date: Fri, 26 Sep 2025 13:45:37 +0200 Subject: [PATCH 254/303] [D3D12] fix setting vertex buffer array stride if 0 (#8260) --- tests/tests/wgpu-gpu/main.rs | 2 + tests/tests/wgpu-gpu/vertex_state.rs | 197 +++++++++++++++++++++++++++ wgpu-hal/src/dx12/command.rs | 4 +- wgpu-hal/src/dx12/device.rs | 2 +- wgpu-hal/src/dx12/mod.rs | 4 +- 5 files changed, 204 insertions(+), 5 deletions(-) create mode 100644 tests/tests/wgpu-gpu/vertex_state.rs diff --git a/tests/tests/wgpu-gpu/main.rs b/tests/tests/wgpu-gpu/main.rs index d461845e92b..b52e5088ebb 100644 --- a/tests/tests/wgpu-gpu/main.rs +++ b/tests/tests/wgpu-gpu/main.rs @@ -67,6 +67,7 @@ mod transfer; mod transition_resources; mod vertex_formats; mod vertex_indices; +mod vertex_state; mod write_texture; mod zero_init_texture_after_discard; @@ -137,6 +138,7 @@ fn all_tests() -> Vec { transition_resources::all_tests(&mut tests); vertex_formats::all_tests(&mut tests); vertex_indices::all_tests(&mut tests); + vertex_state::all_tests(&mut tests); write_texture::all_tests(&mut tests); zero_init_texture_after_discard::all_tests(&mut tests); diff --git a/tests/tests/wgpu-gpu/vertex_state.rs b/tests/tests/wgpu-gpu/vertex_state.rs new file mode 100644 index 00000000000..5ace09bdfa6 --- /dev/null +++ b/tests/tests/wgpu-gpu/vertex_state.rs @@ -0,0 +1,197 @@ +use wgpu::{ + util::{BufferInitDescriptor, DeviceExt}, + vertex_attr_array, +}; +use wgpu_test::{ + gpu_test, FailureCase, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, +}; + +pub fn all_tests(vec: &mut Vec) { + vec.push(SET_ARRAY_STRIDE_TO_0); +} + +#[gpu_test] +static SET_ARRAY_STRIDE_TO_0: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters( + TestParameters::default() + .limits(wgpu::Limits::downlevel_defaults()) + .expect_fail(FailureCase::backend(wgpu::Backends::METAL)), + ) + .run_async(set_array_stride_to_0); + +/// Tests that draws using a vertex buffer with stride of 0 works correctly (especially on the +/// D3D12 backend; see commentary within). +async fn set_array_stride_to_0(ctx: TestingContext) { + let position_buffer_content: &[f32; 12] = &[ + // Triangle 1 + -1.0, -1.0, // Bottom left + 1.0, 1.0, // Top right + -1.0, 1.0, // Top left + // Triangle 2 + -1.0, -1.0, // Bottom left + 1.0, -1.0, // Bottom right + 1.0, 1.0, // Top right + ]; + let position_buffer = ctx.device.create_buffer_init(&BufferInitDescriptor { + label: None, + contents: bytemuck::cast_slice::(position_buffer_content), + usage: wgpu::BufferUsages::VERTEX, + }); + + let color_buffer_content: &[f32; 4] = &[1.0, 1.0, 1.0, 1.0]; + let color_buffer = ctx.device.create_buffer_init(&BufferInitDescriptor { + label: None, + contents: bytemuck::cast_slice::(color_buffer_content), + usage: wgpu::BufferUsages::VERTEX, + }); + + let shader_src = " + struct VertexOutput { + @builtin(position) position: vec4f, + @location(0) color: vec4f, + } + + @vertex + fn vs_main(@location(0) position: vec2f, @location(1) color: vec4f) -> VertexOutput { + return VertexOutput(vec4f(position, 0.0, 1.0), color); + } + + @fragment + fn fs_main(@location(0) color: vec4f) -> @location(0) vec4f { + return color; + } + "; + + let shader = ctx + .device + .create_shader_module(wgpu::ShaderModuleDescriptor { + label: None, + source: wgpu::ShaderSource::Wgsl(shader_src.into()), + }); + + let vbl = [ + wgpu::VertexBufferLayout { + array_stride: 8, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &vertex_attr_array![0 => Float32x2], + }, + wgpu::VertexBufferLayout { + array_stride: 0, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &vertex_attr_array![1 => Float32x4], + }, + ]; + let pipeline_desc = wgpu::RenderPipelineDescriptor { + label: None, + layout: None, + vertex: wgpu::VertexState { + buffers: &vbl, + module: &shader, + entry_point: Some("vs_main"), + compilation_options: Default::default(), + }, + primitive: wgpu::PrimitiveState::default(), + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), + fragment: Some(wgpu::FragmentState { + module: &shader, + entry_point: Some("fs_main"), + compilation_options: Default::default(), + targets: &[Some(wgpu::ColorTargetState { + format: wgpu::TextureFormat::R8Unorm, + blend: None, + write_mask: wgpu::ColorWrites::ALL, + })], + }), + multiview: None, + cache: None, + }; + let mut first_pipeline_desc = pipeline_desc.clone(); + let mut first_vbl = vbl.clone(); + first_vbl[1].array_stride = 16; + first_pipeline_desc.vertex.buffers = &first_vbl; + let pipeline = ctx.device.create_render_pipeline(&pipeline_desc); + let first_pipeline = ctx.device.create_render_pipeline(&first_pipeline_desc); + + let out_texture = ctx.device.create_texture(&wgpu::TextureDescriptor { + label: None, + size: wgpu::Extent3d { + width: 256, + height: 256, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::R8Unorm, + usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::COPY_SRC, + view_formats: &[], + }); + let out_texture_view = out_texture.create_view(&wgpu::TextureViewDescriptor::default()); + + let readback_buffer = ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 256 * 256, + usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ, + mapped_at_creation: false, + }); + + let mut encoder = ctx + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor::default()); + + { + let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: None, + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + ops: wgpu::Operations::default(), + resolve_target: None, + view: &out_texture_view, + depth_slice: None, + })], + depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, + }); + + // The D3D12 backend used to not set the stride of vertex buffers if it was 0. + rpass.set_pipeline(&first_pipeline); // This call caused the D3D12 backend to set the stride for the 2nd vertex buffer to 16. + rpass.set_pipeline(&pipeline); // This call doesn't set the stride for the 2nd vertex buffer to 0. + rpass.set_vertex_buffer(0, position_buffer.slice(..)); + rpass.set_vertex_buffer(1, color_buffer.slice(..)); + rpass.draw(0..6, 0..1); // Causing this draw to be skipped since it would read OOB of the 2nd vertex buffer. + } + + encoder.copy_texture_to_buffer( + wgpu::TexelCopyTextureInfo { + texture: &out_texture, + mip_level: 0, + origin: wgpu::Origin3d::ZERO, + aspect: wgpu::TextureAspect::All, + }, + wgpu::TexelCopyBufferInfo { + buffer: &readback_buffer, + layout: wgpu::TexelCopyBufferLayout { + offset: 0, + bytes_per_row: Some(256), + rows_per_image: None, + }, + }, + wgpu::Extent3d { + width: 256, + height: 256, + depth_or_array_layers: 1, + }, + ); + + ctx.queue.submit([encoder.finish()]); + + let slice = readback_buffer.slice(..); + slice.map_async(wgpu::MapMode::Read, |_| ()); + + ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + + let data = slice.get_mapped_range(); + let succeeded = data.iter().all(|b| *b == u8::MAX); + assert!(succeeded); +} diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index 2454f82ef88..19b06867f84 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -1121,8 +1121,8 @@ impl crate::CommandEncoder for super::CommandEncoder { .enumerate() { if let Some(stride) = stride { - if vb.StrideInBytes != stride.get() { - vb.StrideInBytes = stride.get(); + if vb.StrideInBytes != stride { + vb.StrideInBytes = stride; self.pass.dirty_vertex_buffers |= 1 << index; } } diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 2b5b43cdaa2..dafbbb5bd80 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -1952,7 +1952,7 @@ impl crate::Device for super::Device { let mut input_element_descs = Vec::new(); for (i, (stride, vbuf)) in vertex_strides.iter_mut().zip(vertex_buffers).enumerate() { - *stride = NonZeroU32::new(vbuf.array_stride as u32); + *stride = Some(vbuf.array_stride as u32); let (slot_class, step_rate) = match vbuf.step_mode { wgt::VertexStepMode::Vertex => { (Direct3D12::D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0) diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 00bde82396c..51fa6e69cc6 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -86,7 +86,7 @@ mod types; mod view; use alloc::{borrow::ToOwned as _, string::String, sync::Arc, vec::Vec}; -use core::{ffi, fmt, mem, num::NonZeroU32, ops::Deref}; +use core::{ffi, fmt, mem, ops::Deref}; use arrayvec::ArrayVec; use hashbrown::HashMap; @@ -1169,7 +1169,7 @@ pub struct RenderPipeline { raw: Direct3D12::ID3D12PipelineState, layout: PipelineLayoutShared, topology: Direct3D::D3D_PRIMITIVE_TOPOLOGY, - vertex_strides: [Option; crate::MAX_VERTEX_BUFFERS], + vertex_strides: [Option; crate::MAX_VERTEX_BUFFERS], } impl crate::DynRenderPipeline for RenderPipeline {} From ce96254f4f11e9a1f8069b2f6c09b6ac66cc39b7 Mon Sep 17 00:00:00 2001 From: Teodor Tanasoaia <28601907+teoxoy@users.noreply.github.com> Date: Fri, 26 Sep 2025 19:37:37 +0200 Subject: [PATCH 255/303] [msl] fix vertex pulling with a stride of 0 (#8265) --- cts_runner/test.lst | 2 +- naga/src/back/msl/mod.rs | 16 +++++++-- naga/src/back/msl/writer.rs | 42 +++++++++++++--------- naga/tests/in/wgsl/msl-vpt-formats-x1.toml | 2 +- naga/tests/in/wgsl/msl-vpt-formats-x2.toml | 2 +- naga/tests/in/wgsl/msl-vpt-formats-x3.toml | 2 +- naga/tests/in/wgsl/msl-vpt-formats-x4.toml | 2 +- naga/tests/in/wgsl/msl-vpt.toml | 4 +-- tests/tests/wgpu-gpu/vertex_state.rs | 8 ++--- wgpu-hal/src/metal/device.rs | 10 +++++- 10 files changed, 56 insertions(+), 34 deletions(-) diff --git a/cts_runner/test.lst b/cts_runner/test.lst index fd4b7d5220e..e21e12d3e14 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -18,7 +18,7 @@ webgpu:api,operation,compute,basic:memcpy:* webgpu:api,operation,compute_pipeline,overrides:* webgpu:api,operation,device,lost:* webgpu:api,operation,render_pass,storeOp:* -fails-if(metal,vulkan) webgpu:api,operation,vertex_state,correctness:array_stride_zero:* +fails-if(vulkan) webgpu:api,operation,vertex_state,correctness:array_stride_zero:* // Presumably vertex pulling, revisit after https://github.com/gfx-rs/wgpu/issues/7981 is fixed. fails-if(metal) webgpu:api,operation,vertex_state,correctness:setVertexBuffer_offset_and_attribute_offset:* fails-if(dx12) webgpu:api,validation,capability_checks,limits,maxBindGroups:setBindGroup,* diff --git a/naga/src/back/msl/mod.rs b/naga/src/back/msl/mod.rs index 7e9180e0c25..64b1280a1b0 100644 --- a/naga/src/back/msl/mod.rs +++ b/naga/src/back/msl/mod.rs @@ -418,6 +418,17 @@ pub enum VertexFormat { Unorm8x4Bgra = 44, } +/// Defines how to advance the data in vertex buffers. +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serialize", derive(serde::Serialize))] +#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] +pub enum VertexBufferStepMode { + Constant, + #[default] + ByVertex, + ByInstance, +} + /// A mapping of vertex buffers and their attributes to shader /// locations. #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -446,9 +457,8 @@ pub struct VertexBufferMapping { pub id: u32, /// Size of the structure in bytes pub stride: u32, - /// True if the buffer is indexed by vertex, false if indexed - /// by instance. - pub indexed_by_vertex: bool, + /// Vertex buffer step mode + pub step_mode: VertexBufferStepMode, /// Vec of the attributes within the structure pub attributes: Vec, } diff --git a/naga/src/back/msl/writer.rs b/naga/src/back/msl/writer.rs index 0bd8d0ab3fe..cec92265416 100644 --- a/naga/src/back/msl/writer.rs +++ b/naga/src/back/msl/writer.rs @@ -6359,7 +6359,7 @@ template struct VertexBufferMappingResolved<'a> { id: u32, stride: u32, - indexed_by_vertex: bool, + step_mode: back::msl::VertexBufferStepMode, ty_name: String, param_name: String, elem_name: String, @@ -6395,10 +6395,14 @@ template "Vertex pulling requires a non-zero buffer stride." ); - if vbm.indexed_by_vertex { - needs_vertex_id = true; - } else { - needs_instance_id = true; + match vbm.step_mode { + back::msl::VertexBufferStepMode::Constant => {} + back::msl::VertexBufferStepMode::ByVertex => { + needs_vertex_id = true; + } + back::msl::VertexBufferStepMode::ByInstance => { + needs_instance_id = true; + } } let buffer_ty = self.namer.call(format!("vb_{buffer_id}_type").as_str()); @@ -6408,7 +6412,7 @@ template vbm_resolved.push(VertexBufferMappingResolved { id: buffer_id, stride: buffer_stride, - indexed_by_vertex: vbm.indexed_by_vertex, + step_mode: vbm.step_mode, ty_name: buffer_ty, param_name: buffer_param, elem_name: buffer_elem, @@ -7199,8 +7203,6 @@ template } if do_vertex_pulling { - assert!(needs_vertex_id || needs_instance_id); - let mut separator = if is_first_argument { is_first_argument = false; ' ' @@ -7278,16 +7280,22 @@ template let idx = &vbm.id; let stride = &vbm.stride; - let index_name = if vbm.indexed_by_vertex { - if let Some(ref name) = v_existing_id { - name - } else { - &v_id + let index_name = match vbm.step_mode { + back::msl::VertexBufferStepMode::Constant => "0", + back::msl::VertexBufferStepMode::ByVertex => { + if let Some(ref name) = v_existing_id { + name + } else { + &v_id + } + } + back::msl::VertexBufferStepMode::ByInstance => { + if let Some(ref name) = i_existing_id { + name + } else { + &i_id + } } - } else if let Some(ref name) = i_existing_id { - name - } else { - &i_id }; write!( self.out, diff --git a/naga/tests/in/wgsl/msl-vpt-formats-x1.toml b/naga/tests/in/wgsl/msl-vpt-formats-x1.toml index 0e8247ca9ac..50af398181b 100644 --- a/naga/tests/in/wgsl/msl-vpt-formats-x1.toml +++ b/naga/tests/in/wgsl/msl-vpt-formats-x1.toml @@ -49,5 +49,5 @@ attributes = [ { offset = 640, shader_location = 40, format = "unorm8x4-bgra" }, ] id = 1 -indexed_by_vertex = true +step_mode = "ByVertex" stride = 644 diff --git a/naga/tests/in/wgsl/msl-vpt-formats-x2.toml b/naga/tests/in/wgsl/msl-vpt-formats-x2.toml index 0e8247ca9ac..50af398181b 100644 --- a/naga/tests/in/wgsl/msl-vpt-formats-x2.toml +++ b/naga/tests/in/wgsl/msl-vpt-formats-x2.toml @@ -49,5 +49,5 @@ attributes = [ { offset = 640, shader_location = 40, format = "unorm8x4-bgra" }, ] id = 1 -indexed_by_vertex = true +step_mode = "ByVertex" stride = 644 diff --git a/naga/tests/in/wgsl/msl-vpt-formats-x3.toml b/naga/tests/in/wgsl/msl-vpt-formats-x3.toml index 0e8247ca9ac..50af398181b 100644 --- a/naga/tests/in/wgsl/msl-vpt-formats-x3.toml +++ b/naga/tests/in/wgsl/msl-vpt-formats-x3.toml @@ -49,5 +49,5 @@ attributes = [ { offset = 640, shader_location = 40, format = "unorm8x4-bgra" }, ] id = 1 -indexed_by_vertex = true +step_mode = "ByVertex" stride = 644 diff --git a/naga/tests/in/wgsl/msl-vpt-formats-x4.toml b/naga/tests/in/wgsl/msl-vpt-formats-x4.toml index 0e8247ca9ac..50af398181b 100644 --- a/naga/tests/in/wgsl/msl-vpt-formats-x4.toml +++ b/naga/tests/in/wgsl/msl-vpt-formats-x4.toml @@ -49,5 +49,5 @@ attributes = [ { offset = 640, shader_location = 40, format = "unorm8x4-bgra" }, ] id = 1 -indexed_by_vertex = true +step_mode = "ByVertex" stride = 644 diff --git a/naga/tests/in/wgsl/msl-vpt.toml b/naga/tests/in/wgsl/msl-vpt.toml index d6cc7bfd2f5..ee6b0b52a53 100644 --- a/naga/tests/in/wgsl/msl-vpt.toml +++ b/naga/tests/in/wgsl/msl-vpt.toml @@ -10,11 +10,11 @@ attributes = [ { offset = 4, shader_location = 1, format = "Float32x4" }, ] id = 1 -indexed_by_vertex = true +step_mode = "ByVertex" stride = 20 [[msl_pipeline.vertex_buffer_mappings]] attributes = [{ offset = 0, shader_location = 2, format = "Float32x2" }] id = 2 -indexed_by_vertex = false +step_mode = "ByInstance" stride = 16 diff --git a/tests/tests/wgpu-gpu/vertex_state.rs b/tests/tests/wgpu-gpu/vertex_state.rs index 5ace09bdfa6..fad6546d39f 100644 --- a/tests/tests/wgpu-gpu/vertex_state.rs +++ b/tests/tests/wgpu-gpu/vertex_state.rs @@ -3,7 +3,7 @@ use wgpu::{ vertex_attr_array, }; use wgpu_test::{ - gpu_test, FailureCase, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, + gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters, TestingContext, }; pub fn all_tests(vec: &mut Vec) { @@ -12,11 +12,7 @@ pub fn all_tests(vec: &mut Vec) { #[gpu_test] static SET_ARRAY_STRIDE_TO_0: GpuTestConfiguration = GpuTestConfiguration::new() - .parameters( - TestParameters::default() - .limits(wgpu::Limits::downlevel_defaults()) - .expect_fail(FailureCase::backend(wgpu::Backends::METAL)), - ) + .parameters(TestParameters::default().limits(wgpu::Limits::downlevel_defaults())) .run_async(set_array_stride_to_0); /// Tests that draws using a vertex buffer with stride of 0 works correctly (especially on the diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index dd5d05b6d50..6b94f43fb1b 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -1154,7 +1154,15 @@ impl crate::Device for super::Device { .try_into() .unwrap() }, - indexed_by_vertex: (vbl.step_mode == wgt::VertexStepMode::Vertex {}), + step_mode: match (vbl.array_stride == 0, vbl.step_mode) { + (true, _) => naga::back::msl::VertexBufferStepMode::Constant, + (false, wgt::VertexStepMode::Vertex) => { + naga::back::msl::VertexBufferStepMode::ByVertex + } + (false, wgt::VertexStepMode::Instance) => { + naga::back::msl::VertexBufferStepMode::ByInstance + } + }, attributes, }); } From 375095f7899d454323daff50648be56cb8ed3191 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Thu, 18 Sep 2025 14:02:17 -0400 Subject: [PATCH 256/303] feat(deno): accept `GPUBuffer` as `GPUBindingResource` --- cts_runner/test.lst | 3 +++ deno_webgpu/bind_group.rs | 11 +++++++++++ deno_webgpu/device.rs | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/cts_runner/test.lst b/cts_runner/test.lst index e21e12d3e14..8f047b60225 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -3,6 +3,7 @@ // cargo xtask cts -- --list // ``` unittests:* +webgpu:api,operation,buffers,createBindGroup:buffer_binding_resource:* webgpu:api,operation,command_buffer,basic:* webgpu:api,operation,command_buffer,copyBufferToBuffer:* fails-if(vulkan) webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth24plus" @@ -23,6 +24,8 @@ fails-if(vulkan) webgpu:api,operation,vertex_state,correctness:array_stride_zero fails-if(metal) webgpu:api,operation,vertex_state,correctness:setVertexBuffer_offset_and_attribute_offset:* fails-if(dx12) webgpu:api,validation,capability_checks,limits,maxBindGroups:setBindGroup,* webgpu:api,validation,createBindGroup:buffer,effective_buffer_binding_size:* +// Fails because we coerce a size of 0 in `GPUDevice.createBindGroup(…)` to `buffer.size - offset`. +// FAIL webgpu:api,validation,createBindGroup:buffer_offset_and_size_for_bind_groups_match:* webgpu:api,validation,encoding,beginComputePass:* webgpu:api,validation,encoding,beginRenderPass:* webgpu:api,validation,encoding,cmds,clearBuffer:* diff --git a/deno_webgpu/bind_group.rs b/deno_webgpu/bind_group.rs index d003ede445a..40ea9aab037 100644 --- a/deno_webgpu/bind_group.rs +++ b/deno_webgpu/bind_group.rs @@ -94,6 +94,7 @@ pub(crate) struct GPUBufferBinding { pub(crate) enum GPUBindingResource { Sampler(Ptr), TextureView(Ptr), + Buffer(Ptr), BufferBinding(GPUBufferBinding), } @@ -125,6 +126,16 @@ impl<'a> WebIdlConverter<'a> for GPUBindingResource { ) .map(Self::TextureView) }) + .or_else(|_| { + >::convert( + scope, + value, + prefix.clone(), + context.borrowed(), + options, + ) + .map(Self::Buffer) + }) .or_else(|_| { GPUBufferBinding::convert(scope, value, prefix, context, options) .map(Self::BufferBinding) diff --git a/deno_webgpu/device.rs b/deno_webgpu/device.rs index aef52607feb..037caaef671 100644 --- a/deno_webgpu/device.rs +++ b/deno_webgpu/device.rs @@ -406,6 +406,13 @@ impl GPUDevice { GPUBindingResource::TextureView(texture_view) => { BindingResource::TextureView(texture_view.id) } + GPUBindingResource::Buffer(buffer) => { + BindingResource::Buffer(wgpu_core::binding_model::BufferBinding { + buffer: buffer.id, + offset: 0, + size: NonZeroU64::new(buffer.size), + }) + } GPUBindingResource::BufferBinding(buffer_binding) => { BindingResource::Buffer(wgpu_core::binding_model::BufferBinding { buffer: buffer_binding.buffer.id, From 2b71b1f99d3386beccacf4adcf00d6f14c4e1921 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Thu, 18 Sep 2025 14:02:17 -0400 Subject: [PATCH 257/303] feat(deno): accept `GPUTexture` as `GPUBindingResource` --- cts_runner/test.lst | 12 +++----- deno_webgpu/bind_group.rs | 12 ++++++++ deno_webgpu/command_encoder.rs | 8 +++-- deno_webgpu/device.rs | 4 +++ deno_webgpu/render_pass.rs | 56 ++++++++++++++++++++++++++++++++-- deno_webgpu/surface.rs | 1 + deno_webgpu/texture.rs | 30 ++++++++++++++++++ 7 files changed, 110 insertions(+), 13 deletions(-) diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 8f047b60225..624fa1274bc 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -110,14 +110,12 @@ webgpu:api,validation,image_copy,layout_related:copy_end_overflows_u64:* fails-if(dx12) webgpu:api,validation,image_copy,layout_related:offset_alignment:* webgpu:api,validation,image_copy,texture_related:format:dimension="1d";* webgpu:api,validation,queue,submit:command_buffer,* -// `GPUTexture` as `GPUTextureView` not supported by Deno. https://github.com/gfx-rs/wgpu/issues/8200 -//FAIL: webgpu:api,validation,render_pass,render_pass_descriptor:attachments,one_color_attachment: -//FAIL: webgpu:api,validation,render_pass,render_pass_descriptor:attachments,one_depth_stencil_attachment: -webgpu:api,validation,render_pass,render_pass_descriptor:attachments,same_size: -webgpu:api,validation,render_pass,render_pass_descriptor:attachments,color_depth_mismatch: -webgpu:api,validation,render_pass,render_pass_descriptor:attachments,layer_count:* -webgpu:api,validation,render_pass,render_pass_descriptor:attachments,mip_level_count:* +webgpu:api,validation,render_pass,render_pass_descriptor:attachments,* +webgpu:api,validation,render_pass,render_pass_descriptor:color_attachments,depthSlice,bound_check:* +// Fails due to missing validation. +// FAIL: webgpu:api,validation,render_pass,render_pass_descriptor:color_attachments,depthSlice,overlaps,diff_miplevel:* webgpu:api,validation,render_pass,render_pass_descriptor:resolveTarget,* +webgpu:api,validation,render_pass,resolve:resolve_attachment:* webgpu:api,validation,texture,rg11b10ufloat_renderable:* webgpu:api,operation,render_pipeline,overrides:* webgpu:api,operation,rendering,basic:clear:* diff --git a/deno_webgpu/bind_group.rs b/deno_webgpu/bind_group.rs index 40ea9aab037..de329ecf468 100644 --- a/deno_webgpu/bind_group.rs +++ b/deno_webgpu/bind_group.rs @@ -17,6 +17,7 @@ use deno_core::WebIDL; use crate::buffer::GPUBuffer; use crate::error::GPUGenericError; use crate::sampler::GPUSampler; +use crate::texture::GPUTexture; use crate::texture::GPUTextureView; use crate::Instance; @@ -93,6 +94,7 @@ pub(crate) struct GPUBufferBinding { pub(crate) enum GPUBindingResource { Sampler(Ptr), + Texture(Ptr), TextureView(Ptr), Buffer(Ptr), BufferBinding(GPUBufferBinding), @@ -116,6 +118,16 @@ impl<'a> WebIdlConverter<'a> for GPUBindingResource { options, ) .map(Self::Sampler) + .or_else(|_| { + >::convert( + scope, + value, + prefix.clone(), + context.borrowed(), + options, + ) + .map(Self::Texture) + }) .or_else(|_| { >::convert( scope, diff --git a/deno_webgpu/command_encoder.rs b/deno_webgpu/command_encoder.rs index 91ea14aea41..1fc9e82bcc7 100644 --- a/deno_webgpu/command_encoder.rs +++ b/deno_webgpu/command_encoder.rs @@ -75,9 +75,11 @@ impl GPUCommandEncoder { .map(|attachment| { attachment.into_option().map(|attachment| { wgpu_core::command::RenderPassColorAttachment { - view: attachment.view.id, + view: attachment.view.to_view_id(), depth_slice: attachment.depth_slice, - resolve_target: attachment.resolve_target.map(|target| target.id), + resolve_target: attachment + .resolve_target + .map(|target| target.to_view_id()), load_op: attachment .load_op .with_default_value(attachment.clear_value.map(Into::into)), @@ -103,7 +105,7 @@ impl GPUCommandEncoder { } Ok(wgpu_core::command::RenderPassDepthStencilAttachment { - view: attachment.view.id, + view: attachment.view.to_view_id(), depth: PassChannel { load_op: attachment .depth_load_op diff --git a/deno_webgpu/device.rs b/deno_webgpu/device.rs index 037caaef671..1c76bf67470 100644 --- a/deno_webgpu/device.rs +++ b/deno_webgpu/device.rs @@ -230,6 +230,7 @@ impl GPUDevice { instance: self.instance.clone(), error_handler: self.error_handler.clone(), id, + default_view_id: Default::default(), label: descriptor.label, size: wgpu_descriptor.size, mip_level_count: wgpu_descriptor.mip_level_count, @@ -403,6 +404,9 @@ impl GPUDevice { GPUBindingResource::Sampler(sampler) => { BindingResource::Sampler(sampler.id) } + GPUBindingResource::Texture(texture) => { + BindingResource::TextureView(texture.default_view_id()) + } GPUBindingResource::TextureView(texture_view) => { BindingResource::TextureView(texture_view.id) } diff --git a/deno_webgpu/render_pass.rs b/deno_webgpu/render_pass.rs index b33b4e2802f..b1ce850f371 100644 --- a/deno_webgpu/render_pass.rs +++ b/deno_webgpu/render_pass.rs @@ -7,6 +7,10 @@ use std::num::NonZeroU64; use deno_core::cppgc::Ptr; use deno_core::op2; use deno_core::v8; +use deno_core::v8::HandleScope; +use deno_core::v8::Local; +use deno_core::v8::Value; +use deno_core::webidl::ContextFn; use deno_core::webidl::IntOptions; use deno_core::webidl::Nullable; use deno_core::webidl::WebIdlConverter; @@ -17,6 +21,7 @@ use deno_core::WebIDL; use crate::buffer::GPUBuffer; use crate::error::GPUGenericError; use crate::render_bundle::GPURenderBundle; +use crate::texture::GPUTexture; use crate::texture::GPUTextureView; use crate::webidl::GPUColor; use crate::Instance; @@ -441,10 +446,10 @@ pub(crate) struct GPURenderPassDescriptor { #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPURenderPassColorAttachment { - pub view: Ptr, + pub view: GPUTextureOrView, #[options(enforce_range = true)] pub depth_slice: Option, - pub resolve_target: Option>, + pub resolve_target: Option, pub clear_value: Option, pub load_op: GPULoadOp, pub store_op: GPUStoreOp, @@ -495,7 +500,7 @@ impl From for wgpu_core::command::StoreOp { #[derive(WebIDL)] #[webidl(dictionary)] pub(crate) struct GPURenderPassDepthStencilAttachment { - pub view: Ptr, + pub view: GPUTextureOrView, pub depth_clear_value: Option, pub depth_load_op: Option, pub depth_store_op: Option, @@ -519,3 +524,48 @@ pub(crate) struct GPURenderPassTimestampWrites { #[options(enforce_range = true)] pub end_of_pass_write_index: Option, } + +pub(crate) enum GPUTextureOrView { + Texture(Ptr), + TextureView(Ptr), +} + +impl GPUTextureOrView { + pub(crate) fn to_view_id(&self) -> wgpu_core::id::TextureViewId { + match self { + Self::Texture(texture) => texture.default_view_id(), + Self::TextureView(texture_view) => texture_view.id, + } + } +} + +impl<'a> WebIdlConverter<'a> for GPUTextureOrView { + type Options = (); + + fn convert<'b>( + scope: &mut HandleScope<'a>, + value: Local<'a, Value>, + prefix: Cow<'static, str>, + context: ContextFn<'b>, + options: &Self::Options, + ) -> Result { + >::convert( + scope, + value, + prefix.clone(), + context.borrowed(), + options, + ) + .map(Self::Texture) + .or_else(|_| { + >::convert( + scope, + value, + prefix.clone(), + context.borrowed(), + options, + ) + .map(Self::TextureView) + }) + } +} diff --git a/deno_webgpu/surface.rs b/deno_webgpu/surface.rs index 0d6e7d07f69..7c389b5434c 100644 --- a/deno_webgpu/surface.rs +++ b/deno_webgpu/surface.rs @@ -146,6 +146,7 @@ impl GPUCanvasContext { instance: config.device.instance.clone(), error_handler: config.device.error_handler.clone(), id, + default_view_id: Default::default(), label: "".to_string(), size: wgpu_types::Extent3d { width: *self.width.borrow(), diff --git a/deno_webgpu/texture.rs b/deno_webgpu/texture.rs index 09b4cac3819..c9a84afea32 100644 --- a/deno_webgpu/texture.rs +++ b/deno_webgpu/texture.rs @@ -1,5 +1,7 @@ // Copyright 2018-2025 the Deno authors. MIT license. +use std::sync::OnceLock; + use deno_core::op2; use deno_core::webidl::WebIdlInterfaceConverter; use deno_core::GarbageCollected; @@ -43,6 +45,7 @@ pub struct GPUTexture { pub error_handler: super::error::ErrorHandler, pub id: wgpu_core::id::TextureId, + pub default_view_id: OnceLock, pub label: String, @@ -54,8 +57,35 @@ pub struct GPUTexture { pub usage: u32, } +impl GPUTexture { + pub(crate) fn default_view_id(&self) -> wgpu_core::id::TextureViewId { + *self.default_view_id.get_or_init(|| { + let (id, err) = + self + .instance + .texture_create_view(self.id, &Default::default(), None); + if let Some(err) = err { + use wgpu_types::error::WebGpuError; + assert_ne!( + err.webgpu_error_type(), + wgpu_types::error::ErrorType::Validation, + concat!( + "getting default view for a texture ", + "caused a validation error (!?)" + ) + ); + self.error_handler.push_error(Some(err)); + } + id + }) + } +} + impl Drop for GPUTexture { fn drop(&mut self) { + if let Some(id) = self.default_view_id.take() { + self.instance.texture_view_drop(id).unwrap(); + } self.instance.texture_drop(self.id); } } From 61e5124eb9530d3b3865556a7da4fd320d03ddc5 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Fri, 26 Sep 2025 17:10:09 -0700 Subject: [PATCH 258/303] [deno] Return `undefined` instead of `null` from WebGPU APIs (#8266) See denoland/deno#29603 --- deno_webgpu/buffer.rs | 5 +++++ deno_webgpu/command_encoder.rs | 6 ++++++ deno_webgpu/compute_pass.rs | 8 ++++++++ deno_webgpu/device.rs | 2 ++ deno_webgpu/query_set.rs | 1 + deno_webgpu/queue.rs | 12 ++++++++---- deno_webgpu/render_bundle.rs | 11 +++++++++++ deno_webgpu/render_pass.rs | 19 +++++++++++++++++++ deno_webgpu/surface.rs | 2 ++ deno_webgpu/texture.rs | 1 + 10 files changed, 63 insertions(+), 4 deletions(-) diff --git a/deno_webgpu/buffer.rs b/deno_webgpu/buffer.rs index bff429dfec9..b975c319acc 100644 --- a/deno_webgpu/buffer.rs +++ b/deno_webgpu/buffer.rs @@ -114,6 +114,9 @@ impl GPUBuffer { *self.map_state.borrow() } + // In the successful case, the promise should resolve to undefined, but + // `#[undefined]` does not seem to work here. + // https://github.com/denoland/deno/issues/29603 #[async_method] async fn map_async( &self, @@ -250,6 +253,7 @@ impl GPUBuffer { } #[nofast] + #[undefined] fn unmap(&self, scope: &mut v8::HandleScope) -> Result<(), BufferError> { for ab in self.mapped_js_buffers.replace(vec![]) { let ab = ab.open(scope); @@ -267,6 +271,7 @@ impl GPUBuffer { } #[fast] + #[undefined] fn destroy(&self) { self.instance.buffer_destroy(self.id); } diff --git a/deno_webgpu/command_encoder.rs b/deno_webgpu/command_encoder.rs index 1fc9e82bcc7..3c9a37c9907 100644 --- a/deno_webgpu/command_encoder.rs +++ b/deno_webgpu/command_encoder.rs @@ -193,6 +193,7 @@ impl GPUCommandEncoder { } #[required(2)] + #[undefined] fn copy_buffer_to_buffer<'a>( &self, scope: &mut v8::HandleScope<'a>, @@ -282,6 +283,7 @@ impl GPUCommandEncoder { } #[required(3)] + #[undefined] fn copy_buffer_to_texture( &self, #[webidl] source: GPUTexelCopyBufferInfo, @@ -317,6 +319,7 @@ impl GPUCommandEncoder { } #[required(3)] + #[undefined] fn copy_texture_to_buffer( &self, #[webidl] source: GPUTexelCopyTextureInfo, @@ -352,6 +355,7 @@ impl GPUCommandEncoder { } #[required(3)] + #[undefined] fn copy_texture_to_texture( &self, #[webidl] source: GPUTexelCopyTextureInfo, @@ -385,6 +389,7 @@ impl GPUCommandEncoder { } #[required(1)] + #[undefined] fn clear_buffer( &self, #[webidl] buffer: Ptr, @@ -399,6 +404,7 @@ impl GPUCommandEncoder { } #[required(5)] + #[undefined] fn resolve_query_set( &self, #[webidl] query_set: Ptr, diff --git a/deno_webgpu/compute_pass.rs b/deno_webgpu/compute_pass.rs index 9fae680fba9..50dffae29b4 100644 --- a/deno_webgpu/compute_pass.rs +++ b/deno_webgpu/compute_pass.rs @@ -49,6 +49,7 @@ impl GPUComputePassEncoder { // TODO(@crowlKats): no-op, needs wpgu to implement changing the label } + #[undefined] fn set_pipeline( &self, #[webidl] pipeline: Ptr, @@ -63,6 +64,7 @@ impl GPUComputePassEncoder { self.error_handler.push_error(err); } + #[undefined] fn dispatch_workgroups( &self, #[webidl(options(enforce_range = true))] work_group_count_x: u32, @@ -83,6 +85,7 @@ impl GPUComputePassEncoder { self.error_handler.push_error(err); } + #[undefined] fn dispatch_workgroups_indirect( &self, #[webidl] indirect_buffer: Ptr, @@ -100,6 +103,7 @@ impl GPUComputePassEncoder { } #[fast] + #[undefined] fn end(&self) { let err = self .instance @@ -108,6 +112,7 @@ impl GPUComputePassEncoder { self.error_handler.push_error(err); } + #[undefined] fn push_debug_group(&self, #[webidl] group_label: String) { let err = self .instance @@ -121,6 +126,7 @@ impl GPUComputePassEncoder { } #[fast] + #[undefined] fn pop_debug_group(&self) { let err = self .instance @@ -129,6 +135,7 @@ impl GPUComputePassEncoder { self.error_handler.push_error(err); } + #[undefined] fn insert_debug_marker(&self, #[webidl] marker_label: String) { let err = self .instance @@ -141,6 +148,7 @@ impl GPUComputePassEncoder { self.error_handler.push_error(err); } + #[undefined] fn set_bind_group<'a>( &self, scope: &mut v8::HandleScope<'a>, diff --git a/deno_webgpu/device.rs b/deno_webgpu/device.rs index 1c76bf67470..cc198b652d2 100644 --- a/deno_webgpu/device.rs +++ b/deno_webgpu/device.rs @@ -142,6 +142,7 @@ impl GPUDevice { } #[fast] + #[undefined] fn destroy(&self) { self.instance.device_destroy(self.id); self @@ -634,6 +635,7 @@ impl GPUDevice { } #[required(1)] + #[undefined] fn push_error_scope(&self, #[webidl] filter: super::error::GPUErrorFilter) { self .error_handler diff --git a/deno_webgpu/query_set.rs b/deno_webgpu/query_set.rs index c726ad6059e..a4ec0d39041 100644 --- a/deno_webgpu/query_set.rs +++ b/deno_webgpu/query_set.rs @@ -53,6 +53,7 @@ impl GPUQuerySet { } #[fast] + #[undefined] fn destroy(&self) -> Result<(), JsErrorBox> { // TODO(https://github.com/gfx-rs/wgpu/issues/6495): Destroy the query // set. Until that is supported, it is okay to do nothing here, the diff --git a/deno_webgpu/queue.rs b/deno_webgpu/queue.rs index 89a153c87ec..2658aed706b 100644 --- a/deno_webgpu/queue.rs +++ b/deno_webgpu/queue.rs @@ -7,7 +7,6 @@ use std::time::Duration; use deno_core::cppgc::Ptr; use deno_core::futures::channel::oneshot; use deno_core::op2; -use deno_core::v8; use deno_core::GarbageCollected; use deno_core::WebIDL; use deno_error::JsErrorBox; @@ -63,11 +62,11 @@ impl GPUQueue { } #[required(1)] + #[undefined] fn submit( &self, - scope: &mut v8::HandleScope, #[webidl] command_buffers: Vec>, - ) -> Result, JsErrorBox> { + ) -> Result<(), JsErrorBox> { let ids = command_buffers .into_iter() .map(|cb| cb.id) @@ -79,9 +78,12 @@ impl GPUQueue { self.error_handler.push_error(Some(err)); } - Ok(v8::undefined(scope).into()) + Ok(()) } + // In the successful case, the promise should resolve to undefined, but + // `#[undefined]` does not seem to work here. + // https://github.com/denoland/deno/issues/29603 #[async_method] async fn on_submitted_work_done(&self) -> Result<(), JsErrorBox> { let (sender, receiver) = oneshot::channel::<()>(); @@ -124,6 +126,7 @@ impl GPUQueue { } #[required(3)] + #[undefined] fn write_buffer( &self, #[webidl] buffer: Ptr, @@ -148,6 +151,7 @@ impl GPUQueue { } #[required(4)] + #[undefined] fn write_texture( &self, #[webidl] destination: GPUTexelCopyTextureInfo, diff --git a/deno_webgpu/render_bundle.rs b/deno_webgpu/render_bundle.rs index 4dd19b9a969..964d72413f7 100644 --- a/deno_webgpu/render_bundle.rs +++ b/deno_webgpu/render_bundle.rs @@ -87,6 +87,7 @@ impl GPURenderBundleEncoder { } } + #[undefined] fn push_debug_group( &self, #[webidl] group_label: String, @@ -110,6 +111,7 @@ impl GPURenderBundleEncoder { } #[fast] + #[undefined] fn pop_debug_group(&self) -> Result<(), JsErrorBox> { let mut encoder = self.encoder.borrow_mut(); let encoder = encoder.as_mut().ok_or_else(|| { @@ -119,6 +121,7 @@ impl GPURenderBundleEncoder { Ok(()) } + #[undefined] fn insert_debug_marker( &self, #[webidl] marker_label: String, @@ -140,6 +143,7 @@ impl GPURenderBundleEncoder { Ok(()) } + #[undefined] fn set_bind_group<'a>( &self, scope: &mut v8::HandleScope<'a>, @@ -226,6 +230,7 @@ impl GPURenderBundleEncoder { Ok(()) } + #[undefined] fn set_pipeline( &self, #[webidl] pipeline: Ptr, @@ -243,6 +248,7 @@ impl GPURenderBundleEncoder { } #[required(2)] + #[undefined] fn set_index_buffer( &self, #[webidl] buffer: Ptr, @@ -265,6 +271,7 @@ impl GPURenderBundleEncoder { } #[required(2)] + #[undefined] fn set_vertex_buffer( &self, #[webidl(options(enforce_range = true))] slot: u32, @@ -288,6 +295,7 @@ impl GPURenderBundleEncoder { } #[required(1)] + #[undefined] fn draw( &self, #[webidl(options(enforce_range = true))] vertex_count: u32, @@ -311,6 +319,7 @@ impl GPURenderBundleEncoder { } #[required(1)] + #[undefined] fn draw_indexed( &self, #[webidl(options(enforce_range = true))] index_count: u32, @@ -336,6 +345,7 @@ impl GPURenderBundleEncoder { } #[required(2)] + #[undefined] fn draw_indirect( &self, #[webidl] indirect_buffer: Ptr, @@ -355,6 +365,7 @@ impl GPURenderBundleEncoder { } #[required(2)] + #[undefined] fn draw_indexed_indirect( &self, #[webidl] indirect_buffer: Ptr, diff --git a/deno_webgpu/render_pass.rs b/deno_webgpu/render_pass.rs index b1ce850f371..61236edcd29 100644 --- a/deno_webgpu/render_pass.rs +++ b/deno_webgpu/render_pass.rs @@ -60,6 +60,7 @@ impl GPURenderPassEncoder { } #[required(6)] + #[undefined] fn set_viewport( &self, #[webidl] x: f32, @@ -85,6 +86,7 @@ impl GPURenderPassEncoder { } #[required(4)] + #[undefined] fn set_scissor_rect( &self, #[webidl(options(enforce_range = true))] x: u32, @@ -106,6 +108,7 @@ impl GPURenderPassEncoder { } #[required(1)] + #[undefined] fn set_blend_constant(&self, #[webidl] color: GPUColor) { let err = self .instance @@ -118,6 +121,7 @@ impl GPURenderPassEncoder { } #[required(1)] + #[undefined] fn set_stencil_reference( &self, #[webidl(options(enforce_range = true))] reference: u32, @@ -133,6 +137,7 @@ impl GPURenderPassEncoder { } #[required(1)] + #[undefined] fn begin_occlusion_query( &self, #[webidl(options(enforce_range = true))] query_index: u32, @@ -148,6 +153,7 @@ impl GPURenderPassEncoder { } #[fast] + #[undefined] fn end_occlusion_query(&self) { let err = self .instance @@ -157,6 +163,7 @@ impl GPURenderPassEncoder { } #[required(1)] + #[undefined] fn execute_bundles(&self, #[webidl] bundles: Vec>) { let err = self .instance @@ -172,6 +179,7 @@ impl GPURenderPassEncoder { } #[fast] + #[undefined] fn end(&self) { let err = self .instance @@ -180,6 +188,7 @@ impl GPURenderPassEncoder { self.error_handler.push_error(err); } + #[undefined] fn push_debug_group(&self, #[webidl] group_label: String) { let err = self .instance @@ -193,6 +202,7 @@ impl GPURenderPassEncoder { } #[fast] + #[undefined] fn pop_debug_group(&self) { let err = self .instance @@ -201,6 +211,7 @@ impl GPURenderPassEncoder { self.error_handler.push_error(err); } + #[undefined] fn insert_debug_marker(&self, #[webidl] marker_label: String) { let err = self .instance @@ -213,6 +224,7 @@ impl GPURenderPassEncoder { self.error_handler.push_error(err); } + #[undefined] fn set_bind_group<'a>( &self, scope: &mut v8::HandleScope<'a>, @@ -296,6 +308,7 @@ impl GPURenderPassEncoder { Ok(()) } + #[undefined] fn set_pipeline( &self, #[webidl] pipeline: Ptr, @@ -308,6 +321,7 @@ impl GPURenderPassEncoder { } #[required(2)] + #[undefined] fn set_index_buffer( &self, #[webidl] buffer: Ptr, @@ -329,6 +343,7 @@ impl GPURenderPassEncoder { } #[required(2)] + #[undefined] fn set_vertex_buffer( &self, #[webidl(options(enforce_range = true))] slot: u32, @@ -350,6 +365,7 @@ impl GPURenderPassEncoder { } #[required(1)] + #[undefined] fn draw( &self, #[webidl(options(enforce_range = true))] vertex_count: u32, @@ -371,6 +387,7 @@ impl GPURenderPassEncoder { } #[required(1)] + #[undefined] fn draw_indexed( &self, #[webidl(options(enforce_range = true))] index_count: u32, @@ -394,6 +411,7 @@ impl GPURenderPassEncoder { } #[required(2)] + #[undefined] fn draw_indirect( &self, #[webidl] indirect_buffer: Ptr, @@ -411,6 +429,7 @@ impl GPURenderPassEncoder { } #[required(2)] + #[undefined] fn draw_indexed_indirect( &self, #[webidl] indirect_buffer: Ptr, diff --git a/deno_webgpu/surface.rs b/deno_webgpu/surface.rs index 7c389b5434c..60df27ce0e1 100644 --- a/deno_webgpu/surface.rs +++ b/deno_webgpu/surface.rs @@ -68,6 +68,7 @@ impl GPUCanvasContext { self.canvas.clone() } + #[undefined] fn configure( &self, #[webidl] configuration: GPUCanvasConfiguration, @@ -113,6 +114,7 @@ impl GPUCanvasContext { } #[fast] + #[undefined] fn unconfigure(&self) { *self.config.borrow_mut() = None; } diff --git a/deno_webgpu/texture.rs b/deno_webgpu/texture.rs index c9a84afea32..8d92d7f308a 100644 --- a/deno_webgpu/texture.rs +++ b/deno_webgpu/texture.rs @@ -154,6 +154,7 @@ impl GPUTexture { self.usage } #[fast] + #[undefined] fn destroy(&self) { self.instance.texture_destroy(self.id); } From f1c876c875124197d34decc8ec3a8006f42623be Mon Sep 17 00:00:00 2001 From: Vecvec Date: Tue, 30 Sep 2025 04:38:33 +1300 Subject: [PATCH 259/303] Create a seperate event for each fence wait. (#8273) * create an event per fence wait * Use seperate event for each `wait_for_present_queue_idle` call. * changelog --- CHANGELOG.md | 1 + wgpu-hal/src/dx12/device.rs | 21 +++++++++------------ wgpu-hal/src/dx12/mod.rs | 1 - 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb156281c0f..889438dab50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -214,6 +214,7 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). #### DX12 +- Create an event per wait to prevent 60 second hangs in certain multithreaded scenarios. By @Vecvec in [#8273](https://github.com/gfx-rs/wgpu/pull/8273). - Fixed a bug where access to matrices with 2 rows would not work in some cases. By @andyleiserson in [#7438](https://github.com/gfx-rs/wgpu/pull/7438). ##### EGL diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index dafbbb5bd80..a135478e38f 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -195,10 +195,7 @@ impl super::Device { Ok(super::Device { raw: raw.clone(), present_queue, - idler: super::Idler { - fence: idle_fence, - event: Event::create(false, false)?, - }, + idler: super::Idler { fence: idle_fence }, features, shared: Arc::new(shared), rtv_pool: Arc::new(Mutex::new(rtv_pool)), @@ -256,16 +253,14 @@ impl super::Device { return Err(crate::DeviceError::Lost); } + let event = Event::create(false, false)?; + let value = cur_value + 1; unsafe { self.present_queue.Signal(&self.idler.fence, value) } .into_device_result("Signal")?; - let hr = unsafe { - self.idler - .fence - .SetEventOnCompletion(value, self.idler.event.0) - }; + let hr = unsafe { self.idler.fence.SetEventOnCompletion(value, event.0) }; hr.into_device_result("Set event")?; - unsafe { Threading::WaitForSingleObject(self.idler.event.0, Threading::INFINITE) }; + unsafe { Threading::WaitForSingleObject(event.0, Threading::INFINITE) }; Ok(()) } @@ -2252,7 +2247,9 @@ impl crate::Device for super::Device { return Ok(true); } - unsafe { fence.raw.SetEventOnCompletion(value, self.idler.event.0) } + let event = Event::create(false, false)?; + + unsafe { fence.raw.SetEventOnCompletion(value, event.0) } .into_device_result("Set event")?; let start_time = Instant::now(); @@ -2288,7 +2285,7 @@ impl crate::Device for super::Device { match unsafe { Threading::WaitForSingleObject( - self.idler.event.0, + event.0, remaining_wait_duration.as_millis().try_into().unwrap(), ) } { diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 51fa6e69cc6..981409192c6 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -653,7 +653,6 @@ impl Drop for Event { /// Helper structure for waiting for GPU. struct Idler { fence: Direct3D12::ID3D12Fence, - event: Event, } #[derive(Debug, Clone)] From 9c92a907e1587fbd5b5f88412d3824fdf0c4b7ad Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 11:43:13 -0400 Subject: [PATCH 260/303] chore(deps): update crate-ci/typos action to v1.36.3 (#8276) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cccc07115ed..38c2eef7ecf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -691,7 +691,7 @@ jobs: run: taplo format --check --diff - name: Check for typos - uses: crate-ci/typos@v1.36.2 + uses: crate-ci/typos@v1.36.3 check-cts-runner: # runtime is normally 2 minutes From bc43a23e0410b9465c3d3a698c9892137c29539d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 11:43:27 -0400 Subject: [PATCH 261/303] chore(deps): update cts digest to 5e7bd6e (#8275) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- cts_runner/revision.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cts_runner/revision.txt b/cts_runner/revision.txt index e377c24deb6..a63351a9d1c 100644 --- a/cts_runner/revision.txt +++ b/cts_runner/revision.txt @@ -1 +1 @@ -81bfec725ae101551cc29f5f028c968b19c14467 +5e7bd6ed86201123ff6b0900974587550afb10e7 From a01ffb7967ce08a3b92e28c15ea34938f51a5ef0 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Mon, 29 Sep 2025 08:44:05 -0700 Subject: [PATCH 262/303] Fix unused warning in a specific feature config (#8271) --- naga/src/back/msl/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/naga/src/back/msl/mod.rs b/naga/src/back/msl/mod.rs index 64b1280a1b0..44aedf686c4 100644 --- a/naga/src/back/msl/mod.rs +++ b/naga/src/back/msl/mod.rs @@ -119,9 +119,8 @@ pub struct BindTarget { pub mutable: bool, } -#[cfg(any(feature = "serialize", feature = "deserialize"))] -#[cfg_attr(feature = "serialize", derive(serde::Serialize))] -#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] +#[cfg(feature = "deserialize")] +#[derive(serde::Deserialize)] struct BindingMapSerialization { resource_binding: crate::ResourceBinding, bind_target: BindTarget, From 8cb94db802a408e21c9c3208a80456844cd2260c Mon Sep 17 00:00:00 2001 From: Nils Hasenbanck Date: Mon, 29 Sep 2025 17:45:39 +0200 Subject: [PATCH 263/303] (Naga) Add support for Storage Image Multisample when ingesting SPIR-V (#8270) --- CHANGELOG.md | 3 +- naga/src/front/spv/mod.rs | 1 + naga/tests/in/spv/load-ms-texture.slang | 21 +++++ naga/tests/in/spv/load-ms-texture.spvasm | 93 ++++++++++++++++++++ naga/tests/in/spv/load-ms-texture.toml | 4 + naga/tests/out/wgsl/spv-load-ms-texture.wgsl | 37 ++++++++ 6 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 naga/tests/in/spv/load-ms-texture.slang create mode 100644 naga/tests/in/spv/load-ms-texture.spvasm create mode 100644 naga/tests/in/spv/load-ms-texture.toml create mode 100644 naga/tests/out/wgsl/spv-load-ms-texture.wgsl diff --git a/CHANGELOG.md b/CHANGELOG.md index 889438dab50..784161662cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -200,7 +200,8 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). - **BREAKING**: Previously the WGSL storage-texture format `rg11b10float` was incorrectly accepted and generated by naga, but now only accepts the the correct name `rg11b10ufloat` instead. By @ErikWDev in [#8219](https://github.com/gfx-rs/wgpu/pull/8219). - The [`source()`](https://doc.rust-lang.org/std/error/trait.Error.html#method.source) method of `ShaderError` no longer reports the error as its own source. By @andyleiserson in [#8258](https://github.com/gfx-rs/wgpu/pull/8258). - naga correctly ingests SPIR-V that use descriptor runtime indexing, which in turn is correctly converted into WGSLs binding array. By @hasenbanck in [8256](https://github.com/gfx-rs/wgpu/pull/8256). - +- naga correctly ingests SPIR-V that loads from multi-sampled textures, which in turn is correctly converted into WGSLs texture_multisampled_2d and load operations. By @hasenbanck in [8270](https://github.com/gfx-rs/wgpu/pull/8270). + #### DX12 - Allow disabling waiting for latency waitable object. By @marcpabst in [#7400](https://github.com/gfx-rs/wgpu/pull/7400) diff --git a/naga/src/front/spv/mod.rs b/naga/src/front/spv/mod.rs index 803e52553dc..42ad38b270e 100644 --- a/naga/src/front/spv/mod.rs +++ b/naga/src/front/spv/mod.rs @@ -83,6 +83,7 @@ pub const SUPPORTED_CAPABILITIES: &[spirv::Capability] = &[ spirv::Capability::GroupNonUniformShuffle, spirv::Capability::GroupNonUniformShuffleRelative, spirv::Capability::RuntimeDescriptorArray, + spirv::Capability::StorageImageMultisample, // tricky ones spirv::Capability::UniformBufferArrayDynamicIndexing, spirv::Capability::StorageBufferArrayDynamicIndexing, diff --git a/naga/tests/in/spv/load-ms-texture.slang b/naga/tests/in/spv/load-ms-texture.slang new file mode 100644 index 00000000000..d8f80fd4e8d --- /dev/null +++ b/naga/tests/in/spv/load-ms-texture.slang @@ -0,0 +1,21 @@ +// Compiled with: +// slangc -target spirv -profile spirv_1_5 -o naga/tests/in/spv/load-ms-texture.spv naga/tests/in/spv/load-ms-texture.slang +// Disassembled with: +// spirv-dis naga/tests/in/spv/load-ms-texture.spv -o naga/tests/in/spv/load-ms-texture.spvasm +#language slang 2026 + +[[vk::binding(0, 0)]] var texture: Texture2DMS; + +[[shader("pixel")]] +func fs_main(float4 position : SV_Position) -> float4 { + let pixel_coord = int2(position.xy); + var color: float4; + + for (var index: int = 0; index < 8; index++) { + color += texture.Load(pixel_coord, index); + } + + color = color / 8.0; + + return color; +} diff --git a/naga/tests/in/spv/load-ms-texture.spvasm b/naga/tests/in/spv/load-ms-texture.spvasm new file mode 100644 index 00000000000..28d4e3d691e --- /dev/null +++ b/naga/tests/in/spv/load-ms-texture.spvasm @@ -0,0 +1,93 @@ +; SPIR-V +; Version: 1.5 +; Generator: Khronos Slang Compiler; 0 +; Bound: 65 +; Schema: 0 + OpCapability StorageImageMultisample + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %fs_main "main" %texture %entryPointParam_fs_main %gl_FragCoord + OpExecutionMode %fs_main OriginUpperLeft + OpSource Slang 1 + OpName %index "index" + OpName %index "index" + OpName %color "color" + OpName %color "color" + OpName %color_0 "color" + OpName %entryPointParam_fs_main "entryPointParam_fs_main" + OpName %texture "texture" + OpName %sampled "sampled" + OpName %color_1 "color" + OpName %fs_main "fs_main" + OpDecorate %gl_FragCoord BuiltIn FragCoord + OpDecorate %entryPointParam_fs_main Location 0 + OpDecorate %texture Binding 0 + OpDecorate %texture DescriptorSet 0 + %void = OpTypeVoid + %3 = OpTypeFunction %void + %int = OpTypeInt 32 1 +%_ptr_Function_int = OpTypePointer Function %int + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Function_v4float = OpTypePointer Function %v4float +%_ptr_Input_v4float = OpTypePointer Input %v4float + %v2float = OpTypeVector %float 2 + %v2int = OpTypeVector %int 2 + %int_0 = OpConstant %int 0 + %bool = OpTypeBool + %int_8 = OpConstant %int 8 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %45 = OpTypeImage %float 2D 2 0 1 1 Unknown +%_ptr_UniformConstant_45 = OpTypePointer UniformConstant %45 + %int_1 = OpConstant %int 1 +%gl_FragCoord = OpVariable %_ptr_Input_v4float Input +%entryPointParam_fs_main = OpVariable %_ptr_Output_v4float Output + %texture = OpVariable %_ptr_UniformConstant_45 UniformConstant +%float_0_125 = OpConstant %float 0.125 + %64 = OpConstantComposite %v4float %float_0_125 %float_0_125 %float_0_125 %float_0_125 + %fs_main = OpFunction %void None %3 + %4 = OpLabel + %index = OpVariable %_ptr_Function_int Function + %color = OpVariable %_ptr_Function_v4float Function + %22 = OpLoad %v4float %gl_FragCoord + %26 = OpVectorShuffle %v2float %22 %22 0 1 + %28 = OpConvertFToS %v2int %26 + OpStore %index %int_0 + OpBranch %12 + %12 = OpLabel + OpLoopMerge %17 %21 None + OpBranch %13 + %13 = OpLabel + OpBranch %14 + %14 = OpLabel + OpBranch %15 + %15 = OpLabel + %31 = OpLoad %int %index + %33 = OpSLessThan %bool %31 %int_8 + OpSelectionMerge %18 None + OpBranchConditional %33 %18 %16 + %16 = OpLabel + OpBranch %17 + %18 = OpLabel + %46 = OpLoad %45 %texture + %49 = OpLoad %int %index + %sampled = OpImageFetch %v4float %46 %28 Sample %49 + %52 = OpLoad %v4float %color + %color_1 = OpFAdd %v4float %52 %sampled + OpBranch %19 + %19 = OpLabel + OpBranch %20 + %20 = OpLabel + %56 = OpLoad %int %index + %57 = OpIAdd %int %56 %int_1 + OpStore %index %57 + OpStore %color %color_1 + OpBranch %21 + %21 = OpLabel + OpBranch %12 + %17 = OpLabel + %37 = OpLoad %v4float %color + %color_0 = OpFMul %v4float %37 %64 + OpStore %entryPointParam_fs_main %color_0 + OpReturn + OpFunctionEnd diff --git a/naga/tests/in/spv/load-ms-texture.toml b/naga/tests/in/spv/load-ms-texture.toml new file mode 100644 index 00000000000..fd5664c637a --- /dev/null +++ b/naga/tests/in/spv/load-ms-texture.toml @@ -0,0 +1,4 @@ +god_mode = true + +[spv-in] +adjust_coordinate_space = true diff --git a/naga/tests/out/wgsl/spv-load-ms-texture.wgsl b/naga/tests/out/wgsl/spv-load-ms-texture.wgsl new file mode 100644 index 00000000000..564a7524266 --- /dev/null +++ b/naga/tests/out/wgsl/spv-load-ms-texture.wgsl @@ -0,0 +1,37 @@ +var global: vec4; +var entryPointParam_fs_main: vec4; +@group(0) @binding(0) +var texture: texture_multisampled_2d; + +fn fs_main() { + var index: i32; + var color: vec4; + + let _e9 = global; + index = 0i; + loop { + let _e12 = index; + if (_e12 < 8i) { + } else { + break; + } + let _e14 = index; + let _e15 = textureLoad(texture, vec2(_e9.xy), _e14); + let _e16 = color; + let _e18 = index; + index = (_e18 + 1i); + color = (_e16 + _e15); + continue; + } + let _e20 = color; + entryPointParam_fs_main = (_e20 * vec4(0.125f, 0.125f, 0.125f, 0.125f)); + return; +} + +@fragment +fn main(@builtin(position) param: vec4) -> @location(0) vec4 { + global = param; + fs_main(); + let _e3 = entryPointParam_fs_main; + return _e3; +} From ea80c7dbc3a1656a225e4db5e48f6fde83cdea65 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 29 Sep 2025 17:50:10 +0200 Subject: [PATCH 264/303] hal/vulkan: Accurately map all formats except fp16 to use the non-linear sRGB color space (#8226) --- CHANGELOG.md | 4 ++++ wgpu-hal/src/vulkan/conv.rs | 9 +++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 784161662cc..fe4afa7574c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -222,6 +222,10 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). - Fixed unwrap failed in context creation for some Android devices. By @uael in [#8024](https://github.com/gfx-rs/wgpu/pull/8024). +##### Vulkan + +- Fixed wrong color format+space being reported versus what is hardcoded in `create_swapchain()`. By @MarijnS95 in [#8226](https://github.com/gfx-rs/wgpu/pull/8226). + #### naga - [wgsl-in] Allow a trailing comma in `@blend_src(…)` attributes. By @ErichDonGubler in [#8137](https://github.com/gfx-rs/wgpu/pull/8137). diff --git a/wgpu-hal/src/vulkan/conv.rs b/wgpu-hal/src/vulkan/conv.rs index e6bcb20ca75..97044233e07 100644 --- a/wgpu-hal/src/vulkan/conv.rs +++ b/wgpu-hal/src/vulkan/conv.rs @@ -161,7 +161,8 @@ impl super::PrivateCapabilities { pub fn map_vk_surface_formats(sf: vk::SurfaceFormatKHR) -> Option { use ash::vk::Format as F; use wgt::TextureFormat as Tf; - // List we care about pulled from https://vulkan.gpuinfo.org/listsurfaceformats.php + // List we care about pulled from https://vulkan.gpuinfo.org/listsurfaceformats.php. + // Device::create_swapchain() hardcodes linear scRGB for fp16, non-linear sRGB otherwise. Some(match sf.color_space { vk::ColorSpaceKHR::SRGB_NONLINEAR => match sf.format { F::B8G8R8A8_UNORM => Tf::Bgra8Unorm, @@ -169,13 +170,13 @@ pub fn map_vk_surface_formats(sf: vk::SurfaceFormatKHR) -> Option Tf::Rgba8Snorm, F::R8G8B8A8_UNORM => Tf::Rgba8Unorm, F::R8G8B8A8_SRGB => Tf::Rgba8UnormSrgb, + F::R16G16B16A16_SNORM => Tf::Rgba16Snorm, + F::R16G16B16A16_UNORM => Tf::Rgba16Unorm, + F::A2B10G10R10_UNORM_PACK32 => Tf::Rgb10a2Unorm, _ => return None, }, vk::ColorSpaceKHR::EXTENDED_SRGB_LINEAR_EXT => match sf.format { F::R16G16B16A16_SFLOAT => Tf::Rgba16Float, - F::R16G16B16A16_SNORM => Tf::Rgba16Snorm, - F::R16G16B16A16_UNORM => Tf::Rgba16Unorm, - F::A2B10G10R10_UNORM_PACK32 => Tf::Rgb10a2Unorm, _ => return None, }, _ => return None, From 8c4aebc0c1b75e3f7412dfc180745a0717fc30ec Mon Sep 17 00:00:00 2001 From: Nils Hasenbanck Date: Mon, 29 Sep 2025 19:15:32 +0200 Subject: [PATCH 265/303] (Naga) Implement OpImageGather and OpImageDrefGather when ingesting SPIR-V (#8280) --- CHANGELOG.md | 3 +- naga/src/front/spv/image.rs | 64 +++++++++++++++++++++++-- naga/src/front/spv/mod.rs | 38 +++++++++++++++ naga/tests/in/spv/gather-cmp.slang | 18 +++++++ naga/tests/in/spv/gather-cmp.spvasm | 49 +++++++++++++++++++ naga/tests/in/spv/gather-cmp.toml | 4 ++ naga/tests/in/spv/gather.slang | 18 +++++++ naga/tests/in/spv/gather.spvasm | 50 +++++++++++++++++++ naga/tests/in/spv/gather.toml | 4 ++ naga/tests/out/wgsl/spv-gather-cmp.wgsl | 21 ++++++++ naga/tests/out/wgsl/spv-gather.wgsl | 21 ++++++++ 11 files changed, 284 insertions(+), 6 deletions(-) create mode 100644 naga/tests/in/spv/gather-cmp.slang create mode 100644 naga/tests/in/spv/gather-cmp.spvasm create mode 100644 naga/tests/in/spv/gather-cmp.toml create mode 100644 naga/tests/in/spv/gather.slang create mode 100644 naga/tests/in/spv/gather.spvasm create mode 100644 naga/tests/in/spv/gather.toml create mode 100644 naga/tests/out/wgsl/spv-gather-cmp.wgsl create mode 100644 naga/tests/out/wgsl/spv-gather.wgsl diff --git a/CHANGELOG.md b/CHANGELOG.md index fe4afa7574c..f19f87586b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -201,7 +201,8 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). - The [`source()`](https://doc.rust-lang.org/std/error/trait.Error.html#method.source) method of `ShaderError` no longer reports the error as its own source. By @andyleiserson in [#8258](https://github.com/gfx-rs/wgpu/pull/8258). - naga correctly ingests SPIR-V that use descriptor runtime indexing, which in turn is correctly converted into WGSLs binding array. By @hasenbanck in [8256](https://github.com/gfx-rs/wgpu/pull/8256). - naga correctly ingests SPIR-V that loads from multi-sampled textures, which in turn is correctly converted into WGSLs texture_multisampled_2d and load operations. By @hasenbanck in [8270](https://github.com/gfx-rs/wgpu/pull/8270). - +- naga implement OpImageGather and OpImageDrefGather operations when ingesting SPIR-V. By @hasenbanck in [8280](https://github.com/gfx-rs/wgpu/pull/8280). + #### DX12 - Allow disabling waiting for latency waitable object. By @marcpabst in [#7400](https://github.com/gfx-rs/wgpu/pull/7400) diff --git a/naga/src/front/spv/image.rs b/naga/src/front/spv/image.rs index ee94fe6efc9..591590be024 100644 --- a/naga/src/front/spv/image.rs +++ b/naga/src/front/spv/image.rs @@ -48,6 +48,8 @@ pub struct SamplingOptions { pub project: bool, /// Depth comparison sampling with a reference value. pub compare: bool, + /// Gather sampling: Operates on four samples of one channel. + pub gather: bool, } enum ExtraCoordinate { @@ -500,10 +502,10 @@ impl> super::Frontend { let result_id = self.next()?; let sampled_image_id = self.next()?; let coordinate_id = self.next()?; - let dref_id = if options.compare { - Some(self.next()?) - } else { - None + let (component_id, dref_id) = match (options.gather, options.compare) { + (true, false) => (Some(self.next()?), None), + (_, true) => (None, Some(self.next()?)), + (_, _) => (None, None), }; let span = self.span_from_with_op(start); @@ -629,6 +631,58 @@ impl> super::Frontend { self.get_expr_handle(coordinate_id, coord_lexp, ctx, emitter, block, body_idx); let coord_type_handle = self.lookup_type.lookup(coord_lexp.type_id)?.handle; + let gather = match (options.gather, component_id) { + (true, Some(component_id)) => { + let component_lexp = self.lookup_expression.lookup(component_id)?; + + let component_value = match ctx.expressions[component_lexp.handle] { + // VUID-StandaloneSpirv-OpImageGather-04664: + // The “Component” operand of OpImageGather, and OpImageSparseGather must be the + // of a constant instruction. + crate::Expression::Constant(const_handle) => { + let constant = &ctx.module.constants[const_handle]; + match ctx.module.global_expressions[constant.init] { + // SPIR-V specification: "It must be a 32-bit integer type scalar." + crate::Expression::Literal(crate::Literal::U32(value)) => value, + crate::Expression::Literal(crate::Literal::I32(value)) => value as u32, + _ => { + log::error!( + "Image gather component constant must be a 32-bit integer literal" + ); + return Err(Error::InvalidOperand); + } + } + } + _ => { + log::error!("Image gather component must be a constant"); + return Err(Error::InvalidOperand); + } + }; + + debug_assert_eq!(level, crate::SampleLevel::Auto); + level = crate::SampleLevel::Zero; + + // SPIR-V specification: "Behavior is undefined if its value is not 0, 1, 2 or 3." + match component_value { + 0 => Some(crate::SwizzleComponent::X), + 1 => Some(crate::SwizzleComponent::Y), + 2 => Some(crate::SwizzleComponent::Z), + 3 => Some(crate::SwizzleComponent::W), + other => { + log::error!("Invalid gather component operand: {other}"); + return Err(Error::InvalidOperand); + } + } + } + (true, None) => { + debug_assert_eq!(level, crate::SampleLevel::Auto); + level = crate::SampleLevel::Zero; + + Some(crate::SwizzleComponent::X) + } + (_, _) => None, + }; + let sampling_bit = if options.compare { SamplingFlags::COMPARISON } else { @@ -745,7 +799,7 @@ impl> super::Frontend { let expr = crate::Expression::ImageSample { image: si_lexp.image, sampler: si_lexp.sampler, - gather: None, //TODO + gather, coordinate, array_index, offset, diff --git a/naga/src/front/spv/mod.rs b/naga/src/front/spv/mod.rs index 42ad38b270e..835cbe1aa82 100644 --- a/naga/src/front/spv/mod.rs +++ b/naga/src/front/spv/mod.rs @@ -2802,6 +2802,7 @@ impl> Frontend { let options = image::SamplingOptions { compare: false, project: false, + gather: false, }; self.parse_image_sample( extra, @@ -2818,6 +2819,7 @@ impl> Frontend { let options = image::SamplingOptions { compare: false, project: true, + gather: false, }; self.parse_image_sample( extra, @@ -2834,6 +2836,7 @@ impl> Frontend { let options = image::SamplingOptions { compare: true, project: false, + gather: false, }; self.parse_image_sample( extra, @@ -2850,6 +2853,41 @@ impl> Frontend { let options = image::SamplingOptions { compare: true, project: true, + gather: false, + }; + self.parse_image_sample( + extra, + options, + ctx, + &mut emitter, + &mut block, + block_id, + body_idx, + )?; + } + Op::ImageGather => { + let extra = inst.expect_at_least(6)?; + let options = image::SamplingOptions { + compare: false, + project: false, + gather: true, + }; + self.parse_image_sample( + extra, + options, + ctx, + &mut emitter, + &mut block, + block_id, + body_idx, + )?; + } + Op::ImageDrefGather => { + let extra = inst.expect_at_least(6)?; + let options = image::SamplingOptions { + compare: true, + project: false, + gather: true, }; self.parse_image_sample( extra, diff --git a/naga/tests/in/spv/gather-cmp.slang b/naga/tests/in/spv/gather-cmp.slang new file mode 100644 index 00000000000..6d579d38f5a --- /dev/null +++ b/naga/tests/in/spv/gather-cmp.slang @@ -0,0 +1,18 @@ +// Compiled with: +// slangc -target spirv -profile spirv_1_5 -o naga/tests/in/spv/gather-cmp.spv naga/tests/in/spv/gather-cmp.slang +// Disassembled with: +// spirv-dis naga/tests/in/spv/gather-cmp.spv -o naga/tests/in/spv/gather-cmp.spvasm + +#language slang 2026 + +[[vk::binding(0, 0)]] var texture: Texture2D; +[[vk::binding(1, 0)]] var depth_sampler: SamplerComparisonState; + +struct VertexOutput { + var texture_coordinates: float2; +}; + +[[shader("pixel")]] +func main(input: VertexOutput) -> float4 { + return texture.GatherCmp(depth_sampler, input.texture_coordinates, 0.5); +} diff --git a/naga/tests/in/spv/gather-cmp.spvasm b/naga/tests/in/spv/gather-cmp.spvasm new file mode 100644 index 00000000000..39e8f819b13 --- /dev/null +++ b/naga/tests/in/spv/gather-cmp.spvasm @@ -0,0 +1,49 @@ +; SPIR-V +; Version: 1.5 +; Generator: Khronos Slang Compiler; 0 +; Bound: 27 +; Schema: 0 + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %texture %depth_sampler %entryPointParam_main %input_texture_coordinates + OpExecutionMode %main OriginUpperLeft + OpSource Slang 1 + OpName %input_texture_coordinates "input.texture_coordinates" + OpName %texture "texture" + OpName %depth_sampler "depth_sampler" + OpName %sampledImage "sampledImage" + OpName %entryPointParam_main "entryPointParam_main" + OpName %main "main" + OpDecorate %input_texture_coordinates Location 0 + OpDecorate %texture Binding 0 + OpDecorate %texture DescriptorSet 0 + OpDecorate %depth_sampler Binding 1 + OpDecorate %depth_sampler DescriptorSet 0 + OpDecorate %entryPointParam_main Location 0 + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 +%_ptr_Input_v2float = OpTypePointer Input %v2float + %10 = OpTypeImage %float 2D 2 0 0 1 Unknown +%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10 + %14 = OpTypeSampler +%_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14 + %18 = OpTypeSampledImage %10 + %v4float = OpTypeVector %float 4 + %float_0_5 = OpConstant %float 0.5 +%_ptr_Output_v4float = OpTypePointer Output %v4float +%input_texture_coordinates = OpVariable %_ptr_Input_v2float Input + %texture = OpVariable %_ptr_UniformConstant_10 UniformConstant +%depth_sampler = OpVariable %_ptr_UniformConstant_14 UniformConstant +%entryPointParam_main = OpVariable %_ptr_Output_v4float Output + %main = OpFunction %void None %3 + %4 = OpLabel + %7 = OpLoad %v2float %input_texture_coordinates + %11 = OpLoad %10 %texture + %15 = OpLoad %14 %depth_sampler +%sampledImage = OpSampledImage %18 %11 %15 + %21 = OpImageDrefGather %v4float %sampledImage %7 %float_0_5 + OpStore %entryPointParam_main %21 + OpReturn + OpFunctionEnd diff --git a/naga/tests/in/spv/gather-cmp.toml b/naga/tests/in/spv/gather-cmp.toml new file mode 100644 index 00000000000..fd5664c637a --- /dev/null +++ b/naga/tests/in/spv/gather-cmp.toml @@ -0,0 +1,4 @@ +god_mode = true + +[spv-in] +adjust_coordinate_space = true diff --git a/naga/tests/in/spv/gather.slang b/naga/tests/in/spv/gather.slang new file mode 100644 index 00000000000..20b1a21c96a --- /dev/null +++ b/naga/tests/in/spv/gather.slang @@ -0,0 +1,18 @@ +// Compiled with: +// slangc -target spirv -profile spirv_1_5 -o naga/tests/in/spv/gather.spv naga/tests/in/spv/gather.slang +// Disassembled with: +// spirv-dis naga/tests/in/spv/gather.spv -o naga/tests/in/spv/gather.spvasm + +#language slang 2026 + +[[vk::binding(0, 0)]] var texture: Texture2D; +[[vk::binding(1, 0)]] var linear_sampler: SamplerState; + +struct VertexOutput { + var texture_coordinates: float2; +}; + +[[shader("pixel")]] +func main(input: VertexOutput) -> float4 { + return texture.GatherGreen(linear_sampler, input.texture_coordinates); +} diff --git a/naga/tests/in/spv/gather.spvasm b/naga/tests/in/spv/gather.spvasm new file mode 100644 index 00000000000..65a8946d05f --- /dev/null +++ b/naga/tests/in/spv/gather.spvasm @@ -0,0 +1,50 @@ +; SPIR-V +; Version: 1.5 +; Generator: Khronos Slang Compiler; 0 +; Bound: 28 +; Schema: 0 + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %texture %linear_sampler %entryPointParam_main %input_texture_coordinates + OpExecutionMode %main OriginUpperLeft + OpSource Slang 1 + OpName %input_texture_coordinates "input.texture_coordinates" + OpName %texture "texture" + OpName %linear_sampler "linear_sampler" + OpName %sampledImage "sampledImage" + OpName %entryPointParam_main "entryPointParam_main" + OpName %main "main" + OpDecorate %input_texture_coordinates Location 0 + OpDecorate %texture Binding 0 + OpDecorate %texture DescriptorSet 0 + OpDecorate %linear_sampler Binding 1 + OpDecorate %linear_sampler DescriptorSet 0 + OpDecorate %entryPointParam_main Location 0 + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v2float = OpTypeVector %float 2 +%_ptr_Input_v2float = OpTypePointer Input %v2float + %10 = OpTypeImage %float 2D 2 0 0 1 Unknown +%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10 + %14 = OpTypeSampler +%_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14 + %18 = OpTypeSampledImage %10 + %v4float = OpTypeVector %float 4 + %int = OpTypeInt 32 1 + %int_1 = OpConstant %int 1 +%_ptr_Output_v4float = OpTypePointer Output %v4float +%input_texture_coordinates = OpVariable %_ptr_Input_v2float Input + %texture = OpVariable %_ptr_UniformConstant_10 UniformConstant +%linear_sampler = OpVariable %_ptr_UniformConstant_14 UniformConstant +%entryPointParam_main = OpVariable %_ptr_Output_v4float Output + %main = OpFunction %void None %3 + %4 = OpLabel + %7 = OpLoad %v2float %input_texture_coordinates + %11 = OpLoad %10 %texture + %15 = OpLoad %14 %linear_sampler +%sampledImage = OpSampledImage %18 %11 %15 + %21 = OpImageGather %v4float %sampledImage %7 %int_1 + OpStore %entryPointParam_main %21 + OpReturn + OpFunctionEnd diff --git a/naga/tests/in/spv/gather.toml b/naga/tests/in/spv/gather.toml new file mode 100644 index 00000000000..fd5664c637a --- /dev/null +++ b/naga/tests/in/spv/gather.toml @@ -0,0 +1,4 @@ +god_mode = true + +[spv-in] +adjust_coordinate_space = true diff --git a/naga/tests/out/wgsl/spv-gather-cmp.wgsl b/naga/tests/out/wgsl/spv-gather-cmp.wgsl new file mode 100644 index 00000000000..3a12edddb09 --- /dev/null +++ b/naga/tests/out/wgsl/spv-gather-cmp.wgsl @@ -0,0 +1,21 @@ +var inputtexture_coordinates_1: vec2; +@group(0) @binding(0) +var texture: texture_depth_2d; +@group(0) @binding(1) +var depth_sampler: sampler_comparison; +var entryPointParam_main: vec4; + +fn main_1() { + let _e5 = inputtexture_coordinates_1; + let _e6 = textureGatherCompare(texture, depth_sampler, _e5, 0.5f); + entryPointParam_main = _e6; + return; +} + +@fragment +fn main(@location(0) inputtexture_coordinates: vec2) -> @location(0) vec4 { + inputtexture_coordinates_1 = inputtexture_coordinates; + main_1(); + let _e3 = entryPointParam_main; + return _e3; +} diff --git a/naga/tests/out/wgsl/spv-gather.wgsl b/naga/tests/out/wgsl/spv-gather.wgsl new file mode 100644 index 00000000000..5a92fdbff8a --- /dev/null +++ b/naga/tests/out/wgsl/spv-gather.wgsl @@ -0,0 +1,21 @@ +var inputtexture_coordinates_1: vec2; +@group(0) @binding(0) +var texture: texture_2d; +@group(0) @binding(1) +var linear_sampler: sampler; +var entryPointParam_main: vec4; + +fn main_1() { + let _e4 = inputtexture_coordinates_1; + let _e5 = textureGather(1, texture, linear_sampler, _e4); + entryPointParam_main = _e5; + return; +} + +@fragment +fn main(@location(0) inputtexture_coordinates: vec2) -> @location(0) vec4 { + inputtexture_coordinates_1 = inputtexture_coordinates; + main_1(); + let _e3 = entryPointParam_main; + return _e3; +} From d0bcb7e62dc591690f8ef23b21cd43fd72f4a6cc Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Tue, 30 Sep 2025 23:45:14 +0200 Subject: [PATCH 266/303] CI: Disallow all warnings in `cargo deny` and prune unmatched `skip`s (#8283) The warnings right now all entail `unmatched-skip` / `unmatched-skip-root` that have (likely) gotten stale since various automated Renovate bumps where `Cargo.lock` changes don't require the corresponding unmatched duplicate to be removed from `.deny.toml` again. An exception has been made for `unmatched-organization` since we don't always have a `git` dependency on a fork in `gfx-rs`, resulting in a warning about that orga being in `sources.allow-org.github`. --- .deny.toml | 10 ---------- .github/workflows/ci.yml | 2 ++ 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/.deny.toml b/.deny.toml index fd4fb3a8a1a..30fa7afdca4 100644 --- a/.deny.toml +++ b/.deny.toml @@ -3,17 +3,10 @@ multiple-versions = "deny" skip-tree = [ { name = "windows-sys", version = "0.45" }, { name = "winit", version = "0.29" }, - { name = "rustc_version", version = "0.2.3" }, - { name = "miniz_oxide", version = "0.7.4" }, { name = "rustc-hash", version = "1.1.0" }, # introduced by Deno, to be investigated - { name = "strum_macros", version = "0.25.3" }, { name = "petgraph", version = "0.6.5" }, - { name = "base64-simd", version = "0.7.0" }, - { name = "bit-set", version = "0.5.3" }, - { name = "bit-vec", version = "0.6.3" }, - { name = "capacity_builder", version = "0.1.3" }, ] skip = [ # Flume uses an old version @@ -35,11 +28,8 @@ skip = [ { name = "ordered-float", version = "2.10.1" }, # bindgen (used by deno) uses old version { name = "itertools", version = "0.13.0" }, - # Strum uses an old version - { name = "heck", version = "0.4.0" }, # Deno uses an old version { name = "bincode", version = "1.3.3" }, - { name = "strum", version = "0.25.0" }, ] wildcards = "deny" allow-wildcard-paths = true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 38c2eef7ecf..54d8561f16f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -746,6 +746,7 @@ jobs: with: command: check advisories arguments: --all-features --workspace + command-arguments: -Dwarnings -Aunmatched-organization rust-version: ${{ env.REPO_MSRV }} cargo-deny-check-rest: @@ -763,4 +764,5 @@ jobs: with: command: check bans licenses sources arguments: --all-features --workspace + command-arguments: -Dwarnings -Aunmatched-organization rust-version: ${{ env.REPO_MSRV }} From 06fc6f7345d70de8aca533f42c7f2cdc1f986b3c Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Tue, 30 Sep 2025 18:02:10 -0400 Subject: [PATCH 267/303] feat(wgsl): recognize `enable primitive-index;` (#8237) --- CHANGELOG.md | 4 ++ naga/src/front/wgsl/mod.rs | 4 +- .../wgsl/parse/directive/enable_extension.rs | 12 ++++++ naga/tests/naga/wgsl_errors.rs | 40 +++++++++++++++++++ 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f19f87586b7..efd9a2c5e02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -166,6 +166,10 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). - Added support for external textures based on WebGPU's [`GPUExternalTexture`](https://www.w3.org/TR/webgpu/#gpuexternaltexture). These allow shaders to transparently operate on potentially multiplanar source texture data in either RGB or YCbCr formats via WGSL's `texture_external` type. This is gated behind the `Features::EXTERNAL_TEXTURE` feature, which is currently only supported on DX12. By @jamienicol in [#4386](https://github.com/gfx-rs/wgpu/issues/4386). +#### naga + +- Expose `naga::front::wgsl::UnimplementedEnableExtension`. By @ErichDonGubler in [#8237](https://github.com/gfx-rs/wgpu/pull/8237). + ### Changes #### General diff --git a/naga/src/front/wgsl/mod.rs b/naga/src/front/wgsl/mod.rs index 2c3387e9cdd..ba41dc80128 100644 --- a/naga/src/front/wgsl/mod.rs +++ b/naga/src/front/wgsl/mod.rs @@ -11,7 +11,9 @@ mod parse; #[cfg(test)] mod tests; -pub use parse::directive::enable_extension::{EnableExtension, ImplementedEnableExtension}; +pub use parse::directive::enable_extension::{ + EnableExtension, ImplementedEnableExtension, UnimplementedEnableExtension, +}; pub use crate::front::wgsl::error::ParseError; pub use crate::front::wgsl::parse::directive::language_extension::{ diff --git a/naga/src/front/wgsl/parse/directive/enable_extension.rs b/naga/src/front/wgsl/parse/directive/enable_extension.rs index e614d19b6fe..38d6d6719ca 100644 --- a/naga/src/front/wgsl/parse/directive/enable_extension.rs +++ b/naga/src/front/wgsl/parse/directive/enable_extension.rs @@ -71,6 +71,7 @@ impl EnableExtension { const CLIP_DISTANCES: &'static str = "clip_distances"; const DUAL_SOURCE_BLENDING: &'static str = "dual_source_blending"; const SUBGROUPS: &'static str = "subgroups"; + const PRIMITIVE_INDEX: &'static str = "primitive_index"; /// Convert from a sentinel word in WGSL into its associated [`EnableExtension`], if possible. pub(crate) fn from_ident(word: &str, span: Span) -> Result<'_, Self> { @@ -81,6 +82,9 @@ impl EnableExtension { Self::Implemented(ImplementedEnableExtension::DualSourceBlending) } Self::SUBGROUPS => Self::Unimplemented(UnimplementedEnableExtension::Subgroups), + Self::PRIMITIVE_INDEX => { + Self::Unimplemented(UnimplementedEnableExtension::PrimitiveIndex) + } _ => return Err(Box::new(Error::UnknownEnableExtension(span, word))), }) } @@ -95,6 +99,7 @@ impl EnableExtension { }, Self::Unimplemented(kind) => match kind { UnimplementedEnableExtension::Subgroups => Self::SUBGROUPS, + UnimplementedEnableExtension::PrimitiveIndex => Self::PRIMITIVE_INDEX, }, } } @@ -132,12 +137,19 @@ pub enum UnimplementedEnableExtension { /// /// [`enable subgroups;`]: https://www.w3.org/TR/WGSL/#extension-subgroups Subgroups, + /// Enables the `@builtin(primitive_index)` attribute in WGSL. + /// + /// In the WGSL standard, this corresponds to [`enable primitive-index;`]. + /// + /// [`enable primitive-index;`]: https://www.w3.org/TR/WGSL/#extension-primitive_index + PrimitiveIndex, } impl UnimplementedEnableExtension { pub(crate) const fn tracking_issue_num(self) -> u16 { match self { Self::Subgroups => 5555, + Self::PrimitiveIndex => 8236, } } } diff --git a/naga/tests/naga/wgsl_errors.rs b/naga/tests/naga/wgsl_errors.rs index c1e8421ace1..675f52b94e1 100644 --- a/naga/tests/naga/wgsl_errors.rs +++ b/naga/tests/naga/wgsl_errors.rs @@ -4098,6 +4098,46 @@ fn invalid_clip_distances() { } } +#[test] +fn recognized_but_unimplemented_enable_extension() { + for extension in [ + naga::front::wgsl::UnimplementedEnableExtension::Subgroups, + naga::front::wgsl::UnimplementedEnableExtension::PrimitiveIndex, + ] { + // NOTE: We match exhaustively here to help maintainers add or remove variants to the above + // array. + let snapshot = match extension { + naga::front::wgsl::UnimplementedEnableExtension::Subgroups => "\ +error: the `subgroups` enable-extension is not yet supported + ┌─ wgsl:1:8 + │ +1 │ enable subgroups; + │ ^^^^^^^^^ this enable-extension specifies standard functionality which is not yet implemented in Naga + │ + = note: Let Naga maintainers know that you ran into this at , so they can prioritize it! + +", + naga::front::wgsl::UnimplementedEnableExtension::PrimitiveIndex => "\ +error: the `primitive_index` enable-extension is not yet supported + ┌─ wgsl:1:8 + │ +1 │ enable primitive_index; + │ ^^^^^^^^^^^^^^^ this enable-extension specifies standard functionality which is not yet implemented in Naga + │ + = note: Let Naga maintainers know that you ran into this at , so they can prioritize it! + +", + }; + + let shader = { + let extension = naga::front::wgsl::EnableExtension::Unimplemented(extension); + format!("enable {};", extension.to_ident()) + }; + + check(&shader, snapshot); + } +} + #[test] fn max_type_size_large_array() { // The total size of an array is not resolved until validation. Type aliases From 00ea850d79043bbe67f6667913c86450fa5d8123 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Wed, 1 Oct 2025 09:19:24 +0200 Subject: [PATCH 268/303] Allow timeouting on poll (#8282) --- CHANGELOG.md | 2 + tests/tests/wgpu-gpu/poll.rs | 31 ++++++++++++- wgpu-core/src/device/mod.rs | 4 -- wgpu-core/src/device/queue.rs | 4 +- wgpu-core/src/device/resource.rs | 12 +++-- wgpu-hal/examples/halmark/main.rs | 4 +- wgpu-hal/examples/ray-traced-triangle/main.rs | 4 +- wgpu-hal/src/dx12/device.rs | 8 ++-- wgpu-hal/src/dynamic/device.rs | 6 +-- wgpu-hal/src/gles/device.rs | 6 ++- wgpu-hal/src/gles/fence.rs | 4 +- wgpu-hal/src/lib.rs | 5 +- wgpu-hal/src/metal/device.rs | 8 ++-- wgpu-hal/src/noop/mod.rs | 2 +- wgpu-hal/src/vulkan/device.rs | 8 +++- wgpu-hal/src/vulkan/mod.rs | 1 - wgpu-types/src/lib.rs | 46 +++++++++++++++++-- 17 files changed, 117 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efd9a2c5e02..54db2d4b59b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -165,6 +165,7 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). - Added mesh shader support to `wgpu`, with examples. Requires passthrough. By @SupaMaggie70Incorporated in [#7345](https://github.com/gfx-rs/wgpu/pull/7345). - Added support for external textures based on WebGPU's [`GPUExternalTexture`](https://www.w3.org/TR/webgpu/#gpuexternaltexture). These allow shaders to transparently operate on potentially multiplanar source texture data in either RGB or YCbCr formats via WGSL's `texture_external` type. This is gated behind the `Features::EXTERNAL_TEXTURE` feature, which is currently only supported on DX12. By @jamienicol in [#4386](https://github.com/gfx-rs/wgpu/issues/4386). +- `wgpu::Device::poll` can now specify a timeout via `wgpu::PollType::WaitWithTimeout`/`wgpu::PollType::WaitForSubmissionIndexWithTimeout`. By @wumpf in [#8282](https://github.com/gfx-rs/wgpu/pull/8282) #### naga @@ -194,6 +195,7 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). - Require new `F16_IN_F32` downlevel flag for `quantizeToF16`, `pack2x16float`, and `unpack2x16float` in WGSL input. By @aleiserson in [#8130](https://github.com/gfx-rs/wgpu/pull/8130). - The error message for non-copyable depth/stencil formats no longer mentions the aspect when it is not relevant. By @reima in [#8156](https://github.com/gfx-rs/wgpu/pull/8156). - Track the initialization status of buffer memory correctly when `copy_texture_to_buffer` skips over padding space between rows or layers, or when the start/end of a texture-buffer transfer is not 4B aligned. By @andyleiserson in [#8099](https://github.com/gfx-rs/wgpu/pull/8099). +- `wgpu::PollType::Wait`/`wgpu::PollType::WaitForSubmissionIndex` will no longer timeout after 60 seconds, but instead wait indefinitely or (depending on backend implementation) until an error is encountered. Use `wgpu::PollType::WaitWithTimeout`/`wgpu::PollType::WaitForSubmissionIndexWithTimeout` if you need a timeout. By @wumpf in [#8282](https://github.com/gfx-rs/wgpu/pull/8282) #### naga diff --git a/tests/tests/wgpu-gpu/poll.rs b/tests/tests/wgpu-gpu/poll.rs index 70d3b393c7e..6f29313fdcc 100644 --- a/tests/tests/wgpu-gpu/poll.rs +++ b/tests/tests/wgpu-gpu/poll.rs @@ -1,4 +1,4 @@ -use std::num::NonZeroU64; +use std::{num::NonZeroU64, time::Duration}; use wgpu::{ BindGroupDescriptor, BindGroupEntry, BindGroupLayoutDescriptor, BindGroupLayoutEntry, @@ -13,8 +13,10 @@ use wgpu_test::{ pub fn all_tests(vec: &mut Vec) { vec.extend([ WAIT, + WAIT_WITH_TIMEOUT, DOUBLE_WAIT, WAIT_ON_SUBMISSION, + WAIT_ON_SUBMISSION_WITH_TIMEOUT, DOUBLE_WAIT_ON_SUBMISSION, WAIT_OUT_OF_ORDER, WAIT_AFTER_BAD_SUBMISSION, @@ -75,6 +77,18 @@ static WAIT: GpuTestConfiguration = GpuTestConfiguration::new() ctx.async_poll(PollType::wait()).await.unwrap(); }); +#[gpu_test] +static WAIT_WITH_TIMEOUT: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_async(|ctx| async move { + let cmd_buf = generate_dummy_work(&ctx); + + ctx.queue.submit(Some(cmd_buf)); + ctx.async_poll(PollType::WaitWithTimeout(Duration::from_secs(1))) + .await + .unwrap(); + }); + #[gpu_test] static DOUBLE_WAIT: GpuTestConfiguration = GpuTestConfiguration::new() .parameters(TestParameters::default().enable_noop()) @@ -96,6 +110,21 @@ static WAIT_ON_SUBMISSION: GpuTestConfiguration = GpuTestConfiguration::new() ctx.async_poll(PollType::wait_for(index)).await.unwrap(); }); +#[gpu_test] +static WAIT_ON_SUBMISSION_WITH_TIMEOUT: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_async(|ctx| async move { + let cmd_buf = generate_dummy_work(&ctx); + + let index = ctx.queue.submit(Some(cmd_buf)); + ctx.async_poll(PollType::WaitForSubmissionIndexWithTimeout { + submission_index: index, + timeout: Duration::from_secs(1), + }) + .await + .unwrap(); + }); + #[gpu_test] static DOUBLE_WAIT_ON_SUBMISSION: GpuTestConfiguration = GpuTestConfiguration::new() .parameters(TestParameters::default().enable_noop()) diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 643b07c8f3b..38e1b1d08f8 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -35,10 +35,6 @@ pub const SHADER_STAGE_COUNT: usize = hal::MAX_CONCURRENT_SHADER_STAGES; // value is enough for a 16k texture with float4 format. pub(crate) const ZERO_BUFFER_SIZE: BufferAddress = 512 << 10; -// If a submission is not completed within this time, we go off into UB land. -// See https://github.com/gfx-rs/wgpu/issues/4589. 60s to reduce the chances of this. -const CLEANUP_WAIT_MS: u32 = 60000; - pub(crate) const ENTRYPOINT_FAILURE_ERROR: &str = "The given EntryPoint is Invalid"; pub type DeviceDescriptor<'a> = wgt::DeviceDescriptor>; diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index eb936ce7095..0f36ad1e5f7 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -183,9 +183,9 @@ impl Drop for Queue { fence.as_ref(), last_successful_submission_index, #[cfg(not(target_arch = "wasm32"))] - timeout_ms, + Some(core::time::Duration::from_millis(timeout_ms)), #[cfg(target_arch = "wasm32")] - 0, // WebKit and Chromium don't support a non-0 timeout + Some(core::time::Duration::ZERO), // WebKit and Chromium don't support a non-0 timeout ) }; // Note: If we don't panic below we are in UB land (destroying resources while they are still in use by the GPU). diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 7d5898ecc2d..f1f0a4c4fb1 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -29,7 +29,6 @@ use crate::{ device::{ bgl, create_validator, life::WaitIdleError, map_buffer, AttachmentData, DeviceLostInvocation, HostMap, MissingDownlevelFlags, MissingFeatures, RenderPassContext, - CLEANUP_WAIT_MS, }, hal_label, init_tracker::{ @@ -712,7 +711,10 @@ impl Device { // If a wait was requested, determine which submission index to wait for. let wait_submission_index = match poll_type { - wgt::PollType::WaitForSubmissionIndex(submission_index) => { + wgt::PollType::WaitForSubmissionIndex(submission_index) + | wgt::PollType::WaitForSubmissionIndexWithTimeout { + submission_index, .. + } => { let last_successful_submission_index = self .last_successful_submission_index .load(Ordering::Acquire); @@ -728,7 +730,7 @@ impl Device { Some(submission_index) } - wgt::PollType::Wait => Some( + wgt::PollType::Wait | wgt::PollType::WaitWithTimeout { .. } => Some( self.last_successful_submission_index .load(Ordering::Acquire), ), @@ -741,7 +743,7 @@ impl Device { let wait_result = unsafe { self.raw() - .wait(fence.as_ref(), target_submission_index, CLEANUP_WAIT_MS) + .wait(fence.as_ref(), target_submission_index, poll_type.timeout()) }; // This error match is only about `DeviceErrors`. At this stage we do not care if @@ -4499,7 +4501,7 @@ impl Device { let last_done_index = unsafe { self.raw().get_fence_value(fence.as_ref()) } .map_err(|e| self.handle_hal_error(e))?; if last_done_index < submission_index { - unsafe { self.raw().wait(fence.as_ref(), submission_index, !0) } + unsafe { self.raw().wait(fence.as_ref(), submission_index, None) } .map_err(|e| self.handle_hal_error(e))?; drop(fence); if let Some(queue) = self.get_queue() { diff --git a/wgpu-hal/examples/halmark/main.rs b/wgpu-hal/examples/halmark/main.rs index 22f211c909b..c70e37bc12b 100644 --- a/wgpu-hal/examples/halmark/main.rs +++ b/wgpu-hal/examples/halmark/main.rs @@ -54,7 +54,7 @@ struct ExecutionContext { impl ExecutionContext { unsafe fn wait_and_clear(&mut self, device: &A::Device) { - device.wait(&self.fence, self.fence_value, !0).unwrap(); + device.wait(&self.fence, self.fence_value, None).unwrap(); self.encoder.reset_all(self.used_cmd_bufs.drain(..)); for view in self.used_views.drain(..) { device.destroy_texture_view(view); @@ -519,7 +519,7 @@ impl Example { queue .submit(&[&init_cmd], &[], (&mut fence, init_fence_value)) .unwrap(); - device.wait(&fence, init_fence_value, !0).unwrap(); + device.wait(&fence, init_fence_value, None).unwrap(); device.destroy_buffer(staging_buffer); cmd_encoder.reset_all(iter::once(init_cmd)); fence diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index 43cb405ef14..69c4ff2cf4e 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -181,7 +181,7 @@ struct ExecutionContext { impl ExecutionContext { unsafe fn wait_and_clear(&mut self, device: &A::Device) { - device.wait(&self.fence, self.fence_value, !0).unwrap(); + device.wait(&self.fence, self.fence_value, None).unwrap(); self.encoder.reset_all(self.used_cmd_bufs.drain(..)); for view in self.used_views.drain(..) { device.destroy_texture_view(view); @@ -816,7 +816,7 @@ impl Example { queue .submit(&[&init_cmd], &[], (&mut fence, init_fence_value)) .unwrap(); - device.wait(&fence, init_fence_value, !0).unwrap(); + device.wait(&fence, init_fence_value, None).unwrap(); cmd_encoder.reset_all(iter::once(init_cmd)); fence }; diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index a135478e38f..6cd959e7114 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -2237,9 +2237,9 @@ impl crate::Device for super::Device { &self, fence: &super::Fence, value: crate::FenceValue, - timeout_ms: u32, + timeout: Option, ) -> Result { - let timeout_duration = Duration::from_millis(timeout_ms as u64); + let timeout = timeout.unwrap_or(Duration::MAX); // We first check if the fence has already reached the value we're waiting for. let mut fence_value = unsafe { fence.raw.GetCompletedValue() }; @@ -2273,7 +2273,7 @@ impl crate::Device for super::Device { // // This happens when a previous iteration WaitForSingleObject succeeded with a previous fence value, // right before the timeout would have been hit. - let remaining_wait_duration = match timeout_duration.checked_sub(elapsed) { + let remaining_wait_duration = match timeout.checked_sub(elapsed) { Some(remaining) => remaining, None => { log::trace!("Timeout elapsed in between waits!"); @@ -2286,7 +2286,7 @@ impl crate::Device for super::Device { match unsafe { Threading::WaitForSingleObject( event.0, - remaining_wait_duration.as_millis().try_into().unwrap(), + remaining_wait_duration.as_millis().min(u32::MAX as u128) as u32, ) } { Foundation::WAIT_OBJECT_0 => {} diff --git a/wgpu-hal/src/dynamic/device.rs b/wgpu-hal/src/dynamic/device.rs index 1f6ed912689..20263143808 100644 --- a/wgpu-hal/src/dynamic/device.rs +++ b/wgpu-hal/src/dynamic/device.rs @@ -135,7 +135,7 @@ pub trait DynDevice: DynResource { &self, fence: &dyn DynFence, value: FenceValue, - timeout_ms: u32, + timeout: Option, ) -> Result; unsafe fn start_graphics_debugger_capture(&self) -> bool; @@ -486,10 +486,10 @@ impl DynDevice for D { &self, fence: &dyn DynFence, value: FenceValue, - timeout_ms: u32, + timeout: Option, ) -> Result { let fence = fence.expect_downcast_ref(); - unsafe { D::wait(self, fence, value, timeout_ms) } + unsafe { D::wait(self, fence, value, timeout) } } unsafe fn start_graphics_debugger_capture(&self) -> bool { diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index dda5525c61c..b45d53cc23e 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -1564,7 +1564,7 @@ impl crate::Device for super::Device { &self, fence: &super::Fence, wait_value: crate::FenceValue, - timeout_ms: u32, + timeout: Option, ) -> Result { if fence.satisfied(wait_value) { return Ok(true); @@ -1578,7 +1578,9 @@ impl crate::Device for super::Device { let timeout_ns = if cfg!(any(webgl, Emscripten)) { 0 } else { - (timeout_ms as u64 * 1_000_000).min(!0u32 as u64) + timeout + .map(|t| t.as_nanos().min(u32::MAX as u128) as u32) + .unwrap_or(u32::MAX) }; fence.wait(gl, wait_value, timeout_ns) } diff --git a/wgpu-hal/src/gles/fence.rs b/wgpu-hal/src/gles/fence.rs index b29a6324290..d5cd0ec42c9 100644 --- a/wgpu-hal/src/gles/fence.rs +++ b/wgpu-hal/src/gles/fence.rs @@ -102,7 +102,7 @@ impl Fence { &self, gl: &glow::Context, wait_value: crate::FenceValue, - timeout_ns: u64, + timeout_ns: u32, ) -> Result { let last_completed = self.last_completed.load(Ordering::Acquire); @@ -134,7 +134,7 @@ impl Fence { gl.client_wait_sync( gl_fence.sync, glow::SYNC_FLUSH_COMMANDS_BIT, - timeout_ns as i32, + timeout_ns.min(i32::MAX as u32) as i32, ) }; diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index b4255a6c811..a614098240d 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -981,6 +981,9 @@ pub trait Device: WasmNotSendSync { /// Calling `wait` with a lower [`FenceValue`] than `fence`'s current value /// returns immediately. /// + /// If `timeout` is provided, the function will block indefinitely or until + /// an error is encountered. + /// /// Returns `Ok(true)` on success and `Ok(false)` on timeout. /// /// [`Fence`]: Api::Fence @@ -989,7 +992,7 @@ pub trait Device: WasmNotSendSync { &self, fence: &::Fence, value: FenceValue, - timeout_ms: u32, + timeout: Option, ) -> Result; /// Start a graphics debugger capture. diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index 6b94f43fb1b..9f994e6302f 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -1580,7 +1580,7 @@ impl crate::Device for super::Device { &self, fence: &super::Fence, wait_value: crate::FenceValue, - timeout_ms: u32, + timeout: Option, ) -> DeviceResult { if wait_value <= fence.completed_value.load(atomic::Ordering::Acquire) { return Ok(true); @@ -1603,8 +1603,10 @@ impl crate::Device for super::Device { if let MTLCommandBufferStatus::Completed = cmd_buf.status() { return Ok(true); } - if start.elapsed().as_millis() >= timeout_ms as u128 { - return Ok(false); + if let Some(timeout) = timeout { + if start.elapsed() >= timeout { + return Ok(false); + } } thread::sleep(core::time::Duration::from_millis(1)); } diff --git a/wgpu-hal/src/noop/mod.rs b/wgpu-hal/src/noop/mod.rs index abd7c628a98..4d06e04331e 100644 --- a/wgpu-hal/src/noop/mod.rs +++ b/wgpu-hal/src/noop/mod.rs @@ -429,7 +429,7 @@ impl crate::Device for Context { &self, fence: &Fence, value: crate::FenceValue, - timeout_ms: u32, + timeout: Option, ) -> DeviceResult { // The relevant commands must have already been submitted, and noop-backend commands are // executed synchronously, so there is no waiting — either it is already done, diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index f04bce4954e..17d075c3810 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -4,6 +4,7 @@ use core::{ mem::{self, MaybeUninit}, num::NonZeroU32, ptr, + time::Duration, }; use arrayvec::ArrayVec; @@ -2443,9 +2444,12 @@ impl crate::Device for super::Device { &self, fence: &super::Fence, wait_value: crate::FenceValue, - timeout_ms: u32, + timeout: Option, ) -> Result { - let timeout_ns = timeout_ms as u64 * super::MILLIS_TO_NANOS; + let timeout_ns = timeout + .unwrap_or(Duration::MAX) + .as_nanos() + .min(u64::MAX as _) as u64; self.shared.wait_for_fence(fence, wait_value, timeout_ns) } diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index e5b2dd49a91..183950b71f0 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -49,7 +49,6 @@ use wgt::InternalCounter; use semaphore_list::SemaphoreList; -const MILLIS_TO_NANOS: u64 = 1_000_000; const MAX_TOTAL_ATTACHMENTS: usize = crate::MAX_COLOR_ATTACHMENTS * 2 + 1; #[derive(Clone, Debug)] diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index aba8542c520..c2c70e67c66 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -16,13 +16,14 @@ extern crate alloc; use alloc::borrow::Cow; use alloc::{string::String, vec, vec::Vec}; -use core::cmp::Ordering; use core::{ + cmp::Ordering, fmt, hash::{Hash, Hasher}, mem, num::NonZeroU32, ops::Range, + time::Duration, }; use bytemuck::{Pod, Zeroable}; @@ -4503,8 +4504,26 @@ pub enum PollType { /// On WebGPU, this has no effect. Callbacks are invoked from the /// window event loop. WaitForSubmissionIndex(T), - /// Same as `WaitForSubmissionIndex` but waits for the most recent submission. + + /// Same as [`Self::WaitForSubmissionIndex`] but with a timeout. + WaitForSubmissionIndexWithTimeout { + /// Submission index to wait for. + submission_index: T, + + /// Max time to wait for the submission to complete. + /// + /// If waiting for the GPU device takes this long or longer, the poll will return [`PollError::Timeout`]. + timeout: Duration, + }, + + /// Same as [`Self::WaitForSubmissionIndex`] but waits for the most recent submission. Wait, + + /// Same as [`Self::Wait`], but with a timeout. + /// + /// If waiting for the GPU device takes this long or longer, the poll will return [`PollError::Timeout`]. + WaitWithTimeout(Duration), + /// Check the device for a single time without blocking. Poll, } @@ -4532,7 +4551,10 @@ impl PollType { #[must_use] pub fn is_wait(&self) -> bool { match *self { - Self::WaitForSubmissionIndex(..) | Self::Wait => true, + Self::WaitForSubmissionIndex(..) + | Self::Wait + | Self::WaitForSubmissionIndexWithTimeout { .. } + | Self::WaitWithTimeout { .. } => true, Self::Poll => false, } } @@ -4546,9 +4568,27 @@ impl PollType { match self { Self::WaitForSubmissionIndex(i) => PollType::WaitForSubmissionIndex(func(i)), Self::Wait => PollType::Wait, + Self::WaitForSubmissionIndexWithTimeout { + submission_index, + timeout, + } => PollType::WaitForSubmissionIndexWithTimeout { + submission_index: func(submission_index), + timeout, + }, + Self::WaitWithTimeout(timeout) => PollType::WaitWithTimeout(timeout), Self::Poll => PollType::Poll, } } + + /// Returns the timeout in milliseconds if the poll type has a timeout. + #[must_use] + pub fn timeout(&self) -> Option { + match self { + Self::WaitForSubmissionIndexWithTimeout { timeout, .. } + | Self::WaitWithTimeout(timeout) => Some(*timeout), + _ => None, + } + } } /// Error states after a device poll From 90702156af02441256a8d530e6699a0cba8b485f Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Tue, 22 Jul 2025 11:08:39 -0400 Subject: [PATCH 269/303] fix(namer): escape, rather than strip, non-ASCII ident. characters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Escape non-ASCII identifier characters with `write!(…, "u{:04x}", …)`, surrounding with `_` as appropriate. This solves (1) a debugging issue where stripped characters would otherwise be invisible, and (2) failure to re-validate that stripped identifiers didn't start with an ASCII digit. I've confirmed that this fixes [bug 1978197](https://bugzilla.mozilla.org/show_bug.cgi?id=1978197) on the Firefox side. --- CHANGELOG.md | 1 + naga/src/proc/namer.rs | 29 +++++++++---- naga/tests/in/wgsl/7995-unicode-idents.wgsl | 14 ++++++ .../out/glsl/spv-do-while.main.Fragment.glsl | 4 +- ...wgsl-7995-unicode-idents.main.Compute.glsl | 21 +++++++++ ...t_atomic_compare_exchange_i32.Compute.glsl | 6 +-- ...t_atomic_compare_exchange_u32.Compute.glsl | 6 +-- .../glsl/wgsl-atomicOps.cs_main.Compute.glsl | 20 ++++----- naga/tests/out/hlsl/spv-do-while.hlsl | 4 +- naga/tests/out/hlsl/spv-fetch_depth.hlsl | 2 +- naga/tests/out/hlsl/spv-fetch_depth.ron | 2 +- .../out/hlsl/wgsl-7995-unicode-idents.hlsl | 15 +++++++ .../out/hlsl/wgsl-7995-unicode-idents.ron | 12 ++++++ .../wgsl-atomicCompareExchange-int64.hlsl | 8 ++-- .../out/hlsl/wgsl-atomicCompareExchange.hlsl | 8 ++-- naga/tests/out/hlsl/wgsl-atomicOps-int64.hlsl | 20 ++++----- naga/tests/out/hlsl/wgsl-atomicOps.hlsl | 20 ++++----- naga/tests/out/msl/spv-do-while.msl | 4 +- naga/tests/out/msl/spv-fetch_depth.msl | 2 +- .../out/msl/wgsl-7995-unicode-idents.msl | 21 +++++++++ .../out/msl/wgsl-atomicCompareExchange.msl | 24 +++++------ naga/tests/out/msl/wgsl-atomicOps.msl | 36 ++++++++-------- ...sl-overrides-atomicCompareExchangeWeak.msl | 12 +++--- .../out/spv/wgsl-7995-unicode-idents.spvasm | 43 +++++++++++++++++++ .../out/wgsl/spv-atomic_compare_exchange.wgsl | 2 +- naga/tests/out/wgsl/spv-atomic_exchange.wgsl | 2 +- naga/tests/out/wgsl/spv-atomic_i_add_sub.wgsl | 2 +- .../out/wgsl/spv-atomic_i_decrement.wgsl | 2 +- .../out/wgsl/spv-atomic_i_increment.wgsl | 2 +- .../out/wgsl/spv-atomic_load_and_store.wgsl | 2 +- .../out/wgsl/spv-binding-arrays.runtime.wgsl | 14 +++--- ...v-builtin-accessed-outside-entrypoint.wgsl | 4 +- naga/tests/out/wgsl/spv-do-while.wgsl | 4 +- naga/tests/out/wgsl/spv-fetch_depth.wgsl | 2 +- naga/tests/out/wgsl/spv-gather-cmp.wgsl | 8 ++-- naga/tests/out/wgsl/spv-gather.wgsl | 8 ++-- .../out/wgsl/wgsl-7995-unicode-idents.wgsl | 14 ++++++ 37 files changed, 276 insertions(+), 124 deletions(-) create mode 100644 naga/tests/in/wgsl/7995-unicode-idents.wgsl create mode 100644 naga/tests/out/glsl/wgsl-7995-unicode-idents.main.Compute.glsl create mode 100644 naga/tests/out/hlsl/wgsl-7995-unicode-idents.hlsl create mode 100644 naga/tests/out/hlsl/wgsl-7995-unicode-idents.ron create mode 100644 naga/tests/out/msl/wgsl-7995-unicode-idents.msl create mode 100644 naga/tests/out/spv/wgsl-7995-unicode-idents.spvasm create mode 100644 naga/tests/out/wgsl/wgsl-7995-unicode-idents.wgsl diff --git a/CHANGELOG.md b/CHANGELOG.md index 54db2d4b59b..66c36cd5c6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -237,6 +237,7 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). - [wgsl-in] Allow a trailing comma in `@blend_src(…)` attributes. By @ErichDonGubler in [#8137](https://github.com/gfx-rs/wgpu/pull/8137). - [wgsl-in] Allow a trailing comma in the list of `case` values inside a `switch`. By @reima in [#8165](https://github.com/gfx-rs/wgpu/pull/8165). +- Escape, rather than strip, identifiers with Unicode. By @ErichDonGubler in [7995](https://github.com/gfx-rs/wgpu/pull/7995). ### Documentation diff --git a/naga/src/proc/namer.rs b/naga/src/proc/namer.rs index 38c1713567e..71c00a4cdaf 100644 --- a/naga/src/proc/namer.rs +++ b/naga/src/proc/namer.rs @@ -118,20 +118,31 @@ impl Namer { { Cow::Borrowed(string) } else { - let mut filtered = string - .chars() - .filter(|&c| c.is_ascii_alphanumeric() || c == '_') - .fold(String::new(), |mut s, c| { - if s.ends_with('_') && c == '_' { - return s; - } + let mut filtered = string.chars().fold(String::new(), |mut s, c| { + let had_underscore_at_end = s.ends_with('_'); + if had_underscore_at_end && c == '_' { + return s; + } + if c.is_ascii_alphanumeric() || c == '_' { s.push(c); - s - }); + } else { + use core::fmt::Write as _; + if !s.is_empty() && !had_underscore_at_end { + s.push('_'); + } + write!(s, "u{:04x}_", c as u32).unwrap(); + } + s + }); let stripped_len = filtered.trim_end_matches(SEPARATOR).len(); filtered.truncate(stripped_len); if filtered.is_empty() { filtered.push_str("unnamed"); + } else if filtered.starts_with(|c: char| c.is_ascii_digit()) { + unreachable!( + "internal error: invalid identifier starting with ASCII digit {:?}", + filtered.chars().nth(0) + ) } Cow::Owned(filtered) }; diff --git a/naga/tests/in/wgsl/7995-unicode-idents.wgsl b/naga/tests/in/wgsl/7995-unicode-idents.wgsl new file mode 100644 index 00000000000..64e932ed09d --- /dev/null +++ b/naga/tests/in/wgsl/7995-unicode-idents.wgsl @@ -0,0 +1,14 @@ +// NOTE: This allows us to suppress compaction below, to force the handling of identifiers +// containing Unicode. +@group(0) @binding(0) +var asdf: f32; + +fn compute() -> f32 { + let θ2 = asdf + 9001.0; + return θ2; +} + +@compute @workgroup_size(1, 1) +fn main() { + compute(); +} diff --git a/naga/tests/out/glsl/spv-do-while.main.Fragment.glsl b/naga/tests/out/glsl/spv-do-while.main.Fragment.glsl index fb8f6e1efa7..a79915b8881 100644 --- a/naga/tests/out/glsl/spv-do-while.main.Fragment.glsl +++ b/naga/tests/out/glsl/spv-do-while.main.Fragment.glsl @@ -4,7 +4,7 @@ precision highp float; precision highp int; -void fb1_(inout bool cond) { +void f_u0028_b1_u003b(inout bool cond) { bool loop_init = true; while(true) { if (!loop_init) { @@ -22,7 +22,7 @@ void fb1_(inout bool cond) { void main_1() { bool param = false; param = false; - fb1_(param); + f_u0028_b1_u003b(param); return; } diff --git a/naga/tests/out/glsl/wgsl-7995-unicode-idents.main.Compute.glsl b/naga/tests/out/glsl/wgsl-7995-unicode-idents.main.Compute.glsl new file mode 100644 index 00000000000..25fb2d7548f --- /dev/null +++ b/naga/tests/out/glsl/wgsl-7995-unicode-idents.main.Compute.glsl @@ -0,0 +1,21 @@ +#version 310 es + +precision highp float; +precision highp int; + +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; + +layout(std430) readonly buffer type_block_0Compute { float _group_0_binding_0_cs; }; + + +float compute() { + float _e1 = _group_0_binding_0_cs; + float u03b8_2_ = (_e1 + 9001.0); + return u03b8_2_; +} + +void main() { + float _e0 = compute(); + return; +} + diff --git a/naga/tests/out/glsl/wgsl-atomicCompareExchange.test_atomic_compare_exchange_i32.Compute.glsl b/naga/tests/out/glsl/wgsl-atomicCompareExchange.test_atomic_compare_exchange_i32.Compute.glsl index 92d9c4355ff..af3f9a13c99 100644 --- a/naga/tests/out/glsl/wgsl-atomicCompareExchange.test_atomic_compare_exchange_i32.Compute.glsl +++ b/naga/tests/out/glsl/wgsl-atomicCompareExchange.test_atomic_compare_exchange_i32.Compute.glsl @@ -5,11 +5,11 @@ precision highp int; layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; -struct _atomic_compare_exchange_resultSint4_ { +struct _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e { int old_value; bool exchanged; }; -struct _atomic_compare_exchange_resultUint4_ { +struct _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e { uint old_value; bool exchanged; }; @@ -50,7 +50,7 @@ void main() { int new = floatBitsToInt((intBitsToFloat(_e14) + 1.0)); uint _e20 = i; int _e22 = old; - _atomic_compare_exchange_resultSint4_ _e23; _e23.old_value = atomicCompSwap(_group_0_binding_0_cs[_e20], _e22, new); + _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e23; _e23.old_value = atomicCompSwap(_group_0_binding_0_cs[_e20], _e22, new); _e23.exchanged = (_e23.old_value == _e22); old = _e23.old_value; exchanged = _e23.exchanged; diff --git a/naga/tests/out/glsl/wgsl-atomicCompareExchange.test_atomic_compare_exchange_u32.Compute.glsl b/naga/tests/out/glsl/wgsl-atomicCompareExchange.test_atomic_compare_exchange_u32.Compute.glsl index bbb4dea843b..bd32bb95781 100644 --- a/naga/tests/out/glsl/wgsl-atomicCompareExchange.test_atomic_compare_exchange_u32.Compute.glsl +++ b/naga/tests/out/glsl/wgsl-atomicCompareExchange.test_atomic_compare_exchange_u32.Compute.glsl @@ -5,11 +5,11 @@ precision highp int; layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; -struct _atomic_compare_exchange_resultSint4_ { +struct _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e { int old_value; bool exchanged; }; -struct _atomic_compare_exchange_resultUint4_ { +struct _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e { uint old_value; bool exchanged; }; @@ -50,7 +50,7 @@ void main() { uint new = floatBitsToUint((uintBitsToFloat(_e14) + 1.0)); uint _e20 = i_1; uint _e22 = old_1; - _atomic_compare_exchange_resultUint4_ _e23; _e23.old_value = atomicCompSwap(_group_0_binding_1_cs[_e20], _e22, new); + _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e23; _e23.old_value = atomicCompSwap(_group_0_binding_1_cs[_e20], _e22, new); _e23.exchanged = (_e23.old_value == _e22); old_1 = _e23.old_value; exchanged_1 = _e23.exchanged; diff --git a/naga/tests/out/glsl/wgsl-atomicOps.cs_main.Compute.glsl b/naga/tests/out/glsl/wgsl-atomicOps.cs_main.Compute.glsl index 7e1b5061ba1..5713a76340f 100644 --- a/naga/tests/out/glsl/wgsl-atomicOps.cs_main.Compute.glsl +++ b/naga/tests/out/glsl/wgsl-atomicOps.cs_main.Compute.glsl @@ -9,11 +9,11 @@ struct Struct { uint atomic_scalar; int atomic_arr[2]; }; -struct _atomic_compare_exchange_resultUint4_ { +struct _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e { uint old_value; bool exchanged; }; -struct _atomic_compare_exchange_resultSint4_ { +struct _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e { int old_value; bool exchanged; }; @@ -135,21 +135,21 @@ void main() { int _e295 = atomicExchange(workgroup_atomic_arr[1], 1); uint _e299 = atomicExchange(workgroup_struct.atomic_scalar, 1u); int _e304 = atomicExchange(workgroup_struct.atomic_arr[1], 1); - _atomic_compare_exchange_resultUint4_ _e308; _e308.old_value = atomicCompSwap(_group_0_binding_0_cs, 1u, 2u); + _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e308; _e308.old_value = atomicCompSwap(_group_0_binding_0_cs, 1u, 2u); _e308.exchanged = (_e308.old_value == 1u); - _atomic_compare_exchange_resultSint4_ _e313; _e313.old_value = atomicCompSwap(_group_0_binding_1_cs[1], 1, 2); + _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e313; _e313.old_value = atomicCompSwap(_group_0_binding_1_cs[1], 1, 2); _e313.exchanged = (_e313.old_value == 1); - _atomic_compare_exchange_resultUint4_ _e318; _e318.old_value = atomicCompSwap(_group_0_binding_2_cs.atomic_scalar, 1u, 2u); + _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e318; _e318.old_value = atomicCompSwap(_group_0_binding_2_cs.atomic_scalar, 1u, 2u); _e318.exchanged = (_e318.old_value == 1u); - _atomic_compare_exchange_resultSint4_ _e324; _e324.old_value = atomicCompSwap(_group_0_binding_2_cs.atomic_arr[1], 1, 2); + _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e324; _e324.old_value = atomicCompSwap(_group_0_binding_2_cs.atomic_arr[1], 1, 2); _e324.exchanged = (_e324.old_value == 1); - _atomic_compare_exchange_resultUint4_ _e328; _e328.old_value = atomicCompSwap(workgroup_atomic_scalar, 1u, 2u); + _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e328; _e328.old_value = atomicCompSwap(workgroup_atomic_scalar, 1u, 2u); _e328.exchanged = (_e328.old_value == 1u); - _atomic_compare_exchange_resultSint4_ _e333; _e333.old_value = atomicCompSwap(workgroup_atomic_arr[1], 1, 2); + _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e333; _e333.old_value = atomicCompSwap(workgroup_atomic_arr[1], 1, 2); _e333.exchanged = (_e333.old_value == 1); - _atomic_compare_exchange_resultUint4_ _e338; _e338.old_value = atomicCompSwap(workgroup_struct.atomic_scalar, 1u, 2u); + _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e338; _e338.old_value = atomicCompSwap(workgroup_struct.atomic_scalar, 1u, 2u); _e338.exchanged = (_e338.old_value == 1u); - _atomic_compare_exchange_resultSint4_ _e344; _e344.old_value = atomicCompSwap(workgroup_struct.atomic_arr[1], 1, 2); + _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e344; _e344.old_value = atomicCompSwap(workgroup_struct.atomic_arr[1], 1, 2); _e344.exchanged = (_e344.old_value == 1); return; } diff --git a/naga/tests/out/hlsl/spv-do-while.hlsl b/naga/tests/out/hlsl/spv-do-while.hlsl index 5724831de7b..cdd5273a6f3 100644 --- a/naga/tests/out/hlsl/spv-do-while.hlsl +++ b/naga/tests/out/hlsl/spv-do-while.hlsl @@ -1,4 +1,4 @@ -void fb1_(inout bool cond) +void f_u0028_b1_u003b(inout bool cond) { uint2 loop_bound = uint2(4294967295u, 4294967295u); bool loop_init = true; @@ -22,7 +22,7 @@ void main_1() bool param = (bool)0; param = false; - fb1_(param); + f_u0028_b1_u003b(param); return; } diff --git a/naga/tests/out/hlsl/spv-fetch_depth.hlsl b/naga/tests/out/hlsl/spv-fetch_depth.hlsl index 71788135f1a..909ac96ad3a 100644 --- a/naga/tests/out/hlsl/spv-fetch_depth.hlsl +++ b/naga/tests/out/hlsl/spv-fetch_depth.hlsl @@ -19,7 +19,7 @@ void function() } [numthreads(32, 1, 1)] -void cullfetch_depth() +void cull_u003a_u003a_fetch_depth() { function(); } diff --git a/naga/tests/out/hlsl/spv-fetch_depth.ron b/naga/tests/out/hlsl/spv-fetch_depth.ron index cb8a85c5f8c..2651131aa2c 100644 --- a/naga/tests/out/hlsl/spv-fetch_depth.ron +++ b/naga/tests/out/hlsl/spv-fetch_depth.ron @@ -5,7 +5,7 @@ ], compute:[ ( - entry_point:"cullfetch_depth", + entry_point:"cull_u003a_u003a_fetch_depth", target_profile:"cs_5_1", ), ], diff --git a/naga/tests/out/hlsl/wgsl-7995-unicode-idents.hlsl b/naga/tests/out/hlsl/wgsl-7995-unicode-idents.hlsl new file mode 100644 index 00000000000..3bc8261789f --- /dev/null +++ b/naga/tests/out/hlsl/wgsl-7995-unicode-idents.hlsl @@ -0,0 +1,15 @@ +ByteAddressBuffer asdf : register(t0); + +float compute() +{ + float _e1 = asfloat(asdf.Load(0)); + float u03b8_2_ = (_e1 + 9001.0); + return u03b8_2_; +} + +[numthreads(1, 1, 1)] +void main() +{ + const float _e0 = compute(); + return; +} diff --git a/naga/tests/out/hlsl/wgsl-7995-unicode-idents.ron b/naga/tests/out/hlsl/wgsl-7995-unicode-idents.ron new file mode 100644 index 00000000000..a07b03300b1 --- /dev/null +++ b/naga/tests/out/hlsl/wgsl-7995-unicode-idents.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ], + compute:[ + ( + entry_point:"main", + target_profile:"cs_5_1", + ), + ], +) diff --git a/naga/tests/out/hlsl/wgsl-atomicCompareExchange-int64.hlsl b/naga/tests/out/hlsl/wgsl-atomicCompareExchange-int64.hlsl index e0e4ca4021c..b9086e4a797 100644 --- a/naga/tests/out/hlsl/wgsl-atomicCompareExchange-int64.hlsl +++ b/naga/tests/out/hlsl/wgsl-atomicCompareExchange-int64.hlsl @@ -5,13 +5,13 @@ struct NagaConstants { }; ConstantBuffer _NagaConstants: register(b0, space1); -struct _atomic_compare_exchange_resultSint8_ { +struct _atomic_compare_exchange_result_u003c_Sint_u002c_8_u003e { int64_t old_value; bool exchanged; int _end_pad_0; }; -struct _atomic_compare_exchange_resultUint8_ { +struct _atomic_compare_exchange_result_u003c_Uint_u002c_8_u003e { uint64_t old_value; bool exchanged; int _end_pad_0; @@ -63,7 +63,7 @@ void test_atomic_compare_exchange_i64_() int64_t new_ = (_e14 + 10L); uint _e19 = i; int64_t _e21 = old; - _atomic_compare_exchange_resultSint8_ _e22; arr_i64_.InterlockedCompareExchange64(_e19*8, _e21, new_, _e22.old_value); + _atomic_compare_exchange_result_u003c_Sint_u002c_8_u003e _e22; arr_i64_.InterlockedCompareExchange64(_e19*8, _e21, new_, _e22.old_value); _e22.exchanged = (_e22.old_value == _e21); old = _e22.old_value; exchanged = _e22.exchanged; @@ -115,7 +115,7 @@ void test_atomic_compare_exchange_u64_() uint64_t new_1 = (_e14 + 10uL); uint _e19 = i_1; uint64_t _e21 = old_1; - _atomic_compare_exchange_resultUint8_ _e22; arr_u64_.InterlockedCompareExchange64(_e19*8, _e21, new_1, _e22.old_value); + _atomic_compare_exchange_result_u003c_Uint_u002c_8_u003e _e22; arr_u64_.InterlockedCompareExchange64(_e19*8, _e21, new_1, _e22.old_value); _e22.exchanged = (_e22.old_value == _e21); old_1 = _e22.old_value; exchanged_1 = _e22.exchanged; diff --git a/naga/tests/out/hlsl/wgsl-atomicCompareExchange.hlsl b/naga/tests/out/hlsl/wgsl-atomicCompareExchange.hlsl index d523f7a9d2f..907b8303731 100644 --- a/naga/tests/out/hlsl/wgsl-atomicCompareExchange.hlsl +++ b/naga/tests/out/hlsl/wgsl-atomicCompareExchange.hlsl @@ -1,9 +1,9 @@ -struct _atomic_compare_exchange_resultSint4_ { +struct _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e { int old_value; bool exchanged; }; -struct _atomic_compare_exchange_resultUint4_ { +struct _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e { uint old_value; bool exchanged; }; @@ -54,7 +54,7 @@ void test_atomic_compare_exchange_i32_() int new_ = asint((asfloat(_e14) + 1.0)); uint _e20 = i; int _e22 = old; - _atomic_compare_exchange_resultSint4_ _e23; arr_i32_.InterlockedCompareExchange(_e20*4, _e22, new_, _e23.old_value); + _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e23; arr_i32_.InterlockedCompareExchange(_e20*4, _e22, new_, _e23.old_value); _e23.exchanged = (_e23.old_value == _e22); old = _e23.old_value; exchanged = _e23.exchanged; @@ -106,7 +106,7 @@ void test_atomic_compare_exchange_u32_() uint new_1 = asuint((asfloat(_e14) + 1.0)); uint _e20 = i_1; uint _e22 = old_1; - _atomic_compare_exchange_resultUint4_ _e23; arr_u32_.InterlockedCompareExchange(_e20*4, _e22, new_1, _e23.old_value); + _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e23; arr_u32_.InterlockedCompareExchange(_e20*4, _e22, new_1, _e23.old_value); _e23.exchanged = (_e23.old_value == _e22); old_1 = _e23.old_value; exchanged_1 = _e23.exchanged; diff --git a/naga/tests/out/hlsl/wgsl-atomicOps-int64.hlsl b/naga/tests/out/hlsl/wgsl-atomicOps-int64.hlsl index 5c05b4ea9f5..93a806afdd9 100644 --- a/naga/tests/out/hlsl/wgsl-atomicOps-int64.hlsl +++ b/naga/tests/out/hlsl/wgsl-atomicOps-int64.hlsl @@ -10,13 +10,13 @@ struct Struct { int64_t atomic_arr[2]; }; -struct _atomic_compare_exchange_resultUint8_ { +struct _atomic_compare_exchange_result_u003c_Uint_u002c_8_u003e { uint64_t old_value; bool exchanged; int _end_pad_0; }; -struct _atomic_compare_exchange_resultSint8_ { +struct _atomic_compare_exchange_result_u003c_Sint_u002c_8_u003e { int64_t old_value; bool exchanged; int _end_pad_0; @@ -126,21 +126,21 @@ void cs_main(uint3 id : SV_GroupThreadID, uint3 __local_invocation_id : SV_Group int64_t _e279; InterlockedExchange(workgroup_atomic_arr[1], 1L, _e279); uint64_t _e283; InterlockedExchange(workgroup_struct.atomic_scalar, 1uL, _e283); int64_t _e288; InterlockedExchange(workgroup_struct.atomic_arr[1], 1L, _e288); - _atomic_compare_exchange_resultUint8_ _e292; storage_atomic_scalar.InterlockedCompareExchange64(0, 1uL, 2uL, _e292.old_value); + _atomic_compare_exchange_result_u003c_Uint_u002c_8_u003e _e292; storage_atomic_scalar.InterlockedCompareExchange64(0, 1uL, 2uL, _e292.old_value); _e292.exchanged = (_e292.old_value == 1uL); - _atomic_compare_exchange_resultSint8_ _e297; storage_atomic_arr.InterlockedCompareExchange64(8, 1L, 2L, _e297.old_value); + _atomic_compare_exchange_result_u003c_Sint_u002c_8_u003e _e297; storage_atomic_arr.InterlockedCompareExchange64(8, 1L, 2L, _e297.old_value); _e297.exchanged = (_e297.old_value == 1L); - _atomic_compare_exchange_resultUint8_ _e302; storage_struct.InterlockedCompareExchange64(0, 1uL, 2uL, _e302.old_value); + _atomic_compare_exchange_result_u003c_Uint_u002c_8_u003e _e302; storage_struct.InterlockedCompareExchange64(0, 1uL, 2uL, _e302.old_value); _e302.exchanged = (_e302.old_value == 1uL); - _atomic_compare_exchange_resultSint8_ _e308; storage_struct.InterlockedCompareExchange64(8+8, 1L, 2L, _e308.old_value); + _atomic_compare_exchange_result_u003c_Sint_u002c_8_u003e _e308; storage_struct.InterlockedCompareExchange64(8+8, 1L, 2L, _e308.old_value); _e308.exchanged = (_e308.old_value == 1L); - _atomic_compare_exchange_resultUint8_ _e312; InterlockedCompareExchange(workgroup_atomic_scalar, 1uL, 2uL, _e312.old_value); + _atomic_compare_exchange_result_u003c_Uint_u002c_8_u003e _e312; InterlockedCompareExchange(workgroup_atomic_scalar, 1uL, 2uL, _e312.old_value); _e312.exchanged = (_e312.old_value == 1uL); - _atomic_compare_exchange_resultSint8_ _e317; InterlockedCompareExchange(workgroup_atomic_arr[1], 1L, 2L, _e317.old_value); + _atomic_compare_exchange_result_u003c_Sint_u002c_8_u003e _e317; InterlockedCompareExchange(workgroup_atomic_arr[1], 1L, 2L, _e317.old_value); _e317.exchanged = (_e317.old_value == 1L); - _atomic_compare_exchange_resultUint8_ _e322; InterlockedCompareExchange(workgroup_struct.atomic_scalar, 1uL, 2uL, _e322.old_value); + _atomic_compare_exchange_result_u003c_Uint_u002c_8_u003e _e322; InterlockedCompareExchange(workgroup_struct.atomic_scalar, 1uL, 2uL, _e322.old_value); _e322.exchanged = (_e322.old_value == 1uL); - _atomic_compare_exchange_resultSint8_ _e328; InterlockedCompareExchange(workgroup_struct.atomic_arr[1], 1L, 2L, _e328.old_value); + _atomic_compare_exchange_result_u003c_Sint_u002c_8_u003e _e328; InterlockedCompareExchange(workgroup_struct.atomic_arr[1], 1L, 2L, _e328.old_value); _e328.exchanged = (_e328.old_value == 1L); return; } diff --git a/naga/tests/out/hlsl/wgsl-atomicOps.hlsl b/naga/tests/out/hlsl/wgsl-atomicOps.hlsl index 5771c898d94..47b586d7dba 100644 --- a/naga/tests/out/hlsl/wgsl-atomicOps.hlsl +++ b/naga/tests/out/hlsl/wgsl-atomicOps.hlsl @@ -3,12 +3,12 @@ struct Struct { int atomic_arr[2]; }; -struct _atomic_compare_exchange_resultUint4_ { +struct _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e { uint old_value; bool exchanged; }; -struct _atomic_compare_exchange_resultSint4_ { +struct _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e { int old_value; bool exchanged; }; @@ -117,21 +117,21 @@ void cs_main(uint3 id : SV_GroupThreadID, uint3 __local_invocation_id : SV_Group int _e295; InterlockedExchange(workgroup_atomic_arr[1], int(1), _e295); uint _e299; InterlockedExchange(workgroup_struct.atomic_scalar, 1u, _e299); int _e304; InterlockedExchange(workgroup_struct.atomic_arr[1], int(1), _e304); - _atomic_compare_exchange_resultUint4_ _e308; storage_atomic_scalar.InterlockedCompareExchange(0, 1u, 2u, _e308.old_value); + _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e308; storage_atomic_scalar.InterlockedCompareExchange(0, 1u, 2u, _e308.old_value); _e308.exchanged = (_e308.old_value == 1u); - _atomic_compare_exchange_resultSint4_ _e313; storage_atomic_arr.InterlockedCompareExchange(4, int(1), int(2), _e313.old_value); + _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e313; storage_atomic_arr.InterlockedCompareExchange(4, int(1), int(2), _e313.old_value); _e313.exchanged = (_e313.old_value == int(1)); - _atomic_compare_exchange_resultUint4_ _e318; storage_struct.InterlockedCompareExchange(0, 1u, 2u, _e318.old_value); + _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e318; storage_struct.InterlockedCompareExchange(0, 1u, 2u, _e318.old_value); _e318.exchanged = (_e318.old_value == 1u); - _atomic_compare_exchange_resultSint4_ _e324; storage_struct.InterlockedCompareExchange(4+4, int(1), int(2), _e324.old_value); + _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e324; storage_struct.InterlockedCompareExchange(4+4, int(1), int(2), _e324.old_value); _e324.exchanged = (_e324.old_value == int(1)); - _atomic_compare_exchange_resultUint4_ _e328; InterlockedCompareExchange(workgroup_atomic_scalar, 1u, 2u, _e328.old_value); + _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e328; InterlockedCompareExchange(workgroup_atomic_scalar, 1u, 2u, _e328.old_value); _e328.exchanged = (_e328.old_value == 1u); - _atomic_compare_exchange_resultSint4_ _e333; InterlockedCompareExchange(workgroup_atomic_arr[1], int(1), int(2), _e333.old_value); + _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e333; InterlockedCompareExchange(workgroup_atomic_arr[1], int(1), int(2), _e333.old_value); _e333.exchanged = (_e333.old_value == int(1)); - _atomic_compare_exchange_resultUint4_ _e338; InterlockedCompareExchange(workgroup_struct.atomic_scalar, 1u, 2u, _e338.old_value); + _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e338; InterlockedCompareExchange(workgroup_struct.atomic_scalar, 1u, 2u, _e338.old_value); _e338.exchanged = (_e338.old_value == 1u); - _atomic_compare_exchange_resultSint4_ _e344; InterlockedCompareExchange(workgroup_struct.atomic_arr[1], int(1), int(2), _e344.old_value); + _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e344; InterlockedCompareExchange(workgroup_struct.atomic_arr[1], int(1), int(2), _e344.old_value); _e344.exchanged = (_e344.old_value == int(1)); return; } diff --git a/naga/tests/out/msl/spv-do-while.msl b/naga/tests/out/msl/spv-do-while.msl index 7e5d111b505..d58be5ef508 100644 --- a/naga/tests/out/msl/spv-do-while.msl +++ b/naga/tests/out/msl/spv-do-while.msl @@ -5,7 +5,7 @@ using metal::uint; -void fb1_( +void f_u0028_b1_u003b( thread bool& cond ) { uint2 loop_bound = uint2(4294967295u); @@ -29,7 +29,7 @@ void main_1( ) { bool param = {}; param = false; - fb1_(param); + f_u0028_b1_u003b(param); return; } diff --git a/naga/tests/out/msl/spv-fetch_depth.msl b/naga/tests/out/msl/spv-fetch_depth.msl index 867a284372c..642cf305a5c 100644 --- a/naga/tests/out/msl/spv-fetch_depth.msl +++ b/naga/tests/out/msl/spv-fetch_depth.msl @@ -22,7 +22,7 @@ void function( return; } -kernel void cullfetch_depth( +kernel void cull_u003a_u003a_fetch_depth( device type_2& global [[user(fake0)]] , device type_4 const& global_1 [[user(fake0)]] , metal::depth2d global_2 [[user(fake0)]] diff --git a/naga/tests/out/msl/wgsl-7995-unicode-idents.msl b/naga/tests/out/msl/wgsl-7995-unicode-idents.msl new file mode 100644 index 00000000000..9f912706d1c --- /dev/null +++ b/naga/tests/out/msl/wgsl-7995-unicode-idents.msl @@ -0,0 +1,21 @@ +// language: metal1.0 +#include +#include + +using metal::uint; + + +float compute( + device float const& asdf +) { + float _e1 = asdf; + float u03b8_2_ = _e1 + 9001.0; + return u03b8_2_; +} + +kernel void main_( + device float const& asdf [[user(fake0)]] +) { + float _e0 = compute(asdf); + return; +} diff --git a/naga/tests/out/msl/wgsl-atomicCompareExchange.msl b/naga/tests/out/msl/wgsl-atomicCompareExchange.msl index 72c418b9ed3..3c372b55e63 100644 --- a/naga/tests/out/msl/wgsl-atomicCompareExchange.msl +++ b/naga/tests/out/msl/wgsl-atomicCompareExchange.msl @@ -10,19 +10,19 @@ struct type_2 { struct type_4 { metal::atomic_uint inner[128]; }; -struct _atomic_compare_exchange_resultSint4_ { +struct _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e { int old_value; bool exchanged; char _pad2[3]; }; -struct _atomic_compare_exchange_resultUint4_ { +struct _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e { uint old_value; bool exchanged; char _pad2[3]; }; template -_atomic_compare_exchange_resultSint4_ naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( device A *atomic_ptr, int cmp, int v @@ -31,10 +31,10 @@ _atomic_compare_exchange_resultSint4_ naga_atomic_compare_exchange_weak_explicit atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_resultSint4_{cmp, swapped}; + return _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e{cmp, swapped}; } template -_atomic_compare_exchange_resultSint4_ naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( threadgroup A *atomic_ptr, int cmp, int v @@ -43,11 +43,11 @@ _atomic_compare_exchange_resultSint4_ naga_atomic_compare_exchange_weak_explicit atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_resultSint4_{cmp, swapped}; + return _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e{cmp, swapped}; } template -_atomic_compare_exchange_resultUint4_ naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( device A *atomic_ptr, uint cmp, uint v @@ -56,10 +56,10 @@ _atomic_compare_exchange_resultUint4_ naga_atomic_compare_exchange_weak_explicit atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_resultUint4_{cmp, swapped}; + return _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e{cmp, swapped}; } template -_atomic_compare_exchange_resultUint4_ naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( threadgroup A *atomic_ptr, uint cmp, uint v @@ -68,7 +68,7 @@ _atomic_compare_exchange_resultUint4_ naga_atomic_compare_exchange_weak_explicit atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_resultUint4_{cmp, swapped}; + return _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e{cmp, swapped}; } constant uint SIZE = 128u; @@ -112,7 +112,7 @@ kernel void test_atomic_compare_exchange_i32_( int new_ = as_type(as_type(_e14) + 1.0); uint _e20 = i; int _e22 = old; - _atomic_compare_exchange_resultSint4_ _e23 = naga_atomic_compare_exchange_weak_explicit(&arr_i32_.inner[_e20], _e22, new_); + _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e23 = naga_atomic_compare_exchange_weak_explicit(&arr_i32_.inner[_e20], _e22, new_); old = _e23.old_value; exchanged = _e23.exchanged; } @@ -163,7 +163,7 @@ kernel void test_atomic_compare_exchange_u32_( uint new_1 = as_type(as_type(_e14) + 1.0); uint _e20 = i_1; uint _e22 = old_1; - _atomic_compare_exchange_resultUint4_ _e23 = naga_atomic_compare_exchange_weak_explicit(&arr_u32_.inner[_e20], _e22, new_1); + _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e23 = naga_atomic_compare_exchange_weak_explicit(&arr_u32_.inner[_e20], _e22, new_1); old_1 = _e23.old_value; exchanged_1 = _e23.exchanged; } diff --git a/naga/tests/out/msl/wgsl-atomicOps.msl b/naga/tests/out/msl/wgsl-atomicOps.msl index 63cab2a80f5..8266c1bd764 100644 --- a/naga/tests/out/msl/wgsl-atomicOps.msl +++ b/naga/tests/out/msl/wgsl-atomicOps.msl @@ -11,19 +11,19 @@ struct Struct { metal::atomic_uint atomic_scalar; type_2 atomic_arr; }; -struct _atomic_compare_exchange_resultUint4_ { +struct _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e { uint old_value; bool exchanged; char _pad2[3]; }; -struct _atomic_compare_exchange_resultSint4_ { +struct _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e { int old_value; bool exchanged; char _pad2[3]; }; template -_atomic_compare_exchange_resultUint4_ naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( device A *atomic_ptr, uint cmp, uint v @@ -32,10 +32,10 @@ _atomic_compare_exchange_resultUint4_ naga_atomic_compare_exchange_weak_explicit atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_resultUint4_{cmp, swapped}; + return _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e{cmp, swapped}; } template -_atomic_compare_exchange_resultUint4_ naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( threadgroup A *atomic_ptr, uint cmp, uint v @@ -44,11 +44,11 @@ _atomic_compare_exchange_resultUint4_ naga_atomic_compare_exchange_weak_explicit atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_resultUint4_{cmp, swapped}; + return _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e{cmp, swapped}; } template -_atomic_compare_exchange_resultSint4_ naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( device A *atomic_ptr, int cmp, int v @@ -57,10 +57,10 @@ _atomic_compare_exchange_resultSint4_ naga_atomic_compare_exchange_weak_explicit atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_resultSint4_{cmp, swapped}; + return _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e{cmp, swapped}; } template -_atomic_compare_exchange_resultSint4_ naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( threadgroup A *atomic_ptr, int cmp, int v @@ -69,7 +69,7 @@ _atomic_compare_exchange_resultSint4_ naga_atomic_compare_exchange_weak_explicit atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_resultSint4_{cmp, swapped}; + return _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e{cmp, swapped}; } struct cs_mainInput { @@ -182,13 +182,13 @@ kernel void cs_main( int _e295 = metal::atomic_exchange_explicit(&workgroup_atomic_arr.inner[1], 1, metal::memory_order_relaxed); uint _e299 = metal::atomic_exchange_explicit(&workgroup_struct.atomic_scalar, 1u, metal::memory_order_relaxed); int _e304 = metal::atomic_exchange_explicit(&workgroup_struct.atomic_arr.inner[1], 1, metal::memory_order_relaxed); - _atomic_compare_exchange_resultUint4_ _e308 = naga_atomic_compare_exchange_weak_explicit(&storage_atomic_scalar, 1u, 2u); - _atomic_compare_exchange_resultSint4_ _e313 = naga_atomic_compare_exchange_weak_explicit(&storage_atomic_arr.inner[1], 1, 2); - _atomic_compare_exchange_resultUint4_ _e318 = naga_atomic_compare_exchange_weak_explicit(&storage_struct.atomic_scalar, 1u, 2u); - _atomic_compare_exchange_resultSint4_ _e324 = naga_atomic_compare_exchange_weak_explicit(&storage_struct.atomic_arr.inner[1], 1, 2); - _atomic_compare_exchange_resultUint4_ _e328 = naga_atomic_compare_exchange_weak_explicit(&workgroup_atomic_scalar, 1u, 2u); - _atomic_compare_exchange_resultSint4_ _e333 = naga_atomic_compare_exchange_weak_explicit(&workgroup_atomic_arr.inner[1], 1, 2); - _atomic_compare_exchange_resultUint4_ _e338 = naga_atomic_compare_exchange_weak_explicit(&workgroup_struct.atomic_scalar, 1u, 2u); - _atomic_compare_exchange_resultSint4_ _e344 = naga_atomic_compare_exchange_weak_explicit(&workgroup_struct.atomic_arr.inner[1], 1, 2); + _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e308 = naga_atomic_compare_exchange_weak_explicit(&storage_atomic_scalar, 1u, 2u); + _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e313 = naga_atomic_compare_exchange_weak_explicit(&storage_atomic_arr.inner[1], 1, 2); + _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e318 = naga_atomic_compare_exchange_weak_explicit(&storage_struct.atomic_scalar, 1u, 2u); + _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e324 = naga_atomic_compare_exchange_weak_explicit(&storage_struct.atomic_arr.inner[1], 1, 2); + _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e328 = naga_atomic_compare_exchange_weak_explicit(&workgroup_atomic_scalar, 1u, 2u); + _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e333 = naga_atomic_compare_exchange_weak_explicit(&workgroup_atomic_arr.inner[1], 1, 2); + _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e338 = naga_atomic_compare_exchange_weak_explicit(&workgroup_struct.atomic_scalar, 1u, 2u); + _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e344 = naga_atomic_compare_exchange_weak_explicit(&workgroup_struct.atomic_arr.inner[1], 1, 2); return; } diff --git a/naga/tests/out/msl/wgsl-overrides-atomicCompareExchangeWeak.msl b/naga/tests/out/msl/wgsl-overrides-atomicCompareExchangeWeak.msl index 48f09ee6de2..a15984d9c16 100644 --- a/naga/tests/out/msl/wgsl-overrides-atomicCompareExchangeWeak.msl +++ b/naga/tests/out/msl/wgsl-overrides-atomicCompareExchangeWeak.msl @@ -4,14 +4,14 @@ using metal::uint; -struct _atomic_compare_exchange_resultUint4_ { +struct _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e { uint old_value; bool exchanged; char _pad2[3]; }; template -_atomic_compare_exchange_resultUint4_ naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( device A *atomic_ptr, uint cmp, uint v @@ -20,10 +20,10 @@ _atomic_compare_exchange_resultUint4_ naga_atomic_compare_exchange_weak_explicit atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_resultUint4_{cmp, swapped}; + return _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e{cmp, swapped}; } template -_atomic_compare_exchange_resultUint4_ naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( threadgroup A *atomic_ptr, uint cmp, uint v @@ -32,7 +32,7 @@ _atomic_compare_exchange_resultUint4_ naga_atomic_compare_exchange_weak_explicit atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_resultUint4_{cmp, swapped}; + return _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e{cmp, swapped}; } constant int o = 2; @@ -44,6 +44,6 @@ kernel void f( metal::atomic_store_explicit(&a, 0, metal::memory_order_relaxed); } metal::threadgroup_barrier(metal::mem_flags::mem_threadgroup); - _atomic_compare_exchange_resultUint4_ _e5 = naga_atomic_compare_exchange_weak_explicit(&a, 2u, 1u); + _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e5 = naga_atomic_compare_exchange_weak_explicit(&a, 2u, 1u); return; } diff --git a/naga/tests/out/spv/wgsl-7995-unicode-idents.spvasm b/naga/tests/out/spv/wgsl-7995-unicode-idents.spvasm new file mode 100644 index 00000000000..a051e436ab5 --- /dev/null +++ b/naga/tests/out/spv/wgsl-7995-unicode-idents.spvasm @@ -0,0 +1,43 @@ +; SPIR-V +; Version: 1.1 +; Generator: rspirv +; Bound: 24 +OpCapability Shader +OpExtension "SPV_KHR_storage_buffer_storage_class" +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %19 "main" +OpExecutionMode %19 LocalSize 1 1 1 +OpDecorate %4 NonWritable +OpDecorate %4 DescriptorSet 0 +OpDecorate %4 Binding 0 +OpDecorate %5 Block +OpMemberDecorate %5 0 Offset 0 +%2 = OpTypeVoid +%3 = OpTypeFloat 32 +%5 = OpTypeStruct %3 +%6 = OpTypePointer StorageBuffer %5 +%4 = OpVariable %6 StorageBuffer +%9 = OpTypeFunction %3 +%10 = OpTypePointer StorageBuffer %3 +%12 = OpTypeInt 32 0 +%11 = OpConstant %12 0 +%14 = OpConstant %3 9001 +%20 = OpTypeFunction %2 +%8 = OpFunction %3 None %9 +%7 = OpLabel +%13 = OpAccessChain %10 %4 %11 +OpBranch %15 +%15 = OpLabel +%16 = OpLoad %3 %13 +%17 = OpFAdd %3 %16 %14 +OpReturnValue %17 +OpFunctionEnd +%19 = OpFunction %2 None %20 +%18 = OpLabel +%21 = OpAccessChain %10 %4 %11 +OpBranch %22 +%22 = OpLabel +%23 = OpFunctionCall %3 %8 +OpReturn +OpFunctionEnd \ No newline at end of file diff --git a/naga/tests/out/wgsl/spv-atomic_compare_exchange.wgsl b/naga/tests/out/wgsl/spv-atomic_compare_exchange.wgsl index 21456b064c9..88476c5057d 100644 --- a/naga/tests/out/wgsl/spv-atomic_compare_exchange.wgsl +++ b/naga/tests/out/wgsl/spv-atomic_compare_exchange.wgsl @@ -61,6 +61,6 @@ fn function() { } @compute @workgroup_size(32, 1, 1) -fn stagetest_atomic_compare_exchange() { +fn stage_u003a_u003a_test_atomic_compare_exchange() { function(); } diff --git a/naga/tests/out/wgsl/spv-atomic_exchange.wgsl b/naga/tests/out/wgsl/spv-atomic_exchange.wgsl index f954a850795..e17ac9e5879 100644 --- a/naga/tests/out/wgsl/spv-atomic_exchange.wgsl +++ b/naga/tests/out/wgsl/spv-atomic_exchange.wgsl @@ -75,6 +75,6 @@ fn function() { } @compute @workgroup_size(32, 1, 1) -fn stagetest_atomic_exchange() { +fn stage_u003a_u003a_test_atomic_exchange() { function(); } diff --git a/naga/tests/out/wgsl/spv-atomic_i_add_sub.wgsl b/naga/tests/out/wgsl/spv-atomic_i_add_sub.wgsl index d7798bd411d..b783267ad37 100644 --- a/naga/tests/out/wgsl/spv-atomic_i_add_sub.wgsl +++ b/naga/tests/out/wgsl/spv-atomic_i_add_sub.wgsl @@ -21,6 +21,6 @@ fn function() { } @compute @workgroup_size(32, 1, 1) -fn stagetest_atomic_i_add_sub() { +fn stage_u003a_u003a_test_atomic_i_add_sub() { function(); } diff --git a/naga/tests/out/wgsl/spv-atomic_i_decrement.wgsl b/naga/tests/out/wgsl/spv-atomic_i_decrement.wgsl index 190256e1c97..e0bf0a2488a 100644 --- a/naga/tests/out/wgsl/spv-atomic_i_decrement.wgsl +++ b/naga/tests/out/wgsl/spv-atomic_i_decrement.wgsl @@ -32,6 +32,6 @@ fn function() { } @compute @workgroup_size(32, 1, 1) -fn stagetest_atomic_i_decrement() { +fn stage_u003a_u003a_test_atomic_i_decrement() { function(); } diff --git a/naga/tests/out/wgsl/spv-atomic_i_increment.wgsl b/naga/tests/out/wgsl/spv-atomic_i_increment.wgsl index f7282aa3e64..830bf98d971 100644 --- a/naga/tests/out/wgsl/spv-atomic_i_increment.wgsl +++ b/naga/tests/out/wgsl/spv-atomic_i_increment.wgsl @@ -37,6 +37,6 @@ fn function() { } @compute @workgroup_size(32, 1, 1) -fn stagetest_atomic_i_increment() { +fn stage_u003a_u003a_test_atomic_i_increment() { function(); } diff --git a/naga/tests/out/wgsl/spv-atomic_load_and_store.wgsl b/naga/tests/out/wgsl/spv-atomic_load_and_store.wgsl index 9bfaa4ef55e..d33f92171f8 100644 --- a/naga/tests/out/wgsl/spv-atomic_load_and_store.wgsl +++ b/naga/tests/out/wgsl/spv-atomic_load_and_store.wgsl @@ -67,6 +67,6 @@ fn function() { } @compute @workgroup_size(32, 1, 1) -fn stagetest_atomic_load_and_store() { +fn stage_u003a_u003a_test_atomic_load_and_store() { function(); } diff --git a/naga/tests/out/wgsl/spv-binding-arrays.runtime.wgsl b/naga/tests/out/wgsl/spv-binding-arrays.runtime.wgsl index d3d1ebd0fff..72b8244c573 100644 --- a/naga/tests/out/wgsl/spv-binding-arrays.runtime.wgsl +++ b/naga/tests/out/wgsl/spv-binding-arrays.runtime.wgsl @@ -1,5 +1,5 @@ -var inputtexture_coordinates_1: vec2; -var inputtexture_index_1: u32; +var input_u002e_texture_coordinates_1: vec2; +var input_u002e_texture_index_1: u32; @group(0) @binding(0) var textures: binding_array>; @group(0) @binding(1) @@ -7,17 +7,17 @@ var linear_sampler: sampler; var entryPointParam_main: vec4; fn main_1() { - let _e5 = inputtexture_coordinates_1; - let _e6 = inputtexture_index_1; + let _e5 = input_u002e_texture_coordinates_1; + let _e6 = input_u002e_texture_index_1; let _e8 = textureSample(textures[_e6], linear_sampler, _e5); entryPointParam_main = _e8; return; } @fragment -fn main(@location(0) inputtexture_coordinates: vec2, @location(1) @interpolate(flat) inputtexture_index: u32) -> @location(0) vec4 { - inputtexture_coordinates_1 = inputtexture_coordinates; - inputtexture_index_1 = inputtexture_index; +fn main(@location(0) input_u002e_texture_coordinates: vec2, @location(1) @interpolate(flat) input_u002e_texture_index: u32) -> @location(0) vec4 { + input_u002e_texture_coordinates_1 = input_u002e_texture_coordinates; + input_u002e_texture_index_1 = input_u002e_texture_index; main_1(); let _e5 = entryPointParam_main; return _e5; diff --git a/naga/tests/out/wgsl/spv-builtin-accessed-outside-entrypoint.wgsl b/naga/tests/out/wgsl/spv-builtin-accessed-outside-entrypoint.wgsl index 8e1b885bf72..2941b766365 100644 --- a/naga/tests/out/wgsl/spv-builtin-accessed-outside-entrypoint.wgsl +++ b/naga/tests/out/wgsl/spv-builtin-accessed-outside-entrypoint.wgsl @@ -8,7 +8,7 @@ struct gl_PerVertex { var unnamed: gl_PerVertex = gl_PerVertex(vec4(0f, 0f, 0f, 1f), 1f, array(), array()); var gl_VertexIndex_1: i32; -fn builtin_usage() { +fn builtin_usage_u0028_() { let _e9 = gl_VertexIndex_1; let _e12 = gl_VertexIndex_1; unnamed.gl_Position = vec4(select(1f, -4f, (_e9 == 0i)), select(-1f, 4f, (_e12 == 2i)), 0f, 1f); @@ -16,7 +16,7 @@ fn builtin_usage() { } fn main_1() { - builtin_usage(); + builtin_usage_u0028_(); return; } diff --git a/naga/tests/out/wgsl/spv-do-while.wgsl b/naga/tests/out/wgsl/spv-do-while.wgsl index 0b7e3afbcce..3a6d43d95dc 100644 --- a/naga/tests/out/wgsl/spv-do-while.wgsl +++ b/naga/tests/out/wgsl/spv-do-while.wgsl @@ -1,4 +1,4 @@ -fn fb1_(cond: ptr) { +fn f_u0028_b1_u003b(cond: ptr) { loop { continue; continuing { @@ -13,7 +13,7 @@ fn main_1() { var param: bool; param = false; - fb1_((¶m)); + f_u0028_b1_u003b((¶m)); return; } diff --git a/naga/tests/out/wgsl/spv-fetch_depth.wgsl b/naga/tests/out/wgsl/spv-fetch_depth.wgsl index 3e206bc2676..d6a7d5173e8 100644 --- a/naga/tests/out/wgsl/spv-fetch_depth.wgsl +++ b/naga/tests/out/wgsl/spv-fetch_depth.wgsl @@ -21,6 +21,6 @@ fn function() { } @compute @workgroup_size(32, 1, 1) -fn cullfetch_depth() { +fn cull_u003a_u003a_fetch_depth() { function(); } diff --git a/naga/tests/out/wgsl/spv-gather-cmp.wgsl b/naga/tests/out/wgsl/spv-gather-cmp.wgsl index 3a12edddb09..2685fa003f8 100644 --- a/naga/tests/out/wgsl/spv-gather-cmp.wgsl +++ b/naga/tests/out/wgsl/spv-gather-cmp.wgsl @@ -1,4 +1,4 @@ -var inputtexture_coordinates_1: vec2; +var input_u002e_texture_coordinates_1: vec2; @group(0) @binding(0) var texture: texture_depth_2d; @group(0) @binding(1) @@ -6,15 +6,15 @@ var depth_sampler: sampler_comparison; var entryPointParam_main: vec4; fn main_1() { - let _e5 = inputtexture_coordinates_1; + let _e5 = input_u002e_texture_coordinates_1; let _e6 = textureGatherCompare(texture, depth_sampler, _e5, 0.5f); entryPointParam_main = _e6; return; } @fragment -fn main(@location(0) inputtexture_coordinates: vec2) -> @location(0) vec4 { - inputtexture_coordinates_1 = inputtexture_coordinates; +fn main(@location(0) input_u002e_texture_coordinates: vec2) -> @location(0) vec4 { + input_u002e_texture_coordinates_1 = input_u002e_texture_coordinates; main_1(); let _e3 = entryPointParam_main; return _e3; diff --git a/naga/tests/out/wgsl/spv-gather.wgsl b/naga/tests/out/wgsl/spv-gather.wgsl index 5a92fdbff8a..a35708b89c7 100644 --- a/naga/tests/out/wgsl/spv-gather.wgsl +++ b/naga/tests/out/wgsl/spv-gather.wgsl @@ -1,4 +1,4 @@ -var inputtexture_coordinates_1: vec2; +var input_u002e_texture_coordinates_1: vec2; @group(0) @binding(0) var texture: texture_2d; @group(0) @binding(1) @@ -6,15 +6,15 @@ var linear_sampler: sampler; var entryPointParam_main: vec4; fn main_1() { - let _e4 = inputtexture_coordinates_1; + let _e4 = input_u002e_texture_coordinates_1; let _e5 = textureGather(1, texture, linear_sampler, _e4); entryPointParam_main = _e5; return; } @fragment -fn main(@location(0) inputtexture_coordinates: vec2) -> @location(0) vec4 { - inputtexture_coordinates_1 = inputtexture_coordinates; +fn main(@location(0) input_u002e_texture_coordinates: vec2) -> @location(0) vec4 { + input_u002e_texture_coordinates_1 = input_u002e_texture_coordinates; main_1(); let _e3 = entryPointParam_main; return _e3; diff --git a/naga/tests/out/wgsl/wgsl-7995-unicode-idents.wgsl b/naga/tests/out/wgsl/wgsl-7995-unicode-idents.wgsl new file mode 100644 index 00000000000..9a93d697454 --- /dev/null +++ b/naga/tests/out/wgsl/wgsl-7995-unicode-idents.wgsl @@ -0,0 +1,14 @@ +@group(0) @binding(0) +var asdf: f32; + +fn compute() -> f32 { + let _e1 = asdf; + let u03b8_2_ = (_e1 + 9001f); + return u03b8_2_; +} + +@compute @workgroup_size(1, 1, 1) +fn main() { + let _e0 = compute(); + return; +} From 5146b3f8ae29465f28eec7bc918e4eb6f2cc2f2f Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Fri, 25 Jul 2025 17:23:42 -0400 Subject: [PATCH 270/303] fix(namer): normalize ":<>," characters to a snake case separator --- naga/src/proc/namer.rs | 6 ++++ ...t_atomic_compare_exchange_i32.Compute.glsl | 6 ++-- ...t_atomic_compare_exchange_u32.Compute.glsl | 6 ++-- .../glsl/wgsl-atomicOps.cs_main.Compute.glsl | 20 +++++------ naga/tests/out/hlsl/spv-fetch_depth.hlsl | 2 +- naga/tests/out/hlsl/spv-fetch_depth.ron | 2 +- .../wgsl-atomicCompareExchange-int64.hlsl | 8 ++--- .../out/hlsl/wgsl-atomicCompareExchange.hlsl | 8 ++--- naga/tests/out/hlsl/wgsl-atomicOps-int64.hlsl | 20 +++++------ naga/tests/out/hlsl/wgsl-atomicOps.hlsl | 20 +++++------ naga/tests/out/msl/spv-fetch_depth.msl | 2 +- .../out/msl/wgsl-atomicCompareExchange.msl | 24 ++++++------- naga/tests/out/msl/wgsl-atomicOps.msl | 36 +++++++++---------- ...sl-overrides-atomicCompareExchangeWeak.msl | 12 +++---- .../out/wgsl/spv-atomic_compare_exchange.wgsl | 2 +- naga/tests/out/wgsl/spv-atomic_exchange.wgsl | 2 +- naga/tests/out/wgsl/spv-atomic_i_add_sub.wgsl | 2 +- .../out/wgsl/spv-atomic_i_decrement.wgsl | 2 +- .../out/wgsl/spv-atomic_i_increment.wgsl | 2 +- .../out/wgsl/spv-atomic_load_and_store.wgsl | 2 +- naga/tests/out/wgsl/spv-fetch_depth.wgsl | 2 +- 21 files changed, 96 insertions(+), 90 deletions(-) diff --git a/naga/src/proc/namer.rs b/naga/src/proc/namer.rs index 71c00a4cdaf..127e346f3a1 100644 --- a/naga/src/proc/namer.rs +++ b/naga/src/proc/namer.rs @@ -119,6 +119,12 @@ impl Namer { Cow::Borrowed(string) } else { let mut filtered = string.chars().fold(String::new(), |mut s, c| { + let c = match c { + // Make several common characters in C++-ish types become snake case + // separators. + ':' | '<' | '>' | ',' => '_', + c => c, + }; let had_underscore_at_end = s.ends_with('_'); if had_underscore_at_end && c == '_' { return s; diff --git a/naga/tests/out/glsl/wgsl-atomicCompareExchange.test_atomic_compare_exchange_i32.Compute.glsl b/naga/tests/out/glsl/wgsl-atomicCompareExchange.test_atomic_compare_exchange_i32.Compute.glsl index af3f9a13c99..b45d8299f2d 100644 --- a/naga/tests/out/glsl/wgsl-atomicCompareExchange.test_atomic_compare_exchange_i32.Compute.glsl +++ b/naga/tests/out/glsl/wgsl-atomicCompareExchange.test_atomic_compare_exchange_i32.Compute.glsl @@ -5,11 +5,11 @@ precision highp int; layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; -struct _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e { +struct _atomic_compare_exchange_result_Sint_4_ { int old_value; bool exchanged; }; -struct _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e { +struct _atomic_compare_exchange_result_Uint_4_ { uint old_value; bool exchanged; }; @@ -50,7 +50,7 @@ void main() { int new = floatBitsToInt((intBitsToFloat(_e14) + 1.0)); uint _e20 = i; int _e22 = old; - _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e23; _e23.old_value = atomicCompSwap(_group_0_binding_0_cs[_e20], _e22, new); + _atomic_compare_exchange_result_Sint_4_ _e23; _e23.old_value = atomicCompSwap(_group_0_binding_0_cs[_e20], _e22, new); _e23.exchanged = (_e23.old_value == _e22); old = _e23.old_value; exchanged = _e23.exchanged; diff --git a/naga/tests/out/glsl/wgsl-atomicCompareExchange.test_atomic_compare_exchange_u32.Compute.glsl b/naga/tests/out/glsl/wgsl-atomicCompareExchange.test_atomic_compare_exchange_u32.Compute.glsl index bd32bb95781..171b9a869fb 100644 --- a/naga/tests/out/glsl/wgsl-atomicCompareExchange.test_atomic_compare_exchange_u32.Compute.glsl +++ b/naga/tests/out/glsl/wgsl-atomicCompareExchange.test_atomic_compare_exchange_u32.Compute.glsl @@ -5,11 +5,11 @@ precision highp int; layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; -struct _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e { +struct _atomic_compare_exchange_result_Sint_4_ { int old_value; bool exchanged; }; -struct _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e { +struct _atomic_compare_exchange_result_Uint_4_ { uint old_value; bool exchanged; }; @@ -50,7 +50,7 @@ void main() { uint new = floatBitsToUint((uintBitsToFloat(_e14) + 1.0)); uint _e20 = i_1; uint _e22 = old_1; - _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e23; _e23.old_value = atomicCompSwap(_group_0_binding_1_cs[_e20], _e22, new); + _atomic_compare_exchange_result_Uint_4_ _e23; _e23.old_value = atomicCompSwap(_group_0_binding_1_cs[_e20], _e22, new); _e23.exchanged = (_e23.old_value == _e22); old_1 = _e23.old_value; exchanged_1 = _e23.exchanged; diff --git a/naga/tests/out/glsl/wgsl-atomicOps.cs_main.Compute.glsl b/naga/tests/out/glsl/wgsl-atomicOps.cs_main.Compute.glsl index 5713a76340f..104f671218d 100644 --- a/naga/tests/out/glsl/wgsl-atomicOps.cs_main.Compute.glsl +++ b/naga/tests/out/glsl/wgsl-atomicOps.cs_main.Compute.glsl @@ -9,11 +9,11 @@ struct Struct { uint atomic_scalar; int atomic_arr[2]; }; -struct _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e { +struct _atomic_compare_exchange_result_Uint_4_ { uint old_value; bool exchanged; }; -struct _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e { +struct _atomic_compare_exchange_result_Sint_4_ { int old_value; bool exchanged; }; @@ -135,21 +135,21 @@ void main() { int _e295 = atomicExchange(workgroup_atomic_arr[1], 1); uint _e299 = atomicExchange(workgroup_struct.atomic_scalar, 1u); int _e304 = atomicExchange(workgroup_struct.atomic_arr[1], 1); - _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e308; _e308.old_value = atomicCompSwap(_group_0_binding_0_cs, 1u, 2u); + _atomic_compare_exchange_result_Uint_4_ _e308; _e308.old_value = atomicCompSwap(_group_0_binding_0_cs, 1u, 2u); _e308.exchanged = (_e308.old_value == 1u); - _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e313; _e313.old_value = atomicCompSwap(_group_0_binding_1_cs[1], 1, 2); + _atomic_compare_exchange_result_Sint_4_ _e313; _e313.old_value = atomicCompSwap(_group_0_binding_1_cs[1], 1, 2); _e313.exchanged = (_e313.old_value == 1); - _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e318; _e318.old_value = atomicCompSwap(_group_0_binding_2_cs.atomic_scalar, 1u, 2u); + _atomic_compare_exchange_result_Uint_4_ _e318; _e318.old_value = atomicCompSwap(_group_0_binding_2_cs.atomic_scalar, 1u, 2u); _e318.exchanged = (_e318.old_value == 1u); - _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e324; _e324.old_value = atomicCompSwap(_group_0_binding_2_cs.atomic_arr[1], 1, 2); + _atomic_compare_exchange_result_Sint_4_ _e324; _e324.old_value = atomicCompSwap(_group_0_binding_2_cs.atomic_arr[1], 1, 2); _e324.exchanged = (_e324.old_value == 1); - _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e328; _e328.old_value = atomicCompSwap(workgroup_atomic_scalar, 1u, 2u); + _atomic_compare_exchange_result_Uint_4_ _e328; _e328.old_value = atomicCompSwap(workgroup_atomic_scalar, 1u, 2u); _e328.exchanged = (_e328.old_value == 1u); - _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e333; _e333.old_value = atomicCompSwap(workgroup_atomic_arr[1], 1, 2); + _atomic_compare_exchange_result_Sint_4_ _e333; _e333.old_value = atomicCompSwap(workgroup_atomic_arr[1], 1, 2); _e333.exchanged = (_e333.old_value == 1); - _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e338; _e338.old_value = atomicCompSwap(workgroup_struct.atomic_scalar, 1u, 2u); + _atomic_compare_exchange_result_Uint_4_ _e338; _e338.old_value = atomicCompSwap(workgroup_struct.atomic_scalar, 1u, 2u); _e338.exchanged = (_e338.old_value == 1u); - _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e344; _e344.old_value = atomicCompSwap(workgroup_struct.atomic_arr[1], 1, 2); + _atomic_compare_exchange_result_Sint_4_ _e344; _e344.old_value = atomicCompSwap(workgroup_struct.atomic_arr[1], 1, 2); _e344.exchanged = (_e344.old_value == 1); return; } diff --git a/naga/tests/out/hlsl/spv-fetch_depth.hlsl b/naga/tests/out/hlsl/spv-fetch_depth.hlsl index 909ac96ad3a..6dd03da2cbb 100644 --- a/naga/tests/out/hlsl/spv-fetch_depth.hlsl +++ b/naga/tests/out/hlsl/spv-fetch_depth.hlsl @@ -19,7 +19,7 @@ void function() } [numthreads(32, 1, 1)] -void cull_u003a_u003a_fetch_depth() +void cull_fetch_depth() { function(); } diff --git a/naga/tests/out/hlsl/spv-fetch_depth.ron b/naga/tests/out/hlsl/spv-fetch_depth.ron index 2651131aa2c..16eac451859 100644 --- a/naga/tests/out/hlsl/spv-fetch_depth.ron +++ b/naga/tests/out/hlsl/spv-fetch_depth.ron @@ -5,7 +5,7 @@ ], compute:[ ( - entry_point:"cull_u003a_u003a_fetch_depth", + entry_point:"cull_fetch_depth", target_profile:"cs_5_1", ), ], diff --git a/naga/tests/out/hlsl/wgsl-atomicCompareExchange-int64.hlsl b/naga/tests/out/hlsl/wgsl-atomicCompareExchange-int64.hlsl index b9086e4a797..5bf723e1fb6 100644 --- a/naga/tests/out/hlsl/wgsl-atomicCompareExchange-int64.hlsl +++ b/naga/tests/out/hlsl/wgsl-atomicCompareExchange-int64.hlsl @@ -5,13 +5,13 @@ struct NagaConstants { }; ConstantBuffer _NagaConstants: register(b0, space1); -struct _atomic_compare_exchange_result_u003c_Sint_u002c_8_u003e { +struct _atomic_compare_exchange_result_Sint_8_ { int64_t old_value; bool exchanged; int _end_pad_0; }; -struct _atomic_compare_exchange_result_u003c_Uint_u002c_8_u003e { +struct _atomic_compare_exchange_result_Uint_8_ { uint64_t old_value; bool exchanged; int _end_pad_0; @@ -63,7 +63,7 @@ void test_atomic_compare_exchange_i64_() int64_t new_ = (_e14 + 10L); uint _e19 = i; int64_t _e21 = old; - _atomic_compare_exchange_result_u003c_Sint_u002c_8_u003e _e22; arr_i64_.InterlockedCompareExchange64(_e19*8, _e21, new_, _e22.old_value); + _atomic_compare_exchange_result_Sint_8_ _e22; arr_i64_.InterlockedCompareExchange64(_e19*8, _e21, new_, _e22.old_value); _e22.exchanged = (_e22.old_value == _e21); old = _e22.old_value; exchanged = _e22.exchanged; @@ -115,7 +115,7 @@ void test_atomic_compare_exchange_u64_() uint64_t new_1 = (_e14 + 10uL); uint _e19 = i_1; uint64_t _e21 = old_1; - _atomic_compare_exchange_result_u003c_Uint_u002c_8_u003e _e22; arr_u64_.InterlockedCompareExchange64(_e19*8, _e21, new_1, _e22.old_value); + _atomic_compare_exchange_result_Uint_8_ _e22; arr_u64_.InterlockedCompareExchange64(_e19*8, _e21, new_1, _e22.old_value); _e22.exchanged = (_e22.old_value == _e21); old_1 = _e22.old_value; exchanged_1 = _e22.exchanged; diff --git a/naga/tests/out/hlsl/wgsl-atomicCompareExchange.hlsl b/naga/tests/out/hlsl/wgsl-atomicCompareExchange.hlsl index 907b8303731..f92c83c5e1f 100644 --- a/naga/tests/out/hlsl/wgsl-atomicCompareExchange.hlsl +++ b/naga/tests/out/hlsl/wgsl-atomicCompareExchange.hlsl @@ -1,9 +1,9 @@ -struct _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e { +struct _atomic_compare_exchange_result_Sint_4_ { int old_value; bool exchanged; }; -struct _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e { +struct _atomic_compare_exchange_result_Uint_4_ { uint old_value; bool exchanged; }; @@ -54,7 +54,7 @@ void test_atomic_compare_exchange_i32_() int new_ = asint((asfloat(_e14) + 1.0)); uint _e20 = i; int _e22 = old; - _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e23; arr_i32_.InterlockedCompareExchange(_e20*4, _e22, new_, _e23.old_value); + _atomic_compare_exchange_result_Sint_4_ _e23; arr_i32_.InterlockedCompareExchange(_e20*4, _e22, new_, _e23.old_value); _e23.exchanged = (_e23.old_value == _e22); old = _e23.old_value; exchanged = _e23.exchanged; @@ -106,7 +106,7 @@ void test_atomic_compare_exchange_u32_() uint new_1 = asuint((asfloat(_e14) + 1.0)); uint _e20 = i_1; uint _e22 = old_1; - _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e23; arr_u32_.InterlockedCompareExchange(_e20*4, _e22, new_1, _e23.old_value); + _atomic_compare_exchange_result_Uint_4_ _e23; arr_u32_.InterlockedCompareExchange(_e20*4, _e22, new_1, _e23.old_value); _e23.exchanged = (_e23.old_value == _e22); old_1 = _e23.old_value; exchanged_1 = _e23.exchanged; diff --git a/naga/tests/out/hlsl/wgsl-atomicOps-int64.hlsl b/naga/tests/out/hlsl/wgsl-atomicOps-int64.hlsl index 93a806afdd9..eaebd0f591f 100644 --- a/naga/tests/out/hlsl/wgsl-atomicOps-int64.hlsl +++ b/naga/tests/out/hlsl/wgsl-atomicOps-int64.hlsl @@ -10,13 +10,13 @@ struct Struct { int64_t atomic_arr[2]; }; -struct _atomic_compare_exchange_result_u003c_Uint_u002c_8_u003e { +struct _atomic_compare_exchange_result_Uint_8_ { uint64_t old_value; bool exchanged; int _end_pad_0; }; -struct _atomic_compare_exchange_result_u003c_Sint_u002c_8_u003e { +struct _atomic_compare_exchange_result_Sint_8_ { int64_t old_value; bool exchanged; int _end_pad_0; @@ -126,21 +126,21 @@ void cs_main(uint3 id : SV_GroupThreadID, uint3 __local_invocation_id : SV_Group int64_t _e279; InterlockedExchange(workgroup_atomic_arr[1], 1L, _e279); uint64_t _e283; InterlockedExchange(workgroup_struct.atomic_scalar, 1uL, _e283); int64_t _e288; InterlockedExchange(workgroup_struct.atomic_arr[1], 1L, _e288); - _atomic_compare_exchange_result_u003c_Uint_u002c_8_u003e _e292; storage_atomic_scalar.InterlockedCompareExchange64(0, 1uL, 2uL, _e292.old_value); + _atomic_compare_exchange_result_Uint_8_ _e292; storage_atomic_scalar.InterlockedCompareExchange64(0, 1uL, 2uL, _e292.old_value); _e292.exchanged = (_e292.old_value == 1uL); - _atomic_compare_exchange_result_u003c_Sint_u002c_8_u003e _e297; storage_atomic_arr.InterlockedCompareExchange64(8, 1L, 2L, _e297.old_value); + _atomic_compare_exchange_result_Sint_8_ _e297; storage_atomic_arr.InterlockedCompareExchange64(8, 1L, 2L, _e297.old_value); _e297.exchanged = (_e297.old_value == 1L); - _atomic_compare_exchange_result_u003c_Uint_u002c_8_u003e _e302; storage_struct.InterlockedCompareExchange64(0, 1uL, 2uL, _e302.old_value); + _atomic_compare_exchange_result_Uint_8_ _e302; storage_struct.InterlockedCompareExchange64(0, 1uL, 2uL, _e302.old_value); _e302.exchanged = (_e302.old_value == 1uL); - _atomic_compare_exchange_result_u003c_Sint_u002c_8_u003e _e308; storage_struct.InterlockedCompareExchange64(8+8, 1L, 2L, _e308.old_value); + _atomic_compare_exchange_result_Sint_8_ _e308; storage_struct.InterlockedCompareExchange64(8+8, 1L, 2L, _e308.old_value); _e308.exchanged = (_e308.old_value == 1L); - _atomic_compare_exchange_result_u003c_Uint_u002c_8_u003e _e312; InterlockedCompareExchange(workgroup_atomic_scalar, 1uL, 2uL, _e312.old_value); + _atomic_compare_exchange_result_Uint_8_ _e312; InterlockedCompareExchange(workgroup_atomic_scalar, 1uL, 2uL, _e312.old_value); _e312.exchanged = (_e312.old_value == 1uL); - _atomic_compare_exchange_result_u003c_Sint_u002c_8_u003e _e317; InterlockedCompareExchange(workgroup_atomic_arr[1], 1L, 2L, _e317.old_value); + _atomic_compare_exchange_result_Sint_8_ _e317; InterlockedCompareExchange(workgroup_atomic_arr[1], 1L, 2L, _e317.old_value); _e317.exchanged = (_e317.old_value == 1L); - _atomic_compare_exchange_result_u003c_Uint_u002c_8_u003e _e322; InterlockedCompareExchange(workgroup_struct.atomic_scalar, 1uL, 2uL, _e322.old_value); + _atomic_compare_exchange_result_Uint_8_ _e322; InterlockedCompareExchange(workgroup_struct.atomic_scalar, 1uL, 2uL, _e322.old_value); _e322.exchanged = (_e322.old_value == 1uL); - _atomic_compare_exchange_result_u003c_Sint_u002c_8_u003e _e328; InterlockedCompareExchange(workgroup_struct.atomic_arr[1], 1L, 2L, _e328.old_value); + _atomic_compare_exchange_result_Sint_8_ _e328; InterlockedCompareExchange(workgroup_struct.atomic_arr[1], 1L, 2L, _e328.old_value); _e328.exchanged = (_e328.old_value == 1L); return; } diff --git a/naga/tests/out/hlsl/wgsl-atomicOps.hlsl b/naga/tests/out/hlsl/wgsl-atomicOps.hlsl index 47b586d7dba..d32d953a18c 100644 --- a/naga/tests/out/hlsl/wgsl-atomicOps.hlsl +++ b/naga/tests/out/hlsl/wgsl-atomicOps.hlsl @@ -3,12 +3,12 @@ struct Struct { int atomic_arr[2]; }; -struct _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e { +struct _atomic_compare_exchange_result_Uint_4_ { uint old_value; bool exchanged; }; -struct _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e { +struct _atomic_compare_exchange_result_Sint_4_ { int old_value; bool exchanged; }; @@ -117,21 +117,21 @@ void cs_main(uint3 id : SV_GroupThreadID, uint3 __local_invocation_id : SV_Group int _e295; InterlockedExchange(workgroup_atomic_arr[1], int(1), _e295); uint _e299; InterlockedExchange(workgroup_struct.atomic_scalar, 1u, _e299); int _e304; InterlockedExchange(workgroup_struct.atomic_arr[1], int(1), _e304); - _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e308; storage_atomic_scalar.InterlockedCompareExchange(0, 1u, 2u, _e308.old_value); + _atomic_compare_exchange_result_Uint_4_ _e308; storage_atomic_scalar.InterlockedCompareExchange(0, 1u, 2u, _e308.old_value); _e308.exchanged = (_e308.old_value == 1u); - _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e313; storage_atomic_arr.InterlockedCompareExchange(4, int(1), int(2), _e313.old_value); + _atomic_compare_exchange_result_Sint_4_ _e313; storage_atomic_arr.InterlockedCompareExchange(4, int(1), int(2), _e313.old_value); _e313.exchanged = (_e313.old_value == int(1)); - _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e318; storage_struct.InterlockedCompareExchange(0, 1u, 2u, _e318.old_value); + _atomic_compare_exchange_result_Uint_4_ _e318; storage_struct.InterlockedCompareExchange(0, 1u, 2u, _e318.old_value); _e318.exchanged = (_e318.old_value == 1u); - _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e324; storage_struct.InterlockedCompareExchange(4+4, int(1), int(2), _e324.old_value); + _atomic_compare_exchange_result_Sint_4_ _e324; storage_struct.InterlockedCompareExchange(4+4, int(1), int(2), _e324.old_value); _e324.exchanged = (_e324.old_value == int(1)); - _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e328; InterlockedCompareExchange(workgroup_atomic_scalar, 1u, 2u, _e328.old_value); + _atomic_compare_exchange_result_Uint_4_ _e328; InterlockedCompareExchange(workgroup_atomic_scalar, 1u, 2u, _e328.old_value); _e328.exchanged = (_e328.old_value == 1u); - _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e333; InterlockedCompareExchange(workgroup_atomic_arr[1], int(1), int(2), _e333.old_value); + _atomic_compare_exchange_result_Sint_4_ _e333; InterlockedCompareExchange(workgroup_atomic_arr[1], int(1), int(2), _e333.old_value); _e333.exchanged = (_e333.old_value == int(1)); - _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e338; InterlockedCompareExchange(workgroup_struct.atomic_scalar, 1u, 2u, _e338.old_value); + _atomic_compare_exchange_result_Uint_4_ _e338; InterlockedCompareExchange(workgroup_struct.atomic_scalar, 1u, 2u, _e338.old_value); _e338.exchanged = (_e338.old_value == 1u); - _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e344; InterlockedCompareExchange(workgroup_struct.atomic_arr[1], int(1), int(2), _e344.old_value); + _atomic_compare_exchange_result_Sint_4_ _e344; InterlockedCompareExchange(workgroup_struct.atomic_arr[1], int(1), int(2), _e344.old_value); _e344.exchanged = (_e344.old_value == int(1)); return; } diff --git a/naga/tests/out/msl/spv-fetch_depth.msl b/naga/tests/out/msl/spv-fetch_depth.msl index 642cf305a5c..ce239c4f925 100644 --- a/naga/tests/out/msl/spv-fetch_depth.msl +++ b/naga/tests/out/msl/spv-fetch_depth.msl @@ -22,7 +22,7 @@ void function( return; } -kernel void cull_u003a_u003a_fetch_depth( +kernel void cull_fetch_depth( device type_2& global [[user(fake0)]] , device type_4 const& global_1 [[user(fake0)]] , metal::depth2d global_2 [[user(fake0)]] diff --git a/naga/tests/out/msl/wgsl-atomicCompareExchange.msl b/naga/tests/out/msl/wgsl-atomicCompareExchange.msl index 3c372b55e63..967e003a791 100644 --- a/naga/tests/out/msl/wgsl-atomicCompareExchange.msl +++ b/naga/tests/out/msl/wgsl-atomicCompareExchange.msl @@ -10,19 +10,19 @@ struct type_2 { struct type_4 { metal::atomic_uint inner[128]; }; -struct _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e { +struct _atomic_compare_exchange_result_Sint_4_ { int old_value; bool exchanged; char _pad2[3]; }; -struct _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e { +struct _atomic_compare_exchange_result_Uint_4_ { uint old_value; bool exchanged; char _pad2[3]; }; template -_atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_Sint_4_ naga_atomic_compare_exchange_weak_explicit( device A *atomic_ptr, int cmp, int v @@ -31,10 +31,10 @@ _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e naga_atomic_compare_exc atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e{cmp, swapped}; + return _atomic_compare_exchange_result_Sint_4_{cmp, swapped}; } template -_atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_Sint_4_ naga_atomic_compare_exchange_weak_explicit( threadgroup A *atomic_ptr, int cmp, int v @@ -43,11 +43,11 @@ _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e naga_atomic_compare_exc atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e{cmp, swapped}; + return _atomic_compare_exchange_result_Sint_4_{cmp, swapped}; } template -_atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_Uint_4_ naga_atomic_compare_exchange_weak_explicit( device A *atomic_ptr, uint cmp, uint v @@ -56,10 +56,10 @@ _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e naga_atomic_compare_exc atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e{cmp, swapped}; + return _atomic_compare_exchange_result_Uint_4_{cmp, swapped}; } template -_atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_Uint_4_ naga_atomic_compare_exchange_weak_explicit( threadgroup A *atomic_ptr, uint cmp, uint v @@ -68,7 +68,7 @@ _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e naga_atomic_compare_exc atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e{cmp, swapped}; + return _atomic_compare_exchange_result_Uint_4_{cmp, swapped}; } constant uint SIZE = 128u; @@ -112,7 +112,7 @@ kernel void test_atomic_compare_exchange_i32_( int new_ = as_type(as_type(_e14) + 1.0); uint _e20 = i; int _e22 = old; - _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e23 = naga_atomic_compare_exchange_weak_explicit(&arr_i32_.inner[_e20], _e22, new_); + _atomic_compare_exchange_result_Sint_4_ _e23 = naga_atomic_compare_exchange_weak_explicit(&arr_i32_.inner[_e20], _e22, new_); old = _e23.old_value; exchanged = _e23.exchanged; } @@ -163,7 +163,7 @@ kernel void test_atomic_compare_exchange_u32_( uint new_1 = as_type(as_type(_e14) + 1.0); uint _e20 = i_1; uint _e22 = old_1; - _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e23 = naga_atomic_compare_exchange_weak_explicit(&arr_u32_.inner[_e20], _e22, new_1); + _atomic_compare_exchange_result_Uint_4_ _e23 = naga_atomic_compare_exchange_weak_explicit(&arr_u32_.inner[_e20], _e22, new_1); old_1 = _e23.old_value; exchanged_1 = _e23.exchanged; } diff --git a/naga/tests/out/msl/wgsl-atomicOps.msl b/naga/tests/out/msl/wgsl-atomicOps.msl index 8266c1bd764..4afdde1540f 100644 --- a/naga/tests/out/msl/wgsl-atomicOps.msl +++ b/naga/tests/out/msl/wgsl-atomicOps.msl @@ -11,19 +11,19 @@ struct Struct { metal::atomic_uint atomic_scalar; type_2 atomic_arr; }; -struct _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e { +struct _atomic_compare_exchange_result_Uint_4_ { uint old_value; bool exchanged; char _pad2[3]; }; -struct _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e { +struct _atomic_compare_exchange_result_Sint_4_ { int old_value; bool exchanged; char _pad2[3]; }; template -_atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_Uint_4_ naga_atomic_compare_exchange_weak_explicit( device A *atomic_ptr, uint cmp, uint v @@ -32,10 +32,10 @@ _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e naga_atomic_compare_exc atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e{cmp, swapped}; + return _atomic_compare_exchange_result_Uint_4_{cmp, swapped}; } template -_atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_Uint_4_ naga_atomic_compare_exchange_weak_explicit( threadgroup A *atomic_ptr, uint cmp, uint v @@ -44,11 +44,11 @@ _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e naga_atomic_compare_exc atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e{cmp, swapped}; + return _atomic_compare_exchange_result_Uint_4_{cmp, swapped}; } template -_atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_Sint_4_ naga_atomic_compare_exchange_weak_explicit( device A *atomic_ptr, int cmp, int v @@ -57,10 +57,10 @@ _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e naga_atomic_compare_exc atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e{cmp, swapped}; + return _atomic_compare_exchange_result_Sint_4_{cmp, swapped}; } template -_atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_Sint_4_ naga_atomic_compare_exchange_weak_explicit( threadgroup A *atomic_ptr, int cmp, int v @@ -69,7 +69,7 @@ _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e naga_atomic_compare_exc atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e{cmp, swapped}; + return _atomic_compare_exchange_result_Sint_4_{cmp, swapped}; } struct cs_mainInput { @@ -182,13 +182,13 @@ kernel void cs_main( int _e295 = metal::atomic_exchange_explicit(&workgroup_atomic_arr.inner[1], 1, metal::memory_order_relaxed); uint _e299 = metal::atomic_exchange_explicit(&workgroup_struct.atomic_scalar, 1u, metal::memory_order_relaxed); int _e304 = metal::atomic_exchange_explicit(&workgroup_struct.atomic_arr.inner[1], 1, metal::memory_order_relaxed); - _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e308 = naga_atomic_compare_exchange_weak_explicit(&storage_atomic_scalar, 1u, 2u); - _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e313 = naga_atomic_compare_exchange_weak_explicit(&storage_atomic_arr.inner[1], 1, 2); - _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e318 = naga_atomic_compare_exchange_weak_explicit(&storage_struct.atomic_scalar, 1u, 2u); - _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e324 = naga_atomic_compare_exchange_weak_explicit(&storage_struct.atomic_arr.inner[1], 1, 2); - _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e328 = naga_atomic_compare_exchange_weak_explicit(&workgroup_atomic_scalar, 1u, 2u); - _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e333 = naga_atomic_compare_exchange_weak_explicit(&workgroup_atomic_arr.inner[1], 1, 2); - _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e338 = naga_atomic_compare_exchange_weak_explicit(&workgroup_struct.atomic_scalar, 1u, 2u); - _atomic_compare_exchange_result_u003c_Sint_u002c_4_u003e _e344 = naga_atomic_compare_exchange_weak_explicit(&workgroup_struct.atomic_arr.inner[1], 1, 2); + _atomic_compare_exchange_result_Uint_4_ _e308 = naga_atomic_compare_exchange_weak_explicit(&storage_atomic_scalar, 1u, 2u); + _atomic_compare_exchange_result_Sint_4_ _e313 = naga_atomic_compare_exchange_weak_explicit(&storage_atomic_arr.inner[1], 1, 2); + _atomic_compare_exchange_result_Uint_4_ _e318 = naga_atomic_compare_exchange_weak_explicit(&storage_struct.atomic_scalar, 1u, 2u); + _atomic_compare_exchange_result_Sint_4_ _e324 = naga_atomic_compare_exchange_weak_explicit(&storage_struct.atomic_arr.inner[1], 1, 2); + _atomic_compare_exchange_result_Uint_4_ _e328 = naga_atomic_compare_exchange_weak_explicit(&workgroup_atomic_scalar, 1u, 2u); + _atomic_compare_exchange_result_Sint_4_ _e333 = naga_atomic_compare_exchange_weak_explicit(&workgroup_atomic_arr.inner[1], 1, 2); + _atomic_compare_exchange_result_Uint_4_ _e338 = naga_atomic_compare_exchange_weak_explicit(&workgroup_struct.atomic_scalar, 1u, 2u); + _atomic_compare_exchange_result_Sint_4_ _e344 = naga_atomic_compare_exchange_weak_explicit(&workgroup_struct.atomic_arr.inner[1], 1, 2); return; } diff --git a/naga/tests/out/msl/wgsl-overrides-atomicCompareExchangeWeak.msl b/naga/tests/out/msl/wgsl-overrides-atomicCompareExchangeWeak.msl index a15984d9c16..42b93fdfcea 100644 --- a/naga/tests/out/msl/wgsl-overrides-atomicCompareExchangeWeak.msl +++ b/naga/tests/out/msl/wgsl-overrides-atomicCompareExchangeWeak.msl @@ -4,14 +4,14 @@ using metal::uint; -struct _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e { +struct _atomic_compare_exchange_result_Uint_4_ { uint old_value; bool exchanged; char _pad2[3]; }; template -_atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_Uint_4_ naga_atomic_compare_exchange_weak_explicit( device A *atomic_ptr, uint cmp, uint v @@ -20,10 +20,10 @@ _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e naga_atomic_compare_exc atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e{cmp, swapped}; + return _atomic_compare_exchange_result_Uint_4_{cmp, swapped}; } template -_atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e naga_atomic_compare_exchange_weak_explicit( +_atomic_compare_exchange_result_Uint_4_ naga_atomic_compare_exchange_weak_explicit( threadgroup A *atomic_ptr, uint cmp, uint v @@ -32,7 +32,7 @@ _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e naga_atomic_compare_exc atomic_ptr, &cmp, v, metal::memory_order_relaxed, metal::memory_order_relaxed ); - return _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e{cmp, swapped}; + return _atomic_compare_exchange_result_Uint_4_{cmp, swapped}; } constant int o = 2; @@ -44,6 +44,6 @@ kernel void f( metal::atomic_store_explicit(&a, 0, metal::memory_order_relaxed); } metal::threadgroup_barrier(metal::mem_flags::mem_threadgroup); - _atomic_compare_exchange_result_u003c_Uint_u002c_4_u003e _e5 = naga_atomic_compare_exchange_weak_explicit(&a, 2u, 1u); + _atomic_compare_exchange_result_Uint_4_ _e5 = naga_atomic_compare_exchange_weak_explicit(&a, 2u, 1u); return; } diff --git a/naga/tests/out/wgsl/spv-atomic_compare_exchange.wgsl b/naga/tests/out/wgsl/spv-atomic_compare_exchange.wgsl index 88476c5057d..36b460d74af 100644 --- a/naga/tests/out/wgsl/spv-atomic_compare_exchange.wgsl +++ b/naga/tests/out/wgsl/spv-atomic_compare_exchange.wgsl @@ -61,6 +61,6 @@ fn function() { } @compute @workgroup_size(32, 1, 1) -fn stage_u003a_u003a_test_atomic_compare_exchange() { +fn stage_test_atomic_compare_exchange() { function(); } diff --git a/naga/tests/out/wgsl/spv-atomic_exchange.wgsl b/naga/tests/out/wgsl/spv-atomic_exchange.wgsl index e17ac9e5879..0440b1b92b5 100644 --- a/naga/tests/out/wgsl/spv-atomic_exchange.wgsl +++ b/naga/tests/out/wgsl/spv-atomic_exchange.wgsl @@ -75,6 +75,6 @@ fn function() { } @compute @workgroup_size(32, 1, 1) -fn stage_u003a_u003a_test_atomic_exchange() { +fn stage_test_atomic_exchange() { function(); } diff --git a/naga/tests/out/wgsl/spv-atomic_i_add_sub.wgsl b/naga/tests/out/wgsl/spv-atomic_i_add_sub.wgsl index b783267ad37..bebab9e059e 100644 --- a/naga/tests/out/wgsl/spv-atomic_i_add_sub.wgsl +++ b/naga/tests/out/wgsl/spv-atomic_i_add_sub.wgsl @@ -21,6 +21,6 @@ fn function() { } @compute @workgroup_size(32, 1, 1) -fn stage_u003a_u003a_test_atomic_i_add_sub() { +fn stage_test_atomic_i_add_sub() { function(); } diff --git a/naga/tests/out/wgsl/spv-atomic_i_decrement.wgsl b/naga/tests/out/wgsl/spv-atomic_i_decrement.wgsl index e0bf0a2488a..e2f3bd83b6e 100644 --- a/naga/tests/out/wgsl/spv-atomic_i_decrement.wgsl +++ b/naga/tests/out/wgsl/spv-atomic_i_decrement.wgsl @@ -32,6 +32,6 @@ fn function() { } @compute @workgroup_size(32, 1, 1) -fn stage_u003a_u003a_test_atomic_i_decrement() { +fn stage_test_atomic_i_decrement() { function(); } diff --git a/naga/tests/out/wgsl/spv-atomic_i_increment.wgsl b/naga/tests/out/wgsl/spv-atomic_i_increment.wgsl index 830bf98d971..139372776a3 100644 --- a/naga/tests/out/wgsl/spv-atomic_i_increment.wgsl +++ b/naga/tests/out/wgsl/spv-atomic_i_increment.wgsl @@ -37,6 +37,6 @@ fn function() { } @compute @workgroup_size(32, 1, 1) -fn stage_u003a_u003a_test_atomic_i_increment() { +fn stage_test_atomic_i_increment() { function(); } diff --git a/naga/tests/out/wgsl/spv-atomic_load_and_store.wgsl b/naga/tests/out/wgsl/spv-atomic_load_and_store.wgsl index d33f92171f8..0525acb2232 100644 --- a/naga/tests/out/wgsl/spv-atomic_load_and_store.wgsl +++ b/naga/tests/out/wgsl/spv-atomic_load_and_store.wgsl @@ -67,6 +67,6 @@ fn function() { } @compute @workgroup_size(32, 1, 1) -fn stage_u003a_u003a_test_atomic_load_and_store() { +fn stage_test_atomic_load_and_store() { function(); } diff --git a/naga/tests/out/wgsl/spv-fetch_depth.wgsl b/naga/tests/out/wgsl/spv-fetch_depth.wgsl index d6a7d5173e8..17950e9b1e2 100644 --- a/naga/tests/out/wgsl/spv-fetch_depth.wgsl +++ b/naga/tests/out/wgsl/spv-fetch_depth.wgsl @@ -21,6 +21,6 @@ fn function() { } @compute @workgroup_size(32, 1, 1) -fn cull_u003a_u003a_fetch_depth() { +fn cull_fetch_depth() { function(); } From a2547f8211a5568ef0d2b2bcb38c0ddbff9ab120 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 Oct 2025 10:59:09 -0400 Subject: [PATCH 271/303] chore(deps): update dependency macos to v15 (#8278) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/shaders.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/shaders.yml b/.github/workflows/shaders.yml index bc2d2843010..062d6ecb142 100644 --- a/.github/workflows/shaders.yml +++ b/.github/workflows/shaders.yml @@ -67,7 +67,7 @@ jobs: naga-validate-macos: name: "Validate: MSL" - runs-on: macos-14 + runs-on: macos-15 steps: - uses: actions/checkout@v5 From 5b194ec510b3ac7c154b6a6d81a4811567d1e7a3 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Wed, 1 Oct 2025 08:23:46 -0700 Subject: [PATCH 272/303] [deno] Remove kludge for `type` properties (#8262) --- deno_webgpu/01_webgpu.js | 14 -------------- deno_webgpu/query_set.rs | 5 ++--- deno_webgpu/shader.rs | 5 ++--- 3 files changed, 4 insertions(+), 20 deletions(-) diff --git a/deno_webgpu/01_webgpu.js b/deno_webgpu/01_webgpu.js index c958f189e16..8c5ce5c5933 100644 --- a/deno_webgpu/01_webgpu.js +++ b/deno_webgpu/01_webgpu.js @@ -625,13 +625,6 @@ ObjectDefineProperty(GPUCompilationMessage, privateCustomInspect, { }, }); const GPUCompilationMessagePrototype = GPUCompilationMessage.prototype; -// Naming it `type` or `r#type` in Rust does not work. -// https://github.com/gfx-rs/wgpu/issues/7778 -ObjectDefineProperty(GPUCompilationMessage.prototype, "type", { - get() { - return this.ty; - } -}); class GPUShaderStage { constructor() { @@ -845,13 +838,6 @@ ObjectDefineProperty(GPUQuerySetPrototype, privateCustomInspect, { ); }, }); -// Naming it `type` or `r#type` in Rust does not work. -// https://github.com/gfx-rs/wgpu/issues/7778 -ObjectDefineProperty(GPUQuerySet.prototype, "type", { - get() { - return this.ty; - } -}); // Converters diff --git a/deno_webgpu/query_set.rs b/deno_webgpu/query_set.rs index a4ec0d39041..5b5e7dd8f16 100644 --- a/deno_webgpu/query_set.rs +++ b/deno_webgpu/query_set.rs @@ -61,11 +61,10 @@ impl GPUQuerySet { Ok(()) } - // Naming this `type` or `r#type` does not work. - // https://github.com/gfx-rs/wgpu/issues/7778 #[getter] #[string] - fn ty(&self) -> &'static str { + #[rename("type")] + fn r#type(&self) -> &'static str { self.r#type.as_str() } diff --git a/deno_webgpu/shader.rs b/deno_webgpu/shader.rs index 2718826f511..49a81a83c94 100644 --- a/deno_webgpu/shader.rs +++ b/deno_webgpu/shader.rs @@ -96,11 +96,10 @@ impl GPUCompilationMessage { self.message.clone() } - // Naming this `type` or `r#type` does not work. - // https://github.com/gfx-rs/wgpu/issues/7778 #[getter] #[string] - fn ty(&self) -> &'static str { + #[rename("type")] + fn r#type(&self) -> &'static str { self.r#type.as_str() } From 43eccd28f827e17cb4cd226a3c22efa659f98ead Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Wed, 1 Oct 2025 09:08:18 -0700 Subject: [PATCH 273/303] [naga] Remove `naga::path_like`. Use `String` instead. (#8284) Delete the `naga::path_like` module, and simply using `String` and `str` instead. Nothing in Naga uses `Path` or `PathBuf` methods; indeed, Naga only converts these values back and forth from string-like types with `to_string_lossy` and `into`, such that using string-like, rather than path-like, types actually simplifies the code. This also avoids dead code warnings starting in Rust 1.89 that would otherwise require distracting `#[cfg_attr]` conditionals. --- naga-cli/src/bin/naga.rs | 12 +- naga/src/back/spv/mod.rs | 3 +- naga/src/back/spv/writer.rs | 7 +- naga/src/front/spv/mod.rs | 3 +- naga/src/lib.rs | 1 - naga/src/path_like.rs | 238 ---------------------------------- naga/src/span.rs | 10 +- naga/tests/naga/snapshots.rs | 16 +-- wgpu-hal/src/vulkan/device.rs | 4 +- 9 files changed, 20 insertions(+), 274 deletions(-) delete mode 100644 naga/src/path_like.rs diff --git a/naga-cli/src/bin/naga.rs b/naga-cli/src/bin/naga.rs index bbdc63fad5b..b620ecc704f 100644 --- a/naga-cli/src/bin/naga.rs +++ b/naga-cli/src/bin/naga.rs @@ -452,7 +452,7 @@ fn run() -> anyhow::Result<()> { params.spv_in = naga::front::spv::Options { adjust_coordinate_space: !args.keep_coordinate_space, strict_capabilities: false, - block_ctx_dump_prefix: args.block_ctx_dir.clone().map(Into::into), + block_ctx_dump_prefix: args.block_ctx_dir.clone(), }; params.entry_point.clone_from(&args.entry_point); @@ -482,7 +482,7 @@ fn run() -> anyhow::Result<()> { params.compact = args.compact; if args.bulk_validate { - return bulk_validate(args, ¶ms); + return bulk_validate(&args, ¶ms); } let mut files = args.files.iter(); @@ -498,6 +498,8 @@ fn run() -> anyhow::Result<()> { return Err(CliError("Input file path is not specified").into()); }; + let file_name = input_path.to_string_lossy(); + params.input_kind = args.input_kind; params.shader_stage = args.shader_stage; @@ -516,7 +518,7 @@ fn run() -> anyhow::Result<()> { .set(naga::back::spv::WriterFlags::DEBUG, true); params.spv_out.debug_info = Some(naga::back::spv::DebugInfo { source_code: input_text, - file_name: input_path.into(), + file_name: &file_name, language, }) } else { @@ -913,9 +915,9 @@ fn write_output( Ok(()) } -fn bulk_validate(args: Args, params: &Parameters) -> anyhow::Result<()> { +fn bulk_validate(args: &Args, params: &Parameters) -> anyhow::Result<()> { let mut invalid = vec![]; - for input_path in args.files { + for input_path in &args.files { let path = Path::new(&input_path); let input = fs::read(path)?; diff --git a/naga/src/back/spv/mod.rs b/naga/src/back/spv/mod.rs index 371b3f7dbec..4690dc71951 100644 --- a/naga/src/back/spv/mod.rs +++ b/naga/src/back/spv/mod.rs @@ -26,7 +26,6 @@ use spirv::Word; use thiserror::Error; use crate::arena::{Handle, HandleVec}; -use crate::path_like::PathLikeRef; use crate::proc::{BoundsCheckPolicies, TypeResolution}; #[derive(Clone)] @@ -96,7 +95,7 @@ impl IdGenerator { #[derive(Debug, Clone)] pub struct DebugInfo<'a> { pub source_code: &'a str, - pub file_name: PathLikeRef<'a>, + pub file_name: &'a str, pub language: SourceLanguage, } diff --git a/naga/src/back/spv/writer.rs b/naga/src/back/spv/writer.rs index 636766d1e5f..c86a53c6ef8 100644 --- a/naga/src/back/spv/writer.rs +++ b/naga/src/back/spv/writer.rs @@ -14,7 +14,6 @@ use super::{ use crate::{ arena::{Handle, HandleVec, UniqueArena}, back::spv::{BindingInfo, WrappedFunction}, - path_like::PathLike, proc::{Alignment, TypeResolution}, valid::{FunctionInfo, ModuleInfo}, }; @@ -2519,10 +2518,8 @@ impl Writer { if self.flags.contains(WriterFlags::DEBUG) { if let Some(debug_info) = debug_info.as_ref() { let source_file_id = self.id_gen.next(); - self.debugs.push(Instruction::string( - &debug_info.file_name.to_string_lossy(), - source_file_id, - )); + self.debugs + .push(Instruction::string(debug_info.file_name, source_file_id)); debug_info_inner = Some(DebugInfoInner { source_code: debug_info.source_code, diff --git a/naga/src/front/spv/mod.rs b/naga/src/front/spv/mod.rs index 835cbe1aa82..f54c8269f0f 100644 --- a/naga/src/front/spv/mod.rs +++ b/naga/src/front/spv/mod.rs @@ -44,7 +44,6 @@ use petgraph::graphmap::GraphMap; use super::atomic_upgrade::Upgrades; use crate::{ arena::{Arena, Handle, UniqueArena}, - path_like::PathLikeOwned, proc::{Alignment, Layouter}, FastHashMap, FastHashSet, FastIndexMap, }; @@ -384,7 +383,7 @@ pub struct Options { pub adjust_coordinate_space: bool, /// Only allow shaders with the known set of capabilities. pub strict_capabilities: bool, - pub block_ctx_dump_prefix: Option, + pub block_ctx_dump_prefix: Option, } impl Default for Options { diff --git a/naga/src/lib.rs b/naga/src/lib.rs index 19b406588b3..af990fb1dd1 100644 --- a/naga/src/lib.rs +++ b/naga/src/lib.rs @@ -116,7 +116,6 @@ pub mod front; pub mod ir; pub mod keywords; mod non_max_u32; -mod path_like; pub mod proc; mod racy_lock; mod span; diff --git a/naga/src/path_like.rs b/naga/src/path_like.rs deleted file mode 100644 index 36ca39c493b..00000000000 --- a/naga/src/path_like.rs +++ /dev/null @@ -1,238 +0,0 @@ -//! [`PathLike`] and its supporting items, such as [`PathLikeRef`] and [`PathLikeOwned`]. -//! This trait and these types provide a common denominator API for `Path`-like -//! types and operations in `std` and `no_std` contexts. -//! -//! # Usage -//! -//! - Store a [`PathLikeRef<'a>`] instead of a `&'a Path` in structs and enums. -//! - Store a [`PathLikeOwned`] instead of a `PathBuf` in structs and enums. -//! - Accept `impl PathLike` instead of `impl AsRef` for methods which directly -//! work with `Path`-like values. -//! - Accept `Into>` and/or `Into` in methods which -//! will store a `Path`-like value. - -use alloc::{borrow::Cow, string::String}; -use core::fmt; - -mod sealed { - /// Seal for [`PathLike`](super::PathLike). - pub trait Sealed {} -} - -/// A trait that abstracts over types accepted for conversion to the most -/// featureful path representation possible; that is: -/// -/// - When `no_std` is active, this is implemented for: -/// - [`str`], -/// - [`String`], -/// - [`Cow<'_, str>`], and -/// - [`PathLikeRef`] -/// - Otherwise, types that implement `AsRef` (to extract a `&Path`). -/// -/// This type is used as the type bounds for various diagnostic rendering methods, i.e., -/// [`WithSpan::emit_to_string_with_path`](crate::span::WithSpan::emit_to_string_with_path). -pub trait PathLike: sealed::Sealed { - fn to_string_lossy(&self) -> Cow<'_, str>; -} - -/// Abstraction over `Path` which falls back to [`str`] for `no_std` compatibility. -/// -/// This type should be used for _storing_ a reference to a [`PathLike`]. -/// Functions which accept a `Path` should prefer to use `impl PathLike` -/// or `impl Into>`. -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct PathLikeRef<'a>(&'a path_like_impls::PathInner); - -impl fmt::Debug for PathLikeRef<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(self.0, f) - } -} - -impl<'a> From<&'a str> for PathLikeRef<'a> { - fn from(value: &'a str) -> Self { - cfg_if::cfg_if! { - if #[cfg(std)] { - Self(std::path::Path::new(value)) - } else { - Self(value) - } - } - } -} - -/// Abstraction over `PathBuf` which falls back to [`String`] for `no_std` compatibility. -/// -/// This type should be used for _storing_ an owned [`PathLike`]. -/// Functions which accept a `PathBuf` should prefer to use `impl PathLike` -/// or `impl Into`. -#[derive(Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct PathLikeOwned(::Owned); - -impl fmt::Debug for PathLikeOwned { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&self.0, f) - } -} - -impl From for PathLikeOwned { - fn from(value: String) -> Self { - cfg_if::cfg_if! { - if #[cfg(std)] { - Self(value.into()) - } else { - Self(value) - } - } - } -} - -#[cfg(std)] -mod path_like_impls { - //! Implementations of [`PathLike`] within an `std` context. - //! - //! Since `std` is available, we blanket implement [`PathLike`] for all types - //! implementing [`AsRef`]. - - use alloc::borrow::Cow; - use std::path::Path; - - use super::{sealed, PathLike}; - - pub(super) type PathInner = Path; - - impl + ?Sized> PathLike for T { - fn to_string_lossy(&self) -> Cow<'_, str> { - self.as_ref().to_string_lossy() - } - } - - impl + ?Sized> sealed::Sealed for T {} -} - -#[cfg(no_std)] -mod path_like_impls { - //! Implementations of [`PathLike`] within a `no_std` context. - //! - //! Without `std`, we cannot blanket implement on [`AsRef`]. - //! Instead, we manually implement for a subset of types which are known - //! to implement [`AsRef`] when `std` is available. - //! - //! Implementing [`PathLike`] for a type which does _not_ implement [`AsRef`] - //! with `std` enabled breaks the additive requirement of Cargo features. - - use alloc::{borrow::Cow, string::String}; - use core::borrow::Borrow; - - use super::{sealed, PathLike, PathLikeOwned, PathLikeRef}; - - pub(super) type PathInner = str; - - impl PathLike for String { - fn to_string_lossy(&self) -> Cow<'_, str> { - Cow::Borrowed(self.as_str()) - } - } - - impl sealed::Sealed for String {} - - impl PathLike for str { - fn to_string_lossy(&self) -> Cow<'_, str> { - Cow::Borrowed(self) - } - } - - impl sealed::Sealed for str {} - - impl PathLike for Cow<'_, str> { - fn to_string_lossy(&self) -> Cow<'_, str> { - Cow::Borrowed(self.borrow()) - } - } - - impl sealed::Sealed for Cow<'_, str> {} - - impl PathLike for &T { - fn to_string_lossy(&self) -> Cow<'_, str> { - (*self).to_string_lossy() - } - } - - impl sealed::Sealed for &T {} - - impl PathLike for PathLikeRef<'_> { - fn to_string_lossy(&self) -> Cow<'_, str> { - Cow::Borrowed(self.0) - } - } - - impl sealed::Sealed for PathLikeRef<'_> {} - - impl PathLike for PathLikeOwned { - fn to_string_lossy(&self) -> Cow<'_, str> { - Cow::Borrowed(self.0.borrow()) - } - } - - impl sealed::Sealed for PathLikeOwned {} -} - -#[cfg(std)] -mod path_like_owned_std_impls { - //! Traits which can only be implemented for [`PathLikeOwned`] with `std`. - - use std::path::{Path, PathBuf}; - - use super::PathLikeOwned; - - impl AsRef for PathLikeOwned { - fn as_ref(&self) -> &Path { - self.0.as_ref() - } - } - - impl From for PathLikeOwned { - fn from(value: PathBuf) -> Self { - Self(value) - } - } - - impl From for PathBuf { - fn from(value: PathLikeOwned) -> Self { - value.0 - } - } - - impl AsRef for PathLikeOwned { - fn as_ref(&self) -> &PathBuf { - &self.0 - } - } -} - -#[cfg(std)] -mod path_like_ref_std_impls { - //! Traits which can only be implemented for [`PathLikeRef`] with `std`. - - use std::path::Path; - - use super::PathLikeRef; - - impl AsRef for PathLikeRef<'_> { - fn as_ref(&self) -> &Path { - self.0 - } - } - - impl<'a> From<&'a Path> for PathLikeRef<'a> { - fn from(value: &'a Path) -> Self { - Self(value) - } - } - - impl<'a> From> for &'a Path { - fn from(value: PathLikeRef<'a>) -> Self { - value.0 - } - } -} diff --git a/naga/src/span.rs b/naga/src/span.rs index 357c2379f29..adfe7ad607a 100644 --- a/naga/src/span.rs +++ b/naga/src/span.rs @@ -6,7 +6,7 @@ use alloc::{ }; use core::{error::Error, fmt, ops::Range}; -use crate::{error::replace_control_chars, path_like::PathLike, Arena, Handle, UniqueArena}; +use crate::{error::replace_control_chars, Arena, Handle, UniqueArena}; /// A source code span, used for error reporting. #[derive(Clone, Copy, Debug, PartialEq, Default)] @@ -283,14 +283,12 @@ impl WithSpan { /// Emits a summary of the error to standard error stream. #[cfg(feature = "stderr")] - pub fn emit_to_stderr_with_path

(&self, source: &str, path: P) + pub fn emit_to_stderr_with_path(&self, source: &str, path: &str) where E: Error, - P: PathLike, { use codespan_reporting::{files, term}; - let path = path.to_string_lossy(); let files = files::SimpleFile::new(path, replace_control_chars(source)); let config = term::Config::default(); @@ -315,14 +313,12 @@ impl WithSpan { } /// Emits a summary of the error to a string. - pub fn emit_to_string_with_path

(&self, source: &str, path: P) -> String + pub fn emit_to_string_with_path(&self, source: &str, path: &str) -> String where E: Error, - P: PathLike, { use codespan_reporting::{files, term}; - let path = path.to_string_lossy(); let files = files::SimpleFile::new(path, replace_control_chars(source)); let config = term::Config::default(); diff --git a/naga/tests/naga/snapshots.rs b/naga/tests/naga/snapshots.rs index e2d9402813f..e01610f29a8 100644 --- a/naga/tests/naga/snapshots.rs +++ b/naga/tests/naga/snapshots.rs @@ -7,7 +7,7 @@ const DIR_OUT: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/tests/out"); #[allow(unused_variables)] fn check_targets(input: &Input, module: &mut naga::Module, source_code: Option<&str>) { let params = input.read_parameters(DIR_IN); - let name = &input.file_name; + let name = input.file_name.display().to_string(); let targets = params.targets.unwrap(); @@ -44,11 +44,7 @@ fn check_targets(input: &Input, module: &mut naga::Module, source_code: Option<& .subgroup_operations(subgroup_operations) .validate(module) .unwrap_or_else(|err| { - panic!( - "Naga module validation failed on test `{}`:\n{:?}", - name.display(), - err - ); + panic!("Naga module validation failed on test `{name}`:\n{err:?}"); }); let info = { @@ -73,11 +69,7 @@ fn check_targets(input: &Input, module: &mut naga::Module, source_code: Option<& .subgroup_operations(subgroup_operations) .validate(module) .unwrap_or_else(|err| { - panic!( - "Post-compaction module validation failed on test '{}':\n<{:?}", - name.display(), - err, - ) + panic!("Post-compaction module validation failed on test '{name}':\n<{err:?}") }) }; @@ -94,7 +86,7 @@ fn check_targets(input: &Input, module: &mut naga::Module, source_code: Option<& if let Some(source_code) = source_code { debug_info = Some(naga::back::spv::DebugInfo { source_code, - file_name: name.as_path().into(), + file_name: &name, // wgpu#6266: we technically know all the information here to // produce the valid language but it's not too important for // validation purposes diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 17d075c3810..1a710cb2d99 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -896,7 +896,7 @@ impl super::Device { if let Some(ref debug) = naga_shader.debug_source { temp_options.debug_info = Some(naga::back::spv::DebugInfo { source_code: &debug.source_code, - file_name: debug.file_name.as_ref().into(), + file_name: debug.file_name.as_ref(), language: naga::back::spv::SourceLanguage::WGSL, }) } @@ -1932,7 +1932,7 @@ impl crate::Device for super::Device { .as_ref() .map(|d| naga::back::spv::DebugInfo { source_code: d.source_code.as_ref(), - file_name: d.file_name.as_ref().into(), + file_name: d.file_name.as_ref(), language: naga::back::spv::SourceLanguage::WGSL, }); if !desc.runtime_checks.bounds_checks { From 333f811e9c8eae3eaff8f68fec7c0a06db71a2b1 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Thu, 2 Oct 2025 00:08:07 +0200 Subject: [PATCH 274/303] Rework `wgpu::PollType` to only two enum variants (#8285) --- CHANGELOG.md | 41 ++++++- benches/benches/wgpu-benchmark/bind_groups.rs | 2 +- benches/benches/wgpu-benchmark/computepass.rs | 6 +- benches/benches/wgpu-benchmark/renderpass.rs | 6 +- .../wgpu-benchmark/resource_creation.rs | 5 +- deno_webgpu/buffer.rs | 2 +- deno_webgpu/device.rs | 2 +- deno_webgpu/queue.rs | 2 +- .../features/src/big_compute_buffers/mod.rs | 2 +- examples/features/src/framework.rs | 4 +- .../features/src/hello_synchronization/mod.rs | 2 +- examples/features/src/hello_workgroups/mod.rs | 2 +- examples/features/src/mipmap/mod.rs | 2 +- examples/features/src/ray_shadows/mod.rs | 2 +- .../features/src/render_to_texture/mod.rs | 2 +- examples/features/src/repeated_compute/mod.rs | 5 +- examples/features/src/storage_texture/mod.rs | 2 +- .../features/src/timestamp_queries/mod.rs | 2 +- .../standalone/01_hello_compute/src/main.rs | 2 +- player/src/bin/play.rs | 8 +- player/tests/player/main.rs | 8 +- tests/src/image.rs | 2 +- tests/tests/wgpu-gpu/bgra8unorm_storage.rs | 4 +- tests/tests/wgpu-gpu/bind_groups.rs | 2 +- tests/tests/wgpu-gpu/binding_array/buffers.rs | 2 +- .../tests/wgpu-gpu/binding_array/samplers.rs | 2 +- tests/tests/wgpu-gpu/buffer.rs | 20 +++- tests/tests/wgpu-gpu/buffer_usages.rs | 4 +- tests/tests/wgpu-gpu/clip_distances.rs | 4 +- tests/tests/wgpu-gpu/cloneable_types.rs | 4 +- .../tests/wgpu-gpu/compute_pass_ownership.rs | 20 +++- tests/tests/wgpu-gpu/device.rs | 2 +- .../wgpu-gpu/dispatch_workgroups_indirect.rs | 4 +- tests/tests/wgpu-gpu/draw_indirect.rs | 8 +- tests/tests/wgpu-gpu/external_image_copy.rs | 4 +- tests/tests/wgpu-gpu/external_texture/mod.rs | 12 +- tests/tests/wgpu-gpu/life_cycle.rs | 28 +++-- tests/tests/wgpu-gpu/mem_leaks.rs | 9 +- tests/tests/wgpu-gpu/mesh_shader/mod.rs | 8 +- tests/tests/wgpu-gpu/occlusion_query/mod.rs | 4 +- tests/tests/wgpu-gpu/oob_indexing.rs | 8 +- tests/tests/wgpu-gpu/pipeline_cache.rs | 4 +- tests/tests/wgpu-gpu/poll.rs | 107 +++++++++++++++--- tests/tests/wgpu-gpu/push_constants.rs | 8 +- tests/tests/wgpu-gpu/queue_transfer.rs | 2 +- tests/tests/wgpu-gpu/ray_tracing/as_build.rs | 2 +- .../wgpu-gpu/ray_tracing/as_use_after_free.rs | 4 +- tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs | 4 +- tests/tests/wgpu-gpu/regression/issue_3457.rs | 2 +- tests/tests/wgpu-gpu/regression/issue_4024.rs | 2 +- tests/tests/wgpu-gpu/regression/issue_4122.rs | 4 +- tests/tests/wgpu-gpu/regression/issue_6827.rs | 2 +- tests/tests/wgpu-gpu/render_pass_ownership.rs | 20 +++- tests/tests/wgpu-gpu/render_target.rs | 8 +- tests/tests/wgpu-gpu/samplers.rs | 8 +- .../wgpu-gpu/shader/array_size_overrides.rs | 2 +- tests/tests/wgpu-gpu/shader/mod.rs | 2 +- .../shader/workgroup_size_overrides.rs | 2 +- .../shader/zero_init_workgroup_mem.rs | 2 +- .../tests/wgpu-gpu/shader_view_format/mod.rs | 4 +- tests/tests/wgpu-gpu/texture_binding/mod.rs | 2 +- .../wgpu-gpu/timestamp_normalization/utils.rs | 4 +- tests/tests/wgpu-gpu/timestamp_query.rs | 4 +- tests/tests/wgpu-gpu/vertex_formats/mod.rs | 8 +- tests/tests/wgpu-gpu/vertex_indices/mod.rs | 8 +- tests/tests/wgpu-gpu/vertex_state.rs | 4 +- tests/tests/wgpu-gpu/write_texture.rs | 10 +- .../wgpu-validation/api/buffer_mapping.rs | 6 +- .../api/command_buffer_actions.rs | 12 +- tests/tests/wgpu-validation/noop.rs | 2 +- wgpu-core/src/device/global.rs | 5 +- wgpu-core/src/device/resource.rs | 20 +++- wgpu-types/src/lib.rs | 69 ++++------- wgpu/src/api/blas.rs | 3 +- 74 files changed, 416 insertions(+), 190 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66c36cd5c6c..f3b25c8ffeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -158,6 +158,44 @@ by if the `Feature::MULTI_DRAW_INDIRECT_COUNT` feature is available on the devic By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). + +#### `wgpu::PollType::Wait` has now an optional timeout + +We removed `wgpu::PollType::WaitForSubmissionIndex` and added fields to `wgpu::PollType::Wait` in order to express timeouts. + +Before/after for `wgpu::PollType::Wait`: + +```diff +-device.poll(wgpu::PollType::Wait).unwrap(); +-device.poll(wgpu::PollType::wait_indefinitely()).unwrap(); ++device.poll(wgpu::PollType::Wait { ++ submission_index: None, // Wait for most recent submission ++ timeout: Some(std::time::Duration::from_secs(60)), // Previous behavior, but more likely you want `None` instead. ++ }) ++ .unwrap(); +``` + +Before/after for `wgpu::PollType::WaitForSubmissionIndex`: + +```diff +-device.poll(wgpu::PollType::WaitForSubmissionIndex(index_to_wait_on)) ++device.poll(wgpu::PollType::Wait { ++ submission_index: Some(index_to_wait_on), ++ timeout: Some(std::time::Duration::from_secs(60)), // Previous behavior, but more likely you want `None` instead. ++ }) ++ .unwrap(); +``` + +⚠️ Previously, both `wgpu::PollType::WaitForSubmissionIndex` and `wgpu::PollType::Wait` had a hard-coded timeout of 60 seconds. + + +To wait indefinitely on the latest submission, you can also use the `wait_indefinitely` convenience function: +```rust +device.poll(wgpu::PollType::wait_indefinitely()); +``` + +By @wumpf in [#8282](https://github.com/gfx-rs/wgpu/pull/8282), [#8285](https://github.com/gfx-rs/wgpu/pull/8285) + ### New Features #### General @@ -165,7 +203,7 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). - Added mesh shader support to `wgpu`, with examples. Requires passthrough. By @SupaMaggie70Incorporated in [#7345](https://github.com/gfx-rs/wgpu/pull/7345). - Added support for external textures based on WebGPU's [`GPUExternalTexture`](https://www.w3.org/TR/webgpu/#gpuexternaltexture). These allow shaders to transparently operate on potentially multiplanar source texture data in either RGB or YCbCr formats via WGSL's `texture_external` type. This is gated behind the `Features::EXTERNAL_TEXTURE` feature, which is currently only supported on DX12. By @jamienicol in [#4386](https://github.com/gfx-rs/wgpu/issues/4386). -- `wgpu::Device::poll` can now specify a timeout via `wgpu::PollType::WaitWithTimeout`/`wgpu::PollType::WaitForSubmissionIndexWithTimeout`. By @wumpf in [#8282](https://github.com/gfx-rs/wgpu/pull/8282) +- `wgpu::Device::poll` can now specify a timeout via `wgpu::PollType::Wait`. By @wumpf in [#8282](https://github.com/gfx-rs/wgpu/pull/8282) & [#8285](https://github.com/gfx-rs/wgpu/pull/8285) #### naga @@ -195,7 +233,6 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). - Require new `F16_IN_F32` downlevel flag for `quantizeToF16`, `pack2x16float`, and `unpack2x16float` in WGSL input. By @aleiserson in [#8130](https://github.com/gfx-rs/wgpu/pull/8130). - The error message for non-copyable depth/stencil formats no longer mentions the aspect when it is not relevant. By @reima in [#8156](https://github.com/gfx-rs/wgpu/pull/8156). - Track the initialization status of buffer memory correctly when `copy_texture_to_buffer` skips over padding space between rows or layers, or when the start/end of a texture-buffer transfer is not 4B aligned. By @andyleiserson in [#8099](https://github.com/gfx-rs/wgpu/pull/8099). -- `wgpu::PollType::Wait`/`wgpu::PollType::WaitForSubmissionIndex` will no longer timeout after 60 seconds, but instead wait indefinitely or (depending on backend implementation) until an error is encountered. Use `wgpu::PollType::WaitWithTimeout`/`wgpu::PollType::WaitForSubmissionIndexWithTimeout` if you need a timeout. By @wumpf in [#8282](https://github.com/gfx-rs/wgpu/pull/8282) #### naga diff --git a/benches/benches/wgpu-benchmark/bind_groups.rs b/benches/benches/wgpu-benchmark/bind_groups.rs index 50245d441bd..cd2ad451a5a 100644 --- a/benches/benches/wgpu-benchmark/bind_groups.rs +++ b/benches/benches/wgpu-benchmark/bind_groups.rs @@ -155,7 +155,7 @@ fn run_bench(ctx: &mut Criterion) { state .device_state .device - .poll(wgpu::PollType::Wait) + .poll(wgpu::PollType::wait_indefinitely()) .unwrap(); } diff --git a/benches/benches/wgpu-benchmark/computepass.rs b/benches/benches/wgpu-benchmark/computepass.rs index 9254547a1de..ed881641662 100644 --- a/benches/benches/wgpu-benchmark/computepass.rs +++ b/benches/benches/wgpu-benchmark/computepass.rs @@ -489,7 +489,7 @@ fn run_bench(ctx: &mut Criterion) { state .device_state .device - .poll(wgpu::PollType::Wait) + .poll(wgpu::PollType::wait_indefinitely()) .unwrap(); } @@ -538,7 +538,7 @@ fn run_bench(ctx: &mut Criterion) { state .device_state .device - .poll(wgpu::PollType::Wait) + .poll(wgpu::PollType::wait_indefinitely()) .unwrap(); } @@ -584,7 +584,7 @@ fn run_bench(ctx: &mut Criterion) { state .device_state .device - .poll(wgpu::PollType::Wait) + .poll(wgpu::PollType::wait_indefinitely()) .unwrap(); } diff --git a/benches/benches/wgpu-benchmark/renderpass.rs b/benches/benches/wgpu-benchmark/renderpass.rs index 946c32bfe40..07700d68fce 100644 --- a/benches/benches/wgpu-benchmark/renderpass.rs +++ b/benches/benches/wgpu-benchmark/renderpass.rs @@ -497,7 +497,7 @@ fn run_bench(ctx: &mut Criterion) { state .device_state .device - .poll(wgpu::PollType::Wait) + .poll(wgpu::PollType::wait_indefinitely()) .unwrap(); } @@ -544,7 +544,7 @@ fn run_bench(ctx: &mut Criterion) { state .device_state .device - .poll(wgpu::PollType::Wait) + .poll(wgpu::PollType::wait_indefinitely()) .unwrap(); } @@ -584,7 +584,7 @@ fn run_bench(ctx: &mut Criterion) { state .device_state .device - .poll(wgpu::PollType::Wait) + .poll(wgpu::PollType::wait_indefinitely()) .unwrap(); } diff --git a/benches/benches/wgpu-benchmark/resource_creation.rs b/benches/benches/wgpu-benchmark/resource_creation.rs index bbbfc3d2e31..7f23dd15c8d 100644 --- a/benches/benches/wgpu-benchmark/resource_creation.rs +++ b/benches/benches/wgpu-benchmark/resource_creation.rs @@ -61,7 +61,10 @@ fn run_bench(ctx: &mut Criterion) { drop(buffers); state.queue.submit([]); - state.device.poll(wgpu::PollType::Wait).unwrap(); + state + .device + .poll(wgpu::PollType::wait_indefinitely()) + .unwrap(); } duration diff --git a/deno_webgpu/buffer.rs b/deno_webgpu/buffer.rs index b975c319acc..25b448a0aa5 100644 --- a/deno_webgpu/buffer.rs +++ b/deno_webgpu/buffer.rs @@ -177,7 +177,7 @@ impl GPUBuffer { { self .instance - .device_poll(self.device, wgpu_types::PollType::wait()) + .device_poll(self.device, wgpu_types::PollType::wait_indefinitely()) .unwrap(); } tokio::time::sleep(Duration::from_millis(10)).await; diff --git a/deno_webgpu/device.rs b/deno_webgpu/device.rs index cc198b652d2..b59fc633cd4 100644 --- a/deno_webgpu/device.rs +++ b/deno_webgpu/device.rs @@ -685,7 +685,7 @@ impl GPUDevice { fn stop_capture(&self) { self .instance - .device_poll(self.id, wgpu_types::PollType::wait()) + .device_poll(self.id, wgpu_types::PollType::wait_indefinitely()) .unwrap(); unsafe { self.instance.device_stop_graphics_debugger_capture(self.id) }; } diff --git a/deno_webgpu/queue.rs b/deno_webgpu/queue.rs index 2658aed706b..dee47927f47 100644 --- a/deno_webgpu/queue.rs +++ b/deno_webgpu/queue.rs @@ -103,7 +103,7 @@ impl GPUQueue { { self .instance - .device_poll(self.device, wgpu_types::PollType::wait()) + .device_poll(self.device, wgpu_types::PollType::wait_indefinitely()) .unwrap(); } tokio::time::sleep(Duration::from_millis(10)).await; diff --git a/examples/features/src/big_compute_buffers/mod.rs b/examples/features/src/big_compute_buffers/mod.rs index 5a4399fe7c0..7a4f658f73a 100644 --- a/examples/features/src/big_compute_buffers/mod.rs +++ b/examples/features/src/big_compute_buffers/mod.rs @@ -80,7 +80,7 @@ pub async fn execute_gpu_inner( slice.map_async(wgpu::MapMode::Read, |_| {}); } - device.poll(wgpu::PollType::Wait).unwrap(); + device.poll(wgpu::PollType::wait_indefinitely()).unwrap(); let mut data = Vec::new(); for staging_buffer in &staging_buffers { diff --git a/examples/features/src/framework.rs b/examples/features/src/framework.rs index 02e92a1319d..2db0cc4a56a 100644 --- a/examples/features/src/framework.rs +++ b/examples/features/src/framework.rs @@ -597,7 +597,9 @@ impl From> let dst_buffer_slice = dst_buffer.slice(..); dst_buffer_slice.map_async(wgpu::MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let bytes = dst_buffer_slice.get_mapped_range().to_vec(); wgpu_test::image::compare_image_output( diff --git a/examples/features/src/hello_synchronization/mod.rs b/examples/features/src/hello_synchronization/mod.rs index e7061004771..ea41e4944b7 100644 --- a/examples/features/src/hello_synchronization/mod.rs +++ b/examples/features/src/hello_synchronization/mod.rs @@ -182,7 +182,7 @@ async fn get_data( let buffer_slice = staging_buffer.slice(..); let (sender, receiver) = flume::bounded(1); buffer_slice.map_async(wgpu::MapMode::Read, move |r| sender.send(r).unwrap()); - device.poll(wgpu::PollType::wait()).unwrap(); + device.poll(wgpu::PollType::wait_indefinitely()).unwrap(); receiver.recv_async().await.unwrap().unwrap(); output.copy_from_slice(bytemuck::cast_slice(&buffer_slice.get_mapped_range()[..])); staging_buffer.unmap(); diff --git a/examples/features/src/hello_workgroups/mod.rs b/examples/features/src/hello_workgroups/mod.rs index ee2c6fe5948..a3f3885a9ce 100644 --- a/examples/features/src/hello_workgroups/mod.rs +++ b/examples/features/src/hello_workgroups/mod.rs @@ -171,7 +171,7 @@ async fn get_data( let buffer_slice = staging_buffer.slice(..); let (sender, receiver) = flume::bounded(1); buffer_slice.map_async(wgpu::MapMode::Read, move |r| sender.send(r).unwrap()); - device.poll(wgpu::PollType::wait()).unwrap(); + device.poll(wgpu::PollType::wait_indefinitely()).unwrap(); receiver.recv_async().await.unwrap().unwrap(); output.copy_from_slice(bytemuck::cast_slice(&buffer_slice.get_mapped_range()[..])); staging_buffer.unmap(); diff --git a/examples/features/src/mipmap/mod.rs b/examples/features/src/mipmap/mod.rs index 5e5cc3d34e0..3875bc3a76a 100644 --- a/examples/features/src/mipmap/mod.rs +++ b/examples/features/src/mipmap/mod.rs @@ -411,7 +411,7 @@ impl crate::framework::Example for Example { .slice(..) .map_async(wgpu::MapMode::Read, |_| ()); // Wait for device to be done rendering mipmaps - device.poll(wgpu::PollType::wait()).unwrap(); + device.poll(wgpu::PollType::wait_indefinitely()).unwrap(); // This is guaranteed to be ready. let timestamp_view = query_sets .mapping_buffer diff --git a/examples/features/src/ray_shadows/mod.rs b/examples/features/src/ray_shadows/mod.rs index 559ac32342a..d4d1cabe4b6 100644 --- a/examples/features/src/ray_shadows/mod.rs +++ b/examples/features/src/ray_shadows/mod.rs @@ -360,7 +360,7 @@ impl crate::framework::Example for Example { rpass.draw_indexed(0..12, 0, 0..1); } queue.submit(Some(encoder.finish())); - device.poll(wgpu::PollType::Wait).unwrap(); + device.poll(wgpu::PollType::wait_indefinitely()).unwrap(); } } diff --git a/examples/features/src/render_to_texture/mod.rs b/examples/features/src/render_to_texture/mod.rs index 7981f665506..923434dbae6 100644 --- a/examples/features/src/render_to_texture/mod.rs +++ b/examples/features/src/render_to_texture/mod.rs @@ -132,7 +132,7 @@ async fn run(_path: Option) { let buffer_slice = output_staging_buffer.slice(..); let (sender, receiver) = flume::bounded(1); buffer_slice.map_async(wgpu::MapMode::Read, move |r| sender.send(r).unwrap()); - device.poll(wgpu::PollType::wait()).unwrap(); + device.poll(wgpu::PollType::wait_indefinitely()).unwrap(); receiver.recv_async().await.unwrap().unwrap(); log::info!("Output buffer mapped."); { diff --git a/examples/features/src/repeated_compute/mod.rs b/examples/features/src/repeated_compute/mod.rs index 77e5f9c5114..414a53390d1 100644 --- a/examples/features/src/repeated_compute/mod.rs +++ b/examples/features/src/repeated_compute/mod.rs @@ -105,7 +105,10 @@ async fn compute(local_buffer: &mut [u32], context: &WgpuContext) { // One of those can be calling `Device::poll`. This isn't necessary on the web as devices // are polled automatically but natively, we need to make sure this happens manually. // `PollType::Wait` will cause the thread to wait on native but not on WebGpu. - context.device.poll(wgpu::PollType::wait()).unwrap(); + context + .device + .poll(wgpu::PollType::wait_indefinitely()) + .unwrap(); log::info!("Device polled."); // Now we await the receiving and panic if anything went wrong because we're lazy. receiver.recv_async().await.unwrap().unwrap(); diff --git a/examples/features/src/storage_texture/mod.rs b/examples/features/src/storage_texture/mod.rs index 07c3d48f7fa..7db46770ecd 100644 --- a/examples/features/src/storage_texture/mod.rs +++ b/examples/features/src/storage_texture/mod.rs @@ -142,7 +142,7 @@ async fn run(_path: Option) { let buffer_slice = output_staging_buffer.slice(..); let (sender, receiver) = flume::bounded(1); buffer_slice.map_async(wgpu::MapMode::Read, move |r| sender.send(r).unwrap()); - device.poll(wgpu::PollType::wait()).unwrap(); + device.poll(wgpu::PollType::wait_indefinitely()).unwrap(); receiver.recv_async().await.unwrap().unwrap(); log::info!("Output buffer mapped"); { diff --git a/examples/features/src/timestamp_queries/mod.rs b/examples/features/src/timestamp_queries/mod.rs index 2531cc4e692..9d7b6cbc62f 100644 --- a/examples/features/src/timestamp_queries/mod.rs +++ b/examples/features/src/timestamp_queries/mod.rs @@ -161,7 +161,7 @@ impl Queries { self.destination_buffer .slice(..) .map_async(wgpu::MapMode::Read, |_| ()); - device.poll(wgpu::PollType::wait()).unwrap(); + device.poll(wgpu::PollType::wait_indefinitely()).unwrap(); let timestamps = { let timestamp_view = self diff --git a/examples/standalone/01_hello_compute/src/main.rs b/examples/standalone/01_hello_compute/src/main.rs index e9035c034db..35b6b3c697a 100644 --- a/examples/standalone/01_hello_compute/src/main.rs +++ b/examples/standalone/01_hello_compute/src/main.rs @@ -242,7 +242,7 @@ fn main() { // Wait for the GPU to finish working on the submitted work. This doesn't work on WebGPU, so we would need // to rely on the callback to know when the buffer is mapped. - device.poll(wgpu::PollType::Wait).unwrap(); + device.poll(wgpu::PollType::wait_indefinitely()).unwrap(); // We can now read the data from the buffer. let data = buffer_slice.get_mapped_range(); diff --git a/player/src/bin/play.rs b/player/src/bin/play.rs index a053e932f04..dfce80b8ad4 100644 --- a/player/src/bin/play.rs +++ b/player/src/bin/play.rs @@ -134,7 +134,9 @@ fn main() { } unsafe { global.device_stop_graphics_debugger_capture(device) }; - global.device_poll(device, wgt::PollType::wait()).unwrap(); + global + .device_poll(device, wgt::PollType::wait_indefinitely()) + .unwrap(); } #[cfg(feature = "winit")] { @@ -227,7 +229,9 @@ fn main() { }, Event::LoopExiting => { log::info!("Closing"); - global.device_poll(device, wgt::PollType::wait()).unwrap(); + global + .device_poll(device, wgt::PollType::wait_indefinitely()) + .unwrap(); } _ => {} } diff --git a/player/tests/player/main.rs b/player/tests/player/main.rs index 3f57829183d..700a6739048 100644 --- a/player/tests/player/main.rs +++ b/player/tests/player/main.rs @@ -136,7 +136,13 @@ impl Test<'_> { println!("\t\t\tWaiting..."); global - .device_poll(device_id, wgt::PollType::wait()) + .device_poll( + device_id, + wgt::PollType::Wait { + submission_index: None, + timeout: Some(std::time::Duration::from_secs(1)), // Tests really shouldn't need longer than that! + }, + ) .unwrap(); for expect in self.expectations { diff --git a/tests/src/image.rs b/tests/src/image.rs index 94924757fab..93a0fb0b47a 100644 --- a/tests/src/image.rs +++ b/tests/src/image.rs @@ -577,7 +577,7 @@ impl ReadbackBuffers { ) -> Vec { let buffer_slice = buffer.slice(..); buffer_slice.map_async(MapMode::Read, |_| ()); - ctx.async_poll(PollType::wait()).await.unwrap(); + ctx.async_poll(PollType::wait_indefinitely()).await.unwrap(); let (block_width, block_height) = self.texture_format.block_dimensions(); let expected_bytes_per_row = (self.texture_width / block_width) * self.texture_format.block_copy_size(aspect).unwrap_or(4); diff --git a/tests/tests/wgpu-gpu/bgra8unorm_storage.rs b/tests/tests/wgpu-gpu/bgra8unorm_storage.rs index 87ae3e62f3d..82f2b912cf4 100644 --- a/tests/tests/wgpu-gpu/bgra8unorm_storage.rs +++ b/tests/tests/wgpu-gpu/bgra8unorm_storage.rs @@ -146,7 +146,9 @@ static BGRA8_UNORM_STORAGE: GpuTestConfiguration = GpuTestConfiguration::new() let buffer_slice = readback_buffer.slice(..); buffer_slice.map_async(wgpu::MapMode::Read, Result::unwrap); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); { let texels = buffer_slice.get_mapped_range(); diff --git a/tests/tests/wgpu-gpu/bind_groups.rs b/tests/tests/wgpu-gpu/bind_groups.rs index c8b0acad57f..a6924d34ead 100644 --- a/tests/tests/wgpu-gpu/bind_groups.rs +++ b/tests/tests/wgpu-gpu/bind_groups.rs @@ -125,7 +125,7 @@ fn multiple_bindings_with_differing_sizes(ctx: TestingContext) { ctx.queue.write_buffer(&buffer, 0, &data); ctx.queue.submit(Some(encoder.finish())); - ctx.device.poll(PollType::Wait).unwrap(); + ctx.device.poll(PollType::wait_indefinitely()).unwrap(); } /// Test `descriptor` against a bind group layout that requires non-filtering sampler. diff --git a/tests/tests/wgpu-gpu/binding_array/buffers.rs b/tests/tests/wgpu-gpu/binding_array/buffers.rs index 9a9701f12a3..0e3b3166a49 100644 --- a/tests/tests/wgpu-gpu/binding_array/buffers.rs +++ b/tests/tests/wgpu-gpu/binding_array/buffers.rs @@ -265,7 +265,7 @@ async fn binding_array_buffers( let slice = readback_buffer.slice(..); slice.map_async(MapMode::Read, |_| {}); - ctx.device.poll(PollType::Wait).unwrap(); + ctx.device.poll(PollType::wait_indefinitely()).unwrap(); let data = slice.get_mapped_range(); diff --git a/tests/tests/wgpu-gpu/binding_array/samplers.rs b/tests/tests/wgpu-gpu/binding_array/samplers.rs index 636a5487697..d8dfefe21fe 100644 --- a/tests/tests/wgpu-gpu/binding_array/samplers.rs +++ b/tests/tests/wgpu-gpu/binding_array/samplers.rs @@ -251,7 +251,7 @@ async fn binding_array_samplers(ctx: TestingContext, partially_bound: bool) { ctx.queue.submit(Some(encoder.finish())); readback_buffer.slice(..).map_async(MapMode::Read, |_| {}); - ctx.device.poll(PollType::Wait).unwrap(); + ctx.device.poll(PollType::wait_indefinitely()).unwrap(); let readback_buffer_slice = readback_buffer.slice(..).get_mapped_range(); diff --git a/tests/tests/wgpu-gpu/buffer.rs b/tests/tests/wgpu-gpu/buffer.rs index 3ae848ed529..741b34bb3bc 100644 --- a/tests/tests/wgpu-gpu/buffer.rs +++ b/tests/tests/wgpu-gpu/buffer.rs @@ -27,7 +27,9 @@ async fn test_empty_buffer_range(ctx: &TestingContext, buffer_size: u64, label: b0.slice(0..0) .map_async(wgpu::MapMode::Read, Result::unwrap); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); { let view = b0.slice(0..0).get_mapped_range(); @@ -61,7 +63,9 @@ async fn test_empty_buffer_range(ctx: &TestingContext, buffer_size: u64, label: b0.slice(0..0) .map_async(wgpu::MapMode::Write, Result::unwrap); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); //{ // let view = b0.slice(0..0).get_mapped_range_mut(); @@ -90,7 +94,9 @@ async fn test_empty_buffer_range(ctx: &TestingContext, buffer_size: u64, label: b1.unmap(); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); } #[gpu_test] @@ -135,7 +141,9 @@ static MAP_OFFSET: GpuTestConfiguration = GpuTestConfiguration::new() result.unwrap(); }); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); { let slice = write_buf.slice(32..48); @@ -159,7 +167,9 @@ static MAP_OFFSET: GpuTestConfiguration = GpuTestConfiguration::new() .slice(..) .map_async(wgpu::MapMode::Read, Result::unwrap); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let slice = read_buf.slice(..); let view = slice.get_mapped_range(); diff --git a/tests/tests/wgpu-gpu/buffer_usages.rs b/tests/tests/wgpu-gpu/buffer_usages.rs index f4ee67bafaf..b0a65583b7a 100644 --- a/tests/tests/wgpu-gpu/buffer_usages.rs +++ b/tests/tests/wgpu-gpu/buffer_usages.rs @@ -155,7 +155,9 @@ async fn map_test( buffer.destroy(); } - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); if !before_unmap && !before_destroy { { diff --git a/tests/tests/wgpu-gpu/clip_distances.rs b/tests/tests/wgpu-gpu/clip_distances.rs index 3152333e8dd..bbdd2d539ff 100644 --- a/tests/tests/wgpu-gpu/clip_distances.rs +++ b/tests/tests/wgpu-gpu/clip_distances.rs @@ -123,7 +123,9 @@ async fn clip_distances(ctx: TestingContext) { ctx.queue.submit([encoder.finish()]); let slice = readback_buffer.slice(..); slice.map_async(wgpu::MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let data: &[u8] = &slice.get_mapped_range(); // We should have filled the upper sector of the texture. Verify that this is the case. diff --git a/tests/tests/wgpu-gpu/cloneable_types.rs b/tests/tests/wgpu-gpu/cloneable_types.rs index cf09d24fffa..fd578f6cc92 100644 --- a/tests/tests/wgpu-gpu/cloneable_types.rs +++ b/tests/tests/wgpu-gpu/cloneable_types.rs @@ -40,7 +40,9 @@ fn cloneable_buffers(ctx: TestingContext) { assert_eq!(&*data, &cloned_buffer_contents); }); - ctx.device.poll(wgpu::PollType::Wait).unwrap(); + ctx.device + .poll(wgpu::PollType::wait_indefinitely()) + .unwrap(); let data = buffer.slice(..).get_mapped_range(); diff --git a/tests/tests/wgpu-gpu/compute_pass_ownership.rs b/tests/tests/wgpu-gpu/compute_pass_ownership.rs index 2903a517ce5..48f3ee4197c 100644 --- a/tests/tests/wgpu-gpu/compute_pass_ownership.rs +++ b/tests/tests/wgpu-gpu/compute_pass_ownership.rs @@ -63,7 +63,9 @@ async fn compute_pass_resource_ownership(ctx: TestingContext) { drop(pipeline); drop(bind_group); drop(indirect_buffer); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); } assert_compute_pass_executed_normally(encoder, gpu_buffer, cpu_buffer, buffer_size, ctx).await; @@ -111,7 +113,9 @@ async fn compute_pass_query_set_ownership_pipeline_statistics(ctx: TestingContex // Drop the query set. Then do a device poll to make sure it's not dropped too early, no matter what. drop(query_set); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); } assert_compute_pass_executed_normally(encoder, gpu_buffer, cpu_buffer, buffer_size, ctx).await; @@ -167,7 +171,9 @@ async fn compute_pass_query_set_ownership_timestamps(ctx: TestingContext) { // Drop the query sets. Then do a device poll to make sure they're not dropped too early, no matter what. drop(query_set_timestamp_writes); drop(query_set_write_timestamp); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); } assert_compute_pass_executed_normally(encoder, gpu_buffer, cpu_buffer, buffer_size, ctx).await; @@ -206,7 +212,9 @@ async fn compute_pass_keep_encoder_alive(ctx: TestingContext) { let mut cpass = cpass.forget_lifetime(); drop(encoder); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); // Record some draw commands. cpass.set_pipeline(&pipeline); @@ -230,7 +238,9 @@ async fn assert_compute_pass_executed_normally( encoder.copy_buffer_to_buffer(&gpu_buffer, 0, &cpu_buffer, 0, buffer_size); ctx.queue.submit([encoder.finish()]); cpu_buffer.slice(..).map_async(wgpu::MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let data = cpu_buffer.slice(..).get_mapped_range(); diff --git a/tests/tests/wgpu-gpu/device.rs b/tests/tests/wgpu-gpu/device.rs index 5accb3d33b8..7e9d4204ccd 100644 --- a/tests/tests/wgpu-gpu/device.rs +++ b/tests/tests/wgpu-gpu/device.rs @@ -504,7 +504,7 @@ static DEVICE_DESTROY_THEN_LOST: GpuTestConfiguration = GpuTestConfiguration::ne // Make sure the device queues are empty, which ensures that the closure // has been called. assert!(ctx - .async_poll(wgpu::PollType::wait()) + .async_poll(wgpu::PollType::wait_indefinitely()) .await .unwrap() .is_queue_empty()); diff --git a/tests/tests/wgpu-gpu/dispatch_workgroups_indirect.rs b/tests/tests/wgpu-gpu/dispatch_workgroups_indirect.rs index 24a38604f24..f665440fb4a 100644 --- a/tests/tests/wgpu-gpu/dispatch_workgroups_indirect.rs +++ b/tests/tests/wgpu-gpu/dispatch_workgroups_indirect.rs @@ -312,7 +312,9 @@ async fn run_test(ctx: &TestingContext, num_workgroups: &[u32; 3]) -> [u32; 3] { .slice(..) .map_async(wgpu::MapMode::Read, |_| {}); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let view = test_resources.readback_buffer.slice(..).get_mapped_range(); diff --git a/tests/tests/wgpu-gpu/draw_indirect.rs b/tests/tests/wgpu-gpu/draw_indirect.rs index a0c8253be0b..e33ccb83ab7 100644 --- a/tests/tests/wgpu-gpu/draw_indirect.rs +++ b/tests/tests/wgpu-gpu/draw_indirect.rs @@ -322,7 +322,9 @@ async fn run_test(ctx: TestingContext, test_data: TestData, expect_noop: bool) { let slice = readback_buffer.slice(..); slice.map_async(wgpu::MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let data = slice.get_mapped_range(); let succeeded = if expect_noop { @@ -782,7 +784,9 @@ async fn indirect_buffer_offsets(ctx: TestingContext) { let slice = readback_buffer.slice(..); slice.map_async(wgpu::MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let data = slice.get_mapped_range(); let half = data.len() / 2; diff --git a/tests/tests/wgpu-gpu/external_image_copy.rs b/tests/tests/wgpu-gpu/external_image_copy.rs index 78d95882608..044e2632425 100644 --- a/tests/tests/wgpu-gpu/external_image_copy.rs +++ b/tests/tests/wgpu-gpu/external_image_copy.rs @@ -328,7 +328,9 @@ static IMAGE_BITMAP_IMPORT: GpuTestConfiguration = readback_buffer .slice(..) .map_async(wgpu::MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let buffer = readback_buffer.slice(..).get_mapped_range(); diff --git a/tests/tests/wgpu-gpu/external_texture/mod.rs b/tests/tests/wgpu-gpu/external_texture/mod.rs index 4b22bdee15f..7df1cc1d648 100644 --- a/tests/tests/wgpu-gpu/external_texture/mod.rs +++ b/tests/tests/wgpu-gpu/external_texture/mod.rs @@ -223,7 +223,9 @@ fn get_dimensions(ctx: &TestingContext, texture_resource: wgpu::BindingResource) ctx.queue.submit(Some(encoder.finish())); let buffer_slice = download_buffer.slice(..); buffer_slice.map_async(wgpu::MapMode::Read, |_| {}); - ctx.device.poll(wgpu::PollType::Wait).unwrap(); + ctx.device + .poll(wgpu::PollType::wait_indefinitely()) + .unwrap(); let data = buffer_slice.get_mapped_range(); let size: &[u32] = bytemuck::cast_slice(&data); @@ -306,7 +308,9 @@ fn get_loads( ctx.queue.submit(Some(encoder.finish())); let buffer_slice = download_buffer.slice(..); buffer_slice.map_async(wgpu::MapMode::Read, |_| {}); - ctx.device.poll(wgpu::PollType::Wait).unwrap(); + ctx.device + .poll(wgpu::PollType::wait_indefinitely()) + .unwrap(); let data = buffer_slice.get_mapped_range(); let values: &[[f32; 4]] = bytemuck::cast_slice(&data); @@ -397,7 +401,9 @@ fn get_samples( ctx.queue.submit(Some(encoder.finish())); let buffer_slice = download_buffer.slice(..); buffer_slice.map_async(wgpu::MapMode::Read, |_| {}); - ctx.device.poll(wgpu::PollType::Wait).unwrap(); + ctx.device + .poll(wgpu::PollType::wait_indefinitely()) + .unwrap(); let data = buffer_slice.get_mapped_range(); let values: &[[f32; 4]] = bytemuck::cast_slice(&data); diff --git a/tests/tests/wgpu-gpu/life_cycle.rs b/tests/tests/wgpu-gpu/life_cycle.rs index 8fd628663c5..1e5d368c578 100644 --- a/tests/tests/wgpu-gpu/life_cycle.rs +++ b/tests/tests/wgpu-gpu/life_cycle.rs @@ -25,7 +25,9 @@ static BUFFER_DESTROY: GpuTestConfiguration = GpuTestConfiguration::new() buffer.destroy(); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); fail( &ctx.device, @@ -39,7 +41,9 @@ static BUFFER_DESTROY: GpuTestConfiguration = GpuTestConfiguration::new() buffer.destroy(); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); buffer.destroy(); @@ -61,7 +65,9 @@ static BUFFER_DESTROY: GpuTestConfiguration = GpuTestConfiguration::new() } let buffer = ctx.device.create_buffer(&descriptor); buffer.destroy(); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let buffer = ctx.device.create_buffer(&descriptor); buffer.destroy(); { @@ -70,12 +76,16 @@ static BUFFER_DESTROY: GpuTestConfiguration = GpuTestConfiguration::new() let buffer = ctx.device.create_buffer(&descriptor); buffer.destroy(); let buffer = ctx.device.create_buffer(&descriptor); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); buffer.destroy(); } let buffer = ctx.device.create_buffer(&descriptor); buffer.destroy(); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); }); #[gpu_test] @@ -101,11 +111,15 @@ static TEXTURE_DESTROY: GpuTestConfiguration = GpuTestConfiguration::new() texture.destroy(); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); texture.destroy(); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); texture.destroy(); diff --git a/tests/tests/wgpu-gpu/mem_leaks.rs b/tests/tests/wgpu-gpu/mem_leaks.rs index c58981d5b1a..ada016b1f7e 100644 --- a/tests/tests/wgpu-gpu/mem_leaks.rs +++ b/tests/tests/wgpu-gpu/mem_leaks.rs @@ -267,9 +267,12 @@ async fn draw_test_with_reports( let report = global_report.hub_report(); assert_eq!(report.command_buffers.num_allocated, 0); - ctx.async_poll(wgpu::PollType::wait_for(submit_index)) - .await - .unwrap(); + ctx.async_poll(wgpu::PollType::Wait { + submission_index: Some(submit_index), + timeout: None, + }) + .await + .unwrap(); let global_report = ctx.instance.generate_report().unwrap(); let report = global_report.hub_report(); diff --git a/tests/tests/wgpu-gpu/mesh_shader/mod.rs b/tests/tests/wgpu-gpu/mesh_shader/mod.rs index 13771a1fb45..3d7f6df6068 100644 --- a/tests/tests/wgpu-gpu/mesh_shader/mod.rs +++ b/tests/tests/wgpu-gpu/mesh_shader/mod.rs @@ -223,7 +223,9 @@ fn mesh_pipeline_build(ctx: &TestingContext, info: MeshPipelineTestInfo) { pass.draw_mesh_tasks(1, 1, 1); } ctx.queue.submit(Some(encoder.finish())); - ctx.device.poll(wgpu::PollType::Wait).unwrap(); + ctx.device + .poll(wgpu::PollType::wait_indefinitely()) + .unwrap(); } } @@ -333,7 +335,9 @@ fn mesh_draw(ctx: &TestingContext, draw_type: DrawType) { pass.draw_mesh_tasks_indirect(buffer.as_ref().unwrap(), 0); } ctx.queue.submit(Some(encoder.finish())); - ctx.device.poll(wgpu::PollType::Wait).unwrap(); + ctx.device + .poll(wgpu::PollType::wait_indefinitely()) + .unwrap(); } fn default_gpu_test_config(draw_type: DrawType) -> GpuTestConfiguration { diff --git a/tests/tests/wgpu-gpu/occlusion_query/mod.rs b/tests/tests/wgpu-gpu/occlusion_query/mod.rs index a30b0dc5893..caa4f7e9d76 100644 --- a/tests/tests/wgpu-gpu/occlusion_query/mod.rs +++ b/tests/tests/wgpu-gpu/occlusion_query/mod.rs @@ -125,7 +125,9 @@ static OCCLUSION_QUERY: GpuTestConfiguration = GpuTestConfiguration::new() mapping_buffer .slice(..) .map_async(wgpu::MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let query_buffer_view = mapping_buffer.slice(..).get_mapped_range(); let query_data: &[u64; 3] = bytemuck::from_bytes(&query_buffer_view); diff --git a/tests/tests/wgpu-gpu/oob_indexing.rs b/tests/tests/wgpu-gpu/oob_indexing.rs index c5d323a8114..44901df6485 100644 --- a/tests/tests/wgpu-gpu/oob_indexing.rs +++ b/tests/tests/wgpu-gpu/oob_indexing.rs @@ -48,7 +48,9 @@ static RESTRICT_WORKGROUP_PRIVATE_FUNCTION_LET: GpuTestConfiguration = GpuTestCo .slice(..) .map_async(wgpu::MapMode::Read, |_| {}); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let view = test_resources.readback_buffer.slice(..).get_mapped_range(); @@ -449,7 +451,9 @@ async fn d3d12_restrict_dynamic_buffers(ctx: TestingContext) { .slice(..) .map_async(wgpu::MapMode::Read, |_| {}); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let view = readback_buffer.slice(..).get_mapped_range(); diff --git a/tests/tests/wgpu-gpu/pipeline_cache.rs b/tests/tests/wgpu-gpu/pipeline_cache.rs index 2d66f99d9bc..04af5b9a628 100644 --- a/tests/tests/wgpu-gpu/pipeline_cache.rs +++ b/tests/tests/wgpu-gpu/pipeline_cache.rs @@ -179,7 +179,9 @@ async fn validate_pipeline( encoder.copy_buffer_to_buffer(gpu_buffer, 0, cpu_buffer, 0, ARRAY_SIZE * 4); ctx.queue.submit([encoder.finish()]); cpu_buffer.slice(..).map_async(wgpu::MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let data = cpu_buffer.slice(..).get_mapped_range(); diff --git a/tests/tests/wgpu-gpu/poll.rs b/tests/tests/wgpu-gpu/poll.rs index 6f29313fdcc..ca9fd91adb3 100644 --- a/tests/tests/wgpu-gpu/poll.rs +++ b/tests/tests/wgpu-gpu/poll.rs @@ -14,9 +14,11 @@ pub fn all_tests(vec: &mut Vec) { vec.extend([ WAIT, WAIT_WITH_TIMEOUT, + WAIT_WITH_TIMEOUT_MAX, DOUBLE_WAIT, WAIT_ON_SUBMISSION, WAIT_ON_SUBMISSION_WITH_TIMEOUT, + WAIT_ON_SUBMISSION_WITH_TIMEOUT_MAX, DOUBLE_WAIT_ON_SUBMISSION, WAIT_OUT_OF_ORDER, WAIT_AFTER_BAD_SUBMISSION, @@ -74,7 +76,12 @@ static WAIT: GpuTestConfiguration = GpuTestConfiguration::new() let cmd_buf = generate_dummy_work(&ctx); ctx.queue.submit(Some(cmd_buf)); - ctx.async_poll(PollType::wait()).await.unwrap(); + ctx.async_poll(PollType::Wait { + submission_index: None, + timeout: None, + }) + .await + .unwrap(); }); #[gpu_test] @@ -84,9 +91,27 @@ static WAIT_WITH_TIMEOUT: GpuTestConfiguration = GpuTestConfiguration::new() let cmd_buf = generate_dummy_work(&ctx); ctx.queue.submit(Some(cmd_buf)); - ctx.async_poll(PollType::WaitWithTimeout(Duration::from_secs(1))) - .await - .unwrap(); + ctx.async_poll(PollType::Wait { + submission_index: None, + timeout: Some(Duration::from_secs(1)), + }) + .await + .unwrap(); + }); + +#[gpu_test] +static WAIT_WITH_TIMEOUT_MAX: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_async(|ctx| async move { + let cmd_buf = generate_dummy_work(&ctx); + + ctx.queue.submit(Some(cmd_buf)); + ctx.async_poll(PollType::Wait { + submission_index: None, + timeout: Some(Duration::MAX), + }) + .await + .unwrap(); }); #[gpu_test] @@ -96,8 +121,18 @@ static DOUBLE_WAIT: GpuTestConfiguration = GpuTestConfiguration::new() let cmd_buf = generate_dummy_work(&ctx); ctx.queue.submit(Some(cmd_buf)); - ctx.async_poll(PollType::wait()).await.unwrap(); - ctx.async_poll(PollType::wait()).await.unwrap(); + ctx.async_poll(PollType::Wait { + submission_index: None, + timeout: None, + }) + .await + .unwrap(); + ctx.async_poll(PollType::Wait { + submission_index: None, + timeout: None, + }) + .await + .unwrap(); }); #[gpu_test] @@ -107,7 +142,12 @@ static WAIT_ON_SUBMISSION: GpuTestConfiguration = GpuTestConfiguration::new() let cmd_buf = generate_dummy_work(&ctx); let index = ctx.queue.submit(Some(cmd_buf)); - ctx.async_poll(PollType::wait_for(index)).await.unwrap(); + ctx.async_poll(PollType::Wait { + submission_index: Some(index), + timeout: None, + }) + .await + .unwrap(); }); #[gpu_test] @@ -117,9 +157,24 @@ static WAIT_ON_SUBMISSION_WITH_TIMEOUT: GpuTestConfiguration = GpuTestConfigurat let cmd_buf = generate_dummy_work(&ctx); let index = ctx.queue.submit(Some(cmd_buf)); - ctx.async_poll(PollType::WaitForSubmissionIndexWithTimeout { - submission_index: index, - timeout: Duration::from_secs(1), + ctx.async_poll(PollType::Wait { + submission_index: Some(index), + timeout: Some(Duration::from_secs(1)), + }) + .await + .unwrap(); + }); + +#[gpu_test] +static WAIT_ON_SUBMISSION_WITH_TIMEOUT_MAX: GpuTestConfiguration = GpuTestConfiguration::new() + .parameters(TestParameters::default().enable_noop()) + .run_async(|ctx| async move { + let cmd_buf = generate_dummy_work(&ctx); + + let index = ctx.queue.submit(Some(cmd_buf)); + ctx.async_poll(PollType::Wait { + submission_index: Some(index), + timeout: Some(Duration::MAX), }) .await .unwrap(); @@ -132,10 +187,18 @@ static DOUBLE_WAIT_ON_SUBMISSION: GpuTestConfiguration = GpuTestConfiguration::n let cmd_buf = generate_dummy_work(&ctx); let index = ctx.queue.submit(Some(cmd_buf)); - ctx.async_poll(PollType::wait_for(index.clone())) - .await - .unwrap(); - ctx.async_poll(PollType::wait_for(index)).await.unwrap(); + ctx.async_poll(PollType::Wait { + submission_index: Some(index.clone()), + timeout: None, + }) + .await + .unwrap(); + ctx.async_poll(PollType::Wait { + submission_index: Some(index), + timeout: None, + }) + .await + .unwrap(); }); #[gpu_test] @@ -147,8 +210,18 @@ static WAIT_OUT_OF_ORDER: GpuTestConfiguration = GpuTestConfiguration::new() let index1 = ctx.queue.submit(Some(cmd_buf1)); let index2 = ctx.queue.submit(Some(cmd_buf2)); - ctx.async_poll(PollType::wait_for(index2)).await.unwrap(); - ctx.async_poll(PollType::wait_for(index1)).await.unwrap(); + ctx.async_poll(PollType::Wait { + submission_index: Some(index2), + timeout: None, + }) + .await + .unwrap(); + ctx.async_poll(PollType::Wait { + submission_index: Some(index1), + timeout: None, + }) + .await + .unwrap(); }); /// Submit a command buffer to the wrong device. A wait poll shouldn't hang. @@ -186,5 +259,5 @@ async fn wait_after_bad_submission(ctx: TestingContext) { // Specifically, the failed submission should not cause a new fence value to // be allocated that will not be signalled until further work is // successfully submitted, causing a greater fence value to be signalled. - device2.poll(wgpu::PollType::Wait).unwrap(); + device2.poll(wgpu::PollType::wait_indefinitely()).unwrap(); } diff --git a/tests/tests/wgpu-gpu/push_constants.rs b/tests/tests/wgpu-gpu/push_constants.rs index f1fb0f8c660..569fb426dfa 100644 --- a/tests/tests/wgpu-gpu/push_constants.rs +++ b/tests/tests/wgpu-gpu/push_constants.rs @@ -150,7 +150,9 @@ async fn partial_update_test(ctx: TestingContext) { encoder.copy_buffer_to_buffer(&gpu_buffer, 0, &cpu_buffer, 0, 32); ctx.queue.submit([encoder.finish()]); cpu_buffer.slice(..).map_async(wgpu::MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let data = cpu_buffer.slice(..).get_mapped_range(); @@ -368,7 +370,9 @@ async fn render_pass_test(ctx: &TestingContext, use_render_bundle: bool) { let command_buffer = command_encoder.finish(); ctx.queue.submit([command_buffer]); cpu_buffer.slice(..).map_async(MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let mapped_data = cpu_buffer.slice(..).get_mapped_range(); let result = bytemuck::cast_slice::(&mapped_data).to_vec(); drop(mapped_data); diff --git a/tests/tests/wgpu-gpu/queue_transfer.rs b/tests/tests/wgpu-gpu/queue_transfer.rs index 79abefaca28..ffff6f2d957 100644 --- a/tests/tests/wgpu-gpu/queue_transfer.rs +++ b/tests/tests/wgpu-gpu/queue_transfer.rs @@ -58,7 +58,7 @@ static QUEUE_WRITE_TEXTURE_THEN_DESTROY: GpuTestConfiguration = GpuTestConfigura texture.destroy(); ctx.queue.submit([]); - ctx.device.poll(PollType::wait()).unwrap(); + ctx.device.poll(PollType::wait_indefinitely()).unwrap(); }); #[gpu_test] diff --git a/tests/tests/wgpu-gpu/ray_tracing/as_build.rs b/tests/tests/wgpu-gpu/ray_tracing/as_build.rs index af9a811a7e5..fe42272e9d5 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/as_build.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/as_build.rs @@ -186,7 +186,7 @@ fn blas_compaction(ctx: TestingContext) { }); // On native this will trigger the callback. - ctx.device.poll(PollType::Wait).unwrap(); + ctx.device.poll(PollType::wait_indefinitely()).unwrap(); // Check that the callback actually gets called (this test will timeout if it doesn't). recv.recv().unwrap(); // This should return true because the callback has been called, and we haven't rebuilt the BLAS diff --git a/tests/tests/wgpu-gpu/ray_tracing/as_use_after_free.rs b/tests/tests/wgpu-gpu/ray_tracing/as_use_after_free.rs index 970f28d2115..e5213b3e36e 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/as_use_after_free.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/as_use_after_free.rs @@ -91,7 +91,7 @@ fn acceleration_structure_use_after_free(ctx: TestingContext) { // Drop the blas and ensure that if it was going to die, it is dead. drop(blas); - ctx.device.poll(PollType::Wait).unwrap(); + ctx.device.poll(PollType::wait_indefinitely()).unwrap(); // build the tlas package to ensure the blas is dropped let mut encoder = ctx @@ -126,7 +126,7 @@ fn acceleration_structure_use_after_free(ctx: TestingContext) { // Drop the TLAS package and ensure that if it was going to die, it is dead. drop(tlas); - ctx.device.poll(PollType::Wait).unwrap(); + ctx.device.poll(PollType::wait_indefinitely()).unwrap(); // Run the pass with the bind group that references the TLAS package. let mut encoder = ctx diff --git a/tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs b/tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs index d71092dd846..9b1760a0c72 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/scene/mod.rs @@ -101,7 +101,9 @@ fn acceleration_structure_build(ctx: &TestingContext, use_index_buffer: bool) { ctx.queue.submit(Some(encoder.finish())); - ctx.device.poll(wgpu::PollType::Wait).unwrap(); + ctx.device + .poll(wgpu::PollType::wait_indefinitely()) + .unwrap(); } #[gpu_test] diff --git a/tests/tests/wgpu-gpu/regression/issue_3457.rs b/tests/tests/wgpu-gpu/regression/issue_3457.rs index 4b7503776ea..495ad029933 100644 --- a/tests/tests/wgpu-gpu/regression/issue_3457.rs +++ b/tests/tests/wgpu-gpu/regression/issue_3457.rs @@ -172,7 +172,7 @@ static PASS_RESET_VERTEX_BUFFER: GpuTestConfiguration = GpuTestConfiguration::ne drop(vertex_buffer2); // Make sure the buffers are actually deleted. - ctx.async_poll(PollType::wait()).await.unwrap(); + ctx.async_poll(PollType::wait_indefinitely()).await.unwrap(); let mut encoder2 = ctx .device diff --git a/tests/tests/wgpu-gpu/regression/issue_4024.rs b/tests/tests/wgpu-gpu/regression/issue_4024.rs index 036a44f6161..9b7d34b202b 100644 --- a/tests/tests/wgpu-gpu/regression/issue_4024.rs +++ b/tests/tests/wgpu-gpu/regression/issue_4024.rs @@ -41,7 +41,7 @@ static QUEUE_SUBMITTED_CALLBACK_ORDERING: GpuTestConfiguration = GpuTestConfigur // Submit the work. ctx.queue.submit(Some(encoder.finish())); // Ensure the work is finished. - ctx.async_poll(PollType::wait()).await.unwrap(); + ctx.async_poll(PollType::wait_indefinitely()).await.unwrap(); #[derive(Debug)] struct OrderingContext { diff --git a/tests/tests/wgpu-gpu/regression/issue_4122.rs b/tests/tests/wgpu-gpu/regression/issue_4122.rs index e858c800fe1..41b0715c49f 100644 --- a/tests/tests/wgpu-gpu/regression/issue_4122.rs +++ b/tests/tests/wgpu-gpu/regression/issue_4122.rs @@ -38,7 +38,9 @@ async fn fill_test(ctx: &TestingContext, range: Range, size: u64) -> bool { ctx.queue.submit(Some(encoder.finish())); cpu_buffer.slice(..).map_async(wgpu::MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let buffer_slice = cpu_buffer.slice(..); let buffer_data = buffer_slice.get_mapped_range(); diff --git a/tests/tests/wgpu-gpu/regression/issue_6827.rs b/tests/tests/wgpu-gpu/regression/issue_6827.rs index af29947285e..578fac9b7fa 100644 --- a/tests/tests/wgpu-gpu/regression/issue_6827.rs +++ b/tests/tests/wgpu-gpu/regression/issue_6827.rs @@ -79,7 +79,7 @@ async fn run_test(ctx: TestingContext, use_many_writes: bool) { let result_cell = result_cell.clone(); move |result| result_cell.set(result).unwrap() }); - device.poll(wgpu::PollType::Wait).unwrap(); + device.poll(wgpu::PollType::wait_indefinitely()).unwrap(); result_cell .get() .as_ref() diff --git a/tests/tests/wgpu-gpu/render_pass_ownership.rs b/tests/tests/wgpu-gpu/render_pass_ownership.rs index 3e2b1a9831d..8d1f65972e5 100644 --- a/tests/tests/wgpu-gpu/render_pass_ownership.rs +++ b/tests/tests/wgpu-gpu/render_pass_ownership.rs @@ -113,7 +113,9 @@ async fn render_pass_resource_ownership(ctx: TestingContext) { drop(vertex_buffer); drop(index_buffer); drop(occlusion_query_set); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); } assert_render_pass_executed_normally(encoder, gpu_buffer, cpu_buffer, buffer_size, ctx).await; @@ -183,7 +185,9 @@ async fn render_pass_query_set_ownership_pipeline_statistics(ctx: TestingContext // Drop the query set. Then do a device poll to make sure it's not dropped too early, no matter what. drop(query_set); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); } assert_render_pass_executed_normally(encoder, gpu_buffer, cpu_buffer, buffer_size, ctx).await; @@ -260,7 +264,9 @@ async fn render_pass_query_set_ownership_timestamps(ctx: TestingContext) { // Drop the query sets. Then do a device poll to make sure they're not dropped too early, no matter what. drop(query_set_timestamp_writes); drop(query_set_write_timestamp); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); } assert_render_pass_executed_normally(encoder, gpu_buffer, cpu_buffer, buffer_size, ctx).await; @@ -312,7 +318,9 @@ async fn render_pass_keep_encoder_alive(ctx: TestingContext) { let mut rpass = rpass.forget_lifetime(); drop(encoder); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); // Record some a draw command. rpass.set_pipeline(&pipeline); @@ -338,7 +346,9 @@ async fn assert_render_pass_executed_normally( encoder.copy_buffer_to_buffer(&gpu_buffer, 0, &cpu_buffer, 0, buffer_size); ctx.queue.submit([encoder.finish()]); cpu_buffer.slice(..).map_async(wgpu::MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let data = cpu_buffer.slice(..).get_mapped_range(); diff --git a/tests/tests/wgpu-gpu/render_target.rs b/tests/tests/wgpu-gpu/render_target.rs index 9e69e805d8e..e45b8630a4e 100644 --- a/tests/tests/wgpu-gpu/render_target.rs +++ b/tests/tests/wgpu-gpu/render_target.rs @@ -239,7 +239,9 @@ async fn run_test( let slice = readback_buffer.slice(..); slice.map_async(wgpu::MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let data = slice.get_mapped_range(); let succeeded = data.iter().all(|b| *b == u8::MAX); @@ -420,7 +422,9 @@ async fn run_test_3d(ctx: TestingContext) { let slice = readback_buffer.slice(..); slice.map_async(wgpu::MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let data = slice.get_mapped_range(); let succeeded = data.iter().all(|b| *b == u8::MAX); diff --git a/tests/tests/wgpu-gpu/samplers.rs b/tests/tests/wgpu-gpu/samplers.rs index 1192426e41e..6c8018302d5 100644 --- a/tests/tests/wgpu-gpu/samplers.rs +++ b/tests/tests/wgpu-gpu/samplers.rs @@ -124,7 +124,9 @@ fn sampler_creation_failure(ctx: TestingContext) { let failed_count = sampler_storage.len(); sampler_storage.clear(); - ctx.device.poll(wgpu::PollType::Wait).unwrap(); + ctx.device + .poll(wgpu::PollType::wait_indefinitely()) + .unwrap(); for i in 0..failed_count { valid(&ctx.device, || { @@ -539,7 +541,9 @@ fn sampler_bind_group(ctx: TestingContext, group_type: GroupType) { let buffer_slice = transfer_buffer.slice(..); buffer_slice.map_async(wgpu::MapMode::Read, |_| {}); - ctx.device.poll(wgpu::PollType::Wait).unwrap(); + ctx.device + .poll(wgpu::PollType::wait_indefinitely()) + .unwrap(); let buffer_data = buffer_slice.get_mapped_range(); diff --git a/tests/tests/wgpu-gpu/shader/array_size_overrides.rs b/tests/tests/wgpu-gpu/shader/array_size_overrides.rs index d1756660d1f..531f70c597c 100644 --- a/tests/tests/wgpu-gpu/shader/array_size_overrides.rs +++ b/tests/tests/wgpu-gpu/shader/array_size_overrides.rs @@ -144,7 +144,7 @@ async fn array_size_overrides( ctx.queue.submit(Some(encoder.finish())); mapping_buffer.slice(..).map_async(MapMode::Read, |_| ()); - ctx.async_poll(PollType::wait()).await.unwrap(); + ctx.async_poll(PollType::wait_indefinitely()).await.unwrap(); let mapped = mapping_buffer.slice(..).get_mapped_range(); diff --git a/tests/tests/wgpu-gpu/shader/mod.rs b/tests/tests/wgpu-gpu/shader/mod.rs index 44928cf439b..6c8a4637f17 100644 --- a/tests/tests/wgpu-gpu/shader/mod.rs +++ b/tests/tests/wgpu-gpu/shader/mod.rs @@ -377,7 +377,7 @@ async fn shader_input_output_test( ctx.queue.submit(Some(encoder.finish())); mapping_buffer.slice(..).map_async(MapMode::Read, |_| ()); - ctx.async_poll(PollType::wait()).await.unwrap(); + ctx.async_poll(PollType::wait_indefinitely()).await.unwrap(); let mapped = mapping_buffer.slice(..).get_mapped_range(); diff --git a/tests/tests/wgpu-gpu/shader/workgroup_size_overrides.rs b/tests/tests/wgpu-gpu/shader/workgroup_size_overrides.rs index a3de36c5201..3d48ca2a8ff 100644 --- a/tests/tests/wgpu-gpu/shader/workgroup_size_overrides.rs +++ b/tests/tests/wgpu-gpu/shader/workgroup_size_overrides.rs @@ -111,7 +111,7 @@ async fn workgroup_size_overrides( ctx.queue.submit(Some(encoder.finish())); mapping_buffer.slice(..).map_async(MapMode::Read, |_| ()); - ctx.async_poll(PollType::wait()).await.unwrap(); + ctx.async_poll(PollType::wait_indefinitely()).await.unwrap(); let mapped = mapping_buffer.slice(..).get_mapped_range(); diff --git a/tests/tests/wgpu-gpu/shader/zero_init_workgroup_mem.rs b/tests/tests/wgpu-gpu/shader/zero_init_workgroup_mem.rs index fd9ed467df9..7192aac8f99 100644 --- a/tests/tests/wgpu-gpu/shader/zero_init_workgroup_mem.rs +++ b/tests/tests/wgpu-gpu/shader/zero_init_workgroup_mem.rs @@ -135,7 +135,7 @@ static ZERO_INIT_WORKGROUP_MEMORY: GpuTestConfiguration = GpuTestConfiguration:: ctx.queue.submit(Some(encoder.finish())); mapping_buffer.slice(..).map_async(MapMode::Read, |_| ()); - ctx.async_poll(PollType::wait()).await.unwrap(); + ctx.async_poll(PollType::wait_indefinitely()).await.unwrap(); let mapped = mapping_buffer.slice(..).get_mapped_range(); diff --git a/tests/tests/wgpu-gpu/shader_view_format/mod.rs b/tests/tests/wgpu-gpu/shader_view_format/mod.rs index d17f0e67572..0087ff35adc 100644 --- a/tests/tests/wgpu-gpu/shader_view_format/mod.rs +++ b/tests/tests/wgpu-gpu/shader_view_format/mod.rs @@ -189,7 +189,9 @@ async fn reinterpret( let slice = read_buffer.slice(..); slice.map_async(wgpu::MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let data: Vec = slice.get_mapped_range().to_vec(); let tolerance_data: [[u8; 4]; 4] = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [1, 1, 1, 0]]; diff --git a/tests/tests/wgpu-gpu/texture_binding/mod.rs b/tests/tests/wgpu-gpu/texture_binding/mod.rs index a77b3c23386..62b16e38530 100644 --- a/tests/tests/wgpu-gpu/texture_binding/mod.rs +++ b/tests/tests/wgpu-gpu/texture_binding/mod.rs @@ -181,7 +181,7 @@ fn single_scalar_load(ctx: TestingContext) { send.send(()).expect("Thread should wait for receive"); }); // Poll to run map. - ctx.device.poll(PollType::Wait).unwrap(); + ctx.device.poll(PollType::wait_indefinitely()).unwrap(); recv.recv_timeout(Duration::from_secs(10)) .expect("mapping should not take this long"); let val = *bytemuck::from_bytes::<[f32; 4]>(&buffer.slice(..).get_mapped_range()); diff --git a/tests/tests/wgpu-gpu/timestamp_normalization/utils.rs b/tests/tests/wgpu-gpu/timestamp_normalization/utils.rs index 1ce11ad775a..10ee50c2019 100644 --- a/tests/tests/wgpu-gpu/timestamp_normalization/utils.rs +++ b/tests/tests/wgpu-gpu/timestamp_normalization/utils.rs @@ -280,7 +280,9 @@ fn process_shader(ctx: TestingContext, inputs: &[u8], entry_point_src: &str) -> ctx.queue.submit([encoder.finish()]); pulldown_buffer.map_async(wgpu::MapMode::Read, .., |_| {}); - ctx.device.poll(wgpu::PollType::Wait).unwrap(); + ctx.device + .poll(wgpu::PollType::wait_indefinitely()) + .unwrap(); pulldown_buffer.get_mapped_range(..).to_vec() } diff --git a/tests/tests/wgpu-gpu/timestamp_query.rs b/tests/tests/wgpu-gpu/timestamp_query.rs index 08e29c54635..a19bcf2f182 100644 --- a/tests/tests/wgpu-gpu/timestamp_query.rs +++ b/tests/tests/wgpu-gpu/timestamp_query.rs @@ -121,7 +121,9 @@ fn timestamp_query(ctx: TestingContext) { mapping_buffer .slice(..) .map_async(wgpu::MapMode::Read, |_| ()); - ctx.device.poll(wgpu::PollType::wait()).unwrap(); + ctx.device + .poll(wgpu::PollType::wait_indefinitely()) + .unwrap(); let query_buffer_view = mapping_buffer.slice(..).get_mapped_range(); let query_data: &[u64] = bytemuck::cast_slice(&query_buffer_view); diff --git a/tests/tests/wgpu-gpu/vertex_formats/mod.rs b/tests/tests/wgpu-gpu/vertex_formats/mod.rs index 88f7659307e..89f8db03d62 100644 --- a/tests/tests/wgpu-gpu/vertex_formats/mod.rs +++ b/tests/tests/wgpu-gpu/vertex_formats/mod.rs @@ -381,11 +381,15 @@ async fn vertex_formats_common(ctx: TestingContext, tests: &[Test<'_>]) { // See https://github.com/gfx-rs/wgpu/issues/4732 for why this is split between two submissions // with a hard wait in between. ctx.queue.submit([encoder1.finish()]); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); ctx.queue.submit([encoder2.finish()]); let slice = cpu_buffer.slice(..); slice.map_async(wgpu::MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let data: Vec = bytemuck::cast_slice(&slice.get_mapped_range()).to_vec(); let case_name = format!("Case {:?}", test.case); diff --git a/tests/tests/wgpu-gpu/vertex_indices/mod.rs b/tests/tests/wgpu-gpu/vertex_indices/mod.rs index 6d53e960829..4fc63631f1e 100644 --- a/tests/tests/wgpu-gpu/vertex_indices/mod.rs +++ b/tests/tests/wgpu-gpu/vertex_indices/mod.rs @@ -440,11 +440,15 @@ async fn vertex_index_common(ctx: TestingContext) { // See https://github.com/gfx-rs/wgpu/issues/4732 for why this is split between two submissions // with a hard wait in between. ctx.queue.submit([encoder1.finish()]); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); ctx.queue.submit([encoder2.finish()]); let slice = cpu_buffer.slice(..); slice.map_async(wgpu::MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let data: Vec = bytemuck::cast_slice(&slice.get_mapped_range()).to_vec(); let case_name = format!( diff --git a/tests/tests/wgpu-gpu/vertex_state.rs b/tests/tests/wgpu-gpu/vertex_state.rs index fad6546d39f..73cc0ecb78c 100644 --- a/tests/tests/wgpu-gpu/vertex_state.rs +++ b/tests/tests/wgpu-gpu/vertex_state.rs @@ -185,7 +185,9 @@ async fn set_array_stride_to_0(ctx: TestingContext) { let slice = readback_buffer.slice(..); slice.map_async(wgpu::MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let data = slice.get_mapped_range(); let succeeded = data.iter().all(|b| *b == u8::MAX); diff --git a/tests/tests/wgpu-gpu/write_texture.rs b/tests/tests/wgpu-gpu/write_texture.rs index 2b6ad11e836..0f19075b451 100644 --- a/tests/tests/wgpu-gpu/write_texture.rs +++ b/tests/tests/wgpu-gpu/write_texture.rs @@ -94,7 +94,9 @@ static WRITE_TEXTURE_SUBSET_2D: GpuTestConfiguration = let slice = read_buffer.slice(..); slice.map_async(wgpu::MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let data: Vec = slice.get_mapped_range().to_vec(); for byte in &data[..(size as usize * 2)] { @@ -187,7 +189,9 @@ static WRITE_TEXTURE_SUBSET_3D: GpuTestConfiguration = let slice = read_buffer.slice(..); slice.map_async(wgpu::MapMode::Read, |_| ()); - ctx.async_poll(wgpu::PollType::wait()).await.unwrap(); + ctx.async_poll(wgpu::PollType::wait_indefinitely()) + .await + .unwrap(); let data: Vec = slice.get_mapped_range().to_vec(); for byte in &data[..((size * size) as usize * 2)] { @@ -333,7 +337,7 @@ static WRITE_TEXTURE_VIA_STAGING_BUFFER: GpuTestConfiguration = GpuTestConfigura let slice = read_buffer.slice(..); slice.map_async(MapMode::Read, |_| ()); - ctx.async_poll(PollType::wait()).await.unwrap(); + ctx.async_poll(PollType::wait_indefinitely()).await.unwrap(); let read_data: Vec = slice.get_mapped_range().to_vec(); for x in 0..write_width { diff --git a/tests/tests/wgpu-validation/api/buffer_mapping.rs b/tests/tests/wgpu-validation/api/buffer_mapping.rs index 62fcf0a8068..54e6bbdbd2c 100644 --- a/tests/tests/wgpu-validation/api/buffer_mapping.rs +++ b/tests/tests/wgpu-validation/api/buffer_mapping.rs @@ -17,7 +17,7 @@ fn full_immutable_binding() { }); buffer.map_async(wgpu::MapMode::Read, .., |_| {}); - device.poll(wgpu::PollType::Wait).unwrap(); + device.poll(wgpu::PollType::wait_indefinitely()).unwrap(); let mapping = buffer.slice(..).get_mapped_range(); @@ -62,7 +62,7 @@ fn split_immutable_binding() { }); buffer.map_async(wgpu::MapMode::Read, .., |_| {}); - device.poll(wgpu::PollType::Wait).unwrap(); + device.poll(wgpu::PollType::wait_indefinitely()).unwrap(); let mapping0 = buffer.slice(0..512).get_mapped_range(); let mapping1 = buffer.slice(512..1024).get_mapped_range(); @@ -167,7 +167,7 @@ fn partially_mapped() { }); buffer.map_async(wgpu::MapMode::Write, 0..512, |_| {}); - device.poll(wgpu::PollType::Wait).unwrap(); + device.poll(wgpu::PollType::wait_indefinitely()).unwrap(); let _mapping0 = buffer.slice(0..512).get_mapped_range_mut(); let _mapping1 = buffer.slice(512..1024).get_mapped_range_mut(); diff --git a/tests/tests/wgpu-validation/api/command_buffer_actions.rs b/tests/tests/wgpu-validation/api/command_buffer_actions.rs index fd427fae47e..24b5ac255c8 100644 --- a/tests/tests/wgpu-validation/api/command_buffer_actions.rs +++ b/tests/tests/wgpu-validation/api/command_buffer_actions.rs @@ -37,7 +37,7 @@ fn encoder_map_buffer_on_submit_defers_until_submit() { // Submit and wait; callback should fire. queue.submit([encoder.finish()]); - _ = device.poll(wgpu::PollType::Wait); + _ = device.poll(wgpu::PollType::wait_indefinitely()); assert!(fired.load(SeqCst)); } @@ -115,7 +115,7 @@ fn encoder_on_submitted_work_done_defers_until_submit() { assert!(!fired.load(SeqCst)); queue.submit([encoder.finish()]); - _ = device.poll(wgpu::PollType::Wait); + _ = device.poll(wgpu::PollType::wait_indefinitely()); assert!(fired.load(SeqCst)); } @@ -141,7 +141,7 @@ fn encoder_both_callbacks_fire_after_submit() { encoder.clear_buffer(&buffer, 0, None); queue.submit([encoder.finish()]); - _ = device.poll(wgpu::PollType::Wait); + _ = device.poll(wgpu::PollType::wait_indefinitely()); assert!(map_fired.load(SeqCst)); assert!(queue_fired.load(SeqCst)); @@ -169,7 +169,7 @@ fn encoder_multiple_map_buffer_on_submit_callbacks_fire() { encoder.clear_buffer(&buffer1, 0, None); queue.submit([encoder.finish()]); - _ = device.poll(wgpu::PollType::Wait); + _ = device.poll(wgpu::PollType::wait_indefinitely()); assert_eq!(counter.load(SeqCst), 2); } @@ -227,7 +227,7 @@ fn encoder_deferred_map_runs_before_on_submitted_work_done() { encoder.clear_buffer(&buffer, 0, None); queue.submit([encoder.finish()]); - _ = device.poll(wgpu::PollType::Wait); + _ = device.poll(wgpu::PollType::wait_indefinitely()); assert_eq!(order.counter.load(SeqCst), 2); assert_eq!(order.map_order.load(SeqCst), 0); @@ -255,7 +255,7 @@ fn encoder_multiple_on_submitted_callbacks_fire() { encoder.clear_buffer(&buffer, 0, None); queue.submit([encoder.finish()]); - _ = device.poll(wgpu::PollType::Wait); + _ = device.poll(wgpu::PollType::wait_indefinitely()); assert_eq!(counter.load(SeqCst), 2); } diff --git a/tests/tests/wgpu-validation/noop.rs b/tests/tests/wgpu-validation/noop.rs index 76bfff48155..bf5fcbbd035 100644 --- a/tests/tests/wgpu-validation/noop.rs +++ b/tests/tests/wgpu-validation/noop.rs @@ -53,6 +53,6 @@ fn device_and_buffers() { assert_eq!(*result.unwrap(), [1, 2, 3, 4, 5, 6, 7, 8],); done.store(true, Relaxed); }); - device.poll(wgpu::PollType::Wait).unwrap(); + device.poll(wgpu::PollType::wait_indefinitely()).unwrap(); assert!(done2.load(Relaxed)); } diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index 4b35638c48f..c63ed373a60 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -1995,7 +1995,7 @@ impl Global { let maintain_result; (user_callbacks, maintain_result) = - device.maintain(fence, wgt::PollType::Wait, snatch_guard); + device.maintain(fence, wgt::PollType::wait_indefinitely(), snatch_guard); match maintain_result { // We're happy @@ -2121,7 +2121,8 @@ impl Global { for (_id, device) in device_guard.iter() { let poll_type = if force_wait { - wgt::PollType::Wait + // TODO(#8286): Should expose timeout to poll_all. + wgt::PollType::wait_indefinitely() } else { wgt::PollType::Poll }; diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index f1f0a4c4fb1..811aadd3080 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -711,9 +711,9 @@ impl Device { // If a wait was requested, determine which submission index to wait for. let wait_submission_index = match poll_type { - wgt::PollType::WaitForSubmissionIndex(submission_index) - | wgt::PollType::WaitForSubmissionIndexWithTimeout { - submission_index, .. + wgt::PollType::Wait { + submission_index: Some(submission_index), + .. } => { let last_successful_submission_index = self .last_successful_submission_index @@ -730,7 +730,10 @@ impl Device { Some(submission_index) } - wgt::PollType::Wait | wgt::PollType::WaitWithTimeout { .. } => Some( + wgt::PollType::Wait { + submission_index: None, + .. + } => Some( self.last_successful_submission_index .load(Ordering::Acquire), ), @@ -741,9 +744,16 @@ impl Device { if let Some(target_submission_index) = wait_submission_index { log::trace!("Device::maintain: waiting for submission index {target_submission_index}"); + let wait_timeout = match poll_type { + wgt::PollType::Wait { timeout, .. } => timeout, + wgt::PollType::Poll => unreachable!( + "`wait_submission_index` index for poll type `Poll` should be None" + ), + }; + let wait_result = unsafe { self.raw() - .wait(fence.as_ref(), target_submission_index, poll_type.timeout()) + .wait(fence.as_ref(), target_submission_index, wait_timeout) }; // This error match is only about `DeviceErrors`. At this stage we do not care if diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index c2c70e67c66..f397bed3616 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -4503,58 +4503,42 @@ pub enum PollType { /// /// On WebGPU, this has no effect. Callbacks are invoked from the /// window event loop. - WaitForSubmissionIndex(T), - - /// Same as [`Self::WaitForSubmissionIndex`] but with a timeout. - WaitForSubmissionIndexWithTimeout { + Wait { /// Submission index to wait for. - submission_index: T, + /// + /// If not specified, will wait for the most recent submission at the time of the poll. + /// By the time the method returns, more submissions may have taken place. + submission_index: Option, /// Max time to wait for the submission to complete. /// + /// If not specified, will wait indefinitely (or until an error is detected). /// If waiting for the GPU device takes this long or longer, the poll will return [`PollError::Timeout`]. - timeout: Duration, + timeout: Option, }, - /// Same as [`Self::WaitForSubmissionIndex`] but waits for the most recent submission. - Wait, - - /// Same as [`Self::Wait`], but with a timeout. - /// - /// If waiting for the GPU device takes this long or longer, the poll will return [`PollError::Timeout`]. - WaitWithTimeout(Duration), - /// Check the device for a single time without blocking. Poll, } impl PollType { - /// Construct a [`Self::Wait`] variant - #[must_use] - pub fn wait() -> Self { - // This function seems a little silly, but it is useful to allow - // to be split up, as - // it has meaning in that PR. - Self::Wait - } - - /// Construct a [`Self::WaitForSubmissionIndex`] variant + /// Wait indefinitely until for the most recent submission to complete. + /// + /// This is a convenience function that creates a [`Self::Wait`] variant with + /// no timeout and no submission index. #[must_use] - pub fn wait_for(submission_index: T) -> Self { - // This function seems a little silly, but it is useful to allow - // to be split up, as - // it has meaning in that PR. - Self::WaitForSubmissionIndex(submission_index) + pub const fn wait_indefinitely() -> Self { + Self::Wait { + submission_index: None, + timeout: None, + } } /// This `PollType` represents a wait of some kind. #[must_use] pub fn is_wait(&self) -> bool { match *self { - Self::WaitForSubmissionIndex(..) - | Self::Wait - | Self::WaitForSubmissionIndexWithTimeout { .. } - | Self::WaitWithTimeout { .. } => true, + Self::Wait { .. } => true, Self::Poll => false, } } @@ -4566,29 +4550,16 @@ impl PollType { F: FnOnce(T) -> U, { match self { - Self::WaitForSubmissionIndex(i) => PollType::WaitForSubmissionIndex(func(i)), - Self::Wait => PollType::Wait, - Self::WaitForSubmissionIndexWithTimeout { + Self::Wait { submission_index, timeout, - } => PollType::WaitForSubmissionIndexWithTimeout { - submission_index: func(submission_index), + } => PollType::Wait { + submission_index: submission_index.map(func), timeout, }, - Self::WaitWithTimeout(timeout) => PollType::WaitWithTimeout(timeout), Self::Poll => PollType::Poll, } } - - /// Returns the timeout in milliseconds if the poll type has a timeout. - #[must_use] - pub fn timeout(&self) -> Option { - match self { - Self::WaitForSubmissionIndexWithTimeout { timeout, .. } - | Self::WaitWithTimeout(timeout) => Some(*timeout), - _ => None, - } - } } /// Error states after a device poll diff --git a/wgpu/src/api/blas.rs b/wgpu/src/api/blas.rs index 54013882fda..5f884e1644f 100644 --- a/wgpu/src/api/blas.rs +++ b/wgpu/src/api/blas.rs @@ -265,12 +265,11 @@ impl Blas { /// ### Interaction with other functions /// On native, `queue.submit(..)` and polling devices (that is calling `instance.poll_all` or /// `device.poll`) with [`PollType::Poll`] may call the callback. On native, polling devices with - /// [`PollType::Wait`] (or [`PollType::WaitForSubmissionIndex`] with a submission index greater + /// [`PollType::Wait`] (optionally with a submission index greater /// than the last submit the BLAS was used in) will guarantee callback is called. /// /// [`PollType::Poll`]: wgpu_types::PollType::Poll /// [`PollType::Wait`]: wgpu_types::PollType::Wait - /// [`PollType::WaitForSubmissionIndex`]: wgpu_types::PollType::WaitForSubmissionIndex pub fn prepare_compaction_async( &self, callback: impl FnOnce(Result<(), BlasAsyncError>) + WasmNotSend + 'static, From 9380b8775524daec5997e743c8d1943eafc221a1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 Oct 2025 22:42:49 +0000 Subject: [PATCH 275/303] chore(deps): update cargo.lock (#8229) Co-authored-by: Connor Fitzgerald --- .deny.toml | 9 +- Cargo.lock | 466 +++++++++++++++---------------------- Cargo.toml | 2 +- naga/xtask/src/validate.rs | 4 +- 4 files changed, 191 insertions(+), 290 deletions(-) diff --git a/.deny.toml b/.deny.toml index 30fa7afdca4..d5c2534f641 100644 --- a/.deny.toml +++ b/.deny.toml @@ -15,6 +15,9 @@ skip = [ # Deno uses an old version { name = "which", version = "6.0.3" }, + # Winit uses an old version + { name = "windows-sys", version = "0.52.0" }, + # Loom uses a new windows version { name = "windows", version = "0.61.1" }, { name = "windows-core", version = "0.61.2" }, @@ -23,9 +26,6 @@ skip = [ { name = "windows-result", version = "0.3.4" }, { name = "windows-strings", version = "0.4.2" }, - # cargo-metadata uses old version. Only used for infrastructure. - { name = "toml", version = "0.8.23" }, - { name = "ordered-float", version = "2.10.1" }, # bindgen (used by deno) uses old version { name = "itertools", version = "0.13.0" }, # Deno uses an old version @@ -53,7 +53,6 @@ allow = [ "MPL-2.0", "MIT", "MIT-0", - "Unicode-DFS-2016", "Unicode-3.0", "Zlib", ] @@ -68,4 +67,4 @@ unknown-git = "deny" required-git-spec = "rev" [sources.allow-org] -github = ["gfx-rs"] +github = [] diff --git a/Cargo.lock b/Cargo.lock index 7ccdeeccbe0..d58c2159c94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ab_glyph" -version = "0.2.31" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e074464580a518d16a7126262fffaaa47af89d4099d4cb403f8ed938ba12ee7d" +checksum = "01c0457472c38ea5bd1c3b5ada5e368271cb550be7a4ca4a0b4634e9913f6cc2" dependencies = [ "ab_glyph_rasterizer", "owned_ttf_parser", @@ -20,9 +20,9 @@ checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" [[package]] name = "addr2line" -version = "0.24.2" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" dependencies = [ "gimli", ] @@ -55,12 +55,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - [[package]] name = "android-activity" version = "0.5.2" @@ -141,9 +135,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" @@ -176,9 +170,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "approx" @@ -291,9 +285,9 @@ checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" [[package]] name = "backtrace" -version = "0.3.75" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ "addr2line", "cfg-if", @@ -301,7 +295,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", + "windows-link 0.2.0", ] [[package]] @@ -548,11 +542,11 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.12" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0b03af37dad7a14518b7691d81acb0f8222604ad3d1b02f6b4bed5188c0cd5" +checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -577,42 +571,25 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8abf5d501fd757c2d2ee78d0cc40f606e92e3a63544420316565556ed28485e2" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo-util-schemas" -version = "0.8.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dc1a6f7b5651af85774ae5a34b4e8be397d9cf4bc063b7e6dbd99a841837830" +checksum = "122ec45a44b270afd1402f351b782c676b173e3c3fb28d86ff7ebfb4d86a4ee4" dependencies = [ - "semver", "serde", - "serde-untagged", - "serde-value", - "thiserror 2.0.16", - "toml 0.8.23", - "unicode-xid", - "url", ] [[package]] name = "cargo_metadata" -version = "0.22.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3f56c207c76c07652489840ff98687dcf213de178ac0974660d6fefeaf5ec6" +checksum = "981a6f317983eec002839b90fae7411a85621410ae591a9cab2ecf5cb5744873" dependencies = [ "camino", "cargo-platform", - "cargo-util-schemas", "semver", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -623,9 +600,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.36" +version = "1.2.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5252b3d2648e5eedbc1a6f501e3c795e07025c1e93bbf8bbdd6eef7f447a6d54" +checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f" dependencies = [ "find-msvc-tools", "jobserver", @@ -715,9 +692,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.47" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931" +checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" dependencies = [ "clap_builder", "clap_derive", @@ -725,9 +702,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.47" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6" +checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" dependencies = [ "anstream", "anstyle", @@ -791,15 +768,15 @@ dependencies = [ [[package]] name = "console" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e09ced7ebbccb63b4c65413d821f2e00ce54c5ca4514ddc6b3c892fdbcbc69d" +checksum = "b430743a6eb14e9764d4260d4c0d8123087d504eeb9c48f2b2a5e810dd369df4" dependencies = [ "encode_unicode", "libc", "once_cell", "unicode-width", - "windows-sys 0.60.2", + "windows-sys 0.61.1", ] [[package]] @@ -824,9 +801,9 @@ dependencies = [ [[package]] name = "const_panic" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb8a602185c3c95b52f86dc78e55a6df9a287a7a93ddbcf012509930880cf879" +checksum = "e262cdaac42494e3ae34c43969f9cdeb7da178bdb4b66fa6a1ea2edb4c8ae652" dependencies = [ "typewit", ] @@ -1066,7 +1043,7 @@ dependencies = [ "smallvec", "sourcemap", "static_assertions", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "url", "v8", @@ -1129,7 +1106,7 @@ dependencies = [ "strum", "strum_macros", "syn", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -1141,7 +1118,7 @@ dependencies = [ "deno_error", "percent-encoding", "sys_traits", - "thiserror 2.0.16", + "thiserror 2.0.17", "url", ] @@ -1167,7 +1144,7 @@ dependencies = [ "serde", "serde_json", "sys_traits", - "thiserror 2.0.16", + "thiserror 2.0.17", "url", "which 8.0.0", "winapi", @@ -1222,7 +1199,7 @@ dependencies = [ "flate2", "futures", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "uuid", ] @@ -1238,7 +1215,7 @@ dependencies = [ "raw-window-handle 0.6.2", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "wgpu-core", "wgpu-types", @@ -1346,7 +1323,7 @@ checksum = "6e3e0ff2ee0b7aa97428308dd9e1e42369cb22f5fb8dc1c55546637443a60f1e" dependencies = [ "const_panic", "encase_derive", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -1419,24 +1396,14 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" -[[package]] -name = "erased-serde" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" -dependencies = [ - "serde", - "typeid", -] - [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.1", ] [[package]] @@ -1471,9 +1438,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d" +checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" [[package]] name = "fixedbitset" @@ -1701,7 +1668,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc257fdb4038301ce4b9cd1b3b51704509692bb3ff716a410cbd07925d9dae55" dependencies = [ - "rustix 1.0.8", + "rustix 1.1.2", "windows-targets 0.52.6", ] @@ -1728,15 +1695,15 @@ dependencies = [ "js-sys", "libc", "r-efi", - "wasi 0.14.4+wasi-0.2.4", + "wasi 0.14.7+wasi-0.2.4", "wasm-bindgen", ] [[package]] name = "gimli" -version = "0.31.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] name = "gl_generator" @@ -1920,8 +1887,6 @@ version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "allocator-api2", - "equivalent", "foldhash 0.1.5", ] @@ -2241,9 +2206,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.78" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0b063578492ceec17683ef2f8c5e89121fbd0b172cbc280635ab7567db2738" +checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" dependencies = [ "once_cell", "wasm-bindgen", @@ -2283,9 +2248,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.175" +version = "0.2.176" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" +checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" [[package]] name = "libfuzzer-sys" @@ -2300,12 +2265,12 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-targets 0.53.3", + "windows-link 0.2.0", ] [[package]] @@ -2316,9 +2281,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ "bitflags 2.9.4", "libc", @@ -2345,9 +2310,9 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "linux-raw-sys" -version = "0.9.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" @@ -2425,9 +2390,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "memmap2" @@ -2524,7 +2489,7 @@ dependencies = [ "naga-test", "num-traits", "once_cell", - "petgraph 0.8.2", + "petgraph 0.8.3", "pp-rs", "ron", "rspirv", @@ -2532,7 +2497,7 @@ dependencies = [ "serde", "spirv", "strum", - "thiserror 2.0.16", + "thiserror 2.0.17", "unicode-ident", "walkdir", ] @@ -2572,7 +2537,7 @@ dependencies = [ "serde", "serde_json", "spirv", - "toml 0.9.5", + "toml", "walkdir", ] @@ -3038,9 +3003,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.7" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "memchr", ] @@ -3072,15 +3037,6 @@ dependencies = [ "libredox", ] -[[package]] -name = "ordered-float" -version = "2.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" -dependencies = [ - "num-traits", -] - [[package]] name = "ordered-float" version = "5.0.0" @@ -3161,9 +3117,9 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54acf3a685220b533e437e264e4d932cfbdc4cc7ec0cd232ed73c08d03b8a7ca" +checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" dependencies = [ "fixedbitset 0.5.7", "hashbrown 0.15.5", @@ -3272,16 +3228,16 @@ dependencies = [ [[package]] name = "polling" -version = "3.10.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5bd19146350fe804f7cb2669c851c03d69da628803dab0d98018142aaa5d829" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" dependencies = [ "cfg-if", "concurrent-queue", "hermit-abi", "pin-project-lite", - "rustix 1.0.8", - "windows-sys 0.60.2", + "rustix 1.1.2", + "windows-sys 0.61.1", ] [[package]] @@ -3355,9 +3311,9 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ "toml_edit", ] @@ -3402,9 +3358,9 @@ checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" [[package]] name = "pxfm" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55f4fedc84ed39cb7a489322318976425e42a147e2be79d8f878e2884f94e84" +checksum = "83f9b339b02259ada5c0f4a389b7fb472f933aa17ce176fd2ad98f28bb401fde" dependencies = [ "num-traits", ] @@ -3420,9 +3376,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] @@ -3530,9 +3486,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.2" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" +checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" dependencies = [ "aho-corasick", "memchr", @@ -3542,9 +3498,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" +checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" dependencies = [ "aho-corasick", "memchr", @@ -3631,15 +3587,15 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.8" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ "bitflags 2.9.4", "errno", "libc", - "linux-raw-sys 0.9.4", - "windows-sys 0.60.2", + "linux-raw-sys 0.11.0", + "windows-sys 0.61.1", ] [[package]] @@ -3703,58 +3659,38 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" dependencies = [ "serde", + "serde_core", ] [[package]] name = "serde" -version = "1.0.226" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ "serde_core", "serde_derive", ] -[[package]] -name = "serde-untagged" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34836a629bcbc6f1afdf0907a744870039b1e14c0561cb26094fa683b158eff3" -dependencies = [ - "erased-serde", - "serde", - "typeid", -] - -[[package]] -name = "serde-value" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" -dependencies = [ - "ordered-float 2.10.1", - "serde", -] - [[package]] name = "serde_core" -version = "1.0.226" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba2ba63999edb9dac981fb34b3e5c0d111a69b0924e253ed29d83f7c99e966a4" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.226" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8db53ae22f34573731bafa1db20f04027b2d25e02d8205921b569171699cdb33" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -3763,33 +3699,25 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.143" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "indexmap", "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_spanned" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83" +checksum = "5417783452c2be558477e104686f7de5dae53dba813c28435e0e70f82d9b04ee" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -3802,7 +3730,7 @@ dependencies = [ "num-bigint", "serde", "smallvec", - "thiserror 2.0.16", + "thiserror 2.0.17", "v8", ] @@ -4094,11 +4022,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.16", + "thiserror-impl 2.0.17", ] [[package]] @@ -4114,9 +4042,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", @@ -4220,26 +4148,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.23" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "toml_edit", -] - -[[package]] -name = "toml" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8" +checksum = "00e5e5d9bf2475ac9d4f0d9edab68cc573dc2fd644b0dba36b0c30a92dd9eaa0" dependencies = [ "indexmap", - "serde", - "serde_spanned 1.0.0", - "toml_datetime 0.7.0", + "serde_core", + "serde_spanned", + "toml_datetime", "toml_parser", "toml_writer", "winnow", @@ -4247,56 +4163,39 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_datetime" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3" +checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1" dependencies = [ - "serde", + "serde_core", ] [[package]] name = "toml_edit" -version = "0.22.27" +version = "0.23.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +checksum = "f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b" dependencies = [ "indexmap", - "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "toml_write", + "toml_datetime", + "toml_parser", "winnow", ] [[package]] name = "toml_parser" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10" +checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627" dependencies = [ "winnow", ] -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - [[package]] name = "toml_writer" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64" +checksum = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109" [[package]] name = "tracing" @@ -4370,9 +4269,9 @@ dependencies = [ [[package]] name = "trybuild" -version = "1.0.110" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e257d7246e7a9fd015fb0b28b330a8d4142151a33f03e6a497754f4b1f6a8e" +checksum = "0ded9fdb81f30a5708920310bfcd9ea7482ff9cba5f54601f7a19a877d5c2392" dependencies = [ "glob", "serde", @@ -4380,7 +4279,7 @@ dependencies = [ "serde_json", "target-triple", "termcolor", - "toml 0.9.5", + "toml", ] [[package]] @@ -4389,17 +4288,11 @@ version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" -[[package]] -name = "typeid" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" - [[package]] name = "typewit" -version = "1.14.1" +version = "1.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c98488b93df24b7c794d6a58c4198d7a2abde676324beaca84f7fb5b39c0811" +checksum = "f8c1ae7cc0fdb8b842d65d127cb981574b0d2b249b74d1c7a2986863dc134f71" [[package]] name = "unic-char-property" @@ -4444,15 +4337,15 @@ dependencies = [ [[package]] name = "unicode-id-start" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f322b60f6b9736017344fa0635d64be2f458fbc04eef65f6be22976dd1ffd5b" +checksum = "81b79ad29b5e19de4260020f8919b443b2ef0277d242ce532ec7b7a2cc8b6007" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" [[package]] name = "unicode-segmentation" @@ -4590,18 +4483,27 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" -version = "0.14.4+wasi-0.2.4" +version = "0.14.7+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a5f4a424faf49c3c2c344f166f0662341d470ea185e939657aaff130f0ec4a" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.101" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b" +checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" dependencies = [ "cfg-if", "once_cell", @@ -4612,9 +4514,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.101" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb" +checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" dependencies = [ "bumpalo", "log", @@ -4626,9 +4528,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.51" +version = "0.4.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca85039a9b469b38336411d6d6ced91f3fc87109a2a27b0c197663f5144dffe" +checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" dependencies = [ "cfg-if", "js-sys", @@ -4639,9 +4541,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.101" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d" +checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4649,9 +4551,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.101" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa" +checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" dependencies = [ "proc-macro2", "quote", @@ -4662,18 +4564,18 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.101" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1" +checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" dependencies = [ "unicode-ident", ] [[package]] name = "wasm-bindgen-test" -version = "0.3.51" +version = "0.3.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80cc7f8a4114fdaa0c58383caf973fc126cf004eba25c9dc639bccd3880d55ad" +checksum = "4e381134e148c1062f965a42ed1f5ee933eef2927c3f70d1812158f711d39865" dependencies = [ "js-sys", "minicov", @@ -4684,9 +4586,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.51" +version = "0.3.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5ada2ab788d46d4bda04c9d567702a79c8ced14f51f221646a16ed39d0e6a5d" +checksum = "b673bca3298fe582aeef8352330ecbad91849f85090805582400850f8270a2e8" dependencies = [ "proc-macro2", "quote", @@ -4700,7 +4602,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a10e6b67c951a84de7029487e0e0a496860dae49f6699edd279d5ff35b8fbf54" dependencies = [ "deno_error", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -4711,7 +4613,7 @@ checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35" dependencies = [ "cc", "downcast-rs", - "rustix 1.0.8", + "rustix 1.1.2", "scoped-tls", "smallvec", "wayland-sys", @@ -4724,7 +4626,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d" dependencies = [ "bitflags 2.9.4", - "rustix 1.0.8", + "rustix 1.1.2", "wayland-backend", "wayland-scanner", ] @@ -4746,7 +4648,7 @@ version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "447ccc440a881271b19e9989f75726d60faa09b95b0200a9b7eb5cc47c3eeb29" dependencies = [ - "rustix 1.0.8", + "rustix 1.1.2", "wayland-client", "xcursor", ] @@ -4852,9 +4754,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.78" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e4b637749ff0d92b8fad63aa1f7cff3cbe125fd49c175cd6345e7272638b12" +checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" dependencies = [ "js-sys", "wasm-bindgen", @@ -4949,7 +4851,7 @@ dependencies = [ "rustc-hash 1.1.0", "serde", "smallvec", - "thiserror 2.0.16", + "thiserror 2.0.17", "wgpu-core-deps-apple", "wgpu-core-deps-emscripten", "wgpu-core-deps-wasm", @@ -5081,7 +4983,7 @@ dependencies = [ "ndk-sys 0.6.0+11769913", "objc", "once_cell", - "ordered-float 5.0.0", + "ordered-float", "parking_lot", "portable-atomic", "portable-atomic-util", @@ -5092,7 +4994,7 @@ dependencies = [ "renderdoc-sys", "rustc-hash 1.1.0", "smallvec", - "thiserror 2.0.16", + "thiserror 2.0.17", "wasm-bindgen", "web-sys", "wgpu-types", @@ -5175,7 +5077,7 @@ dependencies = [ "log", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "web-sys", ] @@ -5210,7 +5112,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fabb953106c3c8eea8306e4393700d7657561cb43122571b172bbfb7c7ba1d" dependencies = [ "env_home", - "rustix 1.0.8", + "rustix 1.1.2", "winsafe", ] @@ -5236,7 +5138,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.0", + "windows-sys 0.61.1", ] [[package]] @@ -5296,8 +5198,8 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ - "windows-implement 0.60.0", - "windows-interface 0.59.1", + "windows-implement 0.60.1", + "windows-interface 0.59.2", "windows-link 0.1.3", "windows-result 0.3.4", "windows-strings 0.4.2", @@ -5327,9 +5229,9 @@ dependencies = [ [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.60.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "edb307e42a74fb6de9bf3a02d9712678b22399c87e6fa869d6dfcd8c1b7754e0" dependencies = [ "proc-macro2", "quote", @@ -5349,9 +5251,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.59.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "c0abd1ddbc6964ac14db11c7213d6532ef34bd9aa042c2e5935f59d7908b46a5" dependencies = [ "proc-macro2", "quote", @@ -5459,14 +5361,14 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.3", + "windows-targets 0.53.4", ] [[package]] name = "windows-sys" -version = "0.61.0" +version = "0.61.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" +checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" dependencies = [ "windows-link 0.2.0", ] @@ -5519,11 +5421,11 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.3" +version = "0.53.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +checksum = "2d42b7b7f66d2a06854650af09cfdf8713e427a439c97ad65a6375318033ac4b" dependencies = [ - "windows-link 0.1.3", + "windows-link 0.2.0", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", @@ -5841,9 +5743,9 @@ checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" [[package]] name = "wit-bindgen" -version = "0.45.1" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" @@ -5882,7 +5784,7 @@ dependencies = [ "libc", "libloading", "once_cell", - "rustix 1.0.8", + "rustix 1.1.2", "x11rb-protocol", ] diff --git a/Cargo.toml b/Cargo.toml index bd58ec379ed..1e0e41d058c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,7 +106,7 @@ bytemuck = { version = "1.22", features = [ "extern_crate_alloc", "min_const_generics", ] } -cargo_metadata = "0.22" +cargo_metadata = "0.23" cfg_aliases = "0.2.1" cfg-if = "1" criterion = "0.7" diff --git a/naga/xtask/src/validate.rs b/naga/xtask/src/validate.rs index 66144006754..44728584810 100644 --- a/naga/xtask/src/validate.rs +++ b/naga/xtask/src/validate.rs @@ -30,7 +30,7 @@ pub(crate) fn validate(cmd: ValidateSubcommand) -> anyhow::Result<()> { Ok(result) => result, Err(payload) => Err(match payload.downcast_ref::<&str>() { Some(message) => { - anyhow::anyhow!("Validation job thread panicked: {}", message) + anyhow::anyhow!("Validation job thread panicked: {message}") } None => anyhow::anyhow!("Validation job thread panicked"), }), @@ -60,7 +60,7 @@ pub(crate) fn validate(cmd: ValidateSubcommand) -> anyhow::Result<()> { ); if let Err(error) = enqueuing_thread.join().unwrap() { - bail!("Error enqueuing jobs:\n{:#}", error); + bail!("Error enqueuing jobs:\n{error:#}"); } Ok(()) From 482a983e1006333dc249bd1a08b04db3e4a48230 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Wed, 1 Oct 2025 19:36:18 -0400 Subject: [PATCH 276/303] Release v27 (#8287) --- CHANGELOG.md | 4 +- Cargo.lock | 42 ++--- Cargo.toml | 26 +-- LICENSE.MIT | 2 +- README.md | 4 +- docs/broadcast_license.nu | 23 +++ docs/release-checklist.md | 12 +- examples/README.md | 4 +- .../standalone/01_hello_compute/Cargo.toml | 2 +- .../standalone/02_hello_window/Cargo.toml | 2 +- examples/standalone/custom_backend/Cargo.toml | 2 +- naga-cli/LICENSE.APACHE | 176 +++++++++++++++++ naga-cli/LICENSE.MIT | 21 +++ naga/LICENSE.APACHE | 176 +++++++++++++++++ naga/LICENSE.MIT | 21 +++ wgpu-core/LICENSE.APACHE | 177 +++++++++++++++++- wgpu-core/LICENSE.MIT | 22 ++- wgpu-core/platform-deps/apple/LICENSE.APACHE | 176 +++++++++++++++++ wgpu-core/platform-deps/apple/LICENSE.MIT | 21 +++ .../platform-deps/emscripten/LICENSE.APACHE | 176 +++++++++++++++++ .../platform-deps/emscripten/LICENSE.MIT | 21 +++ wgpu-core/platform-deps/wasm/LICENSE.APACHE | 176 +++++++++++++++++ wgpu-core/platform-deps/wasm/LICENSE.MIT | 21 +++ .../windows-linux-android/LICENSE.APACHE | 176 +++++++++++++++++ .../windows-linux-android/LICENSE.MIT | 21 +++ wgpu-hal/LICENSE.APACHE | 177 +++++++++++++++++- wgpu-hal/LICENSE.MIT | 22 ++- wgpu-info/LICENSE.APACHE | 176 +++++++++++++++++ wgpu-info/LICENSE.MIT | 21 +++ wgpu-types/LICENSE.APACHE | 177 +++++++++++++++++- wgpu-types/LICENSE.MIT | 22 ++- wgpu/LICENSE.APACHE | 177 +++++++++++++++++- wgpu/LICENSE.MIT | 22 ++- wgpu/src/lib.rs | 2 +- 34 files changed, 2237 insertions(+), 63 deletions(-) create mode 100644 docs/broadcast_license.nu create mode 100644 naga-cli/LICENSE.APACHE create mode 100644 naga-cli/LICENSE.MIT create mode 100644 naga/LICENSE.APACHE create mode 100644 naga/LICENSE.MIT mode change 120000 => 100644 wgpu-core/LICENSE.APACHE mode change 120000 => 100644 wgpu-core/LICENSE.MIT create mode 100644 wgpu-core/platform-deps/apple/LICENSE.APACHE create mode 100644 wgpu-core/platform-deps/apple/LICENSE.MIT create mode 100644 wgpu-core/platform-deps/emscripten/LICENSE.APACHE create mode 100644 wgpu-core/platform-deps/emscripten/LICENSE.MIT create mode 100644 wgpu-core/platform-deps/wasm/LICENSE.APACHE create mode 100644 wgpu-core/platform-deps/wasm/LICENSE.MIT create mode 100644 wgpu-core/platform-deps/windows-linux-android/LICENSE.APACHE create mode 100644 wgpu-core/platform-deps/windows-linux-android/LICENSE.MIT mode change 120000 => 100644 wgpu-hal/LICENSE.APACHE mode change 120000 => 100644 wgpu-hal/LICENSE.MIT create mode 100644 wgpu-info/LICENSE.APACHE create mode 100644 wgpu-info/LICENSE.MIT mode change 120000 => 100644 wgpu-types/LICENSE.APACHE mode change 120000 => 100644 wgpu-types/LICENSE.MIT mode change 120000 => 100644 wgpu/LICENSE.APACHE mode change 120000 => 100644 wgpu/LICENSE.MIT diff --git a/CHANGELOG.md b/CHANGELOG.md index f3b25c8ffeb..0dd1696c0a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,8 @@ Bottom level categories: ## Unreleased +## v27.0.0 (2025-10-01) + ### Major Changes #### Deferred command buffer actions: `map_buffer_on_submit` and `on_submitted_work_done` @@ -132,6 +134,7 @@ makes it significantly easier to store these types in structs, which is useful f ``` By @sagudev in [#8046](https://github.com/gfx-rs/wgpu/pull/8046) and @cwfitzgerald in [#8070](https://github.com/gfx-rs/wgpu/pull/8161). + #### `EXPERIMENTAL_*` features now require unsafe code to enable We want to be able to expose potentially experimental features to our users before we have ensured that they are fully sound to use. @@ -201,7 +204,6 @@ By @wumpf in [#8282](https://github.com/gfx-rs/wgpu/pull/8282), [#8285](https:// #### General - Added mesh shader support to `wgpu`, with examples. Requires passthrough. By @SupaMaggie70Incorporated in [#7345](https://github.com/gfx-rs/wgpu/pull/7345). - - Added support for external textures based on WebGPU's [`GPUExternalTexture`](https://www.w3.org/TR/webgpu/#gpuexternaltexture). These allow shaders to transparently operate on potentially multiplanar source texture data in either RGB or YCbCr formats via WGSL's `texture_external` type. This is gated behind the `Features::EXTERNAL_TEXTURE` feature, which is currently only supported on DX12. By @jamienicol in [#4386](https://github.com/gfx-rs/wgpu/issues/4386). - `wgpu::Device::poll` can now specify a timeout via `wgpu::PollType::Wait`. By @wumpf in [#8282](https://github.com/gfx-rs/wgpu/pull/8282) & [#8285](https://github.com/gfx-rs/wgpu/pull/8285) diff --git a/Cargo.lock b/Cargo.lock index d58c2159c94..5ac6df3d5d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -966,7 +966,7 @@ checksum = "e2931af7e13dc045d8e9d26afccc6fa115d64e115c9c84b1166288b46f6782c2" [[package]] name = "cts_runner" -version = "26.0.0" +version = "27.0.0" dependencies = [ "deno_console", "deno_core", @@ -1920,7 +1920,7 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" [[package]] name = "hlsl-snapshots" -version = "26.0.0" +version = "27.0.0" dependencies = [ "anyhow", "nanoserde", @@ -2328,7 +2328,7 @@ checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" [[package]] name = "lock-analyzer" -version = "26.0.0" +version = "27.0.0" dependencies = [ "anyhow", "ron", @@ -2467,7 +2467,7 @@ dependencies = [ [[package]] name = "naga" -version = "26.0.0" +version = "27.0.0" dependencies = [ "arbitrary", "arrayvec", @@ -2504,7 +2504,7 @@ dependencies = [ [[package]] name = "naga-cli" -version = "26.0.0" +version = "27.0.0" dependencies = [ "anyhow", "argh", @@ -2517,7 +2517,7 @@ dependencies = [ [[package]] name = "naga-fuzz" -version = "26.0.0" +version = "27.0.0" dependencies = [ "arbitrary", "cfg_aliases 0.2.1", @@ -2527,7 +2527,7 @@ dependencies = [ [[package]] name = "naga-test" -version = "26.0.0" +version = "27.0.0" dependencies = [ "bitflags 2.9.4", "env_logger", @@ -3172,7 +3172,7 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "player" -version = "26.0.0" +version = "27.0.0" dependencies = [ "bytemuck", "env_logger", @@ -4784,7 +4784,7 @@ dependencies = [ [[package]] name = "wgpu" -version = "26.0.0" +version = "27.0.0" dependencies = [ "arrayvec", "bitflags 2.9.4", @@ -4812,7 +4812,7 @@ dependencies = [ [[package]] name = "wgpu-benchmark" -version = "26.0.0" +version = "27.0.0" dependencies = [ "bincode 2.0.1", "bytemuck", @@ -4829,7 +4829,7 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "26.0.0" +version = "27.0.0" dependencies = [ "arrayvec", "bit-set", @@ -4862,28 +4862,28 @@ dependencies = [ [[package]] name = "wgpu-core-deps-apple" -version = "26.0.0" +version = "27.0.0" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-emscripten" -version = "26.0.0" +version = "27.0.0" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-wasm" -version = "26.0.0" +version = "27.0.0" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-windows-linux-android" -version = "26.0.0" +version = "27.0.0" dependencies = [ "wgpu-hal", ] @@ -4918,7 +4918,7 @@ dependencies = [ [[package]] name = "wgpu-examples" -version = "26.0.0" +version = "27.0.0" dependencies = [ "bytemuck", "cfg-if", @@ -4950,7 +4950,7 @@ dependencies = [ [[package]] name = "wgpu-hal" -version = "26.0.0" +version = "27.0.0" dependencies = [ "android_system_properties", "arrayvec", @@ -5005,7 +5005,7 @@ dependencies = [ [[package]] name = "wgpu-info" -version = "26.0.0" +version = "27.0.0" dependencies = [ "anyhow", "bitflags 2.9.4", @@ -5019,7 +5019,7 @@ dependencies = [ [[package]] name = "wgpu-macros" -version = "26.0.0" +version = "27.0.0" dependencies = [ "heck", "quote", @@ -5028,7 +5028,7 @@ dependencies = [ [[package]] name = "wgpu-test" -version = "26.0.0" +version = "27.0.0" dependencies = [ "anyhow", "approx", @@ -5069,7 +5069,7 @@ dependencies = [ [[package]] name = "wgpu-types" -version = "26.0.0" +version = "27.0.0" dependencies = [ "bitflags 2.9.4", "bytemuck", diff --git a/Cargo.toml b/Cargo.toml index 1e0e41d058c..d78e742c29e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,13 +61,13 @@ keywords = ["graphics"] license = "MIT OR Apache-2.0" homepage = "https://wgpu.rs/" repository = "https://github.com/gfx-rs/wgpu" -version = "26.0.0" +version = "27.0.0" authors = ["gfx-rs developers"] [workspace.dependencies] -naga = { version = "26.0.0", path = "./naga" } -naga-test = { version = "26.0.0", path = "./naga-test" } -wgpu = { version = "26.0.0", path = "./wgpu", default-features = false, features = [ +naga = { version = "27.0.0", path = "./naga" } +naga-test = { path = "./naga-test" } +wgpu = { version = "27.0.0", path = "./wgpu", default-features = false, features = [ "serde", "wgsl", "vulkan", @@ -77,21 +77,21 @@ wgpu = { version = "26.0.0", path = "./wgpu", default-features = false, features "static-dxc", "noop", # This should be removed if we ever have non-test crates that depend on wgpu ] } -wgpu-core = { version = "26.0.0", path = "./wgpu-core" } -wgpu-hal = { version = "26.0.0", path = "./wgpu-hal" } -wgpu-macros = { version = "26.0.0", path = "./wgpu-macros" } -wgpu-test = { version = "26.0.0", path = "./tests" } -wgpu-types = { version = "26.0.0", path = "./wgpu-types", default-features = false } +wgpu-core = { version = "27.0.0", path = "./wgpu-core" } +wgpu-hal = { version = "27.0.0", path = "./wgpu-hal" } +wgpu-macros = { version = "27.0.0", path = "./wgpu-macros" } +wgpu-test = { version = "27.0.0", path = "./tests" } +wgpu-types = { version = "27.0.0", path = "./wgpu-types", default-features = false } # These _cannot_ have a version specified. If it does, crates.io will look # for a version of the package on crates when we publish naga. Path dependencies # are allowed through though. hlsl-snapshots = { path = "naga/hlsl-snapshots" } -wgpu-core-deps-windows-linux-android = { version = "26.0.0", path = "./wgpu-core/platform-deps/windows-linux-android" } -wgpu-core-deps-apple = { version = "26.0.0", path = "./wgpu-core/platform-deps/apple" } -wgpu-core-deps-wasm = { version = "26.0.0", path = "./wgpu-core/platform-deps/wasm" } -wgpu-core-deps-emscripten = { version = "26.0.0", path = "./wgpu-core/platform-deps/emscripten" } +wgpu-core-deps-windows-linux-android = { version = "27.0.0", path = "./wgpu-core/platform-deps/windows-linux-android" } +wgpu-core-deps-apple = { version = "27.0.0", path = "./wgpu-core/platform-deps/apple" } +wgpu-core-deps-wasm = { version = "27.0.0", path = "./wgpu-core/platform-deps/wasm" } +wgpu-core-deps-emscripten = { version = "27.0.0", path = "./wgpu-core/platform-deps/emscripten" } anyhow = { version = "1.0.87", default-features = false } approx = "0.5" diff --git a/LICENSE.MIT b/LICENSE.MIT index 4699691b8ed..8d02e4dbd5f 100644 --- a/LICENSE.MIT +++ b/LICENSE.MIT @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 The gfx-rs developers +Copyright (c) 2025 The gfx-rs developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index fd9e0024a18..94d4135843c 100644 --- a/README.md +++ b/README.md @@ -17,13 +17,13 @@ The API is based on the [WebGPU standard][webgpu]. It serves as the core of the | Docs | Examples | Changelog | |:---------------------:|:-------------------------:|:-----------------------:| -| [v26][rel-docs] | [v26][rel-examples] | [v26][rel-change] | +| [v27][rel-docs] | [v27][rel-examples] | [v27][rel-change] | | [`trunk`][trunk-docs] | [`trunk`][trunk-examples] | [`trunk`][trunk-change] | Contributors are welcome! See [CONTRIBUTING.md][contrib] for more information. [rel-docs]: https://docs.rs/wgpu/ -[rel-examples]: https://github.com/gfx-rs/wgpu/tree/v26/examples#readme +[rel-examples]: https://github.com/gfx-rs/wgpu/tree/v27/examples#readme [rel-change]: https://github.com/gfx-rs/wgpu/releases [trunk-docs]: https://wgpu.rs/doc/wgpu/ [trunk-examples]: https://github.com/gfx-rs/wgpu/tree/trunk/examples#readme diff --git a/docs/broadcast_license.nu b/docs/broadcast_license.nu new file mode 100644 index 00000000000..bd676677fc5 --- /dev/null +++ b/docs/broadcast_license.nu @@ -0,0 +1,23 @@ +# Quick maintenance script which broadcasts the license files to all crates +# that are released on crates.io + +# Change to the root of the repository +cd ($env.FILE_PWD | path dirname) + +let crates = [ + "wgpu", + "wgpu-core", + "wgpu-core/platform-deps/apple", + "wgpu-core/platform-deps/emscripten", + "wgpu-core/platform-deps/wasm", + "wgpu-core/platform-deps/windows-linux-android", + "wgpu-hal", + "wgpu-info", + "wgpu-types", + "naga", + "naga-cli", +] + +for crate in $crates { + cp LICENSE.APACHE LICENSE.MIT $"./($crate)/" +} diff --git a/docs/release-checklist.md b/docs/release-checklist.md index ad678930120..4fcc86b8806 100644 --- a/docs/release-checklist.md +++ b/docs/release-checklist.md @@ -36,17 +36,7 @@ Day of Release: - Checkout `trunk` with the merged PR. - Publish! These commands can be pasted directly into your terminal in a single command, and they will publish everything. ```bash - cargo publish -p naga - cargo publish -p naga-cli - cargo publish -p wgpu-types - cargo publish -p wgpu-hal --all-features - cargo publish -p wgpu-core-deps-apple - cargo publish -p wgpu-core-deps-emscripten - cargo publish -p wgpu-core-deps-wasm - cargo publish -p wgpu-core-deps-windows-linux-android - cargo publish -p wgpu-core --all-features - cargo publish -p wgpu - cargo publish -p wgpu-info + cargo +stable publish --workspace --exclude deno_webgpu ``` - If there were any newly published crates, ensure `github:gfx-rs/wgpu` is added as an owner of that crate. - Create a new tag called `vX.Y.Z` and push it to the repo. diff --git a/examples/README.md b/examples/README.md index 4cdc532751b..0ebf805b45c 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,6 +1,6 @@ > [!NOTE] > These are the examples for the development version of wgpu. If you want to see the examples for the latest crates.io release -> of wgpu, go to the [latest release branch](https://github.com/gfx-rs/wgpu/tree/v26/examples#readme). +> of wgpu, go to the [latest release branch](https://github.com/gfx-rs/wgpu/tree/v27/examples#readme). # Examples @@ -23,7 +23,7 @@ be cloned out of the repository to serve as a starting point for your own projec You can also use [`cargo-generate`](https://github.com/cargo-generate/cargo-generate) to easily use these as a basis for your own projects. ```sh -cargo generate gfx-rs/wgpu --branch v26 +cargo generate gfx-rs/wgpu --branch v27 ``` ## Framework Examples diff --git a/examples/standalone/01_hello_compute/Cargo.toml b/examples/standalone/01_hello_compute/Cargo.toml index 448c6c59e4b..a7c36f913a0 100644 --- a/examples/standalone/01_hello_compute/Cargo.toml +++ b/examples/standalone/01_hello_compute/Cargo.toml @@ -8,4 +8,4 @@ publish = false bytemuck = "1.22.0" env_logger = "0.11" pollster = "0.4" -wgpu = "26.0.0" +wgpu = "27.0.0" diff --git a/examples/standalone/02_hello_window/Cargo.toml b/examples/standalone/02_hello_window/Cargo.toml index 8640c143f37..a5f351f95b6 100644 --- a/examples/standalone/02_hello_window/Cargo.toml +++ b/examples/standalone/02_hello_window/Cargo.toml @@ -7,5 +7,5 @@ publish = false [dependencies] env_logger = "0.11" pollster = "0.4" -wgpu = "26.0.0" +wgpu = "27.0.0" winit = { version = "0.30.8", features = ["android-native-activity"] } diff --git a/examples/standalone/custom_backend/Cargo.toml b/examples/standalone/custom_backend/Cargo.toml index 47e52290ec7..5c05a981ea4 100644 --- a/examples/standalone/custom_backend/Cargo.toml +++ b/examples/standalone/custom_backend/Cargo.toml @@ -9,7 +9,7 @@ default = ["web"] web = ["wgpu/web"] [dependencies] -wgpu = { version = "26.0.0", features = [ +wgpu = { version = "27.0.0", features = [ "custom", "wgsl", ], default-features = false } diff --git a/naga-cli/LICENSE.APACHE b/naga-cli/LICENSE.APACHE new file mode 100644 index 00000000000..d9a10c0d8e8 --- /dev/null +++ b/naga-cli/LICENSE.APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/naga-cli/LICENSE.MIT b/naga-cli/LICENSE.MIT new file mode 100644 index 00000000000..8d02e4dbd5f --- /dev/null +++ b/naga-cli/LICENSE.MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 The gfx-rs developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/naga/LICENSE.APACHE b/naga/LICENSE.APACHE new file mode 100644 index 00000000000..d9a10c0d8e8 --- /dev/null +++ b/naga/LICENSE.APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/naga/LICENSE.MIT b/naga/LICENSE.MIT new file mode 100644 index 00000000000..8d02e4dbd5f --- /dev/null +++ b/naga/LICENSE.MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 The gfx-rs developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/wgpu-core/LICENSE.APACHE b/wgpu-core/LICENSE.APACHE deleted file mode 120000 index 7141cad5b28..00000000000 --- a/wgpu-core/LICENSE.APACHE +++ /dev/null @@ -1 +0,0 @@ -../LICENSE.APACHE \ No newline at end of file diff --git a/wgpu-core/LICENSE.APACHE b/wgpu-core/LICENSE.APACHE new file mode 100644 index 00000000000..d9a10c0d8e8 --- /dev/null +++ b/wgpu-core/LICENSE.APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/wgpu-core/LICENSE.MIT b/wgpu-core/LICENSE.MIT deleted file mode 120000 index 6b8772d1a7a..00000000000 --- a/wgpu-core/LICENSE.MIT +++ /dev/null @@ -1 +0,0 @@ -../LICENSE.MIT \ No newline at end of file diff --git a/wgpu-core/LICENSE.MIT b/wgpu-core/LICENSE.MIT new file mode 100644 index 00000000000..8d02e4dbd5f --- /dev/null +++ b/wgpu-core/LICENSE.MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 The gfx-rs developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/wgpu-core/platform-deps/apple/LICENSE.APACHE b/wgpu-core/platform-deps/apple/LICENSE.APACHE new file mode 100644 index 00000000000..d9a10c0d8e8 --- /dev/null +++ b/wgpu-core/platform-deps/apple/LICENSE.APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/wgpu-core/platform-deps/apple/LICENSE.MIT b/wgpu-core/platform-deps/apple/LICENSE.MIT new file mode 100644 index 00000000000..8d02e4dbd5f --- /dev/null +++ b/wgpu-core/platform-deps/apple/LICENSE.MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 The gfx-rs developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/wgpu-core/platform-deps/emscripten/LICENSE.APACHE b/wgpu-core/platform-deps/emscripten/LICENSE.APACHE new file mode 100644 index 00000000000..d9a10c0d8e8 --- /dev/null +++ b/wgpu-core/platform-deps/emscripten/LICENSE.APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/wgpu-core/platform-deps/emscripten/LICENSE.MIT b/wgpu-core/platform-deps/emscripten/LICENSE.MIT new file mode 100644 index 00000000000..8d02e4dbd5f --- /dev/null +++ b/wgpu-core/platform-deps/emscripten/LICENSE.MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 The gfx-rs developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/wgpu-core/platform-deps/wasm/LICENSE.APACHE b/wgpu-core/platform-deps/wasm/LICENSE.APACHE new file mode 100644 index 00000000000..d9a10c0d8e8 --- /dev/null +++ b/wgpu-core/platform-deps/wasm/LICENSE.APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/wgpu-core/platform-deps/wasm/LICENSE.MIT b/wgpu-core/platform-deps/wasm/LICENSE.MIT new file mode 100644 index 00000000000..8d02e4dbd5f --- /dev/null +++ b/wgpu-core/platform-deps/wasm/LICENSE.MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 The gfx-rs developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/wgpu-core/platform-deps/windows-linux-android/LICENSE.APACHE b/wgpu-core/platform-deps/windows-linux-android/LICENSE.APACHE new file mode 100644 index 00000000000..d9a10c0d8e8 --- /dev/null +++ b/wgpu-core/platform-deps/windows-linux-android/LICENSE.APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/wgpu-core/platform-deps/windows-linux-android/LICENSE.MIT b/wgpu-core/platform-deps/windows-linux-android/LICENSE.MIT new file mode 100644 index 00000000000..8d02e4dbd5f --- /dev/null +++ b/wgpu-core/platform-deps/windows-linux-android/LICENSE.MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 The gfx-rs developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/wgpu-hal/LICENSE.APACHE b/wgpu-hal/LICENSE.APACHE deleted file mode 120000 index 7141cad5b28..00000000000 --- a/wgpu-hal/LICENSE.APACHE +++ /dev/null @@ -1 +0,0 @@ -../LICENSE.APACHE \ No newline at end of file diff --git a/wgpu-hal/LICENSE.APACHE b/wgpu-hal/LICENSE.APACHE new file mode 100644 index 00000000000..d9a10c0d8e8 --- /dev/null +++ b/wgpu-hal/LICENSE.APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/wgpu-hal/LICENSE.MIT b/wgpu-hal/LICENSE.MIT deleted file mode 120000 index 6b8772d1a7a..00000000000 --- a/wgpu-hal/LICENSE.MIT +++ /dev/null @@ -1 +0,0 @@ -../LICENSE.MIT \ No newline at end of file diff --git a/wgpu-hal/LICENSE.MIT b/wgpu-hal/LICENSE.MIT new file mode 100644 index 00000000000..8d02e4dbd5f --- /dev/null +++ b/wgpu-hal/LICENSE.MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 The gfx-rs developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/wgpu-info/LICENSE.APACHE b/wgpu-info/LICENSE.APACHE new file mode 100644 index 00000000000..d9a10c0d8e8 --- /dev/null +++ b/wgpu-info/LICENSE.APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/wgpu-info/LICENSE.MIT b/wgpu-info/LICENSE.MIT new file mode 100644 index 00000000000..8d02e4dbd5f --- /dev/null +++ b/wgpu-info/LICENSE.MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 The gfx-rs developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/wgpu-types/LICENSE.APACHE b/wgpu-types/LICENSE.APACHE deleted file mode 120000 index 7141cad5b28..00000000000 --- a/wgpu-types/LICENSE.APACHE +++ /dev/null @@ -1 +0,0 @@ -../LICENSE.APACHE \ No newline at end of file diff --git a/wgpu-types/LICENSE.APACHE b/wgpu-types/LICENSE.APACHE new file mode 100644 index 00000000000..d9a10c0d8e8 --- /dev/null +++ b/wgpu-types/LICENSE.APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/wgpu-types/LICENSE.MIT b/wgpu-types/LICENSE.MIT deleted file mode 120000 index 6b8772d1a7a..00000000000 --- a/wgpu-types/LICENSE.MIT +++ /dev/null @@ -1 +0,0 @@ -../LICENSE.MIT \ No newline at end of file diff --git a/wgpu-types/LICENSE.MIT b/wgpu-types/LICENSE.MIT new file mode 100644 index 00000000000..8d02e4dbd5f --- /dev/null +++ b/wgpu-types/LICENSE.MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 The gfx-rs developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/wgpu/LICENSE.APACHE b/wgpu/LICENSE.APACHE deleted file mode 120000 index 7141cad5b28..00000000000 --- a/wgpu/LICENSE.APACHE +++ /dev/null @@ -1 +0,0 @@ -../LICENSE.APACHE \ No newline at end of file diff --git a/wgpu/LICENSE.APACHE b/wgpu/LICENSE.APACHE new file mode 100644 index 00000000000..d9a10c0d8e8 --- /dev/null +++ b/wgpu/LICENSE.APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/wgpu/LICENSE.MIT b/wgpu/LICENSE.MIT deleted file mode 120000 index 6b8772d1a7a..00000000000 --- a/wgpu/LICENSE.MIT +++ /dev/null @@ -1 +0,0 @@ -../LICENSE.MIT \ No newline at end of file diff --git a/wgpu/LICENSE.MIT b/wgpu/LICENSE.MIT new file mode 100644 index 00000000000..8d02e4dbd5f --- /dev/null +++ b/wgpu/LICENSE.MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 The gfx-rs developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index a9f5d898205..4d183648830 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -14,7 +14,7 @@ //! and . The latter is a WebGPU //! tutorial, but the concepts are nearly identical to `wgpu`. //! -//! There are examples for this version [available on GitHub](https://github.com/gfx-rs/wgpu/tree/v26/examples#readme).. +//! There are examples for this version [available on GitHub](https://github.com/gfx-rs/wgpu/tree/v27/examples#readme). //! //! The API is refcounted, so all handles are cloneable, and if you create a resource which references another, //! it will automatically keep dependent resources alive. From 7b988969be3c9511e4a15f305f08e6ecc92d8304 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Wed, 1 Oct 2025 19:47:08 -0400 Subject: [PATCH 277/303] Remove trunk example warning --- examples/README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/README.md b/examples/README.md index 0ebf805b45c..ce552d8ebaa 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,7 +1,3 @@ -> [!NOTE] -> These are the examples for the development version of wgpu. If you want to see the examples for the latest crates.io release -> of wgpu, go to the [latest release branch](https://github.com/gfx-rs/wgpu/tree/v27/examples#readme). - # Examples If you are just starting your graphics programming journey entirely, we recommend going through [Learn-wgpu](https://sotrh.github.io/learn-wgpu/) From 0df9350a2ed96b6127d3929ed404dca6bbf98a16 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 2 Oct 2025 12:44:50 -0400 Subject: [PATCH 278/303] Fix docs.rs build --- wgpu-core/src/lib.rs | 2 +- wgpu-hal/src/lib.rs | 2 +- wgpu-types/src/lib.rs | 2 +- wgpu/src/lib.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/wgpu-core/src/lib.rs b/wgpu-core/src/lib.rs index d5bd7e48432..fe173c50913 100644 --- a/wgpu-core/src/lib.rs +++ b/wgpu-core/src/lib.rs @@ -17,7 +17,7 @@ ), allow(unused, clippy::let_and_return) )] -#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(docsrs, feature(doc_cfg))] #![allow( // It is much clearer to assert negative conditions with eq! false clippy::bool_assert_comparison, diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index a614098240d..a1a7eb147a1 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -203,7 +203,7 @@ //! [wiki-debug]: https://github.com/gfx-rs/wgpu/wiki/Debugging-wgpu-Applications #![no_std] -#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(docsrs, feature(doc_cfg))] #![allow( // this happens on the GL backend, where it is both thread safe and non-thread safe in the same code. clippy::arc_with_non_send_sync, diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index f397bed3616..5f4ba523968 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -1,7 +1,7 @@ //! This library describes the API surface of WebGPU that is agnostic of the backend. //! This API is used for targeting both Web and Native. -#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(docsrs, feature(doc_cfg))] #![allow( // We don't use syntax sugar where it's not necessary. clippy::match_like_matches_macro, diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 4d183648830..25ac702f053 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -32,7 +32,7 @@ //! #![no_std] -#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(docsrs, feature(doc_cfg))] #![doc(html_logo_url = "https://raw.githubusercontent.com/gfx-rs/wgpu/trunk/logo.png")] #![warn( clippy::alloc_instead_of_core, From d3f487ee499367190d606e8413c7344d3756f3d3 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 2 Oct 2025 12:53:03 -0400 Subject: [PATCH 279/303] Clarify changelog --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0dd1696c0a6..edd14534af5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -156,8 +156,7 @@ By @cwfitzgerald in [#8163](https://github.com/gfx-rs/wgpu/pull/8163). We have removed `Features::MULTI_DRAW_INDIRECT` as it was unconditionally available on all platforms. `RenderPass::multi_draw_indirect` is now available if the device supports downlevel flag `DownlevelFlags::INDIRECT_EXECUTION`. -If you are using spirv-passthrough with multi-draw indirect and `gl_DrawID`, you can know if `MULTI_DRAW_INDIRECT` is being emulated -by if the `Feature::MULTI_DRAW_INDIRECT_COUNT` feature is available on the device, this feature cannot be emulated efficicently. +The `Feature::MULTI_DRAW_INDIRECT_COUNT` feature can be used to determine if multi-draw is supported natively on the device. This is helpful to know if you are using spirv-passthrough and `gl_DrawID` in your shaders. By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). From c76dea031c688ecef0050dbf60506fff128fb23f Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 2 Oct 2025 12:55:32 -0400 Subject: [PATCH 280/303] Bump version to v27.0.1 --- CHANGELOG.md | 6 ++++++ Cargo.lock | 50 +++++++++++++++++++++++++------------------------- Cargo.toml | 2 +- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index edd14534af5..14f6f9b811b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,12 @@ Bottom level categories: ## Unreleased +## v27.0.1 (2025-10-02) + +### Bug Fixes + +- Fixed the build on docs.rs. By @cwfitzgerald in [#8292](https://github.com/gfx-rs/wgpu/pull/8292). + ## v27.0.0 (2025-10-01) ### Major Changes diff --git a/Cargo.lock b/Cargo.lock index 5ac6df3d5d5..b16aed647cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -966,7 +966,7 @@ checksum = "e2931af7e13dc045d8e9d26afccc6fa115d64e115c9c84b1166288b46f6782c2" [[package]] name = "cts_runner" -version = "27.0.0" +version = "27.0.1" dependencies = [ "deno_console", "deno_core", @@ -1403,7 +1403,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.1", + "windows-sys 0.52.0", ] [[package]] @@ -1920,7 +1920,7 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" [[package]] name = "hlsl-snapshots" -version = "27.0.0" +version = "27.0.1" dependencies = [ "anyhow", "nanoserde", @@ -2328,7 +2328,7 @@ checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" [[package]] name = "lock-analyzer" -version = "27.0.0" +version = "27.0.1" dependencies = [ "anyhow", "ron", @@ -2467,7 +2467,7 @@ dependencies = [ [[package]] name = "naga" -version = "27.0.0" +version = "27.0.1" dependencies = [ "arbitrary", "arrayvec", @@ -2504,7 +2504,7 @@ dependencies = [ [[package]] name = "naga-cli" -version = "27.0.0" +version = "27.0.1" dependencies = [ "anyhow", "argh", @@ -2517,7 +2517,7 @@ dependencies = [ [[package]] name = "naga-fuzz" -version = "27.0.0" +version = "27.0.1" dependencies = [ "arbitrary", "cfg_aliases 0.2.1", @@ -2527,7 +2527,7 @@ dependencies = [ [[package]] name = "naga-test" -version = "27.0.0" +version = "27.0.1" dependencies = [ "bitflags 2.9.4", "env_logger", @@ -3172,7 +3172,7 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "player" -version = "27.0.0" +version = "27.0.1" dependencies = [ "bytemuck", "env_logger", @@ -3582,7 +3582,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -3595,7 +3595,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.11.0", - "windows-sys 0.61.1", + "windows-sys 0.52.0", ] [[package]] @@ -4784,7 +4784,7 @@ dependencies = [ [[package]] name = "wgpu" -version = "27.0.0" +version = "27.0.1" dependencies = [ "arrayvec", "bitflags 2.9.4", @@ -4812,7 +4812,7 @@ dependencies = [ [[package]] name = "wgpu-benchmark" -version = "27.0.0" +version = "27.0.1" dependencies = [ "bincode 2.0.1", "bytemuck", @@ -4829,7 +4829,7 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "27.0.0" +version = "27.0.1" dependencies = [ "arrayvec", "bit-set", @@ -4862,28 +4862,28 @@ dependencies = [ [[package]] name = "wgpu-core-deps-apple" -version = "27.0.0" +version = "27.0.1" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-emscripten" -version = "27.0.0" +version = "27.0.1" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-wasm" -version = "27.0.0" +version = "27.0.1" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-windows-linux-android" -version = "27.0.0" +version = "27.0.1" dependencies = [ "wgpu-hal", ] @@ -4918,7 +4918,7 @@ dependencies = [ [[package]] name = "wgpu-examples" -version = "27.0.0" +version = "27.0.1" dependencies = [ "bytemuck", "cfg-if", @@ -4950,7 +4950,7 @@ dependencies = [ [[package]] name = "wgpu-hal" -version = "27.0.0" +version = "27.0.1" dependencies = [ "android_system_properties", "arrayvec", @@ -5005,7 +5005,7 @@ dependencies = [ [[package]] name = "wgpu-info" -version = "27.0.0" +version = "27.0.1" dependencies = [ "anyhow", "bitflags 2.9.4", @@ -5019,7 +5019,7 @@ dependencies = [ [[package]] name = "wgpu-macros" -version = "27.0.0" +version = "27.0.1" dependencies = [ "heck", "quote", @@ -5028,7 +5028,7 @@ dependencies = [ [[package]] name = "wgpu-test" -version = "27.0.0" +version = "27.0.1" dependencies = [ "anyhow", "approx", @@ -5069,7 +5069,7 @@ dependencies = [ [[package]] name = "wgpu-types" -version = "27.0.0" +version = "27.0.1" dependencies = [ "bitflags 2.9.4", "bytemuck", @@ -5138,7 +5138,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.1", + "windows-sys 0.52.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index d78e742c29e..25d12a44796 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,7 +61,7 @@ keywords = ["graphics"] license = "MIT OR Apache-2.0" homepage = "https://wgpu.rs/" repository = "https://github.com/gfx-rs/wgpu" -version = "27.0.0" +version = "27.0.1" authors = ["gfx-rs developers"] [workspace.dependencies] From b34c11033267e401eb7a98524166770b0d81ba1e Mon Sep 17 00:00:00 2001 From: David Stern Date: Fri, 3 Oct 2025 20:41:58 -0400 Subject: [PATCH 281/303] Gate DX12 mesh shader command signature initialization on device support. (#8297) --- CHANGELOG.md | 8 +++++ wgpu-hal/src/dx12/command.rs | 12 +++++-- wgpu-hal/src/dx12/device.rs | 64 +++++++++++++++++++++++------------- wgpu-hal/src/dx12/mod.rs | 2 +- 4 files changed, 60 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14f6f9b811b..fcfec0954a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,14 @@ Bottom level categories: ## Unreleased +## v27.0.2 (2025-10-03) + +### Bug Fixes + +#### DX12 + +- Fix device creation failures for devices that do not support mesh shaders. By @vorporeal in [#8297](https://github.com/gfx-rs/wgpu/pull/8297). + ## v27.0.1 (2025-10-02) ### Bug Fixes diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index 19b06867f84..80cdec40dea 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -1338,14 +1338,17 @@ impl crate::CommandEncoder for super::CommandEncoder { let cmd_list6: Direct3D12::ID3D12GraphicsCommandList6 = self.list.as_ref().unwrap().cast().unwrap(); - let cmd_signature = &self + let Some(cmd_signature) = &self .pass .layout .special_constants .as_ref() .and_then(|sc| sc.indirect_cmd_signatures.as_ref()) .unwrap_or_else(|| &self.shared.cmd_signatures) - .draw_mesh; + .draw_mesh + else { + panic!("Feature `MESH_SHADING` not enabled"); + }; unsafe { cmd_list6.ExecuteIndirect(cmd_signature, draw_count, &buffer.resource, offset, None, 0); } @@ -1401,9 +1404,12 @@ impl crate::CommandEncoder for super::CommandEncoder { self.prepare_dispatch([0; 3]); let cmd_list6: Direct3D12::ID3D12GraphicsCommandList6 = self.list.as_ref().unwrap().cast().unwrap(); + let Some(ref command_signature) = self.shared.cmd_signatures.draw_mesh else { + panic!("Feature `MESH_SHADING` not enabled"); + }; unsafe { cmd_list6.ExecuteIndirect( - &self.shared.cmd_signatures.draw_mesh, + command_signature, max_count, &buffer.resource, offset, diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 6cd959e7114..473423b8145 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -116,6 +116,24 @@ impl super::Device { // maximum number of CBV/SRV/UAV descriptors in heap for Tier 1 let capacity_views = limits.max_non_sampler_bindings as u64; + let draw_mesh = if features + .features_wgpu + .contains(wgt::FeaturesWGPU::EXPERIMENTAL_MESH_SHADER) + { + Some(Self::create_command_signature( + &raw, + None, + size_of::(), + &[Direct3D12::D3D12_INDIRECT_ARGUMENT_DESC { + Type: Direct3D12::D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH, + ..Default::default() + }], + 0, + )?) + } else { + None + }; + let shared = super::DeviceShared { adapter, zero_buffer, @@ -140,16 +158,7 @@ impl super::Device { }], 0, )?, - draw_mesh: Self::create_command_signature( - &raw, - None, - size_of::(), - &[Direct3D12::D3D12_INDIRECT_ARGUMENT_DESC { - Type: Direct3D12::D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH, - ..Default::default() - }], - 0, - )?, + draw_mesh, dispatch: Self::create_command_signature( &raw, None, @@ -1371,47 +1380,58 @@ impl crate::Device for super::Device { }; size_of_val(&first_vertex) + size_of_val(&first_instance) + size_of_val(&other) }; - Some(super::CommandSignatures { - draw: Self::create_command_signature( + + let draw_mesh = if self + .features + .features_wgpu + .contains(wgt::FeaturesWGPU::EXPERIMENTAL_MESH_SHADER) + { + Some(Self::create_command_signature( &self.raw, Some(&raw), - special_constant_buffer_args_len + size_of::(), + special_constant_buffer_args_len + size_of::(), &[ constant_indirect_argument_desc, Direct3D12::D3D12_INDIRECT_ARGUMENT_DESC { - Type: Direct3D12::D3D12_INDIRECT_ARGUMENT_TYPE_DRAW, + Type: Direct3D12::D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH, ..Default::default() }, ], 0, - )?, - draw_indexed: Self::create_command_signature( + )?) + } else { + None + }; + + Some(super::CommandSignatures { + draw: Self::create_command_signature( &self.raw, Some(&raw), - special_constant_buffer_args_len - + size_of::(), + special_constant_buffer_args_len + size_of::(), &[ constant_indirect_argument_desc, Direct3D12::D3D12_INDIRECT_ARGUMENT_DESC { - Type: Direct3D12::D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED, + Type: Direct3D12::D3D12_INDIRECT_ARGUMENT_TYPE_DRAW, ..Default::default() }, ], 0, )?, - draw_mesh: Self::create_command_signature( + draw_indexed: Self::create_command_signature( &self.raw, Some(&raw), - special_constant_buffer_args_len + size_of::(), + special_constant_buffer_args_len + + size_of::(), &[ constant_indirect_argument_desc, Direct3D12::D3D12_INDIRECT_ARGUMENT_DESC { - Type: Direct3D12::D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH, + Type: Direct3D12::D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED, ..Default::default() }, ], 0, )?, + draw_mesh, dispatch: Self::create_command_signature( &self.raw, Some(&raw), diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 981409192c6..125a88287e6 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -659,7 +659,7 @@ struct Idler { struct CommandSignatures { draw: Direct3D12::ID3D12CommandSignature, draw_indexed: Direct3D12::ID3D12CommandSignature, - draw_mesh: Direct3D12::ID3D12CommandSignature, + draw_mesh: Option, dispatch: Direct3D12::ID3D12CommandSignature, } From 627bf91c61341dd063164106fcf8b5dcb1631010 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Fri, 3 Oct 2025 23:40:47 -0400 Subject: [PATCH 282/303] Bump version to v27.0.2 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 25d12a44796..175175f2449 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,7 +61,7 @@ keywords = ["graphics"] license = "MIT OR Apache-2.0" homepage = "https://wgpu.rs/" repository = "https://github.com/gfx-rs/wgpu" -version = "27.0.1" +version = "27.0.2" authors = ["gfx-rs developers"] [workspace.dependencies] From 98caa62267ff2b723b23ea44d1488fd4a7a690f8 Mon Sep 17 00:00:00 2001 From: teoxoy <28601907+teoxoy@users.noreply.github.com> Date: Mon, 6 Oct 2025 19:35:54 +0200 Subject: [PATCH 283/303] [msl-out] use `separator` closure for all fn arguments --- naga/src/back/msl/writer.rs | 57 +++++++++++++------------------------ 1 file changed, 19 insertions(+), 38 deletions(-) diff --git a/naga/src/back/msl/writer.rs b/naga/src/back/msl/writer.rs index cec92265416..6e51f90181e 100644 --- a/naga/src/back/msl/writer.rs +++ b/naga/src/back/msl/writer.rs @@ -6904,16 +6904,25 @@ template // Write the entry point function's name, and begin its argument list. writeln!(self.out, "{em_str} {result_type_name} {fun_name}(")?; + let mut is_first_argument = true; + let mut separator = || { + if is_first_argument { + is_first_argument = false; + ' ' + } else { + ',' + } + }; // If we have produced a struct holding the `EntryPoint`'s // `Function`'s arguments' varyings, pass that struct first. if has_varyings { writeln!( self.out, - " {stage_in_name} {varyings_member_name} [[stage_in]]" + "{} {stage_in_name} {varyings_member_name} [[stage_in]]", + separator() )?; - is_first_argument = false; } let mut local_invocation_id = None; @@ -6953,13 +6962,7 @@ template }; let resolved = options.resolve_local_binding(binding, in_mode)?; - let separator = if is_first_argument { - is_first_argument = false; - ' ' - } else { - ',' - }; - write!(self.out, "{separator} {ty_name} {name}")?; + write!(self.out, "{} {ty_name} {name}", separator())?; resolved.try_fmt(&mut self.out)?; writeln!(self.out)?; } @@ -6968,15 +6971,9 @@ template self.need_workgroup_variables_initialization(options, ep, module, fun_info); if need_workgroup_variables_initialization && local_invocation_id.is_none() { - let separator = if is_first_argument { - is_first_argument = false; - ' ' - } else { - ',' - }; writeln!( self.out, - "{separator} {NAMESPACE}::uint3 __local_invocation_id [[thread_position_in_threadgroup]]" + "{} {NAMESPACE}::uint3 __local_invocation_id [[thread_position_in_threadgroup]]", separator() )?; } @@ -7123,15 +7120,6 @@ template } } - let mut separator = || { - if is_first_argument { - is_first_argument = false; - ' ' - } else { - ',' - } - }; - match module.types[var.ty].inner { crate::TypeInner::Image { class: crate::ImageClass::External, @@ -7203,21 +7191,13 @@ template } if do_vertex_pulling { - let mut separator = if is_first_argument { - is_first_argument = false; - ' ' - } else { - ',' - }; - if needs_vertex_id && v_existing_id.is_none() { // Write the [[vertex_id]] argument. - writeln!(self.out, "{separator} uint {v_id} [[vertex_id]]")?; - separator = ','; + writeln!(self.out, "{} uint {v_id} [[vertex_id]]", separator())?; } if needs_instance_id && i_existing_id.is_none() { - writeln!(self.out, "{separator} uint {i_id} [[instance_id]]")?; + writeln!(self.out, "{} uint {i_id} [[instance_id]]", separator())?; } // Iterate vbm_resolved, output one argument for every vertex buffer, @@ -7228,7 +7208,8 @@ template let param_name = &vbm.param_name; writeln!( self.out, - ", const device {ty_name}* {param_name} [[buffer({id})]]" + "{} const device {ty_name}* {param_name} [[buffer({id})]]", + separator() )?; } } @@ -7238,10 +7219,10 @@ template if needs_buffer_sizes { // this is checked earlier let resolved = options.resolve_sizes_buffer(ep).unwrap(); - let separator = if is_first_argument { ' ' } else { ',' }; write!( self.out, - "{separator} constant _mslBufferSizes& _buffer_sizes", + "{} constant _mslBufferSizes& _buffer_sizes", + separator() )?; resolved.try_fmt(&mut self.out)?; writeln!(self.out)?; From 2ea52e021fe1d6bb8c6afd9c29c057ebeab48685 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Mon, 6 Oct 2025 12:45:27 -0700 Subject: [PATCH 284/303] [ci] Reset cache tag for CTS --- .github/workflows/cts.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cts.yml b/.github/workflows/cts.yml index cc794f7b7ac..317968b78e2 100644 --- a/.github/workflows/cts.yml +++ b/.github/workflows/cts.yml @@ -71,7 +71,7 @@ jobs: - name: caching uses: Swatinem/rust-cache@v2 with: - prefix-key: v2-rust # Increment version for cache busting + prefix-key: v2-rust-wgpu27 # Increment version for cache busting cache-directories: cts # We enable line numbers for panics, but that's it From f3dad2265db8024c13291c076c7acad263fecfc1 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Thu, 22 May 2025 12:51:51 -0400 Subject: [PATCH 285/303] refactor(dx12): detect `UnrestrictedBufferTextureCopyPitchSupported` --- wgpu-hal/src/dx12/adapter.rs | 17 +++++++++++++++++ wgpu-hal/src/dx12/mod.rs | 1 + 2 files changed, 18 insertions(+) diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index 140dcf60a80..9d174adf01c 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -200,6 +200,21 @@ impl super::Adapter { .is_ok() }; + let unrestricted_buffer_texture_copy_pitch_supported = { + let mut features13 = Direct3D12::D3D12_FEATURE_DATA_D3D12_OPTIONS13::default(); + unsafe { + device.CheckFeatureSupport( + Direct3D12::D3D12_FEATURE_D3D12_OPTIONS13, + <*mut _>::cast(&mut features13), + size_of_val(&features13) as u32, + ) + } + .is_ok() + && features13 + .UnrestrictedBufferTextureCopyPitchSupported + .as_bool() + }; + let mut max_sampler_descriptor_heap_size = Direct3D12::D3D12_MAX_SHADER_VISIBLE_SAMPLER_HEAP_SIZE; { @@ -304,6 +319,8 @@ impl super::Adapter { suballocation_supported: !info.name.contains("Iris(R) Xe"), shader_model, max_sampler_descriptor_heap_size, + _unrestricted_buffer_texture_copy_pitch_supported: + unrestricted_buffer_texture_copy_pitch_supported, }; // Theoretically vram limited, but in practice 2^20 is the limit diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 125a88287e6..16c967aa9f4 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -601,6 +601,7 @@ struct PrivateCapabilities { suballocation_supported: bool, shader_model: naga::back::hlsl::ShaderModel, max_sampler_descriptor_heap_size: u32, + _unrestricted_buffer_texture_copy_pitch_supported: bool, } #[derive(Default)] From 341a4e058d7d2d9acc8ea310b9368cda3e5bafdb Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Thu, 22 May 2025 12:51:51 -0400 Subject: [PATCH 286/303] refactor(dx12): lower `list` extraction for copies between textures and buffers --- wgpu-hal/src/dx12/command.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index 80cdec40dea..29b3a725549 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -612,8 +612,9 @@ impl crate::CommandEncoder for super::CommandEncoder { ) where T: Iterator, { - let list = self.list.as_ref().unwrap(); for r in regions { + let list = self.list.as_ref().unwrap(); + let src_location = Direct3D12::D3D12_TEXTURE_COPY_LOCATION { pResource: unsafe { borrow_interface_temporarily(&src.resource) }, Type: Direct3D12::D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, @@ -652,8 +653,9 @@ impl crate::CommandEncoder for super::CommandEncoder { ) where T: Iterator, { - let list = self.list.as_ref().unwrap(); for r in regions { + let list = self.list.as_ref().unwrap(); + let src_location = Direct3D12::D3D12_TEXTURE_COPY_LOCATION { pResource: unsafe { borrow_interface_temporarily(&src.resource) }, Type: Direct3D12::D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, From 3a5e2c4b186cfce1344c768c8f1f7826470ee2c8 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Thu, 22 May 2025 12:51:51 -0400 Subject: [PATCH 287/303] refactor(hal): impl. `From` conversions b/w `wgh::CopyExtent` and `wgt::Extent3d` --- wgpu-hal/src/lib.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index a1a7eb147a1..aa6f119f6c9 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -2438,6 +2438,36 @@ pub struct CopyExtent { pub depth: u32, } +impl From for CopyExtent { + fn from(value: wgt::Extent3d) -> Self { + let wgt::Extent3d { + width, + height, + depth_or_array_layers, + } = value; + Self { + width, + height, + depth: depth_or_array_layers, + } + } +} + +impl From for wgt::Extent3d { + fn from(value: CopyExtent) -> Self { + let CopyExtent { + width, + height, + depth, + } = value; + Self { + width, + height, + depth_or_array_layers: depth, + } + } +} + #[derive(Clone, Debug)] pub struct TextureCopy { pub src_base: TextureCopyBase, From 8d63de77ccbb7829269c096218340e480b3950ed Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Fri, 23 May 2025 17:06:29 -0400 Subject: [PATCH 288/303] refactor(dx12): extract `copy_aligned` in `copy_texture_to_buffer` --- wgpu-hal/src/dx12/command.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index 29b3a725549..85023a8824a 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -653,8 +653,11 @@ impl crate::CommandEncoder for super::CommandEncoder { ) where T: Iterator, { - for r in regions { - let list = self.list.as_ref().unwrap(); + let copy_aligned = |this: &mut Self, + src: &super::Texture, + dst: &super::Buffer, + r: crate::BufferTextureCopy| { + let list = this.list.as_ref().unwrap(); let src_location = Direct3D12::D3D12_TEXTURE_COPY_LOCATION { pResource: unsafe { borrow_interface_temporarily(&src.resource) }, @@ -675,6 +678,10 @@ impl crate::CommandEncoder for super::CommandEncoder { unsafe { list.CopyTextureRegion(&dst_location, 0, 0, 0, &src_location, Some(&src_box)) }; + }; + + for r in regions { + copy_aligned(this, src, dst, r); } } From 46af29df585201b4041a0c58c442d57a97373564 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Mon, 13 Oct 2025 18:22:30 -0400 Subject: [PATCH 289/303] =?UTF-8?q?test(cts):=20add=20`=E2=80=A6,image=5Fc?= =?UTF-8?q?opy:undefined=5Fparams:*`=20with=20current=20failures?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cts_runner/test.lst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cts_runner/test.lst b/cts_runner/test.lst index 624fa1274bc..a5c30eabd1d 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -14,6 +14,15 @@ fails-if(vulkan) webgpu:api,operation,command_buffer,copyTextureToTexture:copy_d webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="stencil8" // Fails with OOM in CI. fails-if(dx12) webgpu:api,operation,command_buffer,image_copy:offsets_and_sizes:* +webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="WriteTexture";checkMethod="FullCopyT2B";dimension="1d" +fails-if(dx12) webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="WriteTexture";checkMethod="FullCopyT2B";dimension="2d" +webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="WriteTexture";checkMethod="FullCopyT2B";dimension="3d" +webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="WriteTexture";checkMethod="PartialCopyT2B";dimension="1d" +fails-if(dx12) webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="WriteTexture";checkMethod="PartialCopyT2B";dimension="2d" +webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="WriteTexture";checkMethod="PartialCopyT2B";dimension="3d" +webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="CopyB2T";checkMethod="FullCopyT2B";dimension="1d" +fails-if(dx12) webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="CopyB2T";checkMethod="FullCopyT2B";dimension="2d" +fails-if(dx12,vulkan,metal) webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="CopyB2T";checkMethod="FullCopyT2B";dimension="3d" webgpu:api,operation,compute,basic:memcpy:* //FAIL: webgpu:api,operation,compute,basic:large_dispatch:* webgpu:api,operation,compute_pipeline,overrides:* From 53c71aeeec664cc60d1d18ae888f7f25716b37a2 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Thu, 22 May 2025 12:51:51 -0400 Subject: [PATCH 290/303] fix(dx12): align tex. <-> buf. copies via intermediate buffer if `!UnrestrictedBufferTextureCopyPitchSupported` --- CHANGELOG.md | 6 + cts_runner/test.lst | 4 +- tests/tests/wgpu-gpu/regression/issue_6827.rs | 12 +- wgpu-hal/src/dx12/adapter.rs | 3 +- wgpu-hal/src/dx12/command.rs | 146 ++++++++++++++++-- wgpu-hal/src/dx12/device.rs | 1 + wgpu-hal/src/dx12/mod.rs | 20 ++- 7 files changed, 166 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fcfec0954a2..8e09ec41a1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,12 @@ Bottom level categories: ## Unreleased +### Bug Fixes + +#### DX12 + +- Align copies b/w textures and buffers via a single intermediate buffer per copy when `D3D12_FEATURE_DATA_D3D12_OPTIONS13.UnrestrictedBufferTextureCopyPitchSupported` is `false`. By @ErichDonGubler in [#7721](https://github.com/gfx-rs/wgpu/pull/7721). + ## v27.0.2 (2025-10-03) ### Bug Fixes diff --git a/cts_runner/test.lst b/cts_runner/test.lst index a5c30eabd1d..4118604fc53 100644 --- a/cts_runner/test.lst +++ b/cts_runner/test.lst @@ -15,13 +15,13 @@ webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:form // Fails with OOM in CI. fails-if(dx12) webgpu:api,operation,command_buffer,image_copy:offsets_and_sizes:* webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="WriteTexture";checkMethod="FullCopyT2B";dimension="1d" -fails-if(dx12) webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="WriteTexture";checkMethod="FullCopyT2B";dimension="2d" +webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="WriteTexture";checkMethod="FullCopyT2B";dimension="2d" webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="WriteTexture";checkMethod="FullCopyT2B";dimension="3d" webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="WriteTexture";checkMethod="PartialCopyT2B";dimension="1d" fails-if(dx12) webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="WriteTexture";checkMethod="PartialCopyT2B";dimension="2d" webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="WriteTexture";checkMethod="PartialCopyT2B";dimension="3d" webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="CopyB2T";checkMethod="FullCopyT2B";dimension="1d" -fails-if(dx12) webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="CopyB2T";checkMethod="FullCopyT2B";dimension="2d" +webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="CopyB2T";checkMethod="FullCopyT2B";dimension="2d" fails-if(dx12,vulkan,metal) webgpu:api,operation,command_buffer,image_copy:undefined_params:initMethod="CopyB2T";checkMethod="FullCopyT2B";dimension="3d" webgpu:api,operation,compute,basic:memcpy:* //FAIL: webgpu:api,operation,compute,basic:large_dispatch:* diff --git a/tests/tests/wgpu-gpu/regression/issue_6827.rs b/tests/tests/wgpu-gpu/regression/issue_6827.rs index 578fac9b7fa..97ad32be412 100644 --- a/tests/tests/wgpu-gpu/regression/issue_6827.rs +++ b/tests/tests/wgpu-gpu/regression/issue_6827.rs @@ -25,17 +25,7 @@ static TEST_SCATTER: GpuTestConfiguration = GpuTestConfiguration::new() .expect_fail(FailureCase::backend_adapter( wgpu::Backends::METAL, "Apple Paravirtual device", // CI on M1 - )) - .expect_fail( - // Unfortunately this depends on if `D3D12_FEATURE_DATA_D3D12_OPTIONS13.UnrestrictedBufferTextureCopyPitchSupported` - // is true, which we have no way to encode. This reproduces in CI though, so not too worried about it. - FailureCase::backend(wgpu::Backends::DX12) - .flaky() - .validation_error( - "D3D12_PLACED_SUBRESOURCE_FOOTPRINT::Offset must be a multiple of 512", - ) - .panic("GraphicsCommandList::close failed: The parameter is incorrect"), - ), + )), ) .run_async(|ctx| async move { run_test(ctx, true).await }); diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index 9d174adf01c..7fb921b1049 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -319,8 +319,7 @@ impl super::Adapter { suballocation_supported: !info.name.contains("Iris(R) Xe"), shader_model, max_sampler_descriptor_heap_size, - _unrestricted_buffer_texture_copy_pitch_supported: - unrestricted_buffer_texture_copy_pitch_supported, + unrestricted_buffer_texture_copy_pitch_supported, }; // Theoretically vram limited, but in practice 2^20 is the limit diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index 85023a8824a..e2382171f9c 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -14,7 +14,7 @@ use crate::{ dxgi::{name::ObjectExt, result::HResult as _}, }, dx12::borrow_interface_temporarily, - AccelerationStructureEntries, + AccelerationStructureEntries, CommandEncoder as _, }; fn make_box(origin: &wgt::Origin3d, size: &crate::CopyExtent) -> Direct3D12::D3D12_BOX { @@ -312,6 +312,78 @@ impl super::CommandEncoder { } } } + + unsafe fn buf_tex_intermediate( + &mut self, + region: crate::BufferTextureCopy, + tex_fmt: wgt::TextureFormat, + copy_op: impl FnOnce(&mut Self, &super::Buffer, wgt::BufferSize, crate::BufferTextureCopy) -> T, + ) -> (T, super::Buffer) { + let size = { + let copy_info = region.buffer_layout.get_buffer_texture_copy_info( + tex_fmt, + region.texture_base.aspect.map(), + ®ion.size.into(), + ); + copy_info.unwrap().bytes_in_copy + }; + + let size = wgt::BufferSize::new(size).unwrap(); + + let buffer = { + let (resource, allocation) = + super::suballocation::DeviceAllocationContext::from(&*self) + .create_buffer(&crate::BufferDescriptor { + label: None, + size: size.get(), + usage: wgt::BufferUses::COPY_SRC | wgt::BufferUses::COPY_DST, + memory_flags: crate::MemoryFlags::empty(), + }) + .expect(concat!( + "internal error: ", + "failed to allocate intermediate buffer ", + "for offset alignment" + )); + super::Buffer { + resource, + size: size.get(), + allocation, + } + }; + + let mut region = region; + region.buffer_layout.offset = 0; + + unsafe { + self.transition_buffers( + [crate::BufferBarrier { + buffer: &buffer, + usage: crate::StateTransition { + from: wgt::BufferUses::empty(), + to: wgt::BufferUses::COPY_DST, + }, + }] + .into_iter(), + ) + }; + + let t = copy_op(self, &buffer, size, region); + + unsafe { + self.transition_buffers( + [crate::BufferBarrier { + buffer: &buffer, + usage: crate::StateTransition { + from: wgt::BufferUses::COPY_DST, + to: wgt::BufferUses::COPY_SRC, + }, + }] + .into_iter(), + ) + }; + + (t, buffer) + } } impl crate::CommandEncoder for super::CommandEncoder { @@ -366,6 +438,7 @@ impl crate::CommandEncoder for super::CommandEncoder { Ok(super::CommandBuffer { raw }) } unsafe fn reset_all>(&mut self, command_buffers: I) { + self.intermediate_copy_bufs.clear(); for cmd_buf in command_buffers { self.free_lists.push(cmd_buf.raw); } @@ -612,31 +685,59 @@ impl crate::CommandEncoder for super::CommandEncoder { ) where T: Iterator, { - for r in regions { + let offset_alignment = self.shared.private_caps.texture_data_placement_alignment(); + + for naive_copy_region in regions { + let is_offset_aligned = naive_copy_region.buffer_layout.offset % offset_alignment == 0; + let (final_copy_region, src) = if is_offset_aligned { + (naive_copy_region, src) + } else { + let (intermediate_to_dst_region, intermediate_buf) = unsafe { + let src_offset = naive_copy_region.buffer_layout.offset; + self.buf_tex_intermediate( + naive_copy_region, + dst.format, + |this, buf, size, intermediate_to_dst_region| { + let layout = crate::BufferCopy { + src_offset, + dst_offset: 0, + size, + }; + this.copy_buffer_to_buffer(src, buf, [layout].into_iter()); + intermediate_to_dst_region + }, + ) + }; + self.intermediate_copy_bufs.push(intermediate_buf); + let intermediate_buf = self.intermediate_copy_bufs.last().unwrap(); + (intermediate_to_dst_region, intermediate_buf) + }; + let list = self.list.as_ref().unwrap(); let src_location = Direct3D12::D3D12_TEXTURE_COPY_LOCATION { pResource: unsafe { borrow_interface_temporarily(&src.resource) }, Type: Direct3D12::D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, Anonymous: Direct3D12::D3D12_TEXTURE_COPY_LOCATION_0 { - PlacedFootprint: r.to_subresource_footprint(dst.format), + PlacedFootprint: final_copy_region.to_subresource_footprint(dst.format), }, }; let dst_location = Direct3D12::D3D12_TEXTURE_COPY_LOCATION { pResource: unsafe { borrow_interface_temporarily(&dst.resource) }, Type: Direct3D12::D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, Anonymous: Direct3D12::D3D12_TEXTURE_COPY_LOCATION_0 { - SubresourceIndex: dst.calc_subresource_for_copy(&r.texture_base), + SubresourceIndex: dst + .calc_subresource_for_copy(&final_copy_region.texture_base), }, }; - let src_box = make_box(&wgt::Origin3d::ZERO, &r.size); + let src_box = make_box(&wgt::Origin3d::ZERO, &final_copy_region.size); unsafe { list.CopyTextureRegion( &dst_location, - r.texture_base.origin.x, - r.texture_base.origin.y, - r.texture_base.origin.z, + final_copy_region.texture_base.origin.x, + final_copy_region.texture_base.origin.y, + final_copy_region.texture_base.origin.z, &src_location, Some(&src_box), ) @@ -680,8 +781,35 @@ impl crate::CommandEncoder for super::CommandEncoder { }; }; + let offset_alignment = self.shared.private_caps.texture_data_placement_alignment(); + for r in regions { - copy_aligned(this, src, dst, r); + let is_offset_aligned = r.buffer_layout.offset % offset_alignment == 0; + if is_offset_aligned { + copy_aligned(self, src, dst, r) + } else { + let orig_offset = r.buffer_layout.offset; + let (intermediate_to_dst_region, src) = unsafe { + self.buf_tex_intermediate( + r, + src.format, + |this, buf, size, intermediate_region| { + copy_aligned(this, src, buf, intermediate_region); + crate::BufferCopy { + src_offset: 0, + dst_offset: orig_offset, + size, + } + }, + ) + }; + + unsafe { + self.copy_buffer_to_buffer(&src, dst, [intermediate_to_dst_region].into_iter()); + } + + self.intermediate_copy_bufs.push(src); + }; } } diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 473423b8145..5a6a489cba2 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -796,6 +796,7 @@ impl crate::Device for super::Device { mem_allocator: self.mem_allocator.clone(), rtv_pool: Arc::clone(&self.rtv_pool), temp_rtv_handles: Vec::new(), + intermediate_copy_bufs: Vec::new(), null_rtv_handle: self.null_rtv_handle, list: None, free_lists: Vec::new(), diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 16c967aa9f4..58544cab732 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -96,7 +96,11 @@ use windows::{ core::{Free, Interface}, Win32::{ Foundation, - Graphics::{Direct3D, Direct3D12, DirectComposition, Dxgi}, + Graphics::{ + Direct3D, + Direct3D12::{self, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT}, + DirectComposition, Dxgi, + }, System::Threading, }, }; @@ -601,7 +605,17 @@ struct PrivateCapabilities { suballocation_supported: bool, shader_model: naga::back::hlsl::ShaderModel, max_sampler_descriptor_heap_size: u32, - _unrestricted_buffer_texture_copy_pitch_supported: bool, + unrestricted_buffer_texture_copy_pitch_supported: bool, +} + +impl PrivateCapabilities { + fn texture_data_placement_alignment(&self) -> u64 { + if self.unrestricted_buffer_texture_copy_pitch_supported { + 4 + } else { + D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT.into() + } + } } #[derive(Default)] @@ -841,6 +855,8 @@ pub struct CommandEncoder { rtv_pool: Arc>, temp_rtv_handles: Vec, + intermediate_copy_bufs: Vec, + null_rtv_handle: descriptor::Handle, list: Option, free_lists: Vec, From ffcb07e7ce165ce1a98a1508afa986975792e102 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Fri, 17 Oct 2025 11:30:07 -0400 Subject: [PATCH 291/303] [build] Commit Cargo.lock changes from the v27.0.2 version bump --- Cargo.lock | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b16aed647cb..1f1c018a977 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -966,7 +966,7 @@ checksum = "e2931af7e13dc045d8e9d26afccc6fa115d64e115c9c84b1166288b46f6782c2" [[package]] name = "cts_runner" -version = "27.0.1" +version = "27.0.2" dependencies = [ "deno_console", "deno_core", @@ -1920,7 +1920,7 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" [[package]] name = "hlsl-snapshots" -version = "27.0.1" +version = "27.0.2" dependencies = [ "anyhow", "nanoserde", @@ -2328,7 +2328,7 @@ checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" [[package]] name = "lock-analyzer" -version = "27.0.1" +version = "27.0.2" dependencies = [ "anyhow", "ron", @@ -2467,7 +2467,7 @@ dependencies = [ [[package]] name = "naga" -version = "27.0.1" +version = "27.0.2" dependencies = [ "arbitrary", "arrayvec", @@ -2504,7 +2504,7 @@ dependencies = [ [[package]] name = "naga-cli" -version = "27.0.1" +version = "27.0.2" dependencies = [ "anyhow", "argh", @@ -2517,7 +2517,7 @@ dependencies = [ [[package]] name = "naga-fuzz" -version = "27.0.1" +version = "27.0.2" dependencies = [ "arbitrary", "cfg_aliases 0.2.1", @@ -2527,7 +2527,7 @@ dependencies = [ [[package]] name = "naga-test" -version = "27.0.1" +version = "27.0.2" dependencies = [ "bitflags 2.9.4", "env_logger", @@ -3172,7 +3172,7 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "player" -version = "27.0.1" +version = "27.0.2" dependencies = [ "bytemuck", "env_logger", @@ -4784,7 +4784,7 @@ dependencies = [ [[package]] name = "wgpu" -version = "27.0.1" +version = "27.0.2" dependencies = [ "arrayvec", "bitflags 2.9.4", @@ -4812,7 +4812,7 @@ dependencies = [ [[package]] name = "wgpu-benchmark" -version = "27.0.1" +version = "27.0.2" dependencies = [ "bincode 2.0.1", "bytemuck", @@ -4829,7 +4829,7 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "27.0.1" +version = "27.0.2" dependencies = [ "arrayvec", "bit-set", @@ -4862,28 +4862,28 @@ dependencies = [ [[package]] name = "wgpu-core-deps-apple" -version = "27.0.1" +version = "27.0.2" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-emscripten" -version = "27.0.1" +version = "27.0.2" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-wasm" -version = "27.0.1" +version = "27.0.2" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-windows-linux-android" -version = "27.0.1" +version = "27.0.2" dependencies = [ "wgpu-hal", ] @@ -4918,7 +4918,7 @@ dependencies = [ [[package]] name = "wgpu-examples" -version = "27.0.1" +version = "27.0.2" dependencies = [ "bytemuck", "cfg-if", @@ -4950,7 +4950,7 @@ dependencies = [ [[package]] name = "wgpu-hal" -version = "27.0.1" +version = "27.0.2" dependencies = [ "android_system_properties", "arrayvec", @@ -5005,7 +5005,7 @@ dependencies = [ [[package]] name = "wgpu-info" -version = "27.0.1" +version = "27.0.2" dependencies = [ "anyhow", "bitflags 2.9.4", @@ -5019,7 +5019,7 @@ dependencies = [ [[package]] name = "wgpu-macros" -version = "27.0.1" +version = "27.0.2" dependencies = [ "heck", "quote", @@ -5028,7 +5028,7 @@ dependencies = [ [[package]] name = "wgpu-test" -version = "27.0.1" +version = "27.0.2" dependencies = [ "anyhow", "approx", @@ -5069,7 +5069,7 @@ dependencies = [ [[package]] name = "wgpu-types" -version = "27.0.1" +version = "27.0.2" dependencies = [ "bitflags 2.9.4", "bytemuck", From 787aa723a1ef96a9604df58ce7321bda139fdeea Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Mon, 20 Oct 2025 15:45:06 -0700 Subject: [PATCH 292/303] Remove `!encoder.is_open` assertion The encoder will be open if `CommandEncoder::as_hal_mut` has been used. --- CHANGELOG.md | 8 ++++++++ wgpu-core/src/command/mod.rs | 6 +----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e09ec41a1e..99c6112f7b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,10 +42,18 @@ Bottom level categories: ### Bug Fixes +#### General + +- Remove an assertion that causes problems if `CommandEncoder::as_hal_mut` is used. By @andyleiserson in [#8387](https://github.com/gfx-rs/wgpu/pull/8387). + #### DX12 - Align copies b/w textures and buffers via a single intermediate buffer per copy when `D3D12_FEATURE_DATA_D3D12_OPTIONS13.UnrestrictedBufferTextureCopyPitchSupported` is `false`. By @ErichDonGubler in [#7721](https://github.com/gfx-rs/wgpu/pull/7721). +#### Naga + +- Fix a bug that resulted in the Metal error `program scope variable must reside in constant address space` in some cases. Backport of [#8311](https://github.com/gfx-rs/wgpu/pull/8311) by @teoxoy. + ## v27.0.2 (2025-10-03) ### Bug Fixes diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 887c19fb357..ccc1a850dc6 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -357,11 +357,7 @@ impl CommandEncoderStatus { // Replace our state with `Consumed`, and return either the inner // state or an error, to be transferred to the command buffer. match mem::replace(self, Self::Consumed) { - Self::Recording(inner) => { - // Nothing should have opened the encoder yet. - assert!(!inner.encoder.is_open); - Self::Finished(inner) - } + Self::Recording(inner) => Self::Finished(inner), Self::Consumed | Self::Finished(_) => Self::Error(EncoderStateError::Ended.into()), Self::Locked(_) => Self::Error(EncoderStateError::Locked.into()), st @ Self::Error(_) => st, From 69fda60787e65a40323c5f0db7a0941112d20ac1 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Tue, 21 Oct 2025 15:49:10 -0400 Subject: [PATCH 293/303] style: format `CHANGELOG.md` with `prettier` --- CHANGELOG.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 99c6112f7b9..b3790909e67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,7 +74,7 @@ Bottom level categories: #### Deferred command buffer actions: `map_buffer_on_submit` and `on_submitted_work_done` -You may schedule buffer mapping and a submission-complete callback to run automatically after you submit, directly from encoders, command buffers, and passes. +You may schedule buffer mapping and a submission-complete callback to run automatically after you submit, directly from encoders, command buffers, and passes. ```rust // Record some GPU work so the submission isn't empty and touches `buffer`. @@ -131,6 +131,7 @@ By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). We have added `Features::EXPERIMENTAL_PRECOMPILED_SHADERS`, replacing existing passthrough types with a unified `CreateShaderModuleDescriptorPassthrough` which allows passing multiple shader codes for different backends. By @SupaMaggie70Incorporated in [#7834](https://github.com/gfx-rs/wgpu/pull/7834) Difference for SPIR-V passthrough: + ```diff - device.create_shader_module_passthrough(wgpu::ShaderModuleDescriptorPassthrough::SpirV( - wgpu::ShaderModuleDescriptorSpirV { @@ -145,6 +146,7 @@ Difference for SPIR-V passthrough: + ..Default::default() }) ``` + This allows using precompiled shaders without manually checking which backend's code to pass, for example if you have shaders precompiled for both DXIL and SPIR-V. #### Buffer mapping apis no longer have lifetimes @@ -181,14 +183,13 @@ By @cwfitzgerald in [#8163](https://github.com/gfx-rs/wgpu/pull/8163). #### Multi-draw indirect is now unconditionally supported when indirect draws are supported -We have removed `Features::MULTI_DRAW_INDIRECT` as it was unconditionally available on all platforms. +We have removed `Features::MULTI_DRAW_INDIRECT` as it was unconditionally available on all platforms. `RenderPass::multi_draw_indirect` is now available if the device supports downlevel flag `DownlevelFlags::INDIRECT_EXECUTION`. The `Feature::MULTI_DRAW_INDIRECT_COUNT` feature can be used to determine if multi-draw is supported natively on the device. This is helpful to know if you are using spirv-passthrough and `gl_DrawID` in your shaders. By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). - #### `wgpu::PollType::Wait` has now an optional timeout We removed `wgpu::PollType::WaitForSubmissionIndex` and added fields to `wgpu::PollType::Wait` in order to express timeouts. @@ -218,8 +219,8 @@ Before/after for `wgpu::PollType::WaitForSubmissionIndex`: ⚠️ Previously, both `wgpu::PollType::WaitForSubmissionIndex` and `wgpu::PollType::Wait` had a hard-coded timeout of 60 seconds. - To wait indefinitely on the latest submission, you can also use the `wait_indefinitely` convenience function: + ```rust device.poll(wgpu::PollType::wait_indefinitely()); ``` From c5f702673eb6b8904d33a22034a20cd49c39d023 Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Tue, 21 Oct 2025 10:33:48 -0700 Subject: [PATCH 294/303] [build] Waive cargo deny for unmaintained `unic-*` crates Related to #8393. --- .deny.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.deny.toml b/.deny.toml index d5c2534f641..1751cf30f4b 100644 --- a/.deny.toml +++ b/.deny.toml @@ -40,6 +40,13 @@ ignore = [ # It's a dependency of `metal` (which is to be replaced with `objc2-metal`), and a # transitive dependency of `deno`. https://github.com/gfx-rs/wgpu/issues/7873 "RUSTSEC-2024-0436", + # `unic-*` crates are no longer maintained https://rustsec.org/advisories/RUSTSEC-2025-0100 + # These are used via `deno`. https://github.com/gfx-rs/wgpu/issues/8393 + "RUSTSEC-2025-0075", + "RUSTSEC-2025-0080", + "RUSTSEC-2025-0081", + "RUSTSEC-2025-0098", + "RUSTSEC-2025-0100", ] [licenses] From 240499299274654f93f784f9e8af60c331acb804 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Tue, 21 Oct 2025 17:50:32 -0400 Subject: [PATCH 295/303] chore: ignore `windows-sys` 0.59.0 in `cargo deny` checks --- .deny.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/.deny.toml b/.deny.toml index 1751cf30f4b..4634adcac85 100644 --- a/.deny.toml +++ b/.deny.toml @@ -2,6 +2,7 @@ multiple-versions = "deny" skip-tree = [ { name = "windows-sys", version = "0.45" }, + { name = "windows-sys", version = "0.59" }, { name = "winit", version = "0.29" }, { name = "rustc-hash", version = "1.1.0" }, From e17bd3aae12e96817af85d4454af6cca32c16535 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Tue, 21 Oct 2025 15:49:10 -0400 Subject: [PATCH 296/303] docs(README): add backport link --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3790909e67..b299ec53c10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,7 +48,7 @@ Bottom level categories: #### DX12 -- Align copies b/w textures and buffers via a single intermediate buffer per copy when `D3D12_FEATURE_DATA_D3D12_OPTIONS13.UnrestrictedBufferTextureCopyPitchSupported` is `false`. By @ErichDonGubler in [#7721](https://github.com/gfx-rs/wgpu/pull/7721). +- Align copies b/w textures and buffers via a single intermediate buffer per copy when `D3D12_FEATURE_DATA_D3D12_OPTIONS13.UnrestrictedBufferTextureCopyPitchSupported` is `false`. By @ErichDonGubler in [#7721](https://github.com/gfx-rs/wgpu/pull/7721), backported in [#8374](https://github.com/gfx-rs/wgpu/pull/8374). #### Naga From 459e34abe69f8085d55b19eaf36087e3f1c2d886 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Tue, 21 Oct 2025 15:49:10 -0400 Subject: [PATCH 297/303] docs(CHANGELOG): hoist backport entry for #8311 to proper place, lowercase `naga` --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b299ec53c10..3fc51b26a84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,10 @@ Bottom level categories: ### Bug Fixes +#### naga + +- Fix a bug that resulted in the Metal error `program scope variable must reside in constant address space` in some cases. Backport of [#8311](https://github.com/gfx-rs/wgpu/pull/8311) by @teoxoy. + #### General - Remove an assertion that causes problems if `CommandEncoder::as_hal_mut` is used. By @andyleiserson in [#8387](https://github.com/gfx-rs/wgpu/pull/8387). @@ -50,10 +54,6 @@ Bottom level categories: - Align copies b/w textures and buffers via a single intermediate buffer per copy when `D3D12_FEATURE_DATA_D3D12_OPTIONS13.UnrestrictedBufferTextureCopyPitchSupported` is `false`. By @ErichDonGubler in [#7721](https://github.com/gfx-rs/wgpu/pull/7721), backported in [#8374](https://github.com/gfx-rs/wgpu/pull/8374). -#### Naga - -- Fix a bug that resulted in the Metal error `program scope variable must reside in constant address space` in some cases. Backport of [#8311](https://github.com/gfx-rs/wgpu/pull/8311) by @teoxoy. - ## v27.0.2 (2025-10-03) ### Bug Fixes From d61dc3af8856f0cd9023c5e888b791d1b7118559 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Tue, 21 Oct 2025 15:49:10 -0400 Subject: [PATCH 298/303] chore: prep. for 27.0.3 release --- CHANGELOG.md | 4 ++++ Cargo.lock | 42 +++++++++++++++++++++--------------------- Cargo.toml | 2 +- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fc51b26a84..3a1dfea3a7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,10 @@ Bottom level categories: ## Unreleased +## v27.0.3 (2025-10-22) + +This release includes `naga`, `wgpu-core` and `wgpu-hal` version `27.0.3`. All other crates remain at their previous versions. + ### Bug Fixes #### naga diff --git a/Cargo.lock b/Cargo.lock index 1f1c018a977..af8892b537a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -966,7 +966,7 @@ checksum = "e2931af7e13dc045d8e9d26afccc6fa115d64e115c9c84b1166288b46f6782c2" [[package]] name = "cts_runner" -version = "27.0.2" +version = "27.0.3" dependencies = [ "deno_console", "deno_core", @@ -1920,7 +1920,7 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" [[package]] name = "hlsl-snapshots" -version = "27.0.2" +version = "27.0.3" dependencies = [ "anyhow", "nanoserde", @@ -2328,7 +2328,7 @@ checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" [[package]] name = "lock-analyzer" -version = "27.0.2" +version = "27.0.3" dependencies = [ "anyhow", "ron", @@ -2467,7 +2467,7 @@ dependencies = [ [[package]] name = "naga" -version = "27.0.2" +version = "27.0.3" dependencies = [ "arbitrary", "arrayvec", @@ -2504,7 +2504,7 @@ dependencies = [ [[package]] name = "naga-cli" -version = "27.0.2" +version = "27.0.3" dependencies = [ "anyhow", "argh", @@ -2517,7 +2517,7 @@ dependencies = [ [[package]] name = "naga-fuzz" -version = "27.0.2" +version = "27.0.3" dependencies = [ "arbitrary", "cfg_aliases 0.2.1", @@ -2527,7 +2527,7 @@ dependencies = [ [[package]] name = "naga-test" -version = "27.0.2" +version = "27.0.3" dependencies = [ "bitflags 2.9.4", "env_logger", @@ -3172,7 +3172,7 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "player" -version = "27.0.2" +version = "27.0.3" dependencies = [ "bytemuck", "env_logger", @@ -4784,7 +4784,7 @@ dependencies = [ [[package]] name = "wgpu" -version = "27.0.2" +version = "27.0.3" dependencies = [ "arrayvec", "bitflags 2.9.4", @@ -4812,7 +4812,7 @@ dependencies = [ [[package]] name = "wgpu-benchmark" -version = "27.0.2" +version = "27.0.3" dependencies = [ "bincode 2.0.1", "bytemuck", @@ -4829,7 +4829,7 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "27.0.2" +version = "27.0.3" dependencies = [ "arrayvec", "bit-set", @@ -4862,28 +4862,28 @@ dependencies = [ [[package]] name = "wgpu-core-deps-apple" -version = "27.0.2" +version = "27.0.3" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-emscripten" -version = "27.0.2" +version = "27.0.3" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-wasm" -version = "27.0.2" +version = "27.0.3" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-windows-linux-android" -version = "27.0.2" +version = "27.0.3" dependencies = [ "wgpu-hal", ] @@ -4918,7 +4918,7 @@ dependencies = [ [[package]] name = "wgpu-examples" -version = "27.0.2" +version = "27.0.3" dependencies = [ "bytemuck", "cfg-if", @@ -4950,7 +4950,7 @@ dependencies = [ [[package]] name = "wgpu-hal" -version = "27.0.2" +version = "27.0.3" dependencies = [ "android_system_properties", "arrayvec", @@ -5005,7 +5005,7 @@ dependencies = [ [[package]] name = "wgpu-info" -version = "27.0.2" +version = "27.0.3" dependencies = [ "anyhow", "bitflags 2.9.4", @@ -5019,7 +5019,7 @@ dependencies = [ [[package]] name = "wgpu-macros" -version = "27.0.2" +version = "27.0.3" dependencies = [ "heck", "quote", @@ -5028,7 +5028,7 @@ dependencies = [ [[package]] name = "wgpu-test" -version = "27.0.2" +version = "27.0.3" dependencies = [ "anyhow", "approx", @@ -5069,7 +5069,7 @@ dependencies = [ [[package]] name = "wgpu-types" -version = "27.0.2" +version = "27.0.3" dependencies = [ "bitflags 2.9.4", "bytemuck", diff --git a/Cargo.toml b/Cargo.toml index 175175f2449..bd5c1995bbf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,7 +61,7 @@ keywords = ["graphics"] license = "MIT OR Apache-2.0" homepage = "https://wgpu.rs/" repository = "https://github.com/gfx-rs/wgpu" -version = "27.0.2" +version = "27.0.3" authors = ["gfx-rs developers"] [workspace.dependencies] From 542d7c98cee1e5ea6a085e032102643f0c54e9aa Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Wed, 22 Oct 2025 08:50:00 -0700 Subject: [PATCH 299/303] Remove fragile dependency constraint on `ordered-float`. (#8371) Bounds like `<=5.0` should never be used unless necessary to avoid bugs, because it will cause a build failure if another package has a requirement like `~5.1.0` or `>=5.1.0`. Upper bounds should always cut at a major version boundary, not before it. --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index af8892b537a..b6bca8059db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3039,9 +3039,9 @@ dependencies = [ [[package]] name = "ordered-float" -version = "5.0.0" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2c1f9f56e534ac6a9b8a4600bdf0f530fb393b5f393e7b4d03489c3cf0c3f01" +checksum = "7f4779c6901a562440c3786d08192c6fbda7c1c2060edd10006b05ee35d10f2d" dependencies = [ "num-traits", ] diff --git a/Cargo.toml b/Cargo.toml index bd5c1995bbf..cf018c81f50 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -153,7 +153,7 @@ obj = "0.10" # NOTE: once_cell/std is *required* for some commonly-used features, selecting this per crate once_cell = { version = "1.21", default-features = false } # Firefox has 3.4.0 vendored, so we allow that version in our dependencies -ordered-float = { version = ">=3, <=5.0", default-features = false } +ordered-float = { version = ">=3, <6.0", default-features = false } parking_lot = "0.12.3" petgraph = { version = "0.8", default-features = false } pico-args = { version = "0.5", features = [ From c06b23b11c42e3f9c4887651bc1b1d63e88cd96e Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Thu, 23 Oct 2025 00:51:40 -0400 Subject: [PATCH 300/303] docs(CHANGELOG): import fixups of old entries from `trunk` (#8406) --- CHANGELOG.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a1dfea3a7a..442340252c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -190,7 +190,8 @@ By @cwfitzgerald in [#8163](https://github.com/gfx-rs/wgpu/pull/8163). We have removed `Features::MULTI_DRAW_INDIRECT` as it was unconditionally available on all platforms. `RenderPass::multi_draw_indirect` is now available if the device supports downlevel flag `DownlevelFlags::INDIRECT_EXECUTION`. -The `Feature::MULTI_DRAW_INDIRECT_COUNT` feature can be used to determine if multi-draw is supported natively on the device. This is helpful to know if you are using spirv-passthrough and `gl_DrawID` in your shaders. +If you are using spirv-passthrough with multi-draw indirect and `gl_DrawID`, you can know if `MULTI_DRAW_INDIRECT` is being emulated +by if the `Feature::MULTI_DRAW_INDIRECT_COUNT` feature is available on the device, this feature cannot be emulated efficicently. By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162). @@ -446,7 +447,7 @@ By @Vecvec in [#7829](https://github.com/gfx-rs/wgpu/pull/7829). #### naga - naga now infers the correct binding layout when a resource appears only in an assignment to `_`. By @andyleiserson in [#7540](https://github.com/gfx-rs/wgpu/pull/7540). -- Implement `dot4U8Packed` and `dot4I8Packed` for all backends, using specialized intrinsics on SPIR-V, HSLS, and Metal if available, and polyfills everywhere else. By @robamler in [#7494](https://github.com/gfx-rs/wgpu/pull/7494), [#7574](https://github.com/gfx-rs/wgpu/pull/7574), and [#7653](https://github.com/gfx-rs/wgpu/pull/7653). +- Implement `dot4U8Packed` and `dot4I8Packed` for all backends, using specialized intrinsics on SPIR-V, HLSL, and Metal if available, and polyfills everywhere else. By @robamler in [#7494](https://github.com/gfx-rs/wgpu/pull/7494), [#7574](https://github.com/gfx-rs/wgpu/pull/7574), and [#7653](https://github.com/gfx-rs/wgpu/pull/7653). - Add polyfilled `pack4x{I,U}8Clamped` built-ins to all backends and WGSL frontend. By @ErichDonGubler in [#7546](https://github.com/gfx-rs/wgpu/pull/7546). - Allow textureLoad's sample index arg to be unsigned. By @jimblandy in [#7625](https://github.com/gfx-rs/wgpu/pull/7625). - Properly convert arguments to atomic operations. By @jimblandy in [#7573](https://github.com/gfx-rs/wgpu/pull/7573). @@ -3948,7 +3949,7 @@ DeviceDescriptor { - Explicitly set Vulkan debug message types instead of !empty() by @victorvde in [#2321](https://github.com/gfx-rs/wgpu/pull/2321) - Use stencil read/write masks by @kvark in [#2382](https://github.com/gfx-rs/wgpu/pull/2382) -- Vulkan: correctly set INDEPENDENT_BLEND,make runable on Android 8.x by @jinleili in [#2498](https://github.com/gfx-rs/wgpu/pull/2498) +- Vulkan: correctly set INDEPENDENT_BLEND,make runnable on Android 8.x by @jinleili in [#2498](https://github.com/gfx-rs/wgpu/pull/2498) - Fix ASTC format mapping by @kvark in [#2476](https://github.com/gfx-rs/wgpu/pull/2476) - Support flipped Y on VK 1.1 devices by @cwfitzgerald in [#2512](https://github.com/gfx-rs/wgpu/pull/2512) - Fixed builtin(primitive_index) for vulkan backend by @kwillemsen in [#2716](https://github.com/gfx-rs/wgpu/pull/2716) From 386d4437682cefb2c2296bba38871bd541ad1cdc Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Wed, 22 Oct 2025 13:59:24 -0400 Subject: [PATCH 301/303] [hal/vulkan] Wait for fence signalled in vkAcquireNextImage --- wgpu-hal/src/vulkan/device.rs | 8 ++++++++ wgpu-hal/src/vulkan/instance.rs | 28 +++++++++++++++++++++++++++- wgpu-hal/src/vulkan/mod.rs | 2 ++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 1a710cb2d99..26c4fa7e025 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -578,6 +578,13 @@ impl super::Device { let images = unsafe { functor.get_swapchain_images(raw) }.map_err(super::map_host_device_oom_err)?; + let fence = unsafe { + self.shared + .raw + .create_fence(&vk::FenceCreateInfo::default(), None) + .map_err(super::map_host_device_oom_err)? + }; + // NOTE: It's important that we define the same number of acquire/present semaphores // as we will need to index into them with the image index. let acquire_semaphores = (0..=images.len()) @@ -597,6 +604,7 @@ impl super::Device { functor, device: Arc::clone(&self.shared), images, + fence, config: config.clone(), acquire_semaphores, next_acquire_index: 0, diff --git a/wgpu-hal/src/vulkan/instance.rs b/wgpu-hal/src/vulkan/instance.rs index 572ffcd3f0f..6cb8515dcee 100644 --- a/wgpu-hal/src/vulkan/instance.rs +++ b/wgpu-hal/src/vulkan/instance.rs @@ -187,6 +187,8 @@ impl super::Swapchain { }; }; + unsafe { device.destroy_fence(self.fence, None) } + // We cannot take this by value, as the function returns `self`. for semaphore in self.acquire_semaphores.drain(..) { let arc_removed = Arc::into_inner(semaphore).expect( @@ -1115,7 +1117,7 @@ impl crate::Surface for super::Surface { swapchain.raw, timeout_ns, acquire_semaphore_guard.acquire, - vk::Fence::null(), + swapchain.fence, ) } { // We treat `VK_SUBOPTIMAL_KHR` as `VK_SUCCESS` on Android. @@ -1138,6 +1140,30 @@ impl crate::Surface for super::Surface { } }; + // Wait for the image was acquired to be fully ready to be rendered too. + // + // This wait is very important on Windows to avoid bad frame pacing on + // Windows where the Vulkan driver is using a DXGI swapchain. See + // https://github.com/gfx-rs/wgpu/issues/8310 and + // https://github.com/gfx-rs/wgpu/issues/8354 for more details. + // + // On other platforms, this wait may serve to slightly decrease frame + // latency, depending on how the platform implements waiting within + // acquire. + unsafe { + swapchain + .device + .raw + .wait_for_fences(&[swapchain.fence], false, timeout_ns) + .map_err(super::map_host_device_oom_and_lost_err)?; + + swapchain + .device + .raw + .reset_fences(&[swapchain.fence]) + .map_err(super::map_host_device_oom_and_lost_err)?; + } + drop(acquire_semaphore_guard); // We only advance the surface semaphores if we successfully acquired an image, otherwise // we should try to re-acquire using the same semaphores. diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 183950b71f0..e2905ac2ac2 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -387,6 +387,8 @@ struct Swapchain { functor: khr::swapchain::Device, device: Arc, images: Vec, + /// Fence used to wait on the acquired image. + fence: vk::Fence, config: crate::SurfaceConfiguration, /// Semaphores used between image acquisition and the first submission From af91efa93da2af9366b252ed7b9a089175f4874e Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Thu, 23 Oct 2025 13:19:34 -0400 Subject: [PATCH 302/303] Bump version to v27.0.4 --- CHANGELOG.md | 10 ++++++++++ Cargo.lock | 50 +++++++++++++++++++++++++------------------------- Cargo.toml | 2 +- 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 442340252c9..ed9adec5b2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,16 @@ Bottom level categories: ## Unreleased +## v27.0.4 (2025-10-23) + +This release includes `wgpu-hal` version `27.0.4`. All other crates remain at their previous versions. + +### Bug Fixes + +#### Vulkan + +- Work around extremely poor frame pacing from AMD and Nvidia cards on Windows in `Fifo` and `FifoRelaxed` present modes. This is due to the drivers implicitly using a DXGI (Direct3D) swapchain to implement these modes and it having vastly different timing properties. See https://github.com/gfx-rs/wgpu/issues/8310 and https://github.com/gfx-rs/wgpu/issues/8354 for more information. By @cwfitzgerald in [#8420](https://github.com/gfx-rs/wgpu/pull/8420). + ## v27.0.3 (2025-10-22) This release includes `naga`, `wgpu-core` and `wgpu-hal` version `27.0.3`. All other crates remain at their previous versions. diff --git a/Cargo.lock b/Cargo.lock index b6bca8059db..f3a4f10c20e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -966,7 +966,7 @@ checksum = "e2931af7e13dc045d8e9d26afccc6fa115d64e115c9c84b1166288b46f6782c2" [[package]] name = "cts_runner" -version = "27.0.3" +version = "27.0.4" dependencies = [ "deno_console", "deno_core", @@ -1403,7 +1403,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1920,7 +1920,7 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" [[package]] name = "hlsl-snapshots" -version = "27.0.3" +version = "27.0.4" dependencies = [ "anyhow", "nanoserde", @@ -2328,7 +2328,7 @@ checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" [[package]] name = "lock-analyzer" -version = "27.0.3" +version = "27.0.4" dependencies = [ "anyhow", "ron", @@ -2467,7 +2467,7 @@ dependencies = [ [[package]] name = "naga" -version = "27.0.3" +version = "27.0.4" dependencies = [ "arbitrary", "arrayvec", @@ -2504,7 +2504,7 @@ dependencies = [ [[package]] name = "naga-cli" -version = "27.0.3" +version = "27.0.4" dependencies = [ "anyhow", "argh", @@ -2517,7 +2517,7 @@ dependencies = [ [[package]] name = "naga-fuzz" -version = "27.0.3" +version = "27.0.4" dependencies = [ "arbitrary", "cfg_aliases 0.2.1", @@ -2527,7 +2527,7 @@ dependencies = [ [[package]] name = "naga-test" -version = "27.0.3" +version = "27.0.4" dependencies = [ "bitflags 2.9.4", "env_logger", @@ -3172,7 +3172,7 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "player" -version = "27.0.3" +version = "27.0.4" dependencies = [ "bytemuck", "env_logger", @@ -3582,7 +3582,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3595,7 +3595,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.11.0", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4784,7 +4784,7 @@ dependencies = [ [[package]] name = "wgpu" -version = "27.0.3" +version = "27.0.4" dependencies = [ "arrayvec", "bitflags 2.9.4", @@ -4812,7 +4812,7 @@ dependencies = [ [[package]] name = "wgpu-benchmark" -version = "27.0.3" +version = "27.0.4" dependencies = [ "bincode 2.0.1", "bytemuck", @@ -4829,7 +4829,7 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "27.0.3" +version = "27.0.4" dependencies = [ "arrayvec", "bit-set", @@ -4862,28 +4862,28 @@ dependencies = [ [[package]] name = "wgpu-core-deps-apple" -version = "27.0.3" +version = "27.0.4" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-emscripten" -version = "27.0.3" +version = "27.0.4" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-wasm" -version = "27.0.3" +version = "27.0.4" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-windows-linux-android" -version = "27.0.3" +version = "27.0.4" dependencies = [ "wgpu-hal", ] @@ -4918,7 +4918,7 @@ dependencies = [ [[package]] name = "wgpu-examples" -version = "27.0.3" +version = "27.0.4" dependencies = [ "bytemuck", "cfg-if", @@ -4950,7 +4950,7 @@ dependencies = [ [[package]] name = "wgpu-hal" -version = "27.0.3" +version = "27.0.4" dependencies = [ "android_system_properties", "arrayvec", @@ -5005,7 +5005,7 @@ dependencies = [ [[package]] name = "wgpu-info" -version = "27.0.3" +version = "27.0.4" dependencies = [ "anyhow", "bitflags 2.9.4", @@ -5019,7 +5019,7 @@ dependencies = [ [[package]] name = "wgpu-macros" -version = "27.0.3" +version = "27.0.4" dependencies = [ "heck", "quote", @@ -5028,7 +5028,7 @@ dependencies = [ [[package]] name = "wgpu-test" -version = "27.0.3" +version = "27.0.4" dependencies = [ "anyhow", "approx", @@ -5069,7 +5069,7 @@ dependencies = [ [[package]] name = "wgpu-types" -version = "27.0.3" +version = "27.0.4" dependencies = [ "bitflags 2.9.4", "bytemuck", @@ -5138,7 +5138,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index cf018c81f50..069e928b81b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,7 +61,7 @@ keywords = ["graphics"] license = "MIT OR Apache-2.0" homepage = "https://wgpu.rs/" repository = "https://github.com/gfx-rs/wgpu" -version = "27.0.3" +version = "27.0.4" authors = ["gfx-rs developers"] [workspace.dependencies] From 76cb48cb633f861921796b6d9da78b017761e89a Mon Sep 17 00:00:00 2001 From: Lucien Greathouse Date: Mon, 19 May 2025 18:44:43 -0400 Subject: [PATCH 303/303] Allow uniform buffers and binding arrays in same bind group --- wgpu-core/src/binding_model.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index 2cbac7bfa6b..489940b77fe 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -586,9 +586,9 @@ impl BindingTypeMaxCountValidator { if self.has_bindless_array && has_dynamic_offset_array { return Err(CreateBindGroupLayoutError::ContainsBothBindingArrayAndDynamicOffsetArray); } - if self.has_bindless_array && has_uniform_buffer { - return Err(CreateBindGroupLayoutError::ContainsBothBindingArrayAndUniformBuffer); - } + // if self.has_bindless_array && has_uniform_buffer { + // return Err(CreateBindGroupLayoutError::ContainsBothBindingArrayAndUniformBuffer); + // } Ok(()) } }