Implement the unified Metal surface creation

This commit is contained in:
Dzmitry Malyshau 2019-02-07 15:10:21 -05:00
parent d2ca924a71
commit 781c9bb627
2 changed files with 94 additions and 58 deletions

View file

@ -67,45 +67,39 @@ pub extern "C" fn gfxCreateInstance(
.map(Handle::new) .map(Handle::new)
.collect(); .collect();
unsafe { let create_info = unsafe { &*pCreateInfo };
let create_info = &*pCreateInfo; let application_info = unsafe { create_info.pApplicationInfo.as_ref() };
let application_info = create_info.pApplicationInfo.as_ref(); if let Some(ai) = application_info {
// Compare major and minor parts of version only - patch is ignored
if let Some(ai) = application_info { let (supported_major, supported_minor, _) = VERSION;
// Compare major and minor parts of version only - patch is ignored let requested_major_minor = ai.apiVersion >> 12;
let (supported_major, supported_minor, _) = VERSION; let version_supported = requested_major_minor
let requested_major_minor = ai.apiVersion >> 12; & (supported_major << 10 | supported_minor)
let version_supported = requested_major_minor == requested_major_minor;
& (supported_major << 10 | supported_minor) if !version_supported {
== requested_major_minor; return VkResult::VK_ERROR_INCOMPATIBLE_DRIVER;
if !version_supported {
return VkResult::VK_ERROR_INCOMPATIBLE_DRIVER;
}
} }
}
let enabled_extensions = if create_info.enabledExtensionCount == 0 { let mut enabled_extensions = Vec::new();
Vec::new() if create_info.enabledExtensionCount != 0 {
} else { for raw in unsafe {
let extensions = slice::from_raw_parts( slice::from_raw_parts(create_info.ppEnabledExtensionNames, create_info.enabledExtensionCount as _)
create_info.ppEnabledExtensionNames, } {
create_info.enabledExtensionCount as _, let cstr = unsafe { CStr::from_ptr(*raw) };
).iter() if !INSTANCE_EXTENSION_NAMES.contains(&cstr.to_bytes_with_nul()) {
.map(|raw| { return VkResult::VK_ERROR_EXTENSION_NOT_PRESENT;
CStr::from_ptr(*raw)
.to_str()
.expect("Invalid extension name")
.to_owned()
})
.collect::<Vec<_>>();
for extension in &extensions {
if !INSTANCE_EXTENSION_NAMES.contains(&extension.as_str()) {
return VkResult::VK_ERROR_EXTENSION_NOT_PRESENT;
}
} }
extensions let owned = cstr
}; .to_str()
.expect("Invalid extension name")
.to_owned();
enabled_extensions.push(owned);
}
}
unsafe {
*pInstance = Handle::new(RawInstance { *pInstance = Handle::new(RawInstance {
backend, backend,
adapters, adapters,
@ -493,6 +487,7 @@ pub extern "C" fn gfxGetInstanceProcAddr(
vkGetPhysicalDeviceSurfacePresentModesKHR, PFN_vkGetPhysicalDeviceSurfacePresentModesKHR => gfxGetPhysicalDeviceSurfacePresentModesKHR, vkGetPhysicalDeviceSurfacePresentModesKHR, PFN_vkGetPhysicalDeviceSurfacePresentModesKHR => gfxGetPhysicalDeviceSurfacePresentModesKHR,
vkCreateWin32SurfaceKHR, PFN_vkCreateWin32SurfaceKHR => gfxCreateWin32SurfaceKHR, vkCreateWin32SurfaceKHR, PFN_vkCreateWin32SurfaceKHR => gfxCreateWin32SurfaceKHR,
vkCreateMetalSurfaceEXT, PFN_vkCreateMetalSurfaceEXT => gfxCreateMetalSurfaceEXT,
vkCreateMacOSSurfaceMVK, PFN_vkCreateMacOSSurfaceMVK => gfxCreateMacOSSurfaceMVK, vkCreateMacOSSurfaceMVK, PFN_vkCreateMacOSSurfaceMVK => gfxCreateMacOSSurfaceMVK,
vkDestroySurfaceKHR, PFN_vkDestroySurfaceKHR => gfxDestroySurfaceKHR, vkDestroySurfaceKHR, PFN_vkDestroySurfaceKHR => gfxDestroySurfaceKHR,
@ -817,10 +812,8 @@ pub extern "C" fn gfxCreateDevice(
rd_device rd_device
}; };
let enabled_extensions = if dev_info.enabledExtensionCount == 0 { let mut enabled_extensions = Vec::new();
Vec::new() if dev_info.enabledExtensionCount != 0 {
} else {
let mut extensions = Vec::new();
for raw in unsafe { for raw in unsafe {
slice::from_raw_parts(dev_info.ppEnabledExtensionNames, dev_info.enabledExtensionCount as _) slice::from_raw_parts(dev_info.ppEnabledExtensionNames, dev_info.enabledExtensionCount as _)
} { } {
@ -832,10 +825,9 @@ pub extern "C" fn gfxCreateDevice(
.to_str() .to_str()
.expect("Invalid extension name") .expect("Invalid extension name")
.to_owned(); .to_owned();
extensions.push(owned); enabled_extensions.push(owned);
} }
extensions }
};
let gpu = Gpu { let gpu = Gpu {
device: gpu.device, device: gpu.device,
@ -879,22 +871,17 @@ pub extern "C" fn gfxDestroyDevice(gpu: VkDevice, _pAllocator: *const VkAllocati
} }
} }
// TODO: Avoid redefining these somehow
static INSTANCE_EXTENSION_NAME_VK_KHR_SURFACE: &str = "VK_KHR_surface";
#[cfg(target_os="windows")]
static INSTANCE_EXTENSION_NAME_VK_KHR_WIN32_SURFACE: &str = "VK_KHR_win32_surface";
#[cfg(target_os="macos")]
static INSTANCE_EXTENSION_NAME_VK_MACOS_SURFACE: &str = "VK_MVK_macos_surface";
lazy_static! { lazy_static! {
// TODO: Request from backend // TODO: Request from backend
static ref INSTANCE_EXTENSION_NAMES: Vec<&'static str> = { static ref INSTANCE_EXTENSION_NAMES: Vec<&'static [u8]> = {
vec![ vec![
INSTANCE_EXTENSION_NAME_VK_KHR_SURFACE, VK_KHR_SURFACE_EXTENSION_NAME,
#[cfg(target_os="windows")] #[cfg(target_os="windows")]
INSTANCE_EXTENSION_NAME_VK_KHR_WIN32_SURFACE, VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
#[cfg(target_os="macos")] #[cfg(target_os="macos")]
INSTANCE_EXTENSION_NAME_VK_MACOS_SURFACE, VK_EXT_METAL_SURFACE_EXTENSION_NAME,
#[cfg(target_os="macos")]
VK_MVK_MACOS_SURFACE_EXTENSION_NAME,
] ]
}; };
@ -920,7 +907,7 @@ lazy_static! {
extension extension
.extensionName[.. name.len()] .extensionName[.. name.len()]
.copy_from_slice(unsafe { .copy_from_slice(unsafe {
mem::transmute(name.as_bytes()) mem::transmute(name)
}); });
} }
@ -1105,8 +1092,8 @@ pub extern "C" fn gfxQueueSubmit(
let submission = hal::queue::Submission { let submission = hal::queue::Submission {
command_buffers: cmd_slice.iter(), command_buffers: cmd_slice.iter(),
wait_semaphores: wait_semaphores, wait_semaphores,
signal_semaphores: signal_semaphores, signal_semaphores,
}; };
unsafe { queue.submit(submission, fence.as_ref()); } unsafe { queue.submit(submission, fence.as_ref()); }
@ -4613,11 +4600,36 @@ pub extern "C" fn gfxQueuePresentKHR(
.map(|semaphore| &**semaphore) .map(|semaphore| &**semaphore)
}; };
unsafe { match unsafe {
queue.present(swapchains, wait_semaphores).unwrap(); queue.present(swapchains, wait_semaphores)
} {
Ok(_) => VkResult::VK_SUCCESS,
Err(_) => VkResult::VK_ERROR_SURFACE_LOST_KHR,
} }
}
VkResult::VK_SUCCESS #[inline]
pub extern "C" fn gfxCreateMetalSurfaceEXT(
instance: VkInstance,
pCreateInfo: *const VkMetalSurfaceCreateInfoEXT,
pAllocator: *const VkAllocationCallbacks,
pSurface: *mut VkSurfaceKHR,
) -> VkResult {
assert!(pAllocator.is_null());
let info = unsafe { &*pCreateInfo };
#[cfg(feature = "gfx-backend-metal")]
unsafe {
assert_eq!(info.flags, 0);
*pSurface = Handle::new(
instance.backend.create_surface_from_layer(info.pLayer as *mut _),
);
VkResult::VK_SUCCESS
}
#[cfg(not(feature = "gfx-backend-metal"))]
{
let _ = (instance, info, pSurface);
unreachable!()
}
} }
#[inline] #[inline]

View file

@ -265,6 +265,9 @@ pub const VK_KHR_WIN32_SURFACE_EXTENSION_NAME: &'static [u8; 21usize] =
b"VK_KHR_win32_surface\x00"; b"VK_KHR_win32_surface\x00";
pub const VK_MVK_MACOS_SURFACE_EXTENSION_NAME: &'static [u8; 21usize] = pub const VK_MVK_MACOS_SURFACE_EXTENSION_NAME: &'static [u8; 21usize] =
b"VK_MVK_macos_surface\x00"; b"VK_MVK_macos_surface\x00";
pub const VK_EXT_METAL_SURFACE_EXTENSION_NAME: &'static [u8; 21usize] =
b"VK_EXT_metal_surface\x00";
pub const VK_EXT_METAL_SURFACE_SPEC_VERSION: ::std::os::raw::c_uint = 1;
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] =
@ -839,6 +842,7 @@ pub enum VkStructureType {
1000099001, 1000099001,
VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK = 1000122000, VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK = 1000122000,
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000, VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000248000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_EXTX = 100163000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_EXTX = 100163000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_EXTX = 100163001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_EXTX = 100163001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_SUPPORT_EXTX = 100163002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_SUPPORT_EXTX = 100163002,
@ -1936,6 +1940,8 @@ pub enum VkStencilFaceFlagBits {
VK_STENCIL_FACE_FLAG_BITS_MAX_ENUM = 2147483647, VK_STENCIL_FACE_FLAG_BITS_MAX_ENUM = 2147483647,
} }
pub type VkStencilFaceFlags = VkFlags; pub type VkStencilFaceFlags = VkFlags;
pub type VkMetalSurfaceCreateFlagsEXT = VkFlags;
pub type PFN_vkAllocationFunction = pub type PFN_vkAllocationFunction =
::std::option::Option<unsafe extern "C" fn(pUserData: ::std::option::Option<unsafe extern "C" fn(pUserData:
*mut ::std::os::raw::c_void, *mut ::std::os::raw::c_void,
@ -6913,6 +6919,13 @@ pub type PFN_vkCreateWin32SurfaceKHR = ::std::option::Option<unsafe extern "C" f
pSurface: *mut VkSurfaceKHR, pSurface: *mut VkSurfaceKHR,
) -> VkResult>; ) -> VkResult>;
pub type PFN_vkCreateMetalSurfaceEXT = ::std::option::Option<unsafe extern "C" fn(
instance: VkInstance,
pCreateInfo: *const VkMetalSurfaceCreateInfoEXT,
pAllocator: *const VkAllocationCallbacks,
pSurface: *mut VkSurfaceKHR,
) -> VkResult>;
pub type PFN_vkCreateMacOSSurfaceMVK = ::std::option::Option<unsafe extern "C" fn( pub type PFN_vkCreateMacOSSurfaceMVK = ::std::option::Option<unsafe extern "C" fn(
instance: VkInstance, instance: VkInstance,
pCreateInfo: *const VkMacOSSurfaceCreateInfoMVK, pCreateInfo: *const VkMacOSSurfaceCreateInfoMVK,
@ -6959,3 +6972,14 @@ pub struct VkPhysicalDeviceImageViewSupportEXTX {
impl Clone for VkPhysicalDeviceImageViewSupportEXTX { impl Clone for VkPhysicalDeviceImageViewSupportEXTX {
fn clone(&self) -> Self { *self } fn clone(&self) -> Self { *self }
} }
#[repr(C)]
#[derive(Debug, Copy)]
pub struct VkMetalSurfaceCreateInfoEXT {
pub sType: VkStructureType,
pub pNext: *const ::std::os::raw::c_void,
pub flags: VkMetalSurfaceCreateFlagsEXT,
pub pLayer: *const ::std::os::raw::c_void,
}
impl Clone for VkMetalSurfaceCreateInfoEXT {
fn clone(&self) -> Self { *self }
}