Don't link Vulkan by default (#526)

This was found to be unreasonably disruptive to downstream CI
configurations.
This commit is contained in:
Benjamin Saunders 2021-12-27 02:49:40 -08:00 committed by GitHub
parent 61d37734f8
commit 7cf3b4f09e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 61 additions and 40 deletions

View file

@ -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/), 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). 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 ## [0.34.0] - 2021-12-22
### Added ### Added

View file

@ -22,6 +22,7 @@ raw-window-metal = "0.1"
[dev-dependencies] [dev-dependencies]
winit = "0.19.4" winit = "0.19.4"
ash = { path = "../ash", version = "0.34", default-features = false, features = ["linked"] }
[[example]] [[example]]
name = "winit" name = "winit"

View file

@ -15,7 +15,7 @@ fn main() -> Result<(), Box<dyn Error>> {
.build(&events_loop)?; .build(&events_loop)?;
unsafe { unsafe {
let entry = ash::Entry::new(); let entry = ash::Entry::linked();
let surface_extensions = ash_window::enumerate_required_extensions(&window)?; let surface_extensions = ash_window::enumerate_required_extensions(&window)?;
let instance_extensions = surface_extensions let instance_extensions = surface_extensions
.iter() .iter()

View file

@ -14,7 +14,7 @@ edition = "2018"
libloading = { version = "0.7", optional = true } libloading = { version = "0.7", optional = true }
[features] [features]
default = ["linked", "debug"] default = ["loaded", "debug"]
# Link the Vulkan loader at compile time. # Link the Vulkan loader at compile time.
linked = [] linked = []
# Support searching for the Vulkan loader manually at runtime. # Support searching for the Vulkan loader manually at runtime.

View file

@ -29,40 +29,12 @@ pub struct Entry {
/// Vulkan core 1.0 /// Vulkan core 1.0
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
impl Entry { 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<dyn std::error::Error>> {
/// 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 /// 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 /// # Safety
/// `dlopen`ing native libraries is inherently unsafe. The safety guidelines /// `dlopen`ing native libraries is inherently unsafe. The safety guidelines
/// for [`Library::new()`] and [`Library::get()`] apply here. /// for [`Library::new()`] and [`Library::get()`] apply here.
@ -103,6 +75,43 @@ impl Entry {
Self::load_from(LIB_PATH) 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<dyn std::error::Error>> {
/// 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` /// Load Vulkan library at `path`
/// ///
/// # Safety /// # Safety
@ -162,7 +171,7 @@ impl Entry {
/// ```no_run /// ```no_run
/// # use ash::{Entry, vk}; /// # use ash::{Entry, vk};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> { /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let entry = Entry::new(); /// let entry = Entry::linked();
/// match entry.try_enumerate_instance_version()? { /// match entry.try_enumerate_instance_version()? {
/// // Vulkan 1.1+ /// // Vulkan 1.1+
/// Some(version) => { /// Some(version) => {
@ -278,9 +287,10 @@ impl Entry {
} }
#[cfg(feature = "linked")] #[cfg(feature = "linked")]
#[cfg_attr(docsrs, doc(cfg(feature = "linked")))]
impl Default for Entry { impl Default for Entry {
fn default() -> Self { fn default() -> Self {
Self::new() Self::linked()
} }
} }

View file

@ -14,7 +14,7 @@
//! ```no_run //! ```no_run
//! use ash::{vk, Entry}; //! use ash::{vk, Entry};
//! # fn main() -> Result<(), Box<dyn std::error::Error>> { //! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let entry = Entry::new(); //! let entry = Entry::linked();
//! let app_info = vk::ApplicationInfo { //! let app_info = vk::ApplicationInfo {
//! api_version: vk::make_api_version(0, 1, 0, 0), //! api_version: vk::make_api_version(0, 1, 0, 0),
//! ..Default::default() //! ..Default::default()
@ -29,7 +29,7 @@
//! //!
//! ## Getting started //! ## 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 //! using [`Entry::load()`], which uses `libloading`. If you want to perform entry point loading
//! yourself, call [`Entry::from_static_fn()`]. //! yourself, call [`Entry::from_static_fn()`].

View file

@ -7,5 +7,8 @@ edition = "2018"
[dependencies] [dependencies]
winit = "0.25.0" winit = "0.25.0"
image = "0.10.4" 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" } ash-window = { path = "../ash-window" }

View file

@ -217,7 +217,7 @@ impl ExampleBase {
)) ))
.build(&event_loop) .build(&event_loop)
.unwrap(); .unwrap();
let entry = Entry::new(); let entry = Entry::linked();
let app_name = CString::new("VulkanTriangle").unwrap(); let app_name = CString::new("VulkanTriangle").unwrap();
let layer_names = [CStr::from_bytes_with_nul_unchecked( let layer_names = [CStr::from_bytes_with_nul_unchecked(