Skip to content

Commit

Permalink
Make ash-window list extensions as &[*const c_char]
Browse files Browse the repository at this point in the history
This alters enumerate_required_extensions() to return the same type that
is expected by vk::InstanceCreateInfoBuilder::enabled_extension_names(),
allowing simple Vulkan apps to omit the boilerplate of mapping to an
intermediate Vec<*const c_char>.
  • Loading branch information
swooster committed Feb 27, 2022
1 parent 67723a9 commit 6c42083
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 21 deletions.
2 changes: 2 additions & 0 deletions ash-window/Changelog.md
Expand Up @@ -2,6 +2,8 @@

## [Unreleased] - ReleaseDate

- Make `enumerate_required_extensions()` return `&[*const c_char]` instead of `Vec<&CStr>` to match `ash::vk::InstanceCreateInfo` (#590)

## [0.9.1] - 2022-02-21

### Changed
Expand Down
6 changes: 1 addition & 5 deletions ash-window/examples/winit.rs
Expand Up @@ -17,14 +17,10 @@ fn main() -> Result<(), Box<dyn Error>> {
unsafe {
let entry = ash::Entry::linked();
let surface_extensions = ash_window::enumerate_required_extensions(&window)?;
let instance_extensions = surface_extensions
.iter()
.map(|ext| ext.as_ptr())
.collect::<Vec<_>>();
let app_desc = vk::ApplicationInfo::builder().api_version(vk::make_api_version(0, 1, 0, 0));
let instance_desc = vk::InstanceCreateInfo::builder()
.application_info(&app_desc)
.enabled_extension_names(&instance_extensions);
.enabled_extension_names(surface_extensions);

let instance = entry.create_instance(&instance_desc, None)?;

Expand Down
61 changes: 52 additions & 9 deletions ash-window/src/lib.rs
@@ -1,8 +1,9 @@
#![warn(trivial_casts, trivial_numeric_casts)]

use std::os::raw::c_char;

use ash::{extensions::khr, prelude::*, vk, Entry, Instance};
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
use std::ffi::CStr;

#[cfg(any(target_os = "macos", target_os = "ios"))]
use ash::extensions::ext; // portability extensions
Expand Down Expand Up @@ -122,10 +123,16 @@ pub unsafe fn create_surface(
/// The returned extensions will include all extension dependencies.
pub fn enumerate_required_extensions(
window_handle: &dyn HasRawWindowHandle,
) -> VkResult<Vec<&'static CStr>> {
) -> VkResult<&'static [*const c_char]> {
let extensions = match window_handle.raw_window_handle() {
#[cfg(target_os = "windows")]
RawWindowHandle::Windows(_) => vec![khr::Surface::name(), khr::Win32Surface::name()],
RawWindowHandle::Windows(_) => {
const WINDOWS_EXTS: [*const c_char; 2] = [
khr::Surface::name().as_ptr(),
khr::Win32Surface::name().as_ptr(),
];
&WINDOWS_EXTS
}

#[cfg(any(
target_os = "linux",
Expand All @@ -134,7 +141,13 @@ pub fn enumerate_required_extensions(
target_os = "netbsd",
target_os = "openbsd"
))]
RawWindowHandle::Wayland(_) => vec![khr::Surface::name(), khr::WaylandSurface::name()],
RawWindowHandle::Wayland(_) => {
const WAYLAND_EXTS: [*const c_char; 2] = [
khr::Surface::name().as_ptr(),
khr::WaylandSurface::name().as_ptr(),
];
&WAYLAND_EXTS
}

#[cfg(any(
target_os = "linux",
Expand All @@ -143,7 +156,13 @@ pub fn enumerate_required_extensions(
target_os = "netbsd",
target_os = "openbsd"
))]
RawWindowHandle::Xlib(_) => vec![khr::Surface::name(), khr::XlibSurface::name()],
RawWindowHandle::Xlib(_) => {
const XLIB_EXTS: [*const c_char; 2] = [
khr::Surface::name().as_ptr(),
khr::XlibSurface::name().as_ptr(),
];
&XLIB_EXTS
}

#[cfg(any(
target_os = "linux",
Expand All @@ -152,16 +171,40 @@ pub fn enumerate_required_extensions(
target_os = "netbsd",
target_os = "openbsd"
))]
RawWindowHandle::Xcb(_) => vec![khr::Surface::name(), khr::XcbSurface::name()],
RawWindowHandle::Xcb(_) => {
const XCB_EXTS: [*const c_char; 2] = [
khr::Surface::name().as_ptr(),
khr::XcbSurface::name().as_ptr(),
];
&XCB_EXTS
}

#[cfg(any(target_os = "android"))]
RawWindowHandle::Android(_) => vec![khr::Surface::name(), khr::AndroidSurface::name()],
RawWindowHandle::Android(_) => {
const ANDROID_EXTS: [*const c_char; 2] = [
khr::Surface::name().as_ptr(),
khr::AndroidSurface::name().as_ptr(),
];
&ANDROID_EXTS
}

#[cfg(any(target_os = "macos"))]
RawWindowHandle::MacOS(_) => vec![khr::Surface::name(), ext::MetalSurface::name()],
RawWindowHandle::MacOS(_) => {
const MACOS_EXTS: [*const c_char; 2] = [
khr::Surface::name().as_ptr(),
ext::MetalSurface::name().as_ptr(),
];
&MACOS_EXTS
}

#[cfg(any(target_os = "ios"))]
RawWindowHandle::IOS(_) => vec![khr::Surface::name(), ext::MetalSurface::name()],
RawWindowHandle::IOS(_) => {
const IOS_EXTS: [*const c_char; 2] = [
khr::Surface::name().as_ptr(),
ext::MetalSurface::name().as_ptr(),
];
&IOS_EXTS
}

_ => return Err(vk::Result::ERROR_EXTENSION_NOT_PRESENT),
};
Expand Down
12 changes: 5 additions & 7 deletions examples/src/lib.rs
Expand Up @@ -228,12 +228,10 @@ impl ExampleBase {
.map(|raw_name| raw_name.as_ptr())
.collect();

let surface_extensions = ash_window::enumerate_required_extensions(&window).unwrap();
let mut extension_names_raw = surface_extensions
.iter()
.map(|ext| ext.as_ptr())
.collect::<Vec<_>>();
extension_names_raw.push(DebugUtils::name().as_ptr());
let mut extension_names = ash_window::enumerate_required_extensions(&window)
.unwrap()
.to_vec();
extension_names.push(DebugUtils::name().as_ptr());

let appinfo = vk::ApplicationInfo::builder()
.application_name(app_name)
Expand All @@ -245,7 +243,7 @@ impl ExampleBase {
let create_info = vk::InstanceCreateInfo::builder()
.application_info(&appinfo)
.enabled_layer_names(&layers_names_raw)
.enabled_extension_names(&extension_names_raw);
.enabled_extension_names(&extension_names);

let instance: Instance = entry
.create_instance(&create_info, None)
Expand Down

0 comments on commit 6c42083

Please sign in to comment.