ash-window: Make enumerate_required_extensions return &[*const c_char] (#590)

* Constify generated extension names

* Constify hand-written extension names

* 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>.

Co-authored-by: Steve Wooster <s.f.m.wooster@gmail.com>
This commit is contained in:
Steve Wooster 2022-03-22 15:47:26 -07:00 committed by GitHub
parent fde6f92c70
commit 1cd810653c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
60 changed files with 576 additions and 533 deletions

View file

@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Update Vulkan-Headers to 1.3.208 (#597)
- Added `VK_EXT_headless_surface` instance extension (#589)
### Changed
- Constified extension names (#590)
## [0.36.0] - 2022-02-21
### Changed

View file

@ -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

View file

@ -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)?;

View file

@ -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<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",
@ -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),
};

View file

@ -26,7 +26,7 @@ impl BufferDeviceAddress {
self.fp.get_buffer_device_address_ext(self.handle, info)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::ExtBufferDeviceAddressFn::name()
}

View file

@ -51,7 +51,7 @@ impl CalibratedTimestamps {
.result_with_success((timestamps, max_deviation))
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::ExtCalibratedTimestampsFn::name()
}

View file

@ -54,7 +54,7 @@ impl DebugMarker {
.cmd_debug_marker_insert_ext(command_buffer, marker_info);
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::ExtDebugMarkerFn::name()
}

View file

@ -50,7 +50,7 @@ impl DebugReport {
.result_with_success(debug_cb)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::ExtDebugReportFn::name()
}

View file

@ -131,7 +131,7 @@ impl DebugUtils {
);
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::ExtDebugUtilsFn::name()
}

View file

@ -175,7 +175,7 @@ impl ExtendedDynamicState {
)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::ExtExtendedDynamicStateFn::name()
}

View file

@ -66,7 +66,7 @@ impl ExtendedDynamicState2 {
.cmd_set_primitive_restart_enable_ext(command_buffer, primitive_restart_enable.into())
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::ExtExtendedDynamicState2Fn::name()
}

View file

@ -70,7 +70,7 @@ impl FullScreenExclusive {
.result_with_success(present_modes)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::ExtFullScreenExclusiveFn::name()
}

View file

@ -38,7 +38,7 @@ impl HeadlessSurface {
.result_with_success(surface)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::ExtHeadlessSurfaceFn::name()
}

View file

@ -37,7 +37,7 @@ impl MetalSurface {
.result_with_success(surface)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::ExtMetalSurfaceFn::name()
}

View file

@ -18,7 +18,7 @@ impl PhysicalDeviceDrm {
props_drm
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::ExtPhysicalDeviceDrmFn::name()
}
}

View file

@ -86,7 +86,7 @@ impl PrivateData {
data
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::ExtPrivateDataFn::name()
}

View file

@ -28,7 +28,7 @@ impl ToolingInfo {
})
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::ExtToolingInfoFn::name()
}

View file

@ -299,7 +299,7 @@ impl AccelerationStructure {
size_info
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrAccelerationStructureFn::name()
}

View file

@ -37,7 +37,7 @@ impl AndroidSurface {
.result_with_success(surface)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrAndroidSurfaceFn::name()
}

View file

@ -44,7 +44,7 @@ impl BufferDeviceAddress {
.get_device_memory_opaque_capture_address_khr(self.handle, info)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrBufferDeviceAddressFn::name()
}

View file

@ -70,7 +70,7 @@ impl CopyCommands2 {
.cmd_resolve_image2_khr(command_buffer, resolve_image_info)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrCopyCommands2Fn::name()
}

View file

@ -72,7 +72,7 @@ impl CreateRenderPass2 {
.cmd_end_render_pass2_khr(command_buffer, subpass_end_info);
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrCreateRenderpass2Fn::name()
}

View file

@ -77,7 +77,7 @@ impl DeferredHostOperations {
.result()
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrDeferredHostOperationsFn::name()
}

View file

@ -125,7 +125,7 @@ impl Display {
.result_with_success(surface.assume_init())
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrDisplayFn::name()
}

View file

@ -38,7 +38,7 @@ impl DisplaySwapchain {
err_code.result_with_success(swapchains)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrDisplaySwapchainFn::name()
}

View file

@ -60,7 +60,7 @@ impl DrawIndirectCount {
);
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrDrawIndirectCountFn::name()
}

View file

@ -31,7 +31,7 @@ impl DynamicRendering {
self.fp.cmd_end_rendering_khr(command_buffer)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrDynamicRenderingFn::name()
}

View file

@ -34,7 +34,7 @@ impl ExternalFenceFd {
.result_with_success(fd)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrExternalFenceFdFn::name()
}

View file

@ -42,7 +42,7 @@ impl ExternalFenceWin32 {
.result_with_success(handle)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrExternalFenceWin32Fn::name()
}

View file

@ -39,7 +39,7 @@ impl ExternalMemoryFd {
.result_with_success(memory_fd_properties)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrExternalMemoryFdFn::name()
}

View file

@ -49,7 +49,7 @@ impl ExternalMemoryWin32 {
.result_with_success(memory_win32_handle_properties)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrExternalMemoryWin32Fn::name()
}

View file

@ -37,7 +37,7 @@ impl ExternalSemaphoreFd {
.result_with_success(fd)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrExternalSemaphoreFdFn::name()
}

View file

@ -42,7 +42,7 @@ impl ExternalSemaphoreWin32 {
.result_with_success(handle)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrExternalSemaphoreWin32Fn::name()
}

View file

@ -73,7 +73,7 @@ impl GetMemoryRequirements2 {
assert_eq!(count as usize, out.len());
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrGetMemoryRequirements2Fn::name()
}

View file

@ -148,7 +148,7 @@ impl GetPhysicalDeviceProperties2 {
assert_eq!(count as usize, out.len());
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrGetPhysicalDeviceProperties2Fn::name()
}

View file

@ -70,7 +70,7 @@ impl GetSurfaceCapabilities2 {
err_code.result()
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrGetSurfaceCapabilities2Fn::name()
}

View file

@ -28,7 +28,7 @@ impl Maintenance1 {
.trim_command_pool_khr(self.handle, command_pool, flags);
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrMaintenance1Fn::name()
}

View file

@ -28,7 +28,7 @@ impl Maintenance3 {
.get_descriptor_set_layout_support_khr(self.handle, create_info, out);
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrMaintenance3Fn::name()
}

View file

@ -72,7 +72,7 @@ impl Maintenance4 {
assert_eq!(count as usize, out.len());
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrMaintenance4Fn::name()
}

View file

@ -61,7 +61,7 @@ impl PipelineExecutableProperties {
})
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrPipelineExecutablePropertiesFn::name()
}

View file

@ -31,7 +31,7 @@ impl PresentWait {
.result()
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrPresentWaitFn::name()
}

View file

@ -54,7 +54,7 @@ impl PushDescriptor {
);
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrPushDescriptorFn::name()
}

View file

@ -166,7 +166,7 @@ impl RayTracingPipeline {
.cmd_set_ray_tracing_pipeline_stack_size_khr(command_buffer, pipeline_stack_size);
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrRayTracingPipelineFn::name()
}

View file

@ -92,7 +92,7 @@ impl Surface {
.destroy_surface_khr(self.handle, surface, allocation_callbacks.as_raw_ptr());
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrSurfaceFn::name()
}

View file

@ -98,7 +98,7 @@ impl Swapchain {
})
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrSwapchainFn::name()
}

View file

@ -89,7 +89,7 @@ impl Synchronization2 {
.result()
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrSynchronization2Fn::name()
}

View file

@ -45,7 +45,7 @@ impl TimelineSemaphore {
.result()
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrTimelineSemaphoreFn::name()
}

View file

@ -55,7 +55,7 @@ impl WaylandSurface {
b > 0
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrWaylandSurfaceFn::name()
}

View file

@ -51,7 +51,7 @@ impl Win32Surface {
b > 0
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrWin32SurfaceFn::name()
}

View file

@ -55,7 +55,7 @@ impl XcbSurface {
b > 0
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrXcbSurfaceFn::name()
}

View file

@ -55,7 +55,7 @@ impl XlibSurface {
b > 0
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::KhrXlibSurfaceFn::name()
}

View file

@ -37,7 +37,7 @@ impl IOSSurface {
.result_with_success(surface)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::MvkIosSurfaceFn::name()
}

View file

@ -37,7 +37,7 @@ impl MacOSSurface {
.result_with_success(surface)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::MvkMacosSurfaceFn::name()
}

View file

@ -37,7 +37,7 @@ impl ViSurface {
.result_with_success(surface)
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::NnViSurfaceFn::name()
}

View file

@ -45,7 +45,7 @@ impl DeviceDiagnosticCheckpoints {
checkpoint_data
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::NvDeviceDiagnosticCheckpointsFn::name()
}

View file

@ -62,7 +62,7 @@ impl MeshShader {
);
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::NvMeshShaderFn::name()
}

View file

@ -249,7 +249,7 @@ impl RayTracing {
.result()
}
pub fn name() -> &'static CStr {
pub const fn name() -> &'static CStr {
vk::NvRayTracingFn::name()
}

File diff suppressed because it is too large Load diff

View file

@ -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)
@ -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)

View file

@ -1037,7 +1037,7 @@ pub fn generate_extension_commands<'a>(
let byte_name_ident = Literal::byte_string(format!("{}\0", extension_name).as_bytes());
let extension_cstr = quote! {
impl #ident {
pub fn name() -> &'static ::std::ffi::CStr {
pub const fn name() -> &'static ::std::ffi::CStr {
unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(#byte_name_ident) }
}
#spec_version