Name |
Date |
Size |
#Lines |
LOC |
||
---|---|---|---|---|---|---|
.. | - | - | ||||
src/ | 25-Apr-2025 | - | 141,451 | 139,271 | ||
tests/ | 25-Apr-2025 | - | 52 | 39 | ||
.cargo-checksum.json | D | 25-Apr-2025 | 10.2 KiB | 1 | 1 | |
Android.bp | D | 25-Apr-2025 | 2.4 KiB | 110 | 103 | |
Cargo.toml | D | 25-Apr-2025 | 1.2 KiB | 55 | 49 | |
LICENSE | D | 25-Apr-2025 | 9.5 KiB | 68 | 39 | |
LICENSE-APACHE | D | 25-Apr-2025 | 9.5 KiB | 68 | 39 | |
LICENSE-MIT | D | 25-Apr-2025 | 1 KiB | 26 | 22 | |
METADATA | D | 25-Apr-2025 | 370 | 18 | 17 | |
MODULE_LICENSE_APACHE2 | D | 25-Apr-2025 | 0 | |||
README.md | D | 25-Apr-2025 | 12.4 KiB | 291 | 232 | |
TEST_MAPPING | D | 25-Apr-2025 | 155 | 9 | 8 | |
build.rs | D | 25-Apr-2025 | 799 | 25 | 22 | |
cargo_embargo.json | D | 25-Apr-2025 | 125 | 9 | 8 |
README.md
1# Ash 2 3A very lightweight wrapper around Vulkan 4 5[](https://crates.io/crates/ash) 6[](https://docs.rs/ash) 7[](https://github.com/MaikKlein/ash/actions?workflow=CI) 8[](LICENSE-MIT) 9[](LICENSE-APACHE) 10[](https://gitter.im/MaikKlein/ash?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 11[](https://blog.rust-lang.org/2022/04/07/Rust-1.60.0.html) 12 13## Overview 14- [x] A true Vulkan API without compromises 15- [x] Convenience features without limiting functionality 16- [x] Additional type safety 17- [x] Device local function pointer loading 18- [x] No validation, everything is **unsafe** 19- [x] Generated from `vk.xml` 20- [x] Support for Vulkan `1.1`, `1.2`, `1.3` 21 22## ⚠️ Semver compatibility warning 23The Vulkan Video bindings are experimental and still seeing breaking changes in their upstream specification, and are only provided by Ash for early adopters. All related functions and types are semver-exempt [^1] (we allow breaking API changes while releasing Ash with non-breaking semver bumps). 24 25[^1]: `generator` complexity makes it so that we cannot easily hide these bindings behind a non-`default` feature flag, and they are widespread across the generated codebase. 26 27## Features 28### Explicit returns with `Result` 29```rust 30// function signature 31pub fn create_instance(&self, 32 create_info: &vk::InstanceCreateInfo, 33 allocation_callbacks: Option<&vk::AllocationCallbacks>) 34 -> Result<Instance, InstanceError> { .. } 35let instance = entry.create_instance(&create_info, None) 36 .expect("Instance creation error"); 37``` 38 39 40### `Vec<T>` instead of mutable slices 41 42```rust 43pub fn get_swapchain_images(&self, 44 swapchain: vk::SwapchainKHR) 45 -> VkResult<Vec<vk::Image>>; 46let present_images = swapchain_loader.get_swapchain_images_khr(swapchain).unwrap(); 47``` 48*Note*: Functions don't return `Vec<T>` if this would limit the functionality. See `p_next`. 49 50### Slices 51```rust 52pub fn cmd_pipeline_barrier(&self, 53 command_buffer: vk::CommandBuffer, 54 src_stage_mask: vk::PipelineStageFlags, 55 dst_stage_mask: vk::PipelineStageFlags, 56 dependency_flags: vk::DependencyFlags, 57 memory_barriers: &[vk::MemoryBarrier], 58 buffer_memory_barriers: &[vk::BufferMemoryBarrier], 59 image_memory_barriers: &[vk::ImageMemoryBarrier]); 60``` 61 62### Strongly typed handles 63 64Each Vulkan handle type is exposed as a newtyped struct for improved type safety. Null handles can be constructed with 65`T::null()`, and handles may be freely converted to and from `u64` with `Handle::from_raw` and `Handle::as_raw` for 66interop with non-Ash Vulkan code. 67 68### Default implementation for all types 69```rust 70// No need to manually set the structure type 71let desc_alloc_info = vk::DescriptorSetAllocateInfo { 72 descriptor_pool: self.pool, 73 descriptor_set_count: self.layouts.len() as u32, 74 p_set_layouts: self.layouts.as_ptr(), 75 ..Default::default() 76}; 77``` 78### Builder pattern 79 80```rust 81// We lose all lifetime information when we call `.build()`. Be careful! 82let queue_info = [vk::DeviceQueueCreateInfo::builder() 83 .queue_family_index(queue_family_index) 84 .queue_priorities(&priorities) 85 .build()]; 86 87// We don't need to call `.build()` here because builders implement `Deref`. 88let device_create_info = vk::DeviceCreateInfo::builder() 89 .queue_create_infos(&queue_info) 90 .enabled_extension_names(&device_extension_names_raw) 91 .enabled_features(&features); 92 93let device: Device = instance 94 .create_device(pdevice, &device_create_info, None) 95 .unwrap(); 96``` 97 98To not lose this lifetime single items can be "cast" to a slice of length _one_ with `std::slice::from_ref` while still taking advantage of `Deref`: 99 100```rust 101let queue_info = vk::DeviceQueueCreateInfo::builder() 102 .queue_family_index(queue_family_index) 103 .queue_priorities(&priorities); 104 105let device_create_info = vk::DeviceCreateInfo::builder() 106 .queue_create_infos(std::slice::from_ref(&queue_info)) 107 ...; 108``` 109 110Builders have an explicit lifetime, and are marked as `#[repr(transparent)]`. 111```rust 112#[repr(transparent)] 113pub struct DeviceCreateInfoBuilder<'a> { 114 inner: DeviceCreateInfo, 115 marker: ::std::marker::PhantomData<&'a ()>, 116} 117impl<'a> DeviceCreateInfoBuilder<'a> { 118 //... 119 pub fn queue_create_infos( 120 mut self, 121 queue_create_infos: &'a [DeviceQueueCreateInfo], 122 ) -> DeviceCreateInfoBuilder<'a> {...} 123 //... 124``` 125 126Every reference has to live as long as the builder itself. Builders implement `Deref` targeting their corresponding Vulkan struct, so references to builders can be passed directly 127to Vulkan functions. 128 129Calling `.build()` will **discard** that lifetime because Vulkan structs use raw pointers internally. This should be avoided as much as possible because this can easily lead to dangling pointers. If `.build()` has to be called, it should be called as late as possible. [Lifetimes of temporaries](https://doc.rust-lang.org/reference/expressions.html#temporary-lifetimes) are extended to the enclosing statement, ensuring they are valid for the duration of a Vulkan call occurring in the same statement. 130 131 132### Pointer chains 133 134```rust 135let mut variable_pointers = vk::PhysicalDeviceVariablePointerFeatures::builder(); 136let mut corner = 137 vk::PhysicalDeviceCornerSampledImageFeaturesNV::builder(); 138; 139let mut device_create_info = vk::DeviceCreateInfo::builder() 140 .push_next(&mut corner) 141 .push_next(&mut variable_pointers); 142``` 143 144Pointer chains in builders differ from raw Vulkan. Instead of chaining every struct manually, you instead use `.push_next` on the struct that you are going to pass into the function. Those structs then get *prepended* into the chain. 145 146`push_next` is also type checked, you can only add valid structs to the chain. Both the structs and the builders can be passed into `push_next`. Only builders for structs that can be passed into functions will implement a `push_next`. 147 148 149### Flags and constants as associated constants 150 151```rust 152// Bitflag 153vk::AccessFlags::COLOR_ATTACHMENT_READ | vk::AccessFlags::COLOR_ATTACHMENT_WRITE 154``` 155 156```rust 157// Constant 158vk::PipelineBindPoint::GRAPHICS, 159``` 160### Debug/Display for Flags 161 162```rust 163let flag = vk::AccessFlags::COLOR_ATTACHMENT_READ 164 | vk::AccessFlags::COLOR_ATTACHMENT_WRITE; 165println!("Debug: {:?}", flag); 166println!("Display: {}", flag); 167// Prints: 168// Debug: AccessFlags(110000000) 169// Display: COLOR_ATTACHMENT_READ | COLOR_ATTACHMENT_WRITE 170``` 171 172### Function pointer loading 173Ash also takes care of loading the function pointers. Function pointers are split into 3 categories. 174 175* Entry: Loads the Vulkan library. Needs to outlive `Instance` and `Device`. 176* Instance: Loads instance level functions. Needs to outlive the `Device`s it has created. 177* Device: Loads device **local** functions. 178 179The loader is just one possible implementation: 180 181* Device level functions are retrieved on a per device basis. 182* Everything is loaded by default, functions that failed to load are initialized to a function that always panics. 183* Do not call Vulkan 1.1 functions if you have created a 1.0 instance. Doing so will result in a panic. 184 185Custom loaders can be implemented. 186 187### Extension loading 188Additionally, every Vulkan extension has to be loaded explicitly. You can find all extensions under [ash::extensions](https://github.com/MaikKlein/ash/tree/master/ash/src/extensions). 189```rust 190use ash::extensions::khr::Swapchain; 191let swapchain_loader = Swapchain::new(&instance, &device); 192let swapchain = swapchain_loader.create_swapchain(&swapchain_create_info).unwrap(); 193``` 194 195### Raw function pointers 196 197Raw function pointers are available, if something hasn't been exposed yet in the higher level API. Please open an issue if anything is missing. 198 199```rust 200device.fp_v1_0().destroy_device(...); 201``` 202 203### Support for extension names 204```rust 205use ash::extensions::{Swapchain, XlibSurface, Surface, DebugReport}; 206#[cfg(all(unix, not(target_os = "android")))] 207fn extension_names() -> Vec<*const i8> { 208 vec![ 209 Surface::name().as_ptr(), 210 XlibSurface::name().as_ptr(), 211 DebugReport::name().as_ptr() 212 ] 213} 214``` 215 216### Implicit handles 217Handles from Instance or Device are passed implicitly. 218```rust 219pub fn create_command_pool(&self, 220 create_info: &vk::CommandPoolCreateInfo) 221 -> VkResult<vk::CommandPool>; 222 223let pool = device.create_command_pool(&pool_create_info).unwrap(); 224``` 225 226### Optional linking 227 228The default `loaded` cargo feature will dynamically load the default Vulkan library for the current platform with `Entry::load`, meaning that the build environment does not have to have Vulkan development packages installed. 229 230If, on the other hand, your application cannot handle Vulkan being missing at runtime, you can instead enable the `linked` feature, which will link your binary with the Vulkan loader directly and expose the infallible `Entry::linked`. 231 232## Example 233You can find the examples [here](https://github.com/MaikKlein/ash/tree/master/examples). 234All examples currently require: the LunarG Validation layers and a Vulkan library that is visible in your `PATH`. An easy way to get started is to use the [LunarG Vulkan SDK](https://lunarg.com/vulkan-sdk/) 235#### Windows 236Make sure that you have a Vulkan ready driver and install the [LunarG Vulkan SDK](https://lunarg.com/vulkan-sdk/). 237#### Linux 238Make sure that you have a Vulkan ready driver and install the [LunarG Vulkan SDK](https://lunarg.com/vulkan-sdk/). You also have to add the library and layers to your path. Have a look at my [post](http://askubuntu.com/a/803110/77183) if you are unsure how to do that. 239#### macOS 240Install the [LunarG Vulkan SDK](https://lunarg.com/vulkan-sdk/). The installer puts the SDK in `$HOME/VulkanSDK/<version>` by default. You will need to set the following environment variables when running cargo: 241```sh 242VULKAN_SDK=$HOME/VulkanSDK/<version>/macOS \ 243DYLD_FALLBACK_LIBRARY_PATH=$VULKAN_SDK/lib \ 244VK_ICD_FILENAMES=$VULKAN_SDK/share/vulkan/icd.d/MoltenVK_icd.json \ 245VK_LAYER_PATH=$VULKAN_SDK/share/vulkan/explicit_layer.d \ 246cargo run ... 247``` 248 249### [Triangle](https://github.com/MaikKlein/ash/blob/master/examples/src/bin/triangle.rs) 250Displays a triangle with vertex colors. 251``` 252cd examples 253cargo run --bin triangle 254``` 255 256 257 258### [Texture](https://github.com/MaikKlein/ash/blob/master/examples/src/bin/texture.rs) 259Displays a texture on a quad. 260``` 261cd examples 262cargo run --bin texture 263``` 264 265 266## Useful resources 267 268### Examples 269 270* [vulkan-tutorial-rust](https://github.com/Usami-Renko/vulkan-tutorial-rust) - A port of [vulkan-tutorial.com](https://vulkan-tutorial.com). 271* [ash-sample-progression](https://github.com/bzm3r/ash-sample-progression) - A port of the LunarG examples. 272* [ash-nv-rt](https://github.com/gwihlidal/ash-nv-rt) A raytracing example for ash. 273 274### Utility libraries 275* [vk-sync](https://github.com/gwihlidal/vk-sync-rs) - Simplified Vulkan synchronization logic, written in rust. 276* [vk-mem-rs](https://github.com/gwihlidal/vk-mem-rs) - This crate provides an FFI layer and idiomatic rust wrappers for the excellent AMD Vulkan Memory Allocator (VMA) C/C++ library. 277* [gpu-allocator](https://github.com/Traverse-Research/gpu-allocator) - Memory allocator written in pure Rust for GPU memory in Vulkan and in the future DirectX 12 278* [lahar](https://github.com/Ralith/lahar) - Tools for asynchronously uploading data to a Vulkan device. 279 280### Libraries that use ash 281* [gfx-rs](https://github.com/gfx-rs/gfx) - gfx-rs is a low-level, cross-platform graphics abstraction library in Rust. 282 283## A thanks to 284 285* [Api with no secrets](https://software.intel.com/en-us/articles/api-without-secrets-introduction-to-vulkan-part-1) 286* [Vulkan tutorial](http://jhenriques.net/development.html) 287* [Vulkan examples](https://github.com/SaschaWillems/Vulkan) 288* [Vulkan tutorial](https://vulkan-tutorial.com/) 289* [Vulkano](https://github.com/vulkano-rs/vulkano) 290* [vk-rs](https://github.com/Osspial/vk-rs) 291