Skip to content

Commit

Permalink
Implements VulkanScreen::new (#1202)
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon authored Dec 25, 2024
1 parent 1467b79 commit 2dccc89
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 98 deletions.
59 changes: 58 additions & 1 deletion Cargo.lock

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

70 changes: 29 additions & 41 deletions gui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,56 +20,51 @@ i-slint-core = "=1.9.0"
libc = "0.2.164"
num_enum = "0.7.3"
obconf = { path = "../src/obconf", features = ["serde", "virt"] }
obfw = { git = "https://github.com/obhq/firmware-dumper.git", rev = "64787fdc0489724f0914356d925be014a2f1bf3e", features = [
"read",
] }
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"] }
thiserror = "2.0.3"
uuid = { version = "1.11.0", features = ["serde", "v4"] }
winit = "0.30.5"

[dependencies.obfw]
git = "https://github.com/obhq/firmware-dumper.git"
rev = "64787fdc0489724f0914356d925be014a2f1bf3e"
features = ["read"]

[dependencies.slint]
version = "=1.9.0"
features = [
slint = { version = "=1.9.0", features = [
"backend-winit",
"compat-1-2",
"raw-window-handle-06",
"renderer-skia",
"std",
]
default-features = false
], default-features = false }
thiserror = "2.0.3"
uuid = { version = "1.11.0", features = ["serde", "v4"] }
winit = { version = "0.30.5", features = ["rwh_05"] }

[target.'cfg(target_arch = "aarch64")'.dependencies]
aarch64 = { path = "../arch/aarch64" }

[target.'cfg(target_arch = "x86_64")'.dependencies]
x86-64 = { path = "../arch/x86-64" }

[target.'cfg(target_os = "linux")'.dependencies.i-slint-renderer-skia]
version = "=1.9.0"
features = ["vulkan", "wayland", "x11"]

[target.'cfg(target_os = "windows")'.dependencies.i-slint-renderer-skia]
version = "=1.9.0"
features = ["vulkan"]

[target.'cfg(target_os = "macos")'.dependencies.i-slint-renderer-skia]
version = "=1.9.0"

[target.'cfg(not(target_os = "macos"))'.dependencies.ash]
version = "0.37.3"
features = ["linked"]
default-features = false
[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",
], default-features = false }
i-slint-renderer-skia = { version = "=1.9.0", features = [
"vulkan",
"wayland",
"x11",
] }
xdg = "2.5.2"

[target.'cfg(windows)'.dependencies.windows-sys]
version = "0.59.0"
features = [
[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",
"Win32_Foundation",
"Win32_Security",
Expand All @@ -78,21 +73,14 @@ features = [
"Win32_System_Memory",
"Win32_System_Registry",
"Win32_System_SystemInformation",
]

[target.'cfg(target_os = "linux")'.dependencies.ashpd]
version = "0.9.2"
features = ["async-std", "raw_handle"]
default-features = false

[target.'cfg(target_os = "linux")'.dependencies]
xdg = "2.5.2"
] }

[target.'cfg(target_os = "macos")'.dependencies]
applevisor-sys = "0.1.3"
core-foundation = "0.10.0"
core-foundation-sys = "0.8.7"
core-graphics-types = "0.1.3"
i-slint-renderer-skia = { version = "=1.9.0" }
metal = "0.29.0"
objc = "0.2.7"

Expand Down
2 changes: 1 addition & 1 deletion gui/src/graphics/metal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl Graphics for Metal {
}

fn create_screen(
&mut self,
self,
profile: &Profile,
attrs: WindowAttributes,
) -> Result<Rc<Self::Screen>, GraphicsError> {
Expand Down
2 changes: 1 addition & 1 deletion gui/src/graphics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub trait Graphics: Sized + 'static {

fn physical_devices(&self) -> &[Self::PhysicalDevice];
fn create_screen(
&mut self,
self,
profile: &Profile,
attrs: WindowAttributes,
) -> Result<Rc<Self::Screen>, GraphicsError>;
Expand Down
53 changes: 40 additions & 13 deletions gui/src/graphics/vulkan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,24 @@
use self::screen::VulkanScreen;
use super::Graphics;
use crate::profile::Profile;
use crate::rt::{create_window, RuntimeError};
use crate::rt::{create_window, raw_display_handle, RuntimeError};
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 std::ffi::CStr;
use std::mem::ManuallyDrop;
use std::rc::Rc;
use thiserror::Error;
use winit::window::WindowAttributes;

mod screen;

pub fn new() -> Result<impl Graphics, GraphicsError> {
// Get required extensions for window.
let exts = enumerate_required_extensions(raw_display_handle())
.map_err(GraphicsError::GetExtensionsForWindow)?;

// Setup application info.
let mut app = ApplicationInfo::default();

Expand All @@ -25,18 +33,19 @@ pub fn new() -> Result<impl Graphics, GraphicsError> {
];

// Setup VkInstanceCreateInfo.
let mut info = InstanceCreateInfo::default();

info.p_application_info = &app;
info.pp_enabled_layer_names = layers.as_ptr();
info.enabled_layer_count = layers.len().try_into().unwrap();
let info = InstanceCreateInfo::builder()
.application_info(&app)
.enabled_layer_names(&layers)
.enabled_extension_names(exts);

// Create Vulkan instance.
let api = ash::Entry::linked();
let mut vk = match unsafe { api.create_instance(&info, None) } {
let entry = Entry::linked();
let mut vk = match unsafe { entry.create_instance(&info, None) } {
Ok(instance) => Vulkan {
devices: ManuallyDrop::new(Vec::new()),
surface: ManuallyDrop::new(Surface::new(&entry, &instance)),
instance,
devices: Vec::new(),
entry,
},
Err(e) => return Err(GraphicsError::CreateInstance(e)),
};
Expand Down Expand Up @@ -84,9 +93,13 @@ pub fn new() -> Result<impl Graphics, GraphicsError> {
}

/// Implementation of [`Graphics`] using Vulkan.
///
/// Fields in this struct need to drop in a correct order.
struct Vulkan {
instance: ash::Instance,
devices: Vec<PhysicalDevice>,
devices: ManuallyDrop<Vec<PhysicalDevice>>,
surface: ManuallyDrop<Surface>,
instance: Instance,
entry: Entry,
}

impl Graphics for Vulkan {
Expand All @@ -98,17 +111,19 @@ impl Graphics for Vulkan {
}

fn create_screen(
&mut self,
self,
profile: &Profile,
attrs: WindowAttributes,
) -> Result<Rc<Self::Screen>, GraphicsError> {
create_window(attrs, move |w| VulkanScreen::new(profile, w))
create_window(attrs, move |w| VulkanScreen::new(self, profile, w))
.map_err(GraphicsError::CreateWindow)
}
}

impl Drop for Vulkan {
fn drop(&mut self) {
unsafe { ManuallyDrop::drop(&mut self.devices) };
unsafe { ManuallyDrop::drop(&mut self.surface) };
unsafe { self.instance.destroy_instance(None) };
}
}
Expand All @@ -127,6 +142,9 @@ 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 All @@ -139,6 +157,15 @@ pub enum GraphicsError {
#[error("no Vulkan device supports graphics operations with Vulkan 1.3")]
NoSuitableDevice,

#[error("couldn't find suitable queue")]
NoQueue,

#[error("couldn't create a logical device")]
CreateDevice(#[source] ash::vk::Result),

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

#[error("couldn't create window")]
CreateWindow(#[source] RuntimeError),
}
Loading

0 comments on commit 2dccc89

Please sign in to comment.