Skip to content

Commit

Permalink
Add probe new added render node
Browse files Browse the repository at this point in the history
Open the first available ivshm node.
If it is sancout buffer with certain resolution,
use the ivshm node to allocate buffer.

Tracked-On: OAM-122966
Signed-off-by: He, Yue <yue.he@intel.com>
  • Loading branch information
yhe39 authored and sysopenci committed Sep 14, 2024
1 parent 761fe4a commit 7d29ab0
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 44 deletions.
144 changes: 114 additions & 30 deletions cros_gralloc/cros_gralloc_driver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
// DRM Card nodes start at 0
#define DRM_CARD_NODE_START 0

#define IVSH_WIDTH 1600
#define IVSH_HEIGHT 900

#define IVSH_DEVICE_NUM 2

class cros_gralloc_driver_preloader
{
public:
Expand Down Expand Up @@ -109,6 +114,54 @@ cros_gralloc_driver *cros_gralloc_driver::get_instance()
close(fd); \
}

int32_t cros_gralloc_driver::reload()
{
int fd;
drmVersionPtr version;
char const *str = "%s/renderD%d";
char *node;

// Max probe two ivshm node, the first one is used for screen cast.
for (uint32_t i = drv_num_; i < drv_num_ + IVSH_DEVICE_NUM; i++) {
if (asprintf(&node, str, DRM_DIR_NAME, i) < 0)
continue;

fd = open(node, O_RDWR, 0);
free(node);
if (fd < 0)
continue;

version = drmGetVersion(fd);
if (!version) {
close(fd);
continue;
}

drmFreeVersion(version);
drv_ivshmem_ = drv_create(fd);
if (!drv_ivshmem_) {
drv_loge("Failed to create driver\n");
close(fd);
continue;;
}

if (drv_init(drv_ivshmem_, gpu_grp_type_)) {
drv_loge("Failed to init driver\n");
DRV_DESTROY(drv_ivshmem_)
continue;;
}
if (drv_virtgpu_is_ivshm(drv_ivshmem_)) {
drv_logi("New added node is virtio-ivishmem node");
return 0;
} else {
drv_logi("New added node is NOT virtio-ivishmem node");
DRV_DESTROY(drv_ivshmem_)
continue;
}
}
return -ENODEV;
}

