From dd745dbc37266915f42226dba70856f9edd63ca3 Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Sun, 31 May 2026 12:56:25 -0400 Subject: [PATCH] render/vulkan: use KHR variant for physical device properties The Vulkan renderer calls vkGetPhysicalDeviceProperties2 while the instance is created with API version 1.0. This violates the specification because the function was promoted to core in 1.1. The resulting validation error leads to undefined behavior and a crash on drivers that enforce strict API checking (e.g. AMD RADV). Replace the core function with the KHR extension variant, which is available when VK_KHR_get_physical_device_properties_2 is enabled, and maintains compatibility with Vulkan 1.0 instances. --- include/render/vulkan.h | 4 +++- render/vulkan/renderer.c | 2 +- render/vulkan/vulkan.c | 14 +++++++++++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/include/render/vulkan.h b/include/render/vulkan.h index de1195b8f..145395da5 100644 --- a/include/render/vulkan.h +++ b/include/render/vulkan.h @@ -24,6 +24,8 @@ struct wlr_vk_instance { PFN_vkCreateDebugUtilsMessengerEXT createDebugUtilsMessengerEXT; PFN_vkDestroyDebugUtilsMessengerEXT destroyDebugUtilsMessengerEXT; } api; + + PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR; }; // Creates and initializes a vulkan instance. @@ -75,7 +77,7 @@ struct wlr_vk_device { // Tries to find the VkPhysicalDevice for the given drm fd. // Might find none and return VK_NULL_HANDLE. VkPhysicalDevice vulkan_find_drm_phdev(struct wlr_vk_instance *ini, int drm_fd); -int vulkan_open_phdev_drm_fd(VkPhysicalDevice phdev); +int vulkan_open_phdev_drm_fd(struct wlr_vk_instance *ini, VkPhysicalDevice phdev); // Creates a device for the given instance and physical device. struct wlr_vk_device *vulkan_device_create(struct wlr_vk_instance *ini, diff --git a/render/vulkan/renderer.c b/render/vulkan/renderer.c index d342dee2c..cfad8ff58 100644 --- a/render/vulkan/renderer.c +++ b/render/vulkan/renderer.c @@ -2818,7 +2818,7 @@ struct wlr_renderer *wlr_vk_renderer_create_with_drm_fd(int drm_fd) { // Do not use the drm_fd that was passed in: we should prefer the render // node even if a primary node was provided - dev->drm_fd = vulkan_open_phdev_drm_fd(phdev); + dev->drm_fd = vulkan_open_phdev_drm_fd(ini, phdev); return vulkan_renderer_create_for_device(dev); diff --git a/render/vulkan/vulkan.c b/render/vulkan/vulkan.c index 3877ec2a7..aa69733d2 100644 --- a/render/vulkan/vulkan.c +++ b/render/vulkan/vulkan.c @@ -195,6 +195,14 @@ struct wlr_vk_instance *vulkan_instance_create(bool debug) { } } + ini->vkGetPhysicalDeviceProperties2KHR = (PFN_vkGetPhysicalDeviceProperties2KHR) + vkGetInstanceProcAddr(ini->instance, "vkGetPhysicalDeviceProperties2KHR"); + if (!ini->vkGetPhysicalDeviceProperties2KHR) { + wlr_log(WLR_ERROR, "vkGetPhysicalDeviceProperties2KHR not found"); + goto error; + } + + return ini; error: @@ -324,7 +332,7 @@ VkPhysicalDevice vulkan_find_drm_phdev(struct wlr_vk_instance *ini, int drm_fd) props.pNext = &driver_props; } - vkGetPhysicalDeviceProperties2(phdev, &props); + ini->vkGetPhysicalDeviceProperties2KHR(phdev, &props); if (has_driver_props) { wlr_log(WLR_INFO, " Driver name: %s (%s)", driver_props.driverName, driver_props.driverInfo); @@ -356,7 +364,7 @@ VkPhysicalDevice vulkan_find_drm_phdev(struct wlr_vk_instance *ini, int drm_fd) return VK_NULL_HANDLE; } -int vulkan_open_phdev_drm_fd(VkPhysicalDevice phdev) { +int vulkan_open_phdev_drm_fd(struct wlr_vk_instance *ini, VkPhysicalDevice phdev) { // vulkan_find_drm_phdev() already checks that VK_EXT_physical_device_drm // is supported VkPhysicalDeviceDrmPropertiesEXT drm_props = { @@ -366,7 +374,7 @@ int vulkan_open_phdev_drm_fd(VkPhysicalDevice phdev) { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, .pNext = &drm_props, }; - vkGetPhysicalDeviceProperties2(phdev, &props); + ini->vkGetPhysicalDeviceProperties2KHR(phdev, &props); dev_t devid; if (drm_props.hasRender) {