diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index b02983ac..fc2dc12c 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -249,6 +249,20 @@ cros_gralloc_driver::cros_gralloc_driver() close(fd); drv_kms_ = nullptr; } + if (drv_kms_) { + bool virtiogpu_with_blob = drv_query_dev_feature(drv_kms_); + if (virtiogpu_with_blob) { + drv_logi("virtio gpu device with blob\n"); + if (drv_kms_) { + int fd = drv_get_fd(drv_kms_); + drv_destroy(drv_kms_); + drv_kms_ = drv_render_; + close(fd); + } + } else { + drv_logi("virtio ivshmem device or no blob\n"); + } + } } } diff --git a/drv.c b/drv.c index 206df166..a3061154 100644 --- a/drv.c +++ b/drv.c @@ -833,3 +833,15 @@ uint32_t drv_get_max_texture_2d_size(struct driver *drv) return UINT32_MAX; } + +bool drv_query_dev_feature(struct driver * drv) +{ + bool ret = false; + assert(drv); + assert(drv->backend); + + if (drv->backend->query_dev_feature) { + ret = drv->backend->query_dev_feature(); + } + return ret; +} diff --git a/drv.h b/drv.h index 3411d032..e90b58fd 100644 --- a/drv.h +++ b/drv.h @@ -251,6 +251,8 @@ int drv_resource_info(struct bo *bo, uint32_t strides[DRV_MAX_PLANES], uint32_t drv_get_max_texture_2d_size(struct driver *drv); +bool drv_query_dev_feature(struct driver * drv); + enum drv_log_level { DRV_LOGV, DRV_LOGD, diff --git a/drv_priv.h b/drv_priv.h index c6eadf4b..c0a9306c 100644 --- a/drv_priv.h +++ b/drv_priv.h @@ -111,6 +111,7 @@ struct backend { int (*resource_info)(struct bo *bo, uint32_t strides[DRV_MAX_PLANES], uint32_t offsets[DRV_MAX_PLANES], uint64_t *format_modifier); uint32_t (*get_max_texture_2d_size)(struct driver *drv); + bool (*query_dev_feature)(); }; // clang-format off diff --git a/external/virtgpu_drm.h b/external/virtgpu_drm.h index 77209009..5dab8783 100644 --- a/external/virtgpu_drm.h +++ b/external/virtgpu_drm.h @@ -85,6 +85,7 @@ struct drm_virtgpu_execbuffer { #define VIRTGPU_PARAM_CREATE_GUEST_HANDLE 8 /* Host OS handle can be created from guest memory. */ #define VIRTGPU_PARAM_RESOURCE_SYNC 9 /* Synchronization resources */ #define VIRTGPU_PARAM_GUEST_VRAM 10 /* All guest allocations happen via virtgpu dedicated heap. */ +#define VIRTGPU_PARAM_QUERY_DEV 11 /* Query the virtio device name. */ struct drm_virtgpu_getparam { __u64 param; diff --git a/virtgpu.c b/virtgpu.c index 2f4b8dbc..01f59aac 100644 --- a/virtgpu.c +++ b/virtgpu.c @@ -28,11 +28,14 @@ struct virtgpu_param params[] = { PARAM(VIRTGPU_PARAM_CROSS_DEVICE), PARAM(VIRTGPU_PARAM_CONTEXT_INIT), PARAM(VIRTGPU_PARAM_SUPPORTED_CAPSET_IDs), PARAM(VIRTGPU_PARAM_CREATE_GUEST_HANDLE), PARAM(VIRTGPU_PARAM_RESOURCE_SYNC), PARAM(VIRTGPU_PARAM_GUEST_VRAM), + PARAM(VIRTGPU_PARAM_QUERY_DEV), }; extern const struct backend virtgpu_virgl; extern const struct backend virtgpu_cross_domain; +int dev_feature = 0; + static int virtgpu_init(struct driver *drv) { int ret = 0; @@ -49,6 +52,14 @@ static int virtgpu_init(struct driver *drv) int ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GETPARAM, &get_param); if (ret) drv_logi("virtgpu backend not enabling %s\n", params[i].name); + if (ret == 0) { + if (strcmp(params[i].name, "VIRTGPU_PARAM_QUERY_DEV") == 0) { + dev_feature += params[i].value; + } + if (strcmp(params[i].name, "VIRTGPU_PARAM_RESOURCE_BLOB") == 0) { + dev_feature += params[i].value; + } + } } for (uint32_t i = 0; i < ARRAY_SIZE(virtgpu_backends); i++) { diff --git a/virtgpu.h b/virtgpu.h index 3f68731f..8241c5b8 100644 --- a/virtgpu.h +++ b/virtgpu.h @@ -23,3 +23,5 @@ enum virtgpu_param_id { param_guest_vram, param_max, }; + +extern int dev_feature; diff --git a/virtgpu_virgl.c b/virtgpu_virgl.c index 9474c405..23522e42 100644 --- a/virtgpu_virgl.c +++ b/virtgpu_virgl.c @@ -1157,6 +1157,10 @@ static uint32_t virgl_get_max_texture_2d_size(struct driver *drv) return VIRGL_2D_MAX_TEXTURE_2D_SIZE; } +static bool virgl_query_dev_feature() { + return (dev_feature == 2); +} + const struct backend virtgpu_virgl = { .name = "virtgpu_virgl", .init = virgl_init, .close = virgl_close, @@ -1171,4 +1175,5 @@ const struct backend virtgpu_virgl = { .name = "virtgpu_virgl", .resolve_format_and_use_flags = virgl_resolve_format_and_use_flags, .resource_info = virgl_resource_info, - .get_max_texture_2d_size = virgl_get_max_texture_2d_size }; + .get_max_texture_2d_size = virgl_get_max_texture_2d_size, + .query_dev_feature = virgl_query_dev_feature };