All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
To: Daniel Vetter <daniel-/w4YWyX8dFk@public.gmane.org>
Cc: virtio-dev-sDuHXQ4OtrM4h7I2RyI4rWD2FQJk+8+b@public.gmane.org,
	"Michael S. Tsirkin"
	<mst-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>,
	"open list:ABI/API"
	<linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
	Rusty Russell <rusty-8n+1lVoiYb80n/F98K4Iww@public.gmane.org>,
	open list <linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
	"open list:DRM DRIVERS"
	<dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org>,
	"open list:VIRTIO CORE,
	NET..."
	<virtualization-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org>,
	Dave Airlie <airlied-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Subject: Re: [PATCH] Add virtio gpu driver.
Date: Fri, 27 May 2016 09:48:22 +0200	[thread overview]
Message-ID: <1464335302.10663.10.camel@redhat.com> (raw)
In-Reply-To: <CAKMK7uFUNT193f5djZD6T8cgRxxnZL73yrqbupPHOd2P-+Y=pQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 505 bytes --]

  Hi,

> I guess I didn't do a good job at looking at your v2: Cursor is still
> using legacy interfaces and not a proper plane. Would be awesome if
> you could fix that up. Atomic drivers really shouldn't use the legacy
> cursor interfaces any more at all.
> -Daniel

Figured that one for the most part, see attached draft.

The only thing I'm wondering is how the hotspot is handled.
drm_mode_cursor_universal doesn't even look at req->hot_{x,y}.

/me looks confused.

cheers,
  Gerd


