Skip to content

Commit

Permalink
drm/vkms: add overlay support
Browse files Browse the repository at this point in the history
Add support to overlay plane, in addition to primary and cursor
planes. In this approach, the plane composition still requires an
active primary plane and planes are composed associatively in the
order: (primary <- overlay) <- cursor

It enables to run the following IGT tests successfully:
- kms_plane_cursor:
  - pipe-A-[overlay, primary, viewport]-size-[64, 128, 256]
- kms_atomic:
  - plane-overlay-legacy
and preserves the successful execution of kms_cursor_crc,
kms_writeback and kms_flip

Signed-off-by: Melissa Wen <melissa.srw@gmail.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/8261bf93d8a0e3ffaf81d8e7c9b3e9c229116be3.1619250933.git.melissa.srw@gmail.com
  • Loading branch information
Melissa Wen committed Apr 29, 2021
1 parent 32a1648 commit 310e506
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 14 deletions.
27 changes: 17 additions & 10 deletions drivers/gpu/drm/vkms/vkms_composer.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,12 @@ static void compose_plane(struct vkms_composer *primary_composer,

static int compose_active_planes(void **vaddr_out,
struct vkms_composer *primary_composer,
struct vkms_composer *cursor_composer)
struct vkms_crtc_state *crtc_state)
{
struct drm_framebuffer *fb = &primary_composer->fb;
struct drm_gem_object *gem_obj = drm_gem_fb_get_obj(fb, 0);
struct drm_gem_shmem_object *shmem_obj = to_drm_gem_shmem_obj(gem_obj);
int i;

if (!*vaddr_out) {
*vaddr_out = kzalloc(shmem_obj->base.size, GFP_KERNEL);
Expand All @@ -195,8 +196,14 @@ static int compose_active_planes(void **vaddr_out,

memcpy(*vaddr_out, shmem_obj->vaddr, shmem_obj->base.size);

if (cursor_composer)
compose_plane(primary_composer, cursor_composer, *vaddr_out);
/* If there are other planes besides primary, we consider the active
* planes should be in z-order and compose them associatively:
* ((primary <- overlay) <- cursor)
*/
for (i = 1; i < crtc_state->num_active_planes; i++)
compose_plane(primary_composer,
crtc_state->active_planes[i]->composer,
*vaddr_out);

return 0;
}
Expand All @@ -218,7 +225,7 @@ void vkms_composer_worker(struct work_struct *work)
struct drm_crtc *crtc = crtc_state->base.crtc;
struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
struct vkms_composer *primary_composer = NULL;
struct vkms_composer *cursor_composer = NULL;
struct vkms_plane_state *act_plane = NULL;
bool crc_pending, wb_pending;
void *vaddr_out = NULL;
u32 crc32 = 0;
Expand All @@ -242,11 +249,11 @@ void vkms_composer_worker(struct work_struct *work)
if (!crc_pending)
return;

if (crtc_state->num_active_planes >= 1)
primary_composer = crtc_state->active_planes[0]->composer;

if (crtc_state->num_active_planes == 2)
cursor_composer = crtc_state->active_planes[1]->composer;
if (crtc_state->num_active_planes >= 1) {
act_plane = crtc_state->active_planes[0];
if (act_plane->base.plane->type == DRM_PLANE_TYPE_PRIMARY)
primary_composer = act_plane->composer;
}

if (!primary_composer)
return;
Expand All @@ -255,7 +262,7 @@ void vkms_composer_worker(struct work_struct *work)
vaddr_out = crtc_state->active_writeback;

ret = compose_active_planes(&vaddr_out, primary_composer,
cursor_composer);
crtc_state);
if (ret) {
if (ret == -EINVAL && !wb_pending)
kfree(vaddr_out);
Expand Down
5 changes: 5 additions & 0 deletions drivers/gpu/drm/vkms/vkms_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ static bool enable_writeback = true;
module_param_named(enable_writeback, enable_writeback, bool, 0444);
MODULE_PARM_DESC(enable_writeback, "Enable/Disable writeback connector support");

static bool enable_overlay;
module_param_named(enable_overlay, enable_overlay, bool, 0444);
MODULE_PARM_DESC(enable_overlay, "Enable/Disable overlay support");

DEFINE_DRM_GEM_FOPS(vkms_driver_fops);

static void vkms_release(struct drm_device *dev)
Expand Down Expand Up @@ -198,6 +202,7 @@ static int __init vkms_init(void)

config->cursor = enable_cursor;
config->writeback = enable_writeback;
config->overlay = enable_overlay;

return vkms_create(config);
}
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/vkms/vkms_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ struct vkms_device;
struct vkms_config {
bool writeback;
bool cursor;
bool overlay;
/* only set when instantiated */
struct vkms_device *dev;
};
Expand Down
11 changes: 10 additions & 1 deletion drivers/gpu/drm/vkms/vkms_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,23 @@ int vkms_output_init(struct vkms_device *vkmsdev, int index)
struct drm_connector *connector = &output->connector;
struct drm_encoder *encoder = &output->encoder;
struct drm_crtc *crtc = &output->crtc;
struct vkms_plane *primary, *cursor = NULL;
struct vkms_plane *primary, *cursor = NULL, *overlay = NULL;
int ret;
int writeback;

primary = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_PRIMARY, index);
if (IS_ERR(primary))
return PTR_ERR(primary);

if (vkmsdev->config->overlay) {
overlay = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_OVERLAY, index);
if (IS_ERR(overlay))
return PTR_ERR(overlay);

if (!overlay->base.possible_crtcs)
overlay->base.possible_crtcs = drm_crtc_mask(crtc);
}

if (vkmsdev->config->cursor) {
cursor = vkms_plane_init(vkmsdev, DRM_PLANE_TYPE_CURSOR, index);
if (IS_ERR(cursor))
Expand Down
15 changes: 12 additions & 3 deletions drivers/gpu/drm/vkms/vkms_plane.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ static int vkms_plane_atomic_check(struct drm_plane *plane,
if (IS_ERR(crtc_state))
return PTR_ERR(crtc_state);

if (plane->type == DRM_PLANE_TYPE_CURSOR)
if (plane->type != DRM_PLANE_TYPE_PRIMARY)
can_position = true;

ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
Expand Down Expand Up @@ -200,14 +200,23 @@ struct vkms_plane *vkms_plane_init(struct vkms_device *vkmsdev,
const u32 *formats;
int nformats;

if (type == DRM_PLANE_TYPE_CURSOR) {
switch (type) {
case DRM_PLANE_TYPE_PRIMARY:
formats = vkms_formats;
nformats = ARRAY_SIZE(vkms_formats);
funcs = &vkms_primary_helper_funcs;
break;
case DRM_PLANE_TYPE_CURSOR:
case DRM_PLANE_TYPE_OVERLAY:
formats = vkms_plane_formats;
nformats = ARRAY_SIZE(vkms_plane_formats);
funcs = &vkms_primary_helper_funcs;
} else {
break;
default:
formats = vkms_formats;
nformats = ARRAY_SIZE(vkms_formats);
funcs = &vkms_primary_helper_funcs;
break;
}

plane = drmm_universal_plane_alloc(dev, struct vkms_plane, base, 1 << index,
Expand Down

0 comments on commit 310e506

Please sign in to comment.