Merge branch 'generator'

This commit is contained in:
Maik Klein 2018-11-12 13:10:52 +01:00
commit 69f3644362
40 changed files with 45861 additions and 6232 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
target
Cargo.lock
!examples/Cargo.lock
.idea

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "generator/Vulkan-Headers"]
path = generator/Vulkan-Headers
url = https://github.com/KhronosGroup/Vulkan-Headers

View file

@ -6,3 +6,4 @@ rust:
script:
- cargo build --manifest-path ash/Cargo.toml
- cargo build --manifest-path examples/Cargo.toml
- cargo build --manifest-path generator/Cargo.toml

View file

@ -2,4 +2,5 @@
members = [
"examples",
"ash",
"generator",
]

View file

@ -1,6 +1,45 @@
- 0.18.0: Fixes arm build => uses libc everywhere. Remove `AlignByteSlice`.
# 0.25.0
- 0.17.0: Refactor Align to use vk::DeviceSize.
* Adds support for Vulkan 1.1
- 0.16.0: `map_memory` now returns a void ptr. `ash::util::Align` is a helper struct that
* Constants are not represented as an `enum` anymore. Constants and flags are both represented as associated constants.
```Rust
flags: vk::COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
//to
flags: vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER_BIT,
```
* Pretty printing for flags
* Handles can be loaded from outside of ash. See `SomeHandle::from_raw`. This is useful if you need to interact with a C library.
* Removing versioning from ash. `V1_X` are now gone. Versioning had very little benefit in practice, `Entry`, `Instance` and `Device` are now version free. A custom loader can still be implemented. The various traits still remain `DeviceV1_0`.
* `vk.rs` is now generated from `vk.xml`
* Ash now includes all docs inside the `vk.xml`, and are visible in rustdoc.
* `Default` is now implemented for all structs
* There is now a builder pattern
* Handles are now `#[repr(transparent)]`
* Various bug fixes
# 0.18.0
* Fixes arm build => uses libc everywhere. Remove `AlignByteSlice`.
# 0.17.0
* Refactor Align to use vk::DeviceSize.
# 0.16.0
* `map_memory` now returns a void ptr
* `ash::util::Align` is a helper struct that
can write to aligned memory.

166
README.md
View file

