File size: 1,809 Bytes
2409829
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use std::sync::Arc;
use wgpu::{Device, Instance, Queue};

#[derive(Debug, Clone)]
pub struct Context {
	pub device: Arc<Device>,
	pub queue: Arc<Queue>,
	pub instance: Arc<Instance>,
	pub adapter: Arc<wgpu::Adapter>,
}

impl Context {
	pub async fn new() -> Option<Self> {
		// Instantiates instance of WebGPU
		let instance_descriptor = wgpu::InstanceDescriptor {
			backends: wgpu::Backends::all(),
			..Default::default()
		};
		let instance = Instance::new(instance_descriptor);

		let adapter_options = wgpu::RequestAdapterOptions {
			power_preference: wgpu::PowerPreference::HighPerformance,
			compatible_surface: None,
			force_fallback_adapter: false,
		};
		// `request_adapter` instantiates the general connection to the GPU
		let adapter = instance.request_adapter(&adapter_options).await?;

		let required_limits = adapter.limits();
		// `request_device` instantiates the feature specific connection to the GPU, defining some parameters,
		//  `features` being the available features.
		let (device, queue) = adapter
			.request_device(
				&wgpu::DeviceDescriptor {
					label: None,
					// #[cfg(not(feature = "passthrough"))]
					required_features: wgpu::Features::empty(),
					// Currently disabled because not all backend support passthrough.
					// TODO: reenable only when vulkan adapter is available
					// #[cfg(feature = "passthrough")]
					// required_features: wgpu::Features::SPIRV_SHADER_PASSTHROUGH,
					required_limits,
					memory_hints: Default::default(),
				},
				None,
			)
			.await
			.unwrap();

		let info = adapter.get_info();
		// skip this on LavaPipe temporarily
		if info.vendor == 0x10005 {
			return None;
		}
		Some(Self {
			device: Arc::new(device),
			queue: Arc::new(queue),
			adapter: Arc::new(adapter),
			instance: Arc::new(instance),
		})
	}
}