mirror of
https://github.com/bend-n/fimg.git
synced 2024-12-22 10:28:21 -06:00
wgpu types
This commit is contained in:
parent
33e55b5ab5
commit
05f0d3d10d
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "fimg"
|
||||
version = "0.4.34"
|
||||
version = "0.4.36"
|
||||
authors = ["bend-n <bend.n@outlook.com>"]
|
||||
license = "MIT"
|
||||
edition = "2021"
|
||||
|
@ -23,6 +23,7 @@ minifb = { version = "0.25.0", default-features = false, features = [
|
|||
"x11",
|
||||
"wayland",
|
||||
], optional = true }
|
||||
wgpu = { version = "0.19.1", default-features = false, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
iai = { git = "https://github.com/bend-n/iai.git" }
|
||||
|
@ -59,6 +60,7 @@ text = ["fontdue"]
|
|||
blur = ["slur"]
|
||||
real-show = ["minifb", "text"]
|
||||
default = ["save", "scale"]
|
||||
wgpu-convert = ["dep:wgpu"]
|
||||
|
||||
[profile.release]
|
||||
debug = 2
|
||||
|
|
|
@ -92,6 +92,8 @@ mod pack;
|
|||
mod span;
|
||||
mod sub;
|
||||
pub mod uninit;
|
||||
#[cfg(feature = "wgpu-convert")]
|
||||
mod wgpu_convert;
|
||||
pub use pack::Pack;
|
||||
pub mod pixels;
|
||||
#[cfg(feature = "scale")]
|
||||
|
|
105
src/wgpu_convert.rs
Normal file
105
src/wgpu_convert.rs
Normal file
|
@ -0,0 +1,105 @@
|
|||
use std::num::NonZeroU32;
|
||||
|
||||
use wgpu::{util::*, *};
|
||||
|
||||
use crate::Image;
|
||||
|
||||
impl<T, const N: usize> Image<T, N> {
|
||||
/// Get the size as a [`wgpu::Extend3d`].
|
||||
pub fn wgpu_size(&self) -> Extent3d {
|
||||
Extent3d {
|
||||
width: self.width(),
|
||||
height: self.height(),
|
||||
depth_or_array_layers: 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsRef<[u8]>> Image<T, 4> {
|
||||
/// Upload this image to the gpu, returning a [`wgpu::Texture`].
|
||||
pub fn send(&self, dev: &Device, q: &Queue, usage: TextureUsages) -> Texture {
|
||||
dev.create_texture_with_data(
|
||||
&q,
|
||||
&TextureDescriptor {
|
||||
label: None,
|
||||
size: self.wgpu_size(),
|
||||
mip_level_count: 1,
|
||||
sample_count: 1,
|
||||
dimension: TextureDimension::D2,
|
||||
format: TextureFormat::Rgba8Unorm,
|
||||
view_formats: &[],
|
||||
usage,
|
||||
},
|
||||
util::TextureDataOrder::LayerMajor,
|
||||
self.bytes(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Image<Box<[u8]>, 4> {
|
||||
/// Downlodas a purportedly [`TextureFormat::Rgba8Unorm`] image from the gpu.
|
||||
/// # Panics
|
||||
///
|
||||
/// When a "error occurs while trying to async map a buffer".
|
||||
pub fn download(
|
||||
dev: &Device,
|
||||
q: &Queue,
|
||||
texture: &Texture,
|
||||
(width, height): (NonZeroU32, NonZeroU32),
|
||||
) -> Self {
|
||||
let mut encoder = dev.create_command_encoder(&CommandEncoderDescriptor { label: None });
|
||||
let texture_size = Extent3d {
|
||||
width: width.get(),
|
||||
height: height.get(),
|
||||
depth_or_array_layers: 1,
|
||||
};
|
||||
|
||||
let row = width.get() as usize * 4;
|
||||
let pad = {
|
||||
let padding = (256 - row % 256) % 256;
|
||||
row + padding
|
||||
};
|
||||
|
||||
let output_buffer = dev.create_buffer(&BufferDescriptor {
|
||||
label: None,
|
||||
size: pad as u64 * height.get() as u64,
|
||||
usage: BufferUsages::COPY_DST | BufferUsages::MAP_READ,
|
||||
mapped_at_creation: false,
|
||||
});
|
||||
|
||||
encoder.copy_texture_to_buffer(
|
||||
wgpu::ImageCopyTexture {
|
||||
aspect: wgpu::TextureAspect::All,
|
||||
texture,
|
||||
mip_level: 0,
|
||||
origin: wgpu::Origin3d::ZERO,
|
||||
},
|
||||
wgpu::ImageCopyBuffer {
|
||||
buffer: &output_buffer,
|
||||
layout: wgpu::ImageDataLayout {
|
||||
offset: 0,
|
||||
bytes_per_row: Some(pad as u32),
|
||||
rows_per_image: Some(height.get()),
|
||||
},
|
||||
},
|
||||
texture_size,
|
||||
);
|
||||
q.submit(Some(encoder.finish()));
|
||||
|
||||
let buffer_slice = output_buffer.slice(..);
|
||||
buffer_slice.map_async(wgpu::MapMode::Read, Result::unwrap);
|
||||
|
||||
dev.poll(wgpu::Maintain::Wait);
|
||||
|
||||
let mut out = crate::uninit::Image::<_, 4>::new(width, height);
|
||||
for (padded, pixels) in buffer_slice
|
||||
.get_mapped_range()
|
||||
.chunks_exact(pad)
|
||||
.zip(out.buf().chunks_exact_mut(row))
|
||||
{
|
||||
::core::mem::MaybeUninit::write_slice(pixels, &padded[..row]);
|
||||
}
|
||||
|
||||
unsafe { out.assume_init().boxed() }
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue