From 7cf3b4f09eba7c5375eb367f1d930c3583ec78b7 Mon Sep 17 00:00:00 2001 From: Benjamin Saunders Date: Mon, 27 Dec 2021 02:49:40 -0800 Subject: [PATCH] Don't link Vulkan by default (#526) This was found to be unreasonably disruptive to downstream CI configurations. --- Changelog.md | 7 ++++ ash-window/Cargo.toml | 1 + ash-window/examples/winit.rs | 2 +- ash/Cargo.toml | 2 +- ash/src/entry.rs | 78 ++++++++++++++++++++---------------- ash/src/lib.rs | 4 +- examples/Cargo.toml | 5 ++- examples/src/lib.rs | 2 +- 8 files changed, 61 insertions(+), 40 deletions(-) diff --git a/Changelog.md b/Changelog.md index 28328b4..62ced5b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- `loaded` feature enabled by default in place of `linked` to relax default constraints on the build environment +- `Entry::new` renamed to `Entry::linked` + ## [0.34.0] - 2021-12-22 ### Added diff --git a/ash-window/Cargo.toml b/ash-window/Cargo.toml index b8b1aec..4dbb60f 100644 --- a/ash-window/Cargo.toml +++ b/ash-window/Cargo.toml @@ -22,6 +22,7 @@ raw-window-metal = "0.1" [dev-dependencies] winit = "0.19.4" +ash = { path = "../ash", version = "0.34", default-features = false, features = ["linked"] } [[example]] name = "winit" diff --git a/ash-window/examples/winit.rs b/ash-window/examples/winit.rs index 0921897..16d460c 100644 --- a/ash-window/examples/winit.rs +++ b/ash-window/examples/winit.rs @@ -15,7 +15,7 @@ fn main() -> Result<(), Box> { .build(&events_loop)?; unsafe { - let entry = ash::Entry::new(); + let entry = ash::Entry::linked(); let surface_extensions = ash_window::enumerate_required_extensions(&window)?; let instance_extensions = surface_extensions .iter() diff --git a/ash/Cargo.toml b/ash/Cargo.toml index 1896144..9cc9c4f 100644 --- a/ash/Cargo.toml +++ b/ash/Cargo.toml @@ -14,7 +14,7 @@ edition = "2018" libloading = { version = "0.7", optional = true } [features] -default = ["linked", "debug"] +default = ["loaded", "debug"] # Link the Vulkan loader at compile time. linked = [] # Support searching for the Vulkan loader manually at runtime. diff --git a/ash/src/entry.rs b/ash/src/entry.rs index a517620..b3a4a12 100644 --- a/ash/src/entry.rs +++ b/ash/src/entry.rs @@ -29,40 +29,12 @@ pub struct Entry { /// Vulkan core 1.0 #[allow(non_camel_case_types)] impl Entry { - /// Load entry points from a Vulkan loader linked at compile time - /// - /// Note that instance/device functions are still fetched via `vkGetInstanceProcAddr` and - /// `vkGetDeviceProcAddr` for maximum performance. - /// - /// ```no_run - /// use ash::{vk, Entry}; - /// # fn main() -> Result<(), Box> { - /// let entry = Entry::new(); - /// let app_info = vk::ApplicationInfo { - /// api_version: vk::make_api_version(0, 1, 0, 0), - /// ..Default::default() - /// }; - /// let create_info = vk::InstanceCreateInfo { - /// p_application_info: &app_info, - /// ..Default::default() - /// }; - /// let instance = unsafe { entry.create_instance(&create_info, None)? }; - /// # Ok(()) } - /// ``` - #[cfg(feature = "linked")] - #[cfg_attr(docsrs, doc(cfg(feature = "linked")))] - pub fn new() -> Self { - // Sound because we're linking to Vulkan, which provides a vkGetInstanceProcAddr that has - // defined behavior in this use. - unsafe { - Self::from_static_fn(vk::StaticFn { - get_instance_proc_addr: vkGetInstanceProcAddr, - }) - } - } - /// Load default Vulkan library for the current platform /// + /// Prefer this over [`linked`](Self::linked) when your application can gracefully handle + /// environments that lack Vulkan support, and when the build environment might not have Vulkan + /// development packages installed (e.g. the Vulkan SDK, or Ubuntu's `libvulkan-dev`). + /// /// # Safety /// `dlopen`ing native libraries is inherently unsafe. The safety guidelines /// for [`Library::new()`] and [`Library::get()`] apply here. @@ -103,6 +75,43 @@ impl Entry { Self::load_from(LIB_PATH) } + /// Load entry points from a Vulkan loader linked at compile time + /// + /// Compared to [`load`](Self::load), this is infallible, but requires that the build + /// environment have Vulkan development packages installed (e.g. the Vulkan SDK, or Ubuntu's + /// `libvulkan-dev`), and prevents the resulting binary from starting in environments that do not + /// support Vulkan. + /// + /// Note that instance/device functions are still fetched via `vkGetInstanceProcAddr` and + /// `vkGetDeviceProcAddr` for maximum performance. + /// + /// ```no_run + /// use ash::{vk, Entry}; + /// # fn main() -> Result<(), Box> { + /// let entry = Entry::linked(); + /// let app_info = vk::ApplicationInfo { + /// api_version: vk::make_api_version(0, 1, 0, 0), + /// ..Default::default() + /// }; + /// let create_info = vk::InstanceCreateInfo { + /// p_application_info: &app_info, + /// ..Default::default() + /// }; + /// let instance = unsafe { entry.create_instance(&create_info, None)? }; + /// # Ok(()) } + /// ``` + #[cfg(feature = "linked")] + #[cfg_attr(docsrs, doc(cfg(feature = "linked")))] + pub fn linked() -> Self { + // Sound because we're linking to Vulkan, which provides a vkGetInstanceProcAddr that has + // defined behavior in this use. + unsafe { + Self::from_static_fn(vk::StaticFn { + get_instance_proc_addr: vkGetInstanceProcAddr, + }) + } + } + /// Load Vulkan library at `path` /// /// # Safety @@ -162,7 +171,7 @@ impl Entry { /// ```no_run /// # use ash::{Entry, vk}; /// # fn main() -> Result<(), Box> { - /// let entry = Entry::new(); + /// let entry = Entry::linked(); /// match entry.try_enumerate_instance_version()? { /// // Vulkan 1.1+ /// Some(version) => { @@ -278,9 +287,10 @@ impl Entry { } #[cfg(feature = "linked")] +#[cfg_attr(docsrs, doc(cfg(feature = "linked")))] impl Default for Entry { fn default() -> Self { - Self::new() + Self::linked() } } diff --git a/ash/src/lib.rs b/ash/src/lib.rs index 97bf4cd..86f337d 100644 --- a/ash/src/lib.rs +++ b/ash/src/lib.rs @@ -14,7 +14,7 @@ //! ```no_run //! use ash::{vk, Entry}; //! # fn main() -> Result<(), Box> { -//! let entry = Entry::new(); +//! let entry = Entry::linked(); //! let app_info = vk::ApplicationInfo { //! api_version: vk::make_api_version(0, 1, 0, 0), //! ..Default::default() @@ -29,7 +29,7 @@ //! //! ## Getting started //! -//! Load the Vulkan library linked at compile time using [`Entry::new()`], or load it at runtime +//! Load the Vulkan library linked at compile time using [`Entry::linked()`], or load it at runtime //! using [`Entry::load()`], which uses `libloading`. If you want to perform entry point loading //! yourself, call [`Entry::from_static_fn()`]. diff --git a/examples/Cargo.toml b/examples/Cargo.toml index a8d090a..0e31ba0 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -7,5 +7,8 @@ edition = "2018" [dependencies] winit = "0.25.0" image = "0.10.4" -ash = { path = "../ash" } +# The examples require the validation layers, which means the SDK or +# equivalent development packages should be present, so we can link +# directly and benefit from the infallible `Entry` constructor. +ash = { path = "../ash", default-features = false, features = ["linked", "debug"] } ash-window = { path = "../ash-window" } diff --git a/examples/src/lib.rs b/examples/src/lib.rs index b3e19bf..1142e1e 100644 --- a/examples/src/lib.rs +++ b/examples/src/lib.rs @@ -217,7 +217,7 @@ impl ExampleBase { )) .build(&event_loop) .unwrap(); - let entry = Entry::new(); + let entry = Entry::linked(); let app_name = CString::new("VulkanTriangle").unwrap(); let layer_names = [CStr::from_bytes_with_nul_unchecked(