42: Improve ICD: adding missing entrypoints and add magic loader field r=kvark a=msiglreith

Fixes #32 
Vulkan stuck in endless loop, dx12 crashing at device creation (missing extension information)
This commit is contained in:
bors[bot] 2018-03-01 14:54:18 +00:00
commit 1c06394db0
5 changed files with 122 additions and 23 deletions

View file

@ -1,6 +1,8 @@
use VK_NULL_HANDLE; use VK_NULL_HANDLE;
use std::{borrow, fmt, ops}; use std::{borrow, fmt, ops};
static ICD_LOADER_MAGIC: u32 = 0x01CDC0DE;
#[repr(C)] #[repr(C)]
pub struct Handle<T>(*mut T); pub struct Handle<T>(*mut T);
@ -51,3 +53,53 @@ impl<T> fmt::Debug for Handle<T> {
write!(formatter, "Handle({:p})", self.0) write!(formatter, "Handle({:p})", self.0)
} }
} }
#[repr(C)]
pub struct DispatchHandle<T>(u32, Handle<T>);
impl<T> DispatchHandle<T> {
pub fn new(value: T) -> Self {
DispatchHandle(ICD_LOADER_MAGIC, Handle::new(value))
}
pub fn unwrap(self) -> Box<T> {
self.1.unwrap()
}
pub fn is_null(&self) -> bool {
self.1.is_null()
}
}
impl<T> Clone for DispatchHandle<T> {
fn clone(&self) -> Self {
DispatchHandle(self.0, self.1)
}
}
impl<T> Copy for DispatchHandle<T> {}
impl<T> ops::Deref for DispatchHandle<T> {
type Target = T;
fn deref(&self) -> &T {
self.1.deref()
}
}
impl<T> ops::DerefMut for DispatchHandle<T> {
fn deref_mut(&mut self) -> &mut T {
self.1.deref_mut()
}
}
impl<T> borrow::Borrow<T> for DispatchHandle<T> {
fn borrow(&self) -> &T {
self.1.borrow()
}
}
impl<T> fmt::Debug for DispatchHandle<T> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "DispatchHandle({:p})", (self.1).0)
}
}

View file

