From 47289ebc8d815bac2cf0cbb1515972c94d3cee2b 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: --- 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 +- 5 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c index c85cdfe1853..898bdd7bcdb 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 c91633e9bc4..f2049101a3f 100644 --- a/src/vulkan/wsi/wsi_common_display.c +++ b/src/vulkan/wsi/wsi_common_display.c @@ -1100,7 +1100,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 }, @@ -3114,7 +3114,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 = @@ -3148,7 +3148,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 63995c6d208..9835f8f990b 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 ff17db5e778..b89e962c3ff 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 52a388e3b37..a401e0a034e 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -160,7 +160,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);