From: Dillon Amburgey <dillona@gmail.com>
To: dri-devel@lists.freedesktop.org
Cc: airlied@redhat.com, airlied@gmail.com, kraxel@redhat.com,
maarten.lankhorst@linux.intel.com, mripard@kernel.org,
tzimmermann@suse.de, simona@ffwll.ch,
virtualization@lists.linux.dev,
spice-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org
Subject: [PATCH] drm/qxl: size packed dumb heads from the plane source
Date: Wed, 23 Sep 2026 22:52:22 -0400 [thread overview]
Message-ID: <20260924025222.6077-1-dillona@gmail.com> (raw)
QXL packs per-CRTC dumb buffers into a single primary surface.
qxl_update_dumb_head() recorded each dumb BO allocation (bo->surf)
instead of the plane source rectangle. Scanning 1280x800 from a
2048x1024 dumb framebuffer beside a 1024x768 head therefore created
a 3072x1024 primary and placed head 1 at +2048, rather than 2304x800
with head 1 at +1280.
Use src_w/src_h when building the packed shadow, and copy only that
source rectangle into it.
Fixes: 90adda2ce898 ("drm/qxl: cover all crtcs in shadow bo.")
Assisted-by: LLM sparse
Signed-off-by: Dillon Amburgey <dillona@gmail.com>
---
Tested on torvalds/linux 62f4c998b297. A DRM client (not Xorg, not
SPICE) programmed one QXL device with max_outputs=2. CRTC 0 scans a
1280x800 rectangle from a 2048x1024 dumb framebuffer (the allocation
is larger than the scanout). CRTC 1 scans a separate 1024x768 dumb
framebuffer. Unpatched, qxl_update_dumb_head() sizes packed heads
from bo->surf, so QEMU's qxl_create_guest_primary is 3072x1024
(2048+1024 by max height) and monitors_config places head 1 at +2048.
With this patch, the primary is 2304x800 (1280+1024) and head 1 is at
+1280.
Content outside CRTC 0's 1280x800 source rectangle did not appear in
the packed primary, and both heads' source rectangles did.
checkpatch.pl --strict: 0 errors, 0 warnings, 0 checks. W=1 and Sparse
on drivers/gpu/drm/qxl/qxl_display.c added no warnings.
drivers/gpu/drm/qxl/qxl_display.c | 39 ++++++++++++++++---------------
1 file changed, 20 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
index 0719fc6a52d5..e57aeeb97f84 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -670,13 +670,17 @@ static void qxl_primary_atomic_update(struct drm_plane *plane,
struct qxl_device *qdev = to_qxl(plane->dev);
struct qxl_bo *bo = gem_to_qxl_bo(new_state->fb->obj[0]);
struct qxl_bo *primary;
- struct drm_clip_rect norect = {
- .x1 = 0,
- .y1 = 0,
- .x2 = new_state->fb->width,
- .y2 = new_state->fb->height
- };
+ struct drm_clip_rect norect;
uint32_t dumb_shadow_offset = 0;
+ u32 src_x = new_state->src_x >> 16;
+ u32 src_y = new_state->src_y >> 16;
+ u32 src_w = new_state->src_w >> 16;
+ u32 src_h = new_state->src_h >> 16;
+
+ norect.x1 = src_x;
+ norect.y1 = src_y;
+ norect.x2 = src_x + src_w;
+ norect.y2 = src_y + src_h;
primary = bo->shadow ? bo->shadow : bo;
@@ -689,7 +693,7 @@ static void qxl_primary_atomic_update(struct drm_plane *plane,
if (bo->is_dumb)
dumb_shadow_offset =
- qdev->dumb_heads[new_state->crtc->index].x;
+ qdev->dumb_heads[new_state->crtc->index].x - src_x;
qxl_draw_dirty_fb(qdev, new_state->fb, bo, 0, 0, &norect, 1, 1,
dumb_shadow_offset);
@@ -764,18 +768,14 @@ static void qxl_cursor_atomic_disable(struct drm_plane *plane,
qcrtc->cursor_bo = NULL;
}
-static void qxl_update_dumb_head(struct qxl_device *qdev,
- int index, struct qxl_bo *bo)
+static void qxl_update_dumb_head(struct qxl_device *qdev, int index,
+ struct qxl_bo *bo, uint32_t width,
+ uint32_t height)
{
- uint32_t width, height;
-
if (index >= qdev->monitors_config->max_allowed)
return;
- if (bo && bo->is_dumb) {
- width = bo->surf.width;
- height = bo->surf.height;
- } else {
+ if (!bo || !bo->is_dumb) {
width = 0;
height = 0;
}
@@ -820,12 +820,11 @@ static void qxl_calc_dumb_shadow(struct qxl_device *qdev,
}
static void qxl_prepare_shadow(struct qxl_device *qdev, struct qxl_bo *user_bo,
- int crtc_index)
+ int crtc_index, uint32_t width, uint32_t height)
{
struct qxl_surface surf;
- qxl_update_dumb_head(qdev, crtc_index,
- user_bo);
+ qxl_update_dumb_head(qdev, crtc_index, user_bo, width, height);
qxl_calc_dumb_shadow(qdev, &surf);
if (!qdev->dumb_shadow_bo ||
qdev->dumb_shadow_bo->surf.width != surf.width ||
@@ -869,7 +868,9 @@ static int qxl_plane_prepare_fb(struct drm_plane *plane,
if (plane->type == DRM_PLANE_TYPE_PRIMARY &&
user_bo->is_dumb) {
- qxl_prepare_shadow(qdev, user_bo, new_state->crtc->index);
+ qxl_prepare_shadow(qdev, user_bo, new_state->crtc->index,
+ new_state->src_w >> 16,
+ new_state->src_h >> 16);
}
if (plane->type == DRM_PLANE_TYPE_CURSOR &&
base-commit: 62f4c998b297cf233997a2b4cd6fc2d2df0319c9
--
2.43.0
next reply other threads:[~2026-09-24 2:53 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-24 2:52 Dillon Amburgey [this message]
2026-09-24 3:06 ` [PATCH] drm/qxl: size packed dumb heads from the plane source sashiko-bot
2026-09-25 3:30 ` [PATCH v2] " Dillon Amburgey
2026-09-25 3:42 ` sashiko-bot
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=20260924025222.6077-1-dillona@gmail.com \
--to=dillona@gmail.com \
--cc=airlied@gmail.com \
--cc=airlied@redhat.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=kraxel@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=simona@ffwll.ch \
--cc=spice-devel@lists.freedesktop.org \
--cc=tzimmermann@suse.de \
--cc=virtualization@lists.linux.dev \
/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.