From a8d3e80fdd0c67e6611743e8b3fb33eb1440fd32 Mon Sep 17 00:00:00 2001 From: Kyle Mayes Date: Fri, 22 Sep 2023 22:33:39 -0400 Subject: [PATCH] Add no_std compatibility --- .github/workflows/ci.yml | 11 +++++ CHANGELOG.md | 5 ++ README.md | 6 ++- .../generator/generate/file/Builders.kt | 10 ++-- .../generator/generate/file/Chains.kt | 2 +- .../generator/generate/file/Commands.kt | 6 +-- .../generator/generate/file/Enums.kt | 14 ++++-- .../generator/generate/file/Extensions.kt | 7 +-- .../generator/generate/file/Functions.kt | 2 +- .../generator/generate/file/Handles.kt | 4 +- .../generator/generate/file/Structs.kt | 6 +-- .../generator/generate/file/Typedefs.kt | 2 +- .../generator/generate/file/Unions.kt | 6 +-- .../generator/generate/file/Versions.kt | 7 +-- vulkanalia-sys/Cargo.toml | 5 ++ vulkanalia-sys/src/arrays.rs | 14 +++--- vulkanalia-sys/src/bitfields.rs | 2 +- vulkanalia-sys/src/commands.rs | 2 +- vulkanalia-sys/src/enums.rs | 7 ++- vulkanalia-sys/src/functions.rs | 2 +- vulkanalia-sys/src/handles.rs | 4 +- vulkanalia-sys/src/lib.rs | 5 ++ vulkanalia-sys/src/structs.rs | 6 +-- vulkanalia-sys/src/typedefs.rs | 2 +- vulkanalia-sys/src/unions.rs | 6 +-- vulkanalia/Cargo.toml | 7 ++- vulkanalia/src/bytecode.rs | 17 ++++--- vulkanalia/src/chain.rs | 6 +-- vulkanalia/src/lib.rs | 46 ++++++++++-------- vulkanalia/src/loader.rs | 48 +++++++++++++++---- vulkanalia/src/vk/builders.rs | 10 ++-- vulkanalia/src/vk/chains.rs | 2 +- vulkanalia/src/vk/commands.rs | 4 +- vulkanalia/src/vk/enums.rs | 7 ++- vulkanalia/src/vk/extensions.rs | 7 +-- vulkanalia/src/vk/versions.rs | 7 +-- 36 files changed, 201 insertions(+), 103 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 48e6c8e9..a2d78ad8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,6 +29,17 @@ jobs: with: command: test args: --verbose --all-features + # Test (no_std) + - name: Cargo Build (vulkanalia-sys/no_std) + uses: actions-rs/cargo@v1 + with: + command: build + args: --manifest-path vulkanalia-sys/Cargo.toml --no-default-features + - name: Cargo Build (vulkanalia/no_std) + uses: actions-rs/cargo@v1 + with: + command: build + args: --manifest-path vulkanalia/Cargo.toml --no-default-features format-vulkanalia: name: Format - Vulkanalia diff --git a/CHANGELOG.md b/CHANGELOG.md index e9789581..834ea71d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## [0.23.0] - UNRELEASED + +### Changed +- Added `no_std` compability for `vulkanalia` and `vulkanalia-sys` crates + ## [0.22.0] - 2023-09-15 ### Fixed diff --git a/README.md b/README.md index 8cdc80c6..7ce6b95e 100644 --- a/README.md +++ b/README.md @@ -23,12 +23,16 @@ For users new to Vulkan, there is a complete adaptation of https://vulkan-tutori ## Cargo Features -The `vulkanalia` crate has the following notable Cargo features: +The `vulkanalia` crate has the following notable non-default Cargo features: * `libloading` (**non-default**) – enables integration with [`libloading`](https://crates.io/crates/libloading) (adds the [`LibloadingLoader`](https://docs.rs/vulkanalia/latest/vulkanalia/loader/struct.LibloadingLoader.html) struct which can be used to load the initial Vulkan commands from a Vulkan shared library) * `window` (**non-default**) – enables integration with [`raw-window-handle`](https://crates.io/crates/raw-window-handle) (adds the [`window`](https://docs.rs/vulkanalia/latest/vulkanalia/window/index.html) module which can be used to create surfaces for windows from libraries that support `raw-window-handle` (e.g., [`winit`](https://crates.io/crates/winit)) * `provisional` (**non-default**) – enables access to [provisional Vulkan extensions](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/provisional-headers.html) (**WARNING:** these extensions are not guaranteed to be backwards compatible and are not intended to be used in production applications) +By default, the `vulkanalia-sys` and `vulkanalia` crates depend on the Rust standard library. However, by disabling the default features for these crates, you can use either of these crates in a `no_std` environment. If you do this, the following features are of note: + +* `no_std_error` (**non-default**): enables implementations of the [`Error` trait](https://doc.rust-lang.org/beta/core/error/trait.Error.html) for various error types in `vulkanalia` and `vulkanalia-sys` when the default `std` feature is not enabled (the usage of the `Error` trait in `core` is [not yet stable](https://github.com/rust-lang/rust/issues/103765) and requires the `core-error` feature to be enabled) + ## Example See the `examples` directory for an implementation of the classic triangle example using `vulkanalia`. diff --git a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Builders.kt b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Builders.kt index ae3719e7..1a20eb62 100644 --- a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Builders.kt +++ b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Builders.kt @@ -22,11 +22,11 @@ import com.kylemayes.generator.support.PeekableIterator /** Generates Rust structs to build Vulkan structs. */ fun Registry.generateBuilders() = """ -use std::fmt; -use std::marker::PhantomData; -use std::ops; -use std::os::raw::{c_char, c_int, c_void}; -use std::ptr::NonNull; +use core::ffi::{c_char, c_int, c_void}; +use core::fmt; +use core::marker::PhantomData; +use core::ops; +use core::ptr::NonNull; use super::*; diff --git a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Chains.kt b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Chains.kt index dbd550fc..180b691c 100644 --- a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Chains.kt +++ b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Chains.kt @@ -10,7 +10,7 @@ import java.lang.Error fun Registry.generateChains(): String { return """ -use std::os::raw::c_void; +use core::ffi::c_void; use super::*; diff --git a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Commands.kt b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Commands.kt index b007796b..1819370c 100644 --- a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Commands.kt +++ b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Commands.kt @@ -11,7 +11,7 @@ import com.kylemayes.generator.registry.Registry /** Generates Rust type aliases for Vulkan commands. */ fun Registry.generateCommands() = """ -use std::os::raw::{c_char, c_int, c_void}; +use core::ffi::{c_char, c_int, c_void}; use crate::*; @@ -41,8 +41,8 @@ fun Registry.generateCommandStructs(): String { generateCommandStruct(it.key, supported) } return """ -use std::mem; -use std::os::raw::{c_char, c_int, c_void}; +use core::mem; +use core::ffi::{c_char, c_int, c_void}; use super::*; diff --git a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Enums.kt b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Enums.kt index 53d3e704..bc29d9a4 100644 --- a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Enums.kt +++ b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Enums.kt @@ -12,8 +12,12 @@ import com.kylemayes.generator.registry.intern /** Generates Rust structs for Vulkan enums. */ fun Registry.generateEnums() = """ +use core::fmt; + +#[cfg(feature = "std")] use std::error; -use std::fmt; +#[cfg(all(feature = "no_std_error", not(feature="std")))] +use core::error; ${enums.values.sortedBy { it.name }.joinToString("\n") { generateEnum(it) }} ${generateAliases(enums.keys)} @@ -22,8 +26,12 @@ ${generateAliases(enums.keys)} /** Generates Rust structs for success result and error result enums. */ fun Registry.generateResultEnums() = """ +use core::fmt; + +#[cfg(feature = "std")] use std::error; -use std::fmt; +#[cfg(all(feature = "no_std_error", not(feature="std")))] +use core::error; use super::Result; @@ -68,7 +76,7 @@ private fun Registry.generateEnum(enum: Enum, documentation: String? = null): St val (display, error) = if (enum.name.value == "Result" || enum.name.value == "ErrorCode") { val default = "write!(f, \"unknown Vulkan result (code = {})\", self.0)" val display = generateFmtImpl(enum, "Display", default) { "\"${results[it.value] ?: it.name.value}\"" } - display to "impl error::Error for ${enum.name} { }" + display to "#[cfg(any(feature=\"std\", feature=\"no_std_error\"))] impl error::Error for ${enum.name} { }" } else { "" to "" } diff --git a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Extensions.kt b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Extensions.kt index e50e29d1..4a446344 100644 --- a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Extensions.kt +++ b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Extensions.kt @@ -105,9 +105,10 @@ pub const ${extension.name}_EXTENSION: Extension = Extension { /** Generates Rust modules and traits for Vulkan extensions. */ fun Registry.generateExtensionTraits() = """ -use std::mem::MaybeUninit; -use std::os::raw::{c_int, c_void}; -use std::ptr; +use alloc::vec::Vec; +use core::ffi::{c_int, c_void}; +use core::mem::MaybeUninit; +use core::ptr; use super::*; diff --git a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Functions.kt b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Functions.kt index e4ebf7f8..1ca408ba 100644 --- a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Functions.kt +++ b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Functions.kt @@ -9,7 +9,7 @@ import com.kylemayes.generator.registry.Registry /** Generates Rust type aliases for Vulkan function pointer types. */ fun Registry.generateFunctions() = """ -use std::os::raw::{c_char, c_void}; +use core::ffi::{c_char, c_void}; use crate::*; diff --git a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Handles.kt b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Handles.kt index 97f9cd64..25e89c27 100644 --- a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Handles.kt +++ b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Handles.kt @@ -11,8 +11,8 @@ import com.kylemayes.generator.support.toSnakeCase /** Generates Rust structs for Vulkan handles. */ fun Registry.generateHandles() = """ -use std::fmt; -use std::hash::Hash; +use core::fmt; +use core::hash::Hash; use crate::ObjectType; diff --git a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Structs.kt b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Structs.kt index a5899ced..eec669dd 100644 --- a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Structs.kt +++ b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Structs.kt @@ -15,9 +15,9 @@ import com.kylemayes.generator.support.PeekableIterator /** Generates Rust structs for Vulkan structs. */ fun Registry.generateStructs(): String { return """ -use std::fmt; -use std::os::raw::{c_char, c_int, c_void}; -use std::ptr; +use core::ffi::{c_char, c_int, c_void}; +use core::fmt; +use core::ptr; use crate::*; diff --git a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Typedefs.kt b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Typedefs.kt index f979b122..631d116f 100644 --- a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Typedefs.kt +++ b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Typedefs.kt @@ -9,7 +9,7 @@ import com.kylemayes.generator.registry.Typedef /** Generates Rust type aliases for Vulkan typedefs and platform types. */ fun Registry.generateTypedefs() = """ -use std::os::raw::{c_ulong, c_void}; +use core::ffi::{c_ulong, c_void}; ${basetypes.values.sortedBy { it.name }.joinToString("\n") { generateTypedef(it) }} diff --git a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Unions.kt b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Unions.kt index b1a21f87..533e8c09 100644 --- a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Unions.kt +++ b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Unions.kt @@ -10,9 +10,9 @@ import com.kylemayes.generator.registry.Structure /** Generates Rust unions for Vulkan unions. */ fun Registry.generateUnions() = """ -use std::fmt; -use std::mem::MaybeUninit; -use std::os::raw::{c_char, c_void}; +use core::ffi::{c_char, c_void}; +use core::fmt; +use core::mem::MaybeUninit; use crate::*; diff --git a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Versions.kt b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Versions.kt index a853f29a..89cde1ab 100644 --- a/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Versions.kt +++ b/generator/src/main/kotlin/com/kylemayes/generator/generate/file/Versions.kt @@ -13,9 +13,10 @@ import com.kylemayes.generator.registry.Version fun Registry.generateVersionTraits(): String { var versions = """ -use std::mem::MaybeUninit; -use std::os::raw::c_void; -use std::ptr; +use alloc::vec::Vec; +use core::ffi::c_void; +use core::mem::MaybeUninit; +use core::ptr; use super::*; """ diff --git a/vulkanalia-sys/Cargo.toml b/vulkanalia-sys/Cargo.toml index ccb25ab8..8fb44742 100644 --- a/vulkanalia-sys/Cargo.toml +++ b/vulkanalia-sys/Cargo.toml @@ -20,6 +20,11 @@ categories = ["graphics"] [features] +default = ["std"] + +std = [] +no_std_error = [] + provisional = [] [dependencies] diff --git a/vulkanalia-sys/src/arrays.rs b/vulkanalia-sys/src/arrays.rs index f63c7bb8..ce9835d0 100644 --- a/vulkanalia-sys/src/arrays.rs +++ b/vulkanalia-sys/src/arrays.rs @@ -9,12 +9,12 @@ clippy::upper_case_acronyms )] -use std::borrow::Cow; -use std::ffi::CStr; -use std::fmt; -use std::hash; -use std::ops; -use std::os::raw::c_char; +use alloc::borrow::Cow; +use alloc::string::String; +use core::ffi::{c_char, CStr}; +use core::fmt; +use core::hash; +use core::ops; /// An array containing a sequence of bytes. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -88,7 +88,7 @@ impl From> for [u8; N] { /// /// assert_eq!(hasher1.finish(), hasher2.finish()); /// ``` -#[derive(Copy, Clone)] +#[derive(Copy, Clone, PartialOrd, Ord)] #[repr(transparent)] pub struct StringArray([c_char; N]); diff --git a/vulkanalia-sys/src/bitfields.rs b/vulkanalia-sys/src/bitfields.rs index 3e88860d..4ec3b093 100644 --- a/vulkanalia-sys/src/bitfields.rs +++ b/vulkanalia-sys/src/bitfields.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 -use std::fmt; +use core::fmt; /// A pair of bitfields stored in an `u32`. /// diff --git a/vulkanalia-sys/src/commands.rs b/vulkanalia-sys/src/commands.rs index 13d7065c..96f6bacc 100644 --- a/vulkanalia-sys/src/commands.rs +++ b/vulkanalia-sys/src/commands.rs @@ -18,7 +18,7 @@ clippy::useless_transmute )] -use std::os::raw::{c_char, c_int, c_void}; +use core::ffi::{c_char, c_int, c_void}; use crate::*; diff --git a/vulkanalia-sys/src/enums.rs b/vulkanalia-sys/src/enums.rs index 9ff1d0f8..d22415c5 100644 --- a/vulkanalia-sys/src/enums.rs +++ b/vulkanalia-sys/src/enums.rs @@ -18,8 +18,12 @@ clippy::useless_transmute )] +use core::fmt; + +#[cfg(all(feature = "no_std_error", not(feature = "std")))] +use core::error; +#[cfg(feature = "std")] use std::error; -use std::fmt; /// #[repr(transparent)] @@ -4545,6 +4549,7 @@ impl fmt::Display for Result { } } +#[cfg(any(feature = "std", feature = "no_std_error"))] impl error::Error for Result {} /// diff --git a/vulkanalia-sys/src/functions.rs b/vulkanalia-sys/src/functions.rs index 80f94d02..2388ae8b 100644 --- a/vulkanalia-sys/src/functions.rs +++ b/vulkanalia-sys/src/functions.rs @@ -18,7 +18,7 @@ clippy::useless_transmute )] -use std::os::raw::{c_char, c_void}; +use core::ffi::{c_char, c_void}; use crate::*; diff --git a/vulkanalia-sys/src/handles.rs b/vulkanalia-sys/src/handles.rs index 11116c93..db718f57 100644 --- a/vulkanalia-sys/src/handles.rs +++ b/vulkanalia-sys/src/handles.rs @@ -18,8 +18,8 @@ clippy::useless_transmute )] -use std::fmt; -use std::hash::Hash; +use core::fmt; +use core::hash::Hash; use crate::ObjectType; diff --git a/vulkanalia-sys/src/lib.rs b/vulkanalia-sys/src/lib.rs index b383b7e9..625142c4 100644 --- a/vulkanalia-sys/src/lib.rs +++ b/vulkanalia-sys/src/lib.rs @@ -2,6 +2,11 @@ //! Raw Vulkan bindings for Rust. +#![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(feature = "core_error", feature(no_std_error))] + +extern crate alloc; + mod arrays; mod bitfields; diff --git a/vulkanalia-sys/src/structs.rs b/vulkanalia-sys/src/structs.rs index 758fcb56..41a2fc2f 100644 --- a/vulkanalia-sys/src/structs.rs +++ b/vulkanalia-sys/src/structs.rs @@ -18,9 +18,9 @@ clippy::useless_transmute )] -use std::fmt; -use std::os::raw::{c_char, c_int, c_void}; -use std::ptr; +use core::ffi::{c_char, c_int, c_void}; +use core::fmt; +use core::ptr; use crate::*; diff --git a/vulkanalia-sys/src/typedefs.rs b/vulkanalia-sys/src/typedefs.rs index eb78da62..36267998 100644 --- a/vulkanalia-sys/src/typedefs.rs +++ b/vulkanalia-sys/src/typedefs.rs @@ -18,7 +18,7 @@ clippy::useless_transmute )] -use std::os::raw::{c_ulong, c_void}; +use core::ffi::{c_ulong, c_void}; /// pub type Bool32 = u32; diff --git a/vulkanalia-sys/src/unions.rs b/vulkanalia-sys/src/unions.rs index 05eca918..3873bb43 100644 --- a/vulkanalia-sys/src/unions.rs +++ b/vulkanalia-sys/src/unions.rs @@ -18,9 +18,9 @@ clippy::useless_transmute )] -use std::fmt; -use std::mem::MaybeUninit; -use std::os::raw::{c_char, c_void}; +use core::ffi::{c_char, c_void}; +use core::fmt; +use core::mem::MaybeUninit; use crate::*; diff --git a/vulkanalia/Cargo.toml b/vulkanalia/Cargo.toml index 473117d1..f9292229 100644 --- a/vulkanalia/Cargo.toml +++ b/vulkanalia/Cargo.toml @@ -20,6 +20,11 @@ categories = ["graphics"] [features] +default = ["std"] + +std = ["vulkanalia-sys/std"] +no_std_error = ["vulkanalia-sys/no_std_error"] + provisional = ["vulkanalia-sys/provisional"] window = ["raw-window-handle", "cocoa", "metal", "objc"] @@ -27,7 +32,7 @@ window = ["raw-window-handle", "cocoa", "metal", "objc"] libloading = { version = "0.7", optional = true } raw-window-handle = { version = "0.5", optional = true } -vulkanalia-sys = { version = "0.22", path = "../vulkanalia-sys" } +vulkanalia-sys = { version = "0.22", path = "../vulkanalia-sys", default-features = false } [target.'cfg(target_os = "macos")'.dependencies] diff --git a/vulkanalia/src/bytecode.rs b/vulkanalia/src/bytecode.rs index b7e1964b..532dcd4c 100644 --- a/vulkanalia/src/bytecode.rs +++ b/vulkanalia/src/bytecode.rs @@ -1,9 +1,13 @@ //! SPIR-V bytecode. -use std::alloc::{self, Layout}; +use alloc::alloc::{alloc as malloc, dealloc as free, Layout}; +use core::fmt; +use core::slice; + +#[cfg(all(feature = "no_std_error", not(feature = "std")))] +use core::error; +#[cfg(feature = "std")] use std::error; -use std::fmt; -use std::slice; /// An error raised by a failure to construct a [`Bytecode`]. #[derive(Clone, Debug, PartialEq)] @@ -14,7 +18,7 @@ pub enum BytecodeError { Length(usize), } -impl std::fmt::Display for BytecodeError { +impl fmt::Display for BytecodeError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use BytecodeError::*; match self { @@ -24,6 +28,7 @@ impl std::fmt::Display for BytecodeError { } } +#[cfg(any(feature = "std", feature = "no_std_error"))] impl error::Error for BytecodeError {} /// A 4-byte aligned SPIR-V bytecode buffer. @@ -55,7 +60,7 @@ impl Bytecode { // SAFETY: Safe because `layout` is guaranteed to have non-zero size // because `size` is always non-zero and `align` is always 4. - let pointer = unsafe { alloc::alloc(layout) }; + let pointer = unsafe { malloc(layout) }; if pointer.is_null() { return Err(BytecodeError::Alloc); } @@ -84,6 +89,6 @@ impl Bytecode { impl Drop for Bytecode { fn drop(&mut self) { let layout = Layout::from_size_align(self.1, 4).unwrap(); - unsafe { alloc::dealloc(self.0, layout) }; + unsafe { free(self.0, layout) }; } } diff --git a/vulkanalia/src/chain.rs b/vulkanalia/src/chain.rs index 1dae5065..9728f963 100644 --- a/vulkanalia/src/chain.rs +++ b/vulkanalia/src/chain.rs @@ -81,9 +81,9 @@ //! assert_eq!(full.descriptor_indexing, 1); //! ``` -use std::iter; -use std::os::raw::c_void; -use std::ptr::NonNull; +use core::ffi::c_void; +use core::iter; +use core::ptr::NonNull; use crate::prelude::v1_0::*; diff --git a/vulkanalia/src/lib.rs b/vulkanalia/src/lib.rs index 8c658bae..3f5bdb87 100644 --- a/vulkanalia/src/lib.rs +++ b/vulkanalia/src/lib.rs @@ -2,6 +2,11 @@ //! Vulkan bindings for Rust. +#![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(feature = "core_error", feature(no_std_error))] + +extern crate alloc; + pub mod bytecode; pub mod chain; pub mod loader; @@ -10,15 +15,15 @@ pub mod vk; #[cfg(feature = "window")] pub mod window; -use std::collections::HashSet; -use std::error; -use std::fmt; -use std::mem; -use std::os::raw::c_char; -use std::slice; -use std::sync::Arc; +use alloc::boxed::Box; +use alloc::collections::btree_set::BTreeSet; +use alloc::sync::Arc; +use core::ffi::c_char; +use core::fmt; +use core::mem; +use core::slice; -use self::loader::Loader; +use self::loader::{Loader, LoaderError}; use self::prelude::v1_0::*; use self::vk::{DeviceCommands, EntryCommands, InstanceCommands}; @@ -143,9 +148,7 @@ impl Entry { /// implementation to load the entry commands so the safety requirements of /// [`Loader::load`] for the [`Loader`] implementation used must be upheld. #[inline] - pub unsafe fn new( - loader: impl Loader + 'static, - ) -> Result> { + pub unsafe fn new(loader: impl Loader + 'static) -> Result> { let loader = Arc::new(loader); let raw = loader.load(b"vkGetInstanceProcAddr")?; @@ -225,20 +228,20 @@ pub struct Instance { get_device: vk::PFN_vkGetDeviceProcAddr, handle: vk::Instance, commands: InstanceCommands, - extensions: HashSet, - layers: HashSet, + extensions: BTreeSet, + layers: BTreeSet, } impl Instance { /// Gets the loaded extensions for this Vulkan instance. #[inline] - pub fn extensions(&self) -> &HashSet { + pub fn extensions(&self) -> &BTreeSet { &self.extensions } /// Gets the loaded layers for this Vulkan instance. #[inline] - pub fn layers(&self) -> &HashSet { + pub fn layers(&self) -> &BTreeSet { &self.layers } @@ -288,20 +291,20 @@ unsafe impl Sync for Instance {} pub struct Device { handle: vk::Device, commands: DeviceCommands, - extensions: HashSet, - layers: HashSet, + extensions: BTreeSet, + layers: BTreeSet, } impl Device { /// Gets the loaded extensions for this Vulkan device. #[inline] - pub fn extensions(&self) -> &HashSet { + pub fn extensions(&self) -> &BTreeSet { &self.extensions } /// Gets the loaded layers for this Vulkan device. #[inline] - pub fn layers(&self) -> &HashSet { + pub fn layers(&self) -> &BTreeSet { &self.layers } } @@ -320,7 +323,10 @@ unsafe impl Send for Device {} unsafe impl Sync for Device {} #[inline] -unsafe fn get_names(num_strings: u32, strings: *const *const c_char) -> HashSet { +unsafe fn get_names( + num_strings: u32, + strings: *const *const c_char, +) -> BTreeSet { slice::from_raw_parts(strings, num_strings as usize) .iter() .map(|s| vk::ExtensionName::from_ptr(*s)) diff --git a/vulkanalia/src/loader.rs b/vulkanalia/src/loader.rs index edcb23de..526e857b 100644 --- a/vulkanalia/src/loader.rs +++ b/vulkanalia/src/loader.rs @@ -2,6 +2,11 @@ //! Vulkan function loaders. +use alloc::boxed::Box; + +#[cfg(all(feature = "no_std_error", not(feature = "std")))] +use core::error; +#[cfg(feature = "std")] use std::error; /// The default Vulkan shared library filename on the current platform (Windows). @@ -25,6 +30,29 @@ pub const LIBRARY: &str = "libvulkan.dylib"; ))] pub const LIBRARY: &str = "libvulkan.so.1"; +/// An error produced by a failure to load a Vulkan function. +#[cfg(any(feature = "std", feature = "no_std_error"))] +pub trait LoaderError: error::Error + Send + Sync + 'static {} +/// An error produced by a failure to load a Vulkan function. +#[cfg(not(any(feature = "std", feature = "no_std_error")))] +pub trait LoaderError: core::fmt::Debug + core::fmt::Display + Send + Sync + 'static {} + +#[cfg(not(any(feature = "std", feature = "no_std_error")))] +impl LoaderError for alloc::string::String {} + +impl<'a> From<&'a str> for Box { + #[cfg(any(feature = "std", feature = "no_std_error"))] + fn from(value: &'a str) -> Self { + value.into() + } + + #[cfg(not(any(feature = "std", feature = "no_std_error")))] + fn from(value: &'a str) -> Self { + use alloc::string::ToString; + Box::new(value.to_string()) as Box + } +} + /// A Vulkan function loader. pub trait Loader { /// Loads a Vulkan function. @@ -32,15 +60,12 @@ pub trait Loader { /// # Safety /// /// See implementations for safety documentation. - unsafe fn load( - &self, - name: &[u8], - ) -> Result>; + unsafe fn load(&self, name: &[u8]) -> Result>; } #[cfg(feature = "libloading")] mod libloading_loader { - use std::error; + use std::boxed::Box; use std::ffi::OsStr; use std::mem; @@ -48,6 +73,14 @@ mod libloading_loader { use super::*; + impl LoaderError for Error {} + + impl From for Box { + fn from(value: Error) -> Self { + Box::new(value) as Box + } + } + /// A Vulkan function loader that uses `libloading`. #[derive(Debug)] pub struct LibloadingLoader(Library); @@ -77,10 +110,7 @@ mod libloading_loader { /// /// See [`libloading::Library::get`](https://docs.rs/libloading/0.7/libloading/struct.Library.html#method.get). #[inline] - unsafe fn load( - &self, - name: &[u8], - ) -> Result> { + unsafe fn load(&self, name: &[u8]) -> Result> { let symbol: Symbol> = self.0.get(name)?; let symbol = symbol.lift_option().ok_or("missing function")?; Ok(mem::transmute(symbol)) diff --git a/vulkanalia/src/vk/builders.rs b/vulkanalia/src/vk/builders.rs index da0f682e..83c1e16c 100644 --- a/vulkanalia/src/vk/builders.rs +++ b/vulkanalia/src/vk/builders.rs @@ -18,11 +18,11 @@ clippy::useless_transmute )] -use std::fmt; -use std::marker::PhantomData; -use std::ops; -use std::os::raw::{c_char, c_int, c_void}; -use std::ptr::NonNull; +use core::ffi::{c_char, c_int, c_void}; +use core::fmt; +use core::marker::PhantomData; +use core::ops; +use core::ptr::NonNull; use super::*; diff --git a/vulkanalia/src/vk/chains.rs b/vulkanalia/src/vk/chains.rs index d5f4faf2..f37f5dcb 100644 --- a/vulkanalia/src/vk/chains.rs +++ b/vulkanalia/src/vk/chains.rs @@ -18,7 +18,7 @@ clippy::useless_transmute )] -use std::os::raw::c_void; +use core::ffi::c_void; use super::*; diff --git a/vulkanalia/src/vk/commands.rs b/vulkanalia/src/vk/commands.rs index 558f53f0..6358bbb4 100644 --- a/vulkanalia/src/vk/commands.rs +++ b/vulkanalia/src/vk/commands.rs @@ -18,8 +18,8 @@ clippy::useless_transmute )] -use std::mem; -use std::os::raw::{c_char, c_int, c_void}; +use core::ffi::{c_char, c_int, c_void}; +use core::mem; use super::*; diff --git a/vulkanalia/src/vk/enums.rs b/vulkanalia/src/vk/enums.rs index b923b575..ba0aee37 100644 --- a/vulkanalia/src/vk/enums.rs +++ b/vulkanalia/src/vk/enums.rs @@ -18,8 +18,12 @@ clippy::useless_transmute )] +use core::fmt; + +#[cfg(all(feature = "no_std_error", not(feature = "std")))] +use core::error; +#[cfg(feature = "std")] use std::error; -use std::fmt; use super::Result; @@ -208,6 +212,7 @@ impl fmt::Display for ErrorCode { } } +#[cfg(any(feature = "std", feature = "no_std_error"))] impl error::Error for ErrorCode {} impl From for ErrorCode { diff --git a/vulkanalia/src/vk/extensions.rs b/vulkanalia/src/vk/extensions.rs index 7f1e85ec..49844bee 100644 --- a/vulkanalia/src/vk/extensions.rs +++ b/vulkanalia/src/vk/extensions.rs @@ -18,9 +18,10 @@ clippy::useless_transmute )] -use std::mem::MaybeUninit; -use std::os::raw::{c_int, c_void}; -use std::ptr; +use alloc::vec::Vec; +use core::ffi::{c_int, c_void}; +use core::mem::MaybeUninit; +use core::ptr; use super::*; diff --git a/vulkanalia/src/vk/versions.rs b/vulkanalia/src/vk/versions.rs index cdf3a9fc..34d1de81 100644 --- a/vulkanalia/src/vk/versions.rs +++ b/vulkanalia/src/vk/versions.rs @@ -18,9 +18,10 @@ clippy::useless_transmute )] -use std::mem::MaybeUninit; -use std::os::raw::c_void; -use std::ptr; +use alloc::vec::Vec; +use core::ffi::c_void; +use core::mem::MaybeUninit; +use core::ptr; use super::*;