Skip to content

Commit

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

Tracked-On: OAM-122966
Signed-off-by: He, Yue <[email protected]>
  • Loading branch information
yhe39 committed Sep 9, 2024
1 parent 485e908 commit b0ade11
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 44 deletions.
173 changes: 143 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,83 @@ 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";
uint32_t j;
char *node;

const int render_num = 10;
const int name_length = 50;
int availabe_node = 0;

availabe_node = 0;
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;
}

availabe_node++;
drv_num_ = i;
close(fd);
drmFreeVersion(version);
}

// have the ivshemem node
if ((availabe_node > 0) && !drv_ivshmem_) {
if (asprintf(&node, str, DRM_DIR_NAME, drv_num_) < 0) {
drv_loge("Open new added node fail\n");
return -ENODEV;
}

fd = open(node, O_RDWR, 0);
free(node);

version = drmGetVersion(fd);

if (strcmp(version->name, "virtio_gpu")) {
drv_logi("New added node is not virtiogpu device\n");
close(fd);
drmFreeVersion(version);
return -ENODEV;
}

drmFreeVersion(version);

drv_ivshmem_ = drv_create(fd);
if (!drv_ivshmem_) {
drv_loge("Failed to create driver for virtio device\n");
close(fd);
return -ENODEV;
}

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

cros_gralloc_driver::cros_gralloc_driver()
{
/*
Expand All @@ -134,9 +216,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 +231,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 +263,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
ivshm_node_idx = availabe_node;
}

if (!strcmp(version->name, "i915")) {
Expand All @@ -201,23 +290,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 +339,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 +416,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 +433,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 +481,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 +538,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 +696,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 @@ -253,6 +253,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
Loading

0 comments on commit b0ade11

Please sign in to comment.