vulkan/wsi/x11: add support to detect if we can support rendering (v3)
This adds support to radv_GetPhysicalDeviceXlibPresentationSupportKHR and radv_GetPhysicalDeviceXcbPresentationSupportKHR to check if the local device file descriptor is compatible with the descriptor retrieved from the X server via DRI3. This will stop radv binding to an X server until we have prime support in place. Hopefully apps use this API before trying to render things. v2: drop unneeded function, don't leak memory. (jekstrand) v3: also check in surface_get_support callback. Reviewed-by: Jason Ekstrand <jason@jlekstrand.net> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
@@ -225,6 +225,8 @@ radv_physical_device_init(struct radv_physical_device *device,
|
||||
result = VK_ERROR_INCOMPATIBLE_DRIVER;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
device->local_fd = fd;
|
||||
device->ws->query_info(device->ws, &device->rad_info);
|
||||
result = radv_init_wsi(device);
|
||||
if (result != VK_SUCCESS) {
|
||||
@@ -249,7 +251,7 @@ radv_physical_device_init(struct radv_physical_device *device,
|
||||
|
||||
fprintf(stderr, "WARNING: radv is not a conformant vulkan implementation, testing use only.\n");
|
||||
device->name = device->rad_info.name;
|
||||
close(fd);
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
fail:
|
||||
@@ -263,6 +265,7 @@ radv_physical_device_finish(struct radv_physical_device *device)
|
||||
radv_extensions_finish(device->instance, &device->extensions);
|
||||
radv_finish_wsi(device);
|
||||
device->ws->destroy(device->ws);
|
||||
close(device->local_fd);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -280,6 +280,7 @@ struct radv_physical_device {
|
||||
const char * name;
|
||||
uint8_t uuid[VK_UUID_SIZE];
|
||||
|
||||
int local_fd;
|
||||
struct wsi_device wsi_device;
|
||||
struct radv_extensions extensions;
|
||||
};
|
||||
|
@@ -92,7 +92,7 @@ VkResult radv_GetPhysicalDeviceSurfaceSupportKHR(
|
||||
|
||||
return iface->get_support(surface, &device->wsi_device,
|
||||
&device->instance->alloc,
|
||||
queueFamilyIndex, pSupported);
|
||||
queueFamilyIndex, device->local_fd, pSupported);
|
||||
}
|
||||
|
||||
VkResult radv_GetPhysicalDeviceSurfaceCapabilitiesKHR(
|
||||
|
@@ -45,7 +45,9 @@ VkBool32 radv_GetPhysicalDeviceXcbPresentationSupportKHR(
|
||||
return wsi_get_physical_device_xcb_presentation_support(
|
||||
&device->wsi_device,
|
||||
&device->instance->alloc,
|
||||
queueFamilyIndex, connection, visual_id);
|
||||
queueFamilyIndex,
|
||||
device->local_fd,
|
||||
connection, visual_id);
|
||||
}
|
||||
|
||||
VkBool32 radv_GetPhysicalDeviceXlibPresentationSupportKHR(
|
||||
@@ -59,7 +61,9 @@ VkBool32 radv_GetPhysicalDeviceXlibPresentationSupportKHR(
|
||||
return wsi_get_physical_device_xcb_presentation_support(
|
||||
&device->wsi_device,
|
||||
&device->instance->alloc,
|
||||
queueFamilyIndex, XGetXCBConnection(dpy), visualID);
|
||||
queueFamilyIndex,
|
||||
device->local_fd,
|
||||
XGetXCBConnection(dpy), visualID);
|
||||
}
|
||||
|
||||
VkResult radv_CreateXcbSurfaceKHR(
|
||||
|
@@ -68,6 +68,7 @@ AM_CPPFLAGS += \
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS += \
|
||||
$(LIBDRM_CFLAGS) \
|
||||
$(INTEL_CFLAGS) \
|
||||
$(VALGRIND_CFLAGS) \
|
||||
$(DEFINES)
|
||||
@@ -93,7 +94,7 @@ VULKAN_SOURCES = \
|
||||
$(VULKAN_GENERATED_FILES) \
|
||||
$(VULKAN_FILES)
|
||||
|
||||
VULKAN_LIB_DEPS =
|
||||
VULKAN_LIB_DEPS = $(LIBDRM_LIBS)
|
||||
|
||||
if HAVE_PLATFORM_X11
|
||||
AM_CPPFLAGS += \
|
||||
|
@@ -202,7 +202,7 @@ anv_physical_device_init(struct anv_physical_device *device,
|
||||
|
||||
isl_device_init(&device->isl_dev, &device->info, swizzled);
|
||||
|
||||
close(fd);
|
||||
device->local_fd = fd;
|
||||
return VK_SUCCESS;
|
||||
|
||||
fail:
|
||||
@@ -215,6 +215,7 @@ anv_physical_device_finish(struct anv_physical_device *device)
|
||||
{
|
||||
anv_finish_wsi(device);
|
||||
ralloc_free(device->compiler);
|
||||
close(device->local_fd);
|
||||
}
|
||||
|
||||
static const VkExtensionProperties global_extensions[] = {
|
||||
|
@@ -532,6 +532,7 @@ struct anv_physical_device {
|
||||
uint8_t uuid[VK_UUID_SIZE];
|
||||
|
||||
struct wsi_device wsi_device;
|
||||
int local_fd;
|
||||
};
|
||||
|
||||
struct anv_instance {
|
||||
|
@@ -94,7 +94,7 @@ VkResult anv_GetPhysicalDeviceSurfaceSupportKHR(
|
||||
|
||||
return iface->get_support(surface, &device->wsi_device,
|
||||
&device->instance->alloc,
|
||||
queueFamilyIndex, pSupported);
|
||||
queueFamilyIndex, device->local_fd, pSupported);
|
||||
}
|
||||
|
||||
VkResult anv_GetPhysicalDeviceSurfaceCapabilitiesKHR(
|
||||
|
@@ -41,7 +41,9 @@ VkBool32 anv_GetPhysicalDeviceXcbPresentationSupportKHR(
|
||||
return wsi_get_physical_device_xcb_presentation_support(
|
||||
&device->wsi_device,
|
||||
&device->instance->alloc,
|
||||
queueFamilyIndex, connection, visual_id);
|
||||
queueFamilyIndex,
|
||||
device->local_fd,
|
||||
connection, visual_id);
|
||||
}
|
||||
|
||||
VkBool32 anv_GetPhysicalDeviceXlibPresentationSupportKHR(
|
||||
@@ -55,7 +57,9 @@ VkBool32 anv_GetPhysicalDeviceXlibPresentationSupportKHR(
|
||||
return wsi_get_physical_device_xcb_presentation_support(
|
||||
&device->wsi_device,
|
||||
&device->instance->alloc,
|
||||
queueFamilyIndex, XGetXCBConnection(dpy), visualID);
|
||||
queueFamilyIndex,
|
||||
device->local_fd,
|
||||
XGetXCBConnection(dpy), visualID);
|
||||
}
|
||||
|
||||
VkResult anv_CreateXcbSurfaceKHR(
|
||||
|
@@ -13,6 +13,7 @@ AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/gallium/include
|
||||
|
||||
AM_CFLAGS = \
|
||||
$(LIBDRM_CFLAGS) \
|
||||
$(VISIBILITY_CFLAGS)
|
||||
|
||||
VULKAN_LIB_DEPS =
|
||||
|
@@ -71,6 +71,7 @@ struct wsi_interface {
|
||||
struct wsi_device *wsi_device,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
uint32_t queueFamilyIndex,
|
||||
int local_fd,
|
||||
VkBool32* pSupported);
|
||||
VkResult (*get_capabilities)(VkIcdSurfaceBase *surface,
|
||||
VkSurfaceCapabilitiesKHR* pSurfaceCapabilities);
|
||||
|
@@ -351,6 +351,7 @@ wsi_wl_surface_get_support(VkIcdSurfaceBase *surface,
|
||||
struct wsi_device *wsi_device,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
uint32_t queueFamilyIndex,
|
||||
int local_fd,
|
||||
VkBool32* pSupported)
|
||||
{
|
||||
*pSupported = true;
|
||||
|
@@ -33,8 +33,9 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <xf86drm.h>
|
||||
#include "util/hash_table.h"
|
||||
|
||||
#include "wsi_common.h"
|
||||
@@ -59,6 +60,66 @@ struct wsi_x11 {
|
||||
struct hash_table *connections;
|
||||
};
|
||||
|
||||
|
||||
/** wsi_dri3_open
|
||||
*
|
||||
* Wrapper around xcb_dri3_open
|
||||
*/
|
||||
static int
|
||||
wsi_dri3_open(xcb_connection_t *conn,
|
||||
xcb_window_t root,
|
||||
uint32_t provider)
|
||||
{
|
||||
xcb_dri3_open_cookie_t cookie;
|
||||
xcb_dri3_open_reply_t *reply;
|
||||
int fd;
|
||||
|
||||
cookie = xcb_dri3_open(conn,
|
||||
root,
|
||||
provider);
|
||||
|
||||
reply = xcb_dri3_open_reply(conn, cookie, NULL);
|
||||
if (!reply)
|
||||
return -1;
|
||||
|
||||
if (reply->nfd != 1) {
|
||||
free(reply);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = xcb_dri3_open_reply_fds(conn, reply)[0];
|
||||
free(reply);
|
||||
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static bool
|
||||
wsi_x11_check_dri3_compatible(xcb_connection_t *conn, int local_fd)
|
||||
{
|
||||
xcb_screen_iterator_t screen_iter =
|
||||
xcb_setup_roots_iterator(xcb_get_setup(conn));
|
||||
xcb_screen_t *screen = screen_iter.data;
|
||||
|
||||
int dri3_fd = wsi_dri3_open(conn, screen->root, None);
|
||||
if (dri3_fd != -1) {
|
||||
char *local_dev = drmGetRenderDeviceNameFromFd(local_fd);
|
||||
char *dri3_dev = drmGetRenderDeviceNameFromFd(dri3_fd);
|
||||
int ret;
|
||||
|
||||
close(dri3_fd);
|
||||
|
||||
ret = strcmp(local_dev, dri3_dev);
|
||||
|
||||
free(local_dev);
|
||||
free(dri3_dev);
|
||||
|
||||
if (ret != 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct wsi_x11_connection *
|
||||
wsi_x11_connection_create(const VkAllocationCallbacks *alloc,
|
||||
xcb_connection_t *conn)
|
||||
@@ -255,6 +316,7 @@ VkBool32 wsi_get_physical_device_xcb_presentation_support(
|
||||
struct wsi_device *wsi_device,
|
||||
VkAllocationCallbacks *alloc,
|
||||
uint32_t queueFamilyIndex,
|
||||
int fd,
|
||||
xcb_connection_t* connection,
|
||||
xcb_visualid_t visual_id)
|
||||
{
|
||||
@@ -270,6 +332,9 @@ VkBool32 wsi_get_physical_device_xcb_presentation_support(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!wsi_x11_check_dri3_compatible(connection, fd))
|
||||
return false;
|
||||
|
||||
unsigned visual_depth;
|
||||
if (!connection_get_visualtype(connection, visual_id, &visual_depth))
|
||||
return false;
|
||||
@@ -303,6 +368,7 @@ x11_surface_get_support(VkIcdSurfaceBase *icd_surface,
|
||||
struct wsi_device *wsi_device,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
uint32_t queueFamilyIndex,
|
||||
int local_fd,
|
||||
VkBool32* pSupported)
|
||||
{
|
||||
xcb_connection_t *conn = x11_surface_get_connection(icd_surface);
|
||||
@@ -320,6 +386,9 @@ x11_surface_get_support(VkIcdSurfaceBase *icd_surface,
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
if (!wsi_x11_check_dri3_compatible(conn, local_fd))
|
||||
return false;
|
||||
|
||||
unsigned visual_depth;
|
||||
if (!get_visualtype_for_window(conn, window, &visual_depth)) {
|
||||
*pSupported = false;
|
||||
|
@@ -29,6 +29,7 @@ VkBool32 wsi_get_physical_device_xcb_presentation_support(
|
||||
struct wsi_device *wsi_device,
|
||||
VkAllocationCallbacks *alloc,
|
||||
uint32_t queueFamilyIndex,
|
||||
int local_fd,
|
||||
xcb_connection_t* connection,
|
||||
xcb_visualid_t visual_id);
|
||||
|
||||
|
Reference in New Issue
Block a user