From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- third_party/rust/wgpu-core/src/global.rs | 172 +++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 third_party/rust/wgpu-core/src/global.rs (limited to 'third_party/rust/wgpu-core/src/global.rs') diff --git a/third_party/rust/wgpu-core/src/global.rs b/third_party/rust/wgpu-core/src/global.rs new file mode 100644 index 0000000000..9a8c43bf33 --- /dev/null +++ b/third_party/rust/wgpu-core/src/global.rs @@ -0,0 +1,172 @@ +use std::sync::Arc; + +use wgt::Backend; + +use crate::{ + hal_api::HalApi, + hub::{HubReport, Hubs}, + instance::{Instance, Surface}, + registry::{Registry, RegistryReport}, + resource_log, + storage::Element, +}; + +#[derive(Debug, PartialEq, Eq)] +pub struct GlobalReport { + pub surfaces: RegistryReport, + #[cfg(vulkan)] + pub vulkan: Option, + #[cfg(metal)] + pub metal: Option, + #[cfg(dx12)] + pub dx12: Option, + #[cfg(gles)] + pub gl: Option, +} + +impl GlobalReport { + pub fn surfaces(&self) -> &RegistryReport { + &self.surfaces + } + pub fn hub_report(&self, backend: Backend) -> &HubReport { + match backend { + #[cfg(vulkan)] + Backend::Vulkan => self.vulkan.as_ref().unwrap(), + #[cfg(metal)] + Backend::Metal => self.metal.as_ref().unwrap(), + #[cfg(dx12)] + Backend::Dx12 => self.dx12.as_ref().unwrap(), + #[cfg(gles)] + Backend::Gl => self.gl.as_ref().unwrap(), + _ => panic!("HubReport is not supported on this backend"), + } + } +} + +pub struct Global { + pub instance: Instance, + pub surfaces: Registry, + pub(crate) hubs: Hubs, +} + +impl Global { + pub fn new(name: &str, instance_desc: wgt::InstanceDescriptor) -> Self { + profiling::scope!("Global::new"); + Self { + instance: Instance::new(name, instance_desc), + surfaces: Registry::without_backend(), + hubs: Hubs::new(), + } + } + + /// # Safety + /// + /// Refer to the creation of wgpu-hal Instance for every backend. + pub unsafe fn from_hal_instance(name: &str, hal_instance: A::Instance) -> Self { + profiling::scope!("Global::new"); + Self { + instance: A::create_instance_from_hal(name, hal_instance), + surfaces: Registry::without_backend(), + hubs: Hubs::new(), + } + } + + /// # Safety + /// + /// - The raw instance handle returned must not be manually destroyed. + pub unsafe fn instance_as_hal(&self) -> Option<&A::Instance> { + A::instance_as_hal(&self.instance) + } + + /// # Safety + /// + /// - The raw handles obtained from the Instance must not be manually destroyed + pub unsafe fn from_instance(instance: Instance) -> Self { + profiling::scope!("Global::new"); + Self { + instance, + surfaces: Registry::without_backend(), + hubs: Hubs::new(), + } + } + + pub fn clear_backend(&self, _dummy: ()) { + let hub = A::hub(self); + let surfaces_locked = self.surfaces.read(); + // this is used for tests, which keep the adapter + hub.clear(&surfaces_locked, false); + } + + pub fn generate_report(&self) -> GlobalReport { + GlobalReport { + surfaces: self.surfaces.generate_report(), + #[cfg(vulkan)] + vulkan: if self.instance.vulkan.is_some() { + Some(self.hubs.vulkan.generate_report()) + } else { + None + }, + #[cfg(metal)] + metal: if self.instance.metal.is_some() { + Some(self.hubs.metal.generate_report()) + } else { + None + }, + #[cfg(dx12)] + dx12: if self.instance.dx12.is_some() { + Some(self.hubs.dx12.generate_report()) + } else { + None + }, + #[cfg(gles)] + gl: if self.instance.gl.is_some() { + Some(self.hubs.gl.generate_report()) + } else { + None + }, + } + } +} + +impl Drop for Global { + fn drop(&mut self) { + profiling::scope!("Global::drop"); + resource_log!("Global::drop"); + let mut surfaces_locked = self.surfaces.write(); + + // destroy hubs before the instance gets dropped + #[cfg(vulkan)] + { + self.hubs.vulkan.clear(&surfaces_locked, true); + } + #[cfg(metal)] + { + self.hubs.metal.clear(&surfaces_locked, true); + } + #[cfg(dx12)] + { + self.hubs.dx12.clear(&surfaces_locked, true); + } + #[cfg(gles)] + { + self.hubs.gl.clear(&surfaces_locked, true); + } + + // destroy surfaces + for element in surfaces_locked.map.drain(..) { + if let Element::Occupied(arc_surface, _) = element { + if let Some(surface) = Arc::into_inner(arc_surface) { + self.instance.destroy_surface(surface); + } else { + panic!("Surface cannot be destroyed because is still in use"); + } + } + } + } +} + +#[cfg(send_sync)] +fn _test_send_sync(global: &Global) { + fn test_internal(_: T) {} + test_internal(global) +} -- cgit v1.2.3