Skip to content

Commit

Permalink
Seperate video/render usage for dual gpu case
Browse files Browse the repository at this point in the history
1, In dual gpu scenario, make iGpu alloc video bo,
and make dGpu alloc render bo.
2, Limit dGpu alloc x-tiling most for render.

Tracked-On: OAM-123645
Signed-off-by: ZhuChenyanX <[email protected]>
  • Loading branch information
ZhuChenyanX authored and chenyanxzhu committed Aug 23, 2024
1 parent ccbbf9d commit d3563d4
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 50 deletions.
144 changes: 94 additions & 50 deletions cros_gralloc/cros_gralloc_driver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,25 @@ cros_gralloc_driver *cros_gralloc_driver::get_instance()
return &s_instance;
}

#define DRV_INIT(drv, type, idx) \
if (drv) { \
if (drv_init(drv, type)) { \
drv_loge("Failed to init driver %d\n", idx); \
int fd = drv_get_fd(drv); \
drv_destroy(drv); \
close(fd); \
drv = nullptr; \
} \
}

#define DRV_DESTROY(drv) \
if (drv) { \
int fd = drv_get_fd(drv); \
drv_destroy(drv); \
drv = nullptr; \
close(fd); \
}

cros_gralloc_driver::cros_gralloc_driver()
{
/*
Expand All @@ -115,21 +134,18 @@ cros_gralloc_driver::cros_gralloc_driver()
char *node_name[render_num] = {};
int availabe_node = 0;
int virtio_node_idx = -1;
int i915_node_idx = -1;
int renderer_idx = 0;
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");
mt8183_camera_quirk_ = !strncmp(buf, "kukui", strlen("kukui"));

// destroy drivers if exist before re-initializing them
if (drv_render_) {
int fd = drv_get_fd(drv_render_);
drv_destroy(drv_render_);
drv_render_ = nullptr;
close(fd);
}
if (drv_video_ != drv_render_)
DRV_DESTROY(drv_video_)
DRV_DESTROY(drv_render_)

for (uint32_t i = min_render_node; i < max_render_node; i++) {
if (asprintf(&node, render_nodes_fmt, DRM_DIR_NAME, i) < 0)
Expand Down Expand Up @@ -163,7 +179,15 @@ cros_gralloc_driver::cros_gralloc_driver()
}

if (!strcmp(version->name, "i915")) {
i915_node_idx = availabe_node;
// Prefer i915 for performance consideration.
//
// TODO: We might have multiple i915 devices in the system and in
// this case we are effectively using the one with largest card id
// which is normally the dGPU VF or dGPU passed through device.
renderer_idx = availabe_node;
// Use first available i915 node for video bo alloc
if (video_idx == -1)
video_idx = availabe_node;
}

node_fd[availabe_node] = fd;
Expand All @@ -176,28 +200,6 @@ cros_gralloc_driver::cros_gralloc_driver()
}

if (availabe_node > 0) {
if (i915_node_idx != -1) {
// Prefer i915 for performance consideration.
//
// TODO: We might have multiple i915 devices in the system and in
// this case we are effectively using the one with largest card id
// which is normally the dGPU VF or dGPU passed through device.
renderer_idx = i915_node_idx;
} else if (virtio_node_idx != -1) {
// Fallback to virtio-GPU
renderer_idx = virtio_node_idx;
} else {
drv_loge("Weird scenario! Neither of i915 nor virtio-GPU device is"
" found. Use the first deivice.\n");
renderer_idx = 0;
}
drv_render_ = drv_create(node_fd[renderer_idx]);
if (!drv_render_) {
drv_loge("Failed to create driver for the device with card id %d\n",
renderer_idx);
close(node_fd[renderer_idx]);
}

switch (availabe_node) {
// only have one render node, is GVT-d/BM/VirtIO
case 1:
Expand All @@ -213,20 +215,48 @@ cros_gralloc_driver::cros_gralloc_driver()
// TO-DO: the 3rd node is i915 or others.
break;
}
if (drv_render_) {
if (drv_init(drv_render_, gpu_grp_type)) {
drv_loge("Failed to init driver\n");
fd = drv_get_fd(drv_render_);
drv_destroy(drv_render_);
close(fd);
drv_render_ = nullptr;

// if no i915 node found
if (renderer_idx == -1) {
if (virtio_node_idx != -1) {
// Fallback to virtio-GPU
video_idx = renderer_idx = virtio_node_idx;
} else {
drv_loge("Weird scenario! Neither of i915 nor virtio-GPU device is"
" found. Use the first deivice.\n");
video_idx = renderer_idx = 0;
}
}

// Create drv
if (!(drv_render_ = drv_create(node_fd[renderer_idx]))) {
drv_loge("Failed to create driver for the render device with card id %d\n",
renderer_idx);
close(node_fd[renderer_idx]);
}
if (video_idx != renderer_idx) {
drv_video_ = drv_create(node_fd[video_idx]);
if (!drv_video_) {
drv_loge("Failed to create driver for the video device with card id %d\n",
video_idx);
close(node_fd[video_idx]);
}
} else {
drv_video_ = drv_render_;
if (!drv_video_)
drv_loge("Failed to create driver for the video device with card id %d\n",
video_idx);
}

// Init drv
DRV_INIT(drv_render_, gpu_grp_type, renderer_idx)
if (video_idx != renderer_idx)
DRV_INIT(drv_video_, gpu_grp_type, video_idx)
}

for (int i = 0; i < availabe_node; i++) {
free(node_name[i]);
if (i != renderer_idx) {
if ((i != renderer_idx) && (i != video_idx)) {
close(node_fd[i]);
}
}
Expand All @@ -237,20 +267,29 @@ cros_gralloc_driver::~cros_gralloc_driver()
buffers_.clear();
handles_.clear();

if (drv_render_) {
int fd = drv_get_fd(drv_render_);
drv_destroy(drv_render_);
drv_render_ = nullptr;
close(fd);
}

if (drv_video_ != drv_render_)
DRV_DESTROY(drv_video_)
DRV_DESTROY(drv_render_)
}

bool cros_gralloc_driver::is_initialized()
{
return (drv_render_ != nullptr);
}

bool cros_gralloc_driver::is_video_format(const struct cros_gralloc_buffer_descriptor *descriptor)
{
if (!IsSupportedYUVFormat(descriptor->droid_format))
return false;

// if supported yuv format, almost is_video==TRUE, except check flex implementation.
// In this case only camera usage is video format, according to 'drv_resolve_format_and_use_flags_helper()'.
if (descriptor->drm_format == DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED)
return (descriptor->use_flags & (BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE));

return true;
}

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 @@ -259,7 +298,7 @@ bool cros_gralloc_driver::get_resolved_format_and_use_flags(
uint64_t resolved_use_flags;
struct combination *combo;

struct driver *drv = drv_render_;
struct driver *drv = is_video_format(descriptor) ? drv_video_ : drv_render_;
if (mt8183_camera_quirk_ && (descriptor->use_flags & BO_USE_CAMERA_READ) &&
!(descriptor->use_flags & BO_USE_SCANOUT) &&
descriptor->drm_format == DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED) {
Expand Down Expand Up @@ -302,7 +341,7 @@ bool cros_gralloc_driver::is_supported(const struct cros_gralloc_buffer_descript
{
uint32_t resolved_format;
uint64_t resolved_use_flags;
struct driver *drv = drv_render_;
struct driver *drv = is_video_format(descriptor) ? drv_video_ : drv_render_;
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))
return false;
Expand Down Expand Up @@ -351,7 +390,7 @@ int32_t cros_gralloc_driver::allocate(const struct cros_gralloc_buffer_descripto

struct driver *drv;

drv = drv_render_;
drv = is_video_format(descriptor) ? drv_video_ : drv_render_;

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 @@ -501,7 +540,12 @@ int32_t cros_gralloc_driver::retain(buffer_handle_t handle)
return -EINVAL;
}

drv = drv_render_;
struct cros_gralloc_buffer_descriptor descriptor = {
.droid_format = hnd->droid_format,
.drm_format = hnd->format,
.use_flags = hnd->use_flags,
};
drv = is_video_format(&descriptor) ? drv_video_ : drv_render_;

auto hnd_it = handles_.find(hnd);
if (hnd_it != handles_.end()) {
Expand Down
4 changes: 4 additions & 0 deletions cros_gralloc/cros_gralloc_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class cros_gralloc_driver
cros_gralloc_driver();
~cros_gralloc_driver();
bool is_initialized();
bool is_video_format(const struct cros_gralloc_buffer_descriptor *descriptor);
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 All @@ -83,7 +84,10 @@ class cros_gralloc_driver
int32_t refcount = 1;
};

// in dual gpu scenario, use iGPU for video, use dGPU for render;
// otherwise they may be the same node.
struct driver *drv_render_ = nullptr;
struct driver *drv_video_ = nullptr;
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
6 changes: 6 additions & 0 deletions i915.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,12 @@ 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))
return 0;

struct format_metadata metadata_4_tiled = { .tiling = I915_TILING_4,
.priority = 3,
.modifier = I915_FORMAT_MOD_4_TILED };
Expand Down

0 comments on commit d3563d4

Please sign in to comment.