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 <robdclark@chromium.org>
Fixes: baa38c144f ("vulkan/wsi: Use VK_EXT_pci_bus_info for DRM fd matching")
Reviewed-by: Mark Collins <mark@igalia.com>
Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Signed-off-by: Valentine Burley <valentine.burley@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29627>
This commit is contained in:
Valentine Burley 2024-08-07 21:30:32 +00:00 committed by Marge Bot
parent 37d0cdc36f
commit 47289ebc8d
5 changed files with 27 additions and 8 deletions

View file

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

View file

@ -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;
}

View file

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

View file

@ -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,

View file

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