Skip to content

Commit

Permalink
pass around RawDisplayHandle and RawWindowHandle in implementation (#…
Browse files Browse the repository at this point in the history
…3022)

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.
  • Loading branch information
i509VCB authored Sep 15, 2022
1 parent 94ce763 commit 9e3efd7
Show file tree
Hide file tree
Showing 15 changed files with 88 additions and 40 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<A>` 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)
Expand Down
9 changes: 7 additions & 2 deletions player/src/bin/play.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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 }) => {
Expand Down
44 changes: 35 additions & 9 deletions wgpu-core/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
#[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<G, SurfaceId>,
) -> SurfaceId {
profiling::scope!("Instance::create_surface");
Expand All @@ -434,11 +435,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
fn init<A: hal::Api>(
_: A,
inst: &Option<A::Instance>,
handle: &(impl raw_window_handle::HasRawWindowHandle
+ raw_window_handle::HasRawDisplayHandle),
display_handle: raw_window_handle::RawDisplayHandle,
window_handle: raw_window_handle::RawWindowHandle,
) -> Option<HalSurface<A>> {
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,
Expand All @@ -454,15 +455,40 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
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();
Expand Down
7 changes: 6 additions & 1 deletion wgpu-hal/examples/halmark/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -91,7 +92,11 @@ impl<A: hal::Api> Example<A> {
},
};
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();
Expand Down
3 changes: 2 additions & 1 deletion wgpu-hal/src/dx11/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ impl crate::Instance<super::Api> 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<super::Surface, crate::InstanceError> {
todo!()
}
Expand Down
5 changes: 3 additions & 2 deletions wgpu-hal/src/dx12/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,10 @@ impl crate::Instance<super::Api> 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<super::Surface, crate::InstanceError> {
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 _),
Expand Down
3 changes: 2 additions & 1 deletion wgpu-hal/src/empty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ impl crate::Instance<Api> 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<Context, crate::InstanceError> {
Ok(Context)
}
Expand Down
12 changes: 5 additions & 7 deletions wgpu-hal/src/gles/egl.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -770,16 +769,15 @@ impl crate::Instance<super::Api> 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<Surface, crate::InstanceError> {
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(_), _) => {}
Expand Down Expand Up @@ -853,7 +851,7 @@ impl crate::Instance<super::Api> 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,
})
Expand Down Expand Up @@ -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<Swapchain>,
srgb_kind: SrgbFrameBufferKind,
}
Expand Down
5 changes: 3 additions & 2 deletions wgpu-hal/src/gles/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,10 @@ impl crate::Instance<super::Api> 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<Surface, crate::InstanceError> {
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")
Expand Down
3 changes: 2 additions & 1 deletion wgpu-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ pub trait Instance<A: Api>: Sized + Send + Sync {
unsafe fn init(desc: &InstanceDescriptor) -> Result<Self, InstanceError>;
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<A::Surface, InstanceError>;
unsafe fn destroy_surface(&self, surface: A::Surface);
unsafe fn enumerate_adapters(&self) -> Vec<ExposedAdapter<A>>;
Expand Down
5 changes: 3 additions & 2 deletions wgpu-hal/src/metal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,10 @@ impl crate::Instance<Api> 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<Surface, crate::InstanceError> {
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;
Expand Down
9 changes: 3 additions & 6 deletions wgpu-hal/src/vulkan/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -591,15 +591,12 @@ impl crate::Instance<super::Api> 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<super::Surface, crate::InstanceError> {
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))
}
Expand Down
7 changes: 5 additions & 2 deletions wgpu/src/backend/direct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
}
Expand Down
5 changes: 3 additions & 2 deletions wgpu/src/backend/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
};
Expand Down
9 changes: 7 additions & 2 deletions wgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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),
),
}
}

Expand Down

0 comments on commit 9e3efd7

Please sign in to comment.