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);