mirror of
https://github.com/bend-n/fimg.git
synced 2024-12-22 02:28:19 -06:00
wgpu types
This commit is contained in:
parent
33e55b5ab5
commit
05f0d3d10d
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "fimg"
|
name = "fimg"
|
||||||
version = "0.4.34"
|
version = "0.4.36"
|
||||||
authors = ["bend-n <bend.n@outlook.com>"]
|
authors = ["bend-n <bend.n@outlook.com>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
@ -23,6 +23,7 @@ minifb = { version = "0.25.0", default-features = false, features = [
|
||||||
"x11",
|
"x11",
|
||||||
"wayland",
|
"wayland",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
|
wgpu = { version = "0.19.1", default-features = false, optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
iai = { git = "https://github.com/bend-n/iai.git" }
|
iai = { git = "https://github.com/bend-n/iai.git" }
|
||||||
|
@ -59,6 +60,7 @@ text = ["fontdue"]
|
||||||
blur = ["slur"]
|
blur = ["slur"]
|
||||||
real-show = ["minifb", "text"]
|
real-show = ["minifb", "text"]
|
||||||
default = ["save", "scale"]
|
default = ["save", "scale"]
|
||||||
|
wgpu-convert = ["dep:wgpu"]
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
debug = 2
|
debug = 2
|
||||||
|
|
|
@ -92,6 +92,8 @@ mod pack;
|
||||||
mod span;
|
mod span;
|
||||||
mod sub;
|
mod sub;
|
||||||
pub mod uninit;
|
pub mod uninit;
|
||||||
|
#[cfg(feature = "wgpu-convert")]
|
||||||
|
mod wgpu_convert;
|
||||||
pub use pack::Pack;
|
pub use pack::Pack;
|
||||||
pub mod pixels;
|
pub mod pixels;
|
||||||
#[cfg(feature = "scale")]
|
#[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