From ccde34b72f55c51b644b635bc94e167822595c23 Mon Sep 17 00:00:00 2001 From: Valentine Burley Date: Wed, 7 Aug 2024 21:30:32 +0000 Subject: [PATCH] vulkan/wsi: Refactor can_present_on_device Make wsi_device_matches_drm_fd() a default helper that PCI based GPUs plug in to wsi_dev->can_present_on_device. This is needed for devices without libdrm, where wsi_device_matches_drm_fd was still being called causing an "undefined reference" build error. Suggested-by: Rob Clark Fixes: baa38c144f6 ("vulkan/wsi: Use VK_EXT_pci_bus_info for DRM fd matching") Reviewed-by: Mark Collins Reviewed-by: Faith Ekstrand Signed-off-by: Valentine Burley Part-of: (cherry picked from commit 47289ebc8d815bac2cf0cbb1515972c94d3cee2b) --- .pick_status.json | 2 +- src/vulkan/wsi/wsi_common.c | 19 +++++++++++++++++++ src/vulkan/wsi/wsi_common_display.c | 6 +++--- src/vulkan/wsi/wsi_common_drm.c | 6 +++--- src/vulkan/wsi/wsi_common_private.h | 2 +- src/vulkan/wsi/wsi_common_x11.c | 2 +- 6 files changed, 28 insertions(+), 9 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index ab27eb82c2b..49ac4221d81 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -1414,7 +1414,7 @@ "description": "vulkan/wsi: Refactor can_present_on_device", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "baa38c144f6ab544bccabff3739631bab33e4cd7", "notes": null diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c index cdd4968d16a..d9ae2a6998e 100644 --- a/src/vulkan/wsi/wsi_common.c +++ b/src/vulkan/wsi/wsi_common.c @@ -58,6 +58,10 @@ static const struct debug_control debug_control[] = { { NULL, }, }; +static bool present_false(VkPhysicalDevice pdevice, int fd) { + return false; +} + VkResult wsi_device_init(struct wsi_device *wsi, VkPhysicalDevice pdevice, @@ -270,6 +274,21 @@ wsi_device_init(struct wsi_device *wsi, } } + /* can_present_on_device is a function pointer used to determine if images + * can be presented directly on a given device file descriptor (fd). + * If HAVE_LIBDRM is defined, it will be initialized to a platform-specific + * function (wsi_device_matches_drm_fd). Otherwise, it is initialized to + * present_false to ensure that it always returns false, preventing potential + * segmentation faults from unchecked calls. + * Drivers for non-PCI based GPUs are expected to override this after calling + * wsi_device_init(). + */ +#ifdef HAVE_LIBDRM + wsi->can_present_on_device = wsi_device_matches_drm_fd; +#else + wsi->can_present_on_device = present_false; +#endif + return VK_SUCCESS; fail: wsi_device_finish(wsi, alloc); diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c index 3dc4a670cd7..19be4f0b821 100644 --- a/src/vulkan/wsi/wsi_common_display.c +++ b/src/vulkan/wsi/wsi_common_display.c @@ -1099,7 +1099,7 @@ wsi_display_surface_get_present_rectangles(VkIcdSurfaceBase *surface_base, wsi_display_mode *mode = wsi_display_mode_from_handle(surface->displayMode); VK_OUTARRAY_MAKE_TYPED(VkRect2D, out, pRects, pRectCount); - if (wsi_device_matches_drm_fd(wsi_device, mode->connector->wsi->fd)) { + if (wsi_device->can_present_on_device(wsi_device->pdevice, mode->connector->wsi->fd)) { vk_outarray_append_typed(VkRect2D, &out, rect) { *rect = (VkRect2D) { .offset = { 0, 0 }, @@ -3111,7 +3111,7 @@ wsi_AcquireDrmDisplayEXT(VkPhysicalDevice physicalDevice, VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); struct wsi_device *wsi_device = pdevice->wsi_device; - if (!wsi_device_matches_drm_fd(wsi_device, drmFd)) + if (!wsi_device->can_present_on_device(wsi_device->pdevice, drmFd)) return VK_ERROR_UNKNOWN; struct wsi_display *wsi = @@ -3145,7 +3145,7 @@ wsi_GetDrmDisplayEXT(VkPhysicalDevice physicalDevice, VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); struct wsi_device *wsi_device = pdevice->wsi_device; - if (!wsi_device_matches_drm_fd(wsi_device, drmFd)) { + if (!wsi_device->can_present_on_device(wsi_device->pdevice, drmFd)) { *pDisplay = VK_NULL_HANDLE; return VK_ERROR_UNKNOWN; } diff --git a/src/vulkan/wsi/wsi_common_drm.c b/src/vulkan/wsi/wsi_common_drm.c index dc636735022..2c247255103 100644 --- a/src/vulkan/wsi/wsi_common_drm.c +++ b/src/vulkan/wsi/wsi_common_drm.c @@ -440,10 +440,10 @@ wsi_common_drm_devices_equal(int fd_a, int fd_b) } bool -wsi_device_matches_drm_fd(const struct wsi_device *wsi, int drm_fd) +wsi_device_matches_drm_fd(VkPhysicalDevice physicalDevice, int drm_fd) { - if (wsi->can_present_on_device) - return wsi->can_present_on_device(wsi->pdevice, drm_fd); + VK_FROM_HANDLE(vk_physical_device, pdevice, physicalDevice); + const struct wsi_device *wsi = pdevice->wsi_device; drmDevicePtr fd_device; int ret = drmGetDevice2(drm_fd, 0, &fd_device); diff --git a/src/vulkan/wsi/wsi_common_private.h b/src/vulkan/wsi/wsi_common_private.h index 7767f7b8431..69136292018 100644 --- a/src/vulkan/wsi/wsi_common_private.h +++ b/src/vulkan/wsi/wsi_common_private.h @@ -225,7 +225,7 @@ struct wsi_swapchain { }; bool -wsi_device_matches_drm_fd(const struct wsi_device *wsi, int drm_fd); +wsi_device_matches_drm_fd(VkPhysicalDevice pdevice, int drm_fd); void wsi_wl_surface_destroy(VkIcdSurfaceBase *icd_surface, VkInstance _instance, diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index c6afea8b958..0cc0bf8919f 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -157,7 +157,7 @@ wsi_x11_check_dri3_compatible(const struct wsi_device *wsi_dev, if (dri3_fd == -1) return true; - bool match = wsi_device_matches_drm_fd(wsi_dev, dri3_fd); + bool match = wsi_dev->can_present_on_device(wsi_dev->pdevice, dri3_fd); close(dri3_fd);