From b919665a9b5f0b85def8aeeb4ed3ea3b6c7cf43c Mon Sep 17 00:00:00 2001 From: msiglreith Date: Fri, 8 Dec 2017 19:18:18 +0100 Subject: [PATCH] ICD implementation groundwork --- libportability-gfx/Cargo.toml | 3 + libportability-gfx/src/impls.rs | 166 ++++++++++++++++++---- libportability-gfx/src/lib.rs | 81 +---------- libportability-icd/portability_debug.json | 7 + libportability-icd/src/lib.rs | 55 +++++++ 5 files changed, 208 insertions(+), 104 deletions(-) create mode 100644 libportability-icd/portability_debug.json diff --git a/libportability-gfx/Cargo.toml b/libportability-gfx/Cargo.toml index b34486e..c9f0ed5 100644 --- a/libportability-gfx/Cargo.toml +++ b/libportability-gfx/Cargo.toml @@ -6,6 +6,9 @@ authors = ["Dzmitry Malyshau "] [lib] name = "portability_gfx" +[dependencies] +lazy_static = "1.0" + [dependencies.gfx-hal] #path = "../gfx/src/hal" git = "https://github.com/kvark/gfx-rs" diff --git a/libportability-gfx/src/impls.rs b/libportability-gfx/src/impls.rs index 8a3ed03..380bf86 100644 --- a/libportability-gfx/src/impls.rs +++ b/libportability-gfx/src/impls.rs @@ -1,7 +1,8 @@ use super::*; +use std::mem; -pub fn gfxCreateInstance( +pub extern fn gfxCreateInstance( _pCreateInfo: *const VkInstanceCreateInfo, _pAllocator: *const VkAllocationCallbacks, pInstance: *mut VkInstance, @@ -11,7 +12,7 @@ pub fn gfxCreateInstance( VkResult::VK_SUCCESS } -pub fn gfxDestroyInstance( +pub extern fn gfxDestroyInstance( instance: VkInstance, _pAllocator: *const VkAllocationCallbacks, ) { @@ -19,7 +20,7 @@ pub fn gfxDestroyInstance( //let it drop } -pub fn gfxEnumeratePhysicalDevices( +pub extern fn gfxEnumeratePhysicalDevices( instance: VkInstance, pPhysicalDeviceCount: *mut u32, pPhysicalDevices: *mut VkPhysicalDevice, @@ -36,7 +37,7 @@ pub fn gfxEnumeratePhysicalDevices( VkResult::VK_SUCCESS } -pub fn gfxGetPhysicalDeviceQueueFamilyProperties( +pub extern fn gfxGetPhysicalDeviceQueueFamilyProperties( adapter: VkPhysicalDevice, pQueueFamilyPropertyCount: *mut u32, pQueueFamilyProperties: *mut VkQueueFamilyProperties, @@ -110,7 +111,7 @@ extern "C" { -> PFN_vkVoidFunction; } -pub fn gfxCreateDevice( +pub extern fn gfxCreateDevice( adapter: VkPhysicalDevice, pCreateInfo: *const VkDeviceCreateInfo, _pAllocator: *const VkAllocationCallbacks, @@ -133,21 +134,59 @@ pub fn gfxCreateDevice( VkResult::VK_SUCCESS } -pub fn gfxDestroyDevice( +pub extern fn gfxDestroyDevice( device: VkDevice, _pAllocator: *const VkAllocationCallbacks, ) { let _ = device.unwrap(); //TODO? } -extern "C" { - pub fn vkEnumerateInstanceExtensionProperties(pLayerName: - *const ::std::os::raw::c_char, - pPropertyCount: *mut u32, - pProperties: - *mut VkExtensionProperties) - -> VkResult; +lazy_static! { + static ref INSTANCE_EXTENSIONS: [VkExtensionProperties; 1] = { + let mut extensions = [ + VkExtensionProperties { + extensionName: [0; 256], // VK_KHR_SURFACE_EXTENSION_NAME + specVersion: VK_KHR_SURFACE_SPEC_VERSION, + } + ]; + + extensions[0] + .extensionName[..VK_KHR_SURFACE_EXTENSION_NAME.len()] + .copy_from_slice(unsafe { + mem::transmute(VK_KHR_SURFACE_EXTENSION_NAME as &[u8]) + }); + + extensions + }; } + +pub extern fn gfxEnumerateInstanceExtensionProperties( + pLayerName: *const ::std::os::raw::c_char, + pPropertyCount: *mut u32, + pProperties: *mut VkExtensionProperties, +) -> VkResult { + let property_count = unsafe { &mut *pPropertyCount }; + let num_extensions = INSTANCE_EXTENSIONS.len() as u32; + + if pProperties.is_null() { + *property_count = num_extensions; + } else { + if *property_count > num_extensions { + *property_count = num_extensions; + } + let properties = unsafe { slice::from_raw_parts_mut(pProperties, *property_count as usize) }; + for i in 0..*property_count as usize { + properties[i] = INSTANCE_EXTENSIONS[i]; + } + + if *property_count < num_extensions { + return VkResult::VK_INCOMPLETE; + } + } + + VkResult::VK_SUCCESS +} + extern "C" { pub fn vkEnumerateDeviceExtensionProperties(physicalDevice: VkPhysicalDevice, @@ -378,7 +417,7 @@ extern "C" { *const VkImageSubresource, pLayout: *mut VkSubresourceLayout); } -pub fn gfxCreateImageView( +pub extern fn gfxCreateImageView( gpu: VkDevice, pCreateInfo: *const VkImageViewCreateInfo, pAllocator: *const VkAllocationCallbacks, @@ -407,7 +446,7 @@ pub fn gfxCreateImageView( }, } } -pub fn gfxDestroyImageView( +pub extern fn gfxDestroyImageView( gpu: VkDevice, imageView: VkImageView, pAllocator: *const VkAllocationCallbacks, @@ -580,7 +619,7 @@ extern "C" { pGranularity: *mut VkExtent2D); } -pub fn gfxCreateCommandPool( +pub extern fn gfxCreateCommandPool( gpu: VkDevice, pCreateInfo: *const VkCommandPoolCreateInfo, _pAllocator: *const VkAllocationCallbacks, @@ -605,7 +644,7 @@ pub fn gfxCreateCommandPool( VkResult::VK_SUCCESS } -pub fn gfxDestroyCommandPool( +pub extern fn gfxDestroyCommandPool( gpu: VkDevice, commandPool: VkCommandPool, _pAllocator: *const VkAllocationCallbacks, @@ -613,7 +652,7 @@ pub fn gfxDestroyCommandPool( gpu.device.destroy_command_pool(*commandPool.unwrap()); } -pub fn gfxResetCommandPool( +pub extern fn gfxResetCommandPool( _gpu: VkDevice, mut commandPool: VkCommandPool, _flags: VkCommandPoolResetFlags, @@ -622,7 +661,7 @@ pub fn gfxResetCommandPool( VkResult::VK_SUCCESS } -pub fn gfxAllocateCommandBuffers( +pub extern fn gfxAllocateCommandBuffers( _gpu: VkDevice, pAllocateInfo: *const VkCommandBufferAllocateInfo, pCommandBuffers: *mut VkCommandBuffer, @@ -643,7 +682,7 @@ pub fn gfxAllocateCommandBuffers( VkResult::VK_SUCCESS } -pub fn gfxFreeCommandBuffers( +pub extern fn gfxFreeCommandBuffers( _gpu: VkDevice, mut commandPool: VkCommandPool, commandBufferCount: u32, @@ -925,7 +964,7 @@ extern "C" { pCommandBuffers: *const VkCommandBuffer); } -pub fn gfxDestroySurfaceKHR( +pub extern fn gfxDestroySurfaceKHR( _instance: VkInstance, surface: VkSurfaceKHR, _: *const VkAllocationCallbacks, @@ -933,7 +972,7 @@ pub fn gfxDestroySurfaceKHR( let _ = surface.unwrap(); //TODO } -pub fn gfxGetPhysicalDeviceSurfaceSupportKHR( +pub extern fn gfxGetPhysicalDeviceSurfaceSupportKHR( adapter: VkPhysicalDevice, queueFamilyIndex: u32, surface: VkSurfaceKHR, @@ -945,7 +984,7 @@ pub fn gfxGetPhysicalDeviceSurfaceSupportKHR( VkResult::VK_SUCCESS } -pub fn gfxGetPhysicalDeviceSurfaceCapabilitiesKHR( +pub extern fn gfxGetPhysicalDeviceSurfaceCapabilitiesKHR( adapter: VkPhysicalDevice, surface: VkSurfaceKHR, pSurfaceCapabilities: *mut VkSurfaceCapabilitiesKHR, @@ -975,7 +1014,7 @@ pub fn gfxGetPhysicalDeviceSurfaceCapabilitiesKHR( VkResult::VK_SUCCESS } -pub fn gfxGetPhysicalDeviceSurfaceFormatsKHR( +pub extern fn gfxGetPhysicalDeviceSurfaceFormatsKHR( adapter: VkPhysicalDevice, surface: VkSurfaceKHR, pSurfaceFormatCount: *mut u32, @@ -997,7 +1036,7 @@ pub fn gfxGetPhysicalDeviceSurfaceFormatsKHR( VkResult::VK_SUCCESS } -pub fn gfxGetPhysicalDeviceSurfacePresentModesKHR( +pub extern fn gfxGetPhysicalDeviceSurfacePresentModesKHR( _adapter: VkPhysicalDevice, _surface: VkSurfaceKHR, pPresentModeCount: *mut u32, @@ -1016,6 +1055,83 @@ pub fn gfxGetPhysicalDeviceSurfacePresentModesKHR( VkResult::VK_SUCCESS } +pub extern fn gfxCreateSwapchainKHR( + gpu: VkDevice, + pCreateInfo: *const VkSwapchainCreateInfoKHR, + _pAllocator: *const VkAllocationCallbacks, + pSwapchain: *mut VkSwapchainKHR, +) -> VkResult { + let info = unsafe { &*pCreateInfo }; + // TODO: more checks + assert_eq!(info.clipped, VK_TRUE); // TODO + assert_eq!(info.imageSharingMode, VkSharingMode::VK_SHARING_MODE_EXCLUSIVE); // TODO + + let config = hal::SwapchainConfig { + color_format: conv::hal_from_format(info.imageFormat), + depth_stencil_format: None, + image_count: info.minImageCount, + }; + let (swapchain, backbuffers) = gpu.device.create_swapchain(&mut info.surface.clone(), config); + + let images = match backbuffers { + hal::Backbuffer::Images(images) => { + images.into_iter().map(|image| Handle::new(image)).collect() + }, + hal::Backbuffer::Framebuffer(_) => { + panic!("Expected backbuffer images. Backends returning only framebuffers are not supported!") + }, + }; + + let swapchain = Swapchain { + raw: swapchain, + images, + }; + + unsafe { *pSwapchain = Handle::new(swapchain) }; + VkResult::VK_SUCCESS +} +pub extern fn gfxDestroySwapchainKHR( + device: VkDevice, + mut swapchain: VkSwapchainKHR, + pAllocator: *const VkAllocationCallbacks, +) { + for image in &mut swapchain.images { + let _ = image.unwrap(); + } + let _ = swapchain.unwrap(); +} +pub extern fn gfxGetSwapchainImagesKHR( + device: VkDevice, + swapchain: VkSwapchainKHR, + pSwapchainImageCount: *mut u32, + pSwapchainImages: *mut VkImage, +) -> VkResult { + debug_assert!(!pSwapchainImageCount.is_null()); + + let swapchain_image_count = unsafe { &mut*pSwapchainImageCount }; + let available_images = swapchain.images.len() as u32; + + if pSwapchainImages.is_null() { + // If NULL the number of presentable images is returned. + *swapchain_image_count = available_images; + } else { + *swapchain_image_count = available_images.min(*swapchain_image_count); + let swapchain_images = unsafe { + slice::from_raw_parts_mut(pSwapchainImages, *swapchain_image_count as _) + }; + + for i in 0..*swapchain_image_count as _ { + swapchain_images[i] = swapchain.images[i]; + } + + if *swapchain_image_count < available_images { + return VkResult::VK_INCOMPLETE; + } + } + + VkResult::VK_SUCCESS +} + extern "C" { pub fn vkCmdProcessCommandsNVX(commandBuffer: VkCommandBuffer, pProcessCommandsInfo: diff --git a/libportability-gfx/src/lib.rs b/libportability-gfx/src/lib.rs index 0d9698a..273a034 100644 --- a/libportability-gfx/src/lib.rs +++ b/libportability-gfx/src/lib.rs @@ -5,6 +5,8 @@ extern crate gfx_hal as hal; extern crate gfx_backend_vulkan as back; +#[macro_use] +extern crate lazy_static; mod conv; mod handle; @@ -4527,85 +4529,6 @@ pub type PFN_vkQueuePresentKHR = pPresentInfo: *const VkPresentInfoKHR) -> VkResult>; -pub fn gfxCreateSwapchainKHR( - gpu: VkDevice, - pCreateInfo: *const VkSwapchainCreateInfoKHR, - _pAllocator: *const VkAllocationCallbacks, - pSwapchain: *mut VkSwapchainKHR, -) -> VkResult { - let info = unsafe { &*pCreateInfo }; - // TODO: more checks - assert_eq!(info.clipped, VK_TRUE); // TODO - assert_eq!(info.imageSharingMode, VkSharingMode::VK_SHARING_MODE_EXCLUSIVE); // TODO - - let config = hal::SwapchainConfig { - color_format: conv::hal_from_format(info.imageFormat), - depth_stencil_format: None, - image_count: info.minImageCount, - }; - let (swapchain, backbuffers) = gpu.device.create_swapchain(&mut info.surface.clone(), config); - - let images = match backbuffers { - hal::Backbuffer::Images(images) => { - images.into_iter().map(|image| Handle::new(image)).collect() - }, - hal::Backbuffer::Framebuffer(_) => { - panic!("Expected backbuffer images. Backends returning only framebuffers are not supported!") - }, - }; - - let swapchain = Swapchain { - raw: swapchain, - images, - }; - - unsafe { *pSwapchain = Handle::new(swapchain) }; - VkResult::VK_SUCCESS -} -pub fn gfxDestroySwapchainKHR( - device: VkDevice, - mut swapchain: VkSwapchainKHR, - pAllocator: *const VkAllocationCallbacks, -) { - for image in &mut swapchain.images { - let _ = image.unwrap(); - } - let _ = swapchain.unwrap(); -} -pub fn gfxGetSwapchainImagesKHR( - device: VkDevice, - swapchain: VkSwapchainKHR, - pSwapchainImageCount: *mut u32, - pSwapchainImages: *mut VkImage, -) -> VkResult { - debug_assert!(!pSwapchainImageCount.is_null()); - - let swapchain_image_count = unsafe { *pSwapchainImageCount }; - let available_images = swapchain.images.len(); - - if pSwapchainImages.is_null() { - // If NULL the number of presentable images is returned. - unsafe { *pSwapchainImageCount = swapchain.images.len() as _; } - } else { - let num_images = available_images.min(swapchain_image_count as _); - let swapchain_images = unsafe { - slice::from_raw_parts_mut(pSwapchainImages, num_images) - }; - - for i in 0..num_images as _ { - swapchain_images[i] = swapchain.images[i]; - } - - // Overwrite pSwapchainImageCount with actual image count - unsafe { *pSwapchainImageCount = num_images as _; } - - if num_images < available_images { - return VkResult::VK_INCOMPLETE; - } - } - - VkResult::VK_SUCCESS -} extern "C" { pub fn vkAcquireNextImageKHR(device: VkDevice, swapchain: VkSwapchainKHR, timeout: u64, semaphore: VkSemaphore, diff --git a/libportability-icd/portability_debug.json b/libportability-icd/portability_debug.json new file mode 100644 index 0000000..9ee9845 --- /dev/null +++ b/libportability-icd/portability_debug.json @@ -0,0 +1,7 @@ +{ + "file_format_version": "1.0.0", + "ICD": { + "library_path": "..\\target\\debug\\portability_icd.dll", + "api_version": "1.0.0" + } +} diff --git a/libportability-icd/src/lib.rs b/libportability-icd/src/lib.rs index 6b0881d..7bdcd06 100644 --- a/libportability-icd/src/lib.rs +++ b/libportability-icd/src/lib.rs @@ -1,3 +1,58 @@ +#![allow(non_snake_case)] + extern crate portability_gfx; use portability_gfx::*; + +use std::ffi::CStr; +use std::mem; +use std::ptr; + +const ICD_VERSION: u32 = 5; + +macro_rules! proc_addr { + ($name:expr, $($vk:pat => $gfx:expr),*) => ( + match $name { + $( + stringify!($vk) => unsafe { mem::transmute::<_, PFN_vkVoidFunction>($gfx as *const ()) } + ),* + _ => None + } + ); +} + +#[no_mangle] +pub extern fn vk_icdGetInstanceProcAddr( + instance: VkInstance, pName: *const ::std::os::raw::c_char, +) -> PFN_vkVoidFunction { + let name = unsafe { CStr::from_ptr(pName) }; + let name = match name.to_str() { + Ok(name) => name, + Err(_) => return None, + }; + + proc_addr!{ name, + vkCreateInstance => gfxCreateInstance, + vkEnumerateInstanceExtensionProperties => gfxEnumerateInstanceExtensionProperties + } +} + +#[no_mangle] +pub extern fn vk_icdNegotiateLoaderICDInterfaceVersion( + pSupportedVersion: *mut ::std::os::raw::c_uint, +) -> VkResult { + let supported_version = unsafe { &mut *pSupportedVersion }; + if *supported_version > ICD_VERSION { + *supported_version = ICD_VERSION; + } + + VkResult::VK_SUCCESS +} + +#[no_mangle] +pub extern fn vk_icdGetPhysicalDeviceProcAddr( + instance: VkInstance, pName: *const ::std::os::raw::c_char, +) -> PFN_vkVoidFunction { + unimplemented!() +} +