From d5f3c11ba2132373daf10c54a4fd1a037678cfd1 Mon Sep 17 00:00:00 2001 From: maik klein Date: Mon, 26 Dec 2016 01:58:44 +0100 Subject: [PATCH] Added experimental windows support --- examples/Cargo.lock | 11 ++++++ examples/Cargo.toml | 3 ++ examples/src/lib.rs | 61 ++++++++++++++++++++------------- src/extensions/mod.rs | 2 ++ src/extensions/win32_surface.rs | 39 +++++++++++++++++++++ src/vk.rs | 41 +++++++++++----------- 6 files changed, 113 insertions(+), 44 deletions(-) create mode 100644 src/extensions/win32_surface.rs diff --git a/examples/Cargo.lock b/examples/Cargo.lock index 87e37a7..9994983 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -5,6 +5,7 @@ dependencies = [ "ash 0.2.0", "glfw 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", + "user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "winit 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -580,6 +581,15 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "user32-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "wayland-client" version = "0.7.6" @@ -755,6 +765,7 @@ dependencies = [ "checksum target_build_utils 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "54c550e226618cd35334b75e92bfa5437c61474bdb75c38bf330ab5a8037b77c" "checksum tempfile 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9270837a93bad1b1dac18fe67e786b3c960513af86231f6f4f57fddd594ff0c8" "checksum user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6717129de5ac253f5642fc78a51d0c7de6f9f53d617fc94e9bae7f6e71cf5504" +"checksum user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ef4711d107b21b410a3a974b1204d9accc8b10dad75d8324b5d755de1617d47" "checksum wayland-client 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8c3e3edc131b755a1c6ab9873ce27557f5c5f075959597cd201bc00019555c9e" "checksum wayland-kbd 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7707deadab966d6ea58651f4150add1fc442058a9598c3da11f0ce27c99f440f" "checksum wayland-scanner 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c7459efa4b7bab8f34657ce6167ff470871cc7932d75cfc8db7e2ef99f81397b" diff --git a/examples/Cargo.toml b/examples/Cargo.toml index c6cc326..6139c48 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -8,3 +8,6 @@ glfw = "0.9.1" winit = "0.5.6" image = "0.10.4" ash = { version = "*", path = "../"} + +[target.'cfg(windows)'.dependencies] +user32-sys = "0.2.0" diff --git a/examples/src/lib.rs b/examples/src/lib.rs index e0704f9..bb7dbc2 100644 --- a/examples/src/lib.rs +++ b/examples/src/lib.rs @@ -2,6 +2,8 @@ #[macro_use] extern crate ash; extern crate winit; +#[cfg(windows)] +extern crate user32; use ash::vk; use std::default::Default; @@ -11,11 +13,6 @@ use ash::extensions::{Swapchain, XlibSurface, Surface, DebugReport}; use ash::device::Device; use std::ptr; use std::ffi::{CStr, CString}; -use std::mem; -use std::path::Path; -use std::fs::File; -use std::io::Read; -use winit::os::unix::WindowExt; use std::ops::Drop; // Simple offset_of macro akin to C++ offsetof @@ -41,7 +38,8 @@ pub fn record_submit_commandbuffer(device f: F) { unsafe { device.reset_command_buffer(command_buffer, - vk::COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT); + vk::COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT) + .expect("Reset command buffer failed."); let command_buffer_begin_info = vk::CommandBufferBeginInfo { s_type: vk::StructureType::CommandBufferBeginInfo, p_next: ptr::null(), @@ -57,7 +55,7 @@ pub fn record_submit_commandbuffer(device p_next: ptr::null(), flags: vk::FenceCreateFlags::empty(), }; - let submit_fence = device.create_fence(&fence_create_info).unwrap(); + let submit_fence = device.create_fence(&fence_create_info).expect("Create fence failed."); let submit_info = vk::SubmitInfo { s_type: vk::StructureType::SubmitInfo, p_next: ptr::null(), @@ -69,8 +67,10 @@ pub fn record_submit_commandbuffer(device signal_semaphore_count: signal_semaphores.len() as u32, p_signal_semaphores: signal_semaphores.as_ptr(), }; - device.queue_submit(submit_queue, &[submit_info], submit_fence); - device.wait_for_fences(&[submit_fence], true, std::u64::MAX); + device.queue_submit(submit_queue, &[submit_info], submit_fence) + .expect("queue submit failed."); + device.wait_for_fences(&[submit_fence], true, std::u64::MAX) + .expect("Wait for fence failed."); device.destroy_fence(submit_fence); } } @@ -80,6 +80,7 @@ fn create_surface(instance: &Instance, entry: &Entry, window: &winit::Window) -> Result { + use winit::os::unix::WindowExt; let x11_display = window.get_xlib_display().unwrap(); let x11_window = window.get_xlib_window().unwrap(); let x11_create_info = vk::XlibSurfaceCreateInfoKHR { @@ -94,6 +95,26 @@ fn create_surface(instance: &Instance, xlib_surface_loader.create_xlib_surface_khr(&x11_create_info) } +#[cfg(windows)] +fn create_surface(instance: &Instance, + entry: &Entry, + window: &winit::Window) + -> Result { + use winit::os::windows::WindowExt; + let hwnd = window.get_hwnd(); + let hinstance = user32::GetWindow(hwnd, 0); + let win32_create_info = vk::Win32SurfaceCreateInfoKHR { + s_type: vk::StructureType::Win32SurfaceCreateInfoKhr, + p_next: ptr::null(), + flags: Default::default(), + hinstance: hinstance, + hwnd: hwnd, + }; + let win32_surface_loader = Win32Surface::new(&entry, &instance) + .expect("Unable to load win32 surface"); + win32_surface_loader.create_win32_surface_khr(&win32create_info) +} + #[cfg(all(unix, not(target_os = "android")))] fn extension_names() -> Vec { vec![CString::new("VK_KHR_surface").unwrap(), @@ -108,14 +129,14 @@ fn extension_names() -> Vec { CString::new("VK_EXT_debug_report").unwrap()] } -unsafe extern "system" fn vulkan_debug_callback(flags: vk::DebugReportFlagsEXT, - obj_type: vk::DebugReportObjectTypeEXT, - obj: u64, - loc: usize, - message: i32, - p_layer_prefix: *const i8, +unsafe extern "system" fn vulkan_debug_callback(_: vk::DebugReportFlagsEXT, + _: vk::DebugReportObjectTypeEXT, + _: u64, + _: usize, + _: i32, + _: *const i8, p_message: *const i8, - data: *mut ()) + _: *mut ()) -> u32 { println!("{:?}", CStr::from_ptr(p_message)); 1 @@ -195,7 +216,6 @@ impl ExampleBase { .build() .unwrap(); let entry = Entry::load_vulkan().unwrap(); - let instance_ext_props = entry.enumerate_instance_extension_properties().unwrap(); let app_name = CString::new("VulkanTriangle").unwrap(); let raw_name = app_name.as_ptr(); @@ -381,13 +401,6 @@ impl ExampleBase { command_pool: pool, level: vk::CommandBufferLevel::Primary, }; - let command_buffer_allocate_info = vk::CommandBufferAllocateInfo { - s_type: vk::StructureType::CommandBufferAllocateInfo, - p_next: ptr::null(), - command_buffer_count: 2, - command_pool: pool, - level: vk::CommandBufferLevel::Primary, - }; let command_buffers = device.allocate_command_buffers(&command_buffer_allocate_info) .unwrap(); let setup_command_buffer = command_buffers[0]; diff --git a/src/extensions/mod.rs b/src/extensions/mod.rs index 87efb79..ec0c13e 100644 --- a/src/extensions/mod.rs +++ b/src/extensions/mod.rs @@ -2,8 +2,10 @@ pub use self::swapchain::Swapchain; pub use self::surface::Surface; pub use self::xlibsurface::XlibSurface; pub use self::debug_report::DebugReport; +pub use self::win32_surface::Win32Surface; mod swapchain; mod surface; mod xlibsurface; mod debug_report; +mod win32_surface; diff --git a/src/extensions/win32_surface.rs b/src/extensions/win32_surface.rs new file mode 100644 index 0000000..376987c --- /dev/null +++ b/src/extensions/win32_surface.rs @@ -0,0 +1,39 @@ +use prelude::*; +use std::ptr; +use std::mem; +use instance::Instance; +use entry::Entry; +use vk; + +pub struct Win32Surface { + pub handle: vk::Instance, + pub win32_surface_fn: vk::Win32SurfaceFn, +} + +impl Win32Surface { + pub fn new(entry: &Entry, instance: &Instance) -> Result { + let surface_fn = vk::Win32SurfaceFn::load(|name| { + unsafe { + mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr())) + } + })?; + Ok(Win32Surface { + handle: instance.handle(), + win32_surface_fn: surface_fn, + }) + } + + pub fn create_win32_surface_khr(&self, + create_info: &vk::Win32SurfaceCreateInfoKHR) + -> VkResult { + unsafe { + let mut surface = mem::uninitialized(); + let err_code = self.win32_surface_fn + .create_win32_surface_khr(self.handle, create_info, ptr::null(), &mut surface); + match err_code { + vk::Result::Success => Ok(surface), + _ => Err(err_code), + } + } + } +} diff --git a/src/vk.rs b/src/vk.rs index a825dcc..d0d6bcd 100644 --- a/src/vk.rs +++ b/src/vk.rs @@ -3831,14 +3831,6 @@ vk_functions!{ p_properties: *mut SparseImageFormatProperties, ) -> (); - - "vkGetPhysicalDeviceXlibPresentationSupportKHR", get_physical_device_xlib_presentation_support_khr( - physical_device: PhysicalDevice, - queue_family_index: uint32_t, - dpy: *mut Display, - visual_id: VisualID, - ) -> Bool32; - "vkCreateXcbSurfaceKHR", create_xcb_surface_khr( instance: Instance, p_create_info: *const XcbSurfaceCreateInfoKHR, @@ -3866,18 +3858,6 @@ vk_functions!{ connection: *mut MirConnection, ) -> Bool32; - "vkCreateWin32SurfaceKHR", create_win32_surface_khr( - instance: Instance, - p_create_info: *const Win32SurfaceCreateInfoKHR, - p_allocator: *const AllocationCallbacks, - p_surface: *mut SurfaceKHR, - ) -> Result; - - "vkGetPhysicalDeviceWin32PresentationSupportKHR", get_physical_device_win32_presentation_support_khr( - physical_device: PhysicalDevice, - queue_family_index: uint32_t, - ) -> Bool32; - "vkCreateAndroidSurfaceKHR", create_android_surface_khr( instance: Instance, p_create_info: *const AndroidSurfaceCreateInfoKHR, @@ -4868,6 +4848,13 @@ vk_functions!{ p_allocator: *const AllocationCallbacks, p_surface: *mut SurfaceKHR, ) -> Result; + + "vkGetPhysicalDeviceXlibPresentationSupportKHR", get_physical_device_xlib_presentation_support_khr( + physical_device: PhysicalDevice, + queue_family_index: uint32_t, + dpy: *mut Display, + visual_id: VisualID, + ) -> Bool32; } vk_functions!{ DebugReportFn, @@ -4895,4 +4882,18 @@ vk_functions!{ p_message: *const c_char, ) -> (); } +vk_functions!{ + Win32SurfaceFn, + "vkCreateWin32SurfaceKHR", create_win32_surface_khr( + instance: Instance, + p_create_info: *const Win32SurfaceCreateInfoKHR, + p_allocator: *const AllocationCallbacks, + p_surface: *mut SurfaceKHR, + ) -> Result; + + "vkGetPhysicalDeviceWin32PresentationSupportKHR", get_physical_device_win32_presentation_support_khr( + physical_device: PhysicalDevice, + queue_family_index: uint32_t, + ) -> Bool32; +} }