@ -11,19 +11,15 @@ A very lightweight wrapper around Vulkan
[![Crates.io Version](https://img.shields.io/crates/v/ash.svg)](https://crates.io/crates/ash)
[![](https://tokei.rs/b1/github/maikklein/ash)](https://github.com/MaikKlein/ash)
## Stable yet?
I don't expect any big changes anymore. The library will still remain < 1.0 until I had time to use it in a real project. If you encounter any problems, feel free to open an [Issue](https://github.com/MaikKlein/ash/issues).
## Why Ash?
- [x] Lightweight Vulkan wrapper
- [x] Low overhead
- [x] Additional type safety
- [x] Trait based, version specific loader
## What does it do?
## Overview
- [x] A true Vulkan API without compromises
- [x] Convenience features that don't limit the functionality
- [x] Function pointer loading
- [x] No validation, everything is **unsafe**
- [x] Generated from `vk.xml`
## Features
### Explicit returns with `Result`
Functions return a `type VkResult<T> = Result<T, vk::Result>` instead of an error code. No mutable references for the output are required.
```Rust
// function signature
pub fn create_instance(&self,
@ -35,7 +31,8 @@ let instance = entry.create_instance(&create_info, None)
```
Always returns a `Vec<T>` for functions that output multiple values.
### Returns a `Vec<T>` (*when possible*) for functions that output multiple values.
```Rust
pub fn get_swapchain_images_khr(&self,
swapchain: vk::SwapchainKHR)
@ -43,23 +40,8 @@ pub fn get_swapchain_images_khr(&self,
let present_images = swapchain_loader.get_swapchain_images_khr(swapchain).unwrap();
```
### Slices
Ash always uses slices in functions.
### Slices in functions
```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,
@ -68,77 +50,61 @@ pub fn cmd_pipeline_barrier(&self,
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]);
```
### Type safety
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.
### Default implementation for all types
```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,
// No need to manually set the structure type
let desc_alloc_info = vk::DescriptorSetAllocateInfo {
descriptor_pool: self.pool,
descriptor_set_count: self.layouts.len() as u32,
p_set_layouts: self.layouts.as_ptr(),
..Default::default()
};
let pool = device.create_command_pool(&pool_create_info, None).unwrap();
```
### Builder pattern
```Rust
let pipeline_vertex_input_state_create_info = vk::PipelineVertexInputStateCreateInfo::builder()
.vertex_binding_descriptions(&Vertex::binding_descriptions())
.vertex_attribute_descriptions(&Vertex::attribute_descriptions()).build();
```
*Note*: No validation is done, the lifetimes only have to live as long as the builder object. It is the responsibility of the user to make sure that the pointers are valid.
### Flags and constants as associated constants
```Rust
dst_access_mask: vk::AccessFlags::COLOR_ATTACHMENT_READ
| vk::AccessFlags::COLOR_ATTACHMENT_WRITE,
```
Additionally pointers like `Instance`, `Device`, `Queue` etc are hidden behind a type. Those pointers can only be constructed from within `Ash` which eliminates some invalid API usage and has the benefit of making some functions in Vulkan **safe**.
```Rust
pipeline_bind_point: vk::PipelineBindPoint::GRAPHICS,
```
### Debug/Display for Flags
```Rust
let flag = vk::AccessFlags::COLOR_ATTACHMENT_READ
| vk::AccessFlags::COLOR_ATTACHMENT_WRITE;
println!("Debug: {:?}", flag);
println!("Display: {}", flag);
// Prints:
// Debug: AccessFlags(110000000)
// Display: COLOR_ATTACHMENT_READ | COLOR_ATTACHMENT_WRITE
```
### Interop
```Rust
PipelineBindPoint::from_raw(bindpoint);
```
### Function pointer loading
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 will load its own function pointers to achieve better performance. Click [here](https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/loader/LoaderAndLayerInterface.md) for more information.
Ash also manages multiple versions of Vulkan without any breakage. You will never run into any runtime error because you tried to access a function pointer that failed to load. Function pointers either load successfully or fail and return an error.
```Rust
use ash::{Device, Instance};
// Specifies the version that you want to load
use ash::version::V1_0;
// Those traits implement the version specific functions
use ash::version::{InstanceV1_0, DeviceV1_0, EntryV1_0};
let entry = Entry::<V1_0>::new().unwrap();
let instance = entry.create_instance(...).expect("Instance creation error.");
let device = instance.create_device(...).expect("Device creation error.");
```
A `V1_X` struct is used to indicate the version.
```Rust
// Define your types
type YourDevice = Device<V1_0>;
type YourInstance = Instance<V1_0>;
```
You can upgrade to a future version without any breakage.
```Rust
// For example, switching from V1_0 to V1_3 will not cause any breakage.
type YourDevice = Device<V1_3>;
type YourInstance = Instance<V1_3>;
```
A newer version can always be converted to an older version.
```Rust
let newer_device: Device<V1_5> = ...;
let older_device: Device<V1_0> = newer_device.into();
```
Or specify the *minimum* version that you require with a trait.
```Rust
fn do_something_with_a_device<Device: DeviceV1_0>(device: &Device){}
```
### Extension loading
Additionally, 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). You still have to tell Vulkan which instance or device extensions you want to load.
Additionally, 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).
```Rust
use ash::extensions::Swapchain;
let swapchain_loader = Swapchain::new(&instance, &device).expect("Unable to load swapchain");
let swapchain_loader = Swapchain::new(&instance, &device);
let swapchain = swapchain_loader.create_swapchain_khr(&swapchain_create_info).unwrap();
```
@ -156,16 +122,8 @@ fn extension_names() -> Vec<*const i8> {
```
### Implicit handles
You don't have to pass an Instance or Device handle anymore, this is done implicitly for you. This makes sure that you will always use the most optimal implementation for your `Device`.
Handles from Instance or Device are passed implicitly.
```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>;
@ -203,24 +161,6 @@ cargo run --bin texture
```
![texture](http://i.imgur.com/trow00H.png)
## Roadmap
### Extensions
- [x] Swapchain
- [x] Surface
- [x] XlibSurface
- [x] DebugReport
- [x] Win32Surface
- [x] MirSurface
- [x] XcbSurface
- [x] AndroidSurface
- [x] WaylandSurface
- [ ] Display
### In progress
- Wrapping the complete spec
- Version specific loader
## A thanks to
* [Api with no secrets](https://software.intel.com/en-us/articles/api-without-secrets-introduction-to-vulkan-part-1)

View file

@ -1,6 +1,6 @@
environment:
matrix:
- TARGET: 1.21.0-x86_64-pc-windows
- TARGET: 1.28.0-x86_64-pc-windows
COMPILER: msvc
install:
- if %COMPILER%==gnu choco install -y mingw

View file

@ -12,7 +12,6 @@ documentation = "https://docs.rs/ash"
[dependencies]
shared_library = "0.1.9"
lazy_static = "0.2.1"
libc = "0.2.26"
[features]
default = []

View file

@ -1,30 +1,31 @@
#![allow(dead_code)]
use vk;
use std::os::raw::c_void;
use std::ptr;
pub trait VkAllocation {
unsafe extern "system" fn allocation(
*mut (),
vk::size_t,
vk::size_t,
usize,
usize,
vk::SystemAllocationScope,
) -> *mut ();
unsafe extern "system" fn reallocation(
*mut vk::c_void,
*mut vk::c_void,
vk::size_t,
vk::size_t,
*mut c_void,
*mut c_void,
usize,
usize,
vk::SystemAllocationScope,
) -> *mut vk::c_void;
unsafe extern "system" fn free(*mut vk::c_void, *mut vk::c_void);
) -> *mut c_void;
unsafe extern "system" fn free(*mut c_void, *mut c_void);
unsafe extern "system" fn internal_allocation(
*mut vk::c_void,
vk::size_t,
*mut c_void,
usize,
vk::InternalAllocationType,
vk::SystemAllocationScope,
);
unsafe extern "system" fn internal_free(
*mut vk::c_void,
vk::size_t,
*mut c_void,
usize,
vk::InternalAllocationType,
vk::SystemAllocationScope,
);
@ -47,33 +48,33 @@ pub struct TestAlloc;
impl VkAllocation for TestAlloc {
unsafe extern "system" fn allocation(
_: *mut (),
_: vk::size_t,
_: vk::size_t,
_: usize,
_: usize,
_: vk::SystemAllocationScope,
) -> *mut () {
ptr::null_mut()
}
unsafe extern "system" fn reallocation(
_: *mut vk::c_void,
_: *mut vk::c_void,
_: vk::size_t,
_: vk::size_t,
_: *mut c_void,
_: *mut c_void,
_: usize,
_: usize,
_: vk::SystemAllocationScope,
) -> *mut vk::c_void {
) -> *mut c_void {
ptr::null_mut()
}
unsafe extern "system" fn free(_: *mut vk::c_void, _: *mut vk::c_void) {}
unsafe extern "system" fn free(_: *mut c_void, _: *mut c_void) {}
unsafe extern "system" fn internal_allocation(
_: *mut vk::c_void,
_: vk::size_t,
_: *mut c_void,
_: usize,
_: vk::InternalAllocationType,
_: vk::SystemAllocationScope,
) {
}
unsafe extern "system" fn internal_free(
_: *mut vk::c_void,
_: vk::size_t,
_: *mut c_void,
_: usize,
_: vk::InternalAllocationType,
_: vk::SystemAllocationScope,
) {
@ -82,33 +83,33 @@ impl VkAllocation for TestAlloc {
impl VkAllocation for DefaultAllocatorCallback {
unsafe extern "system" fn allocation(
_: *mut (),
_: vk::size_t,
_: vk::size_t,
_: usize,
_: usize,
_: vk::SystemAllocationScope,
) -> *mut () {
ptr::null_mut()
}
unsafe extern "system" fn reallocation(
_: *mut vk::c_void,
_: *mut vk::c_void,
_: vk::size_t,
_: vk::size_t,
_: *mut c_void,
_: *mut c_void,
_: usize,
_: usize,
_: vk::SystemAllocationScope,
) -> *mut vk::c_void {
) -> *mut c_void {
ptr::null_mut()
}
unsafe extern "system" fn free(_: *mut vk::c_void, _: *mut vk::c_void) {}
unsafe extern "system" fn free(_: *mut c_void, _: *mut c_void) {}
unsafe extern "system" fn internal_allocation(
_: *mut vk::c_void,
_: vk::size_t,
_: *mut c_void,
_: usize,
_: vk::InternalAllocationType,
_: vk::SystemAllocationScope,
) {
}
unsafe extern "system" fn internal_free(
_: *mut vk::c_void,
_: vk::size_t,
_: *mut c_void,
_: usize,
_: vk::InternalAllocationType,
_: vk::SystemAllocationScope,
) {

File diff suppressed because it is too large Load diff

View file

@ -1,45 +1,53 @@
use prelude::*;
use std::mem;
use std::ptr;
use vk;
use instance::Instance;
use prelude::*;
use shared_library::dynamic_library::DynamicLibrary;
use std::error::Error;
use std::fmt;
use std::mem;
use std::os::raw::c_char;
use std::path::Path;
use std::ptr;
use vk;
use RawPtr;
use version::{EntryLoader, FunctionPointers, InstanceLoader, V1_0};
use std::sync::Arc;
use libc;
#[cfg(windows)]
const LIB_PATH: &'static str = "vulkan-1.dll";
#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios", target_os = "android"))))]
#[cfg(
all(
unix,
not(
any(
target_os = "macos",
target_os = "ios",
target_os = "android"
)
)
)
)]
const LIB_PATH: &'static str = "libvulkan.so.1";
#[cfg(target_os = "android")]
const LIB_PATH: &'static str = "libvulkan.so";
#[cfg(target_os = "macos")]
const LIB_PATH: &'static str = "libvulkan.1.dylib";
#[cfg(target_os = "ios")]
#[cfg(any(target_os = "macos", target_os = "ios"))]
const LIB_PATH: &'static str = "libMoltenVK.dylib";
#[derive(Clone)]
pub struct EntryCustom<V: FunctionPointers, L> {
static_fn: vk::StaticFn,
entry_fn: V::EntryFp,
vk_lib: L,
lazy_static! {
static ref VK_LIB: Result<DynamicLibrary, String> =
DynamicLibrary::open(Some(&Path::new(LIB_PATH)));
}
#[derive(Clone)]
pub struct Entry {
static_fn: vk::StaticFn,
entry_fn_1_0: vk::EntryFnV1_0,
entry_fn_1_1: vk::EntryFnV1_1,
}
pub type Entry<V> = EntryCustom<V, Arc<DynamicLibrary>>;
#[derive(Debug)]
pub enum LoadingError {
LibraryLoadError(String),
EntryLoadError(Vec<&'static str>),
StaticLoadError(Vec<&'static str>),
}
#[derive(Debug)]
@ -69,32 +77,14 @@ impl Error for InstanceError {
#[allow(non_camel_case_types)]
pub trait EntryV1_0 {
type Fp: FunctionPointers;
type Instance;
fn fp_v1_0(&self) -> &vk::EntryFnV1_0;
fn static_fn(&self) -> &vk::StaticFn;
unsafe fn create_instance(
&self,
create_info: &vk::InstanceCreateInfo,
allocation_callbacks: Option<&vk::AllocationCallbacks>,
) -> Result<Instance<Self::Fp>, InstanceError> {
let mut instance: vk::Instance = mem::uninitialized();
let err_code = self.fp_v1_0().create_instance(
create_info,
allocation_callbacks.as_raw_ptr(),
&mut instance,
);
if err_code != vk::Result::Success {
return Err(InstanceError::VkError(err_code));
}
let instance_fp =
<Self::Fp as FunctionPointers>::InstanceFp::load(
&self.static_fn(),
instance,
).map_err(InstanceError::LoadError)?;
Ok(Instance::from_raw(instance, instance_fp))
}
) -> Result<Self::Instance, InstanceError>;
fn enumerate_instance_layer_properties(&self) -> VkResult<Vec<vk::LayerProperties>> {
unsafe {
let mut num = 0;
@ -102,16 +92,16 @@ pub trait EntryV1_0 {
.enumerate_instance_layer_properties(&mut num, ptr::null_mut());
let mut v = Vec::with_capacity(num as usize);
let err_code = self.fp_v1_0()
let err_code = self
.fp_v1_0()
.enumerate_instance_layer_properties(&mut num, v.as_mut_ptr());
v.set_len(num as usize);
match err_code {
vk::Result::Success => Ok(v),
vk::Result::SUCCESS => Ok(v),
_ => Err(err_code),
}
}
}
fn enumerate_instance_extension_properties(&self) -> VkResult<Vec<vk::ExtensionProperties>> {
unsafe {
let mut num = 0;
@ -128,7 +118,7 @@ pub trait EntryV1_0 {
);
data.set_len(num as usize);
match err_code {
vk::Result::Success => Ok(data),
vk::Result::SUCCESS => Ok(data),
_ => Err(err_code),
}
}
@ -137,56 +127,77 @@ pub trait EntryV1_0 {
fn get_instance_proc_addr(
&self,
instance: vk::Instance,
p_name: *const vk::c_char,
p_name: *const c_char,
) -> vk::PFN_vkVoidFunction {
unsafe { self.static_fn().get_instance_proc_addr(instance, p_name) }
}
}
impl<L> EntryV1_0 for EntryCustom<V1_0, L> {
type Fp = V1_0;
impl EntryV1_0 for Entry {
type Instance = Instance;
unsafe fn create_instance(
&self,
create_info: &vk::InstanceCreateInfo,
allocation_callbacks: Option<&vk::AllocationCallbacks>,
) -> Result<Self::Instance, InstanceError> {
let mut instance: vk::Instance = mem::uninitialized();
let err_code = self.fp_v1_0().create_instance(
create_info,
allocation_callbacks.as_raw_ptr(),
&mut instance,
);
if err_code != vk::Result::SUCCESS {
return Err(InstanceError::VkError(err_code));
}
Ok(Instance::load(&self.static_fn, instance))
}
fn fp_v1_0(&self) -> &vk::EntryFnV1_0 {
self.entry_fn.fp_v1_0()
&self.entry_fn_1_0
}
fn static_fn(&self) -> &vk::StaticFn {
&self.static_fn
}
}
impl<V: FunctionPointers, L> EntryCustom<V, L> {
pub fn new_custom<OpenFunc, LoadFunc>(o: OpenFunc, mut l: LoadFunc) -> Result<Self, LoadingError>
where
OpenFunc: FnOnce() -> Result<L, LoadingError>,
LoadFunc: FnMut(&mut L, &::std::ffi::CStr) -> *const libc::c_void,
{
let mut vk_lib = o()?;
let static_fn =
vk::StaticFn::load(|name| l(&mut vk_lib, name)).map_err(LoadingError::StaticLoadError)?;
impl Entry {
pub fn new() -> Result<Self, LoadingError> {
let lib = VK_LIB
.as_ref()
.map_err(|err| LoadingError::LibraryLoadError(err.clone()))?;
let entry_fn =
unsafe { V::EntryFp::load(&static_fn) }.map_err(LoadingError::EntryLoadError)?;
let static_fn = vk::StaticFn::load(|name| unsafe {
lib.symbol(&*name.to_string_lossy())
.unwrap_or(ptr::null_mut())
});
Ok(EntryCustom {
let entry_fn_1_0 = vk::EntryFnV1_0::load(|name| unsafe {
mem::transmute(static_fn.get_instance_proc_addr(vk::Instance::null(), name.as_ptr()))
});
let entry_fn_1_1 = vk::EntryFnV1_1::load(|name| unsafe {
mem::transmute(static_fn.get_instance_proc_addr(vk::Instance::null(), name.as_ptr()))
});
Ok(Entry {
static_fn,
entry_fn,
vk_lib,
entry_fn_1_0,
entry_fn_1_1,
})
}
}
impl<V: FunctionPointers> Entry<V> {
pub fn new() -> Result<Self, LoadingError> {
Self::new_custom(
|| {
DynamicLibrary::open(Some(&Path::new(LIB_PATH)))
.map_err(|err| LoadingError::LibraryLoadError(err.clone()))
.map(|dl| Arc::new(dl))
},
|vk_lib, name| unsafe {
vk_lib
.symbol(&*name.to_string_lossy())
.unwrap_or(ptr::null_mut())
},
)
#[allow(non_camel_case_types)]
pub trait EntryV1_1: EntryV1_0 {
fn fp_v1_1(&self) -> &vk::EntryFnV1_1;
fn enumerate_instance_version(&self) -> VkResult<u32> {
unsafe {
let mut api_version = 0;
let err_code = self.fp_v1_1().enumerate_instance_version(&mut api_version);
match err_code {
vk::Result::SUCCESS => Ok(api_version),
_ => Err(err_code),
}
}
}
}

View file

@ -1,32 +1,29 @@
#![allow(dead_code)]
use prelude::*;
use std::mem;
use vk;
use std::ffi::CStr;
use RawPtr;
use std::mem;
use version::{EntryV1_0, InstanceV1_0};
use vk;
use RawPtr;
#[derive(Clone)]
pub struct AndroidSurface {
handle: vk::Instance,
android_surface_fn: vk::AndroidSurfaceFn,
android_surface_fn: vk::KhrAndroidSurfaceFn,
}
impl AndroidSurface {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<AndroidSurface, Vec<&'static str>> {
let surface_fn = vk::AndroidSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(
instance.handle(),
name.as_ptr(),
))
})?;
Ok(AndroidSurface {
) -> AndroidSurface {
let surface_fn = vk::KhrAndroidSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
});
AndroidSurface {
handle: instance.handle(),
android_surface_fn: surface_fn,
})
}
}
pub fn name() -> &'static CStr {
@ -46,7 +43,7 @@ impl AndroidSurface {
&mut surface,
);
match err_code {
vk::Result::Success => Ok(surface),
vk::Result::SUCCESS => Ok(surface),
_ => Err(err_code),
}
}

View file

@ -1,29 +1,26 @@
#![allow(dead_code)]
use prelude::*;
use std::mem;
use vk;
use std::ffi::CStr;
use version::{InstanceV1_0, DeviceV1_0};
use std::mem;
use version::{DeviceV1_0, InstanceV1_0};
use vk;
#[derive(Clone)]
pub struct DebugMarker {
debug_marker_fn: vk::DebugMarkerFn,
debug_marker_fn: vk::ExtDebugMarkerFn,
}
impl DebugMarker {
pub fn new<I: InstanceV1_0, D: DeviceV1_0>(
instance: &I,
device: &D
) -> Result<DebugMarker, Vec<&'static str>> {
let debug_marker_fn = vk::DebugMarkerFn::load(|name| unsafe {
mem::transmute(instance.get_device_proc_addr(
device.handle(),
name.as_ptr(),
))
})?;
Ok(DebugMarker {
device: &D,
) -> DebugMarker {
let debug_marker_fn = vk::ExtDebugMarkerFn::load(|name| unsafe {
mem::transmute(instance.get_device_proc_addr(device.handle(), name.as_ptr()))
});
DebugMarker {
debug_marker_fn: debug_marker_fn,
})
}
}
pub fn name() -> &'static CStr {
@ -33,46 +30,37 @@ impl DebugMarker {
pub unsafe fn debug_marker_set_object_name_ext(
&self,
device: vk::Device,
name_info: &vk::DebugMarkerObjectNameInfoEXT
name_info: &vk::DebugMarkerObjectNameInfoEXT,
) -> VkResult<()> {
let err_code = self.debug_marker_fn.debug_marker_set_object_name_ext(
device,
name_info
);
let err_code = self
.debug_marker_fn
.debug_marker_set_object_name_ext(device, name_info);
match err_code {
vk::Result::Success => Ok(()),
_ => Err(err_code)
vk::Result::SUCCESS => Ok(()),
_ => Err(err_code),
}
}
pub unsafe fn cmd_debug_marker_begin_ext(
&self,
command_buffer: vk::CommandBuffer,
marker_info: &vk::DebugMarkerMarkerInfoEXT
marker_info: &vk::DebugMarkerMarkerInfoEXT,
) {
self.debug_marker_fn.cmd_debug_marker_begin_ext(
command_buffer,
marker_info
);
self.debug_marker_fn
.cmd_debug_marker_begin_ext(command_buffer, marker_info);
}
pub unsafe fn cmd_debug_marker_end_ext(
&self,
command_buffer: vk::CommandBuffer,
) {
self.debug_marker_fn.cmd_debug_marker_end_ext(
command_buffer,
);
pub unsafe fn cmd_debug_marker_end_ext(&self, command_buffer: vk::CommandBuffer) {
self.debug_marker_fn
.cmd_debug_marker_end_ext(command_buffer);
}
pub unsafe fn cmd_debug_marker_insert_ext(
&self,
command_buffer: vk::CommandBuffer,
marker_info: &vk::DebugMarkerMarkerInfoEXT
marker_info: &vk::DebugMarkerMarkerInfoEXT,
) {
self.debug_marker_fn.cmd_debug_marker_insert_ext(
command_buffer,
marker_info
);
self.debug_marker_fn
.cmd_debug_marker_insert_ext(command_buffer, marker_info);
}
}

View file

@ -1,32 +1,29 @@
#![allow(dead_code)]
use prelude::*;
use std::mem;
use vk;
use std::ffi::CStr;
use RawPtr;
use std::mem;
use version::{EntryV1_0, InstanceV1_0};
use vk;
use RawPtr;
#[derive(Clone)]
pub struct DebugReport {
handle: vk::Instance,
debug_report_fn: vk::DebugReportFn,
debug_report_fn: vk::ExtDebugReportFn,
}
impl DebugReport {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<DebugReport, Vec<&'static str>> {
let debug_report_fn = vk::DebugReportFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(
instance.handle(),
name.as_ptr(),
))
})?;
Ok(DebugReport {
) -> DebugReport {
let debug_report_fn = vk::ExtDebugReportFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
});
DebugReport {
handle: instance.handle(),
debug_report_fn: debug_report_fn,
})
debug_report_fn,
}
}
pub fn name() -> &'static CStr {
@ -58,7 +55,7 @@ impl DebugReport {
&mut debug_cb,
);
match err_code {
vk::Result::Success => Ok(debug_cb),
vk::Result::SUCCESS => Ok(debug_cb),
_ => Err(err_code),
}
}

View file

@ -0,0 +1,145 @@
#![allow(dead_code)]
use prelude::*;
use std::ffi::CStr;
use std::mem;
use version::{EntryV1_0, InstanceV1_0};
use {vk, RawPtr};
#[derive(Clone)]
pub struct DebugUtils {
handle: vk::Instance,
debug_utils_fn: vk::ExtDebugUtilsFn,
}
impl DebugUtils {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> DebugUtils {
let debug_utils_fn = vk::ExtDebugUtilsFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
});
DebugUtils {
handle: instance.handle(),
debug_utils_fn,
}
}
pub fn name() -> &'static CStr {
CStr::from_bytes_with_nul(b"VK_EXT_debug_utils\0").expect("Wrong extension string")
}
pub unsafe fn debug_utils_set_object_name_ext(
&self,
device: vk::Device,
name_info: &vk::DebugUtilsObjectNameInfoEXT,
) -> VkResult<()> {
let err_code = self.debug_utils_fn.set_debug_utils_object_name_ext(device, name_info);
match err_code {
vk::Result::SUCCESS => Ok(()),
_ => Err(err_code),
}
}
pub unsafe fn debug_utils_set_object_tag_ext(
&self,
device: vk::Device,
tag_info: &vk::DebugUtilsObjectTagInfoEXT,
) -> VkResult<()> {
let err_code = self.debug_utils_fn.set_debug_utils_object_tag_ext(device, tag_info);
match err_code {
vk::Result::SUCCESS => Ok(()),
_ => Err(err_code),
}
}
pub unsafe fn cmd_begin_debug_utils_label_ext(
&self,
command_buffer: vk::CommandBuffer,
label: &vk::DebugUtilsLabelEXT,
) {
self.debug_utils_fn
.cmd_begin_debug_utils_label_ext(command_buffer, label);
}
pub unsafe fn cmd_end_debug_utils_label_ext(&self, command_buffer: vk::CommandBuffer) {
self.debug_utils_fn
.cmd_end_debug_utils_label_ext(command_buffer);
}
pub unsafe fn cmd_insert_debug_utils_label_ext(
&self,
command_buffer: vk::CommandBuffer,
label: &vk::DebugUtilsLabelEXT,
) {
self.debug_utils_fn
.cmd_insert_debug_utils_label_ext(command_buffer, label);
}
pub unsafe fn queue_begin_debug_utils_label_ext(
&self,
queue: vk::Queue,
label: &vk::DebugUtilsLabelEXT,
) {
self.debug_utils_fn
.queue_begin_debug_utils_label_ext(queue, label);
}
pub unsafe fn queue_end_debug_utils_label_ext(&self, queue: vk::Queue) {
self.debug_utils_fn.queue_end_debug_utils_label_ext(queue);
}
pub unsafe fn queue_insert_debug_utils_label_ext(
&self,
queue: vk::Queue,
label: &vk::DebugUtilsLabelEXT,
) {
self.debug_utils_fn
.queue_insert_debug_utils_label_ext(queue, label);
}
pub unsafe fn create_debug_utils_messenger_ext(
&self,
create_info: &vk::DebugUtilsMessengerCreateInfoEXT,
allocator: Option<&vk::AllocationCallbacks>,
) -> VkResult<vk::DebugUtilsMessengerEXT> {
let mut messenger = mem::uninitialized();
let err_code = self.debug_utils_fn.create_debug_utils_messenger_ext(
self.handle,
create_info,
allocator.as_raw_ptr(),
&mut messenger,
);
match err_code {
vk::Result::SUCCESS => Ok(messenger),
_ => Err(err_code),
}
}
pub unsafe fn destroy_debug_utils_messenger_ext(
&self,
messenger: vk::DebugUtilsMessengerEXT,
allocator: Option<&vk::AllocationCallbacks>,
) {
self.debug_utils_fn.destroy_debug_utils_messenger_ext(
self.handle,
messenger,
allocator.as_raw_ptr(),
);
}
pub unsafe fn submit_debug_utils_message_ext(
&self,
instance: vk::Instance,
message_severity: vk::DebugUtilsMessageSeverityFlagsEXT,
message_types: vk::DebugUtilsMessageTypeFlagsEXT,
callback_data: &vk::DebugUtilsMessengerCallbackDataEXT,
) {
self.debug_utils_fn.submit_debug_utils_message_ext(
instance,
message_severity,
message_types,
callback_data,
);
}
}

View file

@ -1,32 +1,29 @@
#![allow(dead_code)]
use prelude::*;
use std::mem;
use vk;
use std::ffi::CStr;
use std::mem;
use version::{DeviceV1_0, InstanceV1_0};
use vk;
use RawPtr;
use version::{InstanceV1_0, DeviceV1_0};
#[derive(Clone)]
pub struct DisplaySwapchain {
handle: vk::Device,
swapchain_fn: vk::DisplaySwapchainFn,
swapchain_fn: vk::KhrDisplaySwapchainFn,
}
impl DisplaySwapchain {
pub fn new<I: InstanceV1_0, D: DeviceV1_0>(
instance: &I,
device: &D,
) -> Result<DisplaySwapchain, Vec<&'static str>> {
let swapchain_fn = vk::DisplaySwapchainFn::load(|name| unsafe {
mem::transmute(instance.get_device_proc_addr(
device.handle(),
name.as_ptr(),
))
})?;
Ok(DisplaySwapchain {
) -> DisplaySwapchain {
let swapchain_fn = vk::KhrDisplaySwapchainFn::load(|name| unsafe {
mem::transmute(instance.get_device_proc_addr(device.handle(), name.as_ptr()))
});
DisplaySwapchain {
handle: device.handle(),
swapchain_fn: swapchain_fn,
})
}
}
pub fn name() -> &'static CStr {
@ -48,7 +45,7 @@ impl DisplaySwapchain {
);
swapchains.set_len(create_infos.len());
match err_code {
vk::Result::Success => Ok(swapchains),
vk::Result::SUCCESS => Ok(swapchains),
_ => Err(err_code),
}
}

View file

@ -1,32 +1,29 @@
#![allow(dead_code)]
use prelude::*;
use std::mem;
use vk;
use std::ffi::CStr;
use RawPtr;
use std::mem;
use version::{EntryV1_0, InstanceV1_0};
use vk;
use RawPtr;
#[derive(Clone)]
pub struct IOSSurface {
handle: vk::Instance,
ios_surface_fn: vk::IOSSurfaceFn,
ios_surface_fn: vk::MvkIosSurfaceFn,
}
impl IOSSurface {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<IOSSurface, Vec<&'static str>> {
let surface_fn = vk::IOSSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(
instance.handle(),
name.as_ptr(),
))
})?;
Ok(IOSSurface {
) -> IOSSurface{
let surface_fn = vk::MvkIosSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
});
IOSSurface {
handle: instance.handle(),
ios_surface_fn: surface_fn,
})
}
}
pub fn name() -> &'static CStr {
@ -46,7 +43,7 @@ impl IOSSurface {
&mut surface,
);
match err_code {
vk::Result::Success => Ok(surface),
vk::Result::SUCCESS => Ok(surface),
_ => Err(err_code),
}
}

View file

@ -1,52 +1,49 @@
#![allow(dead_code)]
use prelude::*;
use std::mem;
use vk;
use std::ffi::CStr;
use RawPtr;
use std::mem;
use version::{EntryV1_0, InstanceV1_0};
use vk;
use RawPtr;
#[derive(Clone)]
pub struct MacOSSurface {
handle: vk::Instance,
macos_surface_fn: vk::MacOSSurfaceFn,
macos_surface_fn: vk::MvkMacosSurfaceFn,
}
impl MacOSSurface {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<MacOSSurface, Vec<&'static str>> {
let surface_fn = vk::MacOSSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(
instance.handle(),
name.as_ptr(),
))
})?;
Ok(MacOSSurface {
) -> MacOSSurface {
let surface_fn = vk::MvkMacosSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
});
MacOSSurface {
handle: instance.handle(),
macos_surface_fn: surface_fn,
})
}
}
pub fn name() -> &'static CStr {
CStr::from_bytes_with_nul(b"VK_MVK_macos_surface\0").expect("Wrong extension string")
}
pub unsafe fn create_macos_surface_mvk(
pub unsafe fn create_mac_os_surface_mvk(
&self,
create_info: &vk::MacOSSurfaceCreateInfoMVK,
allocation_callbacks: Option<&vk::AllocationCallbacks>,
) -> VkResult<vk::SurfaceKHR> {
let mut surface = mem::uninitialized();
let err_code = self.macos_surface_fn.create_macos_surface_mvk(
let err_code = self.macos_surface_fn.create_mac_os_surface_mvk(
self.handle,
create_info,
allocation_callbacks.as_raw_ptr(),
&mut surface,
);
match err_code {
vk::Result::Success => Ok(surface),
vk::Result::SUCCESS => Ok(surface),
_ => Err(err_code),
}
}

View file

@ -1,53 +0,0 @@
#![allow(dead_code)]
use prelude::*;
use std::mem;
use vk;
use std::ffi::CStr;
use RawPtr;
use version::{EntryV1_0, InstanceV1_0};
#[derive(Clone)]
pub struct MirSurface {
handle: vk::Instance,
mir_surface_fn: vk::MirSurfaceFn,
}
impl MirSurface {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<MirSurface, Vec<&'static str>> {
let surface_fn = vk::MirSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(
instance.handle(),
name.as_ptr(),
))
})?;
Ok(MirSurface {
handle: instance.handle(),
mir_surface_fn: surface_fn,
})
}
pub fn name() -> &'static CStr {
CStr::from_bytes_with_nul(b"VK_KHR_mir_surface\0").expect("Wrong extension string")
}
pub unsafe fn create_mir_surface_khr(
&self,
create_info: &vk::MirSurfaceCreateInfoKHR,
allocation_callbacks: Option<&vk::AllocationCallbacks>,
) -> VkResult<vk::SurfaceKHR> {
let mut surface = mem::uninitialized();
let err_code = self.mir_surface_fn.create_mir_surface_khr(
self.handle,
create_info,
allocation_callbacks.as_raw_ptr(),
&mut surface,
);
match err_code {
vk::Result::Success => Ok(surface),
_ => Err(err_code),
}
}
}

View file

@ -1,27 +1,27 @@
pub use self::swapchain::Swapchain;
pub use self::display_swapchain::DisplaySwapchain;
pub use self::surface::Surface;
pub use self::xlib_surface::XlibSurface;
pub use self::android_surface::AndroidSurface;
pub use self::debug_marker::DebugMarker;
pub use self::debug_report::DebugReport;
pub use self::win32_surface::Win32Surface;
pub use self::mir_surface::MirSurface;
pub use self::xcb_surface::XcbSurface;
pub use self::wayland_surface::WaylandSurface;
pub use self::android_surface::AndroidSurface;
pub use self::macos_surface::MacOSSurface;
pub use self::debug_utils::DebugUtils;
pub use self::display_swapchain::DisplaySwapchain;
pub use self::ios_surface::IOSSurface;
pub use self::macos_surface::MacOSSurface;
pub use self::surface::Surface;
pub use self::swapchain::Swapchain;
pub use self::wayland_surface::WaylandSurface;
pub use self::win32_surface::Win32Surface;
pub use self::xcb_surface::XcbSurface;
pub use self::xlib_surface::XlibSurface;
mod swapchain;
mod display_swapchain;
mod surface;
mod xlib_surface;
mod win32_surface;
mod android_surface;
mod debug_marker;
mod debug_report;
mod mir_surface;
mod android_surface;
mod wayland_surface;
mod xcb_surface;
mod macos_surface;
mod debug_utils;
mod display_swapchain;
mod ios_surface;
mod macos_surface;
mod surface;
mod swapchain;
mod wayland_surface;
mod win32_surface;
mod xcb_surface;
mod xlib_surface;

View file

@ -1,131 +1,123 @@
#![allow(dead_code)]
use prelude::*;
use std::ptr;
use std::mem;
use vk;
use std::ffi::CStr;
use RawPtr;
use std::mem;
use std::ptr;
use version::{EntryV1_0, InstanceV1_0};
use vk;
use RawPtr;
#[derive(Clone)]
pub struct Surface {
handle: vk::Instance,
surface_fn: vk::SurfaceFn,
surface_fn: vk::KhrSurfaceFn,
}
impl Surface {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<Surface, Vec<&'static str>> {
let surface_fn = vk::SurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(
instance.handle(),
name.as_ptr(),
))
})?;
Ok(Surface {
) -> Surface {
let surface_fn = vk::KhrSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
});
Surface {
handle: instance.handle(),
surface_fn: surface_fn,
})
}
}
pub fn name() -> &'static CStr {
CStr::from_bytes_with_nul(b"VK_KHR_surface\0").expect("Wrong extension string")
}
pub fn get_physical_device_surface_support_khr(
pub unsafe fn get_physical_device_surface_support_khr(
&self,
physical_device: vk::PhysicalDevice,
queue_index: vk::uint32_t,
queue_index: u32,
surface: vk::SurfaceKHR,
) -> bool {
unsafe {
let mut b = mem::uninitialized();
self.surface_fn.get_physical_device_surface_support_khr(
physical_device,
queue_index,
surface,
&mut b,
);
b > 0
}
let mut b = mem::uninitialized();
self.surface_fn.get_physical_device_surface_support_khr(
physical_device,
queue_index,
surface,
&mut b,
);
b > 0
}
pub fn get_physical_device_surface_present_modes_khr(
pub unsafe fn get_physical_device_surface_present_modes_khr(
&self,
physical_device: vk::PhysicalDevice,
surface: vk::SurfaceKHR,
) -> VkResult<Vec<vk::PresentModeKHR>> {
unsafe {
let mut count = 0;
self.surface_fn
.get_physical_device_surface_present_modes_khr(
physical_device,
surface,
&mut count,
ptr::null_mut(),
);
let mut v = Vec::with_capacity(count as usize);
let err_code = self.surface_fn
.get_physical_device_surface_present_modes_khr(
physical_device,
surface,
&mut count,
v.as_mut_ptr(),
);
v.set_len(count as usize);
match err_code {
vk::Result::Success => Ok(v),
_ => Err(err_code),
}
}
}
pub fn get_physical_device_surface_capabilities_khr(
&self,
physical_device: vk::PhysicalDevice,
surface: vk::SurfaceKHR,
) -> VkResult<vk::SurfaceCapabilitiesKHR> {
unsafe {
let mut surface_capabilities = mem::uninitialized();
let err_code = self.surface_fn
.get_physical_device_surface_capabilities_khr(
physical_device,
surface,
&mut surface_capabilities,
);
match err_code {
vk::Result::Success => Ok(surface_capabilities),
_ => Err(err_code),
}
}
}
pub fn get_physical_device_surface_formats_khr(
&self,
physical_device: vk::PhysicalDevice,
surface: vk::SurfaceKHR,
) -> VkResult<Vec<vk::SurfaceFormatKHR>> {
unsafe {
let mut count = 0;
self.surface_fn.get_physical_device_surface_formats_khr(
let mut count = 0;
self.surface_fn
.get_physical_device_surface_present_modes_khr(
physical_device,
surface,
&mut count,
ptr::null_mut(),
);
let mut v = Vec::with_capacity(count as usize);
let err_code = self.surface_fn.get_physical_device_surface_formats_khr(
let mut v = Vec::with_capacity(count as usize);
let err_code = self
.surface_fn
.get_physical_device_surface_present_modes_khr(
physical_device,
surface,
&mut count,
v.as_mut_ptr(),
);
v.set_len(count as usize);
match err_code {
vk::Result::Success => Ok(v),
_ => Err(err_code),
}
v.set_len(count as usize);
match err_code {
vk::Result::SUCCESS => Ok(v),
_ => Err(err_code),
}
}
pub unsafe fn get_physical_device_surface_capabilities_khr(
&self,
physical_device: vk::PhysicalDevice,
surface: vk::SurfaceKHR,
) -> VkResult<vk::SurfaceCapabilitiesKHR> {
let mut surface_capabilities = mem::uninitialized();
let err_code = self
.surface_fn
.get_physical_device_surface_capabilities_khr(
physical_device,
surface,
&mut surface_capabilities,
);
match err_code {
vk::Result::SUCCESS => Ok(surface_capabilities),
_ => Err(err_code),
}
}
pub unsafe fn get_physical_device_surface_formats_khr(
&self,
physical_device: vk::PhysicalDevice,
surface: vk::SurfaceKHR,
) -> VkResult<Vec<vk::SurfaceFormatKHR>> {
let mut count = 0;
self.surface_fn.get_physical_device_surface_formats_khr(
physical_device,
surface,
&mut count,
ptr::null_mut(),
);
let mut v = Vec::with_capacity(count as usize);
let err_code = self.surface_fn.get_physical_device_surface_formats_khr(
physical_device,
surface,
&mut count,
v.as_mut_ptr(),
);
v.set_len(count as usize);
match err_code {
vk::Result::SUCCESS => Ok(v),
_ => Err(err_code),
}
}

View file

@ -1,33 +1,30 @@
#![allow(dead_code)]
use prelude::*;
use std::ptr;
use std::mem;
use vk;
use std::ffi::CStr;
use std::mem;
use std::ptr;
use version::{DeviceV1_0, InstanceV1_0};
use vk;
use RawPtr;
use version::{InstanceV1_0, DeviceV1_0};
#[derive(Clone)]
pub struct Swapchain {
handle: vk::Device,
swapchain_fn: vk::SwapchainFn,
swapchain_fn: vk::KhrSwapchainFn,
}
impl Swapchain {
pub fn new<I: InstanceV1_0, D: DeviceV1_0>(
instance: &I,
device: &D,
) -> Result<Swapchain, Vec<&'static str>> {
let swapchain_fn = vk::SwapchainFn::load(|name| unsafe {
mem::transmute(instance.get_device_proc_addr(
device.handle(),
name.as_ptr(),
))
})?;
Ok(Swapchain {
) -> Swapchain {
let swapchain_fn = vk::KhrSwapchainFn::load(|name| unsafe {
mem::transmute(instance.get_device_proc_addr(device.handle(), name.as_ptr()))
});
Swapchain {
handle: device.handle(),
swapchain_fn: swapchain_fn,
})
}
}
pub fn name() -> &'static CStr {
@ -46,13 +43,14 @@ impl Swapchain {
);
}
/// On success, returns the next image's index and whether the swapchain is suboptimal for the surface.
pub unsafe fn acquire_next_image_khr(
&self,
swapchain: vk::SwapchainKHR,
timeout: vk::uint64_t,
timeout: u64,
semaphore: vk::Semaphore,
fence: vk::Fence,
) -> VkResult<vk::uint32_t> {
) -> VkResult<(u32, bool)> {
let mut index = mem::uninitialized();
let err_code = self.swapchain_fn.acquire_next_image_khr(
self.handle,
@ -63,7 +61,8 @@ impl Swapchain {
&mut index,
);
match err_code {
vk::Result::Success => Ok(index),
vk::Result::SUCCESS => Ok((index, false)),
vk::Result::SUBOPTIMAL_KHR => Ok((index, true)),
_ => Err(err_code),
}
}
@ -81,48 +80,48 @@ impl Swapchain {
&mut swapchain,
);
match err_code {
vk::Result::Success => Ok(swapchain),
vk::Result::SUCCESS => Ok(swapchain),
_ => Err(err_code),
}
}
/// On success, returns whether the swapchain is suboptimal for the surface.
pub unsafe fn queue_present_khr(
&self,
queue: vk::Queue,
create_info: &vk::PresentInfoKHR,
) -> VkResult<()> {
) -> VkResult<bool> {
let err_code = self.swapchain_fn.queue_present_khr(queue, create_info);
match err_code {
vk::Result::Success => Ok(()),
vk::Result::SUCCESS => Ok(false),
vk::Result::SUBOPTIMAL_KHR => Ok(true),
_ => Err(err_code),
}
}
pub fn get_swapchain_images_khr(
pub unsafe fn get_swapchain_images_khr(
&self,
swapchain: vk::SwapchainKHR,
) -> VkResult<Vec<vk::Image>> {
unsafe {
let mut count = 0;
self.swapchain_fn.get_swapchain_images_khr(
self.handle,
swapchain,
&mut count,
ptr::null_mut(),
);
let mut count = 0;
self.swapchain_fn.get_swapchain_images_khr(
self.handle,
swapchain,
&mut count,
ptr::null_mut(),
);
let mut v = Vec::with_capacity(count as vk::size_t);
let err_code = self.swapchain_fn.get_swapchain_images_khr(
self.handle,
swapchain,
&mut count,
v.as_mut_ptr(),
);
v.set_len(count as vk::size_t);
match err_code {
vk::Result::Success => Ok(v),
_ => Err(err_code),
}
let mut v = Vec::with_capacity(count as usize);
let err_code = self.swapchain_fn.get_swapchain_images_khr(
self.handle,
swapchain,
&mut count,
v.as_mut_ptr(),
);
v.set_len(count as usize);
match err_code {
vk::Result::SUCCESS => Ok(v),
_ => Err(err_code),
}
}
}

View file

@ -1,32 +1,29 @@
#![allow(dead_code)]
use prelude::*;
use std::mem;
use vk;
use std::ffi::CStr;
use RawPtr;
use std::mem;
use version::{EntryV1_0, InstanceV1_0};
use vk;
use RawPtr;
#[derive(Clone)]
pub struct WaylandSurface {
handle: vk::Instance,
wayland_surface_fn: vk::WaylandSurfaceFn,
wayland_surface_fn: vk::KhrWaylandSurfaceFn,
}
impl WaylandSurface {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<WaylandSurface, Vec<&'static str>> {
let surface_fn = vk::WaylandSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(
instance.handle(),
name.as_ptr(),
))
})?;
Ok(WaylandSurface {
) -> WaylandSurface {
let surface_fn = vk::KhrWaylandSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
});
WaylandSurface {
handle: instance.handle(),
wayland_surface_fn: surface_fn,
})
}
}
pub fn name() -> &'static CStr {
@ -46,7 +43,7 @@ impl WaylandSurface {
&mut surface,
);
match err_code {
vk::Result::Success => Ok(surface),
vk::Result::SUCCESS => Ok(surface),
_ => Err(err_code),
}
}

View file

@ -1,32 +1,29 @@
#![allow(dead_code)]
use prelude::*;
use std::mem;
use vk;
use std::ffi::CStr;
use RawPtr;
use std::mem;
use version::{EntryV1_0, InstanceV1_0};
use vk;
use RawPtr;
#[derive(Clone)]
pub struct Win32Surface {
handle: vk::Instance,
win32_surface_fn: vk::Win32SurfaceFn,
win32_surface_fn: vk::KhrWin32SurfaceFn,
}
impl Win32Surface {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<Win32Surface, Vec<&'static str>> {
let surface_fn = vk::Win32SurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(
instance.handle(),
name.as_ptr(),
))
})?;
Ok(Win32Surface {
) -> Win32Surface {
let surface_fn = vk::KhrWin32SurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
});
Win32Surface {
handle: instance.handle(),
win32_surface_fn: surface_fn,
})
}
}
pub fn name() -> &'static CStr {
@ -46,7 +43,7 @@ impl Win32Surface {
&mut surface,
);
match err_code {
vk::Result::Success => Ok(surface),
vk::Result::SUCCESS => Ok(surface),
_ => Err(err_code),
}
}

View file

@ -1,32 +1,29 @@
#![allow(dead_code)]
use prelude::*;
use std::mem;
use vk;
use std::ffi::CStr;
use RawPtr;
use std::mem;
use version::{EntryV1_0, InstanceV1_0};
use vk;
use RawPtr;
#[derive(Clone)]
pub struct XcbSurface {
handle: vk::Instance,
xcb_surface_fn: vk::XcbSurfaceFn,
xcb_surface_fn: vk::KhrXcbSurfaceFn,
}
impl XcbSurface {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<XcbSurface, Vec<&'static str>> {
let surface_fn = vk::XcbSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(
instance.handle(),
name.as_ptr(),
))
})?;
Ok(XcbSurface {
) -> XcbSurface {
let surface_fn = vk::KhrXcbSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
});
XcbSurface {
handle: instance.handle(),
xcb_surface_fn: surface_fn,
})
}
}
pub fn name() -> &'static CStr {
@ -46,7 +43,7 @@ impl XcbSurface {
&mut surface,
);
match err_code {
vk::Result::Success => Ok(surface),
vk::Result::SUCCESS => Ok(surface),
_ => Err(err_code),
}
}

View file

@ -1,32 +1,29 @@
#![allow(dead_code)]
use prelude::*;
use std::mem;
use vk;
use std::ffi::CStr;
use RawPtr;
use std::mem;
use version::{EntryV1_0, InstanceV1_0};
use vk;
use RawPtr;
#[derive(Clone)]
pub struct XlibSurface {
handle: vk::Instance,
xlib_surface_fn: vk::XlibSurfaceFn,
xlib_surface_fn: vk::KhrXlibSurfaceFn,
}
impl XlibSurface {
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
entry: &E,
instance: &I,
) -> Result<XlibSurface, Vec<&'static str>> {
let surface_fn = vk::XlibSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(
instance.handle(),
name.as_ptr(),
))
})?;
Ok(XlibSurface {
) -> XlibSurface {
let surface_fn = vk::KhrXlibSurfaceFn::load(|name| unsafe {
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
});
XlibSurface {
handle: instance.handle(),
xlib_surface_fn: surface_fn,
})
}
}
pub fn name() -> &'static CStr {
@ -46,7 +43,7 @@ impl XlibSurface {
&mut surface,
);
match err_code {
vk::Result::Success => Ok(surface),
vk::Result::SUCCESS => Ok(surface),
_ => Err(err_code),
}
}

View file

@ -1,80 +1,43 @@
#![allow(dead_code)]
use prelude::*;
use std::ptr;
use std::mem;
use vk;
use device::Device;
use std::error::Error;
use std::fmt;
use prelude::*;
use std::mem;
use std::os::raw::c_char;
use std::ptr;
use vk;
use RawPtr;
use version::{FunctionPointers, V1_0};
use version::DeviceLoader;
#[derive(Debug)]
pub enum DeviceError {
LoadError(Vec<&'static str>),
VkError(vk::Result),
}
impl fmt::Display for DeviceError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "DeviceError::{:?}", self)
}
}
impl Error for DeviceError {
fn description(&self) -> &str {
"DeviceErrorr"
}
fn cause(&self) -> Option<&Error> {
if let &DeviceError::VkError(ref err) = self {
return err.cause();
}
None
}
}
#[derive(Clone)]
pub struct Instance<V: FunctionPointers> {
pub struct Instance {
handle: vk::Instance,
instance_fp: V::InstanceFp,
instance_fn_1_0: vk::InstanceFnV1_0,
instance_fn_1_1: vk::InstanceFnV1_1,
}
impl Instance {
pub unsafe fn load(static_fn: &vk::StaticFn, instance: vk::Instance) -> Self {
let instance_fn_1_0 = vk::InstanceFnV1_0::load(|name| {
mem::transmute(static_fn.get_instance_proc_addr(instance, name.as_ptr()))
});
let instance_fn_1_1 = vk::InstanceFnV1_1::load(|name| {
mem::transmute(static_fn.get_instance_proc_addr(instance, name.as_ptr()))
});
impl InstanceV1_0 for Instance<V1_0> {
type Fp = V1_0;
fn handle(&self) -> vk::Instance {
self.handle
}
fn fp_v1_0(&self) -> &vk::InstanceFnV1_0 {
&self.instance_fp.instance_fn
}
}
impl<V: FunctionPointers> Instance<V> {
pub fn handle(&self) -> vk::Instance {
self.handle
}
pub fn from_raw(handle: vk::Instance, version: V::InstanceFp) -> Self {
Instance {
handle: handle,
instance_fp: version,
handle: instance,
instance_fn_1_0,
instance_fn_1_1,
}
}
}
#[allow(non_camel_case_types)]
pub trait InstanceV1_0 {
type Fp: FunctionPointers;
fn handle(&self) -> vk::Instance;
fn fp_v1_0(&self) -> &vk::InstanceFnV1_0;
impl InstanceV1_0 for Instance {
type Device = Device;
unsafe fn create_device(
&self,
physical_device: vk::PhysicalDevice,
create_info: &vk::DeviceCreateInfo,
allocation_callbacks: Option<&vk::AllocationCallbacks>,
) -> Result<Device<Self::Fp>, DeviceError> {
) -> Result<Self::Device, vk::Result> {
let mut device: vk::Device = mem::uninitialized();
let err_code = self.fp_v1_0().create_device(
physical_device,
@ -82,49 +45,246 @@ pub trait InstanceV1_0 {
allocation_callbacks.as_raw_ptr(),
&mut device,
);
if err_code != vk::Result::Success {
return Err(DeviceError::VkError(err_code));
if err_code != vk::Result::SUCCESS {
return Err(err_code);
}
let device_fn =
<<Self as InstanceV1_0>::Fp as FunctionPointers>::DeviceFp::load(
self.fp_v1_0(),
device,
).map_err(|err| DeviceError::LoadError(err))?;
Ok(Device::from_raw(device, device_fn))
Ok(Device::load(&self.instance_fn_1_0, device))
}
fn handle(&self) -> vk::Instance {
self.handle
}
fn get_device_proc_addr(
&self,
device: vk::Device,
p_name: *const vk::c_char,
) -> vk::PFN_vkVoidFunction {
unsafe { self.fp_v1_0().get_device_proc_addr(device, p_name) }
fn fp_v1_0(&self) -> &vk::InstanceFnV1_0 {
&self.instance_fn_1_0
}
}
unsafe fn destroy_instance(&self, allocation_callbacks: Option<&vk::AllocationCallbacks>) {
self.fp_v1_0().destroy_instance(
impl InstanceV1_1 for Instance {
fn fp_v1_1(&self) -> &vk::InstanceFnV1_1 {
&self.instance_fn_1_1
}
}
#[allow(non_camel_case_types)]
pub trait InstanceV1_1: InstanceV1_0 {
fn fp_v1_1(&self) -> &vk::InstanceFnV1_1;
unsafe fn enumerate_physical_device_groups_len(&self) -> usize {
let mut group_count = mem::uninitialized();
self.fp_v1_1().enumerate_physical_device_groups(
self.handle(),
allocation_callbacks.as_raw_ptr(),
&mut group_count,
ptr::null_mut(),
);
group_count as usize
}
fn enumerate_physical_device_groups(
&self,
out: &mut [vk::PhysicalDeviceGroupProperties],
) -> VkResult<()> {
unsafe {
let mut group_count = out.len() as u32;
let err_code = self.fp_v1_1().enumerate_physical_device_groups(
self.handle(),
&mut group_count,
out.as_mut_ptr(),
);
if err_code == vk::Result::SUCCESS {
Ok(())
} else {
Err(err_code)
}
}
}
unsafe fn get_physical_device_properties2(
&self,
physical_device: vk::PhysicalDevice,
prop: &mut vk::PhysicalDeviceProperties2,
) {
self.fp_v1_1()
.get_physical_device_properties2(physical_device, prop);
}
unsafe fn get_physical_device_format_properties2(
&self,
physical_device: vk::PhysicalDevice,
format: vk::Format,
out: &mut vk::FormatProperties2,
) {
self.fp_v1_1()
.get_physical_device_format_properties2(physical_device, format, out);
}
unsafe fn get_physical_device_image_format_properties2(
&self,
physical_device: vk::PhysicalDevice,
format_info: &vk::PhysicalDeviceImageFormatInfo2,
image_format_prop: &mut vk::ImageFormatProperties2,
) -> VkResult<()> {
let err_code = self.fp_v1_1().get_physical_device_image_format_properties2(
physical_device,
format_info,
image_format_prop,
);
if err_code == vk::Result::SUCCESS {
Ok(())
} else {
Err(err_code)
}
}
unsafe fn get_physical_device_queue_family_properties2_len(
&self,
physical_device: vk::PhysicalDevice,
) -> usize {
let mut queue_count = 0;
self.fp_v1_1().get_physical_device_queue_family_properties2(
physical_device,
&mut queue_count,
ptr::null_mut(),
);
queue_count as usize
}
unsafe fn get_physical_device_queue_family_properties2(
&self,
physical_device: vk::PhysicalDevice,
queue_family_props: &mut [vk::QueueFamilyProperties2],
) {
let mut queue_count = queue_family_props.len() as u32;
self.fp_v1_1().get_physical_device_queue_family_properties2(
physical_device,
&mut queue_count,
queue_family_props.as_mut_ptr(),
);
}
fn get_physical_device_format_properties(
unsafe fn get_physical_device_memory_properties2(
&self,
physical_device: vk::PhysicalDevice,
out: &mut vk::PhysicalDeviceMemoryProperties2,
) {
self.fp_v1_1()
.get_physical_device_memory_properties2(physical_device, out);
}
unsafe fn get_physical_device_sparse_image_format_properties2_len(
&self,
physical_device: vk::PhysicalDevice,
format_info: &vk::PhysicalDeviceSparseImageFormatInfo2,
) -> usize {
let mut format_count = 0;
self.fp_v1_1()
.get_physical_device_sparse_image_format_properties2(
physical_device,
format_info,
&mut format_count,
ptr::null_mut(),
);
format_count as usize
}
unsafe fn get_physical_device_sparse_image_format_properties2(
&self,
physical_device: vk::PhysicalDevice,
format_info: &vk::PhysicalDeviceSparseImageFormatInfo2,
out: &mut [vk::SparseImageFormatProperties2],
) {
let mut format_count = out.len() as u32;
self.fp_v1_1()
.get_physical_device_sparse_image_format_properties2(
physical_device,
format_info,
&mut format_count,
out.as_mut_ptr(),
);
}
unsafe fn get_physical_device_external_buffer_properties(
&self,
physical_device: vk::PhysicalDevice,
external_buffer_info: &vk::PhysicalDeviceExternalBufferInfo,
out: &mut vk::ExternalBufferProperties,
) {
self.fp_v1_1()
.get_physical_device_external_buffer_properties(
physical_device,
external_buffer_info,
out,
);
}
unsafe fn get_physical_device_external_fence_properties(
&self,
physical_device: vk::PhysicalDevice,
external_fence_info: &vk::PhysicalDeviceExternalFenceInfo,
out: &mut vk::ExternalFenceProperties,
) {
self.fp_v1_1()
.get_physical_device_external_fence_properties(
physical_device,
external_fence_info,
out,
);
}
unsafe fn get_physical_device_external_semaphore_properties(
&self,
physical_device: vk::PhysicalDevice,
external_semaphore_info: &vk::PhysicalDeviceExternalSemaphoreInfo,
out: &mut vk::ExternalSemaphoreProperties,
) {
self.fp_v1_1()
.get_physical_device_external_semaphore_properties(
physical_device,
external_semaphore_info,
out,
);
}
}
#[allow(non_camel_case_types)]
pub trait InstanceV1_0 {
type Device;
fn handle(&self) -> vk::Instance;
fn fp_v1_0(&self) -> &vk::InstanceFnV1_0;
unsafe fn create_device(
&self,
physical_device: vk::PhysicalDevice,
create_info: &vk::DeviceCreateInfo,
allocation_callbacks: Option<&vk::AllocationCallbacks>,
) -> Result<Self::Device, vk::Result>;
unsafe fn get_device_proc_addr(
&self,
device: vk::Device,
p_name: *const c_char,
) -> vk::PFN_vkVoidFunction {
self.fp_v1_0().get_device_proc_addr(device, p_name)
}
unsafe fn destroy_instance(&self, allocation_callbacks: Option<&vk::AllocationCallbacks>) {
self.fp_v1_0()
.destroy_instance(self.handle(), allocation_callbacks.as_raw_ptr());
}
unsafe fn get_physical_device_format_properties(
&self,
physical_device: vk::PhysicalDevice,
format: vk::Format,
) -> vk::FormatProperties {
unsafe {
let mut format_prop = mem::uninitialized();
self.fp_v1_0().get_physical_device_format_properties(
physical_device,
format,
&mut format_prop,
);
format_prop
}
let mut format_prop = mem::uninitialized();
self.fp_v1_0().get_physical_device_format_properties(
physical_device,
format,
&mut format_prop,
);
format_prop
}
fn get_physical_device_image_format_properties(
unsafe fn get_physical_device_image_format_properties(
&self,
physical_device: vk::PhysicalDevice,
format: vk::Format,
@ -133,138 +293,112 @@ pub trait InstanceV1_0 {
usage: vk::ImageUsageFlags,
flags: vk::ImageCreateFlags,
) -> VkResult<vk::ImageFormatProperties> {
unsafe {
let mut image_format_prop = mem::uninitialized();
let err_code = self.fp_v1_0().get_physical_device_image_format_properties(
physical_device,
format,
typ,
tiling,
usage,
flags,
&mut image_format_prop,
);
if err_code == vk::Result::Success {
Ok(image_format_prop)
} else {
Err(err_code)
}
let mut image_format_prop = mem::uninitialized();
let err_code = self.fp_v1_0().get_physical_device_image_format_properties(
physical_device,
format,
typ,
tiling,
usage,
flags,
&mut image_format_prop,
);
if err_code == vk::Result::SUCCESS {
Ok(image_format_prop)
} else {
Err(err_code)
}
}
fn get_physical_device_memory_properties(
unsafe fn get_physical_device_memory_properties(
&self,
physical_device: vk::PhysicalDevice,
) -> vk::PhysicalDeviceMemoryProperties {
unsafe {
let mut memory_prop = mem::uninitialized();
self.fp_v1_0().get_physical_device_memory_properties(
physical_device,
&mut memory_prop,
);
memory_prop
}
let mut memory_prop = mem::uninitialized();
self.fp_v1_0()
.get_physical_device_memory_properties(physical_device, &mut memory_prop);
memory_prop
}
fn get_physical_device_properties(
unsafe fn get_physical_device_properties(
&self,
physical_device: vk::PhysicalDevice,
) -> vk::PhysicalDeviceProperties {
unsafe {
let mut prop = mem::uninitialized();
self.fp_v1_0().get_physical_device_properties(
physical_device,
&mut prop,
);
prop
}
let mut prop = mem::uninitialized();
self.fp_v1_0()
.get_physical_device_properties(physical_device, &mut prop);
prop
}
fn get_physical_device_queue_family_properties(
unsafe fn get_physical_device_queue_family_properties(
&self,
physical_device: vk::PhysicalDevice,
) -> Vec<vk::QueueFamilyProperties> {
unsafe {
let mut queue_count = 0;
self.fp_v1_0().get_physical_device_queue_family_properties(
physical_device,
&mut queue_count,
ptr::null_mut(),
);
let mut queue_families_vec = Vec::with_capacity(queue_count as usize);
self.fp_v1_0().get_physical_device_queue_family_properties(
physical_device,
&mut queue_count,
queue_families_vec.as_mut_ptr(),
);
queue_families_vec.set_len(queue_count as usize);
queue_families_vec
}
let mut queue_count = 0;
self.fp_v1_0().get_physical_device_queue_family_properties(
physical_device,
&mut queue_count,
ptr::null_mut(),
);
let mut queue_families_vec = Vec::with_capacity(queue_count as usize);
self.fp_v1_0().get_physical_device_queue_family_properties(
physical_device,
&mut queue_count,
queue_families_vec.as_mut_ptr(),
);
queue_families_vec.set_len(queue_count as usize);
queue_families_vec
}
fn get_physical_device_features(
unsafe fn get_physical_device_features(
&self,
physical_device: vk::PhysicalDevice,
) -> vk::PhysicalDeviceFeatures {
unsafe {
let mut prop = mem::uninitialized();
self.fp_v1_0().get_physical_device_features(
physical_device,
&mut prop,
);
prop
let mut prop = mem::uninitialized();
self.fp_v1_0()
.get_physical_device_features(physical_device, &mut prop);
prop
}
unsafe fn enumerate_physical_devices(&self) -> VkResult<Vec<vk::PhysicalDevice>> {
let mut num = mem::uninitialized();
self.fp_v1_0()
.enumerate_physical_devices(self.handle(), &mut num, ptr::null_mut());
let mut physical_devices = Vec::<vk::PhysicalDevice>::with_capacity(num as usize);
let err_code = self.fp_v1_0().enumerate_physical_devices(
self.handle(),
&mut num,
physical_devices.as_mut_ptr(),
);
physical_devices.set_len(num as usize);
match err_code {
vk::Result::SUCCESS => Ok(physical_devices),
_ => Err(err_code),
}
}
fn enumerate_physical_devices(&self) -> VkResult<Vec<vk::PhysicalDevice>> {
unsafe {
let mut num = mem::uninitialized();
self.fp_v1_0().enumerate_physical_devices(
self.handle(),
&mut num,
ptr::null_mut(),
);
let mut physical_devices = Vec::<vk::PhysicalDevice>::with_capacity(num as usize);
let err_code = self.fp_v1_0().enumerate_physical_devices(
self.handle(),
&mut num,
physical_devices.as_mut_ptr(),
);
physical_devices.set_len(num as usize);
match err_code {
vk::Result::Success => Ok(physical_devices),
_ => Err(err_code),
}
}
}
fn enumerate_device_extension_properties(
unsafe fn enumerate_device_extension_properties(
&self,
device: vk::PhysicalDevice,
) -> Result<Vec<vk::ExtensionProperties>, vk::Result> {
unsafe {
let mut num = 0;
self.fp_v1_0().enumerate_device_extension_properties(
device,
ptr::null(),
&mut num,
ptr::null_mut(),
);
let mut data = Vec::with_capacity(num as usize);
let err_code = self.fp_v1_0().enumerate_device_extension_properties(
device,
ptr::null(),
&mut num,
data.as_mut_ptr(),
);
data.set_len(num as usize);
match err_code {
vk::Result::Success => Ok(data),
_ => Err(err_code),
}
let mut num = 0;
self.fp_v1_0().enumerate_device_extension_properties(
device,
ptr::null(),
&mut num,
ptr::null_mut(),
);
let mut data = Vec::with_capacity(num as usize);
let err_code = self.fp_v1_0().enumerate_device_extension_properties(
device,
ptr::null(),
&mut num,
data.as_mut_ptr(),
);
data.set_len(num as usize);
match err_code {
vk::Result::SUCCESS => Ok(data),
_ => Err(err_code),
}
}
}
// pub trait InstanceMajor1Minor1: InstanceMajor1Minor0 {}
// pub trait InstanceMajor1Minor2: InstanceMajor1Minor1 {}

View file

@ -1,21 +1,18 @@
extern crate libc;
extern crate shared_library;
#[macro_use]
extern crate lazy_static;
pub use instance::{Instance, DeviceError};
extern crate shared_library;
pub use device::Device;
pub use entry::{Entry, EntryCustom, InstanceError, LoadingError};
pub use entry::{Entry, InstanceError, LoadingError};
pub use instance::Instance;
mod instance;
mod device;
mod entry;
pub mod prelude;
pub mod vk;
//mod allocator;
pub mod extensions;
pub mod version;
mod instance;
pub mod prelude;
pub mod util;
pub mod version;
pub mod vk;
pub trait RawPtr<T> {
fn as_raw_ptr(&self) -> *const T;
}
@ -24,6 +21,7 @@ impl<'r, T> RawPtr<T> for Option<&'r T> {
fn as_raw_ptr(&self) -> *const T {
match self {
&Some(inner) => inner as *const T,
_ => ::std::ptr::null(),
}
}

View file

@ -1,6 +1,7 @@
use std::iter::Iterator;
use std::marker::PhantomData;
use std::mem::size_of;
use std::os::raw::c_void;
use vk;
/// `Align` handles dynamic alignment. The is useful for dynamic uniform buffers where
@ -12,7 +13,7 @@ use vk;
/// an additional allocation and with the correct alignment.
#[derive(Debug, Clone)]
pub struct Align<T> {
ptr: *mut vk::c_void,
ptr: *mut c_void,
elem_size: vk::DeviceSize,
size: vk::DeviceSize,
_m: PhantomData<T>,
@ -46,7 +47,7 @@ fn calc_padding(adr: vk::DeviceSize, align: vk::DeviceSize) -> vk::DeviceSize {
impl<T> Align<T> {
pub unsafe fn new(
ptr: *mut vk::c_void,
ptr: *mut c_void,
alignment: vk::DeviceSize,
size: vk::DeviceSize,
) -> Self {

View file

@ -1,99 +1,3 @@
use vk;
pub use instance::InstanceV1_0;
pub use device::DeviceV1_0;
pub use entry::EntryV1_0;
use std::mem;
pub trait FunctionPointers {
type InstanceFp: InstanceLoader + Clone;
type DeviceFp: DeviceLoader + Clone;
type EntryFp: EntryLoader + Clone;
}
#[allow(non_camel_case_types)]
#[derive(Clone)]
pub struct V1_0;
impl FunctionPointers for V1_0 {
type InstanceFp = InstanceFpV1_0;
type DeviceFp = DeviceFpV1_0;
type EntryFp = EntryFpV1_0;
}
#[allow(non_camel_case_types)]
#[derive(Clone)]
pub struct InstanceFpV1_0 {
pub instance_fn: vk::InstanceFnV1_0,
}
#[allow(non_camel_case_types)]
#[derive(Clone)]
pub struct EntryFpV1_0 {
pub entry_fn: vk::EntryFnV1_0,
}
impl EntryLoader for EntryFpV1_0 {
fn fp_v1_0(&self) -> &vk::EntryFnV1_0 {
&self.entry_fn
}
unsafe fn load(static_fn: &vk::StaticFn) -> Result<Self, Vec<&'static str>> {
let entry_fn = vk::EntryFnV1_0::load(|name| {
mem::transmute(static_fn.get_instance_proc_addr(
vk::Instance::null(),
name.as_ptr(),
))
})?;
Ok(EntryFpV1_0 { entry_fn: entry_fn })
}
}
pub trait EntryLoader: Sized {
fn fp_v1_0(&self) -> &vk::EntryFnV1_0;
unsafe fn load(static_fn: &vk::StaticFn) -> Result<Self, Vec<&'static str>>;
}
pub trait InstanceLoader: Sized {
fn fp_v1_0(&self) -> &vk::InstanceFnV1_0;
unsafe fn load(
static_fn: &vk::StaticFn,
instance: vk::Instance,
) -> Result<Self, Vec<&'static str>>;
}
pub trait DeviceLoader: Sized {
unsafe fn load(
instance_fn: &vk::InstanceFnV1_0,
device: vk::Device,
) -> Result<Self, Vec<&'static str>>;
}
impl DeviceLoader for DeviceFpV1_0 {
unsafe fn load(
instance_fn: &vk::InstanceFnV1_0,
device: vk::Device,
) -> Result<Self, Vec<&'static str>> {
let device_fn = vk::DeviceFnV1_0::load(|name| {
mem::transmute(instance_fn.get_device_proc_addr(device, name.as_ptr()))
})?;
Ok(DeviceFpV1_0 { device_fn: device_fn })
}
}
impl InstanceLoader for InstanceFpV1_0 {
fn fp_v1_0(&self) -> &vk::InstanceFnV1_0 {
&self.instance_fn
}
unsafe fn load(
static_fn: &vk::StaticFn,
instance: vk::Instance,
) -> Result<Self, Vec<&'static str>> {
let instance_fn = vk::InstanceFnV1_0::load(|name| {
mem::transmute(static_fn.get_instance_proc_addr(instance, name.as_ptr()))
})?;
Ok(InstanceFpV1_0 { instance_fn: instance_fn })
}
}
#[allow(non_camel_case_types)]
#[derive(Clone)]
pub struct DeviceFpV1_0 {
pub device_fn: vk::DeviceFnV1_0,
}
pub use device::{DeviceV1_0, DeviceV1_1};
pub use entry::{EntryV1_0, EntryV1_1};
pub use instance::{InstanceV1_0, InstanceV1_1};

File diff suppressed because it is too large Load diff

12
ash/tests/display.rs Normal file
View file

@ -0,0 +1,12 @@
extern crate ash;
use ash::vk;
#[test]
fn display_flags() {
assert_eq!((vk::AccessFlags::INDIRECT_COMMAND_READ | vk::AccessFlags::VERTEX_ATTRIBUTE_READ).to_string(), "INDIRECT_COMMAND_READ | VERTEX_ATTRIBUTE_READ");
}
#[test]
fn display_enum() {
assert_eq!(vk::ChromaLocation::MIDPOINT.to_string(), "MIDPOINT");
}

View file

@ -4,7 +4,7 @@ version = "0.1.0"
authors = ["maik klein <maikklein@googlemail.com>"]
[dependencies]
winit = "0.11.1"
winit = "0.16"
image = "0.10.4"
ash = { path = "../ash" }

File diff suppressed because it is too large Load diff

View file

@ -1,18 +1,17 @@
extern crate ash;
#[macro_use]
extern crate examples;
use ash::util::*;
use ash::vk;
use examples::*;
use std::default::Default;
use std::ptr;
use std::ffi::CString;
use std::mem;
use std::path::Path;
use std::fs::File;
use std::io::Read;
use examples::*;
use ash::util::*;
use std::mem;
use std::mem::align_of;
use std::path::Path;
use std::ptr;
#[derive(Clone, Debug, Copy)]
struct Vertex {
@ -27,50 +26,50 @@ fn main() {
vk::AttachmentDescription {
format: base.surface_format.format,
flags: vk::AttachmentDescriptionFlags::empty(),
samples: vk::SAMPLE_COUNT_1_BIT,
load_op: vk::AttachmentLoadOp::Clear,
store_op: vk::AttachmentStoreOp::Store,
stencil_load_op: vk::AttachmentLoadOp::DontCare,
stencil_store_op: vk::AttachmentStoreOp::DontCare,
initial_layout: vk::ImageLayout::Undefined,
final_layout: vk::ImageLayout::PresentSrcKhr,
samples: vk::SampleCountFlags::TYPE_1,
load_op: vk::AttachmentLoadOp::CLEAR,
store_op: vk::AttachmentStoreOp::STORE,
stencil_load_op: vk::AttachmentLoadOp::DONT_CARE,
stencil_store_op: vk::AttachmentStoreOp::DONT_CARE,
initial_layout: vk::ImageLayout::UNDEFINED,
final_layout: vk::ImageLayout::PRESENT_SRC_KHR,
},
vk::AttachmentDescription {
format: vk::Format::D16Unorm,
format: vk::Format::D16_UNORM,
flags: vk::AttachmentDescriptionFlags::empty(),
samples: vk::SAMPLE_COUNT_1_BIT,
load_op: vk::AttachmentLoadOp::Clear,
store_op: vk::AttachmentStoreOp::DontCare,
stencil_load_op: vk::AttachmentLoadOp::DontCare,
stencil_store_op: vk::AttachmentStoreOp::DontCare,
initial_layout: vk::ImageLayout::DepthStencilAttachmentOptimal,
final_layout: vk::ImageLayout::DepthStencilAttachmentOptimal,
samples: vk::SampleCountFlags::TYPE_1,
load_op: vk::AttachmentLoadOp::CLEAR,
store_op: vk::AttachmentStoreOp::DONT_CARE,
stencil_load_op: vk::AttachmentLoadOp::DONT_CARE,
stencil_store_op: vk::AttachmentStoreOp::DONT_CARE,
initial_layout: vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
final_layout: vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
},
];
let color_attachment_ref = vk::AttachmentReference {
attachment: 0,
layout: vk::ImageLayout::ColorAttachmentOptimal,
layout: vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL,
};
let depth_attachment_ref = vk::AttachmentReference {
attachment: 1,
layout: vk::ImageLayout::DepthStencilAttachmentOptimal,
layout: vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
};
let dependency = vk::SubpassDependency {
dependency_flags: Default::default(),
src_subpass: vk::VK_SUBPASS_EXTERNAL,
src_subpass: vk::SUBPASS_EXTERNAL,
dst_subpass: Default::default(),
src_stage_mask: vk::PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
src_stage_mask: vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT,
src_access_mask: Default::default(),
dst_access_mask: vk::ACCESS_COLOR_ATTACHMENT_READ_BIT
| vk::ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
dst_stage_mask: vk::PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
dst_access_mask: vk::AccessFlags::COLOR_ATTACHMENT_READ
| vk::AccessFlags::COLOR_ATTACHMENT_WRITE,
dst_stage_mask: vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT,
};
let subpass = vk::SubpassDescription {
color_attachment_count: 1,
p_color_attachments: &color_attachment_ref,
p_depth_stencil_attachment: &depth_attachment_ref,
flags: Default::default(),
pipeline_bind_point: vk::PipelineBindPoint::Graphics,
pipeline_bind_point: vk::PipelineBindPoint::GRAPHICS,
input_attachment_count: 0,
p_input_attachments: ptr::null(),
p_resolve_attachments: ptr::null(),
@ -78,7 +77,7 @@ fn main() {
p_preserve_attachments: ptr::null(),
};
let renderpass_create_info = vk::RenderPassCreateInfo {
s_type: vk::StructureType::RenderPassCreateInfo,
s_type: vk::StructureType::RENDER_PASS_CREATE_INFO,
flags: Default::default(),
p_next: ptr::null(),
attachment_count: renderpass_attachments.len() as u32,
@ -88,15 +87,17 @@ fn main() {
dependency_count: 1,
p_dependencies: &dependency,
};
let renderpass = base.device
let renderpass = base
.device
.create_render_pass(&renderpass_create_info, None)
.unwrap();
let framebuffers: Vec<vk::Framebuffer> = base.present_image_views
let framebuffers: Vec<vk::Framebuffer> = base
.present_image_views
.iter()
.map(|&present_image_view| {
let framebuffer_attachments = [present_image_view, base.depth_image_view];
let frame_buffer_create_info = vk::FramebufferCreateInfo {
s_type: vk::StructureType::FramebufferCreateInfo,
s_type: vk::StructureType::FRAMEBUFFER_CREATE_INFO,
p_next: ptr::null(),
flags: Default::default(),
render_pass: renderpass,
@ -113,12 +114,12 @@ fn main() {
.collect();
let index_buffer_data = [0u32, 1, 2];
let index_buffer_info = vk::BufferCreateInfo {
s_type: vk::StructureType::BufferCreateInfo,
s_type: vk::StructureType::BUFFER_CREATE_INFO,
p_next: ptr::null(),
flags: vk::BufferCreateFlags::empty(),
size: std::mem::size_of_val(&index_buffer_data) as u64,
usage: vk::BUFFER_USAGE_INDEX_BUFFER_BIT,
sharing_mode: vk::SharingMode::Exclusive,
usage: vk::BufferUsageFlags::INDEX_BUFFER,
sharing_mode: vk::SharingMode::EXCLUSIVE,
queue_family_index_count: 0,
p_queue_family_indices: ptr::null(),
};
@ -128,18 +129,20 @@ fn main() {
find_memorytype_index(
&index_buffer_memory_req,
&base.device_memory_properties,
vk::MEMORY_PROPERTY_HOST_VISIBLE_BIT,
vk::MemoryPropertyFlags::HOST_VISIBLE,
).expect("Unable to find suitable memorytype for the index buffer.");
let index_allocate_info = vk::MemoryAllocateInfo {
s_type: vk::StructureType::MemoryAllocateInfo,
s_type: vk::StructureType::MEMORY_ALLOCATE_INFO,
p_next: ptr::null(),
allocation_size: index_buffer_memory_req.size,
memory_type_index: index_buffer_memory_index,
};
let index_buffer_memory = base.device
let index_buffer_memory = base
.device
.allocate_memory(&index_allocate_info, None)
.unwrap();
let index_ptr = base.device
let index_ptr = base
.device
.map_memory(
index_buffer_memory,
0,
@ -159,34 +162,37 @@ fn main() {
.unwrap();
let vertex_input_buffer_info = vk::BufferCreateInfo {
s_type: vk::StructureType::BufferCreateInfo,
s_type: vk::StructureType::BUFFER_CREATE_INFO,
p_next: ptr::null(),
flags: vk::BufferCreateFlags::empty(),
size: 3 * std::mem::size_of::<Vertex>() as u64,
usage: vk::BUFFER_USAGE_VERTEX_BUFFER_BIT,
sharing_mode: vk::SharingMode::Exclusive,
usage: vk::BufferUsageFlags::VERTEX_BUFFER,
sharing_mode: vk::SharingMode::EXCLUSIVE,
queue_family_index_count: 0,
p_queue_family_indices: ptr::null(),
};
let vertex_input_buffer = base.device
let vertex_input_buffer = base
.device
.create_buffer(&vertex_input_buffer_info, None)
.unwrap();
let vertex_input_buffer_memory_req = base.device
let vertex_input_buffer_memory_req = base
.device
.get_buffer_memory_requirements(vertex_input_buffer);
let vertex_input_buffer_memory_index =
find_memorytype_index(
&vertex_input_buffer_memory_req,
&base.device_memory_properties,
vk::MEMORY_PROPERTY_HOST_VISIBLE_BIT,
vk::MemoryPropertyFlags::HOST_VISIBLE,
).expect("Unable to find suitable memorytype for the vertex buffer.");
let vertex_buffer_allocate_info = vk::MemoryAllocateInfo {
s_type: vk::StructureType::MemoryAllocateInfo,
s_type: vk::StructureType::MEMORY_ALLOCATE_INFO,
p_next: ptr::null(),
allocation_size: vertex_input_buffer_memory_req.size,
memory_type_index: vertex_input_buffer_memory_index,
};
let vertex_input_buffer_memory = base.device
let vertex_input_buffer_memory = base
.device
.allocate_memory(&vertex_buffer_allocate_info, None)
.unwrap();
let vertices = [
@ -203,7 +209,8 @@ fn main() {
color: [1.0, 0.0, 0.0, 1.0],
},
];
let vert_ptr = base.device
let vert_ptr = base
.device
.map_memory(
vertex_input_buffer_memory,
0,
@ -231,7 +238,7 @@ fn main() {
.filter_map(|byte| byte.ok())
.collect();
let vertex_shader_info = vk::ShaderModuleCreateInfo {
s_type: vk::StructureType::ShaderModuleCreateInfo,
s_type: vk::StructureType::SHADER_MODULE_CREATE_INFO,
p_next: ptr::null(),
flags: Default::default(),
code_size: vertex_bytes.len(),
@ -239,22 +246,24 @@ fn main() {
};
let frag_bytes: Vec<u8> = frag_spv_file.bytes().filter_map(|byte| byte.ok()).collect();
let frag_shader_info = vk::ShaderModuleCreateInfo {
s_type: vk::StructureType::ShaderModuleCreateInfo,
s_type: vk::StructureType::SHADER_MODULE_CREATE_INFO,
p_next: ptr::null(),
flags: Default::default(),
code_size: frag_bytes.len(),
p_code: frag_bytes.as_ptr() as *const u32,
};
let vertex_shader_module = base.device
let vertex_shader_module = base
.device
.create_shader_module(&vertex_shader_info, None)
.expect("Vertex shader module error");
let fragment_shader_module = base.device
let fragment_shader_module = base
.device
.create_shader_module(&frag_shader_info, None)
.expect("Fragment shader module error");
let layout_create_info = vk::PipelineLayoutCreateInfo {
s_type: vk::StructureType::PipelineLayoutCreateInfo,
s_type: vk::StructureType::PIPELINE_LAYOUT_CREATE_INFO,
p_next: ptr::null(),
flags: Default::default(),
set_layout_count: 0,
@ -263,54 +272,53 @@ fn main() {
p_push_constant_ranges: ptr::null(),
};
let pipeline_layout = base.device
let pipeline_layout = base
.device
.create_pipeline_layout(&layout_create_info, None)
.unwrap();
let shader_entry_name = CString::new("main").unwrap();
let shader_stage_create_infos = [
vk::PipelineShaderStageCreateInfo {
s_type: vk::StructureType::PipelineShaderStageCreateInfo,
s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO,
p_next: ptr::null(),
flags: Default::default(),
module: vertex_shader_module,
p_name: shader_entry_name.as_ptr(),
p_specialization_info: ptr::null(),
stage: vk::SHADER_STAGE_VERTEX_BIT,
stage: vk::ShaderStageFlags::VERTEX,
},
vk::PipelineShaderStageCreateInfo {
s_type: vk::StructureType::PipelineShaderStageCreateInfo,
s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO,
p_next: ptr::null(),
flags: Default::default(),
module: fragment_shader_module,
p_name: shader_entry_name.as_ptr(),
p_specialization_info: ptr::null(),
stage: vk::SHADER_STAGE_FRAGMENT_BIT,
},
];
let vertex_input_binding_descriptions = [
vk::VertexInputBindingDescription {
binding: 0,
stride: mem::size_of::<Vertex>() as u32,
input_rate: vk::VertexInputRate::Vertex,
stage: vk::ShaderStageFlags::FRAGMENT,
},
];
let vertex_input_binding_descriptions = [vk::VertexInputBindingDescription {
binding: 0,
stride: mem::size_of::<Vertex>() as u32,
input_rate: vk::VertexInputRate::VERTEX,
}];
let vertex_input_attribute_descriptions = [
vk::VertexInputAttributeDescription {
location: 0,
binding: 0,
format: vk::Format::R32g32b32a32Sfloat,
format: vk::Format::R32G32B32A32_SFLOAT,
offset: offset_of!(Vertex, pos) as u32,
},
vk::VertexInputAttributeDescription {
location: 1,
binding: 0,
format: vk::Format::R32g32b32a32Sfloat,
format: vk::Format::R32G32B32A32_SFLOAT,
offset: offset_of!(Vertex, color) as u32,
},
];
let vertex_input_state_info = vk::PipelineVertexInputStateCreateInfo {
s_type: vk::StructureType::PipelineVertexInputStateCreateInfo,
s_type: vk::StructureType::PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
p_next: ptr::null(),
flags: Default::default(),
vertex_attribute_description_count: vertex_input_attribute_descriptions.len() as u32,
@ -319,30 +327,26 @@ fn main() {
p_vertex_binding_descriptions: vertex_input_binding_descriptions.as_ptr(),
};
let vertex_input_assembly_state_info = vk::PipelineInputAssemblyStateCreateInfo {
s_type: vk::StructureType::PipelineInputAssemblyStateCreateInfo,
s_type: vk::StructureType::PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
flags: Default::default(),
p_next: ptr::null(),
primitive_restart_enable: 0,
topology: vk::PrimitiveTopology::TriangleList,
topology: vk::PrimitiveTopology::TRIANGLE_LIST,
};
let viewports = [
vk::Viewport {
x: 0.0,
y: 0.0,
width: base.surface_resolution.width as f32,
height: base.surface_resolution.height as f32,
min_depth: 0.0,
max_depth: 1.0,
},
];
let scissors = [
vk::Rect2D {
offset: vk::Offset2D { x: 0, y: 0 },
extent: base.surface_resolution.clone(),
},
];
let viewports = [vk::Viewport {
x: 0.0,
y: 0.0,
width: base.surface_resolution.width as f32,
height: base.surface_resolution.height as f32,
min_depth: 0.0,
max_depth: 1.0,
}];
let scissors = [vk::Rect2D {
offset: vk::Offset2D { x: 0, y: 0 },
extent: base.surface_resolution.clone(),
}];
let viewport_state_info = vk::PipelineViewportStateCreateInfo {
s_type: vk::StructureType::PipelineViewportStateCreateInfo,
s_type: vk::StructureType::PIPELINE_VIEWPORT_STATE_CREATE_INFO,
p_next: ptr::null(),
flags: Default::default(),
scissor_count: scissors.len() as u32,
@ -351,25 +355,25 @@ fn main() {
p_viewports: viewports.as_ptr(),
};
let rasterization_info = vk::PipelineRasterizationStateCreateInfo {
s_type: vk::StructureType::PipelineRasterizationStateCreateInfo,
s_type: vk::StructureType::PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
p_next: ptr::null(),
flags: Default::default(),
cull_mode: vk::CULL_MODE_NONE,
cull_mode: vk::CullModeFlags::NONE,
depth_bias_clamp: 0.0,
depth_bias_constant_factor: 0.0,
depth_bias_enable: 0,
depth_bias_slope_factor: 0.0,
depth_clamp_enable: 0,
front_face: vk::FrontFace::CounterClockwise,
front_face: vk::FrontFace::COUNTER_CLOCKWISE,
line_width: 1.0,
polygon_mode: vk::PolygonMode::Fill,
polygon_mode: vk::PolygonMode::FILL,
rasterizer_discard_enable: 0,
};
let multisample_state_info = vk::PipelineMultisampleStateCreateInfo {
s_type: vk::StructureType::PipelineMultisampleStateCreateInfo,
s_type: vk::StructureType::PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
flags: Default::default(),
p_next: ptr::null(),
rasterization_samples: vk::SAMPLE_COUNT_1_BIT,
rasterization_samples: vk::SampleCountFlags::TYPE_1,
sample_shading_enable: 0,
min_sample_shading: 0.0,
p_sample_mask: ptr::null(),
@ -377,21 +381,21 @@ fn main() {
alpha_to_coverage_enable: 0,
};
let noop_stencil_state = vk::StencilOpState {
fail_op: vk::StencilOp::Keep,
pass_op: vk::StencilOp::Keep,
depth_fail_op: vk::StencilOp::Keep,
compare_op: vk::CompareOp::Always,
fail_op: vk::StencilOp::KEEP,
pass_op: vk::StencilOp::KEEP,
depth_fail_op: vk::StencilOp::KEEP,
compare_op: vk::CompareOp::ALWAYS,
compare_mask: 0,
write_mask: 0,
reference: 0,
};
let depth_state_info = vk::PipelineDepthStencilStateCreateInfo {
s_type: vk::StructureType::PipelineDepthStencilStateCreateInfo,
s_type: vk::StructureType::PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
p_next: ptr::null(),
flags: Default::default(),
depth_test_enable: 1,
depth_write_enable: 1,
depth_compare_op: vk::CompareOp::LessOrEqual,
depth_compare_op: vk::CompareOp::LESS_OR_EQUAL,
depth_bounds_test_enable: 0,
stencil_test_enable: 0,
front: noop_stencil_state.clone(),
@ -399,38 +403,36 @@ fn main() {
max_depth_bounds: 1.0,
min_depth_bounds: 0.0,
};
let color_blend_attachment_states = [
vk::PipelineColorBlendAttachmentState {
blend_enable: 0,
src_color_blend_factor: vk::BlendFactor::SrcColor,
dst_color_blend_factor: vk::BlendFactor::OneMinusDstColor,
color_blend_op: vk::BlendOp::Add,
src_alpha_blend_factor: vk::BlendFactor::Zero,
dst_alpha_blend_factor: vk::BlendFactor::Zero,
alpha_blend_op: vk::BlendOp::Add,
color_write_mask: vk::ColorComponentFlags::all(),
},
];
let color_blend_attachment_states = [vk::PipelineColorBlendAttachmentState {
blend_enable: 0,
src_color_blend_factor: vk::BlendFactor::SRC_COLOR,
dst_color_blend_factor: vk::BlendFactor::ONE_MINUS_DST_COLOR,
color_blend_op: vk::BlendOp::ADD,
src_alpha_blend_factor: vk::BlendFactor::ZERO,
dst_alpha_blend_factor: vk::BlendFactor::ZERO,
alpha_blend_op: vk::BlendOp::ADD,
color_write_mask: vk::ColorComponentFlags::all(),
}];
let color_blend_state = vk::PipelineColorBlendStateCreateInfo {
s_type: vk::StructureType::PipelineColorBlendStateCreateInfo,
s_type: vk::StructureType::PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
p_next: ptr::null(),
flags: Default::default(),
logic_op_enable: 0,
logic_op: vk::LogicOp::Clear,
logic_op: vk::LogicOp::CLEAR,
attachment_count: color_blend_attachment_states.len() as u32,
p_attachments: color_blend_attachment_states.as_ptr(),
blend_constants: [0.0, 0.0, 0.0, 0.0],
};
let dynamic_state = [vk::DynamicState::Viewport, vk::DynamicState::Scissor];
let dynamic_state = [vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR];
let dynamic_state_info = vk::PipelineDynamicStateCreateInfo {
s_type: vk::StructureType::PipelineDynamicStateCreateInfo,
s_type: vk::StructureType::PIPELINE_DYNAMIC_STATE_CREATE_INFO,
p_next: ptr::null(),
flags: Default::default(),
dynamic_state_count: dynamic_state.len() as u32,
p_dynamic_states: dynamic_state.as_ptr(),
};
let graphic_pipeline_info = vk::GraphicsPipelineCreateInfo {
s_type: vk::StructureType::GraphicsPipelineCreateInfo,
s_type: vk::StructureType::GRAPHICS_PIPELINE_CREATE_INFO,
p_next: ptr::null(),
flags: vk::PipelineCreateFlags::empty(),
stage_count: shader_stage_create_infos.len() as u32,
@ -450,14 +452,16 @@ fn main() {
base_pipeline_handle: vk::Pipeline::null(),
base_pipeline_index: 0,
};
let graphics_pipelines = base.device
let graphics_pipelines = base
.device
.create_graphics_pipelines(vk::PipelineCache::null(), &[graphic_pipeline_info], None)
.expect("Unable to create graphics pipeline");
let graphic_pipeline = graphics_pipelines[0];
base.render_loop(|| {
let present_index = base.swapchain_loader
let (present_index, _) = base
.swapchain_loader
.acquire_next_image_khr(
base.swapchain,
std::u64::MAX,
@ -472,7 +476,7 @@ fn main() {
},
},
vk::ClearValue {
depth: vk::ClearDepthStencilValue {
depth_stencil: vk::ClearDepthStencilValue {
depth: 1.0,
stencil: 0,
},
@ -480,7 +484,7 @@ fn main() {
];
let render_pass_begin_info = vk::RenderPassBeginInfo {
s_type: vk::StructureType::RenderPassBeginInfo,
s_type: vk::StructureType::RENDER_PASS_BEGIN_INFO,
p_next: ptr::null(),
render_pass: renderpass,
framebuffer: framebuffers[present_index as usize],
@ -495,18 +499,18 @@ fn main() {
&base.device,
base.draw_command_buffer,
base.present_queue,
&[vk::PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT],
&[vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT],
&[base.present_complete_semaphore],
&[base.rendering_complete_semaphore],
|device, draw_command_buffer| {
device.cmd_begin_render_pass(
draw_command_buffer,
&render_pass_begin_info,
vk::SubpassContents::Inline,
vk::SubpassContents::INLINE,
);
device.cmd_bind_pipeline(
draw_command_buffer,
vk::PipelineBindPoint::Graphics,
vk::PipelineBindPoint::GRAPHICS,
graphic_pipeline,
);
device.cmd_set_viewport(draw_command_buffer, 0, &viewports);
@ -521,7 +525,7 @@ fn main() {
draw_command_buffer,
index_buffer,
0,
vk::IndexType::Uint32,
vk::IndexType::UINT32,
);
device.cmd_draw_indexed(
draw_command_buffer,
@ -538,7 +542,7 @@ fn main() {
);
//let mut present_info_err = mem::uninitialized();
let present_info = vk::PresentInfoKHR {
s_type: vk::StructureType::PresentInfoKhr,
s_type: vk::StructureType::PRESENT_INFO_KHR,
p_next: ptr::null(),
wait_semaphore_count: 1,
p_wait_semaphores: &base.rendering_complete_semaphore,

View file

@ -22,7 +22,7 @@ use objc::runtime::YES;
use std::mem;
use ash::vk;
use std::default::Default;
use ash::Device;
use ash::Entry;
use ash::Instance;
use ash::Device;
@ -35,22 +35,22 @@ use ash::extensions::XlibSurface;
#[cfg(target_os = "macos")]
use ash::extensions::MacOSSurface;
use std::cell::RefCell;
use std::ptr;
use std::default::Default;
use std::ffi::{CStr, CString};
use std::ops::Drop;
use std::os::raw::{c_char, c_void};
use std::ptr;
// Simple offset_of macro akin to C++ offsetof
#[macro_export]
macro_rules! offset_of{
($base: path, $field: ident) => {
{
#[allow(unused_unsafe)]
unsafe{
let b: $base = mem::uninitialized();
(&b.$field as *const _ as isize) - (&b as *const _ as isize)
}
macro_rules! offset_of {
($base:path, $field:ident) => {{
#[allow(unused_unsafe)]
unsafe {
let b: $base = mem::uninitialized();
(&b.$field as *const _ as isize) - (&b as *const _ as isize)
}
}
}};
}
pub fn record_submit_commandbuffer<D: DeviceV1_0, F: FnOnce(&D, vk::CommandBuffer)>(
@ -66,14 +66,13 @@ pub fn record_submit_commandbuffer<D: DeviceV1_0, F: FnOnce(&D, vk::CommandBuffe
device
.reset_command_buffer(
command_buffer,
vk::COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT,
)
.expect("Reset command buffer failed.");
vk::CommandBufferResetFlags::RELEASE_RESOURCES,
).expect("Reset command buffer failed.");
let command_buffer_begin_info = vk::CommandBufferBeginInfo {
s_type: vk::StructureType::CommandBufferBeginInfo,
s_type: vk::StructureType::COMMAND_BUFFER_BEGIN_INFO,
p_next: ptr::null(),
p_inheritance_info: ptr::null(),
flags: vk::COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
flags: vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT,
};
device
.begin_command_buffer(command_buffer, &command_buffer_begin_info)
@ -83,7 +82,7 @@ pub fn record_submit_commandbuffer<D: DeviceV1_0, F: FnOnce(&D, vk::CommandBuffe
.end_command_buffer(command_buffer)
.expect("End commandbuffer");
let fence_create_info = vk::FenceCreateInfo {
s_type: vk::StructureType::FenceCreateInfo,
s_type: vk::StructureType::FENCE_CREATE_INFO,
p_next: ptr::null(),
flags: vk::FenceCreateFlags::empty(),
};
@ -91,7 +90,7 @@ pub fn record_submit_commandbuffer<D: DeviceV1_0, F: FnOnce(&D, vk::CommandBuffe
.create_fence(&fence_create_info, None)
.expect("Create fence failed.");
let submit_info = vk::SubmitInfo {
s_type: vk::StructureType::SubmitInfo,
s_type: vk::StructureType::SUBMIT_INFO,
p_next: ptr::null(),
wait_semaphore_count: wait_semaphores.len() as u32,
p_wait_semaphores: wait_semaphores.as_ptr(),
@ -121,14 +120,14 @@ unsafe fn create_surface<E: EntryV1_0, I: InstanceV1_0>(
let x11_display = window.get_xlib_display().unwrap();
let x11_window = window.get_xlib_window().unwrap();
let x11_create_info = vk::XlibSurfaceCreateInfoKHR {
s_type: vk::StructureType::XlibSurfaceCreateInfoKhr,
s_type: vk::StructureType::XLIB_SURFACE_CREATE_INFO_KHR,
p_next: ptr::null(),
flags: Default::default(),
window: x11_window as vk::Window,
dpy: x11_display as *mut vk::Display,
};
let xlib_surface_loader =
XlibSurface::new(entry, instance).expect("Unable to load xlib surface");
XlibSurface::new(entry, instance);
xlib_surface_loader.create_xlib_surface_khr(&x11_create_info, None)
}
@ -173,20 +172,20 @@ unsafe fn create_surface<E: EntryV1_0, I: InstanceV1_0>(
window: &winit::Window,
) -> Result<vk::SurfaceKHR, vk::Result> {
use winapi::shared::windef::HWND;
use winapi::um::winuser::GetWindow;
use winapi::um::libloaderapi::GetModuleHandleW;
use winit::os::windows::WindowExt;
let hwnd = window.get_hwnd() as HWND;
let hinstance = GetWindow(hwnd, 0) as *const vk::c_void;
let hinstance = GetModuleHandleW(ptr::null()) as *const c_void;
let win32_create_info = vk::Win32SurfaceCreateInfoKHR {
s_type: vk::StructureType::Win32SurfaceCreateInfoKhr,
s_type: vk::StructureType::WIN32_SURFACE_CREATE_INFO_KHR,
p_next: ptr::null(),
flags: Default::default(),
hinstance: hinstance,
hwnd: hwnd as *const vk::c_void,
hwnd: hwnd as *const c_void,
};
let win32_surface_loader =
Win32Surface::new(entry, instance).expect("Unable to load win32 surface");
Win32Surface::new(entry, instance);
win32_surface_loader.create_win32_surface_khr(&win32_create_info, None)
}
@ -220,12 +219,12 @@ fn extension_names() -> Vec<*const i8> {
unsafe extern "system" fn vulkan_debug_callback(
_: vk::DebugReportFlagsEXT,
_: vk::DebugReportObjectTypeEXT,
_: vk::uint64_t,
_: vk::size_t,
_: vk::int32_t,
_: *const vk::c_char,
p_message: *const vk::c_char,
_: *mut vk::c_void,
_: u64,
_: usize,
_: i32,
_: *const c_char,
p_message: *const c_char,
_: *mut c_void,
) -> u32 {
println!("{:?}", CStr::from_ptr(p_message));
vk::VK_FALSE
@ -269,9 +268,9 @@ pub fn find_memorytype_index_f<F: Fn(vk::MemoryPropertyFlags, vk::MemoryProperty
}
pub struct ExampleBase {
pub entry: Entry<V1_0>,
pub instance: Instance<V1_0>,
pub device: Device<V1_0>,
pub entry: Entry,
pub instance: Instance,
pub device: Device,
pub surface_loader: Surface,
pub swapchain_loader: Swapchain,
pub debug_report_loader: DebugReport,
@ -318,7 +317,7 @@ impl ExampleBase {
ControlFlow::Continue
}
}
WindowEvent::Closed => winit::ControlFlow::Break,
WindowEvent::CloseRequested => winit::ControlFlow::Break,
_ => ControlFlow::Continue,
},
_ => ControlFlow::Continue,
@ -331,8 +330,10 @@ impl ExampleBase {
let events_loop = winit::EventsLoop::new();
let window = winit::WindowBuilder::new()
.with_title("Ash - Example")
.with_dimensions(window_width, window_height)
.build(&events_loop)
.with_dimensions(winit::dpi::LogicalSize::new(
window_width as f64,
window_height as f64,
)).build(&events_loop)
.unwrap();
let entry = Entry::new().unwrap();
let app_name = CString::new("VulkanTriangle").unwrap();
@ -347,7 +348,7 @@ impl ExampleBase {
let extension_names_raw = extension_names();
let appinfo = vk::ApplicationInfo {
p_application_name: raw_name,
s_type: vk::StructureType::ApplicationInfo,
s_type: vk::StructureType::APPLICATION_INFO,
p_next: ptr::null(),
application_version: 0,
p_engine_name: raw_name,
@ -355,7 +356,7 @@ impl ExampleBase {
api_version: vk_make_version!(1, 0, 36),
};
let create_info = vk::InstanceCreateInfo {
s_type: vk::StructureType::InstanceCreateInfo,
s_type: vk::StructureType::INSTANCE_CREATE_INFO,
p_next: ptr::null(),
flags: Default::default(),
p_application_info: &appinfo,
@ -364,19 +365,20 @@ impl ExampleBase {
pp_enabled_extension_names: extension_names_raw.as_ptr(),
enabled_extension_count: extension_names_raw.len() as u32,
};
let instance: Instance<V1_0> = entry
let instance: Instance = entry
.create_instance(&create_info, None)
.expect("Instance creation error");
let debug_info = vk::DebugReportCallbackCreateInfoEXT {
s_type: vk::StructureType::DebugReportCallbackCreateInfoExt,
s_type: vk::StructureType::DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
p_next: ptr::null(),
flags: vk::DEBUG_REPORT_ERROR_BIT_EXT | vk::DEBUG_REPORT_WARNING_BIT_EXT
| vk::DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
pfn_callback: vulkan_debug_callback,
flags: vk::DebugReportFlagsEXT::ERROR
| vk::DebugReportFlagsEXT::WARNING
| vk::DebugReportFlagsEXT::PERFORMANCE_WARNING,
pfn_callback: Some(vulkan_debug_callback),
p_user_data: ptr::null_mut(),
};
let debug_report_loader =
DebugReport::new(&entry, &instance).expect("Unable to load debug report");
DebugReport::new(&entry, &instance);
let debug_call_back = debug_report_loader
.create_debug_report_callback_ext(&debug_info, None)
.unwrap();
@ -385,7 +387,7 @@ impl ExampleBase {
.enumerate_physical_devices()
.expect("Physical device error");
let surface_loader =
Surface::new(&entry, &instance).expect("Unable to load the Surface extension");
Surface::new(&entry, &instance);
let (pdevice, queue_family_index) = pdevices
.iter()
.map(|pdevice| {
@ -394,21 +396,19 @@ impl ExampleBase {
.iter()
.enumerate()
.filter_map(|(index, ref info)| {
let supports_graphic_and_surface = info.queue_flags
.subset(vk::QUEUE_GRAPHICS_BIT)
&& surface_loader.get_physical_device_surface_support_khr(
*pdevice,
index as u32,
surface,
);
let supports_graphic_and_surface =
info.queue_flags.contains(vk::QueueFlags::GRAPHICS) && surface_loader
.get_physical_device_surface_support_khr(
*pdevice,
index as u32,
surface,
);
match supports_graphic_and_surface {
true => Some((*pdevice, index)),
_ => None,
}
})
.nth(0)
})
.filter_map(|v| v)
}).nth(0)
}).filter_map(|v| v)
.nth(0)
.expect("Couldn't find suitable device.");
let queue_family_index = queue_family_index as u32;
@ -419,7 +419,7 @@ impl ExampleBase {
};
let priorities = [1.0];
let queue_info = vk::DeviceQueueCreateInfo {
s_type: vk::StructureType::DeviceQueueCreateInfo,
s_type: vk::StructureType::DEVICE_QUEUE_CREATE_INFO,
p_next: ptr::null(),
flags: Default::default(),
queue_family_index: queue_family_index as u32,
@ -427,7 +427,7 @@ impl ExampleBase {
queue_count: priorities.len() as u32,
};
let device_create_info = vk::DeviceCreateInfo {
s_type: vk::StructureType::DeviceCreateInfo,
s_type: vk::StructureType::DEVICE_CREATE_INFO,
p_next: ptr::null(),
flags: Default::default(),
queue_create_info_count: 1,
@ -438,7 +438,7 @@ impl ExampleBase {
pp_enabled_extension_names: device_extension_names_raw.as_ptr(),
p_enabled_features: &features,
};
let device: Device<V1_0> = instance
let device: Device = instance
.create_device(pdevice, &device_create_info, None)
.unwrap();
let present_queue = device.get_device_queue(queue_family_index as u32, 0);
@ -449,13 +449,12 @@ impl ExampleBase {
let surface_format = surface_formats
.iter()
.map(|sfmt| match sfmt.format {
vk::Format::Undefined => vk::SurfaceFormatKHR {
format: vk::Format::B8g8r8Unorm,
vk::Format::UNDEFINED => vk::SurfaceFormatKHR {
format: vk::Format::B8G8R8_UNORM,
color_space: sfmt.color_space,
},
_ => sfmt.clone(),
})
.nth(0)
}).nth(0)
.expect("Unable to find suitable surface format.");
let surface_capabilities = surface_loader
.get_physical_device_surface_capabilities_khr(pdevice, surface)
@ -475,9 +474,9 @@ impl ExampleBase {
};
let pre_transform = if surface_capabilities
.supported_transforms
.subset(vk::SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
.contains(vk::SurfaceTransformFlagsKHR::IDENTITY)
{
vk::SURFACE_TRANSFORM_IDENTITY_BIT_KHR
vk::SurfaceTransformFlagsKHR::IDENTITY
} else {
surface_capabilities.current_transform
};
@ -487,12 +486,12 @@ impl ExampleBase {
let present_mode = present_modes
.iter()
.cloned()
.find(|&mode| mode == vk::PresentModeKHR::Mailbox)
.unwrap_or(vk::PresentModeKHR::Fifo);
.find(|&mode| mode == vk::PresentModeKHR::MAILBOX)
.unwrap_or(vk::PresentModeKHR::FIFO);
let swapchain_loader =
Swapchain::new(&instance, &device).expect("Unable to load swapchain");
Swapchain::new(&instance, &device);
let swapchain_create_info = vk::SwapchainCreateInfoKHR {
s_type: vk::StructureType::SwapchainCreateInfoKhr,
s_type: vk::StructureType::SWAPCHAIN_CREATE_INFO_KHR,
p_next: ptr::null(),
flags: Default::default(),
surface: surface,
@ -500,10 +499,10 @@ impl ExampleBase {
image_color_space: surface_format.color_space,
image_format: surface_format.format,
image_extent: surface_resolution.clone(),
image_usage: vk::IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
image_sharing_mode: vk::SharingMode::Exclusive,
image_usage: vk::ImageUsageFlags::COLOR_ATTACHMENT,
image_sharing_mode: vk::SharingMode::EXCLUSIVE,
pre_transform: pre_transform,
composite_alpha: vk::COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
composite_alpha: vk::CompositeAlphaFlagsKHR::OPAQUE,
present_mode: present_mode,
clipped: 1,
old_swapchain: vk::SwapchainKHR::null(),
@ -515,18 +514,18 @@ impl ExampleBase {
.create_swapchain_khr(&swapchain_create_info, None)
.unwrap();
let pool_create_info = vk::CommandPoolCreateInfo {
s_type: vk::StructureType::CommandPoolCreateInfo,
s_type: vk::StructureType::COMMAND_POOL_CREATE_INFO,
p_next: ptr::null(),
flags: vk::COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
flags: vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER,
queue_family_index: queue_family_index,
};
let pool = device.create_command_pool(&pool_create_info, None).unwrap();
let command_buffer_allocate_info = vk::CommandBufferAllocateInfo {
s_type: vk::StructureType::CommandBufferAllocateInfo,
s_type: vk::StructureType::COMMAND_BUFFER_ALLOCATE_INFO,
p_next: ptr::null(),
command_buffer_count: 2,
command_pool: pool,
level: vk::CommandBufferLevel::Primary,
level: vk::CommandBufferLevel::PRIMARY,
};
let command_buffers = device
.allocate_command_buffers(&command_buffer_allocate_info)
@ -541,10 +540,10 @@ impl ExampleBase {
.iter()
.map(|&image| {
let create_view_info = vk::ImageViewCreateInfo {
s_type: vk::StructureType::ImageViewCreateInfo,
s_type: vk::StructureType::IMAGE_VIEW_CREATE_INFO,
p_next: ptr::null(),
flags: Default::default(),
view_type: vk::ImageViewType::Type2d,
view_type: vk::ImageViewType::TYPE_2D,
format: surface_format.format,
components: vk::ComponentMapping {
r: vk::ComponentSwizzle::R,
@ -553,7 +552,7 @@ impl ExampleBase {
a: vk::ComponentSwizzle::A,
},
subresource_range: vk::ImageSubresourceRange {
aspect_mask: vk::IMAGE_ASPECT_COLOR_BIT,
aspect_mask: vk::ImageAspectFlags::COLOR,
base_mip_level: 0,
level_count: 1,
base_array_layer: 0,
@ -562,15 +561,14 @@ impl ExampleBase {
image: image,
};
device.create_image_view(&create_view_info, None).unwrap()
})
.collect();
}).collect();
let device_memory_properties = instance.get_physical_device_memory_properties(pdevice);
let depth_image_create_info = vk::ImageCreateInfo {
s_type: vk::StructureType::ImageCreateInfo,
s_type: vk::StructureType::IMAGE_CREATE_INFO,
p_next: ptr::null(),
flags: Default::default(),
image_type: vk::ImageType::Type2d,
format: vk::Format::D16Unorm,
image_type: vk::ImageType::TYPE_2D,
format: vk::Format::D16_UNORM,
extent: vk::Extent3D {
width: surface_resolution.width,
height: surface_resolution.height,
@ -578,25 +576,24 @@ impl ExampleBase {
},
mip_levels: 1,
array_layers: 1,
samples: vk::SAMPLE_COUNT_1_BIT,
tiling: vk::ImageTiling::Optimal,
usage: vk::IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
sharing_mode: vk::SharingMode::Exclusive,
samples: vk::SampleCountFlags::TYPE_1,
tiling: vk::ImageTiling::OPTIMAL,
usage: vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT,
sharing_mode: vk::SharingMode::EXCLUSIVE,
queue_family_index_count: 0,
p_queue_family_indices: ptr::null(),
initial_layout: vk::ImageLayout::Undefined,
initial_layout: vk::ImageLayout::UNDEFINED,
};
let depth_image = device.create_image(&depth_image_create_info, None).unwrap();
let depth_image_memory_req = device.get_image_memory_requirements(depth_image);
let depth_image_memory_index =
find_memorytype_index(
&depth_image_memory_req,
&device_memory_properties,
vk::MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
).expect("Unable to find suitable memory index for depth image.");
let depth_image_memory_index = find_memorytype_index(
&depth_image_memory_req,
&device_memory_properties,
vk::MemoryPropertyFlags::DEVICE_LOCAL,
).expect("Unable to find suitable memory index for depth image.");
let depth_image_allocate_info = vk::MemoryAllocateInfo {
s_type: vk::StructureType::MemoryAllocateInfo,
s_type: vk::StructureType::MEMORY_ALLOCATE_INFO,
p_next: ptr::null(),
allocation_size: depth_image_memory_req.size,
memory_type_index: depth_image_memory_index,
@ -611,23 +608,23 @@ impl ExampleBase {
&device,
setup_command_buffer,
present_queue,
&[vk::PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT],
&[vk::PipelineStageFlags::BOTTOM_OF_PIPE],
&[],
&[],
|device, setup_command_buffer| {
let layout_transition_barrier = vk::ImageMemoryBarrier {
s_type: vk::StructureType::ImageMemoryBarrier,
s_type: vk::StructureType::IMAGE_MEMORY_BARRIER,
p_next: ptr::null(),
src_access_mask: Default::default(),
dst_access_mask: vk::ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
| vk::ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
old_layout: vk::ImageLayout::Undefined,
new_layout: vk::ImageLayout::DepthStencilAttachmentOptimal,
src_queue_family_index: vk::VK_QUEUE_FAMILY_IGNORED,
dst_queue_family_index: vk::VK_QUEUE_FAMILY_IGNORED,
dst_access_mask: vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ
| vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE,
old_layout: vk::ImageLayout::UNDEFINED,
new_layout: vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
src_queue_family_index: vk::QUEUE_FAMILY_IGNORED,
dst_queue_family_index: vk::QUEUE_FAMILY_IGNORED,
image: depth_image,
subresource_range: vk::ImageSubresourceRange {
aspect_mask: vk::IMAGE_ASPECT_DEPTH_BIT,
aspect_mask: vk::ImageAspectFlags::DEPTH,
base_mip_level: 0,
level_count: 1,
base_array_layer: 0,
@ -636,8 +633,8 @@ impl ExampleBase {
};
device.cmd_pipeline_barrier(
setup_command_buffer,
vk::PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
vk::PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
vk::PipelineStageFlags::BOTTOM_OF_PIPE,
vk::PipelineStageFlags::LATE_FRAGMENT_TESTS,
vk::DependencyFlags::empty(),
&[],
&[],
@ -646,19 +643,19 @@ impl ExampleBase {
},
);
let depth_image_view_info = vk::ImageViewCreateInfo {
s_type: vk::StructureType::ImageViewCreateInfo,
s_type: vk::StructureType::IMAGE_VIEW_CREATE_INFO,
p_next: ptr::null(),
flags: Default::default(),
view_type: vk::ImageViewType::Type2d,
view_type: vk::ImageViewType::TYPE_2D,
format: depth_image_create_info.format,
components: vk::ComponentMapping {
r: vk::ComponentSwizzle::Identity,
g: vk::ComponentSwizzle::Identity,
b: vk::ComponentSwizzle::Identity,
a: vk::ComponentSwizzle::Identity,
r: vk::ComponentSwizzle::IDENTITY,
g: vk::ComponentSwizzle::IDENTITY,
b: vk::ComponentSwizzle::IDENTITY,
a: vk::ComponentSwizzle::IDENTITY,
},
subresource_range: vk::ImageSubresourceRange {
aspect_mask: vk::IMAGE_ASPECT_DEPTH_BIT,
aspect_mask: vk::ImageAspectFlags::DEPTH,
base_mip_level: 0,
level_count: 1,
base_array_layer: 0,
@ -670,7 +667,7 @@ impl ExampleBase {
.create_image_view(&depth_image_view_info, None)
.unwrap();
let semaphore_create_info = vk::SemaphoreCreateInfo {
s_type: vk::StructureType::SemaphoreCreateInfo,
s_type: vk::StructureType::SEMAPHORE_CREATE_INFO,
p_next: ptr::null(),
flags: Default::default(),
};

20
generator/Cargo.toml Normal file
View file

@ -0,0 +1,20 @@
[package]
name = "generator"
version = "0.1.0"
authors = ["Maik Klein <maikklein@googlemail.com>"]
[dependencies]
vk-parse = "0.1"
vkxml = "0.3"
nom = "4.0"
heck = "0.3"
proc-macro2 = "0.2"
itertools = "0.7"
[dependencies.quote]
version = "0.4.2"
[dependencies.syn]
version = "0.12.14"
features = ["full", "extra-traits"]

@ -0,0 +1 @@
Subproject commit 718a04e51b967fbe6de9d09ecfc15397f0eae5bd

View file

@ -0,0 +1,7 @@
extern crate generator;
use generator::write_source_code;
use std::path::Path;
fn main() {
write_source_code(Path::new("Vulkan-Headers/registry/vk.xml"));
}

1899
generator/src/lib.rs Normal file

File diff suppressed because it is too large Load diff