diff --git a/player/src/lib.rs b/player/src/lib.rs index 5ded59d70..d0ecda446 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -147,7 +147,8 @@ impl GlobalPlay for wgc::hub::Global { } A::CreateTexture(id, desc) => { self.device_maintain_ids::(device).unwrap(); - self.device_create_texture::(device, &desc, id).unwrap(); + let (_, error) = self.device_create_texture::(device, &desc, id); + assert_eq!(error, None); } A::FreeTexture(id) => { self.texture_destroy::(id).unwrap(); diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 7c7ebe26c..c3f467494 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -500,6 +500,14 @@ impl Device { ) -> Result, resource::CreateTextureError> { debug_assert_eq!(self_id.backend(), B::VARIANT); + let features = conv::texture_features(desc.format); + if !self.features.contains(features) { + return Err(resource::CreateTextureError::MissingFeature( + features, + desc.format, + )); + } + // Ensure `D24Plus` textures cannot be copied match desc.format { TextureFormat::Depth24Plus | TextureFormat::Depth24PlusStencil8 => { @@ -915,10 +923,10 @@ impl crate::hub::Resource for Device { } #[error("device is invalid")] -#[derive(Clone, Debug, Error)] +#[derive(Clone, Debug, Error, PartialEq)] pub struct InvalidDevice; -#[derive(Clone, Debug, Error)] +#[derive(Clone, Debug, Error, PartialEq)] pub enum DeviceError { #[error("parent device is invalid")] Invalid, @@ -1280,62 +1288,53 @@ impl Global { device_id: id::DeviceId, desc: &resource::TextureDescriptor, id_in: Input, - ) -> Result { + ) -> (id::TextureId, Option) { span!(_guard, INFO, "Device::create_texture"); let hub = B::hub(self); let mut token = Token::root(); let (device_guard, mut token) = hub.devices.read(&mut token); - let device = device_guard - .get(device_id) - .map_err(|_| DeviceError::Invalid)?; + let error = loop { + let device = match device_guard.get(device_id) { + Ok(device) => device, + Err(_) => break DeviceError::Invalid.into(), + }; + let texture = match device.create_texture(device_id, desc) { + Ok(texture) => texture, + Err(error) => break error, + }; + let num_levels = texture.full_range.levels.end; + let num_layers = texture.full_range.layers.end; + let ref_count = texture.life_guard.add_ref(); - let texture_features = conv::texture_features(desc.format); - if texture_features != wgt::Features::empty() && !device.features.contains(texture_features) - { - return Err(resource::CreateTextureError::MissingFeature( - texture_features, - desc.format, - )); - } + let id = hub.textures.register_identity(id_in, texture, &mut token); + #[cfg(feature = "trace")] + if let Some(ref trace) = device.trace { + trace + .lock() + .add(trace::Action::CreateTexture(id.0, desc.clone())); + } - let texture = device.create_texture(device_id, desc)?; - let num_levels = texture.full_range.levels.end; - let num_layers = texture.full_range.layers.end; - let ref_count = texture.life_guard.add_ref(); - - let id = hub.textures.register_identity(id_in, texture, &mut token); - #[cfg(feature = "trace")] - if let Some(ref trace) = device.trace { - trace + device + .trackers .lock() - .add(trace::Action::CreateTexture(id.0, desc.clone())); - } + .textures + .init(id, ref_count, TextureState::new(num_levels, num_layers)) + .unwrap(); + return (id.0, None); + }; - device - .trackers - .lock() + let id = hub .textures - .init(id, ref_count, TextureState::new(num_levels, num_layers)) - .unwrap(); - Ok(id.0) + .register_error(id_in, desc.label.borrow_or_default(), &mut token); + (id, Some(error)) } pub fn texture_label(&self, id: id::TextureId) -> String { B::hub(self).textures.label_for_resource(id) } - pub fn texture_error( - &self, - id_in: Input, - label: Option<&str>, - ) -> id::TextureId { - B::hub(self) - .textures - .register_error(id_in, label.unwrap_or(""), &mut Token::root()) - } - pub fn texture_destroy( &self, texture_id: id::TextureId, diff --git a/wgpu-core/src/lib.rs b/wgpu-core/src/lib.rs index e9a36400c..4ce70c31f 100644 --- a/wgpu-core/src/lib.rs +++ b/wgpu-core/src/lib.rs @@ -8,6 +8,8 @@ unused_extern_crates, unused_qualifications )] +// We use loops for getting early-out of scope without closures. +#![allow(clippy::never_loop)] #[macro_use] mod macros; diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 16319dd27..75b5fbb16 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -207,14 +207,14 @@ pub struct Texture { pub(crate) life_guard: LifeGuard, } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq)] pub enum TextureErrorDimension { X, Y, Z, } -#[derive(Clone, Debug, Error)] +#[derive(Clone, Debug, Error, PartialEq)] pub enum TextureDimensionError { #[error("Dimension {0:?} is zero")] Zero(TextureErrorDimension), @@ -224,7 +224,7 @@ pub enum TextureDimensionError { InvalidSampleCount(u32), } -#[derive(Clone, Debug, Error)] +#[derive(Clone, Debug, Error, PartialEq)] pub enum CreateTextureError { #[error(transparent)] Device(#[from] DeviceError),