From 6c420836c356c1d9863e442c76908c9a2bb6fb7a Mon Sep 17 00:00:00 2001 From: Steve Wooster Date: Fri, 25 Feb 2022 15:49:00 -0800 Subject: [PATCH] Make ash-window list extensions as &[*const c_char] 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>. --- ash-window/Changelog.md | 2 ++ ash-window/examples/winit.rs | 6 +--- ash-window/src/lib.rs | 61 ++++++++++++++++++++++++++++++------ examples/src/lib.rs | 12 +++---- 4 files changed, 60 insertions(+), 21 deletions(-) diff --git a/ash-window/Changelog.md b/ash-window/Changelog.md index df604f1b8..9502fd8cd 100644 --- a/ash-window/Changelog.md +++ b/ash-window/Changelog.md @@ -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 diff --git a/ash-window/examples/winit.rs b/ash-window/examples/winit.rs index 16d460cfa..4987bbbe9 100644 --- a/ash-window/examples/winit.rs +++ b/ash-window/examples/winit.rs @@ -17,14 +17,10 @@ fn main() -> Result<(), Box> { 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::>(); 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)?; diff --git a/ash-window/src/lib.rs b/ash-window/src/lib.rs index da0f27ec0..cc6ad3127 100644 --- a/ash-window/src/lib.rs +++ b/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 @@ -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> { +) -> 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", @@ -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", @@ -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", @@ -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), }; diff --git a/examples/src/lib.rs b/examples/src/lib.rs index 714074766..25a577dfc 100644 --- a/examples/src/lib.rs +++ b/examples/src/lib.rs @@ -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::>(); - 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) @@ -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)