Skip to content

Allow enabling additional vulkan extensions in Adapter::open and Instance::init #7829

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ Bottom level categories:
- Add support for [quad operations](https://www.w3.org/TR/WGSL/#quad-builtin-functions) (requires `SUBGROUP` feature to be enabled). By @dzamkov and @valaphee in [#7683](https://github.com/gfx-rs/wgpu/pull/7683).
- Add support for `atomicCompareExchangeWeak` in HLSL and GLSL backends. By @cryvosh in [#7658](https://github.com/gfx-rs/wgpu/pull/7658)

#### 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
Expand Down
42 changes: 33 additions & 9 deletions wgpu-hal/src/vulkan/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2271,25 +2271,36 @@ 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<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(
&mut enabled_extensions,
&mut enabled_phd_features,
&mut family_infos,
&mut pre_info,
)
}

let str_pointers = enabled_extensions
.iter()
Expand All @@ -2299,7 +2310,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);
Expand Down Expand Up @@ -2335,6 +2346,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,
Expand Down
64 changes: 42 additions & 22 deletions wgpu-hal/src/vulkan/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -585,27 +585,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.
unsafe fn init_with_callback(
desc: &crate::InstanceDescriptor,
callback: Option<super::CreateInstanceCallback>,
) -> Result<Self, crate::InstanceError> {
profiling::scope!("Init Vulkan Backend");

let entry = unsafe {
Expand Down Expand Up @@ -654,7 +646,12 @@ 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(&mut extensions, &mut create_info, &entry)
}

let instance_layers = {
profiling::scope!("vkEnumerateInstanceLayerProperties");
Expand Down Expand Up @@ -814,7 +811,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()])
Expand Down Expand Up @@ -876,6 +873,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,
Expand Down
16 changes: 16 additions & 0 deletions wgpu-hal/src/vulkan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1500,3 +1500,19 @@ struct RawTlasInstance {
shader_binding_table_record_offset_and_flags: u32,
acceleration_structure_reference: u64,
}

pub type CreateDeviceCallback<'a> = &'a dyn Fn(
&mut Vec<&'static CStr>,
&mut PhysicalDeviceFeatures,
&mut Vec<vk::DeviceQueueCreateInfo>,
&mut vk::DeviceCreateInfo,
);

pub type CreateInstanceCallback<'a> = &'a dyn Fn(
// extensions
&mut Vec<&'static CStr>,
// create info
&mut vk::InstanceCreateInfo,
// The wgpu loaded entry
&ash::Entry,
);
Loading