Check enabled extensions

This commit is contained in:
Joshua Groves 2018-06-17 20:29:45 -06:00
parent 321cc54f81
commit 52bfd5d3ca
2 changed files with 89 additions and 4 deletions

View file

@ -35,7 +35,7 @@ macro_rules! proc_addr {
#[inline] #[inline]
pub extern "C" fn gfxCreateInstance( pub extern "C" fn gfxCreateInstance(
_pCreateInfo: *const VkInstanceCreateInfo, pCreateInfo: *const VkInstanceCreateInfo,
_pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
pInstance: *mut VkInstance, pInstance: *mut VkInstance,
) -> VkResult { ) -> VkResult {
@ -52,7 +52,29 @@ pub extern "C" fn gfxCreateInstance(
.map(Handle::new) .map(Handle::new)
.collect(); .collect();
unsafe { *pInstance = Handle::new(RawInstance { backend, adapters }) }; unsafe {
let create_info = &*pCreateInfo;
let enabled_extensions = if create_info.enabledExtensionCount == 0 {
Vec::new()
} else {
slice::from_raw_parts(create_info.ppEnabledExtensionNames, create_info.enabledExtensionCount as _)
.iter()
.map(|raw| CStr::from_ptr(*raw)
.to_str()
.expect("Invalid extension name")
.to_owned()
)
.collect()
};
*pInstance = Handle::new(RawInstance {
backend,
adapters,
enabled_extensions,
});
}
VkResult::VK_SUCCESS VkResult::VK_SUCCESS
} }
@ -326,15 +348,15 @@ pub extern "C" fn gfxGetInstanceProcAddr(
return device_addr; return device_addr;
} }
// Required instance
match name { match name {
"vkEnumerateInstanceVersion" | "vkEnumerateInstanceVersion" |
"vkEnumerateInstanceExtensionProperties" | "vkEnumerateInstanceExtensionProperties" |
"vkEnumerateInstanceLayerProperties" | "vkEnumerateInstanceLayerProperties" |
"vkCreateInstance" => { "vkCreateInstance" => {
// Instance is not required for these special cases // Instance is not required for these special cases
// See https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkGetInstanceProcAddr.html // See https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkGetInstanceProcAddr.html
}, }
_ => { _ => {
if instance.as_ref().is_none() { if instance.as_ref().is_none() {
return None; return None;
@ -342,6 +364,28 @@ pub extern "C" fn gfxGetInstanceProcAddr(
} }
} }
// Required extensions
match name {
"vkGetPhysicalDeviceSurfaceSupportKHR" |
"vkGetPhysicalDeviceSurfaceCapabilitiesKHR" |
"vkGetPhysicalDeviceSurfaceFormatsKHR" |
"vkGetPhysicalDeviceSurfacePresentModesKHR" |
"vkDestroySurfaceKHR"
=> {
let surface_ext = unsafe { *VK_KHR_SURFACE_EXTENSION_NAME.as_ptr() };
let surface_extension_enabled = instance
.as_ref()
.unwrap()
.enabled_extensions
.iter()
.any(|e| unsafe { *e.as_ptr() } == surface_ext);
if !surface_extension_enabled {
return None;
}
}
_ => {}
}
proc_addr!{ name, proc_addr!{ name,
vkCreateInstance, PFN_vkCreateInstance => gfxCreateInstance, vkCreateInstance, PFN_vkCreateInstance => gfxCreateInstance,
vkDestroyInstance, PFN_vkDestroyInstance => gfxDestroyInstance, vkDestroyInstance, PFN_vkDestroyInstance => gfxDestroyInstance,
@ -385,10 +429,33 @@ pub extern "C" fn gfxGetDeviceProcAddr(
Err(_) => return None, Err(_) => return None,
}; };
// Required device
if device.as_ref().is_none() { if device.as_ref().is_none() {
return None; return None;
} }
// Required extensions
match name {
"vkCreateSwapchainKHR" |
"vkDestroySwapchainKHR" |
"vkGetSwapchainImagesKHR" |
"vkAcquireNextImageKHR" |
"vkQueuePresentKHR"
=> {
let swapchain_ext = unsafe { *VK_KHR_SWAPCHAIN_EXTENSION_NAME.as_ptr() };
let swapchain_extension_enabled = device
.as_ref()
.unwrap()
.enabled_extensions
.iter()
.any(|e| unsafe { *e.as_ptr() } == swapchain_ext);
if !swapchain_extension_enabled {
return None;
}
}
_ => {}
}
proc_addr!{ name, proc_addr!{ name,
vkGetDeviceProcAddr, PFN_vkGetDeviceProcAddr => gfxGetDeviceProcAddr, vkGetDeviceProcAddr, PFN_vkGetDeviceProcAddr => gfxGetDeviceProcAddr,
vkDestroyDevice, PFN_vkDestroyDevice => gfxDestroyDevice, vkDestroyDevice, PFN_vkDestroyDevice => gfxDestroyDevice,
@ -595,9 +662,25 @@ pub extern "C" fn gfxCreateDevice(
rd_device rd_device
}; };
let enabled_extensions = if dev_info.enabledExtensionCount == 0 {
Vec::new()
} else {
unsafe {
slice::from_raw_parts(dev_info.ppEnabledExtensionNames, dev_info.enabledExtensionCount as _)
.iter()
.map(|raw| CStr::from_ptr(*raw)
.to_str()
.expect("Invalid extension name")
.to_owned()
)
.collect()
}
};
let gpu = Gpu { let gpu = Gpu {
device: gpu.device, device: gpu.device,
queues, queues,
enabled_extensions,
#[cfg(feature = "renderdoc")] #[cfg(feature = "renderdoc")]
renderdoc, renderdoc,
#[cfg(feature = "renderdoc")] #[cfg(feature = "renderdoc")]

View file

@ -63,11 +63,13 @@ pub type QueueFamilyIndex = u32;
pub struct RawInstance { pub struct RawInstance {
pub backend: back::Instance, pub backend: back::Instance,
pub adapters: Vec<VkPhysicalDevice>, pub adapters: Vec<VkPhysicalDevice>,
pub enabled_extensions: Vec<String>,
} }
pub struct Gpu<B: hal::Backend> { pub struct Gpu<B: hal::Backend> {
device: B::Device, device: B::Device,
queues: HashMap<QueueFamilyIndex, Vec<VkQueue>>, queues: HashMap<QueueFamilyIndex, Vec<VkQueue>>,
enabled_extensions: Vec<String>,
#[cfg(feature = "renderdoc")] #[cfg(feature = "renderdoc")]
renderdoc: renderdoc::RenderDoc<renderdoc::V110>, renderdoc: renderdoc::RenderDoc<renderdoc::V110>,
#[cfg(feature = "renderdoc")] #[cfg(feature = "renderdoc")]