vulkan: Optionally share one JSON manifest per driver between architectures

If the library_path is just a basename like `libvulkan_lvp.so`, then we
can share the same JSON manifest like `lvp_icd.json` between all of the
architectures, like we already do for Vulkan layers. The library will
be looked up in the dynamic linker's default search path in this case,
and in practice will be found in `${libdir}`. This is how the Mesa's
EGL driver and Vulkan layers work, how Mesa is packaged in Debian 13,
and also how the Nvidia proprietary driver works; it makes installation
simpler for distros, especially on multiarch systems like Debian and
the freedesktop.org SDK.

However, if we want a separate manifest per architecture in order to
be able to write the full path into it, we still need per-architecture
filename disambiguation like `lvp_icd.x86_64.json`.

We presumably still want a separate per architecture on Windows, because
the concept of a single monolithic `${libdir}` is less common there, and
it can also be helpful during development when setting `$VK_DRIVER_FILES`
to force the use of a specific driver installed in a non-default location.

Use the following parameter to passed to vk_icd_gen:
'--icd-lib-path', vulkan_icd_lib_path,
'--icd-filename', icd_file_name,
output : 'virtio_icd.' + vulkan_manifest_suffix,

and the output is passed by '--out', '@OUTPUT@',
so we can detect vulkan_manifest_per_architecture from the --out parameter in script.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/13745
Signed-off-by: Simon McVittie <smcv@collabora.com>
Co-authored-by: Yonggang Luo <luoyonggang@gmail.com>
Reviewed-by: Mel Henning <mhenning@darkrefraction.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Eric Engestrom <eric@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37314>
This commit is contained in:
Simon McVittie 2025-09-25 21:01:25 +08:00 committed by Marge Bot
parent 1ec7bc382d
commit b860ae309a
17 changed files with 107 additions and 47 deletions

View file

@ -2304,6 +2304,13 @@ else
vulkan_icd_lib_path = get_option('prefix') / get_option('libdir')
endif
vulkan_manifest_per_architecture = get_option('vulkan-manifest-per-architecture')
if vulkan_manifest_per_architecture
vulkan_manifest_suffix = '@0@.json'.format(host_machine.cpu())
else
vulkan_manifest_suffix = 'json'
endif
subdir('include')
subdir('bin')

View file

@ -286,6 +286,19 @@ option(
'Default: $datadir/vulkan/icd.d'
)
option(
'vulkan-manifest-per-architecture',
type : 'boolean',
value : true,
description : 'If true, Vulkan ICDs have a separate JSON manifest per ' +
'architecture, for example lvp_icd.x86_64.json. ' +
'(Recommended for non-default ${prefix}.) ' +
'If false, all architectures share a single JSON manifest, ' +
'for example lvp_icd.json, referencing the library by its ' +
'basename. ' +
'(Recommended for Unix OS distros installing into /usr.)'
)
option(
'moltenvk-dir',
type : 'string',

View file

@ -283,7 +283,8 @@ icd_command = [
prog_python, '@INPUT0@',
'--api-version', '1.4', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', vulkan_icd_lib_path / icd_file_name,
'--icd-lib-path', vulkan_icd_lib_path,
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
]
if with_platform_windows
@ -293,7 +294,7 @@ endif
radeon_icd = custom_target(
'radeon_icd',
input : [vk_icd_gen, vk_api_xml],
output : 'radeon_icd.@0@.json'.format(host_machine.cpu()),
output : 'radeon_icd.' + vulkan_manifest_suffix,
command : icd_command,
build_by_default : true,
install_dir : with_vulkan_icd_dir,
@ -310,7 +311,8 @@ _dev_icd = custom_target(
prog_python, '@INPUT0@',
'--api-version', '1.4', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', meson.current_build_dir() / icd_file_name,
'--icd-lib-path', meson.current_build_dir(),
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,

View file

@ -106,12 +106,13 @@ icd_file_name = libname_prefix + 'vulkan_asahi.' + libname_suffix
asahi_icd = custom_target(
input : [vk_icd_gen, vk_api_xml],
output : 'asahi_icd.@0@.json'.format(host_machine.cpu()),
output : 'asahi_icd.' + vulkan_manifest_suffix,
command : [
prog_python, '@INPUT0@',
'--api-version', '1.4', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', vulkan_icd_lib_path / icd_file_name,
'--icd-lib-path', vulkan_icd_lib_path,
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,
@ -128,7 +129,8 @@ custom_target(
prog_python, '@INPUT0@',
'--api-version', '1.4', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', meson.current_build_dir() / icd_file_name,
'--icd-lib-path', meson.current_build_dir(),
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,

View file

@ -127,12 +127,13 @@ icd_file_name = libname_prefix + 'vulkan_broadcom.' + libname_suffix
broadcom_icd = custom_target(
'broadcom_icd',
input : [vk_icd_gen, vk_api_xml],
output : 'broadcom_icd.@0@.json'.format(host_machine.cpu()),
output : 'broadcom_icd.' + vulkan_manifest_suffix,
command : [
prog_python, '@INPUT0@',
'--api-version', '1.3', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', vulkan_icd_lib_path / icd_file_name,
'--icd-lib-path', vulkan_icd_lib_path,
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,
@ -150,7 +151,8 @@ _dev_icd = custom_target(
prog_python, '@INPUT0@',
'--api-version', '1.3', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', meson.current_build_dir() / icd_file_name,
'--icd-lib-path', meson.current_build_dir(),
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,

View file

@ -228,12 +228,13 @@ icd_file_name = libname_prefix + 'vulkan_freedreno.' + libname_suffix
freedreno_icd = custom_target(
'freedreno_icd',
input : [vk_icd_gen, vk_api_xml],
output : 'freedreno_icd.@0@.json'.format(host_machine.cpu()),
output : 'freedreno_icd.' + vulkan_manifest_suffix,
command : [
prog_python, '@INPUT0@',
'--api-version', '1.4', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', vulkan_icd_lib_path / icd_file_name,
'--icd-lib-path', vulkan_icd_lib_path,
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,
@ -251,7 +252,8 @@ _dev_icd = custom_target(
prog_python, '@INPUT0@',
'--api-version', '1.4', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', meson.current_build_dir() / icd_file_name,
'--icd-lib-path', meson.current_build_dir(),
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,

View file

@ -24,7 +24,8 @@ icd_command = [
prog_python, '@INPUT0@',
'--api-version', '1.4', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', vulkan_icd_lib_path / icd_file_name,
'--icd-lib-path', vulkan_icd_lib_path,
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
]
if host_machine.system() == 'windows'
@ -34,7 +35,7 @@ endif
lvp_icd = custom_target(
'lvp_icd',
input : [vk_icd_gen, vk_api_xml],
output : 'lvp_icd.@0@.json'.format(host_machine.cpu()),
output : 'lvp_icd.' + vulkan_manifest_suffix,
command : icd_command,
build_by_default : true,
install_dir : with_vulkan_icd_dir,
@ -51,7 +52,8 @@ _dev_icd = custom_target(
prog_python, '@INPUT0@',
'--api-version', '1.4', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', meson.current_build_dir() / icd_file_name,
'--icd-lib-path', meson.current_build_dir(),
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,

View file

@ -66,7 +66,7 @@ icd_file_name = libname_prefix + 'vulkan_gfxstream.' + libname_suffix
gfxstream_icd = custom_target(
'gfxstream_vk_icd',
input: [vk_icd_gen, vk_api_xml],
output: 'gfxstream_vk_icd.@0@.json'.format(host_machine.cpu()),
output : 'gfxstream_vk_icd.' + vulkan_manifest_suffix,
command: [
prog_python,
'@INPUT0@',
@ -76,8 +76,10 @@ gfxstream_icd = custom_target(
'@INPUT1@',
'--sizeof-pointer',
sizeof_pointer,
'--lib-path',
vulkan_icd_lib_path / icd_file_name,
'--icd-lib-path',
vulkan_icd_lib_path,
'--icd-filename',
icd_file_name,
'--out',
'@OUTPUT@',
],
@ -100,8 +102,10 @@ _dev_icd = custom_target(
'@INPUT1@',
'--sizeof-pointer',
sizeof_pointer,
'--lib-path',
meson.current_build_dir() / icd_file_name,
'--icd-lib-path',
meson.current_build_dir(),
'--icd-filename',
icd_file_name,
'--out',
'@OUTPUT@',
],

View file

@ -144,12 +144,13 @@ icd_file_name = libname_prefix + 'vulkan_powervr_mesa.' + libname_suffix
powervr_mesa_icd = custom_target(
'powervr_mesa_icd',
input : [vk_icd_gen, vk_api_xml],
output : 'powervr_mesa_icd.@0@.json'.format(host_machine.cpu()),
output : 'powervr_mesa_icd.' + vulkan_manifest_suffix,
command : [
prog_python, '@INPUT0@',
'--api-version', '1.4', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', vulkan_icd_lib_path / icd_file_name,
'--icd-lib-path', vulkan_icd_lib_path,
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,
@ -166,7 +167,8 @@ _dev_icd = custom_target(
prog_python, '@INPUT0@',
'--api-version', '1.4', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', meson.current_build_dir() / icd_file_name,
'--icd-lib-path', meson.current_build_dir(),
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,

View file

@ -50,12 +50,13 @@ icd_file_name = libname_prefix + 'vulkan_intel.' + libname_suffix
intel_icd = custom_target(
'intel_icd',
input : [vk_icd_gen, vk_api_xml],
output : 'intel_icd.@0@.json'.format(host_machine.cpu()),
output : 'intel_icd.' + vulkan_manifest_suffix,
command : [
prog_python, '@INPUT0@',
'--api-version', '1.4', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', vulkan_icd_lib_path / icd_file_name,
'--icd-lib-path', vulkan_icd_lib_path,
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,
@ -73,7 +74,8 @@ _dev_icd = custom_target(
prog_python, '@INPUT0@',
'--api-version', '1.4', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', meson.current_build_dir() / icd_file_name,
'--icd-lib-path', meson.current_build_dir(),
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,

View file

@ -21,12 +21,13 @@ icd_file_name = libname_prefix + 'vulkan_intel_hasvk.' + libname_suffix
intel_hasvk_icd = custom_target(
'intel_hasvk_icd',
input : [vk_icd_gen, vk_api_xml],
output : 'intel_hasvk_icd.@0@.json'.format(host_machine.cpu()),
output : 'intel_hasvk_icd.' + vulkan_manifest_suffix,
command : [
prog_python, '@INPUT0@',
'--api-version', '1.3', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', vulkan_icd_lib_path / icd_file_name,
'--icd-lib-path', vulkan_icd_lib_path,
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,
@ -44,7 +45,8 @@ _dev_icd = custom_target(
prog_python, '@INPUT0@',
'--api-version', '1.3', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', meson.current_build_dir() / icd_file_name,
'--icd-lib-path', meson.current_build_dir(),
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,

View file

@ -177,14 +177,17 @@ libvulkan_kosmickrisp = shared_library(
install : true,
)
icd_file_name = libname_prefix + 'vulkan_kosmickrisp.' + libname_suffix
kosmickrisp_mesa_icd = custom_target(
'kosmickrisp_mesa_icd',
input : [vk_icd_gen, vk_api_xml],
output : 'kosmickrisp_mesa_icd.@0@.json'.format(host_machine.cpu()),
output : 'kosmickrisp_mesa_icd.' + vulkan_manifest_suffix,
command : [
prog_python, '@INPUT0@',
'--api-version', '1.3', '--xml', '@INPUT1@',
'--lib-path', get_option('prefix') / get_option('libdir') / 'libvulkan_kosmickrisp.dylib',
'--icd-lib-path', vulkan_icd_lib_path,
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,
@ -200,7 +203,8 @@ kosmickrisp_icd = custom_target(
command : [
prog_python, '@INPUT0@',
'--api-version', '1.3', '--xml', '@INPUT1@',
'--lib-path', meson.current_build_dir() / 'libvulkan_kosmickrisp.dylib',
'--icd-lib-path', meson.current_build_dir(),
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,

View file

@ -80,7 +80,8 @@ icd_command = [
prog_python, '@INPUT0@',
'--api-version', '1.1', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', vulkan_icd_lib_path / icd_file_name,
'--icd-lib-path', vulkan_icd_lib_path,
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
]
@ -88,7 +89,8 @@ icd_dev_command = [
prog_python, '@INPUT0@',
'--api-version', '1.1', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', join_paths(meson.current_build_dir(), icd_file_name),
'--icd-lib-path', meson.current_build_dir(),
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
]
@ -100,7 +102,7 @@ endif
dzn_icd = custom_target(
'dzn_icd',
input : [vk_icd_gen, vk_api_xml],
output : 'dzn_icd.@0@.json'.format(host_machine.cpu()),
output : 'dzn_icd.' + vulkan_manifest_suffix,
command : icd_command,
build_by_default : true,
install_dir : with_vulkan_icd_dir,

View file

@ -164,12 +164,13 @@ icd_file_name = libname_prefix + 'vulkan_nouveau.' + libname_suffix
nouveau_icd = custom_target(
'nouveau_icd',
input : [vk_icd_gen, vk_api_xml],
output : 'nouveau_icd.@0@.json'.format(host_machine.cpu()),
output : 'nouveau_icd.' + vulkan_manifest_suffix,
command : [
prog_python, '@INPUT0@',
'--api-version', '1.4', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', vulkan_icd_lib_path / icd_file_name,
'--icd-lib-path', vulkan_icd_lib_path,
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,
@ -187,7 +188,8 @@ custom_target(
prog_python, '@INPUT0@',
'--api-version', '1.4', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', meson.current_build_dir() / icd_file_name,
'--icd-lib-path', meson.current_build_dir(),
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,

View file

@ -241,12 +241,13 @@ icd_file_name = libname_prefix + 'vulkan_panfrost.' + libname_suffix
panfrost_icd = custom_target(
'panfrost_icd',
input : [vk_icd_gen, vk_api_xml],
output : 'panfrost_icd.@0@.json'.format(host_machine.cpu()),
output : 'panfrost_icd.' + vulkan_manifest_suffix,
command : [
prog_python, '@INPUT0@',
'--api-version', '1.4', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', vulkan_icd_lib_path / icd_file_name,
'--icd-lib-path', vulkan_icd_lib_path,
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,
@ -264,7 +265,8 @@ _dev_icd = custom_target(
prog_python, '@INPUT0@',
'--api-version', '1.4', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', meson.current_build_dir() / icd_file_name,
'--icd-lib-path', meson.current_build_dir(),
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,

View file

@ -20,12 +20,13 @@ icd_file_name = libname_prefix + 'vulkan_virtio.' + libname_suffix
virtio_icd = custom_target(
'virtio_icd',
input : [vk_icd_gen, vk_api_xml],
output : 'virtio_icd.@0@.json'.format(host_machine.cpu()),
output : 'virtio_icd.' + vulkan_manifest_suffix,
command : [
prog_python, '@INPUT0@',
'--api-version', '1.4', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', vulkan_icd_lib_path / icd_file_name,
'--icd-lib-path', vulkan_icd_lib_path,
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,
@ -43,7 +44,8 @@ _dev_icd = custom_target(
prog_python, '@INPUT0@',
'--api-version', '1.4', '--xml', '@INPUT1@',
'--sizeof-pointer', sizeof_pointer,
'--lib-path', meson.current_build_dir() / icd_file_name,
'--icd-lib-path', meson.current_build_dir(),
'--icd-filename', icd_file_name,
'--out', '@OUTPUT@',
],
build_by_default : true,

View file

@ -22,6 +22,7 @@
import argparse
import json
import os
import re
import xml.etree.ElementTree as et
@ -48,8 +49,10 @@ if __name__ == '__main__':
help='Vulkan registry XML for patch version')
parser.add_argument('--sizeof-pointer', required=False, type=int,
help='sizeof(void*) on the host cpu')
parser.add_argument('--lib-path', required=True,
help='Path to installed library')
parser.add_argument('--icd-lib-path', required=True,
help='Folder of icd lib_path to installed library')
parser.add_argument('--icd-filename', required=True,
help='Filename of icd lib_path to installed library')
parser.add_argument('--out', required=False,
help='Output json file.')
parser.add_argument('--use-backslash', action='store_true',
@ -63,7 +66,12 @@ if __name__ == '__main__':
else:
re.match(r'\d+\.\d+\.\d+', version)
lib_path = args.lib_path
lib_path = args.icd_filename
if args.out and len(os.path.basename(args.out).split('.')) == 3:
# The output filename is the form of '${icd_id}.${host_machine.cpu()}.json',
# that means vulkan_manifest_per_architecture are true.
lib_path = args.icd_lib_path + '/' + args.icd_filename
if args.use_backslash:
lib_path = lib_path.replace('/', '\\')