From 485e908c90e2cdfb4e9d919b4cbeef54ab6e72cf Mon Sep 17 00:00:00 2001 From: "He, Yue" Date: Wed, 28 Aug 2024 10:19:04 +0000 Subject: [PATCH] Add the function to check virtio features If it is virtio-gpu with blob, close drv_kms_. use i915 to allocate all buffers. Otherwise use drv_kms_ to allocat scanout non-video buffers. Test Done: 1. Android VM boot without issue. 2. Android display well on QNX. 3. Video playback without issue. Tracked-On: OAM-119826 Signed-off-by: Weifeng Liu Signed-off-by: He, Yue --- cros_gralloc/cros_gralloc_driver.cc | 14 ++++++++++++++ drv.c | 12 ++++++++++++ drv.h | 2 ++ drv_priv.h | 1 + external/virtgpu_drm.h | 13 +++++++++++++ virtgpu.c | 14 -------------- virtgpu.h | 30 ++++++++++++++++++++++++++--- virtgpu_virgl.c | 29 +++++++++++++++++++++++++++- 8 files changed, 97 insertions(+), 18 deletions(-) diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc index 8d093b8a..b01a0a90 100644 --- a/cros_gralloc/cros_gralloc_driver.cc +++ b/cros_gralloc/cros_gralloc_driver.cc @@ -268,6 +268,20 @@ cros_gralloc_driver::cros_gralloc_driver() DRV_INIT(drv_video_, gpu_grp_type, video_idx) if ((virtio_node_idx != -1) && (virtio_node_idx != renderer_idx)) DRV_INIT(drv_kms_, gpu_grp_type, virtio_node_idx) + if (drv_kms_ && (virtio_node_idx != renderer_idx)) { + bool virtiopic_with_blob = drv_virtpci_with_blob(drv_kms_); + // The virtio pci device with blob feature could import buffers + // from i915, otherwise need use virtio to allocate scanout + // non-video buffers. + if (virtiopic_with_blob) { + drv_logi("virtio gpu device with blob\n"); + if ((drv_kms_ != drv_render_) && drv_kms_) + DRV_DESTROY(drv_kms_) + drv_kms_ = drv_render_; + } else { + drv_logi("virtio ivshmem device or no blob\n"); + } + } } for (int i = 0; i < availabe_node; i++) { diff --git a/drv.c b/drv.c index 206df166..0c1be8bc 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_virtpci_with_blob(struct driver * drv) +{ + bool ret = false; + assert(drv); + assert(drv->backend); + + if (drv->backend->virtpci_with_blob) { + ret = drv->backend->virtpci_with_blob(drv); + } + return ret; +} diff --git a/drv.h b/drv.h index 3411d032..6aacdc12 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_virtpci_with_blob(struct driver * drv); + enum drv_log_level { DRV_LOGV, DRV_LOGD, diff --git a/drv_priv.h b/drv_priv.h index c6eadf4b..167c73a6 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 (*virtpci_with_blob)(struct driver *drv); }; // clang-format off diff --git a/external/virtgpu_drm.h b/external/virtgpu_drm.h index 77209009..5a23b511 100644 --- a/external/virtgpu_drm.h +++ b/external/virtgpu_drm.h @@ -85,6 +85,19 @@ 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. */ + +#define VIRTGPU_PARAM_3D_FEATURES_BIT (1ull << VIRTGPU_PARAM_3D_FEATURES) +#define VIRTGPU_PARAM_CAPSET_QUERY_FIX_BIT (1ull << VIRTGPU_PARAM_CAPSET_QUERY_FIX) +#define VIRTGPU_PARAM_RESOURCE_BLOB_BIT (1ull << VIRTGPU_PARAM_RESOURCE_BLOB) +#define VIRTGPU_PARAM_HOST_VISIBLE_BIT (1ull << VIRTGPU_PARAM_HOST_VISIBLE) +#define VIRTGPU_PARAM_CROSS_DEVICE_BIT (1ull << VIRTGPU_PARAM_CROSS_DEVICE) +#define VIRTGPU_PARAM_CONTEXT_INIT_BIT (1ull << VIRTGPU_PARAM_CONTEXT_INIT) +#define VIRTGPU_PARAM_SUPPORTED_CAPSET_IDs_BIT (1ull << VIRTGPU_PARAM_SUPPORTED_CAPSET_IDs) +#define VIRTGPU_PARAM_CREATE_GUEST_HANDLE_BIT (1ull << VIRTGPU_PARAM_CREATE_GUEST_HANDLE) +#define VIRTGPU_PARAM_RESOURCE_SYNC_BIT (1ull << VIRTGPU_PARAM_RESOURCE_SYNC) +#define VIRTGPU_PARAM_GUEST_VRAM_BIT (1ull << VIRTGPU_PARAM_GUEST_VRAM) +#define VIRTGPU_PARAM_QUERY_DEV_BIT (1ull << VIRTGPU_PARAM_QUERY_DEV) struct drm_virtgpu_getparam { __u64 param; diff --git a/virtgpu.c b/virtgpu.c index 2f4b8dbc..bec7814e 100644 --- a/virtgpu.c +++ b/virtgpu.c @@ -16,20 +16,6 @@ #include "util.h" #include "virtgpu.h" -#define PARAM(x) \ - (struct virtgpu_param) \ - { \ - x, #x, 0 \ - } - -struct virtgpu_param params[] = { - PARAM(VIRTGPU_PARAM_3D_FEATURES), PARAM(VIRTGPU_PARAM_CAPSET_QUERY_FIX), - PARAM(VIRTGPU_PARAM_RESOURCE_BLOB), PARAM(VIRTGPU_PARAM_HOST_VISIBLE), - 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), -}; - extern const struct backend virtgpu_virgl; extern const struct backend virtgpu_cross_domain; diff --git a/virtgpu.h b/virtgpu.h index 3f68731f..19ef43ce 100644 --- a/virtgpu.h +++ b/virtgpu.h @@ -4,10 +4,32 @@ * found in the LICENSE file. */ +#ifndef __VIRTGPU_H__ +#define __VIRTGPU_H__ + +#include "drv_priv.h" +#include "external/virtgpu_drm.h" +#include "util.h" + +#define PARAM(x) \ + (struct virtgpu_param) \ + { \ + x, #x, 0 \ + } + struct virtgpu_param { - uint64_t param; - const char *name; - uint32_t value; + uint64_t param; + const char *name; + uint32_t value; +}; + +static struct virtgpu_param params[] = { + PARAM(VIRTGPU_PARAM_3D_FEATURES), PARAM(VIRTGPU_PARAM_CAPSET_QUERY_FIX), + PARAM(VIRTGPU_PARAM_RESOURCE_BLOB), PARAM(VIRTGPU_PARAM_HOST_VISIBLE), + 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), }; enum virtgpu_param_id { @@ -23,3 +45,5 @@ enum virtgpu_param_id { param_guest_vram, param_max, }; + +#endif diff --git a/virtgpu_virgl.c b/virtgpu_virgl.c index 9474c405..87de3c67 100644 --- a/virtgpu_virgl.c +++ b/virtgpu_virgl.c @@ -58,6 +58,7 @@ struct virgl_priv { union virgl_caps caps; int host_gbm_enabled; atomic_int next_blob_id; + uint64_t dev_feature; }; static uint32_t translate_format(uint32_t drm_fourcc) @@ -596,6 +597,26 @@ static int virgl_init(struct driver *drv) virgl_init_params_and_caps(drv); + struct virgl_priv *prv = (struct virgl_priv *)drv->priv; + + prv->dev_feature = 0; + + for (uint32_t i = 0; i < ARRAY_SIZE(params); i++) { + struct drm_virtgpu_getparam get_param = { 0 }; + + get_param.param = params[i].param; + get_param.value = (uint64_t)(uintptr_t)¶ms[i].value; + int ret = drmIoctl(drv->fd, DRM_IOCTL_VIRTGPU_GETPARAM, &get_param); + if (ret == 0) { + if ((strcmp(params[i].name, "VIRTGPU_PARAM_QUERY_DEV") == 0) && (params[i].value == 1)) { + prv->dev_feature |= VIRTGPU_PARAM_QUERY_DEV_BIT; + } + if ((strcmp(params[i].name, "VIRTGPU_PARAM_RESOURCE_BLOB") == 0) && (params[i].value == 1)) { + prv->dev_feature |= VIRTGPU_PARAM_RESOURCE_BLOB_BIT; + } + } + } + if (params[param_3d].value) { /* This doesn't mean host can scanout everything, it just means host * hypervisor can show it. */ @@ -1157,6 +1178,11 @@ static uint32_t virgl_get_max_texture_2d_size(struct driver *drv) return VIRGL_2D_MAX_TEXTURE_2D_SIZE; } +static bool virgl_virtpci_with_blob(struct driver *drv) { + struct virgl_priv *prv = (struct virgl_priv *)drv->priv; + return ((prv->dev_feature & VIRTGPU_PARAM_QUERY_DEV_BIT ) && (prv->dev_feature & VIRTGPU_PARAM_RESOURCE_BLOB_BIT)); +} + const struct backend virtgpu_virgl = { .name = "virtgpu_virgl", .init = virgl_init, .close = virgl_close, @@ -1171,4 +1197,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, + .virtpci_with_blob = virgl_virtpci_with_blob };