Skip to content

Commit

Permalink
drm/virtio: Add multiple planar format buffer support
Browse files Browse the repository at this point in the history
Add multiple gem obj backs for virtio gpu framebuffer to support multiple
planer for some pixel format.

Test-done:
- GAS;
- iGPU VF + virtio-GPU;
- iGPU VF + dGPU passthrough.

Tracked-On: OAM-124054
Signed-off-by: hangliu1 <[email protected]>
Signed-off-by: HeYue <[email protected]>
Signed-off-by: Weifeng Liu <[email protected]>
  • Loading branch information
yhe39 authored and sysopenci committed Aug 29, 2024
1 parent 181b960 commit 5aff8c2
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 31 deletions.
1 change: 1 addition & 0 deletions drivers/gpu/drm/virtio/virtgpu_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ static int virtio_gpu_features(struct seq_file *m, void *data)
virtio_gpu_add_bool(m, "multi_plane", vgdev->has_multi_plane);
virtio_gpu_add_bool(m, "rotation", vgdev->has_rotation);
virtio_gpu_add_bool(m, "pixel_blend_mode", vgdev->has_pixel_blend_mode);
virtio_gpu_add_bool(m, "multi_planar", vgdev->has_multi_planar);
virtio_gpu_add_bool(m, "modifier", vgdev->has_modifier);
virtio_gpu_add_int(m, "cap sets", vgdev->num_capsets);
virtio_gpu_add_int(m, "scanouts", vgdev->num_scanouts);
Expand Down
57 changes: 28 additions & 29 deletions drivers/gpu/drm/virtio/virtgpu_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,26 +88,6 @@ static const struct drm_framebuffer_funcs virtio_gpu_fb_funcs = {
.dirty = drm_atomic_helper_dirtyfb,
};

static int
virtio_gpu_framebuffer_init(struct drm_device *dev,
struct virtio_gpu_framebuffer *vgfb,
const struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_gem_object *obj)
{
int ret;

vgfb->base.obj[0] = obj;

drm_helper_mode_fill_fb_struct(dev, &vgfb->base, mode_cmd);

ret = drm_framebuffer_init(dev, &vgfb->base, &virtio_gpu_fb_funcs);
if (ret) {
vgfb->base.obj[0] = NULL;
return ret;
}
return 0;
}

static void virtio_gpu_crtc_mode_set_nofb(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
Expand Down Expand Up @@ -387,27 +367,46 @@ virtio_gpu_user_framebuffer_create(struct drm_device *dev,
{
struct drm_gem_object *obj = NULL;
struct virtio_gpu_framebuffer *virtio_gpu_fb;

const struct drm_format_info *info;
struct drm_gem_object *objs[DRM_FORMAT_MAX_PLANES];

unsigned int i;
int ret;

/* lookup object associated with res handle */
obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]);
if (!obj)
info = drm_get_format_info(dev, mode_cmd);
if (!info) {
drm_dbg_kms(dev, "Failed to get FB format info\n");
return ERR_PTR(-EINVAL);
}

virtio_gpu_fb = kzalloc(sizeof(*virtio_gpu_fb), GFP_KERNEL);
if (virtio_gpu_fb == NULL) {
drm_gem_object_put(obj);
return ERR_PTR(-ENOMEM);
}

ret = virtio_gpu_framebuffer_init(dev, virtio_gpu_fb, mode_cmd, obj);
if (ret) {
kfree(virtio_gpu_fb);
drm_gem_object_put(obj);
return NULL;
for (i = 0; i < info->num_planes; i++) {
objs[i] = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]);
if (!objs[i]) {
drm_dbg_kms(dev, "Failed to lookup GEM object\n");
goto error;
}
virtio_gpu_fb->base.obj[i] = objs[i];
}

drm_helper_mode_fill_fb_struct(dev, &virtio_gpu_fb->base, mode_cmd);
ret = drm_framebuffer_init(dev, &virtio_gpu_fb->base, &virtio_gpu_fb_funcs);
if (ret)
goto error;

return &virtio_gpu_fb->base;
error:
kfree(virtio_gpu_fb);
while (i > 0) {
--i;
drm_gem_object_put(objs[i]);
}
return ERR_PTR(ret);
}

