use std::sync::Arc;
use bytemuck::Pod;
use pollster::FutureExt as _;
pub use wgpu::{Backends, Features, Limits};
use crate::{
BindGroupDescriptor, Buffer, CommandQueue, Image, ImageInfo, Kernel, KernelInfo, Program,
Sampler, SamplerInfo,
};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ContextInfo {
pub backends: Backends,
pub features: Features,
pub limits: Limits,
}
impl Default for ContextInfo {
fn default() -> Self {
Self {
backends: Backends::all(),
features: Features::empty(),
limits: Limits::default(),
}
}
}
#[derive(Debug)]
pub struct Context {
pub(crate) device: Arc<crate::Device>,
}
impl Context {
pub fn new(info: &ContextInfo) -> Self {
let instance = wgpu::Instance::new(info.backends);
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions::default())
.block_on()
.unwrap();
Self::from_wgpu_adapter(
&adapter,
&wgpu::DeviceDescriptor {
label: Some("Device"),
features: info.features,
limits: info.limits.clone(),
},
)
}
pub fn from_wgpu_adapter(
adapter: &wgpu::Adapter,
device_descriptor: &wgpu::DeviceDescriptor,
) -> Self {
let (device, queue) = adapter
.request_device(&device_descriptor, None)
.block_on()
.unwrap();
Self {
device: Arc::new(crate::Device {
handle: device,
queue,
}),
}
}
pub fn buffer<T: Pod>(&self, capacity: wgpu::BufferAddress) -> Buffer<T> {
Buffer::new(self, capacity)
}
pub fn buffer_from_slice<T: Pod>(&self, data: &[T]) -> Buffer<T> {
Buffer::from_slice(self, data)
}
pub fn image(&self, info: &ImageInfo) -> Image {
Image::new(self, info)
}
pub fn sampler(&self, info: &SamplerInfo) -> Sampler {
Sampler::new(self, info)
}
pub fn bind_group_descriptor(&self) -> BindGroupDescriptor {
BindGroupDescriptor::new(self)
}
pub fn program_from_shader_source(&self, source: wgpu::ShaderSource) -> Program {
Program::from_source(self, source)
}
pub fn program_from_wgsl(&self, source: &str) -> Program {
let shader_source = wgpu::ShaderSource::Wgsl(source.into());
self.program_from_shader_source(shader_source)
}
pub fn kernel(&self, info: &KernelInfo) -> Kernel {
Kernel::new(self, info)
}
pub fn command_queue(&self) -> CommandQueue {
CommandQueue::new(self)
}
#[cfg(feature = "from_image")]
pub fn image_from_rgba8_img(
&self,
image: &image::RgbaImage,
sample_type: crate::ImageSampleType,
) -> Image {
Image::from_rgba8_image(self, image, sample_type)
}
}