mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
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:
@@ -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)
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user