mod window;
mod windowless;
use wgpu::{util::DeviceExt, TextureUsages};
pub use window::*;
pub use windowless::*;
use crate::{Dimension, Error, OwnedTexture};
#[inline]
pub(crate) fn create_wgpu_instance() -> wgpu::Instance {
wgpu::Instance::new(wgpu::InstanceDescriptor {
backends: wgpu::Backends::all(),
flags: wgpu::InstanceFlags::debugging(),
..Default::default()
})
}
#[inline]
pub(crate) async fn request_wgpu_adapter(
wgpu_instance: &wgpu::Instance,
compatible_surface: Option<&wgpu::Surface>,
) -> Result<wgpu::Adapter, Error> {
wgpu_instance
.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::default(),
compatible_surface,
force_fallback_adapter: false,
})
.await
.ok_or(Error::FailedToAcquireAdapter)
}
pub(crate) async fn request_wgpu_device(
wgpu_adapter: &wgpu::Adapter,
) -> Result<(wgpu::Device, wgpu::Queue), Error> {
wgpu_adapter
.request_device(
&wgpu::DeviceDescriptor {
features: wgpu::Features::empty(),
limits: wgpu::Limits::default(),
label: None,
},
None, )
.await
.map_err(|err| Error::FailedToAcquireDevice(err.to_string()))
}
pub trait Handle: Sized {
fn wgpu_device(&self) -> &wgpu::Device;
fn wgpu_queue(&self) -> &wgpu::Queue;
fn make_blank_texture(&self, size: Dimension) -> OwnedTexture<'_, Self> {
let wgpu_texture = self.wgpu_device().create_texture(&wgpu::TextureDescriptor {
size: size.to_extent_3d(),
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Rgba8UnormSrgb,
usage: wgpu::TextureUsages::all().difference(TextureUsages::STORAGE_BINDING), label: None,
view_formats: &[],
});
OwnedTexture::from_raw_parts(self, wgpu_texture)
}
fn make_texture(&self, size: Dimension, data: &[u8]) -> Result<OwnedTexture<'_, Self>, Error> {
if data.len() as u32 != size.area() * 4 {
return Err(Error::TextureDataSizeMismatch {
expected: size.area() * 4,
got: data.len() as u32,
});
}
let wgpu_texture = self.wgpu_device().create_texture_with_data(
self.wgpu_queue(),
&wgpu::TextureDescriptor {
size: size.to_extent_3d(),
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Rgba8UnormSrgb,
usage: wgpu::TextureUsages::all().difference(TextureUsages::STORAGE_BINDING), label: None,
view_formats: &[],
},
data,
);
Ok(OwnedTexture::from_raw_parts(self, wgpu_texture))
}
}