diff --git a/CHANGELOG.md b/CHANGELOG.md index 546e16ecf0..00bb864aa6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,6 +72,7 @@ Bottom level categories: #### General - `copyTextureToTexture` src/dst aspects must both refer to all aspects of src/dst format. By @teoxoy in [#3431](https://github.com/gfx-rs/wgpu/pull/3431) +- Validate before extracting texture selectors. By @teoxoy in [#3487](https://github.com/gfx-rs/wgpu/pull/3487) ## wgpu-0.15.0 (2023-01-25) diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 9370e7bd4c..540e682353 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -179,7 +179,7 @@ pub(crate) fn extract_texture_selector( copy_texture: &ImageCopyTexture, copy_size: &Extent3d, texture: &Texture, -) -> Result<(TextureSelector, hal::TextureCopyBase, wgt::TextureFormat), TransferError> { +) -> Result<(TextureSelector, hal::TextureCopyBase), TransferError> { let format = texture.desc.format; let copy_aspect = hal::FormatAspects::from(format) & hal::FormatAspects::from(copy_texture.aspect); @@ -214,7 +214,7 @@ pub(crate) fn extract_texture_selector( layers, }; - Ok((selector, base, format)) + Ok((selector, base)) } /// WebGPU's [validating linear texture data][vltd] algorithm. @@ -736,8 +736,7 @@ impl Global { copy_size, )?; - let (dst_range, dst_base, _) = - extract_texture_selector(destination, copy_size, dst_texture)?; + let (dst_range, dst_base) = extract_texture_selector(destination, copy_size, dst_texture)?; // Handle texture init *before* dealing with barrier transitions so we // have an easier time inserting "immediate-inits" that may be required @@ -868,7 +867,7 @@ impl Global { 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)?; // Handle texture init *before* dealing with barrier transitions so we // have an easier time inserting "immediate-inits" that may be required @@ -1053,9 +1052,8 @@ impl Global { copy_size, )?; - let (src_range, src_tex_base, _) = - extract_texture_selector(source, copy_size, src_texture)?; - let (dst_range, dst_tex_base, _) = + 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); diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index fe86b0ad1f..e0cc9bf656 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -602,9 +602,7 @@ impl Global { .get_mut(destination.texture) .map_err(|_| TransferError::InvalidTexture(destination.texture))?; - let (selector, dst_base, texture_format) = - extract_texture_selector(destination, size, dst)?; - let format_desc = texture_format.describe(); + let format_desc = dst.desc.format.describe(); if !dst.desc.usage.contains(wgt::TextureUsages::COPY_DST) { return Err( @@ -617,11 +615,13 @@ impl Global { let (hal_copy_size, array_layer_count) = validate_texture_copy_range(destination, &dst.desc, CopySide::Destination, size)?; + let (selector, dst_base) = extract_texture_selector(destination, size, dst)?; + // Note: `_source_bytes_per_array_layer` is ignored since we // have a staging copy, and it can have a different value. let (_, _source_bytes_per_array_layer) = validate_linear_texture_data( data_layout, - texture_format, + dst.desc.format, data.len() as wgt::BufferAddress, CopySide::Source, format_desc.block_size as wgt::BufferAddress, @@ -629,9 +629,9 @@ impl Global { false, )?; - if !conv::is_valid_copy_dst_texture_format(texture_format, destination.aspect) { + if !conv::is_valid_copy_dst_texture_format(dst.desc.format, destination.aspect) { return Err(TransferError::CopyToForbiddenTextureFormat { - format: texture_format, + format: dst.desc.format, aspect: destination.aspect, } .into()); @@ -858,9 +858,6 @@ impl Global { let (mut texture_guard, _) = hub.textures.write(&mut token); // For clear we need write access to the texture. TODO: Can we acquire write lock later? let dst = texture_guard.get_mut(destination.texture).unwrap(); - let (selector, dst_base, _) = - extract_texture_selector(&destination.to_untagged(), &size, dst)?; - if !conv::is_valid_external_image_copy_dst_texture_format(dst.desc.format) { return Err( TransferError::ExternalCopyToForbiddenTextureFormat(dst.desc.format).into(), @@ -930,6 +927,9 @@ impl Global { &size, )?; + let (selector, dst_base) = + extract_texture_selector(&destination.to_untagged(), &size, dst)?; + let mut trackers = device.trackers.lock(); let encoder = device.pending_writes.activate(); diff --git a/wgpu/tests/queue_transfer.rs b/wgpu/tests/queue_transfer.rs index 3ab1cfa98e..62740cf7d2 100644 --- a/wgpu/tests/queue_transfer.rs +++ b/wgpu/tests/queue_transfer.rs @@ -31,7 +31,7 @@ fn queue_write_texture_overflow() { wgpu::ImageCopyTexture { texture: &texture, mip_level: 0, - origin: wgpu::Origin3d::ZERO, + origin: wgpu::Origin3d { x: 0, y: 0, z: 1 }, aspect: wgpu::TextureAspect::All, }, &data, @@ -44,7 +44,7 @@ fn queue_write_texture_overflow() { wgpu::Extent3d { width: 3056263286, height: 64, - depth_or_array_layers: 1144576469, + depth_or_array_layers: 4294967295, }, ); });