From 441bb8b947d069dc730e664f9d29a1ed7a80b010 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Thu, 26 Mar 2026 15:35:41 +0800 Subject: [PATCH] pvr: drop master for the display FD if it's not needed Currently the display FD is opened twice because of pvr_winsys_create() being called twice, however the WSI (which will do modeset on the display FD in case of VK_KHR_display) is registered against the winsys created at PhysicalDevice enumeration time, and the display FD opened at Device creation time will only be used for allocating dumb buffer (which does not require master privilege). Add a parameter to pvr_winsys_create() to indicate whether the master privilege is desired on the display FD, and pass true only when creating the winsys for PhysicalDevice initialization. Fixes VK_KHR_display operation on PowerVR driver, which is broken after the WSI code starts to drop master in commit 870e233ca55a ("vulkan/wsi/display: Avoid holding drm master for the device's fd."). Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/15161 Signed-off-by: Icenowy Zheng Reviewed-by: Frank Binns Part-of: --- src/imagination/vulkan/pvr_arch_device.c | 2 +- src/imagination/vulkan/pvr_physical_device.c | 3 ++- src/imagination/vulkan/winsys/pvr_winsys.c | 7 +++++++ src/imagination/vulkan/winsys/pvr_winsys.h | 1 + 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/imagination/vulkan/pvr_arch_device.c b/src/imagination/vulkan/pvr_arch_device.c index ee45f408fd5..a28179d6ccd 100644 --- a/src/imagination/vulkan/pvr_arch_device.c +++ b/src/imagination/vulkan/pvr_arch_device.c @@ -703,7 +703,7 @@ VkResult PVR_PER_ARCH(create_device)(struct pvr_physical_device *pdevice, assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO); result = pvr_winsys_create(pdevice->render_path, - pdevice->display_path, + pdevice->display_path, false, pAllocator ? pAllocator : &instance->vk.alloc, &ws); if (result != VK_SUCCESS) diff --git a/src/imagination/vulkan/pvr_physical_device.c b/src/imagination/vulkan/pvr_physical_device.c index 1fd79194d9b..219fd89b7c7 100644 --- a/src/imagination/vulkan/pvr_physical_device.c +++ b/src/imagination/vulkan/pvr_physical_device.c @@ -1031,7 +1031,8 @@ VkResult pvr_physical_device_init(struct pvr_physical_device *pdevice, pdevice->render_devid = render_stat.st_rdev; result = - pvr_winsys_create(render_path, display_path, &instance->vk.alloc, &ws); + pvr_winsys_create(render_path, display_path, true, + &instance->vk.alloc, &ws); if (result != VK_SUCCESS) goto err_vk_free_display_path; diff --git a/src/imagination/vulkan/winsys/pvr_winsys.c b/src/imagination/vulkan/winsys/pvr_winsys.c index 058823e8608..64c5c76b175 100644 --- a/src/imagination/vulkan/winsys/pvr_winsys.c +++ b/src/imagination/vulkan/winsys/pvr_winsys.c @@ -50,6 +50,7 @@ void pvr_winsys_destroy(struct pvr_winsys *ws) VkResult pvr_winsys_create(const char *render_path, const char *display_path, + bool keep_display_master, const VkAllocationCallbacks *alloc, struct pvr_winsys **const ws_out) { @@ -76,6 +77,12 @@ VkResult pvr_winsys_create(const char *render_path, display_path); goto err_close_render_fd; } + if (!keep_display_master) { + /* Try to drop master for the display FD if it's not meant to be + * kept, but not to fail if it's not the master at opening time. + */ + drmDropMaster(display_fd); + } } else { display_fd = -1; } diff --git a/src/imagination/vulkan/winsys/pvr_winsys.h b/src/imagination/vulkan/winsys/pvr_winsys.h index 616e67adc50..90b229244c6 100644 --- a/src/imagination/vulkan/winsys/pvr_winsys.h +++ b/src/imagination/vulkan/winsys/pvr_winsys.h @@ -476,6 +476,7 @@ struct pvr_winsys { void pvr_winsys_destroy(struct pvr_winsys *ws); VkResult pvr_winsys_create(const char *render_path, const char *display_path, + bool keep_display_master, const VkAllocationCallbacks *alloc, struct pvr_winsys **ws_out);