Skip to content

Commit

Permalink
Creates VkSurfaceKHR manually (#1249)
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon authored Jan 15, 2025
1 parent bbff8bf commit 3d6ba52
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 85 deletions.
59 changes: 1 addition & 58 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions gui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ obfw = { git = "https://github.com/obhq/firmware-dumper.git", rev = "64787fdc048
] }
open = { version = "5.3.1" }
raw-window-handle = "0.6.2"
rwh05 = { package = "raw-window-handle", version = "0.5.2" }
redb = "2.2.0"
rustc-hash = "2.1.0"
serde = { version = "1.0.209", features = ["derive"] }
Expand All @@ -41,7 +40,7 @@ slint = { version = "=1.9.0", features = [
], default-features = false }
thiserror = "2.0.3"
uuid = { version = "1.11.0", features = ["serde", "v4"] }
winit = { version = "0.30.5", features = ["rwh_05"] }
winit = { version = "0.30.5", features = ["rwh_06"] }

[target.'cfg(target_arch = "aarch64")'.dependencies]
aarch64 = { path = "../arch/aarch64" }
Expand All @@ -51,7 +50,6 @@ x86-64 = { path = "../arch/x86-64" }

[target.'cfg(target_os = "linux")'.dependencies]
ash = { version = "0.37.3", features = ["linked"], default-features = false }
ash-window = "=0.12.0"
ashpd = { version = "0.9.2", features = [
"async-std",
"raw_handle",
Expand All @@ -68,7 +66,6 @@ xdg = "2.5.2"

[target.'cfg(target_os = "windows")'.dependencies]
ash = { version = "0.37.3", features = ["linked"], default-features = false }
ash-window = "=0.12.0"
i-slint-renderer-skia = { version = "=1.9.0", features = ["vulkan"] }
windows-sys = { version = "0.59.0", features = [
"Win32",
Expand Down
6 changes: 3 additions & 3 deletions gui/src/graphics/metal/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::rt::{Hook, WindowHandler};
use metal::{CAMetalLayer, MetalLayer};
use objc::runtime::{Object, NO, YES};
use objc::{msg_send, sel, sel_impl};
use rwh05::{HasRawWindowHandle, RawWindowHandle};
use raw_window_handle::{HasWindowHandle, RawWindowHandle};
use std::error::Error;
use std::ptr::null_mut;
use std::rc::Rc;
Expand All @@ -27,8 +27,8 @@ impl MetalWindow {
window: Window,
) -> Result<Rc<Self>, Box<dyn Error + Send + Sync>> {
let layer = unsafe { engine.create_layer() };
let view = match window.raw_window_handle() {
RawWindowHandle::AppKit(v) => v.ns_view as *mut Object,
let view = match window.window_handle().unwrap().as_raw() {
RawWindowHandle::AppKit(v) => v.ns_view.as_ptr() as *mut Object,
_ => unreachable!(),
};

Expand Down
62 changes: 56 additions & 6 deletions gui/src/graphics/vulkan/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
use super::{GraphicsError, VulkanBuilder};
use crate::graphics::Graphics;
use crate::profile::Profile;
use ash::vk::{DeviceCreateInfo, DeviceQueueCreateInfo, QueueFlags, SurfaceKHR};
use ash::extensions::khr::{WaylandSurface, Win32Surface, XcbSurface, XlibSurface};
use ash::vk::{
DeviceCreateInfo, DeviceQueueCreateInfo, QueueFlags, SurfaceKHR, WaylandSurfaceCreateInfoKHR,
Win32SurfaceCreateInfoKHR, XcbSurfaceCreateInfoKHR, XlibSurfaceCreateInfoKHR,
};
use ash::Device;
use ash_window::create_surface;
use rwh05::{HasRawDisplayHandle, HasRawWindowHandle};
use raw_window_handle::{HasDisplayHandle, HasWindowHandle, RawDisplayHandle, RawWindowHandle};
use winit::window::Window;

/// Implementation of [`Graphics`] using Vulkan.
Expand Down Expand Up @@ -51,10 +54,57 @@ impl Vulkan {
/// # Safety
/// The returned [`SurfaceKHR`] must be destroyed before `win` and this [`Vulkan`].
pub unsafe fn create_surface(&self, win: &Window) -> Result<SurfaceKHR, ash::vk::Result> {
let dh = win.raw_display_handle();
let wh = win.raw_window_handle();
let e = &self.builder.entry;
let i = &self.builder.instance;
let w = win.window_handle().unwrap();

create_surface(&self.builder.entry, &self.builder.instance, dh, wh, None)
match w.as_ref() {
RawWindowHandle::UiKit(_)
| RawWindowHandle::AppKit(_)
| RawWindowHandle::Web(_)
| RawWindowHandle::WebCanvas(_)
| RawWindowHandle::WebOffscreenCanvas(_) => {
unreachable!()
}
RawWindowHandle::Xlib(v) => {
let c = XlibSurfaceCreateInfoKHR::builder()
.dpy(match win.display_handle().unwrap().as_ref() {
RawDisplayHandle::Xlib(v) => v.display.unwrap().as_ptr().cast(),
_ => unreachable!(),
})
.window(v.window);

XlibSurface::new(e, i).create_xlib_surface(&c, None)
}
RawWindowHandle::Xcb(v) => {
let c = XcbSurfaceCreateInfoKHR::builder()
.connection(match win.display_handle().unwrap().as_ref() {
RawDisplayHandle::Xcb(v) => v.connection.unwrap().as_ptr(),
_ => unreachable!(),
})
.window(v.window.get());

XcbSurface::new(e, i).create_xcb_surface(&c, None)
}
RawWindowHandle::Wayland(v) => {
let c = WaylandSurfaceCreateInfoKHR::builder()
.display(match win.display_handle().unwrap().as_ref() {
RawDisplayHandle::Wayland(v) => v.display.as_ptr(),
_ => unreachable!(),
})
.surface(v.surface.as_ptr());

WaylandSurface::new(e, i).create_wayland_surface(&c, None)
}
RawWindowHandle::Win32(v) => {
let c = Win32SurfaceCreateInfoKHR::builder()
.hinstance(v.hinstance.unwrap().get() as _)
.hwnd(v.hwnd.get() as _);

Win32Surface::new(e, i).create_win32_surface(&c, None)
}
_ => todo!(),
}
}

/// # Safety
Expand Down
21 changes: 14 additions & 7 deletions gui/src/graphics/vulkan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::rt::{create_window, raw_display_handle};
use ash::extensions::khr::Surface;
use ash::vk::{ApplicationInfo, InstanceCreateInfo, QueueFlags, API_VERSION_1_3};
use ash::{Entry, Instance};
use ash_window::enumerate_required_extensions;
use raw_window_handle::RawDisplayHandle;
use std::ffi::CStr;
use std::mem::ManuallyDrop;
use std::rc::Rc;
Expand All @@ -21,8 +21,18 @@ mod window;

pub fn builder() -> Result<impl EngineBuilder, GraphicsError> {
// Get required extensions for window.
let exts = enumerate_required_extensions(raw_display_handle())
.map_err(GraphicsError::GetExtensionsForWindow)?;
let mut exts = vec![c"VK_KHR_surface".as_ptr()];

match raw_display_handle() {
RawDisplayHandle::UiKit(_) | RawDisplayHandle::AppKit(_) | RawDisplayHandle::Web(_) => {
unreachable!()
}
RawDisplayHandle::Xlib(_) => exts.push(c"VK_KHR_xlib_surface".as_ptr()),
RawDisplayHandle::Xcb(_) => exts.push(c"VK_KHR_xcb_surface".as_ptr()),
RawDisplayHandle::Wayland(_) => exts.push(c"VK_KHR_wayland_surface".as_ptr()),
RawDisplayHandle::Windows(_) => exts.push(c"VK_KHR_win32_surface".as_ptr()),
_ => todo!(),
}

// Setup application info.
let mut app = ApplicationInfo::default();
Expand All @@ -40,7 +50,7 @@ pub fn builder() -> Result<impl EngineBuilder, GraphicsError> {
let info = InstanceCreateInfo::builder()
.application_info(&app)
.enabled_layer_names(&layers)
.enabled_extension_names(exts);
.enabled_extension_names(&exts);

// Create Vulkan instance.
let entry = Entry::linked();
Expand Down Expand Up @@ -153,9 +163,6 @@ impl super::PhysicalDevice for PhysicalDevice {
/// Represents an error when operation on Vulkan fails.
#[derive(Debug, Error)]
pub enum GraphicsError {
#[error("couldn't get required Vulkan extensions for window")]
GetExtensionsForWindow(#[source] ash::vk::Result),

#[error("couldn't create Vulkan instance")]
CreateInstance(#[source] ash::vk::Result),

Expand Down
4 changes: 2 additions & 2 deletions gui/src/rt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ pub use self::window::*;

use self::context::Context;
use self::task::TaskList;
use raw_window_handle::{HasDisplayHandle, RawDisplayHandle};
use rustc_hash::FxHashMap;
use rwh05::{HasRawDisplayHandle, RawDisplayHandle};
use std::any::{Any, TypeId};
use std::cell::Cell;
use std::collections::HashMap;
Expand Down Expand Up @@ -141,7 +141,7 @@ pub fn yield_now() -> impl Future<Output = ()> {
/// # Panics
/// If called from the other thread than main thread.
pub fn raw_display_handle() -> RawDisplayHandle {
Context::with(|cx| cx.el.raw_display_handle())
Context::with(|cx| cx.el.display_handle().unwrap().as_raw())
}

/// You need to call [`register_window()`] after this to receive events for the created window and
Expand Down
5 changes: 2 additions & 3 deletions gui/src/ui/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ pub(super) use self::window::Window;
use crate::rt::{create_window, raw_display_handle, WindowHandler};
use i_slint_core::graphics::RequestedGraphicsAPI;
use i_slint_renderer_skia::SkiaRenderer;
#[cfg(target_os = "linux")]
use raw_window_handle::RawDisplayHandle;
use rustc_hash::FxHashMap;
use slint::platform::{
duration_until_next_timer_update, update_timers_and_animations, SetPlatformError, WindowAdapter,
Expand Down Expand Up @@ -40,9 +42,6 @@ impl SlintBackend {
/// # Safety
/// The returned [`SlintBackend`] must not outlive the event loop.
pub unsafe fn new() -> Result<Self, BackendError> {
#[cfg(target_os = "linux")]
use rwh05::RawDisplayHandle;

let mut b = Self {
#[cfg(target_os = "linux")]
wayland: None,
Expand Down
5 changes: 3 additions & 2 deletions gui/src/ui/backend/wayland.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::BackendError;
use raw_window_handle::WaylandDisplayHandle;
use std::cell::RefCell;
use std::future::Future;
use std::hint::unreachable_unchecked;
Expand All @@ -25,9 +26,9 @@ pub struct Wayland {
impl Wayland {
/// # Safety
/// `display` must outlive the returned [`Wayland`].
pub unsafe fn new(display: rwh05::WaylandDisplayHandle) -> Result<Self, BackendError> {
pub unsafe fn new(display: WaylandDisplayHandle) -> Result<Self, BackendError> {
// Get wayland connection.
let backend = Backend::from_foreign_display(display.display.cast());
let backend = Backend::from_foreign_display(display.display.as_ptr().cast());
let conn = Connection::from_backend(backend);

// Get global objects.
Expand Down

0 comments on commit 3d6ba52

Please sign in to comment.