Added experimental windows support

This commit is contained in:
maik klein 2016-12-26 01:58:44 +01:00
parent 79f41b3208
commit d5f3c11ba2
6 changed files with 113 additions and 44 deletions

11
examples/Cargo.lock generated
View file

@ -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"

View file

@ -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"

View file

@ -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<F: FnOnce(&Device, vk::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<F: FnOnce(&Device, vk::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<F: FnOnce(&Device, vk::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<vk::SurfaceKHR, vk::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<vk::SurfaceKHR, vk::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<CString> {
vec![CString::new("VK_KHR_surface").unwrap(),
@ -108,14 +129,14 @@ fn extension_names() -> Vec<CString> {
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];

View file

@ -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;

View file

@ -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<Win32Surface, String> {
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<vk::SurfaceKHR> {
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),
}
}
}
}

View file

@ -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;
}
}