use std::ffi::CString;
#[derive(Clone, Debug, Default)]
pub struct DeviceExtensions {
enabled: Vec<&'static str>,
}
#[derive(Clone, Debug, Default)]
pub struct InstanceExtensions {
enabled: Vec<&'static str>,
}
impl DeviceExtensions {
pub fn new() -> Self {
Self::default()
}
pub fn enable_raw(mut self, name: &'static str) -> Self {
self.enable(name);
self
}
pub fn names(&self) -> &[&'static str] {
&self.enabled
}
pub fn contains(&self, name: &str) -> bool {
self.enabled.contains(&name)
}
fn enable(&mut self, name: &'static str) {
if !self.enabled.contains(&name) {
self.enabled.push(name);
}
}
}
impl InstanceExtensions {
pub fn new() -> Self {
Self::default()
}
pub fn enable_raw(mut self, name: &'static str) -> Self {
self.enable(name);
self
}
pub fn names(&self) -> &[&'static str] {
&self.enabled
}
pub fn contains(&self, name: &str) -> bool {
self.enabled.contains(&name)
}
fn enable(&mut self, name: &'static str) {
if !self.enabled.contains(&name) {
self.enabled.push(name);
}
}
pub(crate) fn to_cstrings(&self) -> std::result::Result<Vec<CString>, std::ffi::NulError> {
self.enabled.iter().map(|s| CString::new(*s)).collect()
}
}
include!(concat!(env!("OUT_DIR"), "/device_extensions_generated.rs"));
include!(concat!(env!("OUT_DIR"), "/instance_extensions_generated.rs"));
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn device_extensions_dedups_transitive_requires() {
let ext = DeviceExtensions::new()
.khr_swapchain()
.enable_raw(crate::raw::bindings::KHR_SWAPCHAIN_EXTENSION_NAME);
let names = ext.names();
let count = names
.iter()
.filter(|n| **n == crate::raw::bindings::KHR_SWAPCHAIN_EXTENSION_NAME)
.count();
assert_eq!(count, 1, "khr_swapchain should only appear once");
}
#[test]
fn device_extensions_khr_cooperative_matrix_includes_deps() {
let ext = DeviceExtensions::new().khr_cooperative_matrix();
assert!(
ext.contains(crate::raw::bindings::KHR_COOPERATIVE_MATRIX_EXTENSION_NAME),
"primary extension enabled"
);
}
#[test]
fn instance_extensions_khr_surface() {
let ext = InstanceExtensions::new().khr_surface();
assert!(ext.contains(crate::raw::bindings::KHR_SURFACE_EXTENSION_NAME));
}
#[test]
fn raw_escape_hatch_works() {
let ext = DeviceExtensions::new().enable_raw("VK_FAKE_not_yet_in_spec");
assert!(ext.contains("VK_FAKE_not_yet_in_spec"));
}
#[test]
fn contains_lookup_is_by_name_string() {
let ext = DeviceExtensions::new().khr_swapchain();
assert!(ext.contains("VK_KHR_swapchain"));
assert!(!ext.contains("VK_KHR_not_enabled"));
}
}