diff --git a/blade-graphics/src/vulkan/descriptor.rs b/blade-graphics/src/vulkan/descriptor.rs index e23d6984..e2da0b01 100644 --- a/blade-graphics/src/vulkan/descriptor.rs +++ b/blade-graphics/src/vulkan/descriptor.rs @@ -46,10 +46,13 @@ impl super::Device { max_inline_uniform_block_bindings: max_sets, ..Default::default() }; + let descriptor_pool_info = vk::DescriptorPoolCreateInfo::default() .max_sets(max_sets) + .flags(self.workarounds.extra_descriptor_pool_create_flags) .pool_sizes(&descriptor_sizes) .push_next(&mut inline_uniform_block_info); + unsafe { self.core .create_descriptor_pool(&descriptor_pool_info, None) diff --git a/blade-graphics/src/vulkan/init.rs b/blade-graphics/src/vulkan/init.rs index fe559bb9..37aa3520 100644 --- a/blade-graphics/src/vulkan/init.rs +++ b/blade-graphics/src/vulkan/init.rs @@ -22,6 +22,15 @@ const REQUIRED_DEVICE_EXTENSIONS: &[&ffi::CStr] = &[ vk::KHR_DYNAMIC_RENDERING_NAME, ]; +#[derive(Debug)] +#[allow(unused)] +struct SystemBugs { + /// https://gitlab.freedesktop.org/mesa/mesa/-/issues/4688 + intel_unable_to_present: bool, + /// https://github.com/kvark/blade/issues/117 + intel_fix_descriptor_pool_leak: bool, +} + #[derive(Debug)] struct AdapterCapabilities { api_version: u32, @@ -32,12 +41,7 @@ struct AdapterCapabilities { buffer_marker: bool, shader_info: bool, full_screen_exclusive: bool, -} - -#[derive(Debug)] -struct SystemBugs { - /// https://gitlab.freedesktop.org/mesa/mesa/-/issues/4688 - intel_unable_to_present: bool, + bugs: SystemBugs, } // See https://github.com/canonical/nvidia-prime/blob/587c5012be9dddcc17ab4d958f10a24fa3342b4d/prime-select#L56 @@ -52,7 +56,6 @@ unsafe fn inspect_adapter( phd: vk::PhysicalDevice, instance: &super::Instance, driver_api_version: u32, - bugs: &SystemBugs, surface: Option, ) -> Option { let supported_extension_properties = instance @@ -102,6 +105,16 @@ unsafe fn inspect_adapter( return None; } + let vendor_id = properties2_khr.properties.vendor_id; + + let bugs = SystemBugs { + //Note: this is somewhat broad across X11/Wayland and different drivers. + // It could be narrower, but at the end of the day if the user forced Prime + // for GLX it should be safe to assume they want it for Vulkan as well. + intel_unable_to_present: is_nvidia_prime_forced() && vendor_id == db::intel::VENDOR, + intel_fix_descriptor_pool_leak: cfg!(windows) && vendor_id == db::intel::VENDOR, + }; + let queue_family_index = 0; //TODO if let Some(surface) = surface { let khr = instance.surface.as_ref()?; @@ -109,8 +122,7 @@ unsafe fn inspect_adapter( log::warn!("Rejected for not presenting to the window surface"); return None; } - if bugs.intel_unable_to_present && properties2_khr.properties.vendor_id == db::intel::VENDOR - { + if bugs.intel_unable_to_present { log::warn!("Rejecting Intel for not presenting when Nvidia is present (on Linux)"); return None; } @@ -227,6 +239,7 @@ unsafe fn inspect_adapter( buffer_marker, shader_info, full_screen_exclusive, + bugs, }) } @@ -346,14 +359,6 @@ impl super::Context { entry.create_instance(&create_info, None).unwrap() }; - let bugs = SystemBugs { - //Note: this is somewhat broad across X11/Wayland and different drivers. - // It could be narrower, but at the end of the day if the user forced Prime - // for GLX it should be safe to assume they want it for Vulkan as well. - intel_unable_to_present: is_nvidia_prime_forced(), - }; - log::debug!("Bugs {:#?}", bugs); - let vk_surface = surface_handles.map(|(wh, dh)| { ash_window::create_surface(&entry, &core_instance, dh.as_raw(), wh.as_raw(), None) .unwrap() @@ -376,7 +381,7 @@ impl super::Context { let (physical_device, capabilities) = physical_devices .into_iter() .find_map(|phd| { - inspect_adapter(phd, &instance, driver_api_version, &bugs, vk_surface) + inspect_adapter(phd, &instance, driver_api_version, vk_surface) .map(|caps| (phd, caps)) }) .ok_or(crate::NotSupportedError)?; @@ -520,6 +525,14 @@ impl super::Context { extra_sync_dst_access: vk::AccessFlags::TRANSFER_WRITE | vk::AccessFlags::TRANSFER_READ | vk::AccessFlags::ACCELERATION_STRUCTURE_WRITE_KHR, + extra_descriptor_pool_create_flags: if capabilities + .bugs + .intel_fix_descriptor_pool_leak + { + vk::DescriptorPoolCreateFlags::FREE_DESCRIPTOR_SET + } else { + vk::DescriptorPoolCreateFlags::empty() + }, }, }; diff --git a/blade-graphics/src/vulkan/mod.rs b/blade-graphics/src/vulkan/mod.rs index 1ebfcd8d..7434721e 100644 --- a/blade-graphics/src/vulkan/mod.rs +++ b/blade-graphics/src/vulkan/mod.rs @@ -23,6 +23,7 @@ struct RayTracingDevice { struct Workarounds { extra_sync_src_access: vk::AccessFlags, extra_sync_dst_access: vk::AccessFlags, + extra_descriptor_pool_create_flags: vk::DescriptorPoolCreateFlags, } #[derive(Clone)]