@ -17,18 +17,7 @@ use super::*;
const VERSION: (u32, u32, u32) = (1, 0, 66); const VERSION: (u32, u32, u32) = (1, 0, 66);
const DRIVER_VERSION: u32 = 1; const DRIVER_VERSION: u32 = 1;
pub type PFN_vkCreateInstance = ::std::option::Option<unsafe extern "C" fn( #[macro_export]
pCreateInfo: *const VkInstanceCreateInfo,
pAllocator: *const VkAllocationCallbacks,
pInstance: *mut VkInstance,
) -> VkResult>;
pub type PFN_vkEnumeratePhysicalDevices = ::std::option::Option<unsafe extern "C" fn(
instance: VkInstance,
pPhysicalDeviceCount: *mut u32,
pPhysicalDevices: *mut VkPhysicalDevice,
) -> VkResult>;
macro_rules! proc_addr { macro_rules! proc_addr {
($name:expr, $($vk:ident, $pfn_vk:ident => $gfx:expr,)*) => ( ($name:expr, $($vk:ident, $pfn_vk:ident => $gfx:expr,)*) => (
match $name { match $name {
@ -246,6 +235,7 @@ pub extern "C" fn gfxGetInstanceProcAddr(
proc_addr!{ name, proc_addr!{ name,
vkCreateInstance, PFN_vkCreateInstance => gfxCreateInstance, vkCreateInstance, PFN_vkCreateInstance => gfxCreateInstance,
vkDestroyInstance, PFN_vkDestroyInstance => gfxDestroyInstance,
vkCreateDevice, PFN_vkCreateDevice => gfxCreateDevice, vkCreateDevice, PFN_vkCreateDevice => gfxCreateDevice,
vkGetDeviceProcAddr, PFN_vkGetDeviceProcAddr => gfxGetDeviceProcAddr, vkGetDeviceProcAddr, PFN_vkGetDeviceProcAddr => gfxGetDeviceProcAddr,
@ -261,6 +251,7 @@ pub extern "C" fn gfxGetInstanceProcAddr(
vkGetPhysicalDeviceImageFormatProperties, PFN_vkGetPhysicalDeviceImageFormatProperties => gfxGetPhysicalDeviceImageFormatProperties, vkGetPhysicalDeviceImageFormatProperties, PFN_vkGetPhysicalDeviceImageFormatProperties => gfxGetPhysicalDeviceImageFormatProperties,
vkGetPhysicalDeviceMemoryProperties, PFN_vkGetPhysicalDeviceMemoryProperties => gfxGetPhysicalDeviceMemoryProperties, vkGetPhysicalDeviceMemoryProperties, PFN_vkGetPhysicalDeviceMemoryProperties => gfxGetPhysicalDeviceMemoryProperties,
vkGetPhysicalDeviceQueueFamilyProperties, PFN_vkGetPhysicalDeviceQueueFamilyProperties => gfxGetPhysicalDeviceQueueFamilyProperties, vkGetPhysicalDeviceQueueFamilyProperties, PFN_vkGetPhysicalDeviceQueueFamilyProperties => gfxGetPhysicalDeviceQueueFamilyProperties,
vkGetPhysicalDeviceSparseImageFormatProperties, PFN_vkGetPhysicalDeviceSparseImageFormatProperties => gfxGetPhysicalDeviceSparseImageFormatProperties,
vkGetPhysicalDeviceSurfaceSupportKHR, PFN_vkGetPhysicalDeviceSurfaceSupportKHR => gfxGetPhysicalDeviceSurfaceSupportKHR, vkGetPhysicalDeviceSurfaceSupportKHR, PFN_vkGetPhysicalDeviceSurfaceSupportKHR => gfxGetPhysicalDeviceSurfaceSupportKHR,
vkGetPhysicalDeviceSurfaceCapabilitiesKHR, PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR => gfxGetPhysicalDeviceSurfaceCapabilitiesKHR, vkGetPhysicalDeviceSurfaceCapabilitiesKHR, PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR => gfxGetPhysicalDeviceSurfaceCapabilitiesKHR,
@ -457,7 +448,7 @@ pub extern "C" fn gfxCreateDevice(
let group = gpu.queues.take_raw(id).unwrap(); let group = gpu.queues.take_raw(id).unwrap();
let queues = group let queues = group
.into_iter() .into_iter()
.map(Handle::new) .map(DispatchHandle::new)
.collect(); .collect();
(info.queueFamilyIndex, queues) (info.queueFamilyIndex, queues)
@ -470,7 +461,7 @@ pub extern "C" fn gfxCreateDevice(
}; };
unsafe { unsafe {
*pDevice = Handle::new(gpu); *pDevice = DispatchHandle::new(gpu);
} }
VkResult::VK_SUCCESS VkResult::VK_SUCCESS
} }
@ -484,11 +475,16 @@ pub extern "C" fn gfxDestroyDevice(device: VkDevice, _pAllocator: *const VkAlloc
} }
lazy_static! { lazy_static! {
static ref INSTANCE_EXTENSIONS: [VkExtensionProperties; 1] = { static ref INSTANCE_EXTENSIONS: Vec<VkExtensionProperties> = {
let mut extensions = [ let mut extensions = [
VkExtensionProperties { VkExtensionProperties {
extensionName: [0; 256], // VK_KHR_SURFACE_EXTENSION_NAME extensionName: [0; 256], // VK_KHR_SURFACE_EXTENSION_NAME
specVersion: VK_KHR_SURFACE_SPEC_VERSION, 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 { .copy_from_slice(unsafe {
mem::transmute(VK_KHR_SURFACE_EXTENSION_NAME as &[u8]) 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) }; let output = unsafe { slice::from_raw_parts_mut(pCommandBuffers, count) };
for (out, cmd_buf) in output.iter_mut().zip(cmd_bufs) { for (out, cmd_buf) in output.iter_mut().zip(cmd_bufs) {
*out = Handle::new(cmd_buf); *out = DispatchHandle::new(cmd_buf);
} }
VkResult::VK_SUCCESS VkResult::VK_SUCCESS

View file

@ -21,7 +21,7 @@ mod handle;
mod impls; mod impls;
use back::Backend as B; use back::Backend as B;
use handle::Handle; use handle::{DispatchHandle, Handle};
use std::{cmp, slice}; use std::{cmp, slice};
use std::collections::HashMap; use std::collections::HashMap;
@ -31,10 +31,10 @@ pub use impls::*;
// Vulkan objects // Vulkan objects
pub type VkInstance = Handle<back::Instance>; pub type VkInstance = Handle<back::Instance>;
pub type VkPhysicalDevice = Handle<hal::Adapter<B>>; pub type VkPhysicalDevice = Handle<hal::Adapter<B>>;
pub type VkDevice = Handle<Gpu<B>>; pub type VkDevice = DispatchHandle<Gpu<B>>;
pub type VkQueue = Handle<<B as hal::Backend>::CommandQueue>; pub type VkQueue = DispatchHandle<<B as hal::Backend>::CommandQueue>;
pub type VkCommandPool = Handle<<B as hal::Backend>::CommandPool>; pub type VkCommandPool = Handle<<B as hal::Backend>::CommandPool>;
pub type VkCommandBuffer = Handle<<B as hal::Backend>::CommandBuffer>; pub type VkCommandBuffer = DispatchHandle<<B as hal::Backend>::CommandBuffer>;
pub type VkDeviceMemory = Handle<<B as hal::Backend>::Memory>; pub type VkDeviceMemory = Handle<<B as hal::Backend>::Memory>;
pub type VkDescriptorSetLayout = Handle<<B as hal::Backend>::DescriptorSetLayout>; pub type VkDescriptorSetLayout = Handle<<B as hal::Backend>::DescriptorSetLayout>;
pub type VkPipelineLayout = Handle<<B as hal::Backend>::PipelineLayout>; pub type VkPipelineLayout = Handle<<B as hal::Backend>::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_SPEC_VERSION: ::std::os::raw::c_uint = 25;
pub const VK_KHR_SURFACE_EXTENSION_NAME: &'static [u8; 15usize] = pub const VK_KHR_SURFACE_EXTENSION_NAME: &'static [u8; 15usize] =
b"VK_KHR_surface\x00"; 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: ::std::os::raw::c_uint = 1;
pub const VK_KHR_SWAPCHAIN_SPEC_VERSION: ::std::os::raw::c_uint = 68; pub const VK_KHR_SWAPCHAIN_SPEC_VERSION: ::std::os::raw::c_uint = 68;
pub const VK_KHR_SWAPCHAIN_EXTENSION_NAME: &'static [u8; 17usize] = pub const VK_KHR_SWAPCHAIN_EXTENSION_NAME: &'static [u8; 17usize] =
@ -6799,3 +6802,20 @@ pub type PFN_vkCmdSetDiscardRectangleEXT =
discardRectangleCount: u32, discardRectangleCount: u32,
pDiscardRectangles: pDiscardRectangles:
*const VkRect2D)>; *const VkRect2D)>;
pub type PFN_vkCreateInstance = ::std::option::Option<unsafe extern "C" fn(
pCreateInfo: *const VkInstanceCreateInfo,
pAllocator: *const VkAllocationCallbacks,
pInstance: *mut VkInstance,
) -> VkResult>;
pub type PFN_vkEnumeratePhysicalDevices = ::std::option::Option<unsafe extern "C" fn(
instance: VkInstance,
pPhysicalDeviceCount: *mut u32,
pPhysicalDevices: *mut VkPhysicalDevice,
) -> VkResult>;
pub type PFN_vkDestroyInstance = ::std::option::Option<unsafe extern "C" fn(
instance: VkInstance,
pAllocator: *const VkAllocationCallbacks,
)>;

View file

@ -5,7 +5,12 @@ authors = ["Dzmitry Malyshau <kvark@mozilla.com>"]
[lib] [lib]
name = "portability_icd" name = "portability_icd"
crate-type = ["dylib"] crate-type = ["cdylib"]
[features]
default = []
dx12 = ["portability-gfx/dx12"]
vulkan = ["portability-gfx/vulkan"]
[dependencies] [dependencies]
portability-gfx = { path = "../libportability-gfx" } portability-gfx = { path = "../libportability-gfx" }

View file

@ -1,5 +1,6 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
#[macro_use]
extern crate portability_gfx; extern crate portability_gfx;
use portability_gfx::*; use portability_gfx::*;
@ -35,5 +36,24 @@ pub extern "C" fn vk_icdGetPhysicalDeviceProcAddr(
instance: VkInstance, instance: VkInstance,
pName: *const ::std::os::raw::c_char, pName: *const ::std::os::raw::c_char,
) -> PFN_vkVoidFunction { ) -> 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,
}
} }