cros_gralloc_driver::cros_gralloc_driver()
{
/*
Expand All @@ -134,9 +187,9 @@ cros_gralloc_driver::cros_gralloc_driver()
char *node_name[render_num] = {};
int availabe_node = 0;
int virtio_node_idx = -1;
int ivshm_node_idx = -1;
int renderer_idx = -1;
int video_idx = -1;
uint32_t gpu_grp_type = 0;

char buf[PROP_VALUE_MAX];
property_get("ro.product.device", buf, "unknown");
Expand All @@ -149,6 +202,10 @@ cros_gralloc_driver::cros_gralloc_driver()
DRV_DESTROY(drv_kms_)
DRV_DESTROY(drv_render_)

if (drv_ivshmem_) {
DRV_DESTROY(drv_ivshmem_)
}

for (uint32_t i = min_render_node; i < max_render_node; i++) {
if (asprintf(&node, render_nodes_fmt, DRM_DIR_NAME, i) < 0)
continue;
Expand Down Expand Up @@ -177,7 +234,10 @@ cros_gralloc_driver::cros_gralloc_driver()
continue;

if (!strcmp(version->name, "virtio_gpu")) {
virtio_node_idx = availabe_node;
if (virtio_node_idx == -1)
virtio_node_idx = availabe_node;
else if (ivshm_node_idx == -1)
ivshm_node_idx = availabe_node;
}

if (!strcmp(version->name, "i915")) {
Expand All @@ -201,23 +261,11 @@ cros_gralloc_driver::cros_gralloc_driver()
drmFreeVersion(version);
}

if (availabe_node > 0) {
switch (availabe_node) {
// only have one render node, is GVT-d/BM/VirtIO
case 1:
gpu_grp_type = (virtio_node_idx != -1)? ONE_GPU_VIRTIO: ONE_GPU_INTEL;
break;
// is SR-IOV or iGPU + dGPU
case 2:
gpu_grp_type = (virtio_node_idx != -1)? TWO_GPU_IGPU_VIRTIO: TWO_GPU_IGPU_DGPU;
break;
// is SR-IOV + dGPU
case 3:
gpu_grp_type = THREE_GPU_IGPU_VIRTIO_DGPU;
// TO-DO: the 3rd node is i915 or others.
break;
}
drv_num_ = DRM_RENDER_NODE_START + availabe_node;

if (availabe_node > 0) {
if ((renderer_idx != -1) && (video_idx != -1) && (video_idx != renderer_idx))
gpu_grp_type_ |= GPU_TYPE_DUAL_IGPU_DGPU;
// if no i915 node found
if (renderer_idx == -1) {
if (virtio_node_idx != -1) {
Expand Down Expand Up @@ -262,31 +310,48 @@ cros_gralloc_driver::cros_gralloc_driver()
drv_kms_ = drv_render_;
}

if (ivshm_node_idx != -1) {
if (!(drv_ivshmem_ = drv_create(node_fd[ivshm_node_idx]))) {
drv_loge("Failed to create driver for the ivshm device with card id %d\n",
ivshm_node_idx);
close(node_fd[ivshm_node_idx]);
}
}

// Init drv
DRV_INIT(drv_render_, gpu_grp_type, renderer_idx)
DRV_INIT(drv_render_, gpu_grp_type_, renderer_idx)
if (video_idx != renderer_idx)
DRV_INIT(drv_video_, gpu_grp_type, video_idx)
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)) {
DRV_INIT(drv_kms_, gpu_grp_type_, virtio_node_idx)
if (drv_kms_ && (virtio_node_idx != renderer_idx) && (drv_kms_ != drv_render_)) {
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");
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");
drv_logi("Virtio ivshmem device or no blob\n");
}
}
if (ivshm_node_idx != -1) {
DRV_INIT(drv_ivshmem_, gpu_grp_type_, ivshm_node_idx)
if (drv_virtgpu_is_ivshm(drv_ivshmem_)) {
drv_logi("Node is virtio-ivishmem node");
} else {
drv_logi("Node is NOT virtio-ivishmem node");
DRV_DESTROY(drv_ivshmem_)
}
}
}

for (int i = 0; i < availabe_node; i++) {
free(node_name[i]);
if ((i != renderer_idx) && (i != video_idx) && (i != virtio_node_idx)) {
if ((i != renderer_idx) && (i != video_idx) && (i != virtio_node_idx) && (i != ivshm_node_idx)) {
close(node_fd[i]);
}
}
Expand Down Expand Up @@ -322,6 +387,14 @@ bool cros_gralloc_driver::is_video_format(const struct cros_gralloc_buffer_descr
return true;
}

bool cros_gralloc_driver::use_ivshm_drv(const struct cros_gralloc_buffer_descriptor *descriptor)
{
if ((descriptor->use_flags & BO_USE_SCANOUT) &&
(descriptor->width == IVSH_WIDTH) && (descriptor->height == IVSH_HEIGHT))
return true;
return false;
}

bool cros_gralloc_driver::get_resolved_format_and_use_flags(
const struct cros_gralloc_buffer_descriptor *descriptor, uint32_t *out_format,
uint64_t *out_use_flags)
Expand All @@ -331,7 +404,9 @@ bool cros_gralloc_driver::get_resolved_format_and_use_flags(
struct combination *combo;

struct driver *drv = is_video_format(descriptor) ? drv_video_ : drv_render_;
if ((descriptor->use_flags & BO_USE_SCANOUT) && !(is_video_format(descriptor)))
if (drv_ivshmem_ && use_ivshm_drv(descriptor)) {
drv = drv_ivshmem_;
} else if ((descriptor->use_flags & BO_USE_SCANOUT) && !(is_video_format(descriptor)))
drv = drv_kms_;

if (mt8183_camera_quirk_ && (descriptor->use_flags & BO_USE_CAMERA_READ) &&
Expand Down Expand Up @@ -377,7 +452,13 @@ bool cros_gralloc_driver::is_supported(const struct cros_gralloc_buffer_descript
uint32_t resolved_format;
uint64_t resolved_use_flags;
struct driver *drv = is_video_format(descriptor) ? drv_video_ : drv_render_;
if ((descriptor->use_flags & BO_USE_SCANOUT) && !(is_video_format(descriptor)))
if (!drv_ivshmem_ && (descriptor->width == IVSH_WIDTH) && (descriptor->height == IVSH_HEIGHT)) {
if (reload()) {
}
}
if (drv_ivshmem_ && use_ivshm_drv(descriptor)) {
drv = drv_ivshmem_;
} else if ((descriptor->use_flags & BO_USE_SCANOUT) && !(is_video_format(descriptor)))
drv = drv_kms_;
uint32_t max_texture_size = drv_get_max_texture_2d_size(drv);
if (!get_resolved_format_and_use_flags(descriptor, &resolved_format, &resolved_use_flags))
Expand Down Expand Up @@ -428,9 +509,10 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto
struct driver *drv;

drv = is_video_format(descriptor) ? drv_video_ : drv_render_;
if ((descriptor->use_flags & BO_USE_SCANOUT) && (!is_video_format(descriptor))) {
if (drv_ivshmem_ && use_ivshm_drv(descriptor)) {
drv = drv_ivshmem_;
} else if ((descriptor->use_flags & BO_USE_SCANOUT) && !(is_video_format(descriptor)))
drv = drv_kms_;
}

if (!get_resolved_format_and_use_flags(descriptor, &resolved_format, &resolved_use_flags)) {
ALOGE("Failed to resolve format and use_flags.");
Expand Down Expand Up @@ -585,7 +667,9 @@ int32_t cros_gralloc_driver::retain(buffer_handle_t handle)
.use_flags = hnd->use_flags,
};
drv = is_video_format(&descriptor) ? drv_video_ : drv_render_;
if ((hnd->use_flags & BO_USE_SCANOUT) && (!is_video_format(&descriptor)))
if (drv_ivshmem_ && use_ivshm_drv(&descriptor)) {
drv = drv_ivshmem_;
} else if ((hnd->use_flags & BO_USE_SCANOUT) && !(is_video_format(&descriptor)))
drv = drv_kms_;

auto hnd_it = handles_.find(hnd);
Expand Down
6 changes: 6 additions & 0 deletions cros_gralloc/cros_gralloc_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define CROS_GRALLOC_DRIVER_H

#include "cros_gralloc_buffer.h"
#include "../drv_priv.h"

#include <functional>
#include <memory>
Expand Down Expand Up @@ -61,6 +62,8 @@ class cros_gralloc_driver
~cros_gralloc_driver();
bool is_initialized();
bool is_video_format(const struct cros_gralloc_buffer_descriptor *descriptor);
bool use_ivshm_drv(const struct cros_gralloc_buffer_descriptor *descriptor);
int32_t reload();
cros_gralloc_buffer *get_buffer(cros_gralloc_handle_t hnd);
bool
get_resolved_format_and_use_flags(const struct cros_gralloc_buffer_descriptor *descriptor,
Expand Down Expand Up @@ -90,6 +93,9 @@ class cros_gralloc_driver
struct driver *drv_video_ = nullptr;
// the drv_kms_ is used to allocate scanout non-video buffer.
struct driver *drv_kms_ = nullptr;
struct driver *drv_ivshmem_ = nullptr;
uint32_t drv_num_ = 0;
uint64_t gpu_grp_type_ = GPU_TYPE_NORMAL;
std::mutex mutex_;
std::unordered_map<uint32_t, std::unique_ptr<cros_gralloc_buffer>> buffers_;
std::unordered_map<cros_gralloc_handle_t, cros_gralloc_imported_handle_info> handles_;
Expand Down
12 changes: 12 additions & 0 deletions drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -845,3 +845,15 @@ bool drv_virtpci_with_blob(struct driver * drv)
}
return ret;
}

bool drv_virtgpu_is_ivshm(struct driver * drv)
{
bool ret = false;
assert(drv);
assert(drv->backend);

if (drv->backend->virtgpu_is_ivshm) {
ret = drv->backend->virtgpu_is_ivshm(drv);
}
return ret;
}
2 changes: 2 additions & 0 deletions drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,8 @@ uint32_t drv_get_max_texture_2d_size(struct driver *drv);

bool drv_virtpci_with_blob(struct driver * drv);

bool drv_virtgpu_is_ivshm(struct driver * drv);

enum drv_log_level {
DRV_LOGV,
DRV_LOGD,
Expand Down
12 changes: 4 additions & 8 deletions drv_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,16 @@ struct combination {
uint64_t use_flags;
};

enum CIV_GPU_TYPE {
ONE_GPU_INTEL = 1,
ONE_GPU_VIRTIO,
TWO_GPU_IGPU_VIRTIO,
TWO_GPU_IGPU_DGPU,
THREE_GPU_IGPU_VIRTIO_DGPU
};
#define GPU_TYPE_NORMAL 0
#define GPU_TYPE_DUAL_IGPU_DGPU (1ull << 0)

struct driver {
int fd;
const struct backend *backend;
void *priv;
pthread_mutex_t buffer_table_lock;
void *buffer_table;
uint32_t gpu_grp_type; // enum CIV_GPU_TYPE
uint64_t gpu_grp_type;
pthread_mutex_t mappings_lock;
struct drv_array *mappings;
struct drv_array *combos;
Expand Down Expand Up @@ -112,6 +107,7 @@ struct backend {
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);
bool (*virtgpu_is_ivshm)(struct driver *drv);
};

// clang-format off
Expand Down
7 changes: 2 additions & 5 deletions i915.c
Original file line number Diff line number Diff line change
Expand Up @@ -443,9 +443,7 @@ static int i915_add_combinations(struct driver *drv)

if (i915_has_tile4(i915)) {
// in dual gpu case, only alloc x-tiling for dgpu for render
if (((drv->gpu_grp_type == TWO_GPU_IGPU_DGPU) ||
(drv->gpu_grp_type == THREE_GPU_IGPU_VIRTIO_DGPU))
&& (i915->graphics_version >= 125))
if ((drv->gpu_grp_type & GPU_TYPE_DUAL_IGPU_DGPU) && (i915->graphics_version >= 125))
return 0;

struct format_metadata metadata_4_tiled = { .tiling = I915_TILING_4,
Expand Down Expand Up @@ -476,8 +474,7 @@ static int i915_add_combinations(struct driver *drv)
struct format_metadata metadata_y_tiled = { .tiling = I915_TILING_Y,
.priority = 3,
.modifier = I915_FORMAT_MOD_Y_TILED };
if ((drv->gpu_grp_type == TWO_GPU_IGPU_DGPU) ||
(drv->gpu_grp_type == THREE_GPU_IGPU_VIRTIO_DGPU)) {
if (drv->gpu_grp_type & GPU_TYPE_DUAL_IGPU_DGPU) {
scanout_and_render_not_linear = unset_flags(scanout_and_render, BO_USE_SCANOUT);
}
/* Support y-tiled NV12 and P010 for libva */
Expand Down
8 changes: 7 additions & 1 deletion virtgpu_virgl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1183,6 +1183,11 @@ static bool virgl_virtpci_with_blob(struct driver *drv) {
return ((prv->dev_feature & VIRTGPU_PARAM_QUERY_DEV_BIT ) && (prv->dev_feature & VIRTGPU_PARAM_RESOURCE_BLOB_BIT));
}

static bool virgl_drv_virtgpu_is_ivshm(struct driver *drv) {
struct virgl_priv *prv = (struct virgl_priv *)drv->priv;
return !(prv->dev_feature & VIRTGPU_PARAM_QUERY_DEV_BIT);
}

const struct backend virtgpu_virgl = { .name = "virtgpu_virgl",
.init = virgl_init,
.close = virgl_close,
Expand All @@ -1198,4 +1203,5 @@ const struct backend virtgpu_virgl = { .name = "virtgpu_virgl",
virgl_resolve_format_and_use_flags,
.resource_info = virgl_resource_info,
.get_max_texture_2d_size = virgl_get_max_texture_2d_size,
.virtpci_with_blob = virgl_virtpci_with_blob };
.virtpci_with_blob = virgl_virtpci_with_blob,
.virtgpu_is_ivshm = virgl_drv_virtgpu_is_ivshm };

0 comments on commit 7d29ab0

Please sign in to comment.