mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Merge #348
348: Add aribitrary texture size handling to the capture example r=me a=rukai * User can specify width + height via arguments. * Defaults to (100, 200) when no arguments. Odd values chosen to make it more likely to pick up issues when testing. * Converts from bgra as I believe that is the most commonly supported format for swapchains? Co-authored-by: Rukai <rubickent@gmail.com>
This commit is contained in:
@@ -52,7 +52,7 @@ gfx-backend-vulkan = { version = "0.5", features = ["x11"] }
|
||||
[dev-dependencies]
|
||||
cgmath = "0.17"
|
||||
log = "0.4"
|
||||
png = "0.15"
|
||||
png = "0.16"
|
||||
winit = { version = "0.22.1", features = ["web-sys"] }
|
||||
rand = { version = "0.7.2", features = ["wasm-bindgen"] }
|
||||
bytemuck = "1"
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
/// the added benefit that this method doesn't require a window to be created.
|
||||
use std::fs::File;
|
||||
use std::mem::size_of;
|
||||
use std::env;
|
||||
use std::io::Write;
|
||||
|
||||
async fn run() {
|
||||
let adapter = wgpu::Instance::new()
|
||||
@@ -27,20 +29,40 @@ async fn run() {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Rendered image is 256×256 with 32-bit RGBA color
|
||||
let size = 256u32;
|
||||
let args: Vec<_> = env::args().collect();
|
||||
let (width, height) = match args.len() {
|
||||
// 0 on wasm, 1 on desktop
|
||||
0 | 1 => (100usize, 200usize),
|
||||
3 => (args[1].parse().unwrap(), args[2].parse().unwrap()),
|
||||
_ => {
|
||||
println!("Incorrect number of arguments, possible usages:");
|
||||
println!("* 0 arguments - uses default width and height of (100, 200)");
|
||||
println!("* 2 arguments - uses specified width and height values");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// It is a webgpu requirement that BufferCopyView.layout.bytes_per_row % wgpu::COPY_BYTES_PER_ROW_ALIGNMENT == 0
|
||||
// So we calculate padded_bytes_per_row by rounding unpadded_bytes_per_row
|
||||
// up to the next multiple of wgpu::COPY_BYTES_PER_ROW_ALIGNMENT.
|
||||
// https://en.wikipedia.org/wiki/Data_structure_alignment#Computing_padding
|
||||
let bytes_per_pixel = size_of::<u32>();
|
||||
let unpadded_bytes_per_row = width * bytes_per_pixel;
|
||||
let align = wgpu::COPY_BYTES_PER_ROW_ALIGNMENT as usize;
|
||||
let padded_bytes_per_row_padding = (align - unpadded_bytes_per_row % align) % align;
|
||||
let padded_bytes_per_row = unpadded_bytes_per_row + padded_bytes_per_row_padding;
|
||||
|
||||
// The output buffer lets us retrieve the data as an array
|
||||
let output_buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: None,
|
||||
size: (size * size) as u64 * size_of::<u32>() as u64,
|
||||
size: (padded_bytes_per_row * height) as u64,
|
||||
usage: wgpu::BufferUsage::MAP_READ | wgpu::BufferUsage::COPY_DST,
|
||||
mapped_at_creation: false,
|
||||
});
|
||||
|
||||
let texture_extent = wgpu::Extent3d {
|
||||
width: size,
|
||||
height: size,
|
||||
width: width as u32,
|
||||
height: height as u32,
|
||||
depth: 1,
|
||||
};
|
||||
|
||||
@@ -81,7 +103,7 @@ async fn run() {
|
||||
buffer: &output_buffer,
|
||||
layout: wgpu::TextureDataLayout {
|
||||
offset: 0,
|
||||
bytes_per_row: size_of::<u32>() as u32 * size,
|
||||
bytes_per_row: padded_bytes_per_row as u32,
|
||||
rows_per_image: 0,
|
||||
},
|
||||
},
|
||||
@@ -108,15 +130,22 @@ async fn run() {
|
||||
}
|
||||
|
||||
if let Ok(()) = buffer_future.await {
|
||||
let data = output_buffer.get_mapped_range(0, wgt::BufferSize::WHOLE);
|
||||
let mut png_encoder = png::Encoder::new(File::create("red.png").unwrap(), size, size);
|
||||
let padded_buffer = output_buffer.get_mapped_range(0, wgt::BufferSize::WHOLE);
|
||||
|
||||
let mut png_encoder = png::Encoder::new(File::create("red.png").unwrap(), width as u32, height as u32);
|
||||
png_encoder.set_depth(png::BitDepth::Eight);
|
||||
png_encoder.set_color(png::ColorType::RGBA);
|
||||
png_encoder
|
||||
let mut png_writer = png_encoder
|
||||
.write_header()
|
||||
.unwrap()
|
||||
.write_image_data(data)
|
||||
.unwrap();
|
||||
.into_stream_writer_with_size(unpadded_bytes_per_row);
|
||||
|
||||
// from the padded_buffer we write just the unpadded bytes into the image
|
||||
for chunk in padded_buffer.chunks(padded_bytes_per_row) {
|
||||
png_writer.write(&chunk[..unpadded_bytes_per_row]).unwrap();
|
||||
}
|
||||
png_writer.finish().unwrap();
|
||||
|
||||
output_buffer.unmap();
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 851 B After Width: | Height: | Size: 534 B |
@@ -28,6 +28,7 @@ pub use wgt::{
|
||||
StencilStateFaceDescriptor, StoreOp, SwapChainDescriptor, SwapChainStatus, TextureAspect,
|
||||
TextureComponentType, TextureDataLayout, TextureDimension, TextureFormat, TextureUsage,
|
||||
TextureViewDimension, VertexAttributeDescriptor, VertexFormat, BIND_BUFFER_ALIGNMENT,
|
||||
COPY_BYTES_PER_ROW_ALIGNMENT,
|
||||
};
|
||||
|
||||
use backend::Context as C;
|
||||
|
||||
Reference in New Issue
Block a user