instance refactor
This commit is contained in:
parent
41e4a2ed9c
commit
20f743d74b
|
|
@ -16,7 +16,8 @@ use tinyvec::{ArrayVec, array_vec};
|
|||
|
||||
use crate::{
|
||||
Error, ExtendsDeviceProperties2Debug, Instance, PhysicalDevice, PhysicalDeviceFeatures,
|
||||
PhysicalDeviceProperties, Queue, Result, VkNameList, make_extention_properties, sync,
|
||||
PhysicalDeviceProperties, Queue, Result, VkNameList, instance::InstanceInner,
|
||||
make_extention_properties, sync,
|
||||
};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
|
|
@ -114,7 +115,7 @@ pub struct DeviceInner {
|
|||
alloc: vk_mem::Allocator,
|
||||
device: DeviceWrapper,
|
||||
physical: PhysicalDevice,
|
||||
instance: Arc<Instance>,
|
||||
instance: Arc<InstanceInner>,
|
||||
swapchain: khr::swapchain::Device,
|
||||
debug_utils: ash::ext::debug_utils::Device,
|
||||
allocated_queues: BTreeMap<(u32, u32), Queue>,
|
||||
|
|
@ -137,18 +138,18 @@ impl core::fmt::Debug for DeviceInner {
|
|||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! make_extention {
|
||||
macro_rules! make_extension {
|
||||
($module:path) => {{
|
||||
use $module::{NAME as EXTENSION_NAME, SPEC_VERSION as EXTENSION_VERSION};
|
||||
Extension {
|
||||
name: EXTENSION_NAME.to_str().unwrap(),
|
||||
$crate::device::Extension {
|
||||
name: EXTENSION_NAME,
|
||||
version: EXTENSION_VERSION,
|
||||
}
|
||||
}};
|
||||
($module:path as $version:expr) => {{
|
||||
use $module::*;
|
||||
Extension {
|
||||
name: NAME.to_str().unwrap(),
|
||||
$crate::device::Extension {
|
||||
name: NAME,
|
||||
version: $version,
|
||||
}
|
||||
}};
|
||||
|
|
@ -156,7 +157,7 @@ macro_rules! make_extention {
|
|||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Extension<'a> {
|
||||
pub name: &'a str,
|
||||
pub name: &'a CStr,
|
||||
pub version: u32,
|
||||
}
|
||||
|
||||
|
|
@ -229,7 +230,7 @@ struct DeviceBuilder;
|
|||
|
||||
impl DeviceBuilder {
|
||||
fn queue_family_supports_presentation(
|
||||
instance: &Instance,
|
||||
instance: &Arc<InstanceInner>,
|
||||
pdev: vk::PhysicalDevice,
|
||||
queue_family: u32,
|
||||
display_handle: RawDisplayHandle,
|
||||
|
|
@ -270,7 +271,7 @@ impl DeviceBuilder {
|
|||
}
|
||||
|
||||
fn select_pdev_queue_families(
|
||||
instance: &Instance,
|
||||
instance: &Arc<InstanceInner>,
|
||||
display_handle: Option<RawDisplayHandle>,
|
||||
pdev: vk::PhysicalDevice,
|
||||
) -> DeviceQueueFamilies {
|
||||
|
|
@ -454,7 +455,7 @@ impl DeviceBuilder {
|
|||
}
|
||||
|
||||
fn choose_physical_device(
|
||||
instance: &Instance,
|
||||
instance: &Arc<InstanceInner>,
|
||||
display_handle: Option<RawDisplayHandle>,
|
||||
requirements: &PhysicalDeviceFeatures,
|
||||
extra_properties: Vec<Box<dyn ExtendsDeviceProperties2Debug>>,
|
||||
|
|
@ -505,8 +506,9 @@ impl DeviceBuilder {
|
|||
properties,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn get_available_extensions(
|
||||
pub(crate) fn get_available_extensions(
|
||||
entry: &ash::Entry,
|
||||
layers: &[&CStr],
|
||||
) -> Result<Vec<ash::vk::ExtensionProperties>> {
|
||||
|
|
@ -526,14 +528,13 @@ impl DeviceBuilder {
|
|||
}
|
||||
|
||||
/// returns a tuple of supported-or-enabled extensions and unsupported-and-requested extensions
|
||||
fn get_extensions<'a>(
|
||||
pub(crate) fn get_extensions<'a>(
|
||||
entry: &ash::Entry,
|
||||
layers: &[&'a CStr],
|
||||
extensions: impl Iterator<Item = Extension<'a>> + 'a,
|
||||
mut extensions: Vec<Extension<'a>>,
|
||||
display_handle: Option<RawDisplayHandle>,
|
||||
) -> Result<(HashSet<Extension<'a>>, HashSet<Extension<'a>>)> {
|
||||
unsafe {
|
||||
let available_extensions = Self::get_available_extensions(entry, layers)?;
|
||||
let available_extensions = get_available_extensions(entry, layers)?;
|
||||
|
||||
let available_extension_names = available_extensions
|
||||
.iter()
|
||||
|
|
@ -550,102 +551,117 @@ impl DeviceBuilder {
|
|||
available_extension_names.iter().collect::<Vec<_>>()
|
||||
);
|
||||
|
||||
let mut out_extensions = HashSet::new();
|
||||
let mut unsupported_extensions = HashSet::new();
|
||||
|
||||
let mut wsi_extensions = Vec::new();
|
||||
wsi_extensions.push(make_extention!(khr::surface));
|
||||
wsi_extensions.push(make_extension!(khr::surface));
|
||||
|
||||
// taken from wgpu-hal/src/vulkan/instance.rs:
|
||||
//
|
||||
// we want to enable all the wsi extensions that are applicable to the
|
||||
// platform, even if the user didn't explicitly request them, or
|
||||
// supplied a different/no display handle, because we might later want
|
||||
// to create a surface for a different windowing system, and enabling
|
||||
// all the wsi extensions doesn't have any real downsides.
|
||||
// We don't notify the user if some of these extensions aren't available
|
||||
// (e.g. because wayland isn't supported on some unix system)
|
||||
if cfg!(all(
|
||||
unix,
|
||||
not(target_os = "android"),
|
||||
not(target_os = "macos")
|
||||
)) {
|
||||
wsi_extensions.push(make_extention!(khr::xlib_surface));
|
||||
wsi_extensions.push(make_extention!(khr::xcb_surface));
|
||||
wsi_extensions.push(make_extention!(khr::wayland_surface));
|
||||
wsi_extensions.push(make_extension!(khr::xlib_surface));
|
||||
wsi_extensions.push(make_extension!(khr::xcb_surface));
|
||||
wsi_extensions.push(make_extension!(khr::wayland_surface));
|
||||
}
|
||||
if cfg!(target_os = "windows") {
|
||||
wsi_extensions.push(make_extention!(khr::win32_surface));
|
||||
wsi_extensions.push(make_extension!(khr::win32_surface));
|
||||
}
|
||||
if cfg!(target_os = "android") {
|
||||
wsi_extensions.push(make_extention!(khr::android_surface));
|
||||
wsi_extensions.push(make_extension!(khr::android_surface));
|
||||
}
|
||||
if cfg!(target_os = "macos") {
|
||||
wsi_extensions.push(make_extention!(ext::metal_surface));
|
||||
wsi_extensions.push(make_extention!(khr::portability_enumeration));
|
||||
wsi_extensions.push(make_extension!(ext::metal_surface));
|
||||
wsi_extensions.push(make_extension!(khr::portability_enumeration));
|
||||
}
|
||||
if cfg!(all(
|
||||
unix,
|
||||
not(target_vendor = "apple"),
|
||||
not(target_family = "wasm")
|
||||
)) {
|
||||
wsi_extensions.push(make_extention!(ext::acquire_drm_display));
|
||||
wsi_extensions.push(make_extention!(ext::direct_mode_display));
|
||||
wsi_extensions.push(make_extention!(khr::display));
|
||||
wsi_extensions.push(make_extension!(ext::acquire_drm_display));
|
||||
wsi_extensions.push(make_extension!(ext::direct_mode_display));
|
||||
wsi_extensions.push(make_extension!(khr::display));
|
||||
}
|
||||
|
||||
for extension in extensions {
|
||||
if let Some(available_version) = available_extension_names.get(&extension.name)
|
||||
&& *available_version >= extension.version
|
||||
let is_extension_available = |ext: &mut Extension| -> bool {
|
||||
if available_extensions
|
||||
.iter()
|
||||
.any(|inst_ext| inst_ext.extension_name_as_c_str() == Ok(ext.name))
|
||||
{
|
||||
out_extensions.insert(extension);
|
||||
true
|
||||
} else {
|
||||
unsupported_extensions.insert(extension);
|
||||
tracing::warn!(
|
||||
"Extension {:?} v{} was requested but is not available",
|
||||
ext.name,
|
||||
ext.version
|
||||
);
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
for extension in wsi_extensions {
|
||||
if let Some(available_version) = available_extension_names.get(&extension.name)
|
||||
&& *available_version >= extension.version
|
||||
{
|
||||
out_extensions.insert(extension);
|
||||
}
|
||||
// don't warn about missing WSI extensions, these might not all
|
||||
// be needed and weren't requested by the user.
|
||||
}
|
||||
|
||||
// if a display handle is provided, ensure the required WSI extensions are present
|
||||
let required_extension_names = display_handle
|
||||
.map(ash_window::enumerate_required_extensions)
|
||||
.unwrap_or(Ok(&[]))?;
|
||||
|
||||
for &extension in required_extension_names {
|
||||
let extension = core::ffi::CStr::from_ptr(extension);
|
||||
let extension = Extension {
|
||||
name: extension.to_str()?,
|
||||
version: 0,
|
||||
};
|
||||
|
||||
if let Some(available_version) = available_extension_names.get(&extension.name)
|
||||
&& *available_version >= extension.version
|
||||
{
|
||||
out_extensions.insert(extension);
|
||||
} else {
|
||||
unsupported_extensions.insert(extension);
|
||||
}
|
||||
let mut enabled_extensions = extensions
|
||||
.extract_if(.., is_extension_available)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
enabled_extensions.extend(wsi_extensions.extract_if(.., is_extension_available));
|
||||
|
||||
// if a display handle is provided, ensure the required WSI extensions are present
|
||||
if let Some(display_handle) = display_handle {
|
||||
let mut required_extensions = ash_window::enumerate_required_extensions(display_handle)?
|
||||
.iter()
|
||||
.map(|&p| Extension {
|
||||
name: unsafe { CStr::from_ptr(p) },
|
||||
version: 0,
|
||||
})
|
||||
// filter out extensions that are already enabled
|
||||
.filter(|ext| {
|
||||
!enabled_extensions
|
||||
.iter()
|
||||
.any(|enabled| enabled.name == ext.name)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// filter out extensions that aren't available, and log a warning for them
|
||||
let display_extensions = required_extensions.extract_if(.., is_extension_available);
|
||||
|
||||
enabled_extensions.extend(display_extensions);
|
||||
extensions.extend(required_extensions);
|
||||
}
|
||||
|
||||
// all extensions remaining in `extensions` at this point are unsupported,
|
||||
// and were requested by the user or are required by the display handle
|
||||
let unsupported_extensions = HashSet::from_iter(extensions);
|
||||
let out_extensions = HashSet::from_iter(enabled_extensions);
|
||||
|
||||
Ok((out_extensions, unsupported_extensions))
|
||||
}
|
||||
}
|
||||
|
||||
fn get_layers<'a>(
|
||||
/// returns a list of enabled, or a tuple of enabled and unsupported but requested layers.
|
||||
pub(crate) fn get_layers<'a>(
|
||||
entry: &ash::Entry,
|
||||
wants_layers: impl Iterator<Item = &'a CStr> + 'a,
|
||||
wants_layers: Vec<&'a CStr>,
|
||||
) -> core::result::Result<Vec<&'a CStr>, (Vec<&'a CStr>, Vec<&'a CStr>)> {
|
||||
unsafe {
|
||||
let wants_layers = wants_layers.collect::<Vec<_>>();
|
||||
let Ok(available_layers) = entry.enumerate_instance_layer_properties() else {
|
||||
return Err((vec![], wants_layers));
|
||||
};
|
||||
|
||||
let available_layers = entry
|
||||
.enumerate_instance_layer_properties()
|
||||
.map_err(|_| (Vec::<&'a CStr>::new(), wants_layers.clone()))?;
|
||||
let available_layer_names = available_layers
|
||||
let Ok(available_layer_names) = available_layers
|
||||
.iter()
|
||||
.map(|layer| layer.layer_name_as_c_str())
|
||||
.collect::<core::result::Result<BTreeSet<_>, _>>()
|
||||
.map_err(|_| (Vec::<&'a CStr>::new(), wants_layers.clone()))?;
|
||||
else {
|
||||
return Err((vec![], wants_layers));
|
||||
};
|
||||
|
||||
tracing::debug!(
|
||||
"Available layers: {:?}",
|
||||
|
|
@ -655,22 +671,21 @@ impl DeviceBuilder {
|
|||
.collect::<Vec<_>>()
|
||||
);
|
||||
|
||||
let mut out_layers = Vec::new();
|
||||
let mut enabled_layers = Vec::new();
|
||||
let mut unsupported_layers = Vec::new();
|
||||
|
||||
for layer in wants_layers {
|
||||
if available_layer_names.contains(&layer) {
|
||||
out_layers.push(layer);
|
||||
enabled_layers.push(layer);
|
||||
} else {
|
||||
unsupported_layers.push(layer);
|
||||
}
|
||||
}
|
||||
|
||||
if !unsupported_layers.is_empty() {
|
||||
Err((out_layers, unsupported_layers))
|
||||
Err((enabled_layers, unsupported_layers))
|
||||
} else {
|
||||
Ok(out_layers)
|
||||
}
|
||||
Ok(enabled_layers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -733,92 +748,18 @@ impl Device {
|
|||
})
|
||||
}
|
||||
pub fn new_from_desc(desc: DeviceDesc) -> crate::Result<Self> {
|
||||
tracing::debug!("creating new device with: {desc:#?}");
|
||||
let entry = unsafe { ash::Entry::load()? };
|
||||
|
||||
let app_name = desc
|
||||
.app_name
|
||||
.and_then(|name| CString::new(name).ok())
|
||||
.unwrap_or(c"ShooterGame".to_owned());
|
||||
|
||||
let app_info = vk::ApplicationInfo::default()
|
||||
.api_version(desc.features.version)
|
||||
.application_name(&app_name)
|
||||
.application_version(desc.app_version)
|
||||
.engine_name(c"VidyaEngine")
|
||||
.engine_version(vk::make_api_version(0, 0, 1, 0));
|
||||
|
||||
let mut validation_info =
|
||||
vk::LayerSettingsCreateInfoEXT::default().settings(desc.layer_settings);
|
||||
|
||||
let extra_instance_extensions = [
|
||||
make_extention!(ext::debug_utils as 1),
|
||||
#[cfg(debug_assertions)]
|
||||
make_extention!(ext::layer_settings),
|
||||
];
|
||||
|
||||
let layers = DeviceBuilder::get_layers(&entry, desc.layers.iter().cloned()).unwrap();
|
||||
|
||||
let (extensions, unsupported_extensions) = DeviceBuilder::get_extensions(
|
||||
&entry,
|
||||
&layers,
|
||||
desc.instance_extensions
|
||||
let instance = Instance::new(&crate::instance::InstanceDesc {
|
||||
app_name: desc.app_name,
|
||||
app_version: desc.app_version,
|
||||
instance_extensions: &desc
|
||||
.instance_extensions
|
||||
.iter()
|
||||
.cloned()
|
||||
.chain(extra_instance_extensions),
|
||||
desc.display_handle,
|
||||
)?;
|
||||
|
||||
if !unsupported_extensions.is_empty() {
|
||||
tracing::error!(
|
||||
"extensions were requested but not supported by instance: {:?}",
|
||||
unsupported_extensions
|
||||
);
|
||||
}
|
||||
|
||||
let layers = VkNameList::from_strs(&layers);
|
||||
let extensions = crate::util::CStringList::from_iter(extensions.iter().map(|ext| ext.name));
|
||||
|
||||
let create_info = vk::InstanceCreateInfo::default()
|
||||
.application_info(&app_info)
|
||||
.enabled_extension_names(&extensions.strings)
|
||||
.enabled_layer_names(&layers.names)
|
||||
.push_next(&mut validation_info);
|
||||
|
||||
tracing::debug!(
|
||||
"Creating instance:\napp_info: {app_info:#?}\ncreate_info: {create_info:#?}"
|
||||
);
|
||||
|
||||
let instance = unsafe { entry.create_instance(&create_info, None)? };
|
||||
|
||||
let debug_utils = {
|
||||
let debug_info = vk::DebugUtilsMessengerCreateInfoEXT::default()
|
||||
.message_severity(
|
||||
vk::DebugUtilsMessageSeverityFlagsEXT::ERROR
|
||||
| vk::DebugUtilsMessageSeverityFlagsEXT::WARNING
|
||||
| vk::DebugUtilsMessageSeverityFlagsEXT::INFO,
|
||||
)
|
||||
.message_type(
|
||||
vk::DebugUtilsMessageTypeFlagsEXT::GENERAL
|
||||
| vk::DebugUtilsMessageTypeFlagsEXT::VALIDATION
|
||||
| vk::DebugUtilsMessageTypeFlagsEXT::PERFORMANCE,
|
||||
)
|
||||
.pfn_user_callback(Some(crate::debug::debug_callback));
|
||||
|
||||
let instance = ext::debug_utils::Instance::new(&entry, &instance);
|
||||
let messenger = unsafe { instance.create_debug_utils_messenger(&debug_info, None)? };
|
||||
|
||||
crate::DebugUtils {
|
||||
instance,
|
||||
messenger,
|
||||
}
|
||||
};
|
||||
|
||||
let instance = Arc::new(Instance {
|
||||
raw: instance,
|
||||
_debug_utils: debug_utils,
|
||||
entry,
|
||||
});
|
||||
.map(|ext| ext.name)
|
||||
.collect::<Vec<_>>(),
|
||||
layers: desc.layers,
|
||||
layer_settings: desc.layer_settings,
|
||||
display_handle: desc.display_handle,
|
||||
})?;
|
||||
|
||||
let mut features = desc.features.with_extension2(make_extention_properties(
|
||||
khr::swapchain::NAME,
|
||||
|
|
@ -836,7 +777,7 @@ impl Device {
|
|||
// additionally, pdev would have to be derived from a device and not a scoring function.
|
||||
|
||||
let pdev = DeviceBuilder::choose_physical_device(
|
||||
&instance,
|
||||
&instance.inner,
|
||||
desc.display_handle,
|
||||
&features,
|
||||
vec![Box::new(
|
||||
|
|
@ -845,13 +786,13 @@ impl Device {
|
|||
)?;
|
||||
|
||||
tracing::trace!("pdev: {pdev:?}");
|
||||
let device = Device::new(instance.clone(), pdev, features)?;
|
||||
let device = Device::new(instance.inner.clone(), pdev, features)?;
|
||||
|
||||
Ok(device)
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
instance: Arc<Instance>,
|
||||
instance: Arc<InstanceInner>,
|
||||
physical: PhysicalDevice,
|
||||
mut features: crate::PhysicalDeviceFeatures,
|
||||
) -> VkResult<Self> {
|
||||
|
|
@ -953,7 +894,7 @@ impl Device {
|
|||
pub fn dev(&self) -> &ash::Device {
|
||||
&self.0.device
|
||||
}
|
||||
pub fn instance(&self) -> &Arc<Instance> {
|
||||
pub fn instance(&self) -> &Arc<InstanceInner> {
|
||||
&self.0.instance
|
||||
}
|
||||
pub fn swapchain(&self) -> &khr::swapchain::Device {
|
||||
|
|
|
|||
|
|
@ -1 +1,172 @@
|
|||
use std::{
|
||||
ffi::{CStr, CString},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use ash::{Entry, ext, vk};
|
||||
use raw_window_handle::RawDisplayHandle;
|
||||
|
||||
use crate::{
|
||||
device::{Extension, get_extensions, get_layers},
|
||||
make_extension,
|
||||
};
|
||||
|
||||
pub struct DebugUtilsCreateInfo {
|
||||
pub severity: vk::DebugUtilsMessageSeverityFlagsEXT,
|
||||
pub message_type: vk::DebugUtilsMessageTypeFlagsEXT,
|
||||
}
|
||||
|
||||
pub struct InstanceInner {
|
||||
pub raw: ash::Instance,
|
||||
pub entry: Entry,
|
||||
pub(crate) _debug_utils: DebugUtils,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Instance {
|
||||
pub(crate) inner: Arc<InstanceInner>,
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for Instance {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("Instance")
|
||||
.field("raw", &self.inner.raw.handle())
|
||||
.finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct InstanceDesc<'a> {
|
||||
pub app_name: Option<&'a str>,
|
||||
pub app_version: u32,
|
||||
pub instance_extensions: &'a [&'a CStr],
|
||||
pub layer_settings: &'a [vk::LayerSettingEXT<'a>],
|
||||
pub layers: &'a [&'a CStr],
|
||||
pub display_handle: Option<RawDisplayHandle>,
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
pub fn new<'a>(desc: &InstanceDesc<'a>) -> crate::Result<Self> {
|
||||
let entry = unsafe { ash::Entry::load()? };
|
||||
|
||||
let app_name = desc
|
||||
.app_name
|
||||
.and_then(|name| CString::new(name).ok())
|
||||
.unwrap_or(c"ShooterGame".to_owned());
|
||||
|
||||
let version =
|
||||
unsafe { entry.try_enumerate_instance_version()? }.unwrap_or(vk::API_VERSION_1_0);
|
||||
|
||||
let app_info = vk::ApplicationInfo::default()
|
||||
.api_version(if version < vk::API_VERSION_1_1 {
|
||||
vk::API_VERSION_1_0
|
||||
} else {
|
||||
// ash doesn't support 1.4 yet
|
||||
vk::API_VERSION_1_3
|
||||
})
|
||||
.application_name(&app_name)
|
||||
.application_version(desc.app_version)
|
||||
.engine_name(c"Bevy Engine")
|
||||
.engine_version(vk::make_api_version(0, 0, 1, 0));
|
||||
|
||||
let mut validation_info =
|
||||
vk::LayerSettingsCreateInfoEXT::default().settings(desc.layer_settings);
|
||||
|
||||
let layers = match get_layers(&entry, desc.layers.to_vec()) {
|
||||
Ok(layers) => layers,
|
||||
Err((supported, unsupported)) => {
|
||||
tracing::error!(
|
||||
"Some requested layers were not supported by instance:\nSupported: {:?}\nUnsupported: {:?}",
|
||||
supported,
|
||||
unsupported
|
||||
);
|
||||
supported
|
||||
}
|
||||
};
|
||||
|
||||
let mut requested_extensions = desc
|
||||
.instance_extensions
|
||||
.iter()
|
||||
.map(|name| Extension { name, version: 0 })
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
requested_extensions.push(make_extension!(ext::debug_utils as 1));
|
||||
#[cfg(debug_assertions)]
|
||||
requested_extensions.push(make_extension!(ext::layer_settings));
|
||||
|
||||
let (extensions, unsupported_extensions) =
|
||||
get_extensions(&entry, &layers, requested_extensions, desc.display_handle)?;
|
||||
|
||||
if !unsupported_extensions.is_empty() {
|
||||
tracing::error!(
|
||||
"extensions were requested but not supported by instance: {:?}",
|
||||
unsupported_extensions
|
||||
);
|
||||
}
|
||||
|
||||
let layers = layers
|
||||
.iter()
|
||||
.map(|layer| layer.as_ptr())
|
||||
.collect::<Vec<_>>();
|
||||
let extensions = extensions
|
||||
.iter()
|
||||
.map(|ext| ext.name.as_ptr())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let create_info = vk::InstanceCreateInfo::default()
|
||||
.application_info(&app_info)
|
||||
.enabled_extension_names(&extensions)
|
||||
.enabled_layer_names(&layers)
|
||||
.push_next(&mut validation_info);
|
||||
|
||||
tracing::debug!(
|
||||
"Creating instance:\napp_info: {app_info:#?}\ncreate_info: {create_info:#?}"
|
||||
);
|
||||
|
||||
let instance = unsafe { entry.create_instance(&create_info, None)? };
|
||||
|
||||
let debug_utils = {
|
||||
let debug_info = vk::DebugUtilsMessengerCreateInfoEXT::default()
|
||||
.message_severity(
|
||||
vk::DebugUtilsMessageSeverityFlagsEXT::ERROR
|
||||
| vk::DebugUtilsMessageSeverityFlagsEXT::WARNING
|
||||
| vk::DebugUtilsMessageSeverityFlagsEXT::INFO,
|
||||
)
|
||||
.message_type(
|
||||
vk::DebugUtilsMessageTypeFlagsEXT::GENERAL
|
||||
| vk::DebugUtilsMessageTypeFlagsEXT::VALIDATION
|
||||
| vk::DebugUtilsMessageTypeFlagsEXT::PERFORMANCE,
|
||||
)
|
||||
.pfn_user_callback(Some(crate::debug::debug_callback));
|
||||
|
||||
let instance = ext::debug_utils::Instance::new(&entry, &instance);
|
||||
let messenger = unsafe { instance.create_debug_utils_messenger(&debug_info, None)? };
|
||||
|
||||
crate::DebugUtils {
|
||||
instance,
|
||||
messenger,
|
||||
}
|
||||
};
|
||||
|
||||
let instance = Arc::new(InstanceInner {
|
||||
raw: instance,
|
||||
_debug_utils: debug_utils,
|
||||
entry,
|
||||
});
|
||||
|
||||
Ok(Self { inner: instance })
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct DebugUtils {
|
||||
pub instance: ext::debug_utils::Instance,
|
||||
pub messenger: vk::DebugUtilsMessengerEXT,
|
||||
}
|
||||
|
||||
impl Drop for DebugUtils {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
self.instance
|
||||
.destroy_debug_utils_messenger(self.messenger, None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -435,30 +435,8 @@ pub struct PhysicalDevice {
|
|||
properties: PhysicalDeviceProperties,
|
||||
}
|
||||
|
||||
struct DebugUtils {
|
||||
instance: ext::debug_utils::Instance,
|
||||
messenger: vk::DebugUtilsMessengerEXT,
|
||||
}
|
||||
|
||||
impl Drop for DebugUtils {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
self.instance
|
||||
.destroy_debug_utils_messenger(self.messenger, None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DebugUtilsCreateInfo {
|
||||
pub severity: vk::DebugUtilsMessageSeverityFlagsEXT,
|
||||
pub message_type: vk::DebugUtilsMessageTypeFlagsEXT,
|
||||
}
|
||||
|
||||
pub struct Instance {
|
||||
entry: Entry,
|
||||
raw: ash::Instance,
|
||||
_debug_utils: DebugUtils,
|
||||
}
|
||||
pub(crate) use instance::DebugUtils;
|
||||
pub use instance::{DebugUtilsCreateInfo, Instance};
|
||||
|
||||
pub struct SamplerCache {
|
||||
device: Device,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
|
|||
use crate::{
|
||||
Instance, Result, define_device_owned_handle,
|
||||
device::{Device, DeviceOwned},
|
||||
images, sync,
|
||||
images,
|
||||
instance::InstanceInner,
|
||||
sync,
|
||||
util::RawMutexGuard,
|
||||
};
|
||||
|
||||
|
|
@ -40,7 +42,7 @@ impl Drop for Surface {
|
|||
|
||||
impl Surface {
|
||||
#[allow(dead_code)]
|
||||
pub fn headless(instance: &Arc<Instance>) -> Result<Self> {
|
||||
pub fn headless(instance: &Arc<InstanceInner>) -> Result<Self> {
|
||||
let headless_instance =
|
||||
ash::ext::headless_surface::Instance::new(&instance.entry, &instance.raw);
|
||||
let functor = khr::surface::Instance::new(&instance.entry, &instance.raw);
|
||||
|
|
@ -67,7 +69,7 @@ impl Surface {
|
|||
/// was created with the appropriate platform-specific surface extensions
|
||||
/// enabled.
|
||||
pub unsafe fn new_from_raw_window_handle(
|
||||
instance: &Arc<Instance>,
|
||||
instance: &Arc<InstanceInner>,
|
||||
display_handle: RawDisplayHandle,
|
||||
window_handle: RawWindowHandle,
|
||||
) -> Result<Self> {
|
||||
|
|
@ -704,7 +706,7 @@ impl WindowSurface {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::device;
|
||||
use crate::make_extension;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
|
@ -712,14 +714,8 @@ mod tests {
|
|||
let device = Device::new_from_default_desc(
|
||||
None,
|
||||
&[
|
||||
device::Extension {
|
||||
name: "VK_EXT_headless_surface",
|
||||
version: ash::ext::headless_surface::SPEC_VERSION,
|
||||
},
|
||||
device::Extension {
|
||||
name: "VK_KHR_surface",
|
||||
version: ash::khr::surface::SPEC_VERSION,
|
||||
},
|
||||
make_extension!(ash::ext::headless_surface),
|
||||
make_extension!(ash::khr::surface),
|
||||
],
|
||||
)?;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue