Validate before extracting texture selectors (#3487)

Move calls to `extract_texture_selector` after calls to `validate_texture_copy_range`, to avoid overflow.
This commit is contained in:
Teodor Tanasoaia
2023-02-14 21:31:18 +01:00
committed by GitHub
parent 581b22e6a0
commit b33731c44c
4 changed files with 18 additions and 19 deletions

View File

@@ -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)

View File

@@ -179,7 +179,7 @@ pub(crate) fn extract_texture_selector<A: hal::Api>(
copy_texture: &ImageCopyTexture,
copy_size: &Extent3d,
texture: &Texture<A>,
) -> 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<A: hal::Api>(
layers,
};
Ok((selector, base, format))
Ok((selector, base))
}
/// WebGPU's [validating linear texture data][vltd] algorithm.
@@ -736,8 +736,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
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<G: GlobalIdentityHandlerFactory> Global<G> {
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<G: GlobalIdentityHandlerFactory> Global<G> {
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);

View File

@@ -602,9 +602,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.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<G: GlobalIdentityHandlerFactory> Global<G> {
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<G: GlobalIdentityHandlerFactory> Global<G> {
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<G: GlobalIdentityHandlerFactory> Global<G> {
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<G: GlobalIdentityHandlerFactory> Global<G> {
&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();

View File

@@ -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,
},
);
});