use std::sync::Arc;
#[derive(Clone)]
pub struct WgpuContext {
pub device: Arc<wgpu::Device>,
pub queue: Arc<wgpu::Queue>,
}
impl WgpuContext {
pub fn new(device: wgpu::Device, queue: wgpu::Queue) -> Self {
Self {
device: Arc::new(device),
queue: Arc::new(queue),
}
}
pub async fn new_async(compatible_surface: Option<&wgpu::Surface<'_>>) -> anyhow::Result<Self> {
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
backends: wgpu::Backends::all(),
..Default::default()
});
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::HighPerformance,
compatible_surface,
force_fallback_adapter: false,
})
.await
.ok_or_else(|| anyhow::anyhow!("Failed to find suitable GPU adapter"))?;
let (device, queue) = adapter
.request_device(
&wgpu::DeviceDescriptor {
label: Some("rein device"),
required_features: wgpu::Features::empty(),
required_limits: wgpu::Limits::default(),
memory_hints: wgpu::MemoryHints::Performance,
},
None,
)
.await?;
Ok(Self::new(device, queue))
}
pub fn new_blocking(compatible_surface: Option<&wgpu::Surface<'_>>) -> anyhow::Result<Self> {
pollster::block_on(Self::new_async(compatible_surface))
}
pub fn submit<I: IntoIterator<Item = wgpu::CommandBuffer>>(&self, command_buffers: I) {
self.queue.submit(command_buffers);
}
pub fn create_encoder(&self, label: Option<&str>) -> wgpu::CommandEncoder {
self.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label })
}
}
impl std::fmt::Debug for WgpuContext {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("WgpuContext").finish()
}
}