ash/README.md

103 lines
4.6 KiB
Markdown
Raw Normal View History

2016-12-10 05:30:05 +11:00
#Ash
2016-12-10 05:25:48 +11:00
A low level Vulkan wrapper for Rust
2016-08-14 09:13:39 +10:00
2016-12-10 05:25:48 +11:00
2016-12-10 05:30:05 +11:00
## Why Ash?
2016-12-10 05:25:48 +11:00
Functions return a `type VkResult<T> = Result<T, vk::Result>` instead of an error code. No mutable references for the output are required.
```Rust
pub fn create_swapchain_khr(&self,
create_info: &vk::SwapchainCreateInfoKHR)
-> VkResult<vk::SwapchainKHR>;
let swapchain = device.create_swapchain_khr(&swapchain_create_info).unwrap();
```
Always returns a `Vec<T>` for functions that output multiple values.
```Rust
pub fn get_swapchain_images_khr(&self,
swapchain: vk::SwapchainKHR)
-> VkResult<Vec<vk::Image>>;
let present_images = device.get_swapchain_images_khr(swapchain).unwrap();
```
2016-12-10 05:30:05 +11:00
Ash always uses slices in functions.
2016-12-10 05:25:48 +11:00
```Rust
// C
void vkCmdPipelineBarrier(
VkCommandBuffer commandBuffer,
VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
VkDependencyFlags dependencyFlags,
uint32_t memoryBarrierCount,
const VkMemoryBarrier* pMemoryBarriers,
uint32_t bufferMemoryBarrierCount,
const VkBufferMemoryBarrier* pBufferMemoryBarriers,
uint32_t imageMemoryBarrierCount,
const VkImageMemoryBarrier* pImageMemoryBarriers);
// Rust
pub fn cmd_pipeline_barrier(&self,
command_buffer: vk::CommandBuffer,
src_stage_mask: vk::PipelineStageFlags,
dst_stage_mask: vk::PipelineStageFlags,
dependency_flags: vk::DependencyFlags,
memory_barriers: &[vk::MemoryBarrier],
buffer_memory_barriers: &[vk::BufferMemoryBarrier],
image_memory_barriers: &[vk::ImageMemoryBarrier]);
device.cmd_pipeline_barrier(setup_command_buffer,
vk::PIPELINE_STAGE_TOP_OF_PIPE_BIT,
vk::PIPELINE_STAGE_TOP_OF_PIPE_BIT,
vk::DependencyFlags::empty(),
&[],
&[],
&[layout_transition_barrier]);
```
Ash still uses raw Vulkan structs. The only difference is type safety. Everything that can be an enum is an enum like `vk::StructureType`, flags are implemented similar to the `Bitflags` crate. Ash also follows the Rust style guide. The reason that Ash uses raw Vulkan structs is to be extensible, just like the Vulkan spec.
```Rust
let pool_create_info = vk::CommandPoolCreateInfo {
s_type: vk::StructureType::CommandPoolCreateInfo,
p_next: ptr::null(),
flags: vk::COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
queue_family_index: queue_family_index,
};
let pool = device.create_command_pool(&pool_create_info).unwrap();
```
Ash also takes care of loading the function pointers. Function pointers are split into 3 categories. Entry, Instance and Device. The reason for not loading it into a global is that in Vulkan you can have multiple devices and each device must load its own function pointers.
```Rust
// Looks for the vulkan lib in your path, alternatively you can supply the path explicitly.
let entry = Entry::load_vulkan().unwrap();
let instance: Instance = entry.create_instance(&create_info).expect("Instance creation error");
let device: Device = instance.create_device(pdevice, &device_create_info)
.unwrap();
```
You don't have to pass an Instance or Device handle anymore, this is done implicitly for you.
```Rust
// C
VkResult vkCreateCommandPool(
VkDevice device,
const VkCommandPoolCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkCommandPool* pCommandPool);
// Rust
pub fn create_command_pool(&self,
create_info: &vk::CommandPoolCreateInfo)
-> VkResult<vk::CommandPool>;
let pool = device.create_command_pool(&pool_create_info).unwrap();
```
```Rust
```
```Rust
```
## Complete
## In progress
- Wrapping the complete spec
- Optional extension loading
## Not started
- Custom allocators