diff --git a/0001-device-select-add-a-layer-setting-to-disable-device-.patch b/0001-device-select-add-a-layer-setting-to-disable-device-.patch new file mode 100644 index 0000000..c286c70 --- /dev/null +++ b/0001-device-select-add-a-layer-setting-to-disable-device-.patch @@ -0,0 +1,149 @@ +From b0158d174d297276397b21a6657ea0ef14652183 Mon Sep 17 00:00:00 2001 +From: Dave Airlie +Date: Wed, 5 Nov 2025 11:01:05 +1000 +Subject: [PATCH 1/2] device-select: add a layer setting to disable device + selection logic + +There are cases like zink where we have a file descriptors we are searching +for devices for, so we don't need device selecting reordering, we just want +the fastest path to get the devices so we can match them. + +This also helps avoid some cases of deadlock inside compositors where +zink/vulkan initialises later and tries to connect to the compositor. + +This uses a VK_EXT_layer_setting to add a bypass setting. +--- + .../VkLayer_MESA_device_select.json.in | 6 +++ + .../device-select-layer/device_select_layer.c | 53 +++++++++++++++---- + 2 files changed, 48 insertions(+), 11 deletions(-) + +diff --git a/src/vulkan/device-select-layer/VkLayer_MESA_device_select.json.in b/src/vulkan/device-select-layer/VkLayer_MESA_device_select.json.in +index 40d6ea8cd8b..1623381a81a 100644 +--- a/src/vulkan/device-select-layer/VkLayer_MESA_device_select.json.in ++++ b/src/vulkan/device-select-layer/VkLayer_MESA_device_select.json.in +@@ -7,6 +7,12 @@ + "api_version": "1.4.303", + "implementation_version": "1", + "description": "Linux device selection layer", ++ "instance_extensions": [ ++ { ++ "name": "VK_EXT_layer_settings", ++ "spec_version": "2" ++ } ++ ], + "functions": { + "vkNegotiateLoaderLayerInterfaceVersion": "vkNegotiateLoaderLayerInterfaceVersion" + }, +diff --git a/src/vulkan/device-select-layer/device_select_layer.c b/src/vulkan/device-select-layer/device_select_layer.c +index 19cfc556f54..c03938b82c0 100644 +--- a/src/vulkan/device-select-layer/device_select_layer.c ++++ b/src/vulkan/device-select-layer/device_select_layer.c +@@ -54,7 +54,9 @@ struct instance_info { + PFN_vkGetPhysicalDeviceProperties2 GetPhysicalDeviceProperties2; + bool has_pci_bus, has_vulkan11; + bool has_wayland, has_xcb; +- bool zink, xwayland, xserver; ++ bool xserver; ++ /* don't do device selection */ ++ bool bypass_device_select; + }; + + static struct hash_table *device_select_instance_ht = NULL; +@@ -118,10 +120,34 @@ static VkResult device_select_CreateInstance(const VkInstanceCreateInfo *pCreate + const VkAllocationCallbacks *pAllocator, + VkInstance *pInstance) + { +- VkLayerInstanceCreateInfo *chain_info; +- for(chain_info = (VkLayerInstanceCreateInfo*)pCreateInfo->pNext; chain_info; chain_info = (VkLayerInstanceCreateInfo*)chain_info->pNext) +- if(chain_info->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO && chain_info->function == VK_LAYER_LINK_INFO) ++ VkLayerInstanceCreateInfo *chain_info = NULL; ++ bool bypass_device_select = false; ++ vk_foreach_struct_const(s, pCreateInfo->pNext) { ++ switch (s->sType) { ++ case VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO: { ++ const VkLayerInstanceCreateInfo *this_info = (const void *)s; ++ if (this_info->function == VK_LAYER_LINK_INFO) ++ chain_info = (VkLayerInstanceCreateInfo *)this_info; /* loses const */ + break; ++ } ++ case VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT: { ++ const VkLayerSettingsCreateInfoEXT *lsci = (const void *)s; ++ for (unsigned i = 0; i < lsci->settingCount; i++) { ++ const VkLayerSettingEXT *ls = &lsci->pSettings[i]; ++ if (!strcmp(ls->pLayerName, "MESA_device_select")) { ++ if (!strcmp(ls->pSettingName, "no_device_select")) { ++ assert(ls->type == VK_LAYER_SETTING_TYPE_BOOL32_EXT); ++ uint32_t *values = (uint32_t *)ls->pValues; ++ bypass_device_select = values[0]; ++ } ++ } ++ } ++ break; ++ } ++ default: ++ break; ++ } ++ } + + assert(chain_info->u.pLayerInfo); + +@@ -140,10 +166,10 @@ static VkResult device_select_CreateInstance(const VkInstanceCreateInfo *pCreate + return result; + } + ++ bool zink = !strcmp(engineName, "mesa zink"); ++ bool xwayland = !strcmp(applicationName, "Xwayland"); + struct instance_info *info = (struct instance_info *)calloc(1, sizeof(struct instance_info)); + info->GetInstanceProcAddr = GetInstanceProcAddr; +- info->zink = !strcmp(engineName, "mesa zink"); +- info->xwayland = !strcmp(applicationName, "Xwayland"); + info->xserver = !strcmp(applicationName, "Xorg") || !strcmp(applicationName, "Xephyr"); + + bool has_wayland = getenv("WAYLAND_DISPLAY") || getenv("WAYLAND_SOCKET"); +@@ -155,16 +181,20 @@ static VkResult device_select_CreateInstance(const VkInstanceCreateInfo *pCreate + info->has_wayland = true; + #endif + #ifdef VK_USE_PLATFORM_XCB_KHR +- if (!strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) && has_xcb) +- info->has_xcb = !info->xserver || !info->zink; ++ if (!strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) && ++ has_xcb) ++ info->has_xcb = !info->xserver || !zink; + #endif + } + ++ if (zink && xwayland) ++ bypass_device_select = true; + /* + * The loader is currently not able to handle GetPhysicalDeviceProperties2KHR calls in + * EnumeratePhysicalDevices when there are other layers present. To avoid mysterious crashes + * for users just use only the vulkan version for now. + */ ++ info->bypass_device_select = bypass_device_select; + info->has_vulkan11 = pCreateInfo->pApplicationInfo && + pCreateInfo->pApplicationInfo->apiVersion >= VK_MAKE_VERSION(1, 1, 0); + +@@ -558,7 +588,7 @@ static VkResult device_select_EnumeratePhysicalDevices(VkInstance instance, + uint32_t selected_physical_device_count = 0; + const char* selection = getenv("MESA_VK_DEVICE_SELECT"); + bool expose_only_one_dev = false; +- if (info->zink && info->xwayland) ++ if (info->bypass_device_select) + return info->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices); + VkResult result = info->EnumeratePhysicalDevices(instance, &physical_device_count, NULL); + VK_OUTARRAY_MAKE_TYPED(VkPhysicalDevice, out, pPhysicalDevices, pPhysicalDeviceCount); +@@ -643,8 +673,9 @@ static VkResult device_select_EnumeratePhysicalDeviceGroups(VkInstance instance, + struct instance_info *info = device_select_layer_get_instance(instance); + uint32_t physical_device_group_count = 0; + uint32_t selected_physical_device_group_count = 0; +- if (info->zink && info->xwayland) +- return info->EnumeratePhysicalDeviceGroups(instance, pPhysicalDeviceGroupCount, pPhysicalDeviceGroups); ++ if (info->bypass_device_select) ++ return info->EnumeratePhysicalDeviceGroups(instance, pPhysicalDeviceGroupCount, ++ pPhysicalDeviceGroups); + VkResult result = info->EnumeratePhysicalDeviceGroups(instance, &physical_device_group_count, NULL); + VK_OUTARRAY_MAKE_TYPED(VkPhysicalDeviceGroupProperties, out, pPhysicalDeviceGroups, pPhysicalDeviceGroupCount); + +-- +2.51.1 + diff --git a/0002-zink-use-device-select-layer-settings-to-disable-dev.patch b/0002-zink-use-device-select-layer-settings-to-disable-dev.patch new file mode 100644 index 0000000..319e4b3 --- /dev/null +++ b/0002-zink-use-device-select-layer-settings-to-disable-dev.patch @@ -0,0 +1,106 @@ +From 30c754624ab73b180c66658701814ec5e3d12a31 Mon Sep 17 00:00:00 2001 +From: Dave Airlie +Date: Wed, 5 Nov 2025 11:02:26 +1000 +Subject: [PATCH 2/2] zink: use device select layer settings to disable device + selection + +In the case where we have a device that we want to choose after +probing, there is no point in asking the device select layer to do +any reordering at all. + +This helps avoid a deadlock inside compositors where we don't need +device selection anyways. +--- + src/gallium/drivers/zink/zink_instance.py | 18 ++++++++++++++++++ + src/gallium/drivers/zink/zink_screen.c | 9 ++++++++- + 2 files changed, 26 insertions(+), 1 deletion(-) + +diff --git a/src/gallium/drivers/zink/zink_instance.py b/src/gallium/drivers/zink/zink_instance.py +index 1ab36bee2ca..c0e813be164 100644 +--- a/src/gallium/drivers/zink/zink_instance.py ++++ b/src/gallium/drivers/zink/zink_instance.py +@@ -37,6 +37,7 @@ import platform + # - nonstandard: Disables validation (cross-checking with vk.xml) if True. + EXTENSIONS = [ + Extension("VK_EXT_debug_utils"), ++ Extension("VK_EXT_layer_settings"), + Extension("VK_KHR_get_physical_device_properties2"), + Extension("VK_KHR_external_memory_capabilities"), + Extension("VK_KHR_external_semaphore_capabilities"), +@@ -62,8 +63,10 @@ LAYERS = [ + conditions=["zink_debug & ZINK_DEBUG_VALIDATION"]), + Layer("VK_LAYER_LUNARG_standard_validation", + conditions=["zink_debug & ZINK_DEBUG_VALIDATION", "!have_layer_KHRONOS_validation"]), ++ Layer("VK_LAYER_MESA_device_select") + ] + ++ + REPLACEMENTS = { + "VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES2_EXTENSION_NAME" : "VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME" + } +@@ -87,6 +90,7 @@ struct zink_screen; + + struct zink_instance_info { + uint32_t loader_version; ++ bool no_device_select; + + %for ext in extensions: + bool have_${ext.name_with_vendor()}; +@@ -261,6 +265,20 @@ zink_create_instance(struct zink_screen *screen, struct zink_instance_info *inst + ici.ppEnabledLayerNames = layers; + ici.enabledLayerCount = num_layers; + ++ VkLayerSettingEXT ds_layer = {0}; ++ VkLayerSettingsCreateInfoEXT lsci = {0}; ++ uint32_t no_device_select_value = instance_info->no_device_select; ++ if (have_EXT_layer_settings && have_layer_MESA_device_select) { ++ ds_layer.pLayerName = "MESA_device_select"; ++ ds_layer.pSettingName = "no_device_select"; ++ ds_layer.type = VK_LAYER_SETTING_TYPE_BOOL32_EXT; ++ ds_layer.valueCount = 1; ++ ds_layer.pValues = &no_device_select_value; ++ lsci.sType = VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT; ++ lsci.settingCount = 1; ++ lsci.pSettings = &ds_layer; ++ ici.pNext = &lsci; ++ } + GET_PROC_ADDR_INSTANCE_LOCAL(screen, NULL, CreateInstance); + assert(vk_CreateInstance); + +diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c +index 7ec86d0090a..34eee2ba113 100644 +--- a/src/gallium/drivers/zink/zink_screen.c ++++ b/src/gallium/drivers/zink/zink_screen.c +@@ -1576,6 +1576,12 @@ zink_destroy_screen(struct pipe_screen *pscreen) + glsl_type_singleton_decref(); + } + ++static bool ++zink_picks_device(int dev_major, uint64_t adapter_luid) ++{ ++ return (dev_major > 0 && dev_major < 255) || adapter_luid; ++} ++ + static int + zink_get_display_device(const struct zink_screen *screen, uint32_t pdev_count, + const VkPhysicalDevice *pdevs, int64_t dev_major, +@@ -1647,7 +1653,7 @@ choose_pdev(struct zink_screen *screen, int64_t dev_major, int64_t dev_minor, ui + bool cpu = debug_get_bool_option("LIBGL_ALWAYS_SOFTWARE", false) || + debug_get_bool_option("D3D_ALWAYS_SOFTWARE", false); + +- if (cpu || (dev_major > 0 && dev_major < 255) || adapter_luid) { ++ if (cpu || zink_picks_device(dev_major, adapter_luid)) { + uint32_t pdev_count; + int idx; + VkPhysicalDevice *pdevs; +@@ -3309,6 +3315,7 @@ zink_internal_create_screen(const struct pipe_screen_config *config, int64_t dev + simple_mtx_lock(&instance_lock); + if (++instance_refcount == 1) { + instance_info.loader_version = zink_get_loader_version(screen); ++ instance_info.no_device_select = zink_picks_device(dev_major, adapter_luid); + instance = zink_create_instance(screen, &instance_info); + } + if (!instance) { +-- +2.51.1 + diff --git a/mesa.spec b/mesa.spec index 05a3b29..f09bad2 100644 --- a/mesa.spec +++ b/mesa.spec @@ -88,7 +88,7 @@ Name: mesa Summary: Mesa graphics libraries -%global ver 25.2.5 +%global ver 25.2.7 Version: %{gsub %ver - ~} Release: %autorelease License: MIT AND BSD-3-Clause AND SGI-B-2.0 @@ -144,9 +144,9 @@ Source14: https://crates.io/api/v1/crates/unicode-ident/%{rust_unicode_ide Source15: https://crates.io/api/v1/crates/rustc-hash/%{rustc_hash_ver}/download#/rustc-hash-%{rustc_hash_ver}.tar.gz -# zink + nvk + hotplug fails -# https://gitlab.freedesktop.org/mesa/mesa/-/issues/14148 -Patch10: wayland-display-hacks.patch +# fix zink/device-select bug +Patch11: 0001-device-select-add-a-layer-setting-to-disable-device-.patch +Patch12: 0002-zink-use-device-select-layer-settings-to-disable-dev.patch BuildRequires: meson BuildRequires: gcc diff --git a/sources b/sources index 20a3312..fc26091 100644 --- a/sources +++ b/sources @@ -1,5 +1,5 @@ SHA512 (libclc-20.1.3.src.tar.xz) = ab6fb0dd0250ab9087b84cf6ec253473cdbcf473e24b626509f1aca1893718608ba31902fa6925ec99f64b1b06d60d49fecb2138c72c8aec433c124c57efad57 -SHA512 (mesa-25.2.5.tar.xz) = 29e61b5ecb467a706e3279c0e79ddd8d55109c08f7856d35c4042f518a70622fb19cdd208a82317654e0396835cb3117b756a96d9a0693bfa33730a50bbbd1d0 +SHA512 (mesa-25.2.7.tar.xz) = 87dd815e0d11d6ec0eb969ee93d3f376103bb899d90599e0b7902394e41c58139384df79f89633e132ca969348d3320f55308a74651d409b454d51f1bcda27bc SHA512 (meson-1.7.0.tar.gz) = a5d1f00b193ca37ae64f85c9dfc29a2661c167d82d9953b9acd1393b222b05fa5fc03ffdf00fd1ae7a2014da3a7366c35f70bf02e3204e929b74f7b00c17c840 SHA512 (paste-1.0.15.tar.gz) = 5026d3ec7141ec4e2517a0b1283912d0801e9356f77b703d954b379439b8d85e3886d42fb28f7835edaeeac465582da14233564fb010c71425a59c9e1cbd46b4 SHA512 (proc-macro2-1.0.101.tar.gz) = 3171c807d24371da2931f9c706fb3129bb9bf3ac40418e5d14cfc372baf96e5fee9ede72091163858e3ba0b4f88594efa1031b0bb7128ca68e7b847dead6856c diff --git a/wayland-display-hacks.patch b/wayland-display-hacks.patch deleted file mode 100644 index a5678a2..0000000 --- a/wayland-display-hacks.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff -up mesa-25.1.9/src/vulkan/device-select-layer/device_select_layer.c.dma mesa-25.1.9/src/vulkan/device-select-layer/device_select_layer.c ---- mesa-25.1.9/src/vulkan/device-select-layer/device_select_layer.c.dma 2025-10-22 05:56:08.362350907 +1000 -+++ mesa-25.1.9/src/vulkan/device-select-layer/device_select_layer.c 2025-10-22 05:56:25.724490868 +1000 -@@ -152,11 +152,11 @@ static VkResult device_select_CreateInst - for (unsigned i = 0; i < pCreateInfo->enabledExtensionCount; i++) { - #ifdef VK_USE_PLATFORM_WAYLAND_KHR - if (!strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) && has_wayland) -- info->has_wayland = true; -+ info->has_wayland = !info->zink; - #endif - #ifdef VK_USE_PLATFORM_XCB_KHR - if (!strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) && has_xcb) -- info->has_xcb = !info->xserver || !info->zink; -+ info->has_xcb = !info->xserver && !info->zink; - #endif - } -