Merge branch 'generator'
This commit is contained in:
commit
69f3644362
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
||||||
target
|
target
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
!examples/Cargo.lock
|
!examples/Cargo.lock
|
||||||
|
.idea
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "generator/Vulkan-Headers"]
|
||||||
|
path = generator/Vulkan-Headers
|
||||||
|
url = https://github.com/KhronosGroup/Vulkan-Headers
|
|
@ -6,3 +6,4 @@ rust:
|
||||||
script:
|
script:
|
||||||
- cargo build --manifest-path ash/Cargo.toml
|
- cargo build --manifest-path ash/Cargo.toml
|
||||||
- cargo build --manifest-path examples/Cargo.toml
|
- cargo build --manifest-path examples/Cargo.toml
|
||||||
|
- cargo build --manifest-path generator/Cargo.toml
|
||||||
|
|
|
@ -2,4 +2,5 @@
|
||||||
members = [
|
members = [
|
||||||
"examples",
|
"examples",
|
||||||
"ash",
|
"ash",
|
||||||
|
"generator",
|
||||||
]
|
]
|
||||||
|
|
45
Changelog.md
45
Changelog.md
|
@ -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.
|
can write to aligned memory.
|
||||||
|
|
166
README.md
166
README.md
|
@ -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)
|
[![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)
|
[![](https://tokei.rs/b1/github/maikklein/ash)](https://github.com/MaikKlein/ash)
|
||||||
|
|
||||||
## Stable yet?
|
## Overview
|
||||||
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).
|
- [x] A true Vulkan API without compromises
|
||||||
|
- [x] Convenience features that don't limit the functionality
|
||||||
## Why Ash?
|
- [x] Function pointer loading
|
||||||
- [x] Lightweight Vulkan wrapper
|
- [x] No validation, everything is **unsafe**
|
||||||
- [x] Low overhead
|
- [x] Generated from `vk.xml`
|
||||||
- [x] Additional type safety
|
|
||||||
- [x] Trait based, version specific loader
|
|
||||||
|
|
||||||
## What does it do?
|
|
||||||
|
|
||||||
|
## Features
|
||||||
### Explicit returns with `Result`
|
### 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
|
```Rust
|
||||||
// function signature
|
// function signature
|
||||||
pub fn create_instance(&self,
|
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
|
```Rust
|
||||||
pub fn get_swapchain_images_khr(&self,
|
pub fn get_swapchain_images_khr(&self,
|
||||||
swapchain: vk::SwapchainKHR)
|
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();
|
let present_images = swapchain_loader.get_swapchain_images_khr(swapchain).unwrap();
|
||||||
```
|
```
|
||||||
|
|
||||||
### Slices
|
### Slices in functions
|
||||||
Ash always uses slices in functions.
|
|
||||||
```Rust
|
```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,
|
pub fn cmd_pipeline_barrier(&self,
|
||||||
command_buffer: vk::CommandBuffer,
|
command_buffer: vk::CommandBuffer,
|
||||||
src_stage_mask: vk::PipelineStageFlags,
|
src_stage_mask: vk::PipelineStageFlags,
|
||||||
|
@ -68,77 +50,61 @@ pub fn cmd_pipeline_barrier(&self,
|
||||||
memory_barriers: &[vk::MemoryBarrier],
|
memory_barriers: &[vk::MemoryBarrier],
|
||||||
buffer_memory_barriers: &[vk::BufferMemoryBarrier],
|
buffer_memory_barriers: &[vk::BufferMemoryBarrier],
|
||||||
image_memory_barriers: &[vk::ImageMemoryBarrier]);
|
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
|
### Default implementation for all types
|
||||||
Ash still uses raw Vulkan structs. The only difference is type safety. Everything that can be an enum is an enum like `vk::StructureType`, flags are implemented similar to the `Bitflags` crate. Ash also follows the Rust style guide. The reason that Ash uses raw Vulkan structs is to be extensible, just like the Vulkan spec.
|
|
||||||
```Rust
|
```Rust
|
||||||
let pool_create_info = vk::CommandPoolCreateInfo {
|
// No need to manually set the structure type
|
||||||
s_type: vk::StructureType::CommandPoolCreateInfo,
|
let desc_alloc_info = vk::DescriptorSetAllocateInfo {
|
||||||
p_next: ptr::null(),
|
descriptor_pool: self.pool,
|
||||||
flags: vk::COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
|
descriptor_set_count: self.layouts.len() as u32,
|
||||||
queue_family_index: queue_family_index,
|
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
|
### 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 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
|
### 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
|
```Rust
|
||||||
use ash::extensions::Swapchain;
|
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();
|
let swapchain = swapchain_loader.create_swapchain_khr(&swapchain_create_info).unwrap();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -156,16 +122,8 @@ fn extension_names() -> Vec<*const i8> {
|
||||||
```
|
```
|
||||||
|
|
||||||
### Implicit handles
|
### 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
|
```Rust
|
||||||
// C
|
|
||||||
VkResult vkCreateCommandPool(
|
|
||||||
VkDevice device,
|
|
||||||
const VkCommandPoolCreateInfo* pCreateInfo,
|
|
||||||
const VkAllocationCallbacks* pAllocator,
|
|
||||||
VkCommandPool* pCommandPool);
|
|
||||||
|
|
||||||
// Rust
|
|
||||||
pub fn create_command_pool(&self,
|
pub fn create_command_pool(&self,
|
||||||
create_info: &vk::CommandPoolCreateInfo)
|
create_info: &vk::CommandPoolCreateInfo)
|
||||||
-> VkResult<vk::CommandPool>;
|
-> VkResult<vk::CommandPool>;
|
||||||
|
@ -203,24 +161,6 @@ cargo run --bin texture
|
||||||
```
|
```
|
||||||
![texture](http://i.imgur.com/trow00H.png)
|
![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
|
## A thanks to
|
||||||
|
|
||||||
* [Api with no secrets](https://software.intel.com/en-us/articles/api-without-secrets-introduction-to-vulkan-part-1)
|
* [Api with no secrets](https://software.intel.com/en-us/articles/api-without-secrets-introduction-to-vulkan-part-1)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
environment:
|
environment:
|
||||||
matrix:
|
matrix:
|
||||||
- TARGET: 1.21.0-x86_64-pc-windows
|
- TARGET: 1.28.0-x86_64-pc-windows
|
||||||
COMPILER: msvc
|
COMPILER: msvc
|
||||||
install:
|
install:
|
||||||
- if %COMPILER%==gnu choco install -y mingw
|
- if %COMPILER%==gnu choco install -y mingw
|
||||||
|
|
|
@ -12,7 +12,6 @@ documentation = "https://docs.rs/ash"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
shared_library = "0.1.9"
|
shared_library = "0.1.9"
|
||||||
lazy_static = "0.2.1"
|
lazy_static = "0.2.1"
|
||||||
libc = "0.2.26"
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
|
|
@ -1,30 +1,31 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use vk;
|
use vk;
|
||||||
|
use std::os::raw::c_void;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
pub trait VkAllocation {
|
pub trait VkAllocation {
|
||||||
unsafe extern "system" fn allocation(
|
unsafe extern "system" fn allocation(
|
||||||
*mut (),
|
*mut (),
|
||||||
vk::size_t,
|
usize,
|
||||||
vk::size_t,
|
usize,
|
||||||
vk::SystemAllocationScope,
|
vk::SystemAllocationScope,
|
||||||
) -> *mut ();
|
) -> *mut ();
|
||||||
unsafe extern "system" fn reallocation(
|
unsafe extern "system" fn reallocation(
|
||||||
*mut vk::c_void,
|
*mut c_void,
|
||||||
*mut vk::c_void,
|
*mut c_void,
|
||||||
vk::size_t,
|
usize,
|
||||||
vk::size_t,
|
usize,
|
||||||
vk::SystemAllocationScope,
|
vk::SystemAllocationScope,
|
||||||
) -> *mut vk::c_void;
|
) -> *mut c_void;
|
||||||
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(
|
unsafe extern "system" fn internal_allocation(
|
||||||
*mut vk::c_void,
|
*mut c_void,
|
||||||
vk::size_t,
|
usize,
|
||||||
vk::InternalAllocationType,
|
vk::InternalAllocationType,
|
||||||
vk::SystemAllocationScope,
|
vk::SystemAllocationScope,
|
||||||
);
|
);
|
||||||
unsafe extern "system" fn internal_free(
|
unsafe extern "system" fn internal_free(
|
||||||
*mut vk::c_void,
|
*mut c_void,
|
||||||
vk::size_t,
|
usize,
|
||||||
vk::InternalAllocationType,
|
vk::InternalAllocationType,
|
||||||
vk::SystemAllocationScope,
|
vk::SystemAllocationScope,
|
||||||
);
|
);
|
||||||
|
@ -47,33 +48,33 @@ pub struct TestAlloc;
|
||||||
impl VkAllocation for TestAlloc {
|
impl VkAllocation for TestAlloc {
|
||||||
unsafe extern "system" fn allocation(
|
unsafe extern "system" fn allocation(
|
||||||
_: *mut (),
|
_: *mut (),
|
||||||
_: vk::size_t,
|
_: usize,
|
||||||
_: vk::size_t,
|
_: usize,
|
||||||
_: vk::SystemAllocationScope,
|
_: vk::SystemAllocationScope,
|
||||||
) -> *mut () {
|
) -> *mut () {
|
||||||
ptr::null_mut()
|
ptr::null_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "system" fn reallocation(
|
unsafe extern "system" fn reallocation(
|
||||||
_: *mut vk::c_void,
|
_: *mut c_void,
|
||||||
_: *mut vk::c_void,
|
_: *mut c_void,
|
||||||
_: vk::size_t,
|
_: usize,
|
||||||
_: vk::size_t,
|
_: usize,
|
||||||
_: vk::SystemAllocationScope,
|
_: vk::SystemAllocationScope,
|
||||||
) -> *mut vk::c_void {
|
) -> *mut c_void {
|
||||||
ptr::null_mut()
|
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(
|
unsafe extern "system" fn internal_allocation(
|
||||||
_: *mut vk::c_void,
|
_: *mut c_void,
|
||||||
_: vk::size_t,
|
_: usize,
|
||||||
_: vk::InternalAllocationType,
|
_: vk::InternalAllocationType,
|
||||||
_: vk::SystemAllocationScope,
|
_: vk::SystemAllocationScope,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
unsafe extern "system" fn internal_free(
|
unsafe extern "system" fn internal_free(
|
||||||
_: *mut vk::c_void,
|
_: *mut c_void,
|
||||||
_: vk::size_t,
|
_: usize,
|
||||||
_: vk::InternalAllocationType,
|
_: vk::InternalAllocationType,
|
||||||
_: vk::SystemAllocationScope,
|
_: vk::SystemAllocationScope,
|
||||||
) {
|
) {
|
||||||
|
@ -82,33 +83,33 @@ impl VkAllocation for TestAlloc {
|
||||||
impl VkAllocation for DefaultAllocatorCallback {
|
impl VkAllocation for DefaultAllocatorCallback {
|
||||||
unsafe extern "system" fn allocation(
|
unsafe extern "system" fn allocation(
|
||||||
_: *mut (),
|
_: *mut (),
|
||||||
_: vk::size_t,
|
_: usize,
|
||||||
_: vk::size_t,
|
_: usize,
|
||||||
_: vk::SystemAllocationScope,
|
_: vk::SystemAllocationScope,
|
||||||
) -> *mut () {
|
) -> *mut () {
|
||||||
ptr::null_mut()
|
ptr::null_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "system" fn reallocation(
|
unsafe extern "system" fn reallocation(
|
||||||
_: *mut vk::c_void,
|
_: *mut c_void,
|
||||||
_: *mut vk::c_void,
|
_: *mut c_void,
|
||||||
_: vk::size_t,
|
_: usize,
|
||||||
_: vk::size_t,
|
_: usize,
|
||||||
_: vk::SystemAllocationScope,
|
_: vk::SystemAllocationScope,
|
||||||
) -> *mut vk::c_void {
|
) -> *mut c_void {
|
||||||
ptr::null_mut()
|
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(
|
unsafe extern "system" fn internal_allocation(
|
||||||
_: *mut vk::c_void,
|
_: *mut c_void,
|
||||||
_: vk::size_t,
|
_: usize,
|
||||||
_: vk::InternalAllocationType,
|
_: vk::InternalAllocationType,
|
||||||
_: vk::SystemAllocationScope,
|
_: vk::SystemAllocationScope,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
unsafe extern "system" fn internal_free(
|
unsafe extern "system" fn internal_free(
|
||||||
_: *mut vk::c_void,
|
_: *mut c_void,
|
||||||
_: vk::size_t,
|
_: usize,
|
||||||
_: vk::InternalAllocationType,
|
_: vk::InternalAllocationType,
|
||||||
_: vk::SystemAllocationScope,
|
_: vk::SystemAllocationScope,
|
||||||
) {
|
) {
|
||||||
|
|
File diff suppressed because it is too large
Load diff
163
ash/src/entry.rs
163
ash/src/entry.rs
|
@ -1,45 +1,53 @@
|
||||||
use prelude::*;
|
|
||||||
use std::mem;
|
|
||||||
use std::ptr;
|
|
||||||
use vk;
|
|
||||||
use instance::Instance;
|
use instance::Instance;
|
||||||
|
use prelude::*;
|
||||||
use shared_library::dynamic_library::DynamicLibrary;
|
use shared_library::dynamic_library::DynamicLibrary;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::mem;
|
||||||
|
use std::os::raw::c_char;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::ptr;
|
||||||
|
use vk;
|
||||||
use RawPtr;
|
use RawPtr;
|
||||||
use version::{EntryLoader, FunctionPointers, InstanceLoader, V1_0};
|
|
||||||
use std::sync::Arc;
|
|
||||||
use libc;
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
const LIB_PATH: &'static str = "vulkan-1.dll";
|
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";
|
const LIB_PATH: &'static str = "libvulkan.so.1";
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
const LIB_PATH: &'static str = "libvulkan.so";
|
const LIB_PATH: &'static str = "libvulkan.so";
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||||
const LIB_PATH: &'static str = "libvulkan.1.dylib";
|
|
||||||
|
|
||||||
#[cfg(target_os = "ios")]
|
|
||||||
const LIB_PATH: &'static str = "libMoltenVK.dylib";
|
const LIB_PATH: &'static str = "libMoltenVK.dylib";
|
||||||
|
|
||||||
#[derive(Clone)]
|
lazy_static! {
|
||||||
pub struct EntryCustom<V: FunctionPointers, L> {
|
static ref VK_LIB: Result<DynamicLibrary, String> =
|
||||||
static_fn: vk::StaticFn,
|
DynamicLibrary::open(Some(&Path::new(LIB_PATH)));
|
||||||
entry_fn: V::EntryFp,
|
}
|
||||||
vk_lib: L,
|
|
||||||
|
#[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)]
|
#[derive(Debug)]
|
||||||
pub enum LoadingError {
|
pub enum LoadingError {
|
||||||
LibraryLoadError(String),
|
LibraryLoadError(String),
|
||||||
EntryLoadError(Vec<&'static str>),
|
|
||||||
StaticLoadError(Vec<&'static str>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -69,32 +77,14 @@ impl Error for InstanceError {
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub trait EntryV1_0 {
|
pub trait EntryV1_0 {
|
||||||
type Fp: FunctionPointers;
|
type Instance;
|
||||||
fn fp_v1_0(&self) -> &vk::EntryFnV1_0;
|
fn fp_v1_0(&self) -> &vk::EntryFnV1_0;
|
||||||
fn static_fn(&self) -> &vk::StaticFn;
|
fn static_fn(&self) -> &vk::StaticFn;
|
||||||
|
|
||||||
unsafe fn create_instance(
|
unsafe fn create_instance(
|
||||||
&self,
|
&self,
|
||||||
create_info: &vk::InstanceCreateInfo,
|
create_info: &vk::InstanceCreateInfo,
|
||||||
allocation_callbacks: Option<&vk::AllocationCallbacks>,
|
allocation_callbacks: Option<&vk::AllocationCallbacks>,
|
||||||
) -> Result<Instance<Self::Fp>, InstanceError> {
|
) -> 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));
|
|
||||||
}
|
|
||||||
let instance_fp =
|
|
||||||
<Self::Fp as FunctionPointers>::InstanceFp::load(
|
|
||||||
&self.static_fn(),
|
|
||||||
instance,
|
|
||||||
).map_err(InstanceError::LoadError)?;
|
|
||||||
Ok(Instance::from_raw(instance, instance_fp))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn enumerate_instance_layer_properties(&self) -> VkResult<Vec<vk::LayerProperties>> {
|
fn enumerate_instance_layer_properties(&self) -> VkResult<Vec<vk::LayerProperties>> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut num = 0;
|
let mut num = 0;
|
||||||
|
@ -102,16 +92,16 @@ pub trait EntryV1_0 {
|
||||||
.enumerate_instance_layer_properties(&mut num, ptr::null_mut());
|
.enumerate_instance_layer_properties(&mut num, ptr::null_mut());
|
||||||
|
|
||||||
let mut v = Vec::with_capacity(num as usize);
|
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());
|
.enumerate_instance_layer_properties(&mut num, v.as_mut_ptr());
|
||||||
v.set_len(num as usize);
|
v.set_len(num as usize);
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(v),
|
vk::Result::SUCCESS => Ok(v),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enumerate_instance_extension_properties(&self) -> VkResult<Vec<vk::ExtensionProperties>> {
|
fn enumerate_instance_extension_properties(&self) -> VkResult<Vec<vk::ExtensionProperties>> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut num = 0;
|
let mut num = 0;
|
||||||
|
@ -128,7 +118,7 @@ pub trait EntryV1_0 {
|
||||||
);
|
);
|
||||||
data.set_len(num as usize);
|
data.set_len(num as usize);
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(data),
|
vk::Result::SUCCESS => Ok(data),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,56 +127,77 @@ pub trait EntryV1_0 {
|
||||||
fn get_instance_proc_addr(
|
fn get_instance_proc_addr(
|
||||||
&self,
|
&self,
|
||||||
instance: vk::Instance,
|
instance: vk::Instance,
|
||||||
p_name: *const vk::c_char,
|
p_name: *const c_char,
|
||||||
) -> vk::PFN_vkVoidFunction {
|
) -> vk::PFN_vkVoidFunction {
|
||||||
unsafe { self.static_fn().get_instance_proc_addr(instance, p_name) }
|
unsafe { self.static_fn().get_instance_proc_addr(instance, p_name) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<L> EntryV1_0 for EntryCustom<V1_0, L> {
|
impl EntryV1_0 for Entry {
|
||||||
type Fp = V1_0;
|
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 {
|
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 {
|
fn static_fn(&self) -> &vk::StaticFn {
|
||||||
&self.static_fn
|
&self.static_fn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: FunctionPointers, L> EntryCustom<V, L> {
|
impl Entry {
|
||||||
pub fn new_custom<OpenFunc, LoadFunc>(o: OpenFunc, mut l: LoadFunc) -> Result<Self, LoadingError>
|
pub fn new() -> Result<Self, LoadingError> {
|
||||||
where
|
let lib = VK_LIB
|
||||||
OpenFunc: FnOnce() -> Result<L, LoadingError>,
|
.as_ref()
|
||||||
LoadFunc: FnMut(&mut L, &::std::ffi::CStr) -> *const libc::c_void,
|
.map_err(|err| LoadingError::LibraryLoadError(err.clone()))?;
|
||||||
{
|
|
||||||
let mut vk_lib = o()?;
|
|
||||||
let static_fn =
|
|
||||||
vk::StaticFn::load(|name| l(&mut vk_lib, name)).map_err(LoadingError::StaticLoadError)?;
|
|
||||||
|
|
||||||
let entry_fn =
|
let static_fn = vk::StaticFn::load(|name| unsafe {
|
||||||
unsafe { V::EntryFp::load(&static_fn) }.map_err(LoadingError::EntryLoadError)?;
|
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,
|
static_fn,
|
||||||
entry_fn,
|
entry_fn_1_0,
|
||||||
vk_lib,
|
entry_fn_1_1,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: FunctionPointers> Entry<V> {
|
#[allow(non_camel_case_types)]
|
||||||
pub fn new() -> Result<Self, LoadingError> {
|
pub trait EntryV1_1: EntryV1_0 {
|
||||||
Self::new_custom(
|
fn fp_v1_1(&self) -> &vk::EntryFnV1_1;
|
||||||
|| {
|
|
||||||
DynamicLibrary::open(Some(&Path::new(LIB_PATH)))
|
fn enumerate_instance_version(&self) -> VkResult<u32> {
|
||||||
.map_err(|err| LoadingError::LibraryLoadError(err.clone()))
|
unsafe {
|
||||||
.map(|dl| Arc::new(dl))
|
let mut api_version = 0;
|
||||||
},
|
let err_code = self.fp_v1_1().enumerate_instance_version(&mut api_version);
|
||||||
|vk_lib, name| unsafe {
|
match err_code {
|
||||||
vk_lib
|
vk::Result::SUCCESS => Ok(api_version),
|
||||||
.symbol(&*name.to_string_lossy())
|
_ => Err(err_code),
|
||||||
.unwrap_or(ptr::null_mut())
|
}
|
||||||
},
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,29 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
use std::mem;
|
|
||||||
use vk;
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use RawPtr;
|
use std::mem;
|
||||||
use version::{EntryV1_0, InstanceV1_0};
|
use version::{EntryV1_0, InstanceV1_0};
|
||||||
|
use vk;
|
||||||
|
use RawPtr;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct AndroidSurface {
|
pub struct AndroidSurface {
|
||||||
handle: vk::Instance,
|
handle: vk::Instance,
|
||||||
android_surface_fn: vk::AndroidSurfaceFn,
|
android_surface_fn: vk::KhrAndroidSurfaceFn,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AndroidSurface {
|
impl AndroidSurface {
|
||||||
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
|
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
|
||||||
entry: &E,
|
entry: &E,
|
||||||
instance: &I,
|
instance: &I,
|
||||||
) -> Result<AndroidSurface, Vec<&'static str>> {
|
) -> AndroidSurface {
|
||||||
let surface_fn = vk::AndroidSurfaceFn::load(|name| unsafe {
|
let surface_fn = vk::KhrAndroidSurfaceFn::load(|name| unsafe {
|
||||||
mem::transmute(entry.get_instance_proc_addr(
|
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
|
||||||
instance.handle(),
|
});
|
||||||
name.as_ptr(),
|
AndroidSurface {
|
||||||
))
|
|
||||||
})?;
|
|
||||||
Ok(AndroidSurface {
|
|
||||||
handle: instance.handle(),
|
handle: instance.handle(),
|
||||||
android_surface_fn: surface_fn,
|
android_surface_fn: surface_fn,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
|
@ -46,7 +43,7 @@ impl AndroidSurface {
|
||||||
&mut surface,
|
&mut surface,
|
||||||
);
|
);
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(surface),
|
vk::Result::SUCCESS => Ok(surface),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,26 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
use std::mem;
|
|
||||||
use vk;
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use version::{InstanceV1_0, DeviceV1_0};
|
use std::mem;
|
||||||
|
use version::{DeviceV1_0, InstanceV1_0};
|
||||||
|
use vk;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct DebugMarker {
|
pub struct DebugMarker {
|
||||||
debug_marker_fn: vk::DebugMarkerFn,
|
debug_marker_fn: vk::ExtDebugMarkerFn,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DebugMarker {
|
impl DebugMarker {
|
||||||
pub fn new<I: InstanceV1_0, D: DeviceV1_0>(
|
pub fn new<I: InstanceV1_0, D: DeviceV1_0>(
|
||||||
instance: &I,
|
instance: &I,
|
||||||
device: &D
|
device: &D,
|
||||||
) -> Result<DebugMarker, Vec<&'static str>> {
|
) -> DebugMarker {
|
||||||
let debug_marker_fn = vk::DebugMarkerFn::load(|name| unsafe {
|
let debug_marker_fn = vk::ExtDebugMarkerFn::load(|name| unsafe {
|
||||||
mem::transmute(instance.get_device_proc_addr(
|
mem::transmute(instance.get_device_proc_addr(device.handle(), name.as_ptr()))
|
||||||
device.handle(),
|
});
|
||||||
name.as_ptr(),
|
DebugMarker {
|
||||||
))
|
|
||||||
})?;
|
|
||||||
Ok(DebugMarker {
|
|
||||||
debug_marker_fn: debug_marker_fn,
|
debug_marker_fn: debug_marker_fn,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
|
@ -33,46 +30,37 @@ impl DebugMarker {
|
||||||
pub unsafe fn debug_marker_set_object_name_ext(
|
pub unsafe fn debug_marker_set_object_name_ext(
|
||||||
&self,
|
&self,
|
||||||
device: vk::Device,
|
device: vk::Device,
|
||||||
name_info: &vk::DebugMarkerObjectNameInfoEXT
|
name_info: &vk::DebugMarkerObjectNameInfoEXT,
|
||||||
) -> VkResult<()> {
|
) -> VkResult<()> {
|
||||||
let err_code = self.debug_marker_fn.debug_marker_set_object_name_ext(
|
let err_code = self
|
||||||
device,
|
.debug_marker_fn
|
||||||
name_info
|
.debug_marker_set_object_name_ext(device, name_info);
|
||||||
);
|
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(()),
|
vk::Result::SUCCESS => Ok(()),
|
||||||
_ => Err(err_code)
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn cmd_debug_marker_begin_ext(
|
pub unsafe fn cmd_debug_marker_begin_ext(
|
||||||
&self,
|
&self,
|
||||||
command_buffer: vk::CommandBuffer,
|
command_buffer: vk::CommandBuffer,
|
||||||
marker_info: &vk::DebugMarkerMarkerInfoEXT
|
marker_info: &vk::DebugMarkerMarkerInfoEXT,
|
||||||
) {
|
) {
|
||||||
self.debug_marker_fn.cmd_debug_marker_begin_ext(
|
self.debug_marker_fn
|
||||||
command_buffer,
|
.cmd_debug_marker_begin_ext(command_buffer, marker_info);
|
||||||
marker_info
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn cmd_debug_marker_end_ext(
|
pub unsafe fn cmd_debug_marker_end_ext(&self, command_buffer: vk::CommandBuffer) {
|
||||||
&self,
|
self.debug_marker_fn
|
||||||
command_buffer: vk::CommandBuffer,
|
.cmd_debug_marker_end_ext(command_buffer);
|
||||||
) {
|
|
||||||
self.debug_marker_fn.cmd_debug_marker_end_ext(
|
|
||||||
command_buffer,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn cmd_debug_marker_insert_ext(
|
pub unsafe fn cmd_debug_marker_insert_ext(
|
||||||
&self,
|
&self,
|
||||||
command_buffer: vk::CommandBuffer,
|
command_buffer: vk::CommandBuffer,
|
||||||
marker_info: &vk::DebugMarkerMarkerInfoEXT
|
marker_info: &vk::DebugMarkerMarkerInfoEXT,
|
||||||
) {
|
) {
|
||||||
self.debug_marker_fn.cmd_debug_marker_insert_ext(
|
self.debug_marker_fn
|
||||||
command_buffer,
|
.cmd_debug_marker_insert_ext(command_buffer, marker_info);
|
||||||
marker_info
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,29 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
use std::mem;
|
|
||||||
use vk;
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use RawPtr;
|
use std::mem;
|
||||||
use version::{EntryV1_0, InstanceV1_0};
|
use version::{EntryV1_0, InstanceV1_0};
|
||||||
|
use vk;
|
||||||
|
use RawPtr;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct DebugReport {
|
pub struct DebugReport {
|
||||||
handle: vk::Instance,
|
handle: vk::Instance,
|
||||||
debug_report_fn: vk::DebugReportFn,
|
debug_report_fn: vk::ExtDebugReportFn,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DebugReport {
|
impl DebugReport {
|
||||||
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
|
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
|
||||||
entry: &E,
|
entry: &E,
|
||||||
instance: &I,
|
instance: &I,
|
||||||
) -> Result<DebugReport, Vec<&'static str>> {
|
) -> DebugReport {
|
||||||
let debug_report_fn = vk::DebugReportFn::load(|name| unsafe {
|
let debug_report_fn = vk::ExtDebugReportFn::load(|name| unsafe {
|
||||||
mem::transmute(entry.get_instance_proc_addr(
|
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
|
||||||
instance.handle(),
|
});
|
||||||
name.as_ptr(),
|
DebugReport {
|
||||||
))
|
|
||||||
})?;
|
|
||||||
Ok(DebugReport {
|
|
||||||
handle: instance.handle(),
|
handle: instance.handle(),
|
||||||
debug_report_fn: debug_report_fn,
|
debug_report_fn,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
|
@ -58,7 +55,7 @@ impl DebugReport {
|
||||||
&mut debug_cb,
|
&mut debug_cb,
|
||||||
);
|
);
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(debug_cb),
|
vk::Result::SUCCESS => Ok(debug_cb),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
145
ash/src/extensions/debug_utils.rs
Normal file
145
ash/src/extensions/debug_utils.rs
Normal 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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,32 +1,29 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
use std::mem;
|
|
||||||
use vk;
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
use std::mem;
|
||||||
|
use version::{DeviceV1_0, InstanceV1_0};
|
||||||
|
use vk;
|
||||||
use RawPtr;
|
use RawPtr;
|
||||||
use version::{InstanceV1_0, DeviceV1_0};
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct DisplaySwapchain {
|
pub struct DisplaySwapchain {
|
||||||
handle: vk::Device,
|
handle: vk::Device,
|
||||||
swapchain_fn: vk::DisplaySwapchainFn,
|
swapchain_fn: vk::KhrDisplaySwapchainFn,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DisplaySwapchain {
|
impl DisplaySwapchain {
|
||||||
pub fn new<I: InstanceV1_0, D: DeviceV1_0>(
|
pub fn new<I: InstanceV1_0, D: DeviceV1_0>(
|
||||||
instance: &I,
|
instance: &I,
|
||||||
device: &D,
|
device: &D,
|
||||||
) -> Result<DisplaySwapchain, Vec<&'static str>> {
|
) -> DisplaySwapchain {
|
||||||
let swapchain_fn = vk::DisplaySwapchainFn::load(|name| unsafe {
|
let swapchain_fn = vk::KhrDisplaySwapchainFn::load(|name| unsafe {
|
||||||
mem::transmute(instance.get_device_proc_addr(
|
mem::transmute(instance.get_device_proc_addr(device.handle(), name.as_ptr()))
|
||||||
device.handle(),
|
});
|
||||||
name.as_ptr(),
|
DisplaySwapchain {
|
||||||
))
|
|
||||||
})?;
|
|
||||||
Ok(DisplaySwapchain {
|
|
||||||
handle: device.handle(),
|
handle: device.handle(),
|
||||||
swapchain_fn: swapchain_fn,
|
swapchain_fn: swapchain_fn,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
|
@ -48,7 +45,7 @@ impl DisplaySwapchain {
|
||||||
);
|
);
|
||||||
swapchains.set_len(create_infos.len());
|
swapchains.set_len(create_infos.len());
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(swapchains),
|
vk::Result::SUCCESS => Ok(swapchains),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,29 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
use std::mem;
|
|
||||||
use vk;
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use RawPtr;
|
use std::mem;
|
||||||
use version::{EntryV1_0, InstanceV1_0};
|
use version::{EntryV1_0, InstanceV1_0};
|
||||||
|
use vk;
|
||||||
|
use RawPtr;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct IOSSurface {
|
pub struct IOSSurface {
|
||||||
handle: vk::Instance,
|
handle: vk::Instance,
|
||||||
ios_surface_fn: vk::IOSSurfaceFn,
|
ios_surface_fn: vk::MvkIosSurfaceFn,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IOSSurface {
|
impl IOSSurface {
|
||||||
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
|
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
|
||||||
entry: &E,
|
entry: &E,
|
||||||
instance: &I,
|
instance: &I,
|
||||||
) -> Result<IOSSurface, Vec<&'static str>> {
|
) -> IOSSurface{
|
||||||
let surface_fn = vk::IOSSurfaceFn::load(|name| unsafe {
|
let surface_fn = vk::MvkIosSurfaceFn::load(|name| unsafe {
|
||||||
mem::transmute(entry.get_instance_proc_addr(
|
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
|
||||||
instance.handle(),
|
});
|
||||||
name.as_ptr(),
|
IOSSurface {
|
||||||
))
|
|
||||||
})?;
|
|
||||||
Ok(IOSSurface {
|
|
||||||
handle: instance.handle(),
|
handle: instance.handle(),
|
||||||
ios_surface_fn: surface_fn,
|
ios_surface_fn: surface_fn,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
|
@ -46,7 +43,7 @@ impl IOSSurface {
|
||||||
&mut surface,
|
&mut surface,
|
||||||
);
|
);
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(surface),
|
vk::Result::SUCCESS => Ok(surface),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,52 +1,49 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
use std::mem;
|
|
||||||
use vk;
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use RawPtr;
|
use std::mem;
|
||||||
use version::{EntryV1_0, InstanceV1_0};
|
use version::{EntryV1_0, InstanceV1_0};
|
||||||
|
use vk;
|
||||||
|
use RawPtr;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct MacOSSurface {
|
pub struct MacOSSurface {
|
||||||
handle: vk::Instance,
|
handle: vk::Instance,
|
||||||
macos_surface_fn: vk::MacOSSurfaceFn,
|
macos_surface_fn: vk::MvkMacosSurfaceFn,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MacOSSurface {
|
impl MacOSSurface {
|
||||||
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
|
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
|
||||||
entry: &E,
|
entry: &E,
|
||||||
instance: &I,
|
instance: &I,
|
||||||
) -> Result<MacOSSurface, Vec<&'static str>> {
|
) -> MacOSSurface {
|
||||||
let surface_fn = vk::MacOSSurfaceFn::load(|name| unsafe {
|
let surface_fn = vk::MvkMacosSurfaceFn::load(|name| unsafe {
|
||||||
mem::transmute(entry.get_instance_proc_addr(
|
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
|
||||||
instance.handle(),
|
});
|
||||||
name.as_ptr(),
|
MacOSSurface {
|
||||||
))
|
|
||||||
})?;
|
|
||||||
Ok(MacOSSurface {
|
|
||||||
handle: instance.handle(),
|
handle: instance.handle(),
|
||||||
macos_surface_fn: surface_fn,
|
macos_surface_fn: surface_fn,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
CStr::from_bytes_with_nul(b"VK_MVK_macos_surface\0").expect("Wrong extension string")
|
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,
|
&self,
|
||||||
create_info: &vk::MacOSSurfaceCreateInfoMVK,
|
create_info: &vk::MacOSSurfaceCreateInfoMVK,
|
||||||
allocation_callbacks: Option<&vk::AllocationCallbacks>,
|
allocation_callbacks: Option<&vk::AllocationCallbacks>,
|
||||||
) -> VkResult<vk::SurfaceKHR> {
|
) -> VkResult<vk::SurfaceKHR> {
|
||||||
let mut surface = mem::uninitialized();
|
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,
|
self.handle,
|
||||||
create_info,
|
create_info,
|
||||||
allocation_callbacks.as_raw_ptr(),
|
allocation_callbacks.as_raw_ptr(),
|
||||||
&mut surface,
|
&mut surface,
|
||||||
);
|
);
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(surface),
|
vk::Result::SUCCESS => Ok(surface),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +1,27 @@
|
||||||
pub use self::swapchain::Swapchain;
|
pub use self::android_surface::AndroidSurface;
|
||||||
pub use self::display_swapchain::DisplaySwapchain;
|
|
||||||
pub use self::surface::Surface;
|
|
||||||
pub use self::xlib_surface::XlibSurface;
|
|
||||||
pub use self::debug_marker::DebugMarker;
|
pub use self::debug_marker::DebugMarker;
|
||||||
pub use self::debug_report::DebugReport;
|
pub use self::debug_report::DebugReport;
|
||||||
pub use self::win32_surface::Win32Surface;
|
pub use self::debug_utils::DebugUtils;
|
||||||
pub use self::mir_surface::MirSurface;
|
pub use self::display_swapchain::DisplaySwapchain;
|
||||||
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::ios_surface::IOSSurface;
|
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 android_surface;
|
||||||
mod display_swapchain;
|
|
||||||
mod surface;
|
|
||||||
mod xlib_surface;
|
|
||||||
mod win32_surface;
|
|
||||||
mod debug_marker;
|
mod debug_marker;
|
||||||
mod debug_report;
|
mod debug_report;
|
||||||
mod mir_surface;
|
mod debug_utils;
|
||||||
mod android_surface;
|
mod display_swapchain;
|
||||||
mod wayland_surface;
|
|
||||||
mod xcb_surface;
|
|
||||||
mod macos_surface;
|
|
||||||
mod ios_surface;
|
mod ios_surface;
|
||||||
|
mod macos_surface;
|
||||||
|
mod surface;
|
||||||
|
mod swapchain;
|
||||||
|
mod wayland_surface;
|
||||||
|
mod win32_surface;
|
||||||
|
mod xcb_surface;
|
||||||
|
mod xlib_surface;
|
||||||
|
|
|
@ -1,46 +1,42 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
use std::ptr;
|
|
||||||
use std::mem;
|
|
||||||
use vk;
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use RawPtr;
|
use std::mem;
|
||||||
|
use std::ptr;
|
||||||
use version::{EntryV1_0, InstanceV1_0};
|
use version::{EntryV1_0, InstanceV1_0};
|
||||||
|
use vk;
|
||||||
|
use RawPtr;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Surface {
|
pub struct Surface {
|
||||||
handle: vk::Instance,
|
handle: vk::Instance,
|
||||||
surface_fn: vk::SurfaceFn,
|
surface_fn: vk::KhrSurfaceFn,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Surface {
|
impl Surface {
|
||||||
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
|
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
|
||||||
entry: &E,
|
entry: &E,
|
||||||
instance: &I,
|
instance: &I,
|
||||||
) -> Result<Surface, Vec<&'static str>> {
|
) -> Surface {
|
||||||
let surface_fn = vk::SurfaceFn::load(|name| unsafe {
|
let surface_fn = vk::KhrSurfaceFn::load(|name| unsafe {
|
||||||
mem::transmute(entry.get_instance_proc_addr(
|
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
|
||||||
instance.handle(),
|
});
|
||||||
name.as_ptr(),
|
Surface {
|
||||||
))
|
|
||||||
})?;
|
|
||||||
Ok(Surface {
|
|
||||||
handle: instance.handle(),
|
handle: instance.handle(),
|
||||||
surface_fn: surface_fn,
|
surface_fn: surface_fn,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
CStr::from_bytes_with_nul(b"VK_KHR_surface\0").expect("Wrong extension string")
|
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,
|
&self,
|
||||||
physical_device: vk::PhysicalDevice,
|
physical_device: vk::PhysicalDevice,
|
||||||
queue_index: vk::uint32_t,
|
queue_index: u32,
|
||||||
surface: vk::SurfaceKHR,
|
surface: vk::SurfaceKHR,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
unsafe {
|
|
||||||
let mut b = mem::uninitialized();
|
let mut b = mem::uninitialized();
|
||||||
self.surface_fn.get_physical_device_surface_support_khr(
|
self.surface_fn.get_physical_device_surface_support_khr(
|
||||||
physical_device,
|
physical_device,
|
||||||
|
@ -50,13 +46,12 @@ impl Surface {
|
||||||
);
|
);
|
||||||
b > 0
|
b > 0
|
||||||
}
|
}
|
||||||
}
|
|
||||||
pub fn get_physical_device_surface_present_modes_khr(
|
pub unsafe fn get_physical_device_surface_present_modes_khr(
|
||||||
&self,
|
&self,
|
||||||
physical_device: vk::PhysicalDevice,
|
physical_device: vk::PhysicalDevice,
|
||||||
surface: vk::SurfaceKHR,
|
surface: vk::SurfaceKHR,
|
||||||
) -> VkResult<Vec<vk::PresentModeKHR>> {
|
) -> VkResult<Vec<vk::PresentModeKHR>> {
|
||||||
unsafe {
|
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
self.surface_fn
|
self.surface_fn
|
||||||
.get_physical_device_surface_present_modes_khr(
|
.get_physical_device_surface_present_modes_khr(
|
||||||
|
@ -66,7 +61,8 @@ impl Surface {
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
);
|
);
|
||||||
let mut v = Vec::with_capacity(count as usize);
|
let mut v = Vec::with_capacity(count as usize);
|
||||||
let err_code = self.surface_fn
|
let err_code = self
|
||||||
|
.surface_fn
|
||||||
.get_physical_device_surface_present_modes_khr(
|
.get_physical_device_surface_present_modes_khr(
|
||||||
physical_device,
|
physical_device,
|
||||||
surface,
|
surface,
|
||||||
|
@ -75,38 +71,35 @@ impl Surface {
|
||||||
);
|
);
|
||||||
v.set_len(count as usize);
|
v.set_len(count as usize);
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(v),
|
vk::Result::SUCCESS => Ok(v),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_physical_device_surface_capabilities_khr(
|
pub unsafe fn get_physical_device_surface_capabilities_khr(
|
||||||
&self,
|
&self,
|
||||||
physical_device: vk::PhysicalDevice,
|
physical_device: vk::PhysicalDevice,
|
||||||
surface: vk::SurfaceKHR,
|
surface: vk::SurfaceKHR,
|
||||||
) -> VkResult<vk::SurfaceCapabilitiesKHR> {
|
) -> VkResult<vk::SurfaceCapabilitiesKHR> {
|
||||||
unsafe {
|
|
||||||
let mut surface_capabilities = mem::uninitialized();
|
let mut surface_capabilities = mem::uninitialized();
|
||||||
let err_code = self.surface_fn
|
let err_code = self
|
||||||
|
.surface_fn
|
||||||
.get_physical_device_surface_capabilities_khr(
|
.get_physical_device_surface_capabilities_khr(
|
||||||
physical_device,
|
physical_device,
|
||||||
surface,
|
surface,
|
||||||
&mut surface_capabilities,
|
&mut surface_capabilities,
|
||||||
);
|
);
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(surface_capabilities),
|
vk::Result::SUCCESS => Ok(surface_capabilities),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_physical_device_surface_formats_khr(
|
pub unsafe fn get_physical_device_surface_formats_khr(
|
||||||
&self,
|
&self,
|
||||||
physical_device: vk::PhysicalDevice,
|
physical_device: vk::PhysicalDevice,
|
||||||
surface: vk::SurfaceKHR,
|
surface: vk::SurfaceKHR,
|
||||||
) -> VkResult<Vec<vk::SurfaceFormatKHR>> {
|
) -> VkResult<Vec<vk::SurfaceFormatKHR>> {
|
||||||
unsafe {
|
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
self.surface_fn.get_physical_device_surface_formats_khr(
|
self.surface_fn.get_physical_device_surface_formats_khr(
|
||||||
physical_device,
|
physical_device,
|
||||||
|
@ -123,11 +116,10 @@ impl Surface {
|
||||||
);
|
);
|
||||||
v.set_len(count as usize);
|
v.set_len(count as usize);
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(v),
|
vk::Result::SUCCESS => Ok(v),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn destroy_surface_khr(
|
pub unsafe fn destroy_surface_khr(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -1,33 +1,30 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
use std::ptr;
|
|
||||||
use std::mem;
|
|
||||||
use vk;
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
use std::mem;
|
||||||
|
use std::ptr;
|
||||||
|
use version::{DeviceV1_0, InstanceV1_0};
|
||||||
|
use vk;
|
||||||
use RawPtr;
|
use RawPtr;
|
||||||
use version::{InstanceV1_0, DeviceV1_0};
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Swapchain {
|
pub struct Swapchain {
|
||||||
handle: vk::Device,
|
handle: vk::Device,
|
||||||
swapchain_fn: vk::SwapchainFn,
|
swapchain_fn: vk::KhrSwapchainFn,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Swapchain {
|
impl Swapchain {
|
||||||
pub fn new<I: InstanceV1_0, D: DeviceV1_0>(
|
pub fn new<I: InstanceV1_0, D: DeviceV1_0>(
|
||||||
instance: &I,
|
instance: &I,
|
||||||
device: &D,
|
device: &D,
|
||||||
) -> Result<Swapchain, Vec<&'static str>> {
|
) -> Swapchain {
|
||||||
let swapchain_fn = vk::SwapchainFn::load(|name| unsafe {
|
let swapchain_fn = vk::KhrSwapchainFn::load(|name| unsafe {
|
||||||
mem::transmute(instance.get_device_proc_addr(
|
mem::transmute(instance.get_device_proc_addr(device.handle(), name.as_ptr()))
|
||||||
device.handle(),
|
});
|
||||||
name.as_ptr(),
|
Swapchain {
|
||||||
))
|
|
||||||
})?;
|
|
||||||
Ok(Swapchain {
|
|
||||||
handle: device.handle(),
|
handle: device.handle(),
|
||||||
swapchain_fn: swapchain_fn,
|
swapchain_fn: swapchain_fn,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
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(
|
pub unsafe fn acquire_next_image_khr(
|
||||||
&self,
|
&self,
|
||||||
swapchain: vk::SwapchainKHR,
|
swapchain: vk::SwapchainKHR,
|
||||||
timeout: vk::uint64_t,
|
timeout: u64,
|
||||||
semaphore: vk::Semaphore,
|
semaphore: vk::Semaphore,
|
||||||
fence: vk::Fence,
|
fence: vk::Fence,
|
||||||
) -> VkResult<vk::uint32_t> {
|
) -> VkResult<(u32, bool)> {
|
||||||
let mut index = mem::uninitialized();
|
let mut index = mem::uninitialized();
|
||||||
let err_code = self.swapchain_fn.acquire_next_image_khr(
|
let err_code = self.swapchain_fn.acquire_next_image_khr(
|
||||||
self.handle,
|
self.handle,
|
||||||
|
@ -63,7 +61,8 @@ impl Swapchain {
|
||||||
&mut index,
|
&mut index,
|
||||||
);
|
);
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(index),
|
vk::Result::SUCCESS => Ok((index, false)),
|
||||||
|
vk::Result::SUBOPTIMAL_KHR => Ok((index, true)),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,28 +80,29 @@ impl Swapchain {
|
||||||
&mut swapchain,
|
&mut swapchain,
|
||||||
);
|
);
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(swapchain),
|
vk::Result::SUCCESS => Ok(swapchain),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// On success, returns whether the swapchain is suboptimal for the surface.
|
||||||
pub unsafe fn queue_present_khr(
|
pub unsafe fn queue_present_khr(
|
||||||
&self,
|
&self,
|
||||||
queue: vk::Queue,
|
queue: vk::Queue,
|
||||||
create_info: &vk::PresentInfoKHR,
|
create_info: &vk::PresentInfoKHR,
|
||||||
) -> VkResult<()> {
|
) -> VkResult<bool> {
|
||||||
let err_code = self.swapchain_fn.queue_present_khr(queue, create_info);
|
let err_code = self.swapchain_fn.queue_present_khr(queue, create_info);
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(()),
|
vk::Result::SUCCESS => Ok(false),
|
||||||
|
vk::Result::SUBOPTIMAL_KHR => Ok(true),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_swapchain_images_khr(
|
pub unsafe fn get_swapchain_images_khr(
|
||||||
&self,
|
&self,
|
||||||
swapchain: vk::SwapchainKHR,
|
swapchain: vk::SwapchainKHR,
|
||||||
) -> VkResult<Vec<vk::Image>> {
|
) -> VkResult<Vec<vk::Image>> {
|
||||||
unsafe {
|
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
self.swapchain_fn.get_swapchain_images_khr(
|
self.swapchain_fn.get_swapchain_images_khr(
|
||||||
self.handle,
|
self.handle,
|
||||||
|
@ -111,18 +111,17 @@ impl Swapchain {
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut v = Vec::with_capacity(count as vk::size_t);
|
let mut v = Vec::with_capacity(count as usize);
|
||||||
let err_code = self.swapchain_fn.get_swapchain_images_khr(
|
let err_code = self.swapchain_fn.get_swapchain_images_khr(
|
||||||
self.handle,
|
self.handle,
|
||||||
swapchain,
|
swapchain,
|
||||||
&mut count,
|
&mut count,
|
||||||
v.as_mut_ptr(),
|
v.as_mut_ptr(),
|
||||||
);
|
);
|
||||||
v.set_len(count as vk::size_t);
|
v.set_len(count as usize);
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(v),
|
vk::Result::SUCCESS => Ok(v),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,32 +1,29 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
use std::mem;
|
|
||||||
use vk;
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use RawPtr;
|
use std::mem;
|
||||||
use version::{EntryV1_0, InstanceV1_0};
|
use version::{EntryV1_0, InstanceV1_0};
|
||||||
|
use vk;
|
||||||
|
use RawPtr;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct WaylandSurface {
|
pub struct WaylandSurface {
|
||||||
handle: vk::Instance,
|
handle: vk::Instance,
|
||||||
wayland_surface_fn: vk::WaylandSurfaceFn,
|
wayland_surface_fn: vk::KhrWaylandSurfaceFn,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WaylandSurface {
|
impl WaylandSurface {
|
||||||
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
|
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
|
||||||
entry: &E,
|
entry: &E,
|
||||||
instance: &I,
|
instance: &I,
|
||||||
) -> Result<WaylandSurface, Vec<&'static str>> {
|
) -> WaylandSurface {
|
||||||
let surface_fn = vk::WaylandSurfaceFn::load(|name| unsafe {
|
let surface_fn = vk::KhrWaylandSurfaceFn::load(|name| unsafe {
|
||||||
mem::transmute(entry.get_instance_proc_addr(
|
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
|
||||||
instance.handle(),
|
});
|
||||||
name.as_ptr(),
|
WaylandSurface {
|
||||||
))
|
|
||||||
})?;
|
|
||||||
Ok(WaylandSurface {
|
|
||||||
handle: instance.handle(),
|
handle: instance.handle(),
|
||||||
wayland_surface_fn: surface_fn,
|
wayland_surface_fn: surface_fn,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
|
@ -46,7 +43,7 @@ impl WaylandSurface {
|
||||||
&mut surface,
|
&mut surface,
|
||||||
);
|
);
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(surface),
|
vk::Result::SUCCESS => Ok(surface),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,29 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
use std::mem;
|
|
||||||
use vk;
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use RawPtr;
|
use std::mem;
|
||||||
use version::{EntryV1_0, InstanceV1_0};
|
use version::{EntryV1_0, InstanceV1_0};
|
||||||
|
use vk;
|
||||||
|
use RawPtr;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Win32Surface {
|
pub struct Win32Surface {
|
||||||
handle: vk::Instance,
|
handle: vk::Instance,
|
||||||
win32_surface_fn: vk::Win32SurfaceFn,
|
win32_surface_fn: vk::KhrWin32SurfaceFn,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Win32Surface {
|
impl Win32Surface {
|
||||||
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
|
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
|
||||||
entry: &E,
|
entry: &E,
|
||||||
instance: &I,
|
instance: &I,
|
||||||
) -> Result<Win32Surface, Vec<&'static str>> {
|
) -> Win32Surface {
|
||||||
let surface_fn = vk::Win32SurfaceFn::load(|name| unsafe {
|
let surface_fn = vk::KhrWin32SurfaceFn::load(|name| unsafe {
|
||||||
mem::transmute(entry.get_instance_proc_addr(
|
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
|
||||||
instance.handle(),
|
});
|
||||||
name.as_ptr(),
|
Win32Surface {
|
||||||
))
|
|
||||||
})?;
|
|
||||||
Ok(Win32Surface {
|
|
||||||
handle: instance.handle(),
|
handle: instance.handle(),
|
||||||
win32_surface_fn: surface_fn,
|
win32_surface_fn: surface_fn,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
|
@ -46,7 +43,7 @@ impl Win32Surface {
|
||||||
&mut surface,
|
&mut surface,
|
||||||
);
|
);
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(surface),
|
vk::Result::SUCCESS => Ok(surface),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,29 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
use std::mem;
|
|
||||||
use vk;
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use RawPtr;
|
use std::mem;
|
||||||
use version::{EntryV1_0, InstanceV1_0};
|
use version::{EntryV1_0, InstanceV1_0};
|
||||||
|
use vk;
|
||||||
|
use RawPtr;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct XcbSurface {
|
pub struct XcbSurface {
|
||||||
handle: vk::Instance,
|
handle: vk::Instance,
|
||||||
xcb_surface_fn: vk::XcbSurfaceFn,
|
xcb_surface_fn: vk::KhrXcbSurfaceFn,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XcbSurface {
|
impl XcbSurface {
|
||||||
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
|
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
|
||||||
entry: &E,
|
entry: &E,
|
||||||
instance: &I,
|
instance: &I,
|
||||||
) -> Result<XcbSurface, Vec<&'static str>> {
|
) -> XcbSurface {
|
||||||
let surface_fn = vk::XcbSurfaceFn::load(|name| unsafe {
|
let surface_fn = vk::KhrXcbSurfaceFn::load(|name| unsafe {
|
||||||
mem::transmute(entry.get_instance_proc_addr(
|
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
|
||||||
instance.handle(),
|
});
|
||||||
name.as_ptr(),
|
XcbSurface {
|
||||||
))
|
|
||||||
})?;
|
|
||||||
Ok(XcbSurface {
|
|
||||||
handle: instance.handle(),
|
handle: instance.handle(),
|
||||||
xcb_surface_fn: surface_fn,
|
xcb_surface_fn: surface_fn,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
|
@ -46,7 +43,7 @@ impl XcbSurface {
|
||||||
&mut surface,
|
&mut surface,
|
||||||
);
|
);
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(surface),
|
vk::Result::SUCCESS => Ok(surface),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,29 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
use std::mem;
|
|
||||||
use vk;
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use RawPtr;
|
use std::mem;
|
||||||
use version::{EntryV1_0, InstanceV1_0};
|
use version::{EntryV1_0, InstanceV1_0};
|
||||||
|
use vk;
|
||||||
|
use RawPtr;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct XlibSurface {
|
pub struct XlibSurface {
|
||||||
handle: vk::Instance,
|
handle: vk::Instance,
|
||||||
xlib_surface_fn: vk::XlibSurfaceFn,
|
xlib_surface_fn: vk::KhrXlibSurfaceFn,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XlibSurface {
|
impl XlibSurface {
|
||||||
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
|
pub fn new<E: EntryV1_0, I: InstanceV1_0>(
|
||||||
entry: &E,
|
entry: &E,
|
||||||
instance: &I,
|
instance: &I,
|
||||||
) -> Result<XlibSurface, Vec<&'static str>> {
|
) -> XlibSurface {
|
||||||
let surface_fn = vk::XlibSurfaceFn::load(|name| unsafe {
|
let surface_fn = vk::KhrXlibSurfaceFn::load(|name| unsafe {
|
||||||
mem::transmute(entry.get_instance_proc_addr(
|
mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr()))
|
||||||
instance.handle(),
|
});
|
||||||
name.as_ptr(),
|
XlibSurface {
|
||||||
))
|
|
||||||
})?;
|
|
||||||
Ok(XlibSurface {
|
|
||||||
handle: instance.handle(),
|
handle: instance.handle(),
|
||||||
xlib_surface_fn: surface_fn,
|
xlib_surface_fn: surface_fn,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name() -> &'static CStr {
|
pub fn name() -> &'static CStr {
|
||||||
|
@ -46,7 +43,7 @@ impl XlibSurface {
|
||||||
&mut surface,
|
&mut surface,
|
||||||
);
|
);
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(surface),
|
vk::Result::SUCCESS => Ok(surface),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,80 +1,43 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
use prelude::*;
|
|
||||||
use std::ptr;
|
|
||||||
use std::mem;
|
|
||||||
use vk;
|
|
||||||
use device::Device;
|
use device::Device;
|
||||||
use std::error::Error;
|
use prelude::*;
|
||||||
use std::fmt;
|
use std::mem;
|
||||||
|
use std::os::raw::c_char;
|
||||||
|
use std::ptr;
|
||||||
|
use vk;
|
||||||
use RawPtr;
|
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)]
|
#[derive(Clone)]
|
||||||
pub struct Instance<V: FunctionPointers> {
|
pub struct Instance {
|
||||||
handle: vk::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 {
|
Instance {
|
||||||
handle: handle,
|
handle: instance,
|
||||||
instance_fp: version,
|
instance_fn_1_0,
|
||||||
|
instance_fn_1_1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
impl InstanceV1_0 for Instance {
|
||||||
pub trait InstanceV1_0 {
|
type Device = Device;
|
||||||
type Fp: FunctionPointers;
|
|
||||||
fn handle(&self) -> vk::Instance;
|
|
||||||
fn fp_v1_0(&self) -> &vk::InstanceFnV1_0;
|
|
||||||
unsafe fn create_device(
|
unsafe fn create_device(
|
||||||
&self,
|
&self,
|
||||||
physical_device: vk::PhysicalDevice,
|
physical_device: vk::PhysicalDevice,
|
||||||
create_info: &vk::DeviceCreateInfo,
|
create_info: &vk::DeviceCreateInfo,
|
||||||
allocation_callbacks: Option<&vk::AllocationCallbacks>,
|
allocation_callbacks: Option<&vk::AllocationCallbacks>,
|
||||||
) -> Result<Device<Self::Fp>, DeviceError> {
|
) -> Result<Self::Device, vk::Result> {
|
||||||
let mut device: vk::Device = mem::uninitialized();
|
let mut device: vk::Device = mem::uninitialized();
|
||||||
let err_code = self.fp_v1_0().create_device(
|
let err_code = self.fp_v1_0().create_device(
|
||||||
physical_device,
|
physical_device,
|
||||||
|
@ -82,38 +45,236 @@ pub trait InstanceV1_0 {
|
||||||
allocation_callbacks.as_raw_ptr(),
|
allocation_callbacks.as_raw_ptr(),
|
||||||
&mut device,
|
&mut device,
|
||||||
);
|
);
|
||||||
if err_code != vk::Result::Success {
|
if err_code != vk::Result::SUCCESS {
|
||||||
return Err(DeviceError::VkError(err_code));
|
return Err(err_code);
|
||||||
}
|
}
|
||||||
let device_fn =
|
Ok(Device::load(&self.instance_fn_1_0, device))
|
||||||
<<Self as InstanceV1_0>::Fp as FunctionPointers>::DeviceFp::load(
|
}
|
||||||
self.fp_v1_0(),
|
fn handle(&self) -> vk::Instance {
|
||||||
device,
|
self.handle
|
||||||
).map_err(|err| DeviceError::LoadError(err))?;
|
|
||||||
Ok(Device::from_raw(device, device_fn))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_device_proc_addr(
|
fn fp_v1_0(&self) -> &vk::InstanceFnV1_0 {
|
||||||
&self,
|
&self.instance_fn_1_0
|
||||||
device: vk::Device,
|
}
|
||||||
p_name: *const vk::c_char,
|
|
||||||
) -> vk::PFN_vkVoidFunction {
|
|
||||||
unsafe { self.fp_v1_0().get_device_proc_addr(device, p_name) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn destroy_instance(&self, allocation_callbacks: Option<&vk::AllocationCallbacks>) {
|
impl InstanceV1_1 for Instance {
|
||||||
self.fp_v1_0().destroy_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(),
|
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,
|
&self,
|
||||||
physical_device: vk::PhysicalDevice,
|
physical_device: vk::PhysicalDevice,
|
||||||
format: vk::Format,
|
format: vk::Format,
|
||||||
) -> vk::FormatProperties {
|
) -> vk::FormatProperties {
|
||||||
unsafe {
|
|
||||||
let mut format_prop = mem::uninitialized();
|
let mut format_prop = mem::uninitialized();
|
||||||
self.fp_v1_0().get_physical_device_format_properties(
|
self.fp_v1_0().get_physical_device_format_properties(
|
||||||
physical_device,
|
physical_device,
|
||||||
|
@ -122,9 +283,8 @@ pub trait InstanceV1_0 {
|
||||||
);
|
);
|
||||||
format_prop
|
format_prop
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn get_physical_device_image_format_properties(
|
unsafe fn get_physical_device_image_format_properties(
|
||||||
&self,
|
&self,
|
||||||
physical_device: vk::PhysicalDevice,
|
physical_device: vk::PhysicalDevice,
|
||||||
format: vk::Format,
|
format: vk::Format,
|
||||||
|
@ -133,7 +293,6 @@ pub trait InstanceV1_0 {
|
||||||
usage: vk::ImageUsageFlags,
|
usage: vk::ImageUsageFlags,
|
||||||
flags: vk::ImageCreateFlags,
|
flags: vk::ImageCreateFlags,
|
||||||
) -> VkResult<vk::ImageFormatProperties> {
|
) -> VkResult<vk::ImageFormatProperties> {
|
||||||
unsafe {
|
|
||||||
let mut image_format_prop = mem::uninitialized();
|
let mut image_format_prop = mem::uninitialized();
|
||||||
let err_code = self.fp_v1_0().get_physical_device_image_format_properties(
|
let err_code = self.fp_v1_0().get_physical_device_image_format_properties(
|
||||||
physical_device,
|
physical_device,
|
||||||
|
@ -144,47 +303,37 @@ pub trait InstanceV1_0 {
|
||||||
flags,
|
flags,
|
||||||
&mut image_format_prop,
|
&mut image_format_prop,
|
||||||
);
|
);
|
||||||
if err_code == vk::Result::Success {
|
if err_code == vk::Result::SUCCESS {
|
||||||
Ok(image_format_prop)
|
Ok(image_format_prop)
|
||||||
} else {
|
} else {
|
||||||
Err(err_code)
|
Err(err_code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn get_physical_device_memory_properties(
|
unsafe fn get_physical_device_memory_properties(
|
||||||
&self,
|
&self,
|
||||||
physical_device: vk::PhysicalDevice,
|
physical_device: vk::PhysicalDevice,
|
||||||
) -> vk::PhysicalDeviceMemoryProperties {
|
) -> vk::PhysicalDeviceMemoryProperties {
|
||||||
unsafe {
|
|
||||||
let mut memory_prop = mem::uninitialized();
|
let mut memory_prop = mem::uninitialized();
|
||||||
self.fp_v1_0().get_physical_device_memory_properties(
|
self.fp_v1_0()
|
||||||
physical_device,
|
.get_physical_device_memory_properties(physical_device, &mut memory_prop);
|
||||||
&mut memory_prop,
|
|
||||||
);
|
|
||||||
memory_prop
|
memory_prop
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn get_physical_device_properties(
|
unsafe fn get_physical_device_properties(
|
||||||
&self,
|
&self,
|
||||||
physical_device: vk::PhysicalDevice,
|
physical_device: vk::PhysicalDevice,
|
||||||
) -> vk::PhysicalDeviceProperties {
|
) -> vk::PhysicalDeviceProperties {
|
||||||
unsafe {
|
|
||||||
let mut prop = mem::uninitialized();
|
let mut prop = mem::uninitialized();
|
||||||
self.fp_v1_0().get_physical_device_properties(
|
self.fp_v1_0()
|
||||||
physical_device,
|
.get_physical_device_properties(physical_device, &mut prop);
|
||||||
&mut prop,
|
|
||||||
);
|
|
||||||
prop
|
prop
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn get_physical_device_queue_family_properties(
|
unsafe fn get_physical_device_queue_family_properties(
|
||||||
&self,
|
&self,
|
||||||
physical_device: vk::PhysicalDevice,
|
physical_device: vk::PhysicalDevice,
|
||||||
) -> Vec<vk::QueueFamilyProperties> {
|
) -> Vec<vk::QueueFamilyProperties> {
|
||||||
unsafe {
|
|
||||||
let mut queue_count = 0;
|
let mut queue_count = 0;
|
||||||
self.fp_v1_0().get_physical_device_queue_family_properties(
|
self.fp_v1_0().get_physical_device_queue_family_properties(
|
||||||
physical_device,
|
physical_device,
|
||||||
|
@ -200,30 +349,21 @@ pub trait InstanceV1_0 {
|
||||||
queue_families_vec.set_len(queue_count as usize);
|
queue_families_vec.set_len(queue_count as usize);
|
||||||
queue_families_vec
|
queue_families_vec
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn get_physical_device_features(
|
unsafe fn get_physical_device_features(
|
||||||
&self,
|
&self,
|
||||||
physical_device: vk::PhysicalDevice,
|
physical_device: vk::PhysicalDevice,
|
||||||
) -> vk::PhysicalDeviceFeatures {
|
) -> vk::PhysicalDeviceFeatures {
|
||||||
unsafe {
|
|
||||||
let mut prop = mem::uninitialized();
|
let mut prop = mem::uninitialized();
|
||||||
self.fp_v1_0().get_physical_device_features(
|
self.fp_v1_0()
|
||||||
physical_device,
|
.get_physical_device_features(physical_device, &mut prop);
|
||||||
&mut prop,
|
|
||||||
);
|
|
||||||
prop
|
prop
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn enumerate_physical_devices(&self) -> VkResult<Vec<vk::PhysicalDevice>> {
|
unsafe fn enumerate_physical_devices(&self) -> VkResult<Vec<vk::PhysicalDevice>> {
|
||||||
unsafe {
|
|
||||||
let mut num = mem::uninitialized();
|
let mut num = mem::uninitialized();
|
||||||
self.fp_v1_0().enumerate_physical_devices(
|
self.fp_v1_0()
|
||||||
self.handle(),
|
.enumerate_physical_devices(self.handle(), &mut num, ptr::null_mut());
|
||||||
&mut num,
|
|
||||||
ptr::null_mut(),
|
|
||||||
);
|
|
||||||
let mut physical_devices = Vec::<vk::PhysicalDevice>::with_capacity(num as usize);
|
let mut physical_devices = Vec::<vk::PhysicalDevice>::with_capacity(num as usize);
|
||||||
let err_code = self.fp_v1_0().enumerate_physical_devices(
|
let err_code = self.fp_v1_0().enumerate_physical_devices(
|
||||||
self.handle(),
|
self.handle(),
|
||||||
|
@ -232,17 +372,15 @@ pub trait InstanceV1_0 {
|
||||||
);
|
);
|
||||||
physical_devices.set_len(num as usize);
|
physical_devices.set_len(num as usize);
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(physical_devices),
|
vk::Result::SUCCESS => Ok(physical_devices),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn enumerate_device_extension_properties(
|
unsafe fn enumerate_device_extension_properties(
|
||||||
&self,
|
&self,
|
||||||
device: vk::PhysicalDevice,
|
device: vk::PhysicalDevice,
|
||||||
) -> Result<Vec<vk::ExtensionProperties>, vk::Result> {
|
) -> Result<Vec<vk::ExtensionProperties>, vk::Result> {
|
||||||
unsafe {
|
|
||||||
let mut num = 0;
|
let mut num = 0;
|
||||||
self.fp_v1_0().enumerate_device_extension_properties(
|
self.fp_v1_0().enumerate_device_extension_properties(
|
||||||
device,
|
device,
|
||||||
|
@ -259,12 +397,8 @@ pub trait InstanceV1_0 {
|
||||||
);
|
);
|
||||||
data.set_len(num as usize);
|
data.set_len(num as usize);
|
||||||
match err_code {
|
match err_code {
|
||||||
vk::Result::Success => Ok(data),
|
vk::Result::SUCCESS => Ok(data),
|
||||||
_ => Err(err_code),
|
_ => Err(err_code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// pub trait InstanceMajor1Minor1: InstanceMajor1Minor0 {}
|
|
||||||
// pub trait InstanceMajor1Minor2: InstanceMajor1Minor1 {}
|
|
||||||
|
|
|
@ -1,21 +1,18 @@
|
||||||
extern crate libc;
|
|
||||||
extern crate shared_library;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
pub use instance::{Instance, DeviceError};
|
extern crate shared_library;
|
||||||
pub use device::Device;
|
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 device;
|
||||||
mod entry;
|
mod entry;
|
||||||
pub mod prelude;
|
|
||||||
pub mod vk;
|
|
||||||
//mod allocator;
|
|
||||||
pub mod extensions;
|
pub mod extensions;
|
||||||
pub mod version;
|
mod instance;
|
||||||
|
pub mod prelude;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
pub mod version;
|
||||||
|
pub mod vk;
|
||||||
pub trait RawPtr<T> {
|
pub trait RawPtr<T> {
|
||||||
fn as_raw_ptr(&self) -> *const 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 {
|
fn as_raw_ptr(&self) -> *const T {
|
||||||
match self {
|
match self {
|
||||||
&Some(inner) => inner as *const T,
|
&Some(inner) => inner as *const T,
|
||||||
|
|
||||||
_ => ::std::ptr::null(),
|
_ => ::std::ptr::null(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use std::iter::Iterator;
|
use std::iter::Iterator;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
|
use std::os::raw::c_void;
|
||||||
use vk;
|
use vk;
|
||||||
|
|
||||||
/// `Align` handles dynamic alignment. The is useful for dynamic uniform buffers where
|
/// `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.
|
/// an additional allocation and with the correct alignment.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Align<T> {
|
pub struct Align<T> {
|
||||||
ptr: *mut vk::c_void,
|
ptr: *mut c_void,
|
||||||
elem_size: vk::DeviceSize,
|
elem_size: vk::DeviceSize,
|
||||||
size: vk::DeviceSize,
|
size: vk::DeviceSize,
|
||||||
_m: PhantomData<T>,
|
_m: PhantomData<T>,
|
||||||
|
@ -46,7 +47,7 @@ fn calc_padding(adr: vk::DeviceSize, align: vk::DeviceSize) -> vk::DeviceSize {
|
||||||
|
|
||||||
impl<T> Align<T> {
|
impl<T> Align<T> {
|
||||||
pub unsafe fn new(
|
pub unsafe fn new(
|
||||||
ptr: *mut vk::c_void,
|
ptr: *mut c_void,
|
||||||
alignment: vk::DeviceSize,
|
alignment: vk::DeviceSize,
|
||||||
size: vk::DeviceSize,
|
size: vk::DeviceSize,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
|
@ -1,99 +1,3 @@
|
||||||
use vk;
|
pub use device::{DeviceV1_0, DeviceV1_1};
|
||||||
pub use instance::InstanceV1_0;
|
pub use entry::{EntryV1_0, EntryV1_1};
|
||||||
pub use device::DeviceV1_0;
|
pub use instance::{InstanceV1_0, InstanceV1_1};
|
||||||
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,
|
|
||||||
}
|
|
||||||
|
|
46774
ash/src/vk.rs
46774
ash/src/vk.rs
File diff suppressed because it is too large
Load diff
12
ash/tests/display.rs
Normal file
12
ash/tests/display.rs
Normal 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");
|
||||||
|
}
|
|
@ -4,7 +4,7 @@ version = "0.1.0"
|
||||||
authors = ["maik klein <maikklein@googlemail.com>"]
|
authors = ["maik klein <maikklein@googlemail.com>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
winit = "0.11.1"
|
winit = "0.16"
|
||||||
image = "0.10.4"
|
image = "0.10.4"
|
||||||
ash = { path = "../ash" }
|
ash = { path = "../ash" }
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,18 +1,17 @@
|
||||||
extern crate ash;
|
extern crate ash;
|
||||||
#[macro_use]
|
|
||||||
extern crate examples;
|
extern crate examples;
|
||||||
|
|
||||||
|
use ash::util::*;
|
||||||
use ash::vk;
|
use ash::vk;
|
||||||
|
use examples::*;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::ptr;
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::mem;
|
|
||||||
use std::path::Path;
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use examples::*;
|
use std::mem;
|
||||||
use ash::util::*;
|
|
||||||
use std::mem::align_of;
|
use std::mem::align_of;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Copy)]
|
#[derive(Clone, Debug, Copy)]
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
|
@ -27,50 +26,50 @@ fn main() {
|
||||||
vk::AttachmentDescription {
|
vk::AttachmentDescription {
|
||||||
format: base.surface_format.format,
|
format: base.surface_format.format,
|
||||||
flags: vk::AttachmentDescriptionFlags::empty(),
|
flags: vk::AttachmentDescriptionFlags::empty(),
|
||||||
samples: vk::SAMPLE_COUNT_1_BIT,
|
samples: vk::SampleCountFlags::TYPE_1,
|
||||||
load_op: vk::AttachmentLoadOp::Clear,
|
load_op: vk::AttachmentLoadOp::CLEAR,
|
||||||
store_op: vk::AttachmentStoreOp::Store,
|
store_op: vk::AttachmentStoreOp::STORE,
|
||||||
stencil_load_op: vk::AttachmentLoadOp::DontCare,
|
stencil_load_op: vk::AttachmentLoadOp::DONT_CARE,
|
||||||
stencil_store_op: vk::AttachmentStoreOp::DontCare,
|
stencil_store_op: vk::AttachmentStoreOp::DONT_CARE,
|
||||||
initial_layout: vk::ImageLayout::Undefined,
|
initial_layout: vk::ImageLayout::UNDEFINED,
|
||||||
final_layout: vk::ImageLayout::PresentSrcKhr,
|
final_layout: vk::ImageLayout::PRESENT_SRC_KHR,
|
||||||
},
|
},
|
||||||
vk::AttachmentDescription {
|
vk::AttachmentDescription {
|
||||||
format: vk::Format::D16Unorm,
|
format: vk::Format::D16_UNORM,
|
||||||
flags: vk::AttachmentDescriptionFlags::empty(),
|
flags: vk::AttachmentDescriptionFlags::empty(),
|
||||||
samples: vk::SAMPLE_COUNT_1_BIT,
|
samples: vk::SampleCountFlags::TYPE_1,
|
||||||
load_op: vk::AttachmentLoadOp::Clear,
|
load_op: vk::AttachmentLoadOp::CLEAR,
|
||||||
store_op: vk::AttachmentStoreOp::DontCare,
|
store_op: vk::AttachmentStoreOp::DONT_CARE,
|
||||||
stencil_load_op: vk::AttachmentLoadOp::DontCare,
|
stencil_load_op: vk::AttachmentLoadOp::DONT_CARE,
|
||||||
stencil_store_op: vk::AttachmentStoreOp::DontCare,
|
stencil_store_op: vk::AttachmentStoreOp::DONT_CARE,
|
||||||
initial_layout: vk::ImageLayout::DepthStencilAttachmentOptimal,
|
initial_layout: vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||||
final_layout: vk::ImageLayout::DepthStencilAttachmentOptimal,
|
final_layout: vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
let color_attachment_ref = vk::AttachmentReference {
|
let color_attachment_ref = vk::AttachmentReference {
|
||||||
attachment: 0,
|
attachment: 0,
|
||||||
layout: vk::ImageLayout::ColorAttachmentOptimal,
|
layout: vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL,
|
||||||
};
|
};
|
||||||
let depth_attachment_ref = vk::AttachmentReference {
|
let depth_attachment_ref = vk::AttachmentReference {
|
||||||
attachment: 1,
|
attachment: 1,
|
||||||
layout: vk::ImageLayout::DepthStencilAttachmentOptimal,
|
layout: vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||||
};
|
};
|
||||||
let dependency = vk::SubpassDependency {
|
let dependency = vk::SubpassDependency {
|
||||||
dependency_flags: Default::default(),
|
dependency_flags: Default::default(),
|
||||||
src_subpass: vk::VK_SUBPASS_EXTERNAL,
|
src_subpass: vk::SUBPASS_EXTERNAL,
|
||||||
dst_subpass: Default::default(),
|
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(),
|
src_access_mask: Default::default(),
|
||||||
dst_access_mask: vk::ACCESS_COLOR_ATTACHMENT_READ_BIT
|
dst_access_mask: vk::AccessFlags::COLOR_ATTACHMENT_READ
|
||||||
| vk::ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
| vk::AccessFlags::COLOR_ATTACHMENT_WRITE,
|
||||||
dst_stage_mask: vk::PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
dst_stage_mask: vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT,
|
||||||
};
|
};
|
||||||
let subpass = vk::SubpassDescription {
|
let subpass = vk::SubpassDescription {
|
||||||
color_attachment_count: 1,
|
color_attachment_count: 1,
|
||||||
p_color_attachments: &color_attachment_ref,
|
p_color_attachments: &color_attachment_ref,
|
||||||
p_depth_stencil_attachment: &depth_attachment_ref,
|
p_depth_stencil_attachment: &depth_attachment_ref,
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
pipeline_bind_point: vk::PipelineBindPoint::Graphics,
|
pipeline_bind_point: vk::PipelineBindPoint::GRAPHICS,
|
||||||
input_attachment_count: 0,
|
input_attachment_count: 0,
|
||||||
p_input_attachments: ptr::null(),
|
p_input_attachments: ptr::null(),
|
||||||
p_resolve_attachments: ptr::null(),
|
p_resolve_attachments: ptr::null(),
|
||||||
|
@ -78,7 +77,7 @@ fn main() {
|
||||||
p_preserve_attachments: ptr::null(),
|
p_preserve_attachments: ptr::null(),
|
||||||
};
|
};
|
||||||
let renderpass_create_info = vk::RenderPassCreateInfo {
|
let renderpass_create_info = vk::RenderPassCreateInfo {
|
||||||
s_type: vk::StructureType::RenderPassCreateInfo,
|
s_type: vk::StructureType::RENDER_PASS_CREATE_INFO,
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
attachment_count: renderpass_attachments.len() as u32,
|
attachment_count: renderpass_attachments.len() as u32,
|
||||||
|
@ -88,15 +87,17 @@ fn main() {
|
||||||
dependency_count: 1,
|
dependency_count: 1,
|
||||||
p_dependencies: &dependency,
|
p_dependencies: &dependency,
|
||||||
};
|
};
|
||||||
let renderpass = base.device
|
let renderpass = base
|
||||||
|
.device
|
||||||
.create_render_pass(&renderpass_create_info, None)
|
.create_render_pass(&renderpass_create_info, None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let framebuffers: Vec<vk::Framebuffer> = base.present_image_views
|
let framebuffers: Vec<vk::Framebuffer> = base
|
||||||
|
.present_image_views
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&present_image_view| {
|
.map(|&present_image_view| {
|
||||||
let framebuffer_attachments = [present_image_view, base.depth_image_view];
|
let framebuffer_attachments = [present_image_view, base.depth_image_view];
|
||||||
let frame_buffer_create_info = vk::FramebufferCreateInfo {
|
let frame_buffer_create_info = vk::FramebufferCreateInfo {
|
||||||
s_type: vk::StructureType::FramebufferCreateInfo,
|
s_type: vk::StructureType::FRAMEBUFFER_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
render_pass: renderpass,
|
render_pass: renderpass,
|
||||||
|
@ -113,12 +114,12 @@ fn main() {
|
||||||
.collect();
|
.collect();
|
||||||
let index_buffer_data = [0u32, 1, 2];
|
let index_buffer_data = [0u32, 1, 2];
|
||||||
let index_buffer_info = vk::BufferCreateInfo {
|
let index_buffer_info = vk::BufferCreateInfo {
|
||||||
s_type: vk::StructureType::BufferCreateInfo,
|
s_type: vk::StructureType::BUFFER_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: vk::BufferCreateFlags::empty(),
|
flags: vk::BufferCreateFlags::empty(),
|
||||||
size: std::mem::size_of_val(&index_buffer_data) as u64,
|
size: std::mem::size_of_val(&index_buffer_data) as u64,
|
||||||
usage: vk::BUFFER_USAGE_INDEX_BUFFER_BIT,
|
usage: vk::BufferUsageFlags::INDEX_BUFFER,
|
||||||
sharing_mode: vk::SharingMode::Exclusive,
|
sharing_mode: vk::SharingMode::EXCLUSIVE,
|
||||||
queue_family_index_count: 0,
|
queue_family_index_count: 0,
|
||||||
p_queue_family_indices: ptr::null(),
|
p_queue_family_indices: ptr::null(),
|
||||||
};
|
};
|
||||||
|
@ -128,18 +129,20 @@ fn main() {
|
||||||
find_memorytype_index(
|
find_memorytype_index(
|
||||||
&index_buffer_memory_req,
|
&index_buffer_memory_req,
|
||||||
&base.device_memory_properties,
|
&base.device_memory_properties,
|
||||||
vk::MEMORY_PROPERTY_HOST_VISIBLE_BIT,
|
vk::MemoryPropertyFlags::HOST_VISIBLE,
|
||||||
).expect("Unable to find suitable memorytype for the index buffer.");
|
).expect("Unable to find suitable memorytype for the index buffer.");
|
||||||
let index_allocate_info = vk::MemoryAllocateInfo {
|
let index_allocate_info = vk::MemoryAllocateInfo {
|
||||||
s_type: vk::StructureType::MemoryAllocateInfo,
|
s_type: vk::StructureType::MEMORY_ALLOCATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
allocation_size: index_buffer_memory_req.size,
|
allocation_size: index_buffer_memory_req.size,
|
||||||
memory_type_index: index_buffer_memory_index,
|
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)
|
.allocate_memory(&index_allocate_info, None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let index_ptr = base.device
|
let index_ptr = base
|
||||||
|
.device
|
||||||
.map_memory(
|
.map_memory(
|
||||||
index_buffer_memory,
|
index_buffer_memory,
|
||||||
0,
|
0,
|
||||||
|
@ -159,34 +162,37 @@ fn main() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let vertex_input_buffer_info = vk::BufferCreateInfo {
|
let vertex_input_buffer_info = vk::BufferCreateInfo {
|
||||||
s_type: vk::StructureType::BufferCreateInfo,
|
s_type: vk::StructureType::BUFFER_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: vk::BufferCreateFlags::empty(),
|
flags: vk::BufferCreateFlags::empty(),
|
||||||
size: 3 * std::mem::size_of::<Vertex>() as u64,
|
size: 3 * std::mem::size_of::<Vertex>() as u64,
|
||||||
usage: vk::BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
usage: vk::BufferUsageFlags::VERTEX_BUFFER,
|
||||||
sharing_mode: vk::SharingMode::Exclusive,
|
sharing_mode: vk::SharingMode::EXCLUSIVE,
|
||||||
queue_family_index_count: 0,
|
queue_family_index_count: 0,
|
||||||
p_queue_family_indices: ptr::null(),
|
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)
|
.create_buffer(&vertex_input_buffer_info, None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let vertex_input_buffer_memory_req = base.device
|
let vertex_input_buffer_memory_req = base
|
||||||
|
.device
|
||||||
.get_buffer_memory_requirements(vertex_input_buffer);
|
.get_buffer_memory_requirements(vertex_input_buffer);
|
||||||
let vertex_input_buffer_memory_index =
|
let vertex_input_buffer_memory_index =
|
||||||
find_memorytype_index(
|
find_memorytype_index(
|
||||||
&vertex_input_buffer_memory_req,
|
&vertex_input_buffer_memory_req,
|
||||||
&base.device_memory_properties,
|
&base.device_memory_properties,
|
||||||
vk::MEMORY_PROPERTY_HOST_VISIBLE_BIT,
|
vk::MemoryPropertyFlags::HOST_VISIBLE,
|
||||||
).expect("Unable to find suitable memorytype for the vertex buffer.");
|
).expect("Unable to find suitable memorytype for the vertex buffer.");
|
||||||
|
|
||||||
let vertex_buffer_allocate_info = vk::MemoryAllocateInfo {
|
let vertex_buffer_allocate_info = vk::MemoryAllocateInfo {
|
||||||
s_type: vk::StructureType::MemoryAllocateInfo,
|
s_type: vk::StructureType::MEMORY_ALLOCATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
allocation_size: vertex_input_buffer_memory_req.size,
|
allocation_size: vertex_input_buffer_memory_req.size,
|
||||||
memory_type_index: vertex_input_buffer_memory_index,
|
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)
|
.allocate_memory(&vertex_buffer_allocate_info, None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let vertices = [
|
let vertices = [
|
||||||
|
@ -203,7 +209,8 @@ fn main() {
|
||||||
color: [1.0, 0.0, 0.0, 1.0],
|
color: [1.0, 0.0, 0.0, 1.0],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
let vert_ptr = base.device
|
let vert_ptr = base
|
||||||
|
.device
|
||||||
.map_memory(
|
.map_memory(
|
||||||
vertex_input_buffer_memory,
|
vertex_input_buffer_memory,
|
||||||
0,
|
0,
|
||||||
|
@ -231,7 +238,7 @@ fn main() {
|
||||||
.filter_map(|byte| byte.ok())
|
.filter_map(|byte| byte.ok())
|
||||||
.collect();
|
.collect();
|
||||||
let vertex_shader_info = vk::ShaderModuleCreateInfo {
|
let vertex_shader_info = vk::ShaderModuleCreateInfo {
|
||||||
s_type: vk::StructureType::ShaderModuleCreateInfo,
|
s_type: vk::StructureType::SHADER_MODULE_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
code_size: vertex_bytes.len(),
|
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_bytes: Vec<u8> = frag_spv_file.bytes().filter_map(|byte| byte.ok()).collect();
|
||||||
let frag_shader_info = vk::ShaderModuleCreateInfo {
|
let frag_shader_info = vk::ShaderModuleCreateInfo {
|
||||||
s_type: vk::StructureType::ShaderModuleCreateInfo,
|
s_type: vk::StructureType::SHADER_MODULE_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
code_size: frag_bytes.len(),
|
code_size: frag_bytes.len(),
|
||||||
p_code: frag_bytes.as_ptr() as *const u32,
|
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)
|
.create_shader_module(&vertex_shader_info, None)
|
||||||
.expect("Vertex shader module error");
|
.expect("Vertex shader module error");
|
||||||
|
|
||||||
let fragment_shader_module = base.device
|
let fragment_shader_module = base
|
||||||
|
.device
|
||||||
.create_shader_module(&frag_shader_info, None)
|
.create_shader_module(&frag_shader_info, None)
|
||||||
.expect("Fragment shader module error");
|
.expect("Fragment shader module error");
|
||||||
|
|
||||||
let layout_create_info = vk::PipelineLayoutCreateInfo {
|
let layout_create_info = vk::PipelineLayoutCreateInfo {
|
||||||
s_type: vk::StructureType::PipelineLayoutCreateInfo,
|
s_type: vk::StructureType::PIPELINE_LAYOUT_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
set_layout_count: 0,
|
set_layout_count: 0,
|
||||||
|
@ -263,54 +272,53 @@ fn main() {
|
||||||
p_push_constant_ranges: ptr::null(),
|
p_push_constant_ranges: ptr::null(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let pipeline_layout = base.device
|
let pipeline_layout = base
|
||||||
|
.device
|
||||||
.create_pipeline_layout(&layout_create_info, None)
|
.create_pipeline_layout(&layout_create_info, None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let shader_entry_name = CString::new("main").unwrap();
|
let shader_entry_name = CString::new("main").unwrap();
|
||||||
let shader_stage_create_infos = [
|
let shader_stage_create_infos = [
|
||||||
vk::PipelineShaderStageCreateInfo {
|
vk::PipelineShaderStageCreateInfo {
|
||||||
s_type: vk::StructureType::PipelineShaderStageCreateInfo,
|
s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
module: vertex_shader_module,
|
module: vertex_shader_module,
|
||||||
p_name: shader_entry_name.as_ptr(),
|
p_name: shader_entry_name.as_ptr(),
|
||||||
p_specialization_info: ptr::null(),
|
p_specialization_info: ptr::null(),
|
||||||
stage: vk::SHADER_STAGE_VERTEX_BIT,
|
stage: vk::ShaderStageFlags::VERTEX,
|
||||||
},
|
},
|
||||||
vk::PipelineShaderStageCreateInfo {
|
vk::PipelineShaderStageCreateInfo {
|
||||||
s_type: vk::StructureType::PipelineShaderStageCreateInfo,
|
s_type: vk::StructureType::PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
module: fragment_shader_module,
|
module: fragment_shader_module,
|
||||||
p_name: shader_entry_name.as_ptr(),
|
p_name: shader_entry_name.as_ptr(),
|
||||||
p_specialization_info: ptr::null(),
|
p_specialization_info: ptr::null(),
|
||||||
stage: vk::SHADER_STAGE_FRAGMENT_BIT,
|
stage: vk::ShaderStageFlags::FRAGMENT,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
let vertex_input_binding_descriptions = [
|
let vertex_input_binding_descriptions = [vk::VertexInputBindingDescription {
|
||||||
vk::VertexInputBindingDescription {
|
|
||||||
binding: 0,
|
binding: 0,
|
||||||
stride: mem::size_of::<Vertex>() as u32,
|
stride: mem::size_of::<Vertex>() as u32,
|
||||||
input_rate: vk::VertexInputRate::Vertex,
|
input_rate: vk::VertexInputRate::VERTEX,
|
||||||
},
|
}];
|
||||||
];
|
|
||||||
let vertex_input_attribute_descriptions = [
|
let vertex_input_attribute_descriptions = [
|
||||||
vk::VertexInputAttributeDescription {
|
vk::VertexInputAttributeDescription {
|
||||||
location: 0,
|
location: 0,
|
||||||
binding: 0,
|
binding: 0,
|
||||||
format: vk::Format::R32g32b32a32Sfloat,
|
format: vk::Format::R32G32B32A32_SFLOAT,
|
||||||
offset: offset_of!(Vertex, pos) as u32,
|
offset: offset_of!(Vertex, pos) as u32,
|
||||||
},
|
},
|
||||||
vk::VertexInputAttributeDescription {
|
vk::VertexInputAttributeDescription {
|
||||||
location: 1,
|
location: 1,
|
||||||
binding: 0,
|
binding: 0,
|
||||||
format: vk::Format::R32g32b32a32Sfloat,
|
format: vk::Format::R32G32B32A32_SFLOAT,
|
||||||
offset: offset_of!(Vertex, color) as u32,
|
offset: offset_of!(Vertex, color) as u32,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
let vertex_input_state_info = vk::PipelineVertexInputStateCreateInfo {
|
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(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
vertex_attribute_description_count: vertex_input_attribute_descriptions.len() as u32,
|
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(),
|
p_vertex_binding_descriptions: vertex_input_binding_descriptions.as_ptr(),
|
||||||
};
|
};
|
||||||
let vertex_input_assembly_state_info = vk::PipelineInputAssemblyStateCreateInfo {
|
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(),
|
flags: Default::default(),
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
primitive_restart_enable: 0,
|
primitive_restart_enable: 0,
|
||||||
topology: vk::PrimitiveTopology::TriangleList,
|
topology: vk::PrimitiveTopology::TRIANGLE_LIST,
|
||||||
};
|
};
|
||||||
let viewports = [
|
let viewports = [vk::Viewport {
|
||||||
vk::Viewport {
|
|
||||||
x: 0.0,
|
x: 0.0,
|
||||||
y: 0.0,
|
y: 0.0,
|
||||||
width: base.surface_resolution.width as f32,
|
width: base.surface_resolution.width as f32,
|
||||||
height: base.surface_resolution.height as f32,
|
height: base.surface_resolution.height as f32,
|
||||||
min_depth: 0.0,
|
min_depth: 0.0,
|
||||||
max_depth: 1.0,
|
max_depth: 1.0,
|
||||||
},
|
}];
|
||||||
];
|
let scissors = [vk::Rect2D {
|
||||||
let scissors = [
|
|
||||||
vk::Rect2D {
|
|
||||||
offset: vk::Offset2D { x: 0, y: 0 },
|
offset: vk::Offset2D { x: 0, y: 0 },
|
||||||
extent: base.surface_resolution.clone(),
|
extent: base.surface_resolution.clone(),
|
||||||
},
|
}];
|
||||||
];
|
|
||||||
let viewport_state_info = vk::PipelineViewportStateCreateInfo {
|
let viewport_state_info = vk::PipelineViewportStateCreateInfo {
|
||||||
s_type: vk::StructureType::PipelineViewportStateCreateInfo,
|
s_type: vk::StructureType::PIPELINE_VIEWPORT_STATE_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
scissor_count: scissors.len() as u32,
|
scissor_count: scissors.len() as u32,
|
||||||
|
@ -351,25 +355,25 @@ fn main() {
|
||||||
p_viewports: viewports.as_ptr(),
|
p_viewports: viewports.as_ptr(),
|
||||||
};
|
};
|
||||||
let rasterization_info = vk::PipelineRasterizationStateCreateInfo {
|
let rasterization_info = vk::PipelineRasterizationStateCreateInfo {
|
||||||
s_type: vk::StructureType::PipelineRasterizationStateCreateInfo,
|
s_type: vk::StructureType::PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
cull_mode: vk::CULL_MODE_NONE,
|
cull_mode: vk::CullModeFlags::NONE,
|
||||||
depth_bias_clamp: 0.0,
|
depth_bias_clamp: 0.0,
|
||||||
depth_bias_constant_factor: 0.0,
|
depth_bias_constant_factor: 0.0,
|
||||||
depth_bias_enable: 0,
|
depth_bias_enable: 0,
|
||||||
depth_bias_slope_factor: 0.0,
|
depth_bias_slope_factor: 0.0,
|
||||||
depth_clamp_enable: 0,
|
depth_clamp_enable: 0,
|
||||||
front_face: vk::FrontFace::CounterClockwise,
|
front_face: vk::FrontFace::COUNTER_CLOCKWISE,
|
||||||
line_width: 1.0,
|
line_width: 1.0,
|
||||||
polygon_mode: vk::PolygonMode::Fill,
|
polygon_mode: vk::PolygonMode::FILL,
|
||||||
rasterizer_discard_enable: 0,
|
rasterizer_discard_enable: 0,
|
||||||
};
|
};
|
||||||
let multisample_state_info = vk::PipelineMultisampleStateCreateInfo {
|
let multisample_state_info = vk::PipelineMultisampleStateCreateInfo {
|
||||||
s_type: vk::StructureType::PipelineMultisampleStateCreateInfo,
|
s_type: vk::StructureType::PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
rasterization_samples: vk::SAMPLE_COUNT_1_BIT,
|
rasterization_samples: vk::SampleCountFlags::TYPE_1,
|
||||||
sample_shading_enable: 0,
|
sample_shading_enable: 0,
|
||||||
min_sample_shading: 0.0,
|
min_sample_shading: 0.0,
|
||||||
p_sample_mask: ptr::null(),
|
p_sample_mask: ptr::null(),
|
||||||
|
@ -377,21 +381,21 @@ fn main() {
|
||||||
alpha_to_coverage_enable: 0,
|
alpha_to_coverage_enable: 0,
|
||||||
};
|
};
|
||||||
let noop_stencil_state = vk::StencilOpState {
|
let noop_stencil_state = vk::StencilOpState {
|
||||||
fail_op: vk::StencilOp::Keep,
|
fail_op: vk::StencilOp::KEEP,
|
||||||
pass_op: vk::StencilOp::Keep,
|
pass_op: vk::StencilOp::KEEP,
|
||||||
depth_fail_op: vk::StencilOp::Keep,
|
depth_fail_op: vk::StencilOp::KEEP,
|
||||||
compare_op: vk::CompareOp::Always,
|
compare_op: vk::CompareOp::ALWAYS,
|
||||||
compare_mask: 0,
|
compare_mask: 0,
|
||||||
write_mask: 0,
|
write_mask: 0,
|
||||||
reference: 0,
|
reference: 0,
|
||||||
};
|
};
|
||||||
let depth_state_info = vk::PipelineDepthStencilStateCreateInfo {
|
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(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
depth_test_enable: 1,
|
depth_test_enable: 1,
|
||||||
depth_write_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,
|
depth_bounds_test_enable: 0,
|
||||||
stencil_test_enable: 0,
|
stencil_test_enable: 0,
|
||||||
front: noop_stencil_state.clone(),
|
front: noop_stencil_state.clone(),
|
||||||
|
@ -399,38 +403,36 @@ fn main() {
|
||||||
max_depth_bounds: 1.0,
|
max_depth_bounds: 1.0,
|
||||||
min_depth_bounds: 0.0,
|
min_depth_bounds: 0.0,
|
||||||
};
|
};
|
||||||
let color_blend_attachment_states = [
|
let color_blend_attachment_states = [vk::PipelineColorBlendAttachmentState {
|
||||||
vk::PipelineColorBlendAttachmentState {
|
|
||||||
blend_enable: 0,
|
blend_enable: 0,
|
||||||
src_color_blend_factor: vk::BlendFactor::SrcColor,
|
src_color_blend_factor: vk::BlendFactor::SRC_COLOR,
|
||||||
dst_color_blend_factor: vk::BlendFactor::OneMinusDstColor,
|
dst_color_blend_factor: vk::BlendFactor::ONE_MINUS_DST_COLOR,
|
||||||
color_blend_op: vk::BlendOp::Add,
|
color_blend_op: vk::BlendOp::ADD,
|
||||||
src_alpha_blend_factor: vk::BlendFactor::Zero,
|
src_alpha_blend_factor: vk::BlendFactor::ZERO,
|
||||||
dst_alpha_blend_factor: vk::BlendFactor::Zero,
|
dst_alpha_blend_factor: vk::BlendFactor::ZERO,
|
||||||
alpha_blend_op: vk::BlendOp::Add,
|
alpha_blend_op: vk::BlendOp::ADD,
|
||||||
color_write_mask: vk::ColorComponentFlags::all(),
|
color_write_mask: vk::ColorComponentFlags::all(),
|
||||||
},
|
}];
|
||||||
];
|
|
||||||
let color_blend_state = vk::PipelineColorBlendStateCreateInfo {
|
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(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
logic_op_enable: 0,
|
logic_op_enable: 0,
|
||||||
logic_op: vk::LogicOp::Clear,
|
logic_op: vk::LogicOp::CLEAR,
|
||||||
attachment_count: color_blend_attachment_states.len() as u32,
|
attachment_count: color_blend_attachment_states.len() as u32,
|
||||||
p_attachments: color_blend_attachment_states.as_ptr(),
|
p_attachments: color_blend_attachment_states.as_ptr(),
|
||||||
blend_constants: [0.0, 0.0, 0.0, 0.0],
|
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 {
|
let dynamic_state_info = vk::PipelineDynamicStateCreateInfo {
|
||||||
s_type: vk::StructureType::PipelineDynamicStateCreateInfo,
|
s_type: vk::StructureType::PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
dynamic_state_count: dynamic_state.len() as u32,
|
dynamic_state_count: dynamic_state.len() as u32,
|
||||||
p_dynamic_states: dynamic_state.as_ptr(),
|
p_dynamic_states: dynamic_state.as_ptr(),
|
||||||
};
|
};
|
||||||
let graphic_pipeline_info = vk::GraphicsPipelineCreateInfo {
|
let graphic_pipeline_info = vk::GraphicsPipelineCreateInfo {
|
||||||
s_type: vk::StructureType::GraphicsPipelineCreateInfo,
|
s_type: vk::StructureType::GRAPHICS_PIPELINE_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: vk::PipelineCreateFlags::empty(),
|
flags: vk::PipelineCreateFlags::empty(),
|
||||||
stage_count: shader_stage_create_infos.len() as u32,
|
stage_count: shader_stage_create_infos.len() as u32,
|
||||||
|
@ -450,14 +452,16 @@ fn main() {
|
||||||
base_pipeline_handle: vk::Pipeline::null(),
|
base_pipeline_handle: vk::Pipeline::null(),
|
||||||
base_pipeline_index: 0,
|
base_pipeline_index: 0,
|
||||||
};
|
};
|
||||||
let graphics_pipelines = base.device
|
let graphics_pipelines = base
|
||||||
|
.device
|
||||||
.create_graphics_pipelines(vk::PipelineCache::null(), &[graphic_pipeline_info], None)
|
.create_graphics_pipelines(vk::PipelineCache::null(), &[graphic_pipeline_info], None)
|
||||||
.expect("Unable to create graphics pipeline");
|
.expect("Unable to create graphics pipeline");
|
||||||
|
|
||||||
let graphic_pipeline = graphics_pipelines[0];
|
let graphic_pipeline = graphics_pipelines[0];
|
||||||
|
|
||||||
base.render_loop(|| {
|
base.render_loop(|| {
|
||||||
let present_index = base.swapchain_loader
|
let (present_index, _) = base
|
||||||
|
.swapchain_loader
|
||||||
.acquire_next_image_khr(
|
.acquire_next_image_khr(
|
||||||
base.swapchain,
|
base.swapchain,
|
||||||
std::u64::MAX,
|
std::u64::MAX,
|
||||||
|
@ -472,7 +476,7 @@ fn main() {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
vk::ClearValue {
|
vk::ClearValue {
|
||||||
depth: vk::ClearDepthStencilValue {
|
depth_stencil: vk::ClearDepthStencilValue {
|
||||||
depth: 1.0,
|
depth: 1.0,
|
||||||
stencil: 0,
|
stencil: 0,
|
||||||
},
|
},
|
||||||
|
@ -480,7 +484,7 @@ fn main() {
|
||||||
];
|
];
|
||||||
|
|
||||||
let render_pass_begin_info = vk::RenderPassBeginInfo {
|
let render_pass_begin_info = vk::RenderPassBeginInfo {
|
||||||
s_type: vk::StructureType::RenderPassBeginInfo,
|
s_type: vk::StructureType::RENDER_PASS_BEGIN_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
render_pass: renderpass,
|
render_pass: renderpass,
|
||||||
framebuffer: framebuffers[present_index as usize],
|
framebuffer: framebuffers[present_index as usize],
|
||||||
|
@ -495,18 +499,18 @@ fn main() {
|
||||||
&base.device,
|
&base.device,
|
||||||
base.draw_command_buffer,
|
base.draw_command_buffer,
|
||||||
base.present_queue,
|
base.present_queue,
|
||||||
&[vk::PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT],
|
&[vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT],
|
||||||
&[base.present_complete_semaphore],
|
&[base.present_complete_semaphore],
|
||||||
&[base.rendering_complete_semaphore],
|
&[base.rendering_complete_semaphore],
|
||||||
|device, draw_command_buffer| {
|
|device, draw_command_buffer| {
|
||||||
device.cmd_begin_render_pass(
|
device.cmd_begin_render_pass(
|
||||||
draw_command_buffer,
|
draw_command_buffer,
|
||||||
&render_pass_begin_info,
|
&render_pass_begin_info,
|
||||||
vk::SubpassContents::Inline,
|
vk::SubpassContents::INLINE,
|
||||||
);
|
);
|
||||||
device.cmd_bind_pipeline(
|
device.cmd_bind_pipeline(
|
||||||
draw_command_buffer,
|
draw_command_buffer,
|
||||||
vk::PipelineBindPoint::Graphics,
|
vk::PipelineBindPoint::GRAPHICS,
|
||||||
graphic_pipeline,
|
graphic_pipeline,
|
||||||
);
|
);
|
||||||
device.cmd_set_viewport(draw_command_buffer, 0, &viewports);
|
device.cmd_set_viewport(draw_command_buffer, 0, &viewports);
|
||||||
|
@ -521,7 +525,7 @@ fn main() {
|
||||||
draw_command_buffer,
|
draw_command_buffer,
|
||||||
index_buffer,
|
index_buffer,
|
||||||
0,
|
0,
|
||||||
vk::IndexType::Uint32,
|
vk::IndexType::UINT32,
|
||||||
);
|
);
|
||||||
device.cmd_draw_indexed(
|
device.cmd_draw_indexed(
|
||||||
draw_command_buffer,
|
draw_command_buffer,
|
||||||
|
@ -538,7 +542,7 @@ fn main() {
|
||||||
);
|
);
|
||||||
//let mut present_info_err = mem::uninitialized();
|
//let mut present_info_err = mem::uninitialized();
|
||||||
let present_info = vk::PresentInfoKHR {
|
let present_info = vk::PresentInfoKHR {
|
||||||
s_type: vk::StructureType::PresentInfoKhr,
|
s_type: vk::StructureType::PRESENT_INFO_KHR,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
wait_semaphore_count: 1,
|
wait_semaphore_count: 1,
|
||||||
p_wait_semaphores: &base.rendering_complete_semaphore,
|
p_wait_semaphores: &base.rendering_complete_semaphore,
|
||||||
|
|
|
@ -22,7 +22,7 @@ use objc::runtime::YES;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use ash::vk;
|
use ash::vk;
|
||||||
use std::default::Default;
|
use ash::Device;
|
||||||
use ash::Entry;
|
use ash::Entry;
|
||||||
use ash::Instance;
|
use ash::Instance;
|
||||||
use ash::Device;
|
use ash::Device;
|
||||||
|
@ -35,22 +35,22 @@ use ash::extensions::XlibSurface;
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
use ash::extensions::MacOSSurface;
|
use ash::extensions::MacOSSurface;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::ptr;
|
use std::default::Default;
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
use std::ops::Drop;
|
use std::ops::Drop;
|
||||||
|
use std::os::raw::{c_char, c_void};
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
// Simple offset_of macro akin to C++ offsetof
|
// Simple offset_of macro akin to C++ offsetof
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! offset_of {
|
macro_rules! offset_of {
|
||||||
($base: path, $field: ident) => {
|
($base:path, $field:ident) => {{
|
||||||
{
|
|
||||||
#[allow(unused_unsafe)]
|
#[allow(unused_unsafe)]
|
||||||
unsafe {
|
unsafe {
|
||||||
let b: $base = mem::uninitialized();
|
let b: $base = mem::uninitialized();
|
||||||
(&b.$field as *const _ as isize) - (&b as *const _ as isize)
|
(&b.$field as *const _ as isize) - (&b as *const _ as isize)
|
||||||
}
|
}
|
||||||
}
|
}};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn record_submit_commandbuffer<D: DeviceV1_0, F: FnOnce(&D, vk::CommandBuffer)>(
|
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
|
device
|
||||||
.reset_command_buffer(
|
.reset_command_buffer(
|
||||||
command_buffer,
|
command_buffer,
|
||||||
vk::COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT,
|
vk::CommandBufferResetFlags::RELEASE_RESOURCES,
|
||||||
)
|
).expect("Reset command buffer failed.");
|
||||||
.expect("Reset command buffer failed.");
|
|
||||||
let command_buffer_begin_info = vk::CommandBufferBeginInfo {
|
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_next: ptr::null(),
|
||||||
p_inheritance_info: ptr::null(),
|
p_inheritance_info: ptr::null(),
|
||||||
flags: vk::COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
flags: vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT,
|
||||||
};
|
};
|
||||||
device
|
device
|
||||||
.begin_command_buffer(command_buffer, &command_buffer_begin_info)
|
.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)
|
.end_command_buffer(command_buffer)
|
||||||
.expect("End commandbuffer");
|
.expect("End commandbuffer");
|
||||||
let fence_create_info = vk::FenceCreateInfo {
|
let fence_create_info = vk::FenceCreateInfo {
|
||||||
s_type: vk::StructureType::FenceCreateInfo,
|
s_type: vk::StructureType::FENCE_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: vk::FenceCreateFlags::empty(),
|
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)
|
.create_fence(&fence_create_info, None)
|
||||||
.expect("Create fence failed.");
|
.expect("Create fence failed.");
|
||||||
let submit_info = vk::SubmitInfo {
|
let submit_info = vk::SubmitInfo {
|
||||||
s_type: vk::StructureType::SubmitInfo,
|
s_type: vk::StructureType::SUBMIT_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
wait_semaphore_count: wait_semaphores.len() as u32,
|
wait_semaphore_count: wait_semaphores.len() as u32,
|
||||||
p_wait_semaphores: wait_semaphores.as_ptr(),
|
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_display = window.get_xlib_display().unwrap();
|
||||||
let x11_window = window.get_xlib_window().unwrap();
|
let x11_window = window.get_xlib_window().unwrap();
|
||||||
let x11_create_info = vk::XlibSurfaceCreateInfoKHR {
|
let x11_create_info = vk::XlibSurfaceCreateInfoKHR {
|
||||||
s_type: vk::StructureType::XlibSurfaceCreateInfoKhr,
|
s_type: vk::StructureType::XLIB_SURFACE_CREATE_INFO_KHR,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
window: x11_window as vk::Window,
|
window: x11_window as vk::Window,
|
||||||
dpy: x11_display as *mut vk::Display,
|
dpy: x11_display as *mut vk::Display,
|
||||||
};
|
};
|
||||||
let xlib_surface_loader =
|
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)
|
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,
|
window: &winit::Window,
|
||||||
) -> Result<vk::SurfaceKHR, vk::Result> {
|
) -> Result<vk::SurfaceKHR, vk::Result> {
|
||||||
use winapi::shared::windef::HWND;
|
use winapi::shared::windef::HWND;
|
||||||
use winapi::um::winuser::GetWindow;
|
use winapi::um::libloaderapi::GetModuleHandleW;
|
||||||
use winit::os::windows::WindowExt;
|
use winit::os::windows::WindowExt;
|
||||||
|
|
||||||
let hwnd = window.get_hwnd() as HWND;
|
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 {
|
let win32_create_info = vk::Win32SurfaceCreateInfoKHR {
|
||||||
s_type: vk::StructureType::Win32SurfaceCreateInfoKhr,
|
s_type: vk::StructureType::WIN32_SURFACE_CREATE_INFO_KHR,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
hinstance: hinstance,
|
hinstance: hinstance,
|
||||||
hwnd: hwnd as *const vk::c_void,
|
hwnd: hwnd as *const c_void,
|
||||||
};
|
};
|
||||||
let win32_surface_loader =
|
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)
|
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(
|
unsafe extern "system" fn vulkan_debug_callback(
|
||||||
_: vk::DebugReportFlagsEXT,
|
_: vk::DebugReportFlagsEXT,
|
||||||
_: vk::DebugReportObjectTypeEXT,
|
_: vk::DebugReportObjectTypeEXT,
|
||||||
_: vk::uint64_t,
|
_: u64,
|
||||||
_: vk::size_t,
|
_: usize,
|
||||||
_: vk::int32_t,
|
_: i32,
|
||||||
_: *const vk::c_char,
|
_: *const c_char,
|
||||||
p_message: *const vk::c_char,
|
p_message: *const c_char,
|
||||||
_: *mut vk::c_void,
|
_: *mut c_void,
|
||||||
) -> u32 {
|
) -> u32 {
|
||||||
println!("{:?}", CStr::from_ptr(p_message));
|
println!("{:?}", CStr::from_ptr(p_message));
|
||||||
vk::VK_FALSE
|
vk::VK_FALSE
|
||||||
|
@ -269,9 +268,9 @@ pub fn find_memorytype_index_f<F: Fn(vk::MemoryPropertyFlags, vk::MemoryProperty
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ExampleBase {
|
pub struct ExampleBase {
|
||||||
pub entry: Entry<V1_0>,
|
pub entry: Entry,
|
||||||
pub instance: Instance<V1_0>,
|
pub instance: Instance,
|
||||||
pub device: Device<V1_0>,
|
pub device: Device,
|
||||||
pub surface_loader: Surface,
|
pub surface_loader: Surface,
|
||||||
pub swapchain_loader: Swapchain,
|
pub swapchain_loader: Swapchain,
|
||||||
pub debug_report_loader: DebugReport,
|
pub debug_report_loader: DebugReport,
|
||||||
|
@ -318,7 +317,7 @@ impl ExampleBase {
|
||||||
ControlFlow::Continue
|
ControlFlow::Continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WindowEvent::Closed => winit::ControlFlow::Break,
|
WindowEvent::CloseRequested => winit::ControlFlow::Break,
|
||||||
_ => ControlFlow::Continue,
|
_ => ControlFlow::Continue,
|
||||||
},
|
},
|
||||||
_ => ControlFlow::Continue,
|
_ => ControlFlow::Continue,
|
||||||
|
@ -331,8 +330,10 @@ impl ExampleBase {
|
||||||
let events_loop = winit::EventsLoop::new();
|
let events_loop = winit::EventsLoop::new();
|
||||||
let window = winit::WindowBuilder::new()
|
let window = winit::WindowBuilder::new()
|
||||||
.with_title("Ash - Example")
|
.with_title("Ash - Example")
|
||||||
.with_dimensions(window_width, window_height)
|
.with_dimensions(winit::dpi::LogicalSize::new(
|
||||||
.build(&events_loop)
|
window_width as f64,
|
||||||
|
window_height as f64,
|
||||||
|
)).build(&events_loop)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let entry = Entry::new().unwrap();
|
let entry = Entry::new().unwrap();
|
||||||
let app_name = CString::new("VulkanTriangle").unwrap();
|
let app_name = CString::new("VulkanTriangle").unwrap();
|
||||||
|
@ -347,7 +348,7 @@ impl ExampleBase {
|
||||||
let extension_names_raw = extension_names();
|
let extension_names_raw = extension_names();
|
||||||
let appinfo = vk::ApplicationInfo {
|
let appinfo = vk::ApplicationInfo {
|
||||||
p_application_name: raw_name,
|
p_application_name: raw_name,
|
||||||
s_type: vk::StructureType::ApplicationInfo,
|
s_type: vk::StructureType::APPLICATION_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
application_version: 0,
|
application_version: 0,
|
||||||
p_engine_name: raw_name,
|
p_engine_name: raw_name,
|
||||||
|
@ -355,7 +356,7 @@ impl ExampleBase {
|
||||||
api_version: vk_make_version!(1, 0, 36),
|
api_version: vk_make_version!(1, 0, 36),
|
||||||
};
|
};
|
||||||
let create_info = vk::InstanceCreateInfo {
|
let create_info = vk::InstanceCreateInfo {
|
||||||
s_type: vk::StructureType::InstanceCreateInfo,
|
s_type: vk::StructureType::INSTANCE_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
p_application_info: &appinfo,
|
p_application_info: &appinfo,
|
||||||
|
@ -364,19 +365,20 @@ impl ExampleBase {
|
||||||
pp_enabled_extension_names: extension_names_raw.as_ptr(),
|
pp_enabled_extension_names: extension_names_raw.as_ptr(),
|
||||||
enabled_extension_count: extension_names_raw.len() as u32,
|
enabled_extension_count: extension_names_raw.len() as u32,
|
||||||
};
|
};
|
||||||
let instance: Instance<V1_0> = entry
|
let instance: Instance = entry
|
||||||
.create_instance(&create_info, None)
|
.create_instance(&create_info, None)
|
||||||
.expect("Instance creation error");
|
.expect("Instance creation error");
|
||||||
let debug_info = vk::DebugReportCallbackCreateInfoEXT {
|
let debug_info = vk::DebugReportCallbackCreateInfoEXT {
|
||||||
s_type: vk::StructureType::DebugReportCallbackCreateInfoExt,
|
s_type: vk::StructureType::DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: vk::DEBUG_REPORT_ERROR_BIT_EXT | vk::DEBUG_REPORT_WARNING_BIT_EXT
|
flags: vk::DebugReportFlagsEXT::ERROR
|
||||||
| vk::DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
|
| vk::DebugReportFlagsEXT::WARNING
|
||||||
pfn_callback: vulkan_debug_callback,
|
| vk::DebugReportFlagsEXT::PERFORMANCE_WARNING,
|
||||||
|
pfn_callback: Some(vulkan_debug_callback),
|
||||||
p_user_data: ptr::null_mut(),
|
p_user_data: ptr::null_mut(),
|
||||||
};
|
};
|
||||||
let debug_report_loader =
|
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
|
let debug_call_back = debug_report_loader
|
||||||
.create_debug_report_callback_ext(&debug_info, None)
|
.create_debug_report_callback_ext(&debug_info, None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -385,7 +387,7 @@ impl ExampleBase {
|
||||||
.enumerate_physical_devices()
|
.enumerate_physical_devices()
|
||||||
.expect("Physical device error");
|
.expect("Physical device error");
|
||||||
let surface_loader =
|
let surface_loader =
|
||||||
Surface::new(&entry, &instance).expect("Unable to load the Surface extension");
|
Surface::new(&entry, &instance);
|
||||||
let (pdevice, queue_family_index) = pdevices
|
let (pdevice, queue_family_index) = pdevices
|
||||||
.iter()
|
.iter()
|
||||||
.map(|pdevice| {
|
.map(|pdevice| {
|
||||||
|
@ -394,9 +396,9 @@ impl ExampleBase {
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter_map(|(index, ref info)| {
|
.filter_map(|(index, ref info)| {
|
||||||
let supports_graphic_and_surface = info.queue_flags
|
let supports_graphic_and_surface =
|
||||||
.subset(vk::QUEUE_GRAPHICS_BIT)
|
info.queue_flags.contains(vk::QueueFlags::GRAPHICS) && surface_loader
|
||||||
&& surface_loader.get_physical_device_surface_support_khr(
|
.get_physical_device_surface_support_khr(
|
||||||
*pdevice,
|
*pdevice,
|
||||||
index as u32,
|
index as u32,
|
||||||
surface,
|
surface,
|
||||||
|
@ -405,10 +407,8 @@ impl ExampleBase {
|
||||||
true => Some((*pdevice, index)),
|
true => Some((*pdevice, index)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
})
|
}).nth(0)
|
||||||
.nth(0)
|
}).filter_map(|v| v)
|
||||||
})
|
|
||||||
.filter_map(|v| v)
|
|
||||||
.nth(0)
|
.nth(0)
|
||||||
.expect("Couldn't find suitable device.");
|
.expect("Couldn't find suitable device.");
|
||||||
let queue_family_index = queue_family_index as u32;
|
let queue_family_index = queue_family_index as u32;
|
||||||
|
@ -419,7 +419,7 @@ impl ExampleBase {
|
||||||
};
|
};
|
||||||
let priorities = [1.0];
|
let priorities = [1.0];
|
||||||
let queue_info = vk::DeviceQueueCreateInfo {
|
let queue_info = vk::DeviceQueueCreateInfo {
|
||||||
s_type: vk::StructureType::DeviceQueueCreateInfo,
|
s_type: vk::StructureType::DEVICE_QUEUE_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
queue_family_index: queue_family_index as u32,
|
queue_family_index: queue_family_index as u32,
|
||||||
|
@ -427,7 +427,7 @@ impl ExampleBase {
|
||||||
queue_count: priorities.len() as u32,
|
queue_count: priorities.len() as u32,
|
||||||
};
|
};
|
||||||
let device_create_info = vk::DeviceCreateInfo {
|
let device_create_info = vk::DeviceCreateInfo {
|
||||||
s_type: vk::StructureType::DeviceCreateInfo,
|
s_type: vk::StructureType::DEVICE_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
queue_create_info_count: 1,
|
queue_create_info_count: 1,
|
||||||
|
@ -438,7 +438,7 @@ impl ExampleBase {
|
||||||
pp_enabled_extension_names: device_extension_names_raw.as_ptr(),
|
pp_enabled_extension_names: device_extension_names_raw.as_ptr(),
|
||||||
p_enabled_features: &features,
|
p_enabled_features: &features,
|
||||||
};
|
};
|
||||||
let device: Device<V1_0> = instance
|
let device: Device = instance
|
||||||
.create_device(pdevice, &device_create_info, None)
|
.create_device(pdevice, &device_create_info, None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let present_queue = device.get_device_queue(queue_family_index as u32, 0);
|
let present_queue = device.get_device_queue(queue_family_index as u32, 0);
|
||||||
|
@ -449,13 +449,12 @@ impl ExampleBase {
|
||||||
let surface_format = surface_formats
|
let surface_format = surface_formats
|
||||||
.iter()
|
.iter()
|
||||||
.map(|sfmt| match sfmt.format {
|
.map(|sfmt| match sfmt.format {
|
||||||
vk::Format::Undefined => vk::SurfaceFormatKHR {
|
vk::Format::UNDEFINED => vk::SurfaceFormatKHR {
|
||||||
format: vk::Format::B8g8r8Unorm,
|
format: vk::Format::B8G8R8_UNORM,
|
||||||
color_space: sfmt.color_space,
|
color_space: sfmt.color_space,
|
||||||
},
|
},
|
||||||
_ => sfmt.clone(),
|
_ => sfmt.clone(),
|
||||||
})
|
}).nth(0)
|
||||||
.nth(0)
|
|
||||||
.expect("Unable to find suitable surface format.");
|
.expect("Unable to find suitable surface format.");
|
||||||
let surface_capabilities = surface_loader
|
let surface_capabilities = surface_loader
|
||||||
.get_physical_device_surface_capabilities_khr(pdevice, surface)
|
.get_physical_device_surface_capabilities_khr(pdevice, surface)
|
||||||
|
@ -475,9 +474,9 @@ impl ExampleBase {
|
||||||
};
|
};
|
||||||
let pre_transform = if surface_capabilities
|
let pre_transform = if surface_capabilities
|
||||||
.supported_transforms
|
.supported_transforms
|
||||||
.subset(vk::SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
|
.contains(vk::SurfaceTransformFlagsKHR::IDENTITY)
|
||||||
{
|
{
|
||||||
vk::SURFACE_TRANSFORM_IDENTITY_BIT_KHR
|
vk::SurfaceTransformFlagsKHR::IDENTITY
|
||||||
} else {
|
} else {
|
||||||
surface_capabilities.current_transform
|
surface_capabilities.current_transform
|
||||||
};
|
};
|
||||||
|
@ -487,12 +486,12 @@ impl ExampleBase {
|
||||||
let present_mode = present_modes
|
let present_mode = present_modes
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.find(|&mode| mode == vk::PresentModeKHR::Mailbox)
|
.find(|&mode| mode == vk::PresentModeKHR::MAILBOX)
|
||||||
.unwrap_or(vk::PresentModeKHR::Fifo);
|
.unwrap_or(vk::PresentModeKHR::FIFO);
|
||||||
let swapchain_loader =
|
let swapchain_loader =
|
||||||
Swapchain::new(&instance, &device).expect("Unable to load swapchain");
|
Swapchain::new(&instance, &device);
|
||||||
let swapchain_create_info = vk::SwapchainCreateInfoKHR {
|
let swapchain_create_info = vk::SwapchainCreateInfoKHR {
|
||||||
s_type: vk::StructureType::SwapchainCreateInfoKhr,
|
s_type: vk::StructureType::SWAPCHAIN_CREATE_INFO_KHR,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
surface: surface,
|
surface: surface,
|
||||||
|
@ -500,10 +499,10 @@ impl ExampleBase {
|
||||||
image_color_space: surface_format.color_space,
|
image_color_space: surface_format.color_space,
|
||||||
image_format: surface_format.format,
|
image_format: surface_format.format,
|
||||||
image_extent: surface_resolution.clone(),
|
image_extent: surface_resolution.clone(),
|
||||||
image_usage: vk::IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
image_usage: vk::ImageUsageFlags::COLOR_ATTACHMENT,
|
||||||
image_sharing_mode: vk::SharingMode::Exclusive,
|
image_sharing_mode: vk::SharingMode::EXCLUSIVE,
|
||||||
pre_transform: pre_transform,
|
pre_transform: pre_transform,
|
||||||
composite_alpha: vk::COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
|
composite_alpha: vk::CompositeAlphaFlagsKHR::OPAQUE,
|
||||||
present_mode: present_mode,
|
present_mode: present_mode,
|
||||||
clipped: 1,
|
clipped: 1,
|
||||||
old_swapchain: vk::SwapchainKHR::null(),
|
old_swapchain: vk::SwapchainKHR::null(),
|
||||||
|
@ -515,18 +514,18 @@ impl ExampleBase {
|
||||||
.create_swapchain_khr(&swapchain_create_info, None)
|
.create_swapchain_khr(&swapchain_create_info, None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let pool_create_info = vk::CommandPoolCreateInfo {
|
let pool_create_info = vk::CommandPoolCreateInfo {
|
||||||
s_type: vk::StructureType::CommandPoolCreateInfo,
|
s_type: vk::StructureType::COMMAND_POOL_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
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,
|
queue_family_index: queue_family_index,
|
||||||
};
|
};
|
||||||
let pool = device.create_command_pool(&pool_create_info, None).unwrap();
|
let pool = device.create_command_pool(&pool_create_info, None).unwrap();
|
||||||
let command_buffer_allocate_info = vk::CommandBufferAllocateInfo {
|
let command_buffer_allocate_info = vk::CommandBufferAllocateInfo {
|
||||||
s_type: vk::StructureType::CommandBufferAllocateInfo,
|
s_type: vk::StructureType::COMMAND_BUFFER_ALLOCATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
command_buffer_count: 2,
|
command_buffer_count: 2,
|
||||||
command_pool: pool,
|
command_pool: pool,
|
||||||
level: vk::CommandBufferLevel::Primary,
|
level: vk::CommandBufferLevel::PRIMARY,
|
||||||
};
|
};
|
||||||
let command_buffers = device
|
let command_buffers = device
|
||||||
.allocate_command_buffers(&command_buffer_allocate_info)
|
.allocate_command_buffers(&command_buffer_allocate_info)
|
||||||
|
@ -541,10 +540,10 @@ impl ExampleBase {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&image| {
|
.map(|&image| {
|
||||||
let create_view_info = vk::ImageViewCreateInfo {
|
let create_view_info = vk::ImageViewCreateInfo {
|
||||||
s_type: vk::StructureType::ImageViewCreateInfo,
|
s_type: vk::StructureType::IMAGE_VIEW_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
view_type: vk::ImageViewType::Type2d,
|
view_type: vk::ImageViewType::TYPE_2D,
|
||||||
format: surface_format.format,
|
format: surface_format.format,
|
||||||
components: vk::ComponentMapping {
|
components: vk::ComponentMapping {
|
||||||
r: vk::ComponentSwizzle::R,
|
r: vk::ComponentSwizzle::R,
|
||||||
|
@ -553,7 +552,7 @@ impl ExampleBase {
|
||||||
a: vk::ComponentSwizzle::A,
|
a: vk::ComponentSwizzle::A,
|
||||||
},
|
},
|
||||||
subresource_range: vk::ImageSubresourceRange {
|
subresource_range: vk::ImageSubresourceRange {
|
||||||
aspect_mask: vk::IMAGE_ASPECT_COLOR_BIT,
|
aspect_mask: vk::ImageAspectFlags::COLOR,
|
||||||
base_mip_level: 0,
|
base_mip_level: 0,
|
||||||
level_count: 1,
|
level_count: 1,
|
||||||
base_array_layer: 0,
|
base_array_layer: 0,
|
||||||
|
@ -562,15 +561,14 @@ impl ExampleBase {
|
||||||
image: image,
|
image: image,
|
||||||
};
|
};
|
||||||
device.create_image_view(&create_view_info, None).unwrap()
|
device.create_image_view(&create_view_info, None).unwrap()
|
||||||
})
|
}).collect();
|
||||||
.collect();
|
|
||||||
let device_memory_properties = instance.get_physical_device_memory_properties(pdevice);
|
let device_memory_properties = instance.get_physical_device_memory_properties(pdevice);
|
||||||
let depth_image_create_info = vk::ImageCreateInfo {
|
let depth_image_create_info = vk::ImageCreateInfo {
|
||||||
s_type: vk::StructureType::ImageCreateInfo,
|
s_type: vk::StructureType::IMAGE_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
image_type: vk::ImageType::Type2d,
|
image_type: vk::ImageType::TYPE_2D,
|
||||||
format: vk::Format::D16Unorm,
|
format: vk::Format::D16_UNORM,
|
||||||
extent: vk::Extent3D {
|
extent: vk::Extent3D {
|
||||||
width: surface_resolution.width,
|
width: surface_resolution.width,
|
||||||
height: surface_resolution.height,
|
height: surface_resolution.height,
|
||||||
|
@ -578,25 +576,24 @@ impl ExampleBase {
|
||||||
},
|
},
|
||||||
mip_levels: 1,
|
mip_levels: 1,
|
||||||
array_layers: 1,
|
array_layers: 1,
|
||||||
samples: vk::SAMPLE_COUNT_1_BIT,
|
samples: vk::SampleCountFlags::TYPE_1,
|
||||||
tiling: vk::ImageTiling::Optimal,
|
tiling: vk::ImageTiling::OPTIMAL,
|
||||||
usage: vk::IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
usage: vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT,
|
||||||
sharing_mode: vk::SharingMode::Exclusive,
|
sharing_mode: vk::SharingMode::EXCLUSIVE,
|
||||||
queue_family_index_count: 0,
|
queue_family_index_count: 0,
|
||||||
p_queue_family_indices: ptr::null(),
|
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 = 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_req = device.get_image_memory_requirements(depth_image);
|
||||||
let depth_image_memory_index =
|
let depth_image_memory_index = find_memorytype_index(
|
||||||
find_memorytype_index(
|
|
||||||
&depth_image_memory_req,
|
&depth_image_memory_req,
|
||||||
&device_memory_properties,
|
&device_memory_properties,
|
||||||
vk::MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
vk::MemoryPropertyFlags::DEVICE_LOCAL,
|
||||||
).expect("Unable to find suitable memory index for depth image.");
|
).expect("Unable to find suitable memory index for depth image.");
|
||||||
|
|
||||||
let depth_image_allocate_info = vk::MemoryAllocateInfo {
|
let depth_image_allocate_info = vk::MemoryAllocateInfo {
|
||||||
s_type: vk::StructureType::MemoryAllocateInfo,
|
s_type: vk::StructureType::MEMORY_ALLOCATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
allocation_size: depth_image_memory_req.size,
|
allocation_size: depth_image_memory_req.size,
|
||||||
memory_type_index: depth_image_memory_index,
|
memory_type_index: depth_image_memory_index,
|
||||||
|
@ -611,23 +608,23 @@ impl ExampleBase {
|
||||||
&device,
|
&device,
|
||||||
setup_command_buffer,
|
setup_command_buffer,
|
||||||
present_queue,
|
present_queue,
|
||||||
&[vk::PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT],
|
&[vk::PipelineStageFlags::BOTTOM_OF_PIPE],
|
||||||
&[],
|
&[],
|
||||||
&[],
|
&[],
|
||||||
|device, setup_command_buffer| {
|
|device, setup_command_buffer| {
|
||||||
let layout_transition_barrier = vk::ImageMemoryBarrier {
|
let layout_transition_barrier = vk::ImageMemoryBarrier {
|
||||||
s_type: vk::StructureType::ImageMemoryBarrier,
|
s_type: vk::StructureType::IMAGE_MEMORY_BARRIER,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
src_access_mask: Default::default(),
|
src_access_mask: Default::default(),
|
||||||
dst_access_mask: vk::ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
|
dst_access_mask: vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ
|
||||||
| vk::ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
| vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE,
|
||||||
old_layout: vk::ImageLayout::Undefined,
|
old_layout: vk::ImageLayout::UNDEFINED,
|
||||||
new_layout: vk::ImageLayout::DepthStencilAttachmentOptimal,
|
new_layout: vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||||
src_queue_family_index: vk::VK_QUEUE_FAMILY_IGNORED,
|
src_queue_family_index: vk::QUEUE_FAMILY_IGNORED,
|
||||||
dst_queue_family_index: vk::VK_QUEUE_FAMILY_IGNORED,
|
dst_queue_family_index: vk::QUEUE_FAMILY_IGNORED,
|
||||||
image: depth_image,
|
image: depth_image,
|
||||||
subresource_range: vk::ImageSubresourceRange {
|
subresource_range: vk::ImageSubresourceRange {
|
||||||
aspect_mask: vk::IMAGE_ASPECT_DEPTH_BIT,
|
aspect_mask: vk::ImageAspectFlags::DEPTH,
|
||||||
base_mip_level: 0,
|
base_mip_level: 0,
|
||||||
level_count: 1,
|
level_count: 1,
|
||||||
base_array_layer: 0,
|
base_array_layer: 0,
|
||||||
|
@ -636,8 +633,8 @@ impl ExampleBase {
|
||||||
};
|
};
|
||||||
device.cmd_pipeline_barrier(
|
device.cmd_pipeline_barrier(
|
||||||
setup_command_buffer,
|
setup_command_buffer,
|
||||||
vk::PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
vk::PipelineStageFlags::BOTTOM_OF_PIPE,
|
||||||
vk::PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
vk::PipelineStageFlags::LATE_FRAGMENT_TESTS,
|
||||||
vk::DependencyFlags::empty(),
|
vk::DependencyFlags::empty(),
|
||||||
&[],
|
&[],
|
||||||
&[],
|
&[],
|
||||||
|
@ -646,19 +643,19 @@ impl ExampleBase {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let depth_image_view_info = vk::ImageViewCreateInfo {
|
let depth_image_view_info = vk::ImageViewCreateInfo {
|
||||||
s_type: vk::StructureType::ImageViewCreateInfo,
|
s_type: vk::StructureType::IMAGE_VIEW_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
view_type: vk::ImageViewType::Type2d,
|
view_type: vk::ImageViewType::TYPE_2D,
|
||||||
format: depth_image_create_info.format,
|
format: depth_image_create_info.format,
|
||||||
components: vk::ComponentMapping {
|
components: vk::ComponentMapping {
|
||||||
r: vk::ComponentSwizzle::Identity,
|
r: vk::ComponentSwizzle::IDENTITY,
|
||||||
g: vk::ComponentSwizzle::Identity,
|
g: vk::ComponentSwizzle::IDENTITY,
|
||||||
b: vk::ComponentSwizzle::Identity,
|
b: vk::ComponentSwizzle::IDENTITY,
|
||||||
a: vk::ComponentSwizzle::Identity,
|
a: vk::ComponentSwizzle::IDENTITY,
|
||||||
},
|
},
|
||||||
subresource_range: vk::ImageSubresourceRange {
|
subresource_range: vk::ImageSubresourceRange {
|
||||||
aspect_mask: vk::IMAGE_ASPECT_DEPTH_BIT,
|
aspect_mask: vk::ImageAspectFlags::DEPTH,
|
||||||
base_mip_level: 0,
|
base_mip_level: 0,
|
||||||
level_count: 1,
|
level_count: 1,
|
||||||
base_array_layer: 0,
|
base_array_layer: 0,
|
||||||
|
@ -670,7 +667,7 @@ impl ExampleBase {
|
||||||
.create_image_view(&depth_image_view_info, None)
|
.create_image_view(&depth_image_view_info, None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let semaphore_create_info = vk::SemaphoreCreateInfo {
|
let semaphore_create_info = vk::SemaphoreCreateInfo {
|
||||||
s_type: vk::StructureType::SemaphoreCreateInfo,
|
s_type: vk::StructureType::SEMAPHORE_CREATE_INFO,
|
||||||
p_next: ptr::null(),
|
p_next: ptr::null(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
20
generator/Cargo.toml
Normal file
20
generator/Cargo.toml
Normal 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"]
|
||||||
|
|
1
generator/Vulkan-Headers
Submodule
1
generator/Vulkan-Headers
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 718a04e51b967fbe6de9d09ecfc15397f0eae5bd
|
7
generator/src/bin/generator.rs
Normal file
7
generator/src/bin/generator.rs
Normal 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
1899
generator/src/lib.rs
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue