From 3a9f5a9f84000bb508ae868e1d72e69738c4b0bb Mon Sep 17 00:00:00 2001 From: i509VCB Date: Tue, 13 Sep 2022 00:15:49 -0500 Subject: [PATCH] pass around RawDisplayHandle and RawWindowHandle in implementation This change is to help with an attempt to allow the Context type in wgpu to be swappable at runtime. In order to do that, the functions provided by Context and it's associated types need to be object safe. Instead of passing a impl trait that combines both HasRawWindowHandle and HasRawDisplayHandle, we seperate the types into their RawDisplayHandle and RawWindowHandle parts internally to reduce some of the hal implementation code mess. --- CHANGELOG.md | 2 ++ player/src/bin/play.rs | 9 +++++-- wgpu-core/src/instance.rs | 44 ++++++++++++++++++++++++------- wgpu-hal/examples/halmark/main.rs | 7 ++++- wgpu-hal/src/dx11/instance.rs | 3 ++- wgpu-hal/src/dx12/instance.rs | 5 ++-- wgpu-hal/src/empty.rs | 3 ++- wgpu-hal/src/gles/egl.rs | 12 ++++----- wgpu-hal/src/gles/web.rs | 5 ++-- wgpu-hal/src/lib.rs | 3 ++- wgpu-hal/src/metal/mod.rs | 5 ++-- wgpu-hal/src/vulkan/instance.rs | 9 +++---- wgpu/src/backend/direct.rs | 7 +++-- wgpu/src/backend/web.rs | 5 ++-- wgpu/src/lib.rs | 9 +++++-- 15 files changed, 88 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3555702a5a..227b27968c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -84,6 +84,8 @@ the same every time it is rendered, we now warn if it is missing. ### Changes #### General +- Changed wgpu-hal and wgpu-core implementation to pass RawDisplayHandle and RawWindowHandle as separate + parameters instead of passing an impl trait over both HasRawDisplayHandle and HasRawWindowHandle. By @i509VCB in [#3022](https://github.com/gfx-rs/wgpu/pull/3022) - Changed `Instance::as_hal` to just return an `Option<&A::Instance>` rather than taking a callback. By @jimb in [#2991](https://github.com/gfx-rs/wgpu/pull/2991) - Added downlevel restriction error message for `InvalidFormatUsages` error by @Seamooo in [#2886](https://github.com/gfx-rs/wgpu/pull/2886) - Add warning when using CompareFunction::*Equal with vertex shader that is missing @invariant tag by @cwfitzgerald in [#2887](https://github.com/gfx-rs/wgpu/pull/2887) diff --git a/player/src/bin/play.rs b/player/src/bin/play.rs index d973ec48c0..3ccc11c270 100644 --- a/player/src/bin/play.rs +++ b/player/src/bin/play.rs @@ -10,6 +10,8 @@ use std::{ }; fn main() { + #[cfg(feature = "winit")] + use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle}; #[cfg(feature = "winit")] use winit::{event_loop::EventLoop, window::WindowBuilder}; @@ -45,8 +47,11 @@ fn main() { let mut command_buffer_id_manager = wgc::hub::IdentityManager::default(); #[cfg(feature = "winit")] - let surface = - global.instance_create_surface(&window, wgc::id::TypedId::zip(0, 1, wgt::Backend::Empty)); + let surface = global.instance_create_surface( + window.raw_display_handle(), + window.raw_window_handle(), + wgc::id::TypedId::zip(0, 1, wgt::Backend::Empty), + ); let device = match actions.pop() { Some(trace::Action::Init { desc, backend }) => { diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 8ad4774c63..1aa1470c8d 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -424,7 +424,8 @@ impl Global { #[cfg(feature = "raw-window-handle")] pub fn instance_create_surface( &self, - handle: &(impl raw_window_handle::HasRawWindowHandle + raw_window_handle::HasRawDisplayHandle), + display_handle: raw_window_handle::RawDisplayHandle, + window_handle: raw_window_handle::RawWindowHandle, id_in: Input, ) -> SurfaceId { profiling::scope!("Instance::create_surface"); @@ -434,11 +435,11 @@ impl Global { fn init( _: A, inst: &Option, - handle: &(impl raw_window_handle::HasRawWindowHandle - + raw_window_handle::HasRawDisplayHandle), + display_handle: raw_window_handle::RawDisplayHandle, + window_handle: raw_window_handle::RawWindowHandle, ) -> Option> { inst.as_ref().and_then(|inst| unsafe { - match inst.create_surface(handle) { + match inst.create_surface(display_handle, window_handle) { Ok(raw) => Some(HalSurface { raw, //acquired_texture: None, @@ -454,15 +455,40 @@ impl Global { let surface = Surface { presentation: None, #[cfg(vulkan)] - vulkan: init(hal::api::Vulkan, &self.instance.vulkan, handle), + vulkan: init( + hal::api::Vulkan, + &self.instance.vulkan, + display_handle, + window_handle, + ), #[cfg(metal)] - metal: init(hal::api::Metal, &self.instance.metal, handle), + metal: init( + hal::api::Metal, + &self.instance.metal, + display_handle, + window_handle, + ), #[cfg(dx12)] - dx12: init(hal::api::Dx12, &self.instance.dx12, handle), + dx12: init( + hal::api::Dx12, + &self.instance.dx12, + display_handle, + window_handle, + ), #[cfg(dx11)] - dx11: init(hal::api::Dx11, &self.instance.dx11, handle), + dx11: init( + hal::api::Dx11, + &self.instance.dx11, + display_handle, + window_handle, + ), #[cfg(gl)] - gl: init(hal::api::Gles, &self.instance.gl, handle), + gl: init( + hal::api::Gles, + &self.instance.gl, + display_handle, + window_handle, + ), }; let mut token = Token::root(); diff --git a/wgpu-hal/examples/halmark/main.rs b/wgpu-hal/examples/halmark/main.rs index 383efcdc53..b9df5f2171 100644 --- a/wgpu-hal/examples/halmark/main.rs +++ b/wgpu-hal/examples/halmark/main.rs @@ -5,6 +5,7 @@ extern crate wgpu_hal as hal; use hal::{ Adapter as _, CommandEncoder as _, Device as _, Instance as _, Queue as _, Surface as _, }; +use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle}; use std::{borrow::Borrow, iter, mem, num::NonZeroU32, ptr, time::Instant}; @@ -91,7 +92,11 @@ impl Example { }, }; let instance = unsafe { A::Instance::init(&instance_desc)? }; - let mut surface = unsafe { instance.create_surface(window).unwrap() }; + let mut surface = unsafe { + instance + .create_surface(window.raw_display_handle(), window.raw_window_handle()) + .unwrap() + }; let (adapter, capabilities) = unsafe { let mut adapters = instance.enumerate_adapters(); diff --git a/wgpu-hal/src/dx11/instance.rs b/wgpu-hal/src/dx11/instance.rs index ac0fdbe597..104ba9e045 100644 --- a/wgpu-hal/src/dx11/instance.rs +++ b/wgpu-hal/src/dx11/instance.rs @@ -27,7 +27,8 @@ impl crate::Instance for super::Instance { unsafe fn create_surface( &self, - rwh: &impl raw_window_handle::HasRawWindowHandle, + display_handle: raw_window_handle::RawDisplayHandle, + window_handle: raw_window_handle::RawWindowHandle, ) -> Result { todo!() } diff --git a/wgpu-hal/src/dx12/instance.rs b/wgpu-hal/src/dx12/instance.rs index 2f115a6a62..b300c39857 100644 --- a/wgpu-hal/src/dx12/instance.rs +++ b/wgpu-hal/src/dx12/instance.rs @@ -67,9 +67,10 @@ impl crate::Instance for super::Instance { unsafe fn create_surface( &self, - has_handle: &impl raw_window_handle::HasRawWindowHandle, + _display_handle: raw_window_handle::RawDisplayHandle, + window_handle: raw_window_handle::RawWindowHandle, ) -> Result { - match has_handle.raw_window_handle() { + match window_handle { raw_window_handle::RawWindowHandle::Win32(handle) => Ok(super::Surface { factory: self.factory, target: SurfaceTarget::WndHandle(handle.hwnd as *mut _), diff --git a/wgpu-hal/src/empty.rs b/wgpu-hal/src/empty.rs index 0c546469b2..24e7720be2 100644 --- a/wgpu-hal/src/empty.rs +++ b/wgpu-hal/src/empty.rs @@ -43,7 +43,8 @@ impl crate::Instance for Context { } unsafe fn create_surface( &self, - rwh: &impl raw_window_handle::HasRawWindowHandle, + _display_handle: raw_window_handle::RawDisplayHandle, + _window_handle: raw_window_handle::RawWindowHandle, ) -> Result { Ok(Context) } diff --git a/wgpu-hal/src/gles/egl.rs b/wgpu-hal/src/gles/egl.rs index bf11afe87d..32264276c6 100644 --- a/wgpu-hal/src/gles/egl.rs +++ b/wgpu-hal/src/gles/egl.rs @@ -1,6 +1,5 @@ use glow::HasContext; use parking_lot::{Mutex, MutexGuard}; -use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle, RawWindowHandle}; use std::{ffi, os::raw, ptr, sync::Arc, time::Duration}; @@ -770,16 +769,15 @@ impl crate::Instance for Instance { #[cfg_attr(target_os = "macos", allow(unused, unused_mut, unreachable_code))] unsafe fn create_surface( &self, - has_handle: &(impl HasRawWindowHandle + HasRawDisplayHandle), + display_handle: raw_window_handle::RawDisplayHandle, + window_handle: raw_window_handle::RawWindowHandle, ) -> Result { use raw_window_handle::RawWindowHandle as Rwh; - let raw_window_handle = has_handle.raw_window_handle(); - #[cfg_attr(any(target_os = "android", feature = "emscripten"), allow(unused_mut))] let mut inner = self.inner.lock(); - match (raw_window_handle, has_handle.raw_display_handle()) { + match (window_handle, display_handle) { (Rwh::Xlib(_), _) => {} (Rwh::Xcb(_), _) => {} (Rwh::Win32(_), _) => {} @@ -853,7 +851,7 @@ impl crate::Instance for Instance { wsi: self.wsi.clone(), config: inner.config, presentable: inner.supports_native_window, - raw_window_handle, + raw_window_handle: window_handle, swapchain: None, srgb_kind: inner.srgb_kind, }) @@ -945,7 +943,7 @@ pub struct Surface { wsi: WindowSystemInterface, config: egl::Config, pub(super) presentable: bool, - raw_window_handle: RawWindowHandle, + raw_window_handle: raw_window_handle::RawWindowHandle, swapchain: Option, srgb_kind: SrgbFrameBufferKind, } diff --git a/wgpu-hal/src/gles/web.rs b/wgpu-hal/src/gles/web.rs index bb561f5bae..396fdad04b 100644 --- a/wgpu-hal/src/gles/web.rs +++ b/wgpu-hal/src/gles/web.rs @@ -108,9 +108,10 @@ impl crate::Instance for Instance { unsafe fn create_surface( &self, - has_handle: &impl raw_window_handle::HasRawWindowHandle, + _display_handle: raw_window_handle::RawDisplayHandle, + window_handle: raw_window_handle::RawWindowHandle, ) -> Result { - if let raw_window_handle::RawWindowHandle::Web(handle) = has_handle.raw_window_handle() { + if let raw_window_handle::RawWindowHandle::Web(handle) = window_handle { let canvas: web_sys::HtmlCanvasElement = web_sys::window() .and_then(|win| win.document()) .expect("Cannot get document") diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index 02d3c13af1..259318bf59 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -178,7 +178,8 @@ pub trait Instance: Sized + Send + Sync { unsafe fn init(desc: &InstanceDescriptor) -> Result; unsafe fn create_surface( &self, - rwh: &(impl raw_window_handle::HasRawWindowHandle + raw_window_handle::HasRawDisplayHandle), + display_handle: raw_window_handle::RawDisplayHandle, + window_handle: raw_window_handle::RawWindowHandle, ) -> Result; unsafe fn destroy_surface(&self, surface: A::Surface); unsafe fn enumerate_adapters(&self) -> Vec>; diff --git a/wgpu-hal/src/metal/mod.rs b/wgpu-hal/src/metal/mod.rs index dee9467e74..d4ba2d14cf 100644 --- a/wgpu-hal/src/metal/mod.rs +++ b/wgpu-hal/src/metal/mod.rs @@ -81,9 +81,10 @@ impl crate::Instance for Instance { unsafe fn create_surface( &self, - has_handle: &impl raw_window_handle::HasRawWindowHandle, + _display_handle: raw_window_handle::RawDisplayHandle, + window_handle: raw_window_handle::RawWindowHandle, ) -> Result { - match has_handle.raw_window_handle() { + match window_handle { #[cfg(target_os = "ios")] raw_window_handle::RawWindowHandle::UiKit(handle) => { let _ = &self.managed_metal_layer_delegate; diff --git a/wgpu-hal/src/vulkan/instance.rs b/wgpu-hal/src/vulkan/instance.rs index bd3a884879..79045ff061 100644 --- a/wgpu-hal/src/vulkan/instance.rs +++ b/wgpu-hal/src/vulkan/instance.rs @@ -591,15 +591,12 @@ impl crate::Instance for super::Instance { unsafe fn create_surface( &self, - has_handle: &(impl raw_window_handle::HasRawWindowHandle - + raw_window_handle::HasRawDisplayHandle), + display_handle: raw_window_handle::RawDisplayHandle, + window_handle: raw_window_handle::RawWindowHandle, ) -> Result { use raw_window_handle::{RawDisplayHandle as Rdh, RawWindowHandle as Rwh}; - match ( - has_handle.raw_window_handle(), - has_handle.raw_display_handle(), - ) { + match (window_handle, display_handle) { (Rwh::Wayland(handle), Rdh::Wayland(display)) => { Ok(self.create_surface_from_wayland(display.display, handle.surface)) } diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 669ba456de..67d439e199 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -843,10 +843,13 @@ impl crate::Context for Context { fn instance_create_surface( &self, - handle: &(impl raw_window_handle::HasRawWindowHandle + raw_window_handle::HasRawDisplayHandle), + display_handle: raw_window_handle::RawDisplayHandle, + window_handle: raw_window_handle::RawWindowHandle, ) -> Self::SurfaceId { Surface { - id: self.0.instance_create_surface(handle, ()), + id: self + .0 + .instance_create_surface(display_handle, window_handle, ()), configured_device: Mutex::new(None), } } diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index f816125148..dc7e473782 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -1021,9 +1021,10 @@ impl crate::Context for Context { fn instance_create_surface( &self, - handle: &impl raw_window_handle::HasRawWindowHandle, + _display_handle: raw_window_handle::RawDisplayHandle, + window_handle: raw_window_handle::RawWindowHandle, ) -> Self::SurfaceId { - let canvas_attribute = match handle.raw_window_handle() { + let canvas_attribute = match window_handle { raw_window_handle::RawWindowHandle::Web(web_handle) => web_handle.id, _ => panic!("expected valid handle for canvas"), }; diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 541fa3566e..97abc067b3 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -197,7 +197,8 @@ trait Context: Debug + Send + Sized + Sync { fn init(backends: Backends) -> Self; fn instance_create_surface( &self, - handle: &(impl raw_window_handle::HasRawWindowHandle + raw_window_handle::HasRawDisplayHandle), + display_handle: raw_window_handle::RawDisplayHandle, + window_handle: raw_window_handle::RawWindowHandle, ) -> Self::SurfaceId; fn instance_request_adapter( &self, @@ -1763,7 +1764,11 @@ impl Instance { ) -> Surface { Surface { context: Arc::clone(&self.context), - id: Context::instance_create_surface(&*self.context, window), + id: Context::instance_create_surface( + &*self.context, + raw_window_handle::HasRawDisplayHandle::raw_display_handle(window), + raw_window_handle::HasRawWindowHandle::raw_window_handle(window), + ), } }