Refactored extension loading into seperate modules

This commit is contained in:
maik klein 2016-12-23 11:42:18 +01:00
parent e5efcc3c1d
commit 1f8e284ca9
10 changed files with 340 additions and 274 deletions

View file

@ -1,7 +1,6 @@
#![allow(dead_code)] #![allow(dead_code)]
#[macro_use] #[macro_use]
extern crate ash; extern crate ash;
extern crate glfw; extern crate glfw;
use ash::vk; use ash::vk;
@ -9,6 +8,7 @@ use std::default::Default;
use glfw::*; use glfw::*;
use ash::entry::Entry; use ash::entry::Entry;
use ash::instance::Instance; use ash::instance::Instance;
use ash::extensions::{Swapchain, XlibSurface, Surface, DebugReport};
use ash::device::Device; use ash::device::Device;
use std::ptr; use std::ptr;
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString};
@ -42,7 +42,7 @@ fn create_surface(instance: &Instance,
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 = instance.load_xlib_surface(&entry); let xlib_surface_loader = XlibSurface::new(&entry, &instance);
xlib_surface_loader.create_xlib_surface_khr(&x11_create_info) xlib_surface_loader.create_xlib_surface_khr(&x11_create_info)
} }
@ -154,10 +154,12 @@ fn main() {
pfn_callback: vulkan_debug_callback, pfn_callback: vulkan_debug_callback,
p_user_data: ptr::null_mut(), p_user_data: ptr::null_mut(),
}; };
let debug_call_back = instance.create_debug_report_callback_ext(&debug_info).unwrap(); let debug_report_loader = DebugReport::new(&entry, &instance);
let debug_call_back = debug_report_loader.create_debug_report_callback_ext(&debug_info)
.unwrap();
let surface = create_surface(&instance, &entry, &window).unwrap(); let surface = create_surface(&instance, &entry, &window).unwrap();
let pdevices = instance.enumerate_physical_devices().expect("Physical device error"); let pdevices = instance.enumerate_physical_devices().expect("Physical device error");
let surface_loader = instance.load_surface(&entry); let surface_loader = Surface::new(&entry, &instance);
let (pdevice, queue_family_index) = pdevices.iter() let (pdevice, queue_family_index) = pdevices.iter()
.map(|pdevice| { .map(|pdevice| {
instance.get_physical_device_queue_family_properties(*pdevice) instance.get_physical_device_queue_family_properties(*pdevice)
@ -255,7 +257,7 @@ fn main() {
.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 = device.load_swapchain(&instance); let swapchain_loader = 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::SwapchainCreateInfoKhr,
p_next: ptr::null(), p_next: ptr::null(),
@ -934,6 +936,6 @@ fn main() {
swapchain_loader.destroy_swapchain_khr(swapchain); swapchain_loader.destroy_swapchain_khr(swapchain);
device.destroy_device(); device.destroy_device();
surface_loader.destroy_surface_khr(surface); surface_loader.destroy_surface_khr(surface);
instance.destroy_debug_report_callback_ext(debug_call_back); debug_report_loader.destroy_debug_report_callback_ext(debug_call_back);
instance.destroy_instance(); instance.destroy_instance();
} }

View file

@ -9,92 +9,11 @@ unsafe impl Sync for Device {}
unsafe impl Send for Device {} unsafe impl Send for Device {}
pub struct Device { pub struct Device {
handle: vk::Device, pub handle: vk::Device,
device_fn: vk::DeviceFn, pub device_fn: vk::DeviceFn,
}
pub struct Swapchain {
handle: vk::Device,
swapchain_fn: vk::SwapchainFn,
}
impl Swapchain {
pub fn destroy_swapchain_khr(&self, swapchain: vk::SwapchainKHR) {
unsafe {
self.swapchain_fn.destroy_swapchain_khr(self.handle, swapchain, ptr::null());
}
}
pub fn acquire_next_image_khr(&self,
swapchain: vk::SwapchainKHR,
timeout: vk::uint64_t,
semaphore: vk::Semaphore,
fence: vk::Fence)
-> VkResult<vk::uint32_t> {
unsafe {
let mut index = mem::uninitialized();
let err_code = self.swapchain_fn
.acquire_next_image_khr(self.handle,
swapchain,
timeout,
semaphore,
fence,
&mut index);
match err_code {
vk::Result::Success => Ok(index),
_ => Err(err_code),
}
}
}
pub fn create_swapchain_khr(&self,
create_info: &vk::SwapchainCreateInfoKHR)
-> VkResult<vk::SwapchainKHR> {
unsafe {
let mut swapchain = mem::uninitialized();
let err_code = self.swapchain_fn
.create_swapchain_khr(self.handle, create_info, ptr::null(), &mut swapchain);
match err_code {
vk::Result::Success => Ok(swapchain),
_ => Err(err_code),
}
}
}
pub fn get_swapchain_images_khr(&self,
swapchain: vk::SwapchainKHR)
-> VkResult<Vec<vk::Image>> {
unsafe {
let mut count = 0;
self.swapchain_fn
.get_swapchain_images_khr(self.handle, swapchain, &mut count, ptr::null_mut());
let mut v = Vec::with_capacity(count as vk::size_t);
let err_code = self.swapchain_fn
.get_swapchain_images_khr(self.handle, swapchain, &mut count, v.as_mut_ptr());
v.set_len(count as vk::size_t);
match err_code {
vk::Result::Success => Ok(v),
_ => Err(err_code),
}
}
}
} }
impl Device { impl Device {
pub fn load_swapchain(&self, instance: &Instance) -> Swapchain {
let swapchain_fn = vk::SwapchainFn::load(|name| {
unsafe {
mem::transmute(instance.instance_fn
.get_device_proc_addr(self.handle, name.as_ptr()))
}
})
.unwrap();
Swapchain {
handle: self.handle,
swapchain_fn: swapchain_fn,
}
}
pub unsafe fn from_raw(handle: vk::Device, device_fn: vk::DeviceFn) -> Self { pub unsafe fn from_raw(handle: vk::Device, device_fn: vk::DeviceFn) -> Self {
Device { Device {

View file

@ -0,0 +1,51 @@
use prelude::*;
use std::ptr;
use std::mem;
use instance::Instance;
use entry::Entry;
use vk;
pub struct DebugReport {
pub handle: vk::Instance,
pub debug_report_fn: vk::DebugReportFn,
}
impl DebugReport {
pub fn new(entry: &Entry, instance: &Instance) -> DebugReport {
let debug_report_fn = vk::DebugReportFn::load(|name| {
unsafe {
mem::transmute(entry.static_fn
.get_instance_proc_addr(instance.handle, name.as_ptr()))
}
})
.unwrap();
DebugReport {
handle: instance.handle,
debug_report_fn: debug_report_fn,
}
}
pub fn destroy_debug_report_callback_ext(&self, debug: vk::DebugReportCallbackEXT) {
unsafe {
self.debug_report_fn.destroy_debug_report_callback_ext(self.handle, debug, ptr::null());
}
}
pub fn create_debug_report_callback_ext(&self,
create_info: &vk::DebugReportCallbackCreateInfoEXT)
-> VkResult<vk::DebugReportCallbackEXT> {
unsafe {
let mut debug_cb = mem::uninitialized();
let err_code = self.debug_report_fn
.create_debug_report_callback_ext(self.handle,
create_info,
ptr::null(),
&mut debug_cb);
match err_code {
vk::Result::Success => Ok(debug_cb),
_ => Err(err_code),
}
}
}
}

9
src/extensions/mod.rs Normal file
View file

@ -0,0 +1,9 @@
pub use self::swapchain::Swapchain;
pub use self::surface::Surface;
pub use self::xlibsurface::XlibSurface;
pub use self::debug_report::DebugReport;
mod swapchain;
mod surface;
mod xlibsurface;
mod debug_report;

114
src/extensions/surface.rs Normal file
View file

@ -0,0 +1,114 @@
use prelude::*;
use std::ptr;
use std::mem;
use instance::Instance;
use entry::Entry;
use vk;
pub struct Surface {
pub handle: vk::Instance,
pub surface_fn: vk::SurfaceFn,
}
impl Surface {
pub fn new(entry: &Entry, instance: &Instance) -> Surface {
let surface_fn = vk::SurfaceFn::load(|name| {
unsafe {
mem::transmute(entry.static_fn
.get_instance_proc_addr(instance.handle, name.as_ptr()))
}
})
.unwrap();
Surface {
handle: instance.handle,
surface_fn: surface_fn,
}
}
pub fn get_physical_device_surface_support_khr(&self,
physical_device: vk::PhysicalDevice,
queue_index: vk::uint32_t,
surface: vk::SurfaceKHR)
-> bool {
unsafe {
let mut b = mem::uninitialized();
self.surface_fn
.get_physical_device_surface_support_khr(physical_device,
queue_index,
surface,
&mut b);
b > 0
}
}
pub fn get_physical_device_surface_present_modes_khr(&self,
physical_device: vk::PhysicalDevice,
surface: vk::SurfaceKHR)
-> VkResult<Vec<vk::PresentModeKHR>> {
unsafe {
let mut count = 0;
self.surface_fn.get_physical_device_surface_present_modes_khr(physical_device,
surface,
&mut count,
ptr::null_mut());
let mut v = Vec::with_capacity(count as usize);
let err_code = self.surface_fn
.get_physical_device_surface_present_modes_khr(physical_device,
surface,
&mut count,
v.as_mut_ptr());
v.set_len(count as usize);
match err_code {
vk::Result::Success => Ok(v),
_ => Err(err_code),
}
}
}
pub fn get_physical_device_surface_capabilities_khr(&self,
physical_device: vk::PhysicalDevice,
surface: vk::SurfaceKHR)
-> VkResult<vk::SurfaceCapabilitiesKHR> {
unsafe {
let mut surface_capabilities = mem::uninitialized();
let err_code = self.surface_fn
.get_physical_device_surface_capabilities_khr(physical_device,
surface,
&mut surface_capabilities);
match err_code {
vk::Result::Success => Ok(surface_capabilities),
_ => Err(err_code),
}
}
}
pub fn get_physical_device_surface_formats_khr(&self,
physical_device: vk::PhysicalDevice,
surface: vk::SurfaceKHR)
-> VkResult<Vec<vk::SurfaceFormatKHR>> {
unsafe {
let mut count = 0;
self.surface_fn.get_physical_device_surface_formats_khr(physical_device,
surface,
&mut count,
ptr::null_mut());
let mut v = Vec::with_capacity(count as usize);
let err_code = self.surface_fn
.get_physical_device_surface_formats_khr(physical_device,
surface,
&mut count,
v.as_mut_ptr());
v.set_len(count as usize);
match err_code {
vk::Result::Success => Ok(v),
_ => Err(err_code),
}
}
}
pub fn destroy_surface_khr(&self, surface: vk::SurfaceKHR) {
unsafe {
self.surface_fn.destroy_surface_khr(self.handle, surface, ptr::null());
}
}
}

View file

@ -0,0 +1,87 @@
use prelude::*;
use std::ptr;
use std::mem;
use instance::Instance;
use device::Device;
use vk;
pub struct Swapchain {
handle: vk::Device,
swapchain_fn: vk::SwapchainFn,
}
impl Swapchain {
pub fn new(instance: &Instance, device: &Device) -> Swapchain {
let swapchain_fn = vk::SwapchainFn::load(|name| {
unsafe {
mem::transmute(instance.instance_fn
.get_device_proc_addr(device.handle, name.as_ptr()))
}
})
.unwrap();
Swapchain {
handle: device.handle,
swapchain_fn: swapchain_fn,
}
}
pub fn destroy_swapchain_khr(&self, swapchain: vk::SwapchainKHR) {
unsafe {
self.swapchain_fn.destroy_swapchain_khr(self.handle, swapchain, ptr::null());
}
}
pub fn acquire_next_image_khr(&self,
swapchain: vk::SwapchainKHR,
timeout: vk::uint64_t,
semaphore: vk::Semaphore,
fence: vk::Fence)
-> VkResult<vk::uint32_t> {
unsafe {
let mut index = mem::uninitialized();
let err_code = self.swapchain_fn
.acquire_next_image_khr(self.handle,
swapchain,
timeout,
semaphore,
fence,
&mut index);
match err_code {
vk::Result::Success => Ok(index),
_ => Err(err_code),
}
}
}
pub fn create_swapchain_khr(&self,
create_info: &vk::SwapchainCreateInfoKHR)
-> VkResult<vk::SwapchainKHR> {
unsafe {
let mut swapchain = mem::uninitialized();
let err_code = self.swapchain_fn
.create_swapchain_khr(self.handle, create_info, ptr::null(), &mut swapchain);
match err_code {
vk::Result::Success => Ok(swapchain),
_ => Err(err_code),
}
}
}
pub fn get_swapchain_images_khr(&self,
swapchain: vk::SwapchainKHR)
-> VkResult<Vec<vk::Image>> {
unsafe {
let mut count = 0;
self.swapchain_fn
.get_swapchain_images_khr(self.handle, swapchain, &mut count, ptr::null_mut());
let mut v = Vec::with_capacity(count as vk::size_t);
let err_code = self.swapchain_fn
.get_swapchain_images_khr(self.handle, swapchain, &mut count, v.as_mut_ptr());
v.set_len(count as vk::size_t);
match err_code {
vk::Result::Success => Ok(v),
_ => Err(err_code),
}
}
}
}

View file

@ -0,0 +1,41 @@
use prelude::*;
use std::ptr;
use std::mem;
use instance::Instance;
use entry::Entry;
use vk;
pub struct XlibSurface {
pub handle: vk::Instance,
pub xlib_surface_fn: vk::XlibSurfaceFn,
}
impl XlibSurface {
pub fn new(entry: &Entry, instance: &Instance) -> XlibSurface {
let surface_fn = vk::XlibSurfaceFn::load(|name| {
unsafe {
mem::transmute(entry.static_fn
.get_instance_proc_addr(instance.handle, name.as_ptr()))
}
})
.unwrap();
XlibSurface {
handle: instance.handle,
xlib_surface_fn: surface_fn,
}
}
pub fn create_xlib_surface_khr(&self,
create_info: &vk::XlibSurfaceCreateInfoKHR)
-> VkResult<vk::SurfaceKHR> {
unsafe {
let mut surface = mem::uninitialized();
let err_code = self.xlib_surface_fn
.create_xlib_surface_khr(self.handle, create_info, ptr::null(), &mut surface);
match err_code {
vk::Result::Success => Ok(surface),
_ => Err(err_code),
}
}
}
}

View file

@ -19,147 +19,8 @@ pub struct Instance {
pub instance_fn: vk::InstanceFn, pub instance_fn: vk::InstanceFn,
} }
pub struct XlibSurface {
pub handle: vk::Instance,
pub xlib_surface_fn: vk::XlibSurfaceFn,
}
impl XlibSurface {
pub fn create_xlib_surface_khr(&self,
create_info: &vk::XlibSurfaceCreateInfoKHR)
-> VkResult<vk::SurfaceKHR> {
unsafe {
let mut surface = mem::uninitialized();
let err_code = self.xlib_surface_fn
.create_xlib_surface_khr(self.handle, create_info, ptr::null(), &mut surface);
match err_code {
vk::Result::Success => Ok(surface),
_ => Err(err_code),
}
}
}
}
pub struct Surface {
pub handle: vk::Instance,
pub surface_fn: vk::SurfaceFn,
}
impl Surface {
pub fn get_physical_device_surface_support_khr(&self,
physical_device: vk::PhysicalDevice,
queue_index: vk::uint32_t,
surface: vk::SurfaceKHR)
-> bool {
unsafe {
let mut b = mem::uninitialized();
self.surface_fn
.get_physical_device_surface_support_khr(physical_device,
queue_index,
surface,
&mut b);
b > 0
}
}
pub fn get_physical_device_surface_present_modes_khr(&self,
physical_device: vk::PhysicalDevice,
surface: vk::SurfaceKHR)
-> VkResult<Vec<vk::PresentModeKHR>> {
unsafe {
let mut count = 0;
self.surface_fn.get_physical_device_surface_present_modes_khr(physical_device,
surface,
&mut count,
ptr::null_mut());
let mut v = Vec::with_capacity(count as usize);
let err_code = self.surface_fn
.get_physical_device_surface_present_modes_khr(physical_device,
surface,
&mut count,
v.as_mut_ptr());
v.set_len(count as usize);
match err_code {
vk::Result::Success => Ok(v),
_ => Err(err_code),
}
}
}
pub fn get_physical_device_surface_capabilities_khr(&self,
physical_device: vk::PhysicalDevice,
surface: vk::SurfaceKHR)
-> VkResult<vk::SurfaceCapabilitiesKHR> {
unsafe {
let mut surface_capabilities = mem::uninitialized();
let err_code = self.surface_fn
.get_physical_device_surface_capabilities_khr(physical_device,
surface,
&mut surface_capabilities);
match err_code {
vk::Result::Success => Ok(surface_capabilities),
_ => Err(err_code),
}
}
}
pub fn get_physical_device_surface_formats_khr(&self,
physical_device: vk::PhysicalDevice,
surface: vk::SurfaceKHR)
-> VkResult<Vec<vk::SurfaceFormatKHR>> {
unsafe {
let mut count = 0;
self.surface_fn.get_physical_device_surface_formats_khr(physical_device,
surface,
&mut count,
ptr::null_mut());
let mut v = Vec::with_capacity(count as usize);
let err_code = self.surface_fn
.get_physical_device_surface_formats_khr(physical_device,
surface,
&mut count,
v.as_mut_ptr());
v.set_len(count as usize);
match err_code {
vk::Result::Success => Ok(v),
_ => Err(err_code),
}
}
}
pub fn destroy_surface_khr(&self, surface: vk::SurfaceKHR) {
unsafe {
self.surface_fn.destroy_surface_khr(self.handle, surface, ptr::null());
}
}
}
impl Instance { impl Instance {
pub fn load_xlib_surface(&self, entry: &Entry) -> XlibSurface {
let surface_fn = vk::XlibSurfaceFn::load(|name| {
unsafe {
mem::transmute(entry.static_fn
.get_instance_proc_addr(self.handle, name.as_ptr()))
}
})
.unwrap();
XlibSurface {
handle: self.handle,
xlib_surface_fn: surface_fn,
}
}
pub fn load_surface(&self, entry: &Entry) -> Surface {
let surface_fn = vk::SurfaceFn::load(|name| {
unsafe {
mem::transmute(entry.static_fn
.get_instance_proc_addr(self.handle, name.as_ptr()))
}
})
.unwrap();
Surface {
handle: self.handle,
surface_fn: surface_fn,
}
}
pub unsafe fn from_raw(handle: vk::Instance, instance_fn: vk::InstanceFn) -> Self { pub unsafe fn from_raw(handle: vk::Instance, instance_fn: vk::InstanceFn) -> Self {
Instance { Instance {
handle: handle, handle: handle,
@ -191,29 +52,6 @@ impl Instance {
} }
} }
pub fn destroy_debug_report_callback_ext(&self, debug: vk::DebugReportCallbackEXT) {
unsafe {
self.instance_fn.destroy_debug_report_callback_ext(self.handle, debug, ptr::null());
}
}
pub fn create_debug_report_callback_ext(&self,
create_info: &vk::DebugReportCallbackCreateInfoEXT)
-> VkResult<vk::DebugReportCallbackEXT> {
unsafe {
let mut debug_cb = mem::uninitialized();
let err_code = self.instance_fn
.create_debug_report_callback_ext(self.handle,
create_info,
ptr::null(),
&mut debug_cb);
match err_code {
vk::Result::Success => Ok(debug_cb),
_ => Err(err_code),
}
}
}
pub fn get_physical_device_format_properties(&self, pub fn get_physical_device_format_properties(&self,
physical_device: vk::PhysicalDevice, physical_device: vk::PhysicalDevice,
format: vk::Format) format: vk::Format)

View file

@ -6,3 +6,5 @@ pub mod entry;
pub mod prelude; pub mod prelude;
pub mod vk; pub mod vk;
pub mod allocator; pub mod allocator;
pub mod extensions;

View file

@ -3949,29 +3949,6 @@ vk_functions!{
p_surface: *mut SurfaceKHR, p_surface: *mut SurfaceKHR,
) -> Result; ) -> Result;
"vkCreateDebugReportCallbackEXT", create_debug_report_callback_ext(
instance: Instance,
p_create_info: *const DebugReportCallbackCreateInfoEXT,
p_allocator: *const AllocationCallbacks,
p_callback: *mut DebugReportCallbackEXT,
) -> Result;
"vkDestroyDebugReportCallbackEXT", destroy_debug_report_callback_ext(
instance: Instance,
callback: DebugReportCallbackEXT,
p_allocator: *const AllocationCallbacks,
) -> ();
"vkDebugReportMessageEXT", debug_report_message_ext(
instance: Instance,
flags: DebugReportFlagsEXT,
object_type: DebugReportObjectTypeEXT,
object: uint64_t,
location: size_t,
message_code: int32_t,
p_layer_prefix: *const c_char,
p_message: *const c_char,
) -> ();
} }
vk_functions!{ vk_functions!{
@ -4892,4 +4869,30 @@ vk_functions!{
p_surface: *mut SurfaceKHR, p_surface: *mut SurfaceKHR,
) -> Result; ) -> Result;
} }
vk_functions!{
DebugReportFn,
"vkCreateDebugReportCallbackEXT", create_debug_report_callback_ext(
instance: Instance,
p_create_info: *const DebugReportCallbackCreateInfoEXT,
p_allocator: *const AllocationCallbacks,
p_callback: *mut DebugReportCallbackEXT,
) -> Result;
"vkDestroyDebugReportCallbackEXT", destroy_debug_report_callback_ext(
instance: Instance,
callback: DebugReportCallbackEXT,
p_allocator: *const AllocationCallbacks,
) -> ();
"vkDebugReportMessageEXT", debug_report_message_ext(
instance: Instance,
flags: DebugReportFlagsEXT,
object_type: DebugReportObjectTypeEXT,
object: uint64_t,
location: size_t,
message_code: int32_t,
p_layer_prefix: *const c_char,
p_message: *const c_char,
) -> ();
}
} }