Add functions to query supported device extensions
@@ -15,6 +15,9 @@ use std::str;
use Error;
use OomError;
+use VulkanObject;
+use VulkanPointers;
+use instance::PhysicalDevice;
use instance::loader;
use instance::loader::LoadingError;
use vk;
@@ -143,6 +146,62 @@ macro_rules! instance_extensions {
);
}
+macro_rules! device_extensions {
+ ($sname:ident, $($ext:ident => $s:expr,)*) => (
+ extensions! {
+ $sname,
+ $( $ext => $s,)*
+ }
+
+ impl $sname {
+ /// See the docs of supported_by_device().
+ pub fn supported_by_device_raw(physical_device: &PhysicalDevice) -> Result<$sname, SupportedExtensionsError> {
+ let vk = physical_device.instance().pointers();
+
+ let properties: Vec<vk::ExtensionProperties> = unsafe {
+ let mut num = 0;
+ try!(check_errors(vk.EnumerateDeviceExtensionProperties(
+ physical_device.internal_object(), ptr::null(), &mut num, ptr::null_mut())));
+
+ let mut properties = Vec::with_capacity(num as usize);
+ try!(check_errors(vk.EnumerateDeviceExtensionProperties(
+ physical_device.internal_object(), ptr::null(), &mut num, properties.as_mut_ptr())));
+ properties.set_len(num as usize);
+ properties
+ };
+
+ let mut extensions = $sname::none();
+ for property in properties {
+ let name = property.extensionName;
+ $(
+ // TODO: this is VERY inefficient
+ // TODO: Check specVersion?
+ let same = {
+ let mut i = 0;
+ while name[i] != 0 && $s[i] != 0 && name[i] as u8 == $s[i] && i < $s.len() { i += 1; }
+ name[i] == 0 && (i >= $s.len() || name[i] as u8 == $s[i])
+ };
+ if same {
+ extensions.$ext = true;
+ }
+ )*
+ }
+
+ Ok(extensions)
+ }
+
+ /// Returns an `Extensions` object with extensions supported by the `PhysicalDevice`.
+ pub fn supported_by_device(physical_device: &PhysicalDevice) -> $sname {
+ match $sname::supported_by_device_raw(physical_device) {
+ Ok(l) => l,
+ Err(SupportedExtensionsError::LoadingError(e)) => unreachable!(),
+ Err(SupportedExtensionsError::OomError(e)) => panic!("{:?}", e),
+ }
+ }
+ }
+ );
+}
+
instance_extensions! {
InstanceExtensions,
khr_surface => b"VK_KHR_surface",
@@ -158,7 +217,7 @@ instance_extensions! {
ext_swapchain_colorspace => b"VK_EXT_swapchain_colorspace",
}
-extensions! {
+device_extensions! {
DeviceExtensions,
khr_swapchain => b"VK_KHR_swapchain",
khr_display_swapchain => b"VK_KHR_display_swapchain",
