1use std::sync::Arc;
2
3use bytemuck::Pod;
4use pollster::FutureExt as _;
5pub use wgpu::{Backends, Features, Limits};
6
7use crate::{
8 BindGroupDescriptor, Buffer, CommandQueue, Image, ImageInfo, Kernel, KernelInfo, Program,
9 Sampler, SamplerInfo,
10};
11
12#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct ContextInfo {
15 pub backends: Backends,
16 pub features: Features,
17 pub limits: Limits,
18}
19
20impl Default for ContextInfo {
21 fn default() -> Self {
22 Self {
23 backends: Backends::all(),
24 features: Features::empty(),
25 limits: Limits::default(),
26 }
27 }
28}
29
30#[derive(Debug)]
32pub struct Context {
33 pub(crate) device: Arc<crate::Device>,
34}
35
36impl Context {
37 pub fn new(info: &ContextInfo) -> Self {
39 let instance = wgpu::Instance::new(info.backends);
40
41 let adapter = instance
42 .request_adapter(&wgpu::RequestAdapterOptions::default())
43 .block_on()
44 .unwrap();
45
46 Self::from_wgpu_adapter(
47 &adapter,
48 &wgpu::DeviceDescriptor {
49 label: Some("Device"),
50 features: info.features,
51 limits: info.limits.clone(),
52 },
53 )
54 }
55
56 pub fn from_wgpu_adapter(
63 adapter: &wgpu::Adapter,
64 device_descriptor: &wgpu::DeviceDescriptor,
65 ) -> Self {
66 let (device, queue) = adapter
67 .request_device(&device_descriptor, None)
68 .block_on()
69 .unwrap();
70
71 Self {
72 device: Arc::new(crate::Device {
73 handle: device,
74 queue,
75 }),
76 }
77 }
78
79 pub fn buffer<T: Pod>(&self, capacity: wgpu::BufferAddress) -> Buffer<T> {
86 Buffer::new(self, capacity)
87 }
88
89 pub fn buffer_from_slice<T: Pod>(&self, data: &[T]) -> Buffer<T> {
96 Buffer::from_slice(self, data)
97 }
98
99 pub fn image(&self, info: &ImageInfo) -> Image {
101 Image::new(self, info)
102 }
103
104 pub fn sampler(&self, info: &SamplerInfo) -> Sampler {
106 Sampler::new(self, info)
107 }
108
109 pub fn bind_group_descriptor(&self) -> BindGroupDescriptor {
112 BindGroupDescriptor::new(self)
113 }
114
115 pub fn program_from_shader_source(&self, source: wgpu::ShaderSource) -> Program {
117 Program::from_source(self, source)
118 }
119
120 pub fn program_from_wgsl(&self, source: &str) -> Program {
122 let shader_source = wgpu::ShaderSource::Wgsl(source.into());
123 self.program_from_shader_source(shader_source)
124 }
125
126 pub fn kernel(&self, info: &KernelInfo) -> Kernel {
128 Kernel::new(self, info)
129 }
130
131 pub fn command_queue(&self) -> CommandQueue {
133 CommandQueue::new(self)
134 }
135
136 #[cfg(feature = "from_image")]
137 pub fn image_from_rgba8_img(
139 &self,
140 image: &image::RgbaImage,
141 sample_type: crate::ImageSampleType,
142 ) -> Image {
143 Image::from_rgba8_image(self, image, sample_type)
144 }
145}