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