diff --git a/libportability-gfx/src/handle.rs b/libportability-gfx/src/handle.rs index 3fc652d..6fdbaa9 100644 --- a/libportability-gfx/src/handle.rs +++ b/libportability-gfx/src/handle.rs @@ -1,6 +1,8 @@ use VK_NULL_HANDLE; use std::{borrow, fmt, ops}; +static ICD_LOADER_MAGIC: u32 = 0x01CDC0DE; + #[repr(C)] pub struct Handle(*mut T); @@ -51,3 +53,53 @@ impl fmt::Debug for Handle { write!(formatter, "Handle({:p})", self.0) } } + +#[repr(C)] +pub struct DispatchHandle(u32, Handle); + +impl DispatchHandle { + pub fn new(value: T) -> Self { + DispatchHandle(ICD_LOADER_MAGIC, Handle::new(value)) + } + + pub fn unwrap(self) -> Box { + self.1.unwrap() + } + + pub fn is_null(&self) -> bool { + self.1.is_null() + } +} + +impl Clone for DispatchHandle { + fn clone(&self) -> Self { + DispatchHandle(self.0, self.1) + } +} + +impl Copy for DispatchHandle {} + +impl ops::Deref for DispatchHandle { + type Target = T; + fn deref(&self) -> &T { + self.1.deref() + } +} + +impl ops::DerefMut for DispatchHandle { + fn deref_mut(&mut self) -> &mut T { + self.1.deref_mut() + } +} + +impl borrow::Borrow for DispatchHandle { + fn borrow(&self) -> &T { + self.1.borrow() + } +} + +impl fmt::Debug for DispatchHandle { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "DispatchHandle({:p})", (self.1).0) + } +} diff --git a/libportability-gfx/src/impls.rs b/libportability-gfx/src/impls.rs index 2332075..4c899fa 100644 --- a/libportability-gfx/src/impls.rs +++ b/libportability-gfx/src/impls.rs @@ -17,18 +17,7 @@ use super::*; const VERSION: (u32, u32, u32) = (1, 0, 66); const DRIVER_VERSION: u32 = 1; -pub type PFN_vkCreateInstance = ::std::option::Option VkResult>; - -pub type PFN_vkEnumeratePhysicalDevices = ::std::option::Option VkResult>; - +#[macro_export] macro_rules! proc_addr { ($name:expr, $($vk:ident, $pfn_vk:ident => $gfx:expr,)*) => ( match $name { @@ -246,6 +235,7 @@ pub extern "C" fn gfxGetInstanceProcAddr( proc_addr!{ name, vkCreateInstance, PFN_vkCreateInstance => gfxCreateInstance, + vkDestroyInstance, PFN_vkDestroyInstance => gfxDestroyInstance, vkCreateDevice, PFN_vkCreateDevice => gfxCreateDevice, vkGetDeviceProcAddr, PFN_vkGetDeviceProcAddr => gfxGetDeviceProcAddr, @@ -261,6 +251,7 @@ pub extern "C" fn gfxGetInstanceProcAddr( vkGetPhysicalDeviceImageFormatProperties, PFN_vkGetPhysicalDeviceImageFormatProperties => gfxGetPhysicalDeviceImageFormatProperties, vkGetPhysicalDeviceMemoryProperties, PFN_vkGetPhysicalDeviceMemoryProperties => gfxGetPhysicalDeviceMemoryProperties, vkGetPhysicalDeviceQueueFamilyProperties, PFN_vkGetPhysicalDeviceQueueFamilyProperties => gfxGetPhysicalDeviceQueueFamilyProperties, + vkGetPhysicalDeviceSparseImageFormatProperties, PFN_vkGetPhysicalDeviceSparseImageFormatProperties => gfxGetPhysicalDeviceSparseImageFormatProperties, vkGetPhysicalDeviceSurfaceSupportKHR, PFN_vkGetPhysicalDeviceSurfaceSupportKHR => gfxGetPhysicalDeviceSurfaceSupportKHR, vkGetPhysicalDeviceSurfaceCapabilitiesKHR, PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR => gfxGetPhysicalDeviceSurfaceCapabilitiesKHR, @@ -457,7 +448,7 @@ pub extern "C" fn gfxCreateDevice( let group = gpu.queues.take_raw(id).unwrap(); let queues = group .into_iter() - .map(Handle::new) + .map(DispatchHandle::new) .collect(); (info.queueFamilyIndex, queues) @@ -470,7 +461,7 @@ pub extern "C" fn gfxCreateDevice( }; unsafe { - *pDevice = Handle::new(gpu); + *pDevice = DispatchHandle::new(gpu); } VkResult::VK_SUCCESS } @@ -484,11 +475,16 @@ pub extern "C" fn gfxDestroyDevice(device: VkDevice, _pAllocator: *const VkAlloc } lazy_static! { - static ref INSTANCE_EXTENSIONS: [VkExtensionProperties; 1] = { + static ref INSTANCE_EXTENSIONS: Vec = { let mut extensions = [ VkExtensionProperties { extensionName: [0; 256], // VK_KHR_SURFACE_EXTENSION_NAME specVersion: VK_KHR_SURFACE_SPEC_VERSION, + }, + #[cfg(target_os="windows")] + VkExtensionProperties { + extensionName: [0; 256], // VK_KHR_WIN32_SURFACE_EXTENSION_NAME + specVersion: VK_KHR_WIN32_SURFACE_SPEC_VERSION, } ]; @@ -497,8 +493,14 @@ lazy_static! { .copy_from_slice(unsafe { mem::transmute(VK_KHR_SURFACE_EXTENSION_NAME as &[u8]) }); + #[cfg(target_os="windows")] + extensions[1] + .extensionName[..VK_KHR_WIN32_SURFACE_EXTENSION_NAME.len()] + .copy_from_slice(unsafe { + mem::transmute(VK_KHR_WIN32_SURFACE_EXTENSION_NAME as &[u8]) + }); - extensions + extensions.to_vec() }; } @@ -2189,7 +2191,7 @@ pub extern "C" fn gfxAllocateCommandBuffers( let output = unsafe { slice::from_raw_parts_mut(pCommandBuffers, count) }; for (out, cmd_buf) in output.iter_mut().zip(cmd_bufs) { - *out = Handle::new(cmd_buf); + *out = DispatchHandle::new(cmd_buf); } VkResult::VK_SUCCESS diff --git a/libportability-gfx/src/lib.rs b/libportability-gfx/src/lib.rs index ae0bfe1..ec746b6 100644 --- a/libportability-gfx/src/lib.rs +++ b/libportability-gfx/src/lib.rs @@ -21,7 +21,7 @@ mod handle; mod impls; use back::Backend as B; -use handle::Handle; +use handle::{DispatchHandle, Handle}; use std::{cmp, slice}; use std::collections::HashMap; @@ -31,10 +31,10 @@ pub use impls::*; // Vulkan objects pub type VkInstance = Handle; pub type VkPhysicalDevice = Handle>; -pub type VkDevice = Handle>; -pub type VkQueue = Handle<::CommandQueue>; +pub type VkDevice = DispatchHandle>; +pub type VkQueue = DispatchHandle<::CommandQueue>; pub type VkCommandPool = Handle<::CommandPool>; -pub type VkCommandBuffer = Handle<::CommandBuffer>; +pub type VkCommandBuffer = DispatchHandle<::CommandBuffer>; pub type VkDeviceMemory = Handle<::Memory>; pub type VkDescriptorSetLayout = Handle<::DescriptorSetLayout>; pub type VkPipelineLayout = Handle<::PipelineLayout>; @@ -188,6 +188,9 @@ pub const VK_KHR_surface: ::std::os::raw::c_uint = 1; pub const VK_KHR_SURFACE_SPEC_VERSION: ::std::os::raw::c_uint = 25; pub const VK_KHR_SURFACE_EXTENSION_NAME: &'static [u8; 15usize] = b"VK_KHR_surface\x00"; +pub const VK_KHR_WIN32_SURFACE_SPEC_VERSION: ::std::os::raw::c_uint = 6; +pub const VK_KHR_WIN32_SURFACE_EXTENSION_NAME: &'static [u8; 21usize] = + b"VK_KHR_win32_surface\x00"; pub const VK_KHR_swapchain: ::std::os::raw::c_uint = 1; pub const VK_KHR_SWAPCHAIN_SPEC_VERSION: ::std::os::raw::c_uint = 68; pub const VK_KHR_SWAPCHAIN_EXTENSION_NAME: &'static [u8; 17usize] = @@ -6799,3 +6802,20 @@ pub type PFN_vkCmdSetDiscardRectangleEXT = discardRectangleCount: u32, pDiscardRectangles: *const VkRect2D)>; + +pub type PFN_vkCreateInstance = ::std::option::Option VkResult>; + +pub type PFN_vkEnumeratePhysicalDevices = ::std::option::Option VkResult>; + +pub type PFN_vkDestroyInstance = ::std::option::Option; diff --git a/libportability-icd/Cargo.toml b/libportability-icd/Cargo.toml index 019d2ed..5125b4e 100644 --- a/libportability-icd/Cargo.toml +++ b/libportability-icd/Cargo.toml @@ -5,7 +5,12 @@ authors = ["Dzmitry Malyshau "] [lib] name = "portability_icd" -crate-type = ["dylib"] +crate-type = ["cdylib"] + +[features] +default = [] +dx12 = ["portability-gfx/dx12"] +vulkan = ["portability-gfx/vulkan"] [dependencies] portability-gfx = { path = "../libportability-gfx" } diff --git a/libportability-icd/src/lib.rs b/libportability-icd/src/lib.rs index 714295a..b152bb5 100644 --- a/libportability-icd/src/lib.rs +++ b/libportability-icd/src/lib.rs @@ -1,5 +1,6 @@ #![allow(non_snake_case)] +#[macro_use] extern crate portability_gfx; use portability_gfx::*; @@ -35,5 +36,24 @@ pub extern "C" fn vk_icdGetPhysicalDeviceProcAddr( instance: VkInstance, pName: *const ::std::os::raw::c_char, ) -> PFN_vkVoidFunction { - gfxGetPhysicslDeviceProcAddr(instance, pName) + let name = unsafe { CStr::from_ptr(pName) }; + let name = match name.to_str() { + Ok(name) => name, + Err(_) => return None, + }; + + proc_addr!{ name, + vkGetPhysicalDeviceFeatures, PFN_vkGetPhysicalDeviceFeatures => gfxGetPhysicalDeviceFeatures, + vkGetPhysicalDeviceProperties, PFN_vkGetPhysicalDeviceProperties => gfxGetPhysicalDeviceProperties, + vkGetPhysicalDeviceFormatProperties, PFN_vkGetPhysicalDeviceFormatProperties => gfxGetPhysicalDeviceFormatProperties, + vkGetPhysicalDeviceImageFormatProperties, PFN_vkGetPhysicalDeviceImageFormatProperties => gfxGetPhysicalDeviceImageFormatProperties, + vkGetPhysicalDeviceMemoryProperties, PFN_vkGetPhysicalDeviceMemoryProperties => gfxGetPhysicalDeviceMemoryProperties, + vkGetPhysicalDeviceQueueFamilyProperties, PFN_vkGetPhysicalDeviceQueueFamilyProperties => gfxGetPhysicalDeviceQueueFamilyProperties, + vkGetPhysicalDeviceSparseImageFormatProperties, PFN_vkGetPhysicalDeviceSparseImageFormatProperties => gfxGetPhysicalDeviceSparseImageFormatProperties, + + vkGetPhysicalDeviceSurfaceSupportKHR, PFN_vkGetPhysicalDeviceSurfaceSupportKHR => gfxGetPhysicalDeviceSurfaceSupportKHR, + vkGetPhysicalDeviceSurfaceCapabilitiesKHR, PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR => gfxGetPhysicalDeviceSurfaceCapabilitiesKHR, + vkGetPhysicalDeviceSurfaceFormatsKHR, PFN_vkGetPhysicalDeviceSurfaceFormatsKHR => gfxGetPhysicalDeviceSurfaceFormatsKHR, + vkGetPhysicalDeviceSurfacePresentModesKHR, PFN_vkGetPhysicalDeviceSurfacePresentModesKHR => gfxGetPhysicalDeviceSurfacePresentModesKHR, + } }