On Thu, 15 Jan 2026, Chad Jablonski wrote:
A large amount of the common setup involved in a blit deals with the
destination. This moves that setup to a helper function which
initializes a struct (ATIBltDst) holding all of the dst state. This setup
will be shared between blits from memory as well as from HOST_DATA.

Otherwise this is a pure refactor of the ati_2d_blt function to make use
of the setup_2d_blt_dst helper and the struct it initializes. There should
be no change in behavior in this patch.

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

diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c
index a8c4c534b9..75bd38e9b0 100644
--- a/hw/display/ati_2d.c
+++ b/hw/display/ati_2d.c
@@ -13,6 +13,7 @@
#include "qemu/log.h"
#include "ui/pixel_ops.h"
#include "ui/console.h"
+#include "ui/rect.h"

/*
 * NOTE:
@@ -24,7 +25,16 @@
 * possible.
 */

-static int ati_bpp_from_datatype(ATIVGAState *s)
+typedef struct {
+    QemuRect rect;
+    int bpp;
+    int stride;
+    bool top_to_bottom;
+    bool left_to_right;
+    uint8_t *bits;
+} ATIBltDst;

I'll need to look at this and further patches in more detail but I wonder if we need separate types for BltDst and BltSrc or could we use a single type for both maybe not using some fields for Src. But if that would not simplify things then these can be separate too.

+
+static int ati_bpp_from_datatype(const ATIVGAState *s)
{
    switch (s->regs.dp_datatype & 0xf) {
    case 2:
@@ -43,57 +53,76 @@ static int ati_bpp_from_datatype(ATIVGAState *s)
    }
}

+static void setup_2d_blt_dst(const ATIVGAState *s, ATIBltDst *dst)
+{
+    unsigned dst_x, dst_y;
+    dst->bpp = ati_bpp_from_datatype(s);
+    dst->stride = s->regs.dst_pitch;
+    dst->left_to_right = s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT;
+    dst->top_to_bottom = s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM;
+    dst->bits = s->vga.vram_ptr + s->regs.dst_offset;
+    dst_x = (dst->left_to_right ?
+            s->regs.dst_x : s->regs.dst_x + 1 - s->regs.dst_width);
+    dst_y = (dst->top_to_bottom ?
+            s->regs.dst_y : s->regs.dst_y + 1 - s->regs.dst_height);
+    qemu_rect_init(&dst->rect, dst_x, dst_y,
+                   s->regs.dst_width, s->regs.dst_height);
+    if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
+        dst->bits += s->regs.crtc_offset & 0x07ffffff;
+        dst->stride *= dst->bpp;
+    }
+}
+
void ati_2d_blt(ATIVGAState *s)
{
    /* FIXME it is probably more complex than this and may need to be */
    /* 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;
+    ATIBltDst _dst; /* TEMP: avoid churn in future patches */
+    ATIBltDst *dst = &_dst;

These will be removed but names beginning with _ are reserved and should not be used so maybe this (and _src in next patch) should be dst_ or something else? Can the churn be avoided by reorganising changes or moving converting to pointer in a separate patch? This patch is quite long and mixes pointer conversion with other refactoring so separating those may help in review.

Regards,
BALATON Zoltan

Reply via email to