Describe the bug
I am helping conda-forge in integrating other directories for ICDs so that we can have:
- THe system ICDs
- The conda-forge installed ICDs
However, the problem is that the ubuntu ICD loader reads:
/usr/share/vulkan/icd.d $ cat intel_icd.json
{
"ICD": {
"api_version": "1.4.318",
"library_path": "libvulkan_intel.so"
},
"file_format_version": "1.0.1"
}
With conda installing its own libvulkan_intel.so this will eventually resolve to conda's version. My claim is that we can't do anything about this other than ask ubuntu to use the full path for ICD libraries (which they likely won't do)
Conda will also install its own icd.json file, to its own ${CONDA_PREFIX}/share/vulkan/icd.d, and thus the same library will appear twice.
I think we should filter it out, just to keep the output less confusing.
Environment (please complete the following information):
- OS: ubuntu 24 + conda(-forge)
- Bitdepth: 64bit
- GPU: intel (well anything really)
- Graphics Driver: mesa 26
- SDK or header version if building from repo: 1.4.357.0
- Enabled layers:
To Reproduce
diff --git a/loader/loader.c b/loader/loader.c
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -2145,6 +2145,31 @@
goto out;
}
+ // Skip a driver we have already scanned. Two different manifests can name the same
+ // library: a distribution manifest using a bare "library_path" resolved through the
+ // dynamic linker search path, and one using an absolute path, can both end up at the
+ // same file. The duplicate checks elsewhere in the loader only compare path strings,
+ // so nothing catches this and the driver is scanned twice, which reports every
+ // physical device it owns twice from vkEnumeratePhysicalDevices.
+ //
+ // dlopen/LoadLibrary returns the same handle for an object that is already loaded, so
+ // comparing handles identifies the duplicate exactly, without resolving paths or
+ // stat()ing anything. Keep the entry already in the list: the search order puts the
+ // more specific manifest first.
+ for (uint32_t i = 0; i < icd_tramp_list->count; i++) {
+ if (icd_tramp_list->scanned_list[i].handle == handle) {
+ loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
+ "loader_scanned_icd_add: Driver %s is the same library as already loaded driver %s, skipping duplicate",
+ filename, icd_tramp_list->scanned_list[i].lib_name);
+ // Release the reference the open above took; the existing entry owns the one
+ // that loader_scanned_icd_clear will release.
+ loader_platform_close_library(handle);
+ handle = NULL;
+ res = VK_SUCCESS;
+ goto out;
+ }
+ }
+
// Try to load the driver's exported vk_icdNegotiateLoaderICDInterfaceVersion
fp_negotiate_icd_version = loader_platform_get_proc_address(handle, "vk_icdNegotiateLoaderICDInterfaceVersion");
VK_LOADER_DEBUG output
Attach output when running with the environment variable VK_LOADER_DEBUG=all
Additional context
Describe the bug
I am helping conda-forge in integrating other directories for ICDs so that we can have:
However, the problem is that the ubuntu ICD loader reads:
With conda installing its own
libvulkan_intel.sothis will eventually resolve to conda's version. My claim is that we can't do anything about this other than ask ubuntu to use the full path for ICD libraries (which they likely won't do)Conda will also install its own icd.json file, to its own
${CONDA_PREFIX}/share/vulkan/icd.d, and thus the same library will appear twice.I think we should filter it out, just to keep the output less confusing.
Environment (please complete the following information):
To Reproduce
VK_LOADER_DEBUG output
Attach output when running with the environment variable VK_LOADER_DEBUG=all
Additional context