diff --git a/wgpu-core/src/command/clear.rs b/wgpu-core/src/command/clear.rs index 3e573b04e76..b4d50fd8f1a 100644 --- a/wgpu-core/src/command/clear.rs +++ b/wgpu-core/src/command/clear.rs @@ -189,6 +189,8 @@ pub(super) fn clear_buffer( }); } + // This must happen after parameter validation (so that errors are reported + // as required by the spec), but before any side effects. if offset == end_offset { log::trace!("Ignoring fill_buffer of size 0"); return Ok(()); diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 727fa611ec2..2f009d80580 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -1037,6 +1037,8 @@ pub(super) fn copy_buffer_to_buffer( .into()); } + // This must happen after parameter validation (so that errors are reported + // as required by the spec), but before any side effects. if size == 0 { log::trace!("Ignoring copy_buffer_to_buffer of size 0"); return Ok(()); @@ -1255,6 +1257,8 @@ pub(super) fn copy_texture_to_buffer( .check_usage(BufferUsages::COPY_DST) .map_err(TransferError::MissingBufferUsage)?; + // This must happen after parameter validation (so that errors are reported + // as required by the spec), but before any side effects. 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(()); @@ -1376,12 +1380,6 @@ pub(super) fn copy_texture_to_texture( .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(state, source, copy_size, src_texture)?; - handle_dst_texture_init(state, destination, copy_size, dst_texture)?; - let src_raw = src_texture.try_raw(state.snatch_guard)?; src_texture .check_usage(TextureUsages::COPY_SRC) @@ -1391,11 +1389,19 @@ pub(super) fn copy_texture_to_texture( .check_usage(TextureUsages::COPY_DST) .map_err(TransferError::MissingTextureUsage)?; + // This must happen after parameter validation (so that errors are reported + // as required by the spec), but before any side effects. 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_src_texture_init(state, source, copy_size, src_texture)?; + handle_dst_texture_init(state, destination, copy_size, dst_texture)?; + let src_pending = state .tracker diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 1afdf7914e2..aeecf9efcd2 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -537,6 +537,8 @@ impl Queue { let data_size = if let Some(data_size) = wgt::BufferSize::new(data_size) { data_size } else { + // This must happen after parameter validation (so that errors are reported + // as required by the spec), but before any side effects. log::trace!("Ignoring write_buffer of size 0"); return Ok(()); }; @@ -791,6 +793,8 @@ impl Queue { let dst_raw = dst.try_raw(&snatch_guard)?; + // This must happen after parameter validation (so that errors are reported + // as required by the spec), but before any side effects. if size.width == 0 || size.height == 0 || size.depth_or_array_layers == 0 { log::trace!("Ignoring write_texture of size 0"); return Ok(()); @@ -963,11 +967,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 mut needs_flag = false; needs_flag |= matches!(source.source, wgt::ExternalImageSource::OffscreenCanvas(_)); needs_flag |= source.origin != wgt::Origin2d::ZERO; @@ -1051,6 +1050,13 @@ impl Queue { let (selector, dst_base) = extract_texture_selector(&destination, &size, &dst)?; + // This must happen after parameter validation (so that errors are reported + // as required by the spec), but before any side effects. + if size.width == 0 || size.height == 0 || size.depth_or_array_layers == 0 { + log::trace!("Ignoring copy_external_image_to_texture of size 0"); + return Ok(()); + } + let mut pending_writes = self.pending_writes.lock(); let encoder = pending_writes.activate();