diff --git a/wgpu-core/src/command/clear.rs b/wgpu-core/src/command/clear.rs index 7a0828fde..fecf58894 100644 --- a/wgpu-core/src/command/clear.rs +++ b/wgpu-core/src/command/clear.rs @@ -12,8 +12,8 @@ use crate::{ id::{BufferId, CommandEncoderId, TextureId}, init_tracker::{MemoryInitKind, TextureInitRange}, resource::{ - DestroyedResourceError, Labeled, ParentDevice, ResourceErrorIdent, Texture, - TextureClearMode, + DestroyedResourceError, Labeled, MissingBufferUsageError, ParentDevice, ResourceErrorIdent, + Texture, TextureClearMode, }, snatch::SnatchGuard, track::{TextureSelector, TextureTracker}, @@ -52,8 +52,8 @@ pub enum ClearError { end_offset: BufferAddress, buffer_size: BufferAddress, }, - #[error("Destination buffer is missing the `COPY_DST` usage flag")] - MissingCopyDstUsageFlag(Option, Option), + #[error(transparent)] + MissingBufferUsage(#[from] MissingBufferUsageError), #[error("Texture lacks the aspects that were specified in the image subresource range. Texture with format {texture_format:?}, specified was {subresource_range_aspects:?}")] MissingTextureAspect { texture_format: wgt::TextureFormat, @@ -115,9 +115,7 @@ impl Global { let snatch_guard = dst_buffer.device.snatchable_lock.read(); let dst_raw = dst_buffer.try_raw(&snatch_guard)?; - if !dst_buffer.usage.contains(BufferUsages::COPY_DST) { - return Err(ClearError::MissingCopyDstUsageFlag(Some(dst), None)); - } + dst_buffer.check_usage(BufferUsages::COPY_DST)?; // Check if offset & size are valid. if offset % wgt::COPY_BUFFER_ALIGNMENT != 0 { diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 64e5e1349..f07a6db00 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -5,7 +5,7 @@ use crate::{ command::{clear_texture, CommandBuffer, CommandEncoderError}, conv, device::{Device, DeviceError, MissingDownlevelFlags}, - error::{ErrorFormatter, PrettyError}, + error::PrettyError, global::Global, hal_api::HalApi, id::{BufferId, CommandEncoderId, TextureId}, @@ -13,7 +13,10 @@ use crate::{ has_copy_partial_init_tracker_coverage, MemoryInitKind, TextureInitRange, TextureInitTrackerAction, }, - resource::{DestroyedResourceError, ParentDevice, Texture, TextureErrorDimension}, + resource::{ + DestroyedResourceError, MissingBufferUsageError, MissingTextureUsageError, ParentDevice, + Texture, TextureErrorDimension, + }, snatch::SnatchGuard, track::{TextureSelector, Tracker}, }; @@ -49,8 +52,10 @@ pub enum TransferError { SameSourceDestinationBuffer, #[error("Source buffer/texture is missing the `COPY_SRC` usage flag")] MissingCopySrcUsageFlag, - #[error("Destination buffer/texture is missing the `COPY_DST` usage flag")] - MissingCopyDstUsageFlag(Option, Option), + #[error(transparent)] + MissingBufferUsage(#[from] MissingBufferUsageError), + #[error(transparent)] + MissingTextureUsage(#[from] MissingTextureUsageError), #[error("Destination texture is missing the `RENDER_ATTACHMENT` usage flag")] MissingRenderAttachmentUsageFlag(TextureId), #[error("Copy of {start_offset}..{end_offset} would end up overrunning the bounds of the {side:?} buffer of size {buffer_size}")] @@ -140,19 +145,8 @@ pub enum TransferError { InvalidMipLevel { requested: u32, count: u32 }, } -impl PrettyError for TransferError { - fn fmt_pretty(&self, fmt: &mut ErrorFormatter) { - fmt.error(self); - if let Self::MissingCopyDstUsageFlag(buf_opt, tex_opt) = *self { - if let Some(buf) = buf_opt { - fmt.buffer_label_with_key(&buf, "destination"); - } - if let Some(tex) = tex_opt { - fmt.texture_label_with_key(&tex, "destination"); - } - } - } -} +impl PrettyError for TransferError {} + /// Error encountered while attempting to do a copy on a command encoder. #[derive(Clone, Debug, Error)] #[non_exhaustive] @@ -607,9 +601,9 @@ impl Global { .set_single(&dst_buffer, hal::BufferUses::COPY_DST); let dst_raw = dst_buffer.try_raw(&snatch_guard)?; - if !dst_buffer.usage.contains(BufferUsages::COPY_DST) { - return Err(TransferError::MissingCopyDstUsageFlag(Some(destination), None).into()); - } + 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 size % wgt::COPY_BUFFER_ALIGNMENT != 0 { @@ -793,11 +787,9 @@ impl Global { .textures .set_single(&dst_texture, dst_range, hal::TextureUses::COPY_DST); let dst_raw = dst_texture.try_raw(&snatch_guard)?; - if !dst_texture.desc.usage.contains(TextureUsages::COPY_DST) { - return Err( - TransferError::MissingCopyDstUsageFlag(None, Some(destination.texture)).into(), - ); - } + dst_texture + .check_usage(TextureUsages::COPY_DST) + .map_err(TransferError::MissingTextureUsage)?; let dst_barrier = dst_pending.map(|pending| pending.into_hal(dst_raw)); if !dst_base.aspect.is_one() { @@ -959,11 +951,9 @@ impl Global { .set_single(&dst_buffer, hal::BufferUses::COPY_DST); let dst_raw = dst_buffer.try_raw(&snatch_guard)?; - if !dst_buffer.usage.contains(BufferUsages::COPY_DST) { - return Err( - TransferError::MissingCopyDstUsageFlag(Some(destination.buffer), None).into(), - ); - } + 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() { @@ -1158,11 +1148,9 @@ impl Global { hal::TextureUses::COPY_DST, ); let dst_raw = dst_texture.try_raw(&snatch_guard)?; - if !dst_texture.desc.usage.contains(TextureUsages::COPY_DST) { - return Err( - TransferError::MissingCopyDstUsageFlag(None, Some(destination.texture)).into(), - ); - } + dst_texture + .check_usage(TextureUsages::COPY_DST) + .map_err(TransferError::MissingTextureUsage)?; barriers.extend(dst_pending.map(|pending| pending.into_hal(dst_raw))); diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 13fac7885..550d8aa7c 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -568,7 +568,7 @@ impl Global { .get(buffer_id) .map_err(|_| TransferError::InvalidBufferId(buffer_id))?; - self.queue_validate_write_buffer_impl(&buffer, buffer_id, buffer_offset, buffer_size)?; + self.queue_validate_write_buffer_impl(&buffer, buffer_offset, buffer_size)?; Ok(()) } @@ -576,16 +576,10 @@ impl Global { fn queue_validate_write_buffer_impl( &self, buffer: &Buffer, - buffer_id: id::BufferId, buffer_offset: u64, buffer_size: u64, ) -> Result<(), TransferError> { - if !buffer.usage.contains(wgt::BufferUsages::COPY_DST) { - return Err(TransferError::MissingCopyDstUsageFlag( - Some(buffer_id), - None, - )); - } + buffer.check_usage(wgt::BufferUsages::COPY_DST)?; if buffer_size % wgt::COPY_BUFFER_ALIGNMENT != 0 { return Err(TransferError::UnalignedCopySize(buffer_size)); } @@ -631,7 +625,7 @@ impl Global { dst.same_device_as(queue.as_ref())?; let src_buffer_size = staging_buffer.size; - self.queue_validate_write_buffer_impl(&dst, buffer_id, buffer_offset, src_buffer_size)?; + self.queue_validate_write_buffer_impl(&dst, buffer_offset, src_buffer_size)?; dst.use_at(device.active_submission_index.load(Ordering::Relaxed) + 1); @@ -712,11 +706,8 @@ impl Global { dst.same_device_as(queue.as_ref())?; - if !dst.desc.usage.contains(wgt::TextureUsages::COPY_DST) { - return Err( - TransferError::MissingCopyDstUsageFlag(None, Some(destination.texture)).into(), - ); - } + dst.check_usage(wgt::TextureUsages::COPY_DST) + .map_err(TransferError::MissingTextureUsage)?; // Note: Doing the copy range validation early is important because ensures that the // dimensions are not going to cause overflow in other parts of the validation. @@ -981,11 +972,8 @@ impl Global { if dst.desc.dimension != wgt::TextureDimension::D2 { return Err(TransferError::InvalidDimensionExternal(destination.texture).into()); } - if !dst.desc.usage.contains(wgt::TextureUsages::COPY_DST) { - return Err( - TransferError::MissingCopyDstUsageFlag(None, Some(destination.texture)).into(), - ); - } + dst.check_usage(wgt::TextureUsages::COPY_DST) + .map_err(TransferError::MissingTextureUsage)?; if !dst .desc .usage diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 4db9f9206..740e1b633 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -514,7 +514,7 @@ impl Buffer { /// Checks that the given buffer usage contains the required buffer usage, /// returns an error otherwise. pub(crate) fn check_usage( - self: &Arc, + &self, expected: wgt::BufferUsages, ) -> Result<(), MissingBufferUsageError> { if self.usage.contains(expected) {