[-- Attachment #2: 0001-wip-virtio-gpu-switch-to-atomic-cursor-interfaces.patch --]
[-- Type: text/x-patch, Size: 10880 bytes --]

From fb1d0700a46d850ec9f931304a9e99854a3ce5e9 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Thu, 26 May 2016 11:42:52 +0200
Subject: [PATCH] [wip] virtio-gpu: switch to atomic cursor interfaces

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 drivers/gpu/drm/virtio/virtgpu_display.c | 102 +++-----------------------
 drivers/gpu/drm/virtio/virtgpu_drv.h     |   1 +
 drivers/gpu/drm/virtio/virtgpu_plane.c   | 122 ++++++++++++++++++++++++-------
 3 files changed, 109 insertions(+), 116 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
index 5990cab..d6b16d1 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -29,8 +29,8 @@
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_atomic_helper.h>
 
-#define XRES_MIN   320
-#define YRES_MIN   200
+#define XRES_MIN    32
+#define YRES_MIN    32
 
 #define XRES_DEF  1024
 #define YRES_DEF   768
@@ -38,86 +38,6 @@
 #define XRES_MAX  8192
 #define YRES_MAX  8192
 
-static void
-virtio_gpu_hide_cursor(struct virtio_gpu_device *vgdev,
-		       struct virtio_gpu_output *output)
-{
-	output->cursor.hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_UPDATE_CURSOR);
-	output->cursor.resource_id = 0;
-	virtio_gpu_cursor_ping(vgdev, output);
-}
-
-static int virtio_gpu_crtc_cursor_set(struct drm_crtc *crtc,
-				      struct drm_file *file_priv,
-				      uint32_t handle,
-				      uint32_t width,
-				      uint32_t height,
-				      int32_t hot_x, int32_t hot_y)
-{
-	struct virtio_gpu_device *vgdev = crtc->dev->dev_private;
-	struct virtio_gpu_output *output =
-		container_of(crtc, struct virtio_gpu_output, crtc);
-	struct drm_gem_object *gobj = NULL;
-	struct virtio_gpu_object *qobj = NULL;
-	struct virtio_gpu_fence *fence = NULL;
-	int ret = 0;
-
-	if (handle == 0) {
-		virtio_gpu_hide_cursor(vgdev, output);
-		return 0;
-	}
-
-	/* lookup the cursor */
-	gobj = drm_gem_object_lookup(crtc->dev, file_priv, handle);
-	if (gobj == NULL)
-		return -ENOENT;
-
-	qobj = gem_to_virtio_gpu_obj(gobj);
-
-	if (!qobj->hw_res_handle) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	virtio_gpu_cmd_transfer_to_host_2d(vgdev, qobj->hw_res_handle, 0,
-					   cpu_to_le32(64),
-					   cpu_to_le32(64),
-					   0, 0, &fence);
-	ret = virtio_gpu_object_reserve(qobj, false);
-	if (!ret) {
-		reservation_object_add_excl_fence(qobj->tbo.resv,
-						  &fence->f);
-		fence_put(&fence->f);
-		virtio_gpu_object_unreserve(qobj);
-		virtio_gpu_object_wait(qobj, false);
-	}
-
-	output->cursor.hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_UPDATE_CURSOR);
-	output->cursor.resource_id = cpu_to_le32(qobj->hw_res_handle);
-	output->cursor.hot_x = cpu_to_le32(hot_x);
-	output->cursor.hot_y = cpu_to_le32(hot_y);
-	virtio_gpu_cursor_ping(vgdev, output);
-	ret = 0;
-
-out:
-	drm_gem_object_unreference_unlocked(gobj);
-	return ret;
-}
-
-static int virtio_gpu_crtc_cursor_move(struct drm_crtc *crtc,
-				    int x, int y)
-{
-	struct virtio_gpu_device *vgdev = crtc->dev->dev_private;
-	struct virtio_gpu_output *output =
-		container_of(crtc, struct virtio_gpu_output, crtc);
-
-	output->cursor.hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_MOVE_CURSOR);
-	output->cursor.pos.x = cpu_to_le32(x);
-	output->cursor.pos.y = cpu_to_le32(y);
-	virtio_gpu_cursor_ping(vgdev, output);
-	return 0;
-}
-
 static int virtio_gpu_page_flip(struct drm_crtc *crtc,
 				struct drm_framebuffer *fb,
 				struct drm_pending_vblank_event *event,
@@ -164,8 +84,6 @@ static int virtio_gpu_page_flip(struct drm_crtc *crtc,
 }
 
 static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = {
-	.cursor_set2            = virtio_gpu_crtc_cursor_set,
-	.cursor_move            = virtio_gpu_crtc_cursor_move,
 	.set_config             = drm_atomic_helper_set_config,
 	.destroy                = drm_crtc_cleanup,
 
@@ -406,7 +324,7 @@ static int vgdev_output_init(struct virtio_gpu_device *vgdev, int index)
 	struct drm_connector *connector = &output->conn;
 	struct drm_encoder *encoder = &output->enc;
 	struct drm_crtc *crtc = &output->crtc;
-	struct drm_plane *plane;
+	struct drm_plane *primary, *cursor;
 
 	output->index = index;
 	if (index == 0) {
@@ -415,14 +333,18 @@ static int vgdev_output_init(struct virtio_gpu_device *vgdev, int index)
 		output->info.r.height = cpu_to_le32(YRES_DEF);
 	}
 
-	plane = virtio_gpu_plane_init(vgdev, index);
-	if (IS_ERR(plane))
-		return PTR_ERR(plane);
-	drm_crtc_init_with_planes(dev, crtc, plane, NULL,
+	primary = virtio_gpu_plane_init(vgdev, DRM_PLANE_TYPE_PRIMARY, index);
+	if (IS_ERR(primary))
+		return PTR_ERR(primary);
+	cursor = virtio_gpu_plane_init(vgdev, DRM_PLANE_TYPE_CURSOR, index);
+	if (IS_ERR(cursor))
+		return PTR_ERR(cursor);
+	drm_crtc_init_with_planes(dev, crtc, primary, cursor,
 				  &virtio_gpu_crtc_funcs, NULL);
 	drm_mode_crtc_set_gamma_size(crtc, 256);
 	drm_crtc_helper_add(crtc, &virtio_gpu_crtc_helper_funcs);
-	plane->crtc = crtc;
+	primary->crtc = crtc;
+	cursor->crtc = crtc;
 
 	drm_connector_init(dev, connector, &virtio_gpu_connector_funcs,
 			   DRM_MODE_CONNECTOR_VIRTUAL);
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 8f486f4..a1f7e9d 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -335,6 +335,7 @@ void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev);
 
 /* virtio_gpu_plane.c */
 struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev,
+					enum drm_plane_type type,
 					int index);
 
 /* virtio_gpu_ttm.c */
diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c
index 70b44a2..d68270f 100644
--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -38,6 +38,10 @@ static const uint32_t virtio_gpu_formats[] = {
 	DRM_FORMAT_ABGR8888,
 };
 
+static const uint32_t virtio_gpu_cursor_formats[] = {
+	DRM_FORMAT_ARGB8888,
+};
+
 static void virtio_gpu_plane_destroy(struct drm_plane *plane)
 {
 	kfree(plane);
@@ -63,39 +67,97 @@ static void virtio_gpu_plane_atomic_update(struct drm_plane *plane,
 {
 	struct drm_device *dev = plane->dev;
 	struct virtio_gpu_device *vgdev = dev->dev_private;
-	struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(plane->crtc);
+	struct virtio_gpu_output *output = NULL;
 	struct virtio_gpu_framebuffer *vgfb;
-	struct virtio_gpu_object *bo;
+	struct virtio_gpu_fence *fence = NULL;
+	struct virtio_gpu_object *bo = NULL;
 	uint32_t handle;
+	int ret = 0;
+
+	if (plane->state->crtc)
+		output = drm_crtc_to_virtio_gpu_output(plane->state->crtc);
+	if (old_state->crtc)
+		output = drm_crtc_to_virtio_gpu_output(old_state->crtc);
+	WARN_ON(!output);
 
 	if (plane->state->fb) {
 		vgfb = to_virtio_gpu_framebuffer(plane->state->fb);
 		bo = gem_to_virtio_gpu_obj(vgfb->obj);
 		handle = bo->hw_res_handle;
-		if (bo->dumb) {
-			virtio_gpu_cmd_transfer_to_host_2d
-				(vgdev, handle, 0,
-				 cpu_to_le32(plane->state->crtc_w),
-				 cpu_to_le32(plane->state->crtc_h),
-				 plane->state->crtc_x, plane->state->crtc_y, NULL);
-		}
 	} else {
 		handle = 0;
 	}
 
-	DRM_DEBUG("handle 0x%x, crtc %dx%d+%d+%d\n", handle,
-		  plane->state->crtc_w, plane->state->crtc_h,
-		  plane->state->crtc_x, plane->state->crtc_y);
-	virtio_gpu_cmd_set_scanout(vgdev, output->index, handle,
-				   plane->state->crtc_w,
-				   plane->state->crtc_h,
-				   plane->state->crtc_x,
-				   plane->state->crtc_y);
-	virtio_gpu_cmd_resource_flush(vgdev, handle,
-				      plane->state->crtc_x,
-				      plane->state->crtc_y,
-				      plane->state->crtc_w,
-				      plane->state->crtc_h);
+	switch (plane->type) {
+	case DRM_PLANE_TYPE_CURSOR:
+		if (bo && bo->dumb && (plane->state->fb != old_state->fb)) {
+			/* new cursor -- update & wait */
+			virtio_gpu_cmd_transfer_to_host_2d
+				(vgdev, handle, 0,
+				 cpu_to_le32(plane->state->crtc_w),
+				 cpu_to_le32(plane->state->crtc_h),
+				 0, 0, &fence);
+			ret = virtio_gpu_object_reserve(bo, false);
+			if (!ret) {
+				reservation_object_add_excl_fence(bo->tbo.resv,
+								  &fence->f);
+				fence_put(&fence->f);
+				fence = NULL;
+				virtio_gpu_object_unreserve(bo);
+				virtio_gpu_object_wait(bo, false);
+			}
+		}
+
+		if (plane->state->fb != old_state->fb) {
+			DRM_DEBUG("cursor update, handle %d, +%d+%d\n", handle,
+				  plane->state->crtc_x,
+				  plane->state->crtc_y);
+			output->cursor.hdr.type =
+				cpu_to_le32(VIRTIO_GPU_CMD_UPDATE_CURSOR);
+			output->cursor.resource_id = cpu_to_le32(handle);
+#if 0
+			output->cursor.hot_x = cpu_to_le32(hot_x);
+			output->cursor.hot_y = cpu_to_le32(hot_y);
+#endif
+		} else {
+			DRM_DEBUG("cursor move +%d+%d\n",
+				  plane->state->crtc_x,
+				  plane->state->crtc_y);
+			output->cursor.hdr.type =
+				cpu_to_le32(VIRTIO_GPU_CMD_MOVE_CURSOR);
+		}
+		output->cursor.pos.x = cpu_to_le32(plane->state->crtc_x);
+		output->cursor.pos.y = cpu_to_le32(plane->state->crtc_y);
+		virtio_gpu_cursor_ping(vgdev, output);
+		break;
+
+	case DRM_PLANE_TYPE_PRIMARY:
+		DRM_DEBUG("primary, handle 0x%x, crtc %dx%d+%d+%d\n", handle,
+			  plane->state->crtc_w, plane->state->crtc_h,
+			  plane->state->crtc_x, plane->state->crtc_y);
+		if (bo && bo->dumb) {
+			virtio_gpu_cmd_transfer_to_host_2d
+				(vgdev, handle, 0,
+				 cpu_to_le32(plane->state->crtc_w),
+				 cpu_to_le32(plane->state->crtc_h),
+				 plane->state->crtc_x, plane->state->crtc_y,
+				 &fence);
+		}
+		virtio_gpu_cmd_set_scanout(vgdev, output->index, handle,
+					   plane->state->crtc_w,
+					   plane->state->crtc_h,
+					   plane->state->crtc_x,
+					   plane->state->crtc_y);
+		virtio_gpu_cmd_resource_flush(vgdev, handle,
+					      plane->state->crtc_x,
+					      plane->state->crtc_y,
+					      plane->state->crtc_w,
+					      plane->state->crtc_h);
+		break;
+
+	default:
+		WARN_ON(true);
+	}
 }
 
 
@@ -105,21 +167,29 @@ static const struct drm_plane_helper_funcs virtio_gpu_plane_helper_funcs = {
 };
 
 struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev,
+					enum drm_plane_type type,
 					int index)
 {
 	struct drm_device *dev = vgdev->ddev;
 	struct drm_plane *plane;
-	int ret;
+	const uint32_t *formats;
+	int ret, nformats;
 
 	plane = kzalloc(sizeof(*plane), GFP_KERNEL);
 	if (!plane)
 		return ERR_PTR(-ENOMEM);
 
+	if (type == DRM_PLANE_TYPE_CURSOR) {
+		formats = virtio_gpu_cursor_formats;
+		nformats = ARRAY_SIZE(virtio_gpu_cursor_formats);
+	} else {
+		formats = virtio_gpu_formats;
+		nformats = ARRAY_SIZE(virtio_gpu_formats);
+	}
 	ret = drm_universal_plane_init(dev, plane, 1 << index,
 				       &virtio_gpu_plane_funcs,
-				       virtio_gpu_formats,
-				       ARRAY_SIZE(virtio_gpu_formats),
-				       DRM_PLANE_TYPE_PRIMARY, NULL);
+				       formats, nformats,
+				       type, NULL);
 	if (ret)
 		goto err_plane_init;
 
-- 
1.8.3.1


WARNING: multiple messages have this Message-ID (diff)
From: Gerd Hoffmann <kraxel@redhat.com>
To: Daniel Vetter <daniel@ffwll.ch>
Cc: virtio-dev@lists.oasis-open.org,
	"Michael S. Tsirkin" <mst@redhat.com>,
	"open list:ABI/API" <linux-api@vger.kernel.org>,
	Rusty Russell <rusty@rustcorp.com.au>,
	open list <linux-kernel@vger.kernel.org>,
	"open list:DRM DRIVERS" <dri-devel@lists.freedesktop.org>,
	"open list:VIRTIO CORE,
	NET..."  <virtualization@lists.linux-foundation.org>,
	Dave Airlie <airlied@redhat.com>
Subject: Re: [PATCH] Add virtio gpu driver.
Date: Fri, 27 May 2016 09:48:22 +0200	[thread overview]
Message-ID: <1464335302.10663.10.camel@redhat.com> (raw)
In-Reply-To: <CAKMK7uFUNT193f5djZD6T8cgRxxnZL73yrqbupPHOd2P-+Y=pQ@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 505 bytes --]

  Hi,

> I guess I didn't do a good job at looking at your v2: Cursor is still
> using legacy interfaces and not a proper plane. Would be awesome if
> you could fix that up. Atomic drivers really shouldn't use the legacy
> cursor interfaces any more at all.
> -Daniel

Figured that one for the most part, see attached draft.

The only thing I'm wondering is how the hotspot is handled.
drm_mode_cursor_universal doesn't even look at req->hot_{x,y}.

/me looks confused.

cheers,
  Gerd


[-- Attachment #2: 0001-wip-virtio-gpu-switch-to-atomic-cursor-interfaces.patch --]
[-- Type: text/x-patch, Size: 10880 bytes --]

From fb1d0700a46d850ec9f931304a9e99854a3ce5e9 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Thu, 26 May 2016 11:42:52 +0200
Subject: [PATCH] [wip] virtio-gpu: switch to atomic cursor interfaces

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 drivers/gpu/drm/virtio/virtgpu_display.c | 102 +++-----------------------
 drivers/gpu/drm/virtio/virtgpu_drv.h     |   1 +
 drivers/gpu/drm/virtio/virtgpu_plane.c   | 122 ++++++++++++++++++++++++-------
 3 files changed, 109 insertions(+), 116 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
index 5990cab..d6b16d1 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -29,8 +29,8 @@
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_atomic_helper.h>
 
-#define XRES_MIN   320
-#define YRES_MIN   200
+#define XRES_MIN    32
+#define YRES_MIN    32
 
 #define XRES_DEF  1024
 #define YRES_DEF   768
@@ -38,86 +38,6 @@
 #define XRES_MAX  8192
 #define YRES_MAX  8192
 
-static void
-virtio_gpu_hide_cursor(struct virtio_gpu_device *vgdev,
-		       struct virtio_gpu_output *output)
-{
-	output->cursor.hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_UPDATE_CURSOR);
-	output->cursor.resource_id = 0;
-	virtio_gpu_cursor_ping(vgdev, output);
-}
-
-static int virtio_gpu_crtc_cursor_set(struct drm_crtc *crtc,
-				      struct drm_file *file_priv,
-				      uint32_t handle,
-				      uint32_t width,
-				      uint32_t height,
-				      int32_t hot_x, int32_t hot_y)
-{
-	struct virtio_gpu_device *vgdev = crtc->dev->dev_private;
-	struct virtio_gpu_output *output =
-		container_of(crtc, struct virtio_gpu_output, crtc);
-	struct drm_gem_object *gobj = NULL;
-	struct virtio_gpu_object *qobj = NULL;
-	struct virtio_gpu_fence *fence = NULL;
-	int ret = 0;
-
-	if (handle == 0) {
-		virtio_gpu_hide_cursor(vgdev, output);
-		return 0;
-	}
-
-	/* lookup the cursor */
-	gobj = drm_gem_object_lookup(crtc->dev, file_priv, handle);
-	if (gobj == NULL)
-		return -ENOENT;
-
-	qobj = gem_to_virtio_gpu_obj(gobj);
-
-	if (!qobj->hw_res_handle) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	virtio_gpu_cmd_transfer_to_host_2d(vgdev, qobj->hw_res_handle, 0,
-					   cpu_to_le32(64),
-					   cpu_to_le32(64),
-					   0, 0, &fence);
-	ret = virtio_gpu_object_reserve(qobj, false);
-	if (!ret) {
-		reservation_object_add_excl_fence(qobj->tbo.resv,
-						  &fence->f);
-		fence_put(&fence->f);
-		virtio_gpu_object_unreserve(qobj);
-		virtio_gpu_object_wait(qobj, false);
-	}
-
-	output->cursor.hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_UPDATE_CURSOR);
-	output->cursor.resource_id = cpu_to_le32(qobj->hw_res_handle);
-	output->cursor.hot_x = cpu_to_le32(hot_x);
-	output->cursor.hot_y = cpu_to_le32(hot_y);
-	virtio_gpu_cursor_ping(vgdev, output);
-	ret = 0;
-
-out:
-	drm_gem_object_unreference_unlocked(gobj);
-	return ret;
-}
-
-static int virtio_gpu_crtc_cursor_move(struct drm_crtc *crtc,
-				    int x, int y)
-{
-	struct virtio_gpu_device *vgdev = crtc->dev->dev_private;
-	struct virtio_gpu_output *output =
-		container_of(crtc, struct virtio_gpu_output, crtc);
-
-	output->cursor.hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_MOVE_CURSOR);
-	output->cursor.pos.x = cpu_to_le32(x);
-	output->cursor.pos.y = cpu_to_le32(y);
-	virtio_gpu_cursor_ping(vgdev, output);
-	return 0;
-}
-
 static int virtio_gpu_page_flip(struct drm_crtc *crtc,
 				struct drm_framebuffer *fb,
 				struct drm_pending_vblank_event *event,
@@ -164,8 +84,6 @@ static int virtio_gpu_page_flip(struct drm_crtc *crtc,
 }
 
 static const struct drm_crtc_funcs virtio_gpu_crtc_funcs = {
-	.cursor_set2            = virtio_gpu_crtc_cursor_set,
-	.cursor_move            = virtio_gpu_crtc_cursor_move,
 	.set_config             = drm_atomic_helper_set_config,
 	.destroy                = drm_crtc_cleanup,
 
@@ -406,7 +324,7 @@ static int vgdev_output_init(struct virtio_gpu_device *vgdev, int index)
 	struct drm_connector *connector = &output->conn;
 	struct drm_encoder *encoder = &output->enc;
 	struct drm_crtc *crtc = &output->crtc;
-	struct drm_plane *plane;
+	struct drm_plane *primary, *cursor;
 
 	output->index = index;
 	if (index == 0) {
@@ -415,14 +333,18 @@ static int vgdev_output_init(struct virtio_gpu_device *vgdev, int index)
 		output->info.r.height = cpu_to_le32(YRES_DEF);
 	}
 
-	plane = virtio_gpu_plane_init(vgdev, index);
-	if (IS_ERR(plane))
-		return PTR_ERR(plane);
-	drm_crtc_init_with_planes(dev, crtc, plane, NULL,
+	primary = virtio_gpu_plane_init(vgdev, DRM_PLANE_TYPE_PRIMARY, index);
+	if (IS_ERR(primary))
+		return PTR_ERR(primary);
+	cursor = virtio_gpu_plane_init(vgdev, DRM_PLANE_TYPE_CURSOR, index);
+	if (IS_ERR(cursor))
+		return PTR_ERR(cursor);
+	drm_crtc_init_with_planes(dev, crtc, primary, cursor,
 				  &virtio_gpu_crtc_funcs, NULL);
 	drm_mode_crtc_set_gamma_size(crtc, 256);
 	drm_crtc_helper_add(crtc, &virtio_gpu_crtc_helper_funcs);
-	plane->crtc = crtc;
+	primary->crtc = crtc;
+	cursor->crtc = crtc;
 
 	drm_connector_init(dev, connector, &virtio_gpu_connector_funcs,
 			   DRM_MODE_CONNECTOR_VIRTUAL);
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 8f486f4..a1f7e9d 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -335,6 +335,7 @@ void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev);
 
 /* virtio_gpu_plane.c */
 struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev,
+					enum drm_plane_type type,
 					int index);
 
 /* virtio_gpu_ttm.c */
diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c
index 70b44a2..d68270f 100644
--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -38,6 +38,10 @@ static const uint32_t virtio_gpu_formats[] = {
 	DRM_FORMAT_ABGR8888,
 };
 
+static const uint32_t virtio_gpu_cursor_formats[] = {
+	DRM_FORMAT_ARGB8888,
+};
+
 static void virtio_gpu_plane_destroy(struct drm_plane *plane)
 {
 	kfree(plane);
@@ -63,39 +67,97 @@ static void virtio_gpu_plane_atomic_update(struct drm_plane *plane,
 {
 	struct drm_device *dev = plane->dev;
 	struct virtio_gpu_device *vgdev = dev->dev_private;
-	struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(plane->crtc);
+	struct virtio_gpu_output *output = NULL;
 	struct virtio_gpu_framebuffer *vgfb;
-	struct virtio_gpu_object *bo;
+	struct virtio_gpu_fence *fence = NULL;
+	struct virtio_gpu_object *bo = NULL;
 	uint32_t handle;
+	int ret = 0;
+
+	if (plane->state->crtc)
+		output = drm_crtc_to_virtio_gpu_output(plane->state->crtc);
+	if (old_state->crtc)
+		output = drm_crtc_to_virtio_gpu_output(old_state->crtc);
+	WARN_ON(!output);
 
 	if (plane->state->fb) {
 		vgfb = to_virtio_gpu_framebuffer(plane->state->fb);
 		bo = gem_to_virtio_gpu_obj(vgfb->obj);
 		handle = bo->hw_res_handle;
-		if (bo->dumb) {
-			virtio_gpu_cmd_transfer_to_host_2d
-				(vgdev, handle, 0,
-				 cpu_to_le32(plane->state->crtc_w),
-				 cpu_to_le32(plane->state->crtc_h),
-				 plane->state->crtc_x, plane->state->crtc_y, NULL);
-		}
 	} else {
 		handle = 0;
 	}
 
-	DRM_DEBUG("handle 0x%x, crtc %dx%d+%d+%d\n", handle,
-		  plane->state->crtc_w, plane->state->crtc_h,
-		  plane->state->crtc_x, plane->state->crtc_y);
-	virtio_gpu_cmd_set_scanout(vgdev, output->index, handle,
-				   plane->state->crtc_w,
-				   plane->state->crtc_h,
-				   plane->state->crtc_x,
-				   plane->state->crtc_y);
-	virtio_gpu_cmd_resource_flush(vgdev, handle,
-				      plane->state->crtc_x,
-				      plane->state->crtc_y,
-				      plane->state->crtc_w,
-				      plane->state->crtc_h);
+	switch (plane->type) {
+	case DRM_PLANE_TYPE_CURSOR:
+		if (bo && bo->dumb && (plane->state->fb != old_state->fb)) {
+			/* new cursor -- update & wait */
+			virtio_gpu_cmd_transfer_to_host_2d
+				(vgdev, handle, 0,
+				 cpu_to_le32(plane->state->crtc_w),
+				 cpu_to_le32(plane->state->crtc_h),
+				 0, 0, &fence);
+			ret = virtio_gpu_object_reserve(bo, false);
+			if (!ret) {
+				reservation_object_add_excl_fence(bo->tbo.resv,
+								  &fence->f);
+				fence_put(&fence->f);
+				fence = NULL;
+				virtio_gpu_object_unreserve(bo);
+				virtio_gpu_object_wait(bo, false);
+			}
+		}
+
+		if (plane->state->fb != old_state->fb) {
+			DRM_DEBUG("cursor update, handle %d, +%d+%d\n", handle,
+				  plane->state->crtc_x,
+				  plane->state->crtc_y);
+			output->cursor.hdr.type =
+				cpu_to_le32(VIRTIO_GPU_CMD_UPDATE_CURSOR);
+			output->cursor.resource_id = cpu_to_le32(handle);
+#if 0
+			output->cursor.hot_x = cpu_to_le32(hot_x);
+			output->cursor.hot_y = cpu_to_le32(hot_y);
+#endif
+		} else {
+			DRM_DEBUG("cursor move +%d+%d\n",
+				  plane->state->crtc_x,
+				  plane->state->crtc_y);
+			output->cursor.hdr.type =
+				cpu_to_le32(VIRTIO_GPU_CMD_MOVE_CURSOR);
+		}
+		output->cursor.pos.x = cpu_to_le32(plane->state->crtc_x);
+		output->cursor.pos.y = cpu_to_le32(plane->state->crtc_y);
+		virtio_gpu_cursor_ping(vgdev, output);
+		break;
+
+	case DRM_PLANE_TYPE_PRIMARY:
+		DRM_DEBUG("primary, handle 0x%x, crtc %dx%d+%d+%d\n", handle,
+			  plane->state->crtc_w, plane->state->crtc_h,
+			  plane->state->crtc_x, plane->state->crtc_y);
+		if (bo && bo->dumb) {
+			virtio_gpu_cmd_transfer_to_host_2d
+				(vgdev, handle, 0,
+				 cpu_to_le32(plane->state->crtc_w),
+				 cpu_to_le32(plane->state->crtc_h),
+				 plane->state->crtc_x, plane->state->crtc_y,
+				 &fence);
+		}
+		virtio_gpu_cmd_set_scanout(vgdev, output->index, handle,
+					   plane->state->crtc_w,
+					   plane->state->crtc_h,
+					   plane->state->crtc_x,
+					   plane->state->crtc_y);
+		virtio_gpu_cmd_resource_flush(vgdev, handle,
+					      plane->state->crtc_x,
+					      plane->state->crtc_y,
+					      plane->state->crtc_w,
+					      plane->state->crtc_h);
+		break;
+
+	default:
+		WARN_ON(true);
+	}
 }
 
 
@@ -105,21 +167,29 @@ static const struct drm_plane_helper_funcs virtio_gpu_plane_helper_funcs = {
 };
 
 struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev,
+					enum drm_plane_type type,
 					int index)
 {
 	struct drm_device *dev = vgdev->ddev;
 	struct drm_plane *plane;
-	int ret;
+	const uint32_t *formats;
+	int ret, nformats;
 
 	plane = kzalloc(sizeof(*plane), GFP_KERNEL);
 	if (!plane)
 		return ERR_PTR(-ENOMEM);
 
+	if (type == DRM_PLANE_TYPE_CURSOR) {
+		formats = virtio_gpu_cursor_formats;
+		nformats = ARRAY_SIZE(virtio_gpu_cursor_formats);
+	} else {
+		formats = virtio_gpu_formats;
+		nformats = ARRAY_SIZE(virtio_gpu_formats);
+	}
 	ret = drm_universal_plane_init(dev, plane, 1 << index,
 				       &virtio_gpu_plane_funcs,
-				       virtio_gpu_formats,
-				       ARRAY_SIZE(virtio_gpu_formats),
-				       DRM_PLANE_TYPE_PRIMARY, NULL);
+				       formats, nformats,
+				       type, NULL);
 	if (ret)
 		goto err_plane_init;
 
-- 
1.8.3.1


  parent reply	other threads:[~2016-05-27  7:48 UTC|newest]

Thread overview: 98+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-24 16:07 [PATCH] Add virtio gpu driver Gerd Hoffmann
2015-03-24 16:07 ` Gerd Hoffmann
2015-03-24 16:15 ` Michael S. Tsirkin
2015-03-25 14:52   ` Gerd Hoffmann
2015-03-25 14:52     ` Gerd Hoffmann
2015-03-25 15:24     ` Michael S. Tsirkin
     [not found]     ` <1427295121.23304.5.camel-3OfP5uLMi4C46o+2HkPkLj4oCIwMql/M@public.gmane.org>
2015-03-25 15:24       ` Michael S. Tsirkin
2015-03-25 15:24         ` Michael S. Tsirkin
2015-03-25 15:37         ` Gerd Hoffmann
2015-03-25 15:37         ` Gerd Hoffmann
2015-03-25 15:37           ` Gerd Hoffmann
2015-03-25 17:09           ` Michael S. Tsirkin
2015-03-26  7:12             ` Gerd Hoffmann
2015-03-26  7:12               ` Gerd Hoffmann
     [not found]               ` <1427353959.9779.2.camel-3OfP5uLMi4C46o+2HkPkLj4oCIwMql/M@public.gmane.org>
2015-03-26  8:18                 ` Michael S. Tsirkin
2015-03-26  8:18                   ` Michael S. Tsirkin
2015-03-26  8:42                   ` [virtio-dev] " Gerd Hoffmann
2015-03-26  8:42                     ` Gerd Hoffmann
2015-03-26  9:04                     ` Michael S. Tsirkin
2015-03-26  9:04                     ` Michael S. Tsirkin
2015-03-26  9:04                       ` Michael S. Tsirkin
2015-03-26 11:38                       ` Gerd Hoffmann
2015-03-26 11:38                         ` Gerd Hoffmann
2015-03-26 11:53                         ` Michael S. Tsirkin
     [not found]                         ` <1427369923.9779.18.camel-3OfP5uLMi4C46o+2HkPkLj4oCIwMql/M@public.gmane.org>
2015-03-26 11:53                           ` Michael S. Tsirkin
2015-03-26 11:53                             ` Michael S. Tsirkin
2015-03-26 15:07                             ` Gerd Hoffmann
2015-03-26 15:07                               ` Gerd Hoffmann
2015-03-26 16:47                               ` Michael S. Tsirkin
     [not found]                               ` <1427382436.8786.15.camel-3OfP5uLMi4C46o+2HkPkLj4oCIwMql/M@public.gmane.org>
2015-03-26 16:47                                 ` Michael S. Tsirkin
2015-03-26 16:47                                   ` Michael S. Tsirkin
2015-03-26 22:49                                   ` Alex Elsayed
2015-03-27  8:08                                   ` Gerd Hoffmann
2015-03-27  8:08                                   ` Gerd Hoffmann
2015-03-26 15:07                             ` Gerd Hoffmann
2015-03-26 16:52                         ` One Thousand Gnomes
2015-03-26 16:52                         ` One Thousand Gnomes
2015-03-26 11:38                       ` Gerd Hoffmann
2015-03-26  8:42                   ` Gerd Hoffmann
2015-03-26  8:18               ` Michael S. Tsirkin
2015-03-26  7:12             ` Gerd Hoffmann
2015-03-25 17:09           ` Michael S. Tsirkin
2015-03-25 14:52   ` Gerd Hoffmann
2015-03-24 16:15 ` Michael S. Tsirkin
     [not found] ` <1427213239-8775-1-git-send-email-kraxel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2015-03-24 16:50   ` Daniel Vetter
2015-03-24 16:50     ` Daniel Vetter
2015-03-25 14:53     ` Gerd Hoffmann
2015-03-25 14:53       ` Gerd Hoffmann
2015-03-26  8:53       ` Daniel Vetter
     [not found]       ` <1427295189.23304.6.camel-3OfP5uLMi4C46o+2HkPkLj4oCIwMql/M@public.gmane.org>
2015-03-26  8:53         ` Daniel Vetter
2015-03-26  8:53           ` Daniel Vetter
2015-03-30 12:23     ` Gerd Hoffmann
2015-03-30 12:23     ` Gerd Hoffmann
2015-03-30 12:23       ` Gerd Hoffmann
2015-03-30 14:49       ` Daniel Vetter
2016-05-25 16:40         ` Daniel Vetter
2016-05-25 16:44           ` Emil Velikov
     [not found]           ` <CAKMK7uFUNT193f5djZD6T8cgRxxnZL73yrqbupPHOd2P-+Y=pQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-05-25 16:44             ` Emil Velikov
2016-05-25 16:44               ` Emil Velikov
2016-05-27  7:48             ` Gerd Hoffmann [this message]
2016-05-27  7:48               ` Gerd Hoffmann
2016-05-27  9:03               ` Daniel Vetter
2016-05-27  9:03                 ` Daniel Vetter
2016-05-30 13:50                 ` Gerd Hoffmann
2016-05-30 13:50                 ` Gerd Hoffmann
2016-05-30 14:47                   ` Daniel Vetter
2016-05-30 14:47                   ` Daniel Vetter
2016-05-30 14:47                     ` Daniel Vetter
2016-05-31  6:29                     ` Gerd Hoffmann
2016-05-31  6:55                       ` Daniel Vetter
     [not found]                       ` <1464676160.5978.24.camel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-05-31  6:55                         ` Daniel Vetter
2016-05-31  6:55                           ` Daniel Vetter
2016-05-31  7:00                         ` Pekka Paalanen
2016-05-31  7:00                           ` Pekka Paalanen
2016-05-31  7:00                       ` Pekka Paalanen
2016-05-31  6:29                     ` Gerd Hoffmann
2016-05-27  9:03               ` Daniel Vetter
2016-05-27  7:48           ` Gerd Hoffmann
2016-05-25 16:40         ` Daniel Vetter
2015-03-30 14:49       ` Daniel Vetter
2015-03-24 20:47   ` Paul Bolle
2015-03-24 20:47     ` Paul Bolle
2015-03-24 22:50   ` Daniel Stone
2015-03-24 22:50     ` Daniel Stone
     [not found]     ` <CAPj87rN4pXHukDRD-e=ZrO1hcts04cSz1Hr9TNAgicGVWE5_-Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-03-25  0:00       ` Dave Airlie
2015-03-25  0:00         ` Dave Airlie
2015-03-25  5:47         ` Daniel Stone
2015-03-25  5:47         ` Daniel Stone
2015-03-25  0:00     ` Dave Airlie
2015-03-25 15:19     ` Gerd Hoffmann
2015-03-25 15:19     ` Gerd Hoffmann
2015-03-25 15:19       ` Gerd Hoffmann
2015-03-24 16:50 ` Daniel Vetter
2015-03-24 17:04 ` Michael S. Tsirkin
2015-03-24 17:04   ` Michael S. Tsirkin
2015-03-24 17:04 ` Michael S. Tsirkin
2015-03-24 20:47 ` Paul Bolle
2015-03-24 22:50 ` Daniel Stone

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1464335302.10663.10.camel@redhat.com \
    --to=kraxel-h+wxahxf7alqt0dzr+alfa@public.gmane.org \
    --cc=airlied-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
    --cc=daniel-/w4YWyX8dFk@public.gmane.org \
    --cc=dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    --cc=linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=mst-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
    --cc=rusty-8n+1lVoiYb80n/F98K4Iww@public.gmane.org \
    --cc=virtio-dev-sDuHXQ4OtrM4h7I2RyI4rWD2FQJk+8+b@public.gmane.org \
    --cc=virtualization-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.