Skip to content

Commit

Permalink
Initial Vulkan backend code
Browse files Browse the repository at this point in the history
  • Loading branch information
i509VCB committed Jun 26, 2022
1 parent 057f261 commit fad6f20
Show file tree
Hide file tree
Showing 7 changed files with 1,191 additions and 1 deletion.
10 changes: 9 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ members = [

[dependencies]
appendlist = "1.4"
# Intentionally pick one commit back from the "release 0.37.1" branch since the release commit is likely to be rebased
ash = { git = "https://github.com/ash-rs/ash", rev = "28a4868dc302013e00569dc5393f8a0b43ed4a70", optional = true }
bitflags = "1"
calloop = "0.10.0"
cgmath = "0.18.0"
Expand All @@ -42,6 +44,7 @@ libloading = { version="0.7.0", optional = true }
nix = "0.22"
once_cell = "1.8.0"
rand = "0.8.4"
scopeguard = { version = "1.1.0", optional = true }
slog = "2"
slog-stdlog = { version = "4", optional = true }
tempfile = { version = "3.0", optional = true }
Expand Down Expand Up @@ -69,7 +72,7 @@ gl_generator = { version = "0.14", optional = true }
pkg-config = { version = "0.3.17", optional = true }

[features]
default = ["backend_drm", "backend_gbm", "backend_libinput", "backend_udev", "backend_session_logind", "backend_x11", "backend_winit", "desktop", "renderer_gl", "renderer_multi", "xwayland", "wayland_frontend", "slog-stdlog"]
default = ["backend_drm", "backend_gbm", "backend_libinput", "backend_udev", "backend_session_logind", "backend_x11", "backend_winit", "desktop", "renderer_gl", "renderer_multi", "xwayland", "wayland_frontend", "slog-stdlog", "backend_vulkan"]
backend_winit = ["winit", "backend_egl", "wayland-egl", "renderer_gl"]
backend_x11 = ["x11rb", "x11rb/dri3", "x11rb/xfixes", "x11rb/present", "x11rb_event_source", "backend_gbm", "backend_drm", "backend_egl"]
backend_drm = ["drm", "drm-ffi"]
Expand All @@ -78,6 +81,7 @@ backend_egl = ["gl_generator", "libloading"]
backend_libinput = ["input"]
backend_session = []
backend_udev = ["udev", "input/udev"]
backend_vulkan = ["ash", "scopeguard"]
backend_session_logind = ["dbus", "backend_session", "pkg-config"]
backend_session_elogind = ["backend_session_logind"]
backend_session_libseat = ["backend_session", "libseat"]
Expand Down Expand Up @@ -105,3 +109,7 @@ required-features = ["wayland_frontend"]
[[example]]
name = "compositor"
required-features = ["wayland_frontend"]

[[example]]
name = "vulkan"
required-features = ["backend_vulkan"]
27 changes: 27 additions & 0 deletions examples/vulkan.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use std::sync::Mutex;

use slog::{o, Drain};
use smithay::backend::vulkan::{Instance, PhysicalDevice};

fn main() {
let logger = slog::Logger::root(Mutex::new(slog_term::term_full().fuse()).fuse(), o!());

println!("Version: {}", Instance::max_instance_version().unwrap());
println!(
"Available instance extensions: {:?}",
Instance::enumerate_extensions().unwrap().collect::<Vec<_>>()
);
println!();

let instance = Instance::new(Version::VERSION_1_3, None, logger).unwrap();

for (idx, phy) in PhysicalDevice::enumerate(&instance).unwrap().enumerate() {
println!(
"Device #{}: {} v{}, {:?}",
idx,
phy.name(),
phy.api_version(),
phy.driver()
);
}
}
3 changes: 3 additions & 0 deletions src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ pub mod session;
#[cfg(feature = "backend_udev")]
pub mod udev;

#[cfg(feature = "backend_vulkan")]
pub mod vulkan;

#[cfg(feature = "backend_winit")]
pub mod winit;

Expand Down
74 changes: 74 additions & 0 deletions src/backend/vulkan/inner.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use std::{
ffi::{CStr, CString},
fmt,
};

use ash::{extensions::ext::DebugUtils, vk};
use slog::Logger;

use super::{version::Version, LoadError, LIBRARY};

pub struct InstanceInner {
pub instance: ash::Instance,
pub version: Version,
pub debug_state: Option<DebugState>,

/// Enabled instance extensions.
pub enabled_extensions: Vec<&'static CStr>,
}

pub struct DebugState {
pub debug_utils: DebugUtils,
pub debug_messenger: vk::DebugUtilsMessengerEXT,
pub logger_ptr: *mut Logger,
}

impl fmt::Debug for InstanceInner {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("InstanceInner")
.field("instance", &self.instance.handle())
.finish_non_exhaustive()
}
}

impl Drop for InstanceInner {
fn drop(&mut self) {
let logger = if let Some(debug) = &self.debug_state {
unsafe {
debug
.debug_utils
.destroy_debug_utils_messenger(debug.debug_messenger, None);
}

Some(unsafe { Box::from_raw(debug.logger_ptr as *mut slog::Logger) })
} else {
None
};

// Users of `Instance` are responsible for compliance with `VUID-vkDestroyInstance-instance-00629`.

// SAFETY (Host Synchronization): InstanceInner is always stored in an Arc, therefore destruction is
// synchronized (since the inner value of an Arc is always dropped on a single thread).
unsafe { self.instance.destroy_instance(None) };

// Now that the instance has been destroyed, we can destroy the logger.
drop(logger);
}
}

impl super::Instance {
pub(super) fn enumerate_layers() -> Result<impl Iterator<Item = CString>, LoadError> {
let library = LIBRARY.as_ref().or(Err(LoadError))?;

let layers = library
.enumerate_instance_layer_properties()
.or(Err(LoadError))?
.into_iter()
.map(|properties| {
// SAFETY: Vulkan guarantees the string is null terminated.
unsafe { CStr::from_ptr(&properties.layer_name as *const _) }.to_owned()
});

Ok(layers)
}
}
Loading

0 comments on commit fad6f20

Please sign in to comment.