static const struct drm_mode_config_funcs virtio_gpu_mode_funcs = {
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/virtio/virtgpu_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ static unsigned int features[] = {
VIRTIO_GPU_F_MULTI_PLANE,
VIRTIO_GPU_F_ROTATION,
VIRTIO_GPU_F_PIXEL_BLEND_MODE,
VIRTIO_GPU_F_MULTI_PLANAR_FORMAT,
};

#ifdef CONFIG_PM_SLEEP
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/virtio/virtgpu_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ struct virtio_gpu_device {
bool has_multi_plane;
bool has_rotation;
bool has_pixel_blend_mode;
bool has_multi_planar;
bool has_indirect;
bool has_resource_assign_uuid;
bool has_resource_blob;
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/virtio/virtgpu_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,9 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev)
if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_PIXEL_BLEND_MODE)) {
vgdev->has_pixel_blend_mode = true;
}
if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_MULTI_PLANAR_FORMAT)) {
vgdev->has_multi_planar = true;
}
if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_BLOB)) {
vgdev->has_resource_blob = true;
if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_MODIFIER)) {
Expand Down
28 changes: 26 additions & 2 deletions drivers/gpu/drm/virtio/virtgpu_plane.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

#include "virtgpu_drv.h"

static const uint32_t virtio_gpu_formats[] = {
static uint32_t virtio_gpu_formats[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
DRM_FORMAT_BGRX8888,
Expand Down Expand Up @@ -114,6 +114,9 @@ uint32_t virtio_gpu_translate_format(uint32_t drm_fourcc)
case DRM_FORMAT_ABGR8888:
format = VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM;
break;
case DRM_FORMAT_NV12:
format = DRM_FORMAT_NV12;
break;
#endif
default:
/*
Expand Down Expand Up @@ -319,6 +322,7 @@ static void virtio_gpu_resource_flush(struct drm_plane *plane,
struct virtio_gpu_object *bo;
struct virtio_gpu_object_array *objs = NULL;
struct virtio_gpu_fence *fence = NULL;
int i;

vgfb = to_virtio_gpu_framebuffer(plane->state->fb);
bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]);
Expand Down Expand Up @@ -367,7 +371,12 @@ static void virtio_gpu_resource_flush_sprite(struct drm_plane *plane, int indx,
kfree(fence);
return;
}

virtio_gpu_array_add_obj(objs, vgfb->base.obj[0]);
for(i=1; i<fb->format->num_planes; i++) {
if(vgfb->base.obj[i] != vgfb->base.obj[0])
virtio_gpu_array_add_obj(objs, vgfb->base.obj[i]);
}
virtio_gpu_array_lock_resv(objs);
}

Expand Down Expand Up @@ -556,7 +565,18 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane,
cmd_set[cnt].data32[1]=(uint32_t)plane->state->alpha;
cnt++;
}

if ((vgdev->has_multi_planar) && (plane->state->fb->format->num_planes > 1)) {
struct virtio_gpu_framebuffer *vgfb;
cmd_set[cnt].cmd = VIRTIO_GPU_TUNNEL_CMD_SET_PLANARS;
cmd_set[cnt].size = plane->state->fb->format->num_planes-1;
vgfb = to_virtio_gpu_framebuffer(plane->state->fb);
for(i=1; i< plane->state->fb->format->num_planes; i++) {
struct virtio_gpu_object *bo;
bo = gem_to_virtio_gpu_obj(vgfb->base.obj[i]);
cmd_set[cnt].data32[i-1] = bo->hw_res_handle;
}
cnt++;
}
if(cnt) {
virtio_gpu_cmd_send_misc(vgdev, output->index, plane->index, cmd_set, cnt);
}
Expand Down Expand Up @@ -751,6 +771,10 @@ struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev,
} else {
formats = virtio_gpu_formats;
nformats = ARRAY_SIZE(virtio_gpu_formats);
if(vgdev->has_multi_planar) {
virtio_gpu_formats[nformats] = DRM_FORMAT_NV12;
nformats++;
}
funcs = &virtio_gpu_primary_helper_funcs;
}

Expand Down
1 change: 1 addition & 0 deletions include/uapi/linux/virtio_gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@

#define VIRTIO_GPU_F_PIXEL_BLEND_MODE 11

#define VIRTIO_GPU_F_MULTI_PLANAR_FORMAT 12

#define VIRTIO_GPU_TUNNEL_CMD_SET_ROTATION 1
#define VIRTIO_GPU_TUNNEL_CMD_SET_BLEND 2
Expand Down

0 comments on commit 5aff8c2

Please sign in to comment.