lkundrak / rpms / kernel

Forked from rpms/kernel 4 years ago
Clone
c75cb4d
From 56cbcb6c41932b19ef0d838f1ff25a662a2e403d Mon Sep 17 00:00:00 2001
ec3df71
From: Gerd Hoffmann <kraxel@redhat.com>
c75cb4d
Date: Thu, 19 Oct 2017 08:21:49 +0200
c75cb4d
Subject: [PATCH] drm/qxl: replace QXL_INFO with DRM_DEBUG_DRIVER
ec3df71
c75cb4d
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
c75cb4d
Reviewed-by: Dave Airlie <airlied@redhat.com>
c75cb4d
Link: http://patchwork.freedesktop.org/patch/msgid/20171019062150.28090-2-kraxel@redhat.com
c75cb4d
---
c75cb4d
 drivers/gpu/drm/qxl/qxl_cmd.c     | 16 +++++++---------
c75cb4d
 drivers/gpu/drm/qxl/qxl_drv.h     | 26 +-------------------------
c75cb4d
 drivers/gpu/drm/qxl/qxl_fb.c      | 13 +++++--------
c75cb4d
 drivers/gpu/drm/qxl/qxl_release.c |  5 ++---
c75cb4d
 drivers/gpu/drm/qxl/qxl_ttm.c     |  4 ++--
c75cb4d
 5 files changed, 17 insertions(+), 47 deletions(-)
ec3df71
c75cb4d
diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c
c75cb4d
index 74fc9362ecf9..8ec53d5abd62 100644
c75cb4d
--- a/drivers/gpu/drm/qxl/qxl_cmd.c
c75cb4d
+++ b/drivers/gpu/drm/qxl/qxl_cmd.c
c75cb4d
@@ -219,7 +219,7 @@ int qxl_garbage_collect(struct qxl_device *qdev)
c75cb4d
 	union qxl_release_info *info;
ec3df71
c75cb4d
 	while (qxl_ring_pop(qdev->release_ring, &id)) {
c75cb4d
-		QXL_INFO(qdev, "popped %lld\n", id);
c75cb4d
+		DRM_DEBUG_DRIVER("popped %lld\n", id);
c75cb4d
 		while (id) {
c75cb4d
 			release = qxl_release_from_id_locked(qdev, id);
c75cb4d
 			if (release == NULL)
c75cb4d
@@ -229,8 +229,8 @@ int qxl_garbage_collect(struct qxl_device *qdev)
c75cb4d
 			next_id = info->next;
c75cb4d
 			qxl_release_unmap(qdev, release, info);
ec3df71
c75cb4d
-			QXL_INFO(qdev, "popped %lld, next %lld\n", id,
c75cb4d
-				next_id);
c75cb4d
+			DRM_DEBUG_DRIVER("popped %lld, next %lld\n", id,
c75cb4d
+					 next_id);
ec3df71
c75cb4d
 			switch (release->type) {
c75cb4d
 			case QXL_RELEASE_DRAWABLE:
c75cb4d
@@ -248,7 +248,7 @@ int qxl_garbage_collect(struct qxl_device *qdev)
c75cb4d
 		}
ec3df71
 	}
c75cb4d
c75cb4d
-	QXL_INFO(qdev, "%s: %d\n", __func__, i);
c75cb4d
+	DRM_DEBUG_DRIVER("%d\n", i);
c75cb4d
c75cb4d
 	return i;
ec3df71
 }
