From 64ffdd52ad873fa8c01c6ac430eea56da4c3ef47 Mon Sep 17 00:00:00 2001 From: Lonsdaleiter <52022063+Lonsdaleiter@users.noreply.github.com> Date: Wed, 4 Aug 2021 07:27:08 -0700 Subject: [PATCH] Added is_surface_supported (#1763) --- wgpu-core/src/device/mod.rs | 18 ++++++++++++++++++ wgpu-core/src/instance.rs | 17 +++++++++++++++++ wgpu/src/backend/direct.rs | 12 ++++++++++++ wgpu/src/lib.rs | 10 ++++++++++ 4 files changed, 57 insertions(+) diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 6f5e999399..52d492aba3 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -2550,6 +2550,24 @@ impl ImplicitPipelineIds<'_, G> { } impl Global { + pub fn adapter_is_surface_supported( + &self, + adapter_id: id::AdapterId, + surface_id: id::SurfaceId, + ) -> Result { + let hub = A::hub(self); + let mut token = Token::root(); + + let (mut surface_guard, mut token) = self.surfaces.write(&mut token); + let (adapter_guard, mut _token) = hub.adapters.read(&mut token); + let adapter = adapter_guard + .get(adapter_id) + .map_err(|_| instance::IsSurfaceSupportedError::InvalidAdapter)?; + let surface = surface_guard + .get_mut(surface_id) + .map_err(|_| instance::IsSurfaceSupportedError::InvalidSurface)?; + Ok(adapter.is_surface_supported(surface)) + } pub fn adapter_get_swap_chain_preferred_format( &self, adapter_id: id::AdapterId, diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 14c0edbe17..63bc7cfa6d 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -181,6 +181,15 @@ impl Adapter { } } + pub fn is_surface_supported(&self, surface: &mut Surface) -> bool { + unsafe { + self.raw + .adapter + .surface_capabilities(A::get_surface_mut(surface)) + } + .is_some() + } + pub fn get_swap_chain_preferred_format( &self, surface: &mut Surface, @@ -344,6 +353,14 @@ impl crate::hub::Resource for Adapter { } } +#[derive(Clone, Debug, Error)] +pub enum IsSurfaceSupportedError { + #[error("invalid adapter")] + InvalidAdapter, + #[error("invalid surface")] + InvalidSurface, +} + #[derive(Clone, Debug, Error)] pub enum GetSwapChainPreferredFormatError { #[error("no suitable format found")] diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index b3e4530f39..8cf7784892 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -795,6 +795,18 @@ impl crate::Context for Context { ready(Ok((device, device_id))) } + fn adapter_is_surface_supported( + &self, + adapter: &Self::AdapterId, + surface: &Self::SurfaceId, + ) -> bool { + let global = &self.0; + match wgc::gfx_select!(adapter => global.adapter_is_surface_supported(*adapter, *surface)) { + Ok(result) => result, + Err(err) => self.handle_error_fatal(err, "Adapter::is_surface_supported"), + } + } + fn adapter_get_swap_chain_preferred_format( &self, adapter: &Self::AdapterId, diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 5da8ddef2a..b371442ce2 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -199,6 +199,11 @@ trait Context: Debug + Send + Sized + Sync { trace_dir: Option<&std::path::Path>, ) -> Self::RequestDeviceFuture; fn instance_poll_all_devices(&self, force_wait: bool); + fn adapter_is_surface_supported( + &self, + adapter: &Self::AdapterId, + surface: &Self::SurfaceId, + ) -> bool; fn adapter_get_swap_chain_preferred_format( &self, adapter: &Self::AdapterId, @@ -1564,6 +1569,11 @@ impl Adapter { }) } + /// Returns whether this adapter may present to the passed surface. + pub fn is_surface_supported(&self, surface: &Surface) -> bool { + Context::adapter_is_surface_supported(&*self.context, &self.id, &surface.id) + } + /// Returns an optimal texture format to use for the [`SwapChain`] with this adapter. /// /// Returns None if the surface is incompatible with the adapter.