loader: Add better support for virtgpu nctx driver loading
In the case of virtio_gpu, if the drm native context capset is supported, we should try loading the native driver before falling back to virgl. Previously this was done with hacks in pipe_virtio_gpu_create_screen(), but this also requires virgl's driconf to be the superset of virgl and all the nctx drivers. Instead add an optional loader callback to probe for nctx support. This is called with the drm capset, if the host supports the drm context type, to allow driver specific code to determine if the specific GPU is supported, so we can cleanly fall back to virgl if it does not (for ex, an old VM guest with a newer host, where mesa in the guest does not support the new GPU, but mesa in the host does). TODO: How to handle the dynamic loader case? Signed-off-by: Rob Clark <robdclark@chromium.org> Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28777>
This commit is contained in:
@@ -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;
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user