Skip to content

Commit 5d14f33

Browse files
Test for use of staging buffer in writeTexture (#7963)
1 parent 9a596fa commit 5d14f33

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed

tests/tests/wgpu-gpu/write_texture.rs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Tests for texture copy
22
3+
use wgpu::*;
34
use wgpu_test::{gpu_test, GpuTestConfiguration};
45

56
#[gpu_test]
@@ -228,3 +229,109 @@ static WRITE_TEXTURE_NO_OOB: GpuTestConfiguration =
228229
},
229230
);
230231
});
232+
233+
// Test a writeTexture operation that will use the staging buffer.
234+
// If run with the address sanitizer, this serves as a regression
235+
// test for https://github.com/gfx-rs/wgpu/pull/7893.
236+
#[gpu_test]
237+
static WRITE_TEXTURE_VIA_STAGING_BUFFER: GpuTestConfiguration = GpuTestConfiguration::new()
238+
.run_async(|ctx| async move {
239+
let width = 89;
240+
let height = 17;
241+
242+
let tex = ctx.device.create_texture(&TextureDescriptor {
243+
label: None,
244+
dimension: TextureDimension::D2,
245+
size: Extent3d {
246+
width,
247+
height,
248+
depth_or_array_layers: 1,
249+
},
250+
format: TextureFormat::R8Uint,
251+
usage: TextureUsages::COPY_DST
252+
| TextureUsages::COPY_SRC
253+
| TextureUsages::TEXTURE_BINDING,
254+
mip_level_count: 1,
255+
sample_count: 1,
256+
view_formats: &[],
257+
});
258+
259+
let write_width: u32 = 31;
260+
let write_height: u32 = 5;
261+
let write_bytes_per_row: u32 = 113;
262+
let write_data = (0..(write_height - 1) * write_bytes_per_row + write_width)
263+
.map(|b| (b % 256) as u8)
264+
.collect::<Vec<_>>();
265+
266+
ctx.queue.write_texture(
267+
TexelCopyTextureInfo {
268+
texture: &tex,
269+
mip_level: 0,
270+
origin: Origin3d::ZERO,
271+
aspect: TextureAspect::All,
272+
},
273+
&write_data,
274+
TexelCopyBufferLayout {
275+
offset: 0,
276+
bytes_per_row: Some(write_bytes_per_row),
277+
rows_per_image: Some(19),
278+
},
279+
Extent3d {
280+
width: write_width,
281+
height: write_height,
282+
depth_or_array_layers: 1,
283+
},
284+
);
285+
286+
ctx.queue.submit(None);
287+
288+
let read_bytes_per_row = wgt::COPY_BYTES_PER_ROW_ALIGNMENT;
289+
let read_buffer = ctx.device.create_buffer(&BufferDescriptor {
290+
label: None,
291+
size: (height * read_bytes_per_row) as u64,
292+
usage: BufferUsages::MAP_READ | wgpu::BufferUsages::COPY_DST,
293+
mapped_at_creation: false,
294+
});
295+
296+
let mut encoder = ctx
297+
.device
298+
.create_command_encoder(&CommandEncoderDescriptor { label: None });
299+
300+
encoder.copy_texture_to_buffer(
301+
TexelCopyTextureInfo {
302+
texture: &tex,
303+
mip_level: 0,
304+
origin: Origin3d::ZERO,
305+
aspect: TextureAspect::All,
306+
},
307+
TexelCopyBufferInfo {
308+
buffer: &read_buffer,
309+
layout: TexelCopyBufferLayout {
310+
offset: 0,
311+
bytes_per_row: Some(read_bytes_per_row),
312+
rows_per_image: Some(height),
313+
},
314+
},
315+
Extent3d {
316+
width,
317+
height,
318+
depth_or_array_layers: 1,
319+
},
320+
);
321+
322+
ctx.queue.submit(Some(encoder.finish()));
323+
324+
let slice = read_buffer.slice(..);
325+
slice.map_async(MapMode::Read, |_| ());
326+
ctx.async_poll(PollType::wait()).await.unwrap();
327+
let read_data: Vec<u8> = slice.get_mapped_range().to_vec();
328+
329+
for x in 0..write_width {
330+
for y in 0..write_height {
331+
assert_eq!(
332+
read_data[(y * read_bytes_per_row + x) as usize],
333+
write_data[(y * write_bytes_per_row + x) as usize]
334+
);
335+
}
336+
}
337+
});

0 commit comments

Comments
 (0)