diff --git a/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c b/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c index 70b3f3a59d7..75fcf6d1dcb 100644 --- a/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c +++ b/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c @@ -42,12 +42,17 @@ #include "frontend/drm_driver.h" #include "pipe_loader_priv.h" +#include "util/log.h" #include "util/os_file.h" #include "util/u_memory.h" #include "util/u_dl.h" #include "util/u_debug.h" #include "util/xmlconfig.h" +#include "virtio/virtio-gpu/drm_hw.h" +#include "virtio/virtio-gpu/virglrenderer_hw.h" +#include "virtgpu_drm.h" + #define DRM_RENDER_NODE_DEV_NAME_FORMAT "%s/renderD%d" #define DRM_RENDER_NODE_MAX_NODES 63 #define DRM_RENDER_NODE_MIN_MINOR 128 @@ -121,6 +126,19 @@ get_driver_descriptor(const char *driver_name, struct util_dl_library **plib) return NULL; } +static int +get_nctx_caps(int fd, struct virgl_renderer_capset_drm *caps) +{ + struct drm_virtgpu_get_caps args = { + .cap_set_id = VIRGL_RENDERER_CAPSET_DRM, + .cap_set_ver = 0, + .addr = (uintptr_t)caps, + .size = sizeof(*caps), + }; + + return drmIoctl(fd, DRM_IOCTL_VIRTGPU_GET_CAPS, &args); +} + static bool pipe_loader_drm_probe_fd_nodup(struct pipe_loader_device **dev, int fd, bool zink) { @@ -156,6 +174,26 @@ pipe_loader_drm_probe_fd_nodup(struct pipe_loader_device **dev, int fd, bool zin ddev->base.driver_name = strdup("radeonsi"); } + if (strcmp(ddev->base.driver_name, "virtio_gpu") == 0) { + struct virgl_renderer_capset_drm caps; + if (get_nctx_caps(fd, &caps) == 0) { +#ifdef GALLIUM_STATIC_TARGETS + for (int i = 0; i < ARRAY_SIZE(driver_descriptors); i++) { + if (!driver_descriptors[i]->probe_nctx) + continue; + if (!driver_descriptors[i]->probe_nctx(fd, &caps)) + continue; + + FREE(ddev->base.driver_name); + ddev->base.driver_name = strdup(driver_descriptors[i]->driver_name); + break; + } +#else + mesa_logw("Dynamic pipe loader does not support virtgpu native context"); +#endif + } + } + struct util_dl_library **plib = NULL; #ifndef GALLIUM_STATIC_TARGETS plib = &ddev->lib; diff --git a/src/gallium/auxiliary/target-helpers/drm_helper.h b/src/gallium/auxiliary/target-helpers/drm_helper.h index 23f2215a1e6..87f58ea8e24 100644 --- a/src/gallium/auxiliary/target-helpers/drm_helper.h +++ b/src/gallium/auxiliary/target-helpers/drm_helper.h @@ -10,12 +10,13 @@ /** * Instantiate a drm_driver_descriptor struct. */ -#define DEFINE_DRM_DRIVER_DESCRIPTOR(descriptor_name, driver, _driconf, _driconf_count, func) \ +#define DEFINE_DRM_DRIVER_DESCRIPTOR(descriptor_name, driver, _driconf, _driconf_count, func, ...) \ const struct drm_driver_descriptor descriptor_name = { \ .driver_name = #driver, \ .driconf = _driconf, \ .driconf_count = _driconf_count, \ .create_screen = func, \ + ##__VA_ARGS__ \ }; /* The static pipe loader refers to the *_driver_descriptor structs for all @@ -33,8 +34,8 @@ const struct drm_driver_descriptor descriptor_name = { \ #ifdef PIPE_LOADER_DYNAMIC -#define DRM_DRIVER_DESCRIPTOR(driver, driconf, driconf_count) \ - PUBLIC DEFINE_DRM_DRIVER_DESCRIPTOR(driver_descriptor, driver, driconf, driconf_count, pipe_##driver##_create_screen) +#define DRM_DRIVER_DESCRIPTOR(driver, driconf, driconf_count, ...) \ + PUBLIC DEFINE_DRM_DRIVER_DESCRIPTOR(driver_descriptor, driver, driconf, driconf_count, pipe_##driver##_create_screen, __VA_ARGS__) #define DRM_DRIVER_DESCRIPTOR_STUB(driver) @@ -42,8 +43,8 @@ const struct drm_driver_descriptor descriptor_name = { \ #else -#define DRM_DRIVER_DESCRIPTOR(driver, driconf, driconf_count) \ - DEFINE_DRM_DRIVER_DESCRIPTOR(driver##_driver_descriptor, driver, driconf, driconf_count, pipe_##driver##_create_screen) +#define DRM_DRIVER_DESCRIPTOR(driver, driconf, driconf_count, ...) \ + DEFINE_DRM_DRIVER_DESCRIPTOR(driver##_driver_descriptor, driver, driconf, driconf_count, pipe_##driver##_create_screen, __VA_ARGS__) #define DRM_DRIVER_DESCRIPTOR_STUB(driver) \ static struct pipe_screen * \ @@ -56,7 +57,7 @@ const struct drm_driver_descriptor descriptor_name = { \ #define DRM_DRIVER_DESCRIPTOR_ALIAS(driver, alias, driconf, driconf_count) \ DEFINE_DRM_DRIVER_DESCRIPTOR(alias##_driver_descriptor, alias, driconf, \ - driconf_count, pipe_##driver##_create_screen) + driconf_count, pipe_##driver##_create_screen, NULL) #endif diff --git a/src/gallium/include/frontend/drm_driver.h b/src/gallium/include/frontend/drm_driver.h index 50f47b72970..d8e153bde3a 100644 --- a/src/gallium/include/frontend/drm_driver.h +++ b/src/gallium/include/frontend/drm_driver.h @@ -10,6 +10,7 @@ struct pipe_screen; struct pipe_screen_config; struct pipe_context; struct pipe_resource; +struct virgl_renderer_capset_drm; struct drm_driver_descriptor { @@ -35,6 +36,12 @@ struct drm_driver_descriptor */ struct pipe_screen* (*create_screen)(int drm_fd, const struct pipe_screen_config *config); + + /** + * Optional hook to probe for driver support for virtgpu native-context + * support. + */ + bool (*probe_nctx)(int drm_fd, const struct virgl_renderer_capset_drm *caps); }; extern const struct drm_driver_descriptor driver_descriptor;