c75cb4d
@@ -381,8 +381,7 @@ void qxl_io_create_primary(struct qxl_device *qdev,
ec3df71
 {
c75cb4d
 	struct qxl_surface_create *create;
c75cb4d
c75cb4d
-	QXL_INFO(qdev, "%s: qdev %p, ram_header %p\n", __func__, qdev,
c75cb4d
-		 qdev->ram_header);
c75cb4d
+	DRM_DEBUG_DRIVER("qdev %p, ram_header %p\n", qdev, qdev->ram_header);
c75cb4d
 	create = &qdev->ram_header->create_surface;
c75cb4d
 	create->format = bo->surf.format;
c75cb4d
 	create->width = bo->surf.width;
c75cb4d
@@ -390,8 +389,7 @@ void qxl_io_create_primary(struct qxl_device *qdev,
c75cb4d
 	create->stride = bo->surf.stride;
c75cb4d
 	create->mem = qxl_bo_physical_address(qdev, bo, offset);
c75cb4d
c75cb4d
-	QXL_INFO(qdev, "%s: mem = %llx, from %p\n", __func__, create->mem,
c75cb4d
-		 bo->kptr);
c75cb4d
+	DRM_DEBUG_DRIVER("mem = %llx, from %p\n", create->mem, bo->kptr);
c75cb4d
c75cb4d
 	create->flags = QXL_SURF_FLAG_KEEP_DATA;
c75cb4d
 	create->type = QXL_SURF_TYPE_PRIMARY;
c75cb4d
@@ -401,7 +399,7 @@ void qxl_io_create_primary(struct qxl_device *qdev,
c75cb4d
c75cb4d
 void qxl_io_memslot_add(struct qxl_device *qdev, uint8_t id)
c75cb4d
 {
c75cb4d
-	QXL_INFO(qdev, "qxl_memslot_add %d\n", id);
c75cb4d
+	DRM_DEBUG_DRIVER("qxl_memslot_add %d\n", id);
c75cb4d
 	wait_for_io_cmd(qdev, id, QXL_IO_MEMSLOT_ADD_ASYNC);
ec3df71
 }
ec3df71
c75cb4d
diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
c75cb4d
index 3397a1907336..d707b351875c 100644
c75cb4d
--- a/drivers/gpu/drm/qxl/qxl_drv.h
c75cb4d
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
c75cb4d
@@ -62,33 +62,9 @@
c820b80
c75cb4d
 #define QXL_DEBUGFS_MAX_COMPONENTS		32
c820b80
c75cb4d
-extern int qxl_log_level;
c75cb4d
 extern int qxl_num_crtc;
c75cb4d
 extern int qxl_max_ioctls;
c820b80
c75cb4d
-enum {
c75cb4d
-	QXL_INFO_LEVEL = 1,
c75cb4d
-	QXL_DEBUG_LEVEL = 2,
c75cb4d
-};
c75cb4d
-
c75cb4d
-#define QXL_INFO(qdev, fmt, ...) do { \
c75cb4d
-		if (qxl_log_level >= QXL_INFO_LEVEL) {	\
c75cb4d
-			qxl_io_log(qdev, fmt, __VA_ARGS__); \
c75cb4d
-		}	\
c75cb4d
-	} while (0)
c75cb4d
-#define QXL_DEBUG(qdev, fmt, ...) do { \
c75cb4d
-		if (qxl_log_level >= QXL_DEBUG_LEVEL) {	\
c75cb4d
-			qxl_io_log(qdev, fmt, __VA_ARGS__); \
c75cb4d
-		}	\
c75cb4d
-	} while (0)
c75cb4d
-#define QXL_INFO_ONCE(qdev, fmt, ...) do { \
c75cb4d
-		static int done;		\
c75cb4d
-		if (!done) {			\
c75cb4d
-			done = 1;			\
c75cb4d
-			QXL_INFO(qdev, fmt, __VA_ARGS__);	\
c75cb4d
-		}						\
c75cb4d
-	} while (0)
c75cb4d
-
c75cb4d
 #define DRM_FILE_OFFSET 0x100000000ULL
c75cb4d
 #define DRM_FILE_PAGE_OFFSET (DRM_FILE_OFFSET >> PAGE_SHIFT)
c75cb4d
c75cb4d
@@ -351,7 +327,7 @@ int qxl_check_idle(struct qxl_ring *ring);
c75cb4d
 static inline void *
c75cb4d
 qxl_fb_virtual_address(struct qxl_device *qdev, unsigned long physical)
c75cb4d
 {
c75cb4d
-	QXL_INFO(qdev, "not implemented (%lu)\n", physical);
c75cb4d
+	DRM_DEBUG_DRIVER("not implemented (%lu)\n", physical);
c75cb4d
 	return 0;
c75cb4d
 }
c75cb4d
c75cb4d
diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c
c75cb4d
index 844c4a31ca13..23af3e352673 100644
c75cb4d
--- a/drivers/gpu/drm/qxl/qxl_fb.c
c75cb4d
+++ b/drivers/gpu/drm/qxl/qxl_fb.c
c75cb4d
@@ -240,18 +240,15 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev,
c75cb4d
 		return ret;
c75cb4d
c75cb4d
 	qbo = gem_to_qxl_bo(gobj);
c75cb4d
-	QXL_INFO(qdev, "%s: %dx%d %d\n", __func__, mode_cmd.width,
c75cb4d
-		 mode_cmd.height, mode_cmd.pitches[0]);
c75cb4d
+	DRM_DEBUG_DRIVER("%dx%d %d\n", mode_cmd.width,
c75cb4d
+			 mode_cmd.height, mode_cmd.pitches[0]);
c75cb4d
c75cb4d
 	shadow = vmalloc(mode_cmd.pitches[0] * mode_cmd.height);
c75cb4d
 	/* TODO: what's the usual response to memory allocation errors? */
c75cb4d
 	BUG_ON(!shadow);
c75cb4d
-	QXL_INFO(qdev,
c75cb4d
-	"surface0 at gpu offset %lld, mmap_offset %lld (virt %p, shadow %p)\n",
c75cb4d
-		 qxl_bo_gpu_offset(qbo),
c75cb4d
-		 qxl_bo_mmap_offset(qbo),
c75cb4d
-		 qbo->kptr,
c75cb4d
-		 shadow);
c75cb4d
+	DRM_DEBUG_DRIVER("surface0 at gpu offset %lld, mmap_offset %lld (virt %p, shadow %p)\n",
c75cb4d
+			 qxl_bo_gpu_offset(qbo), qxl_bo_mmap_offset(qbo),
c75cb4d
+			 qbo->kptr, shadow);
c75cb4d
 	size = mode_cmd.pitches[0] * mode_cmd.height;
c75cb4d
c75cb4d
 	info = drm_fb_helper_alloc_fbi(&qfbdev->helper);
c75cb4d
diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c
c75cb4d
index e6ec845b5be0..a6da6fa6ad58 100644
c75cb4d
--- a/drivers/gpu/drm/qxl/qxl_release.c
c75cb4d
+++ b/drivers/gpu/drm/qxl/qxl_release.c
c75cb4d
@@ -154,7 +154,7 @@ qxl_release_alloc(struct qxl_device *qdev, int type,
c75cb4d
 		return handle;
c820b80
 	}
c75cb4d
 	*ret = release;
c75cb4d
-	QXL_INFO(qdev, "allocated release %d\n", handle);
c75cb4d
+	DRM_DEBUG_DRIVER("allocated release %d\n", handle);
c75cb4d
 	release->id = handle;
c75cb4d
 	return handle;
c820b80
 }
c75cb4d
@@ -179,8 +179,7 @@ void
c75cb4d
 qxl_release_free(struct qxl_device *qdev,
c75cb4d
 		 struct qxl_release *release)
c75cb4d
 {
c75cb4d
-	QXL_INFO(qdev, "release %d, type %d\n", release->id,
c75cb4d
-		 release->type);
c75cb4d
+	DRM_DEBUG_DRIVER("release %d, type %d\n", release->id, release->type);
c75cb4d
c75cb4d
 	if (release->surface_release_id)
c75cb4d
 		qxl_surface_id_dealloc(qdev, release->surface_release_id);
c75cb4d
diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c
c75cb4d
index 7ecf8a4b9fe6..ab4823875311 100644
c75cb4d
--- a/drivers/gpu/drm/qxl/qxl_ttm.c
c75cb4d
+++ b/drivers/gpu/drm/qxl/qxl_ttm.c
c75cb4d
@@ -136,8 +136,8 @@ int qxl_mmap(struct file *filp, struct vm_area_struct *vma)
c75cb4d
 		 "filp->private_data->minor->dev->dev_private == NULL\n");
c75cb4d
 		return -EINVAL;
c75cb4d
 	}
c75cb4d
-	QXL_INFO(qdev, "%s: filp->private_data = 0x%p, vma->vm_pgoff = %lx\n",
c75cb4d
-		 __func__, filp->private_data, vma->vm_pgoff);
c75cb4d
+	DRM_DEBUG_DRIVER("filp->private_data = 0x%p, vma->vm_pgoff = %lx\n",
c75cb4d
+		  filp->private_data, vma->vm_pgoff);
c75cb4d
c75cb4d
 	r = ttm_bo_mmap(filp, vma, &qdev->mman.bdev);
c75cb4d
 	if (unlikely(r != 0))
c820b80
-- 
c75cb4d
2.14.3
c820b80
c75cb4d
From 62676d10b483a2ff6e8b08c5e7c7d63a831343f5 Mon Sep 17 00:00:00 2001
ec3df71
From: Gerd Hoffmann <kraxel@redhat.com>
c75cb4d
Date: Thu, 19 Oct 2017 08:21:50 +0200
c75cb4d
Subject: [PATCH] qxl: alloc & use shadow for dumb buffers
ec3df71
ec3df71
This patch changes the way the primary surface is used for dumb
ec3df71
framebuffers.  Instead of configuring the bo itself as primary surface
ec3df71
a shadow bo is created and used instead.  Framebuffers can share the
ec3df71
shadow bo in case they have the same format and resolution.
ec3df71
ec3df71
On atomic plane updates we don't have to update the primary surface in
ec3df71
case we pageflip from one framebuffer to another framebuffer which
ec3df71
shares the same shadow.  This in turn avoids the flicker caused by the
ec3df71
primary-destroy + primary-create cycle, which is very annonying when
ec3df71
running wayland on qxl.
ec3df71
ec3df71
The qxl driver never actually writes to the shadow bo.  It sends qxl
ec3df71
blit commands which update it though, and the spice server might
ec3df71
actually execute them (and thereby write to the shadow) in case the
ec3df71
local rendering is kicked for some reason.  This happens for example in
ec3df71
case qemu is asked to write out a dump of the guest display (screendump
ec3df71
monitor command).
ec3df71
ec3df71
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
c75cb4d
Reviewed-by: Dave Airlie <airlied@redhat.com>
c75cb4d
Link: http://patchwork.freedesktop.org/patch/msgid/20171019062150.28090-3-kraxel@redhat.com
ec3df71
---
ec3df71
 drivers/gpu/drm/qxl/qxl_cmd.c     |  6 ++++-
ec3df71
 drivers/gpu/drm/qxl/qxl_display.c | 49 ++++++++++++++++++++++++++++++++++++---
ec3df71
 drivers/gpu/drm/qxl/qxl_drv.h     |  2 ++
ec3df71
 drivers/gpu/drm/qxl/qxl_dumb.c    |  1 +
ec3df71
 4 files changed, 54 insertions(+), 4 deletions(-)
ec3df71
ec3df71
diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c
c75cb4d
index 8ec53d5abd62..c0fb52c6d4ca 100644
ec3df71
--- a/drivers/gpu/drm/qxl/qxl_cmd.c
ec3df71
+++ b/drivers/gpu/drm/qxl/qxl_cmd.c
c75cb4d
@@ -387,7 +387,11 @@ void qxl_io_create_primary(struct qxl_device *qdev,
ec3df71
 	create->width = bo->surf.width;
ec3df71
 	create->height = bo->surf.height;
ec3df71
 	create->stride = bo->surf.stride;
ec3df71
-	create->mem = qxl_bo_physical_address(qdev, bo, offset);
ec3df71
+	if (bo->shadow) {
ec3df71
+		create->mem = qxl_bo_physical_address(qdev, bo->shadow, offset);
ec3df71
+	} else {
ec3df71
+		create->mem = qxl_bo_physical_address(qdev, bo, offset);
ec3df71
+	}
801d191
c75cb4d
 	DRM_DEBUG_DRIVER("mem = %llx, from %p\n", create->mem, bo->kptr);
c75cb4d
ec3df71
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
c75cb4d
index afbf50d0c08f..4756b3c9bf2c 100644
ec3df71
--- a/drivers/gpu/drm/qxl/qxl_display.c
ec3df71
+++ b/drivers/gpu/drm/qxl/qxl_display.c
ec3df71
@@ -305,7 +305,9 @@ static const struct drm_crtc_funcs qxl_crtc_funcs = {
ec3df71
 void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb)
ec3df71
 {
ec3df71
 	struct qxl_framebuffer *qxl_fb = to_qxl_framebuffer(fb);
ec3df71
+	struct qxl_bo *bo = gem_to_qxl_bo(qxl_fb->obj);
801d191
ec3df71
+	WARN_ON(bo->shadow);
ec3df71
 	drm_gem_object_unreference_unlocked(qxl_fb->obj);
ec3df71
 	drm_framebuffer_cleanup(fb);
ec3df71
 	kfree(qxl_fb);
c75cb4d
@@ -508,6 +510,7 @@ static void qxl_primary_atomic_update(struct drm_plane *plane,
ec3df71
 	    .x2 = qfb->base.width,
ec3df71
 	    .y2 = qfb->base.height
ec3df71
 	};
ec3df71
+	bool same_shadow = false;
801d191
ec3df71
 	if (old_state->fb) {
ec3df71
 		qfb_old = to_qxl_framebuffer(old_state->fb);
c75cb4d
@@ -519,15 +522,23 @@ static void qxl_primary_atomic_update(struct drm_plane *plane,
ec3df71
 	if (bo == bo_old)
ec3df71
 		return;
801d191
ec3df71
+	if (bo_old && bo_old->shadow && bo->shadow &&
ec3df71
+	    bo_old->shadow == bo->shadow) {
ec3df71
+		same_shadow = true;
ec3df71
+	}
ec3df71
+
ec3df71
 	if (bo_old && bo_old->is_primary) {
ec3df71
-		qxl_io_destroy_primary(qdev);
ec3df71
+		if (!same_shadow)
ec3df71
+			qxl_io_destroy_primary(qdev);
ec3df71
 		bo_old->is_primary = false;
ec3df71
 	}
801d191
ec3df71
 	if (!bo->is_primary) {
ec3df71
-		qxl_io_create_primary(qdev, 0, bo);
ec3df71
+		if (!same_shadow)
ec3df71
+			qxl_io_create_primary(qdev, 0, bo);
ec3df71
 		bo->is_primary = true;
ec3df71
 	}
ec3df71
+
ec3df71
 	qxl_draw_dirty_fb(qdev, qfb, bo, 0, 0, &norect, 1, 1);
ec3df71
 }
801d191
c75cb4d
@@ -679,8 +690,9 @@ static void qxl_cursor_atomic_disable(struct drm_plane *plane,
c75cb4d
 static int qxl_plane_prepare_fb(struct drm_plane *plane,
c75cb4d
 				struct drm_plane_state *new_state)
ec3df71
 {
ec3df71
+	struct qxl_device *qdev = plane->dev->dev_private;
ec3df71
 	struct drm_gem_object *obj;
ec3df71
-	struct qxl_bo *user_bo;
ec3df71
+	struct qxl_bo *user_bo, *old_bo = NULL;
ec3df71
 	int ret;
801d191
ec3df71
 	if (!new_state->fb)
c75cb4d
@@ -689,6 +701,32 @@ static int qxl_plane_prepare_fb(struct drm_plane *plane,
ec3df71
 	obj = to_qxl_framebuffer(new_state->fb)->obj;
ec3df71
 	user_bo = gem_to_qxl_bo(obj);
801d191
ec3df71
+	if (plane->type == DRM_PLANE_TYPE_PRIMARY &&
ec3df71
+	    user_bo->is_dumb && !user_bo->shadow) {
ec3df71
+		if (plane->state->fb) {
ec3df71
+			obj = to_qxl_framebuffer(plane->state->fb)->obj;
ec3df71
+			old_bo = gem_to_qxl_bo(obj);
ec3df71
+		}
ec3df71
+		if (old_bo && old_bo->shadow &&
ec3df71
+		    user_bo->gem_base.size == old_bo->gem_base.size &&
ec3df71
+		    plane->state->crtc     == new_state->crtc &&
ec3df71
+		    plane->state->crtc_w   == new_state->crtc_w &&
ec3df71
+		    plane->state->crtc_h   == new_state->crtc_h &&
ec3df71
+		    plane->state->src_x    == new_state->src_x &&
ec3df71
+		    plane->state->src_y    == new_state->src_y &&
ec3df71
+		    plane->state->src_w    == new_state->src_w &&
ec3df71
+		    plane->state->src_h    == new_state->src_h &&
ec3df71
+		    plane->state->rotation == new_state->rotation &&
ec3df71
+		    plane->state->zpos     == new_state->zpos) {
ec3df71
+			drm_gem_object_get(&old_bo->shadow->gem_base);
ec3df71
+			user_bo->shadow = old_bo->shadow;
ec3df71
+		} else {
ec3df71
+			qxl_bo_create(qdev, user_bo->gem_base.size,
ec3df71
+				      true, true, QXL_GEM_DOMAIN_VRAM, NULL,
ec3df71
+				      &user_bo->shadow);
ec3df71
+		}
ec3df71
+	}
ec3df71
+
ec3df71
 	ret = qxl_bo_pin(user_bo, QXL_GEM_DOMAIN_CPU, NULL);
ec3df71
 	if (ret)
ec3df71
 		return ret;
c75cb4d
@@ -713,6 +751,11 @@ static void qxl_plane_cleanup_fb(struct drm_plane *plane,
ec3df71
 	obj = to_qxl_framebuffer(old_state->fb)->obj;
ec3df71
 	user_bo = gem_to_qxl_bo(obj);
ec3df71
 	qxl_bo_unpin(user_bo);
ec3df71
+
ec3df71
+	if (user_bo->shadow && !user_bo->is_primary) {
ec3df71
+		drm_gem_object_put_unlocked(&user_bo->shadow->gem_base);
ec3df71
+		user_bo->shadow = NULL;
ec3df71
+	}
ec3df71
 }
801d191
ec3df71
 static const uint32_t qxl_cursor_plane_formats[] = {
ec3df71
diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
c75cb4d
index d707b351875c..08752c0ffb35 100644
ec3df71
--- a/drivers/gpu/drm/qxl/qxl_drv.h
ec3df71
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
c75cb4d
@@ -89,6 +89,8 @@ struct qxl_bo {
ec3df71
 	/* Constant after initialization */
ec3df71
 	struct drm_gem_object		gem_base;
ec3df71
 	bool is_primary; /* is this now a primary surface */
ec3df71
+	bool is_dumb;
ec3df71
+	struct qxl_bo *shadow;
ec3df71
 	bool hw_surf_alloc;
ec3df71
 	struct qxl_surface surf;
ec3df71
 	uint32_t surface_id;
ec3df71
diff --git a/drivers/gpu/drm/qxl/qxl_dumb.c b/drivers/gpu/drm/qxl/qxl_dumb.c
c75cb4d
index 5e65d5d2d937..11085ab01374 100644
ec3df71
--- a/drivers/gpu/drm/qxl/qxl_dumb.c
ec3df71
+++ b/drivers/gpu/drm/qxl/qxl_dumb.c
ec3df71
@@ -63,6 +63,7 @@ int qxl_mode_dumb_create(struct drm_file *file_priv,
ec3df71
 					      &handle);
ec3df71
 	if (r)
ec3df71
 		return r;
ec3df71
+	qobj->is_dumb = true;
ec3df71
 	args->pitch = pitch;
ec3df71
 	args->handle = handle;
ec3df71
 	return 0;
ec3df71
-- 
c75cb4d
2.14.3
ec3df71