use std::sync::Arc;
use crate::context::ComputeContext;
pub struct SharedDevice {
pub device: wgpu::Device,
pub queue: wgpu::Queue,
pub adapter_info: Option<wgpu::AdapterInfo>,
}
pub type SharedDeviceRef = Arc<SharedDevice>;
impl SharedDevice {
pub fn new(
device: wgpu::Device,
queue: wgpu::Queue,
adapter_info: Option<wgpu::AdapterInfo>,
) -> SharedDeviceRef {
Arc::new(SharedDevice {
device,
queue,
adapter_info,
})
}
}
pub struct SharedComputeContext {
shared: SharedDeviceRef,
}
impl SharedComputeContext {
pub fn new(shared: SharedDeviceRef) -> Self {
Self { shared }
}
pub fn device(&self) -> &wgpu::Device {
&self.shared.device
}
pub fn queue(&self) -> &wgpu::Queue {
&self.shared.queue
}
pub fn adapter_info(&self) -> Option<&wgpu::AdapterInfo> {
self.shared.adapter_info.as_ref()
}
pub fn clone_ref(&self) -> SharedDeviceRef {
Arc::clone(&self.shared)
}
pub fn into_compute_context(self) -> SharedComputeContext {
self
}
}
pub fn extract_from_context(ctx: ComputeContext) -> SharedDeviceRef {
let info = ctx.adapter_info().clone();
SharedDevice::new(ctx.device, ctx.queue, Some(info))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn shared_compute_context_roundtrip() {
oxiui_core::require_gpu!(ctx, ComputeContext::try_new());
let info = ctx.adapter_info().clone();
let shared = extract_from_context(ctx);
let _device = &shared.device;
let _queue = &shared.queue;
assert_eq!(
shared.adapter_info.as_ref().map(|i| &i.name),
Some(&info.name)
);
}
#[test]
fn shared_device_ref_clone() {
oxiui_core::require_gpu!(ctx, ComputeContext::try_new());
let shared = extract_from_context(ctx);
let clone = Arc::clone(&shared);
assert!(Arc::ptr_eq(&shared, &clone));
}
#[test]
fn shared_compute_context_adapter_info() {
oxiui_core::require_gpu!(ctx, ComputeContext::try_new());
let info = ctx.adapter_info().clone();
let shared = SharedDevice::new(ctx.device, ctx.queue, Some(info));
let sc = SharedComputeContext::new(shared);
assert!(sc.adapter_info().is_some());
}
#[test]
fn shared_device_new_builds_arc() {
oxiui_core::require_gpu!(ctx, ComputeContext::try_new());
let sd = SharedDevice::new(ctx.device, ctx.queue, None);
assert_eq!(Arc::strong_count(&sd), 1);
let _clone = Arc::clone(&sd);
assert_eq!(Arc::strong_count(&sd), 2);
}
}