Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions tests/tests/wgpu-gpu/write_texture.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Tests for texture copy

use wgpu::*;
use wgpu_test::{gpu_test, GpuTestConfiguration};

#[gpu_test]
Expand Down Expand Up @@ -228,3 +229,109 @@ static WRITE_TEXTURE_NO_OOB: GpuTestConfiguration =
},
);
});

// Test a writeTexture operation that will use the staging buffer.
// If run with the address sanitizer, this serves as a regression
// test for https://github.com/gfx-rs/wgpu/pull/7893.
#[gpu_test]
static WRITE_TEXTURE_VIA_STAGING_BUFFER: GpuTestConfiguration = GpuTestConfiguration::new()
.run_async(|ctx| async move {
let width = 89;
let height = 17;

let tex = ctx.device.create_texture(&TextureDescriptor {
label: None,
dimension: TextureDimension::D2,
size: Extent3d {
width,
height,
depth_or_array_layers: 1,
},
format: TextureFormat::R8Uint,
usage: TextureUsages::COPY_DST
| TextureUsages::COPY_SRC
| TextureUsages::TEXTURE_BINDING,
mip_level_count: 1,
sample_count: 1,
view_formats: &[],
});

let write_width: u32 = 31;
let write_height: u32 = 5;
let write_bytes_per_row: u32 = 113;
let write_data = (0..(write_height - 1) * write_bytes_per_row + write_width)
.map(|b| (b % 256) as u8)
.collect::<Vec<_>>();

ctx.queue.write_texture(
TexelCopyTextureInfo {
texture: &tex,
mip_level: 0,
origin: Origin3d::ZERO,
aspect: TextureAspect::All,
},
&write_data,
TexelCopyBufferLayout {
offset: 0,
bytes_per_row: Some(write_bytes_per_row),
rows_per_image: Some(19),
},
Extent3d {
width: write_width,
height: write_height,
depth_or_array_layers: 1,
},
);

ctx.queue.submit(None);

let read_bytes_per_row = wgt::COPY_BYTES_PER_ROW_ALIGNMENT;
let read_buffer = ctx.device.create_buffer(&BufferDescriptor {
label: None,
size: (height * read_bytes_per_row) as u64,
usage: BufferUsages::MAP_READ | wgpu::BufferUsages::COPY_DST,
mapped_at_creation: false,
});

let mut encoder = ctx
.device
.create_command_encoder(&CommandEncoderDescriptor { label: None });

encoder.copy_texture_to_buffer(
TexelCopyTextureInfo {
texture: &tex,
mip_level: 0,
origin: Origin3d::ZERO,
aspect: TextureAspect::All,
},
TexelCopyBufferInfo {
buffer: &read_buffer,
layout: TexelCopyBufferLayout {
offset: 0,
bytes_per_row: Some(read_bytes_per_row),
rows_per_image: Some(height),
},
},
Extent3d {
width,
height,
depth_or_array_layers: 1,
},
);

ctx.queue.submit(Some(encoder.finish()));

let slice = read_buffer.slice(..);
slice.map_async(MapMode::Read, |_| ());
ctx.async_poll(PollType::wait()).await.unwrap();
let read_data: Vec<u8> = slice.get_mapped_range().to_vec();

for x in 0..write_width {
for y in 0..write_height {
assert_eq!(
read_data[(y * read_bytes_per_row + x) as usize],
write_data[(y * write_bytes_per_row + x) as usize]
);
}
}
});