mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-01-10 23:08:13 -05:00
Fix image copy regressions (#8022)
* Restore allowance of unaligned buffer-texture copies This fixes a regression introduced by #7948. However, it makes it possible to reach a panic in initialize_buffer_memory if the copy requires initializing a region of memory that is not 4B aligned. * Fix CopyT2T of multi-layer depth/stencil textures * Adjust test list
This commit is contained in:
@@ -1,6 +1,14 @@
|
||||
unittests:*
|
||||
webgpu:api,operation,command_buffer,basic:*
|
||||
webgpu:api,operation,command_buffer,copyBufferToBuffer:*
|
||||
fails-if(vulkan) webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth24plus"
|
||||
fails-if(vulkan) webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth24plus-stencil8"
|
||||
fails-if(vulkan) webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth16unorm"
|
||||
fails-if(vulkan) webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth32float"
|
||||
fails-if(vulkan) webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="depth32float-stencil8"
|
||||
webgpu:api,operation,command_buffer,copyTextureToTexture:copy_depth_stencil:format="stencil8"
|
||||
// Fails with OOM in CI.
|
||||
fails-if(dx12) webgpu:api,operation,command_buffer,image_copy:offsets_and_sizes:*
|
||||
webgpu:api,operation,compute,basic:memcpy:*
|
||||
//FAIL: webgpu:api,operation,compute,basic:large_dispatch:*
|
||||
webgpu:api,operation,compute_pipeline,overrides:*
|
||||
@@ -63,6 +71,8 @@ fails-if(dx12) webgpu:api,validation,image_copy,buffer_texture_copies:offset_and
|
||||
//mix of PASS and FAIL: other subtests of offset_and_bytesPerRow. Related bugs:
|
||||
// https://github.com/gfx-rs/wgpu/issues/7946, https://github.com/gfx-rs/wgpu/issues/7947
|
||||
webgpu:api,validation,image_copy,layout_related:copy_end_overflows_u64:*
|
||||
// Fails with OOM in CI.
|
||||
fails-if(dx12) webgpu:api,validation,image_copy,layout_related:offset_alignment:*
|
||||
webgpu:api,validation,image_copy,texture_related:format:dimension="1d";*
|
||||
webgpu:api,validation,queue,submit:command_buffer,device_mismatch:*
|
||||
webgpu:api,validation,queue,submit:command_buffer,duplicate_buffers:*
|
||||
@@ -92,6 +102,9 @@ webgpu:api,validation,encoding,queries,general:occlusion_query,query_type:*
|
||||
webgpu:shader,execution,expression,call,builtin,textureSample:sampled_1d_coords:*
|
||||
webgpu:shader,execution,expression,call,builtin,textureSampleBaseClampToEdge:2d_coords:stage="c";textureType="texture_2d<f32>";*
|
||||
webgpu:shader,execution,flow_control,return:*
|
||||
// Many other vertex_buffer_access subtests also passing, but there are too many to enumerate.
|
||||
// Fails on Metal in CI only, not when running locally.
|
||||
fails-if(metal) webgpu:shader,execution,robust_access_vertex:vertex_buffer_access:indexed=true;indirect=false;drawCallTestParameter="baseVertex";type="float32x4";additionalBuffers=4;partialLastNumber=false;offsetVertexBuffer=true
|
||||
webgpu:shader,validation,expression,call,builtin,max:values:*
|
||||
webgpu:shader,validation,statement,statement_behavior:invalid_statements:body="break"
|
||||
webgpu:shader,validation,statement,statement_behavior:invalid_statements:body="break_if"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use alloc::{format, string::String, sync::Arc, vec, vec::Vec};
|
||||
use alloc::{format, string::String, sync::Arc, vec::Vec};
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use thiserror::Error;
|
||||
@@ -399,7 +399,7 @@ pub(crate) fn validate_texture_buffer_copy<T>(
|
||||
return Err(TransferError::CopyAspectNotOne);
|
||||
}
|
||||
|
||||
let mut offset_alignment = if desc.format.is_depth_stencil_format() {
|
||||
let offset_alignment = if desc.format.is_depth_stencil_format() {
|
||||
4
|
||||
} else {
|
||||
// The case where `block_copy_size` returns `None` is currently
|
||||
@@ -411,17 +411,7 @@ pub(crate) fn validate_texture_buffer_copy<T>(
|
||||
.expect("non-copyable formats should have been rejected previously")
|
||||
};
|
||||
|
||||
// TODO(https://github.com/gfx-rs/wgpu/issues/7947): This does not match the spec.
|
||||
// The spec imposes no alignment requirement if `!aligned`, and otherwise
|
||||
// imposes only the `offset_alignment` as calculated above. wgpu currently
|
||||
// can panic on alignments <4B, so we reject them here to avoid a panic.
|
||||
if aligned {
|
||||
offset_alignment = offset_alignment.max(4);
|
||||
} else {
|
||||
offset_alignment = 4;
|
||||
}
|
||||
|
||||
if offset % u64::from(offset_alignment) != 0 {
|
||||
if aligned && offset % u64::from(offset_alignment) != 0 {
|
||||
return Err(TransferError::UnalignedBufferOffset(offset));
|
||||
}
|
||||
|
||||
@@ -1347,45 +1337,32 @@ impl Global {
|
||||
height: src_copy_size.height.min(dst_copy_size.height),
|
||||
depth: src_copy_size.depth.min(dst_copy_size.depth),
|
||||
};
|
||||
|
||||
let regions = (0..array_layer_count).map(|rel_array_layer| {
|
||||
let mut src_base = src_tex_base.clone();
|
||||
let mut dst_base = dst_tex_base.clone();
|
||||
src_base.array_layer += rel_array_layer;
|
||||
dst_base.array_layer += rel_array_layer;
|
||||
hal::TextureCopy {
|
||||
src_base,
|
||||
dst_base,
|
||||
size: hal_copy_size,
|
||||
}
|
||||
});
|
||||
|
||||
let regions = if dst_tex_base.aspect == hal::FormatAspects::DEPTH_STENCIL {
|
||||
vec![
|
||||
hal::TextureCopy {
|
||||
src_base: hal::TextureCopyBase {
|
||||
aspect: hal::FormatAspects::DEPTH,
|
||||
..src_tex_base
|
||||
},
|
||||
dst_base: hal::TextureCopyBase {
|
||||
aspect: hal::FormatAspects::DEPTH,
|
||||
..dst_tex_base
|
||||
},
|
||||
size: hal_copy_size,
|
||||
},
|
||||
hal::TextureCopy {
|
||||
src_base: hal::TextureCopyBase {
|
||||
aspect: hal::FormatAspects::STENCIL,
|
||||
..src_tex_base
|
||||
},
|
||||
dst_base: hal::TextureCopyBase {
|
||||
aspect: hal::FormatAspects::STENCIL,
|
||||
..dst_tex_base
|
||||
},
|
||||
size: hal_copy_size,
|
||||
},
|
||||
]
|
||||
} else {
|
||||
(0..array_layer_count)
|
||||
.map(|rel_array_layer| {
|
||||
let mut src_base = src_tex_base.clone();
|
||||
let mut dst_base = dst_tex_base.clone();
|
||||
src_base.array_layer += rel_array_layer;
|
||||
dst_base.array_layer += rel_array_layer;
|
||||
hal::TextureCopy {
|
||||
src_base,
|
||||
dst_base,
|
||||
size: hal_copy_size,
|
||||
}
|
||||
regions
|
||||
.flat_map(|region| {
|
||||
let (mut depth, mut stencil) = (region.clone(), region);
|
||||
depth.src_base.aspect = hal::FormatAspects::DEPTH;
|
||||
depth.dst_base.aspect = hal::FormatAspects::DEPTH;
|
||||
stencil.src_base.aspect = hal::FormatAspects::STENCIL;
|
||||
stencil.dst_base.aspect = hal::FormatAspects::STENCIL;
|
||||
[depth, stencil]
|
||||
})
|
||||
.collect()
|
||||
.collect::<Vec<_>>()
|
||||
} else {
|
||||
regions.collect::<Vec<_>>()
|
||||
};
|
||||
let cmd_buf_raw = cmd_buf_data.encoder.open()?;
|
||||
unsafe {
|
||||
|
||||
Reference in New Issue
Block a user