From 6717668b5b17481c66db17a624659a5a0a8c390a Mon Sep 17 00:00:00 2001 From: maik klein Date: Sun, 4 Dec 2016 22:51:34 +0100 Subject: [PATCH] further triangle progress --- ash/src/instance.rs | 399 ++++++++++++++++++------------------------ examples/src/main.rs | 136 +++++++++++++- vk_loader2/src/lib.rs | 56 +++--- 3 files changed, 329 insertions(+), 262 deletions(-) diff --git a/ash/src/instance.rs b/ash/src/instance.rs index fdbb965..3cdb036 100644 --- a/ash/src/instance.rs +++ b/ash/src/instance.rs @@ -14,31 +14,6 @@ use vk_loader2 as vk; use load; use shared_library::dynamic_library::DynamicLibrary; type VkResult = Result; -// use fence; -// use extensions::*; -// use surface; -// use device::*; - -// macro_rules! vk_error( -// ($err_name: ident, $($raw_name: ident => $name: ident,)*) => { -// #[derive(Debug)] -// pub enum $err_name { -// $( -// $name, -// )* -// } -// impl From for $err_name { -// fn from(r: vk::Result) -> $err_name { -// match r { -// $( -// vk::Result::$raw_name => $err_name::$name, -// )* -// _ => panic!("Missing error case for '{}', please open an issue.", stringify!($err_name)), -// } -// } -// } -// } -// ); #[cfg(windows)] fn get_path() -> &'static Path { @@ -171,6 +146,111 @@ impl Device { self.device_fn.destroy_device(self.handle, ptr::null()); } } + + pub fn destroy_command_pool(&self, pool: vk::CommandPool) { + unsafe { + self.device_fn.destroy_command_pool(self.handle, pool, ptr::null()); + } + } + + pub fn destroy_swapchain_khr(&self, swapchain: vk::SwapchainKHR) { + unsafe { + self.device_fn.destroy_swapchain_khr(self.handle, swapchain, ptr::null()); + } + } + + pub fn destroy_image_view(&self, image_view: vk::ImageView) { + unsafe { + self.device_fn.destroy_image_view(self.handle, image_view, ptr::null()); + } + } + + pub fn get_device_queue(&self, queue_family_index: u32, queue_index: u32) -> vk::Queue { + unsafe { + let mut queue = mem::uninitialized(); + self.device_fn + .get_device_queue(self.handle, queue_family_index, queue_index, &mut queue); + queue + } + } + + pub fn create_image_view(&self, + create_info: &vk::ImageViewCreateInfo) + -> VkResult { + unsafe { + let mut image_view = mem::uninitialized(); + let err_code = self.device_fn + .create_image_view(self.handle, create_info, ptr::null(), &mut image_view); + match err_code { + vk::Result::Success => Ok(image_view), + _ => Err(err_code), + } + } + } + pub fn get_swapchain_images_khr(&self, + swapchain: vk::SwapchainKHR) + -> VkResult> { + unsafe { + let mut count = 0; + self.device_fn + .get_swapchain_images_khr(self.handle, swapchain, &mut count, ptr::null_mut()); + + let mut v = Vec::with_capacity(count as usize); + let err_code = self.device_fn + .get_swapchain_images_khr(self.handle, swapchain, &mut count, v.as_mut_ptr()); + v.set_len(count as usize); + match err_code { + vk::Result::Success => Ok(v), + _ => Err(err_code), + } + } + } + + pub fn allocate_command_buffers> + (&self, + i: I) + -> VkResult> { + let create_info = i.into(); + unsafe { + let mut buffers = Vec::with_capacity(create_info.command_buffer_count as usize); + let err_code = self.device_fn + .allocate_command_buffers(self.handle, &create_info, buffers.as_mut_ptr()); + buffers.set_len(create_info.command_buffer_count as usize); + match err_code { + vk::Result::Success => Ok(buffers), + _ => Err(err_code), + } + } + } + pub fn create_command_pool>(&self, + i: I) + -> VkResult { + let create_info = i.into(); + unsafe { + let mut pool = mem::uninitialized(); + let err_code = self.device_fn + .create_command_pool(self.handle, &create_info, ptr::null(), &mut pool); + match err_code { + vk::Result::Success => Ok(pool), + _ => Err(err_code), + } + } + } + pub fn create_swapchain_khr> + (&self, + i: I) + -> VkResult { + let create_info = i.into(); + unsafe { + let mut swapchain = mem::uninitialized(); + let err_code = self.device_fn + .create_swapchain_khr(self.handle, &create_info, ptr::null(), &mut swapchain); + match err_code { + vk::Result::Success => Ok(swapchain), + _ => Err(err_code), + } + } + } } impl<'r> Instance<'r> { @@ -180,6 +260,70 @@ impl<'r> Instance<'r> { } } + pub fn get_physical_device_surface_present_modes_khr(&self, + physical_device: vk::PhysicalDevice, + surface: vk::SurfaceKHR) + -> VkResult> { + unsafe { + let mut count = 0; + self.instance_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.instance_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 { + unsafe { + let mut surface_capabilities = mem::uninitialized(); + let err_code = self.instance_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> { + unsafe { + let mut count = 0; + self.instance_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.instance_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.instance_fn.destroy_surface_khr(self.handle, surface, ptr::null()); @@ -300,208 +444,3 @@ impl<'r> Instance<'r> { } } } -// pub struct DebugCallback { -// handle: vk::DebugReportCallbackEXT, -// f: *mut Fn(String), -// } -// -// #[derive(Clone)] -// pub struct Instance { -// pub inner: Arc, -// } -// -// pub struct InstanceImpl { -// pub instance: vk::Instance, -// pub ip: vk::InstancePointers, -// callback: Option, -// } -// -// impl Instance{ -// pub fn handle(&self) -> usize{ -// self.inner.instance -// } -// -// pub fn ip(&self) -> &vk::InstancePointers { -// &self.inner.ip -// } -// } -// -// unsafe impl Send for Instance {} -// unsafe impl Sync for Instance {} -// -// impl Drop for InstanceImpl { -// fn drop(&mut self) { -// unsafe { -// if let Some(ref callback) = self.callback { -// self.ip.DestroyDebugReportCallbackEXT(self.instance, callback.handle, ptr::null()); -// Box::from_raw(callback.f); -// } -// self.ip.DestroyInstance(self.instance, ptr::null()); -// } -// } -// } -// -// pub struct ApplicationInfo { -// pub name: String, -// } -// -// impl Instance { -// pub fn create_surface(&self, s: &S) -> surface::Surface { -// surface::Surface { -// instance: self.clone(), -// handle: s.create_surface(self), -// } -// } -// -// pub fn extenstion_properties() -> InstanceExtension { -// let entry_points = load::entry_points().unwrap(); -// let extension_props = unsafe { -// let mut num = 0; -// entry_points.EnumerateInstanceExtensionProperties(ptr::null(), &mut num, ptr::null_mut()); -// let mut data = Vec::with_capacity(num as usize); -// entry_points.EnumerateInstanceExtensionProperties(ptr::null(), &mut num, data.as_mut_ptr()); -// data.set_len(num as usize); -// InstanceExtensionProperties { ext_props: data } -// }; -// extension_props.into() -// } -// pub fn device_extension_properties(&self, device: vk::PhysicalDevice) -> DeviceExtension { -// let extension_props = unsafe { -// let mut num = 0; -// self.inner.ip -// .EnumerateDeviceExtensionProperties(device, ptr::null(), &mut num, ptr::null_mut()); -// let mut data = Vec::with_capacity(num as usize); -// self.inner.ip.EnumerateDeviceExtensionProperties(device, -// ptr::null(), -// &mut num, -// data.as_mut_ptr()); -// data.set_len(num as usize); -// DeviceExtensionProperties { ext_props: data } -// }; -// extension_props.into() -// } -// -// pub fn new(app_info: &ApplicationInfo, -// extensions: &InstanceExtension, -// f: F) -// -> Instance { -// let entry_points = load::entry_points().unwrap(); -// -// unsafe { -// let mut num = 0; -// entry_points.EnumerateInstanceLayerProperties(&mut num, ptr::null_mut()); -// -// let mut v = Vec::with_capacity(num as usize); -// entry_points.EnumerateInstanceLayerProperties(&mut num, v.as_mut_ptr()); -// v.set_len(num as usize); -// -// for p in v { -// // println!("layer {}", CStr::from_ptr(p.layerName.as_ptr()).to_str().unwrap()); -// } -// } -// let layername = CString::new("VK_LAYER_LUNARG_standard_validation").unwrap(); -// let layer = [layername.as_ptr()]; -// -// let c = CString::new(app_info.name.clone()).unwrap(); -// let raw_name = c.as_ptr(); -// let appinfo = vk::ApplicationInfo { -// pApplicationName: raw_name, -// sType: vk::STRUCTURE_TYPE_APPLICATION_INFO, -// pNext: ptr::null(), -// applicationVersion: 0, -// pEngineName: raw_name, -// engineVersion: 0, -// apiVersion: 0, -// }; -// -// let extension_list = extensions.extension_list(); -// let extension_list_raw = -// extension_list.iter().map(|extension| extension.as_ptr()).collect::>(); -// let create_info = vk::InstanceCreateInfo { -// sType: vk::STRUCTURE_TYPE_INSTANCE_CREATE_INFO, -// pApplicationInfo: &appinfo, -// pNext: ptr::null(), -// ppEnabledLayerNames: layer.as_ptr(), -// enabledLayerCount: layer.len() as u32, -// ppEnabledExtensionNames: extension_list_raw.as_ptr(), -// enabledExtensionCount: extension_list_raw.len() as u32, -// flags: 0, -// }; -// -// let mut instance: vk::Instance = unsafe { mem::uninitialized() }; -// unsafe { -// entry_points.CreateInstance(&create_info, ptr::null(), &mut instance); -// } -// let vk: vk::InstancePointers = { -// let f = load::static_functions().unwrap(); -// vk::InstancePointers::load(|name| unsafe { -// mem::transmute(f.GetInstanceProcAddr(instance, name.as_ptr())) -// }) -// }; -// extern "system" fn debug_callback(flags: vk::DebugReportFlagsEXT, -// obj: vk::DebugReportObjectTypeEXT, -// u: u64, -// u1: usize, -// i: i32, -// chars: *const c_char, -// chars1: *const c_char, -// data: *mut c_void) -// -> u32 { -// unsafe { -// let f = &*(data as *mut F); -// f(CStr::from_ptr(chars).to_str().unwrap().to_owned()); -// f(CStr::from_ptr(chars1).to_str().unwrap().to_owned()); -// } -// 1 -// } -// let raw_boxed_f = Box::into_raw(Box::new(f)); -// let debug = vk::DebugReportCallbackCreateInfoEXT { -// sType: 1000011000, -// pNext: ptr::null(), -// flags: vk::DEBUG_REPORT_ERROR_BIT_EXT | vk::DEBUG_REPORT_WARNING_BIT_EXT, -// pfnCallback: debug_callback::, -// pUserData: raw_boxed_f as *mut c_void, -// }; -// let callback = unsafe { -// let mut callback: vk::DebugReportCallbackEXT = mem::uninitialized(); -// -// assert!(vk.CreateDebugReportCallbackEXT(instance, -// &debug, -// ptr::null(), -// &mut callback) == 0, -// "Debug"); -// -// DebugCallback { -// f: raw_boxed_f, -// handle: callback, -// } -// }; -// Instance { -// inner: Arc::new(InstanceImpl { -// ip: vk, -// instance: instance, -// callback: Some(callback), -// }), -// } -// } -// -// pub fn get_pysical_devices(&self) -> Vec { -// unsafe { -// let mut num = 0; -// self.inner.ip -// .EnumeratePhysicalDevices(self.inner.instance, &mut num, ptr::null_mut()); -// let mut physical_devices = Vec::::with_capacity(num as usize); -// self.inner.ip -// .EnumeratePhysicalDevices(self.inner.instance, &mut num, physical_devices.as_mut_ptr()); -// physical_devices.set_len(num as usize); -// physical_devices.into_iter() -// .map(|handle| { -// PhysicalDevice { -// instance: self.clone(), -// handle: handle, -// } -// }) -// .collect() -// } -// } -// } diff --git a/examples/src/main.rs b/examples/src/main.rs index 559ed56..621b079 100644 --- a/examples/src/main.rs +++ b/examples/src/main.rs @@ -12,18 +12,26 @@ use std::ffi::{CStr, CString}; use std::mem; use std::path::Path; use std::os::raw::c_void; - +macro_rules! printlndb{ + ($arg: tt) => { + println!("{:?}", $arg); + } +} fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) { match event { glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => window.set_should_close(true), _ => {} } } + fn main() { let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap(); - let (mut window, events) = glfw.create_window(1920, - 1080, + let window_width = 1920; + let window_height = 1080; + + let (mut window, events) = glfw.create_window(window_width, + window_height, "Hello this is window", glfw::WindowMode::Windowed) .expect("Failed to create GLFW window."); @@ -32,7 +40,6 @@ fn main() { window.make_current(); let entry = Entry::load_vulkan().unwrap(); let instance_ext_props = entry.enumerate_instance_extension_properties().unwrap(); - // println!("{:?}", instance_ext_props); let app_name = CString::new("TEST").unwrap(); let raw_name = app_name.as_ptr(); @@ -97,6 +104,7 @@ fn main() { .filter_map(|v| v) .nth(0) .expect("Couldn't find suitable device."); + let queue_family_index = queue_family_index as u32; let device_extension_names = [CString::new("VK_KHR_swapchain").unwrap()]; let device_extension_names_raw: Vec<*const i8> = device_extension_names.iter() .map(|raw_name| raw_name.as_ptr()) @@ -124,8 +132,128 @@ fn main() { p_enabled_features: &features, }; let device = instance.create_device(pdevice, device_create_info).unwrap(); + let present_queue = device.get_device_queue(queue_family_index as u32, 0); + let surface_formats = instance.get_physical_device_surface_formats_khr(pdevice, surface) + .unwrap(); + let surface_format = surface_formats.iter() + .map(|sfmt| { + match sfmt.format { + vk::Format::Undefined => { + vk::SurfaceFormatKHR { + format: vk::Format::B8g8r8Unorm, + color_space: sfmt.color_space, + } + } + _ => sfmt.clone(), + } + }) + .nth(0) + .expect("Unable to find suitable surface format."); + let surface_capabilities = + instance.get_physical_device_surface_capabilities_khr(pdevice, surface).unwrap(); + let desired_image_count = 2; + assert!(surface_capabilities.min_image_count <= desired_image_count && + surface_capabilities.max_image_count >= desired_image_count, + "Image count err"); + let surface_resoultion = match surface_capabilities.current_extent.width { + std::u32::MAX => { + vk::Extent2D { + width: window_width, + height: window_height, + } + } + _ => surface_capabilities.current_extent, + }; + let pre_transform = if surface_capabilities.supported_transforms + .subset(vk::SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { + vk::SURFACE_TRANSFORM_IDENTITY_BIT_KHR + } else { + surface_capabilities.current_transform + }; + let present_modes = instance.get_physical_device_surface_present_modes_khr(pdevice, surface) + .unwrap(); + let present_mode = present_modes.iter() + .cloned() + .find(|&mode| mode == vk::PresentModeKHR::Mailbox) + .unwrap_or(vk::PresentModeKHR::Fifo); + let swapchain_create_info = vk::SwapchainCreateInfoKHR { + s_type: vk::StructureType::SwapchainCreateInfoKhr, + p_next: ptr::null(), + flags: 0, + surface: surface, + min_image_count: desired_image_count, + image_color_space: surface_format.color_space, + image_format: surface_format.format, + image_extent: surface_resoultion, + image_usage: vk::IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + image_sharing_mode: vk::SharingMode::Exclusive, + pre_transform: pre_transform, + composite_alpha: vk::COMPOSITE_ALPHA_OPAQUE_BIT_KHR, + present_mode: present_mode, + clipped: 1, + old_swapchain: unsafe { mem::transmute(0u64) }, + // FIX ME: What is this? + image_array_layers: 1, + p_queue_family_indices: ptr::null(), + queue_family_index_count: 0, + }; + let swapchain = device.create_swapchain_khr(swapchain_create_info).unwrap(); + let pool_create_info = vk::CommandPoolCreateInfo { + s_type: vk::StructureType::CommandPoolCreateInfo, + p_next: ptr::null(), + flags: vk::COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, + queue_family_index: queue_family_index, + }; + let pool = device.create_command_pool(pool_create_info).unwrap(); + + 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]; + let draw_command_buffer = command_buffers[1]; + + let present_images = device.get_swapchain_images_khr(swapchain).unwrap(); + printlndb!(present_images); + let present_image_views: Vec = present_images.iter() + .map(|&image| { + let create_view_info = vk::ImageViewCreateInfo { + s_type: vk::StructureType::ImageViewCreateInfo, + p_next: ptr::null(), + flags: 0, + view_type: vk::ImageViewType::Type2d, + format: surface_format.format, + components: vk::ComponentMapping { + r: vk::ComponentSwizzle::R, + g: vk::ComponentSwizzle::G, + b: vk::ComponentSwizzle::B, + a: vk::ComponentSwizzle::A, + }, + subresource_range: vk::ImageSubresourceRange { + aspect_mask: vk::IMAGE_ASPECT_COLOR_BIT, + base_mip_level: 0, + level_count: 1, + base_array_layer: 0, + layer_count: 1, + }, + image: image, + }; + device.create_image_view(&create_view_info).unwrap() + }) + .collect(); + + for image_view in present_image_views { + device.destroy_image_view(image_view); + } + device.destroy_command_pool(pool); + device.destroy_swapchain_khr(swapchain); device.destroy_device(); instance.destroy_surface_khr(surface); instance.destroy_instance(); diff --git a/vk_loader2/src/lib.rs b/vk_loader2/src/lib.rs index f3506cc..542e80e 100644 --- a/vk_loader2/src/lib.rs +++ b/vk_loader2/src/lib.rs @@ -3732,34 +3732,6 @@ vk_functions!{ display: *mut wl_display, ) -> Bool32; - "vkCreateSwapchainKHR", create_swapchain_khr( - device: Device, - p_create_info: *const SwapchainCreateInfoKHR, - p_allocator: *const AllocationCallbacks, - p_swapchain: *mut SwapchainKHR, - ) -> Result; - - "vkDestroySwapchainKHR", destroy_swapchain_khr( - device: Device, - swapchain: SwapchainKHR, - p_allocator: *const AllocationCallbacks, - ) -> (); - - "vkGetSwapchainImagesKHR", get_swapchain_images_khr( - device: Device, - swapchain: SwapchainKHR, - p_swapchain_image_count: *mut uint32_t, - p_swapchain_images: *mut Image, - ) -> Result; - - "vkAcquireNextImageKHR", acquire_next_image_khr( - device: Device, - swapchain: SwapchainKHR, - timeout: uint64_t, - semaphore: Semaphore, - fence: Fence, - p_image_index: *mut uint32_t, - ) -> Result; "vkQueuePresentKHR", queue_present_khr( queue: Queue, @@ -4676,4 +4648,32 @@ vk_functions!{ command_buffer_count: uint32_t, p_command_buffers: *const CommandBuffer, ) -> (); + "vkCreateSwapchainKHR", create_swapchain_khr( + device: Device, + p_create_info: *const SwapchainCreateInfoKHR, + p_allocator: *const AllocationCallbacks, + p_swapchain: *mut SwapchainKHR, + ) -> Result; + + "vkDestroySwapchainKHR", destroy_swapchain_khr( + device: Device, + swapchain: SwapchainKHR, + p_allocator: *const AllocationCallbacks, + ) -> (); + + "vkGetSwapchainImagesKHR", get_swapchain_images_khr( + device: Device, + swapchain: SwapchainKHR, + p_swapchain_image_count: *mut uint32_t, + p_swapchain_images: *mut Image, + ) -> Result; + + "vkAcquireNextImageKHR", acquire_next_image_khr( + device: Device, + swapchain: SwapchainKHR, + timeout: uint64_t, + semaphore: Semaphore, + fence: Fence, + p_image_index: *mut uint32_t, + ) -> Result; }}