Tolerate destruction of textures used in immediate queue operations prior to submit

This commit is contained in:
Andy Leiserson 2025-06-23 12:29:59 -07:00
parent 26ca28e13c
commit 86e6b1835b
3 changed files with 56 additions and 1 deletions

View File

@ -43,6 +43,7 @@ webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bind_grou
webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:bind_groups_and_pipeline_layout_mismatch:encoderType="render%20pass";*
webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:buffer_binding,render_pipeline:*
webgpu:api,validation,encoding,programmable,pipeline_bind_group_compat:sampler_binding,render_pipeline:*
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:*
webgpu:api,validation,queue,submit:command_buffer,submit_invalidates:*

View File

@ -1,7 +1,57 @@
//! Tests for buffer copy validation.
use wgpu::PollType;
use wgpu_test::{fail, gpu_test, GpuTestConfiguration};
#[gpu_test]
static QUEUE_WRITE_TEXTURE_THEN_DESTROY: GpuTestConfiguration = GpuTestConfiguration::new()
.run_sync(|ctx| {
let texture = ctx.device.create_texture(&wgpu::TextureDescriptor {
label: None,
size: wgpu::Extent3d {
width: 64,
height: 32,
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Rgba32Float,
usage: wgpu::TextureUsages::COPY_DST,
view_formats: &[],
});
let data = vec![255; 1024];
ctx.queue.write_texture(
wgpu::TexelCopyTextureInfo {
texture: &texture,
mip_level: 0,
origin: wgpu::Origin3d { x: 0, y: 0, z: 0 },
aspect: wgpu::TextureAspect::All,
},
&data,
wgpu::TexelCopyBufferLayout {
offset: 0,
bytes_per_row: Some(1024),
rows_per_image: Some(32),
},
wgpu::Extent3d {
width: 64,
height: 1,
depth_or_array_layers: 1,
},
);
// Unlike textures used in a command buffer, which must not be destroyed prior to calling
// submit, it is permissible to destroy a texture used in an immediate queue operation
// before calling submit.
texture.destroy();
ctx.queue.submit([]);
ctx.device.poll(PollType::wait()).unwrap();
});
#[gpu_test]
static QUEUE_WRITE_TEXTURE_OVERFLOW: GpuTestConfiguration =
GpuTestConfiguration::new().run_sync(|ctx| {

View File

@ -1311,7 +1311,11 @@ impl Queue {
.unwrap()
};
}
Err(e) => break 'error Err(e.into()),
// The texture must not have been destroyed when its usage here was
// encoded. If it was destroyed after that, then it was transferred
// to `pending_writes.temp_resources` at the time of destruction, so
// we are still okay to use it.
Err(DestroyedResourceError(_)) => {}
}
}