mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
Allow enabling additional vulkan extensions in Adapter::open and Instance::init (#7829)
Co-authored-by: Connor Fitzgerald <connorwadefitzgerald@gmail.com>
This commit is contained in:
parent
208fe4c23d
commit
0d61648eeb
@ -59,6 +59,10 @@ Bottom level categories:
|
||||
- Add acceleration structure limits. By @Vecvec in [#7845](https://github.com/gfx-rs/wgpu/pull/7845).
|
||||
- Add support for clip-distances feature for Vulkan and GL backends. By @dzamkov in [#7730](https://github.com/gfx-rs/wgpu/pull/7730)
|
||||
|
||||
#### Vulkan
|
||||
|
||||
- Add ways to initialise the instance and open the adapter with callbacks to add extensions. By @Vecvec in [#7829](https://github.com/gfx-rs/wgpu/pull/7829).
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
#### General
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use alloc::{borrow::ToOwned as _, collections::BTreeMap, sync::Arc, vec::Vec};
|
||||
use core::ffi::CStr;
|
||||
use alloc::{borrow::ToOwned as _, boxed::Box, collections::BTreeMap, sync::Arc, vec::Vec};
|
||||
use core::{ffi::CStr, marker::PhantomData};
|
||||
|
||||
use ash::{ext, google, khr, vk};
|
||||
use parking_lot::Mutex;
|
||||
@ -2287,25 +2287,37 @@ impl super::Adapter {
|
||||
pub fn texture_format_as_raw(&self, texture_format: wgt::TextureFormat) -> vk::Format {
|
||||
self.private_caps.map_texture_format(texture_format)
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Adapter for super::Adapter {
|
||||
type A = super::Api;
|
||||
|
||||
unsafe fn open(
|
||||
/// # Safety:
|
||||
/// - Same as `open` plus
|
||||
/// - The callback may not change anything that the device does not support.
|
||||
/// - The callback may not remove features.
|
||||
pub unsafe fn open_with_callback<'a>(
|
||||
&self,
|
||||
features: wgt::Features,
|
||||
_limits: &wgt::Limits,
|
||||
memory_hints: &wgt::MemoryHints,
|
||||
callback: Option<Box<super::CreateDeviceCallback<'a>>>,
|
||||
) -> Result<crate::OpenDevice<super::Api>, crate::DeviceError> {
|
||||
let enabled_extensions = self.required_device_extensions(features);
|
||||
let mut enabled_extensions = self.required_device_extensions(features);
|
||||
let mut enabled_phd_features = self.physical_device_features(&enabled_extensions, features);
|
||||
|
||||
let family_index = 0; //TODO
|
||||
let family_info = vk::DeviceQueueCreateInfo::default()
|
||||
.queue_family_index(family_index)
|
||||
.queue_priorities(&[1.0]);
|
||||
let family_infos = [family_info];
|
||||
let mut family_infos = Vec::from([family_info]);
|
||||
|
||||
let mut pre_info = vk::DeviceCreateInfo::default();
|
||||
|
||||
if let Some(callback) = callback {
|
||||
callback(super::CreateDeviceCallbackArgs {
|
||||
extensions: &mut enabled_extensions,
|
||||
device_features: &mut enabled_phd_features,
|
||||
queue_create_infos: &mut family_infos,
|
||||
create_info: &mut pre_info,
|
||||
_phantom: PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
let str_pointers = enabled_extensions
|
||||
.iter()
|
||||
@ -2315,7 +2327,7 @@ impl crate::Adapter for super::Adapter {
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let pre_info = vk::DeviceCreateInfo::default()
|
||||
let pre_info = pre_info
|
||||
.queue_create_infos(&family_infos)
|
||||
.enabled_extension_names(&str_pointers);
|
||||
let info = enabled_phd_features.add_to_device_create(pre_info);
|
||||
@ -2351,6 +2363,19 @@ impl crate::Adapter for super::Adapter {
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Adapter for super::Adapter {
|
||||
type A = super::Api;
|
||||
|
||||
unsafe fn open(
|
||||
&self,
|
||||
features: wgt::Features,
|
||||
_limits: &wgt::Limits,
|
||||
memory_hints: &wgt::MemoryHints,
|
||||
) -> Result<crate::OpenDevice<super::Api>, crate::DeviceError> {
|
||||
unsafe { self.open_with_callback(features, memory_hints, None) }
|
||||
}
|
||||
|
||||
unsafe fn texture_format_capabilities(
|
||||
&self,
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use alloc::{borrow::ToOwned as _, boxed::Box, ffi::CString, string::String, sync::Arc, vec::Vec};
|
||||
use core::{
|
||||
ffi::{c_void, CStr},
|
||||
marker::PhantomData,
|
||||
slice,
|
||||
str::FromStr,
|
||||
};
|
||||
@ -585,27 +586,19 @@ impl super::Instance {
|
||||
swapchain: RwLock::new(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for super::InstanceShared {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
// Keep du alive since destroy_instance may also log
|
||||
let _du = self.debug_utils.take().inspect(|du| {
|
||||
du.extension
|
||||
.destroy_debug_utils_messenger(du.messenger, None);
|
||||
});
|
||||
if self.drop_guard.is_none() {
|
||||
self.raw.destroy_instance(None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Instance for super::Instance {
|
||||
type A = super::Api;
|
||||
|
||||
unsafe fn init(desc: &crate::InstanceDescriptor) -> Result<Self, crate::InstanceError> {
|
||||
/// `Instance::init` but with a callback.
|
||||
/// If you want to add extensions, add the to the `Vec<'static CStr>` not the create info, otherwise
|
||||
/// it will be overwritten
|
||||
///
|
||||
/// # Safety:
|
||||
/// Same as `init` but additionally
|
||||
/// - Callback must not remove features.
|
||||
/// - Callback must not change anything to what the instance does not support.
|
||||
pub unsafe fn init_with_callback(
|
||||
desc: &crate::InstanceDescriptor,
|
||||
callback: Option<Box<super::CreateInstanceCallback>>,
|
||||
) -> Result<Self, crate::InstanceError> {
|
||||
profiling::scope!("Init Vulkan Backend");
|
||||
|
||||
let entry = unsafe {
|
||||
@ -654,7 +647,17 @@ impl crate::Instance for super::Instance {
|
||||
},
|
||||
);
|
||||
|
||||
let extensions = Self::desired_extensions(&entry, instance_api_version, desc.flags)?;
|
||||
let mut extensions = Self::desired_extensions(&entry, instance_api_version, desc.flags)?;
|
||||
let mut create_info = vk::InstanceCreateInfo::default();
|
||||
|
||||
if let Some(callback) = callback {
|
||||
callback(super::CreateInstanceCallbackArgs {
|
||||
extensions: &mut extensions,
|
||||
create_info: &mut create_info,
|
||||
entry: &entry,
|
||||
_phantom: PhantomData,
|
||||
});
|
||||
}
|
||||
|
||||
let instance_layers = {
|
||||
profiling::scope!("vkEnumerateInstanceLayerProperties");
|
||||
@ -814,7 +817,7 @@ impl crate::Instance for super::Instance {
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut create_info = vk::InstanceCreateInfo::default()
|
||||
create_info = create_info
|
||||
.flags(flags)
|
||||
.application_info(&app_info)
|
||||
.enabled_layer_names(&str_pointers[..layers.len()])
|
||||
@ -876,6 +879,29 @@ impl crate::Instance for super::Instance {
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for super::InstanceShared {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
// Keep du alive since destroy_instance may also log
|
||||
let _du = self.debug_utils.take().inspect(|du| {
|
||||
du.extension
|
||||
.destroy_debug_utils_messenger(du.messenger, None);
|
||||
});
|
||||
if self.drop_guard.is_none() {
|
||||
self.raw.destroy_instance(None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Instance for super::Instance {
|
||||
type A = super::Api;
|
||||
|
||||
unsafe fn init(desc: &crate::InstanceDescriptor) -> Result<Self, crate::InstanceError> {
|
||||
unsafe { Self::init_with_callback(desc, None) }
|
||||
}
|
||||
|
||||
unsafe fn create_surface(
|
||||
&self,
|
||||
|
||||
@ -36,7 +36,7 @@ mod semaphore_list;
|
||||
pub use adapter::PhysicalDeviceFeatures;
|
||||
|
||||
use alloc::{boxed::Box, ffi::CString, sync::Arc, vec::Vec};
|
||||
use core::{borrow::Borrow, ffi::CStr, fmt, mem, num::NonZeroU32};
|
||||
use core::{borrow::Borrow, ffi::CStr, fmt, marker::PhantomData, mem, num::NonZeroU32};
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use ash::{ext, khr, vk};
|
||||
@ -1500,3 +1500,65 @@ struct RawTlasInstance {
|
||||
shader_binding_table_record_offset_and_flags: u32,
|
||||
acceleration_structure_reference: u64,
|
||||
}
|
||||
|
||||
/// Arguments to the [`CreateDeviceCallback`].
|
||||
pub struct CreateDeviceCallbackArgs<'arg, 'pnext, 'this>
|
||||
where
|
||||
'this: 'pnext,
|
||||
{
|
||||
/// The extensions to enable for the device. You must not remove anything from this list,
|
||||
/// but you may add to it.
|
||||
pub extensions: &'arg mut Vec<&'static CStr>,
|
||||
/// The physical device features to enable. You may enable features, but must not disable any.
|
||||
pub device_features: &'arg mut PhysicalDeviceFeatures,
|
||||
/// The queue create infos for the device. You may add or modify queue create infos as needed.
|
||||
pub queue_create_infos: &'arg mut Vec<vk::DeviceQueueCreateInfo<'pnext>>,
|
||||
/// The create info for the device. You may add or modify things in the pnext chain, but
|
||||
/// do not turn features off. Additionally, do not add things to the list of extensions,
|
||||
/// or to the feature set, as all changes to that member will be overwritten.
|
||||
pub create_info: &'arg mut vk::DeviceCreateInfo<'pnext>,
|
||||
/// We need to have `'this` in the struct, so we can declare that all lifetimes coming from
|
||||
/// captures in the closure will live longer (and hence satisfy) `'pnext`. However, we
|
||||
/// don't actually directly use `'this`
|
||||
_phantom: PhantomData<&'this ()>,
|
||||
}
|
||||
|
||||
/// Callback to allow changing the vulkan device creation parameters.
|
||||
///
|
||||
/// # Safety:
|
||||
/// - If you want to add extensions, add the to the `Vec<'static CStr>` not the create info,
|
||||
/// as the create info value will be overwritten.
|
||||
/// - Callback must not remove features.
|
||||
/// - Callback must not change anything to what the instance does not support.
|
||||
pub type CreateDeviceCallback<'this> =
|
||||
dyn for<'arg, 'pnext> FnOnce(CreateDeviceCallbackArgs<'arg, 'pnext, 'this>) + 'this;
|
||||
|
||||
/// Arguments to the [`CreateInstanceCallback`].
|
||||
pub struct CreateInstanceCallbackArgs<'arg, 'pnext, 'this>
|
||||
where
|
||||
'this: 'pnext,
|
||||
{
|
||||
/// The extensions to enable for the instance. You must not remove anything from this list,
|
||||
/// but you may add to it.
|
||||
pub extensions: &'arg mut Vec<&'static CStr>,
|
||||
/// The create info for the instance. You may add or modify things in the pnext chain, but
|
||||
/// do not turn features off. Additionally, do not add things to the list of extensions,
|
||||
/// all changes to that member will be overwritten.
|
||||
pub create_info: &'arg mut vk::InstanceCreateInfo<'pnext>,
|
||||
/// Vulkan entry point.
|
||||
pub entry: &'arg ash::Entry,
|
||||
/// We need to have `'this` in the struct, so we can declare that all lifetimes coming from
|
||||
/// captures in the closure will live longer (and hence satisfy) `'pnext`. However, we
|
||||
/// don't actually directly use `'this`
|
||||
_phantom: PhantomData<&'this ()>,
|
||||
}
|
||||
|
||||
/// Callback to allow changing the vulkan instance creation parameters.
|
||||
///
|
||||
/// # Safety:
|
||||
/// - If you want to add extensions, add the to the `Vec<'static CStr>` not the create info,
|
||||
/// as the create info value will be overwritten.
|
||||
/// - Callback must not remove features.
|
||||
/// - Callback must not change anything to what the instance does not support.
|
||||
pub type CreateInstanceCallback<'this> =
|
||||
dyn for<'arg, 'pnext> FnOnce(CreateInstanceCallbackArgs<'arg, 'pnext, 'this>) + 'this;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user