On Thu, 15 Jan 2026, Chad Jablonski wrote:
Use scissor registers to clip blit operations. This is required
for text rendering in X using the r128 driver. Without it overly-wide
glyphs are drawn and create all sorts of chaos.

The visible destination rectangle (vis_dst) is the intersection of the
scissor rectangle and the destination rectangle (dst.rect).

The src also needs to be offset if clipped on the top and/or
left sides to ensure that src data is read correctly and appears
clipped when drawn rather than shifted.

Signed-off-by: Chad Jablonski <[email protected]>
---
hw/display/ati_2d.c | 81 ++++++++++++++++++++++++++++-----------------
1 file changed, 50 insertions(+), 31 deletions(-)

diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c
index 691e0f0702..a5dc5ba98e 100644
--- a/hw/display/ati_2d.c
+++ b/hw/display/ati_2d.c
@@ -86,7 +86,8 @@ static void ati_2d_do_blt(ATIVGAState *s, const ATIBltSrc 
*src, ATIBltDst *dst)
    /* rewritten but for now as a start just to get some output: */
    DisplaySurface *ds = qemu_console_surface(s->vga.con);
    uint8_t *end = s->vga.vram_ptr + s->vga.vram_size;
-    int dst_stride_words, src_stride_words;
+    int dst_stride_words, src_stride_words, vis_src_x, vis_src_y;
+    QemuRect scissor, vis_dst;

    DPRINTF("%p %u ds: %p %d %d rop: %x\n", s->vga.vram_ptr,
            s->vga.vbe_start_addr, surface_data(ds), surface_stride(ds),
@@ -108,14 +109,32 @@ static void ati_2d_do_blt(ATIVGAState *s, const ATIBltSrc 
*src, ATIBltDst *dst)
        return;
    }

+    qemu_rect_init(&scissor,
+                   s->regs.sc_left, s->regs.sc_top,
+                   s->regs.sc_right - s->regs.sc_left + 1,
+                   s->regs.sc_bottom - s->regs.sc_top + 1);
+    qemu_rect_intersect(&dst->rect, &scissor, &vis_dst);

Is there a bit somewhere that enables clipping that needs to be checked here? Or are the sc regs always expected to have meaningful values and clipping is always done?

+    if (!vis_dst.height || !vis_dst.width) {
+        /* Nothing to do, completely clipped */

It's less clear what vis means so maybe this comment could clarify by saying Nothing is visible, completely clipped.

Regards,
BALATON Zoltan

Reply via email to