Skip to content
Open

WinRT #9214

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion wgpu-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ windows-core = { workspace = true, optional = true }
# Backend: Dx12
bit-set = { workspace = true, optional = true }
range-alloc = { workspace = true, optional = true }
once_cell = { workspace = true, optional = true }
once_cell = { workspace = true, optional = true, features = ["std"] }
# backend: GLES
glutin_wgl_sys = { workspace = true, optional = true }

Expand Down
7 changes: 5 additions & 2 deletions wgpu-hal/src/dx12/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1202,7 +1202,8 @@ impl crate::Adapter for super::Adapter {
}
SurfaceTarget::Visual(_)
| SurfaceTarget::SurfaceHandle(_)
| SurfaceTarget::SwapChainPanel(_) => None,
| SurfaceTarget::SwapChainPanel(_)
| SurfaceTarget::CoreWindow(_) => None,
}
};

Expand All @@ -1228,7 +1229,9 @@ impl crate::Adapter for super::Adapter {
| wgt::TextureUses::COPY_DST,
present_modes,
composite_alpha_modes: match surface.target {
SurfaceTarget::WndHandle(_) => vec![wgt::CompositeAlphaMode::Opaque],
SurfaceTarget::WndHandle(_) | SurfaceTarget::CoreWindow(_) => {
vec![wgt::CompositeAlphaMode::Opaque]
}
SurfaceTarget::Visual(_)
| SurfaceTarget::VisualFromWndHandle { .. }
| SurfaceTarget::SurfaceHandle(_)
Expand Down
2 changes: 1 addition & 1 deletion wgpu-hal/src/dx12/dcomp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl DCompLib {
fn get_lib(&self) -> Result<&DynLib, crate::SurfaceError> {
match self.lib.as_ref() {
Ok(lib) => Ok(lib),
Err(err) => Err(err.clone()),
Err(err) => Err((*err).clone()),
}
}

Expand Down
24 changes: 23 additions & 1 deletion wgpu-hal/src/dx12/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,30 @@ impl crate::Instance for super::Instance {
options: self.options.clone(),
})
}
raw_window_handle::RawWindowHandle::WinRt(handle) => {
let target = match self.presentation_system {
wgt::Dx12SwapchainKind::DxgiFromHwnd => {
SurfaceTarget::CoreWindow(handle.core_window.as_ptr())
}
wgt::Dx12SwapchainKind::DxgiFromVisual => {
return Err(crate::InstanceError::new(
"DX12 presentation_system=DxgiFromVisual is not supported for WinRT CoreWindow surfaces"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be documented on the Dx12SwapchainKind variant

.into(),
));
}
};

Ok(super::Surface {
factory: self.factory.clone(),
factory_media: self.factory_media.clone(),
target,
supports_allow_tearing: self.supports_allow_tearing,
swap_chain: RwLock::new(None),
options: self.options.clone(),
})
}
_ => Err(crate::InstanceError::new(format!(
"window handle {window_handle:?} is not a Win32 handle"
"window handle {window_handle:?} is not a Win32 or WinRT handle"
))),
}
}
Expand Down
29 changes: 27 additions & 2 deletions wgpu-hal/src/dx12/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,11 @@ struct SwapChain {
enum SurfaceTarget {
/// Borrowed, lifetime externally managed
WndHandle(Foundation::HWND),
/// Borrowed, lifetime externally managed.
///
/// This is a WinRT CoreWindow pointer (IUnknown) used with
/// IDXGIFactory2::CreateSwapChainForCoreWindow.
CoreWindow(*mut ffi::c_void),
/// `handle` is borrowed, lifetime externally managed
VisualFromWndHandle {
handle: Foundation::HWND,
Expand Down Expand Up @@ -1369,6 +1374,23 @@ impl crate::Surface for Surface {
)
}
}
SurfaceTarget::CoreWindow(core_window) => {
profiling::scope!("IDXGIFactory2::CreateSwapChainForCoreWindow");
let core_window =
unsafe { windows_core::IUnknown::from_raw_borrowed(&core_window) }
.ok_or(crate::SurfaceError::Other(
"CoreWindow pointer should not be NULL",
))?;

unsafe {
self.factory.CreateSwapChainForCoreWindow(
&device.present_queue,
core_window,
&desc,
None,
)
}
}
};

let swap_chain1 = swap_chain1.map_err(|err| {
Expand All @@ -1377,7 +1399,9 @@ impl crate::Surface for Surface {
})?;

match &self.target {
SurfaceTarget::WndHandle(_) | SurfaceTarget::SurfaceHandle(_) => {}
SurfaceTarget::WndHandle(_)
| SurfaceTarget::SurfaceHandle(_)
| SurfaceTarget::CoreWindow(_) => {}
SurfaceTarget::VisualFromWndHandle {
handle,
dcomp_state,
Expand Down Expand Up @@ -1445,7 +1469,8 @@ impl crate::Surface for Surface {
SurfaceTarget::Visual(_)
| SurfaceTarget::VisualFromWndHandle { .. }
| SurfaceTarget::SurfaceHandle(_)
| SurfaceTarget::SwapChainPanel(_) => {}
| SurfaceTarget::SwapChainPanel(_)
| SurfaceTarget::CoreWindow(_) => {}
}

unsafe { swap_chain.SetMaximumFrameLatency(config.maximum_frame_latency) }
Expand Down
110 changes: 84 additions & 26 deletions wgpu-hal/src/gles/egl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ type EglInstance = khronos_egl::Instance<khronos_egl::Static>;

type EglLabel = *const ffi::c_void;

#[cfg(unix)]
type WaylandWindow = *mut wayland_sys::egl::wl_egl_window;
#[cfg(not(unix))]
type WaylandWindow = *mut ffi::c_void;

#[allow(clippy::upper_case_acronyms)]
type EGLDEBUGPROCKHR = Option<
unsafe extern "system" fn(
Expand Down Expand Up @@ -78,6 +83,62 @@ unsafe extern "system" fn egl_debug_proc(
log::log!(log_severity, "EGL '{command}' code 0x{error:x}: {message}",);
}

#[cfg(unix)]
unsafe fn resize_wayland_window(window: WaylandWindow, width: i32, height: i32) {
wayland_sys::ffi_dispatch!(
wayland_sys::egl::wayland_egl_handle(),
wl_egl_window_resize,
window,
width,
height,
0,
0,
);
}

#[cfg(not(unix))]
unsafe fn resize_wayland_window(_window: WaylandWindow, _width: i32, _height: i32) {
unreachable!("Wayland EGL windows are only available on unix targets");
}

#[cfg(unix)]
unsafe fn create_wayland_window(
surface: *mut ffi::c_void,
width: i32,
height: i32,
) -> WaylandWindow {
wayland_sys::ffi_dispatch!(
wayland_sys::egl::wayland_egl_handle(),
wl_egl_window_create,
surface.cast(),
width,
height,
)
}

#[cfg(not(unix))]
unsafe fn create_wayland_window(
_surface: *mut ffi::c_void,
_width: i32,
_height: i32,
) -> WaylandWindow {
unreachable!("Wayland EGL windows are only available on unix targets");
}

#[cfg(unix)]
unsafe fn destroy_wayland_window(window: WaylandWindow) {
wayland_sys::ffi_dispatch!(
wayland_sys::egl::wayland_egl_handle(),
wl_egl_window_destroy,
window,
);
}

#[cfg(not(unix))]
unsafe fn destroy_wayland_window(_window: WaylandWindow) {
unreachable!("Wayland EGL windows are only available on unix targets");
}

#[derive(Clone, Copy, Debug)]
enum SrgbFrameBufferKind {
/// No support for SRGB surface
Expand Down Expand Up @@ -442,6 +503,10 @@ impl Inner {

let (config, supports_native_window) = choose_config(&egl, display, srgb_kind)?;

#[cfg(all(windows, target_vendor = "uwp"))]
let supports_opengl = false;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is OGL not supported on UWP? Then whats the point of all of these GLES changes when you could just disable the backend?


#[cfg(not(all(windows, target_vendor = "uwp")))]
let supports_opengl = if version >= (1, 4) {
let client_apis = egl
.query_string(Some(display), khronos_egl::CLIENT_APIS)
Expand Down Expand Up @@ -900,6 +965,7 @@ impl crate::Instance for Instance {
(Rwh::Xlib(_), _) => {}
(Rwh::Xcb(_), _) => {}
(Rwh::Win32(_), _) => {}
(Rwh::WinRt(_), _) => {}
(Rwh::AppKit(_), _) => {}
(Rwh::OhosNdk(_), _) => {}
#[cfg(target_os = "android")]
Expand Down Expand Up @@ -1052,7 +1118,7 @@ impl super::Device {
#[derive(Debug)]
pub struct Swapchain {
surface: khronos_egl::Surface,
wl_window: Option<*mut wayland_sys::egl::wl_egl_window>,
wl_window: Option<WaylandWindow>,
framebuffer: glow::Framebuffer,
renderbuffer: glow::Renderbuffer,
/// Extent because the window lies
Expand Down Expand Up @@ -1160,10 +1226,7 @@ impl Surface {
unsafe fn unconfigure_impl(
&self,
device: &super::Device,
) -> Option<(
khronos_egl::Surface,
Option<*mut wayland_sys::egl::wl_egl_window>,
)> {
) -> Option<(khronos_egl::Surface, Option<WaylandWindow>)> {
let gl = &device.shared.context.lock();
match self.swapchain.write().take() {
Some(sc) => {
Expand Down Expand Up @@ -1196,15 +1259,13 @@ impl crate::Surface for Surface {
let (surface, wl_window) = match unsafe { self.unconfigure_impl(device) } {
Some((sc, wl_window)) => {
if let Some(window) = wl_window {
wayland_sys::ffi_dispatch!(
wayland_sys::egl::wayland_egl_handle(),
wl_egl_window_resize,
window,
config.extent.width as i32,
config.extent.height as i32,
0,
0,
);
unsafe {
resize_wayland_window(
window,
config.extent.width as i32,
config.extent.height as i32,
)
};
}

(sc, wl_window)
Expand All @@ -1231,13 +1292,13 @@ impl crate::Surface for Surface {
(WindowKind::Unknown, Rwh::OhosNdk(handle)) => handle.native_window.as_ptr(),
#[cfg(unix)]
(WindowKind::Wayland, Rwh::Wayland(handle)) => {
let window = wayland_sys::ffi_dispatch!(
wayland_sys::egl::wayland_egl_handle(),
wl_egl_window_create,
handle.surface.as_ptr().cast(),
config.extent.width as i32,
config.extent.height as i32,
);
let window = unsafe {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you modifying wayland code?

create_wayland_window(
handle.surface.as_ptr().cast(),
config.extent.width as i32,
config.extent.height as i32,
)
};
wl_window = Some(window);
window.cast()
}
Expand All @@ -1246,6 +1307,7 @@ impl crate::Surface for Surface {
(WindowKind::Unknown, Rwh::Win32(handle)) => {
handle.hwnd.get() as *mut ffi::c_void
}
(WindowKind::Unknown, Rwh::WinRt(handle)) => handle.core_window.as_ptr(),
(WindowKind::Unknown, Rwh::AppKit(handle)) => {
#[cfg(not(target_os = "macos"))]
let window_ptr = handle.ns_view.as_ptr();
Expand Down Expand Up @@ -1397,11 +1459,7 @@ impl crate::Surface for Surface {
.destroy_surface(self.egl.display, surface)
.unwrap();
if let Some(window) = wl_window {
wayland_sys::ffi_dispatch!(
wayland_sys::egl::wayland_egl_handle(),
wl_egl_window_destroy,
window,
);
unsafe { destroy_wayland_window(window) };
}
}
}
Expand Down
12 changes: 6 additions & 6 deletions wgpu-hal/src/gles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,13 @@ we don't bother with that combination.
*/

///cbindgen:ignore
#[cfg(not(any(windows, webgl)))]
#[cfg(any(all(windows, target_vendor = "uwp"), not(any(windows, webgl))))]
mod egl;
#[cfg(Emscripten)]
mod emscripten;
#[cfg(webgl)]
mod web;
#[cfg(windows)]
#[cfg(all(windows, not(target_vendor = "uwp")))]
mod wgl;

mod adapter;
Expand All @@ -98,19 +98,19 @@ mod queue;

pub use fence::Fence;

#[cfg(not(any(windows, webgl)))]
#[cfg(any(all(windows, target_vendor = "uwp"), not(any(windows, webgl))))]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stuff like this probably belongs in the build.rs which declares some cfg aliases. It will get annoying to copy this everywhere.

pub use self::egl::{AdapterContext, AdapterContextLock};
#[cfg(not(any(windows, webgl)))]
#[cfg(any(all(windows, target_vendor = "uwp"), not(any(windows, webgl))))]
pub use self::egl::{Instance, Surface};

#[cfg(webgl)]
pub use self::web::AdapterContext;
#[cfg(webgl)]
pub use self::web::{Instance, Surface};

#[cfg(windows)]
#[cfg(all(windows, not(target_vendor = "uwp")))]
use self::wgl::AdapterContext;
#[cfg(windows)]
#[cfg(all(windows, not(target_vendor = "uwp")))]
pub use self::wgl::{Instance, Surface};

use alloc::{boxed::Box, string::String, string::ToString as _, sync::Arc, vec::Vec};
Expand Down
Loading