From: BALATON Zoltan <balaton@eik.bme.hu>
To: qemu-devel@nongnu.org
Cc: "Gerd Hoffmann" <kraxel@redhat.com>,
marcandre.lureau@redhat.com,
"Chad Jablonski" <chad@jablonski.xyz>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>
Subject: [PATCH v6 1/8] ati-vga: Fix colors when frame buffer endianness does not match host
Date: Sat, 21 Mar 2026 17:30:11 +0100 (CET) [thread overview]
Message-ID: <759ed5e3b019cce94e9a4ef003f1fc2e0cea2ec1.1774110169.git.balaton@eik.bme.hu> (raw)
In-Reply-To: <cover.1774110169.git.balaton@eik.bme.hu>
When writing pixels we have to take into account if the frame buffer
endianness matches the host endianness or we need to swap to correct
endianness. This caused wrong colors e.g. with PPC Linux guest that
uses big endian frame buffer when running on little endian host.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Tested-by: Chad Jablonski <chad@jablonski.xyz>
Reviewed-by: Chad Jablonski <chad@jablonski.xyz>
---
hw/display/ati_2d.c | 40 +++++++++++++++++++++++++++++-----------
1 file changed, 29 insertions(+), 11 deletions(-)
diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c
index 37fe6c17ee..0cbbdc33f4 100644
--- a/hw/display/ati_2d.c
+++ b/hw/display/ati_2d.c
@@ -50,6 +50,7 @@ typedef struct {
bool host_data_active;
bool left_to_right;
bool top_to_bottom;
+ bool need_swap;
uint32_t frgd_clr;
const uint8_t *palette;
const uint8_t *vram_end;
@@ -89,6 +90,7 @@ static void setup_2d_blt_ctx(const ATIVGAState *s, ATI2DCtx *ctx)
ctx->host_data_active = s->host_data.active;
ctx->left_to_right = s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT;
ctx->top_to_bottom = s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM;
+ ctx->need_swap = HOST_BIG_ENDIAN != s->vga.big_endian_fb ? true : false;
ctx->frgd_clr = s->regs.dp_brush_frgd_clr;
ctx->palette = s->vga.palette;
ctx->dst_offset = s->regs.dst_offset;
@@ -131,6 +133,17 @@ static void setup_2d_blt_ctx(const ATIVGAState *s, ATI2DCtx *ctx)
(ctx->top_to_bottom ? 'v' : '^'));
}
+static uint32_t make_filler(int bpp, uint32_t color)
+{
+ if (bpp < 24) {
+ color |= color << 16;
+ if (bpp < 15) {
+ color |= color << 8;
+ }
+ }
+ return color;
+}
+
static bool ati_2d_do_blt(ATI2DCtx *ctx, uint8_t use_pixman)
{
QemuRect vis_src, vis_dst;
@@ -255,7 +268,7 @@ static bool ati_2d_do_blt(ATI2DCtx *ctx, uint8_t use_pixman)
switch (ctx->rop3) {
case ROP3_PATCOPY:
- filler = ctx->frgd_clr;
+ filler = make_filler(ctx->bpp, ctx->frgd_clr);
break;
case ROP3_BLACKNESS:
filler = 0xffUL << 24 | rgb_to_pixel32(ctx->palette[0],
@@ -268,10 +281,12 @@ static bool ati_2d_do_blt(ATI2DCtx *ctx, uint8_t use_pixman)
ctx->palette[5]);
break;
}
-
DPRINTF("pixman_fill(%p, %ld, %d, %d, %d, %d, %d, %x)\n",
ctx->dst_bits, ctx->dst_stride / sizeof(uint32_t), ctx->bpp,
vis_dst.x, vis_dst.y, vis_dst.width, vis_dst.height, filler);
+ if (ctx->need_swap) {
+ bswap32s(&filler);
+ }
#ifdef CONFIG_PIXMAN
if (!(use_pixman & BIT(0)) ||
!pixman_fill((uint32_t *)ctx->dst_bits,
@@ -325,11 +340,8 @@ void ati_2d_blt(ATIVGAState *s)
bool ati_host_data_flush(ATIVGAState *s)
{
ATI2DCtx ctx, chunk;
- uint32_t fg = s->regs.dp_src_frgd_clr;
- uint32_t bg = s->regs.dp_src_bkgd_clr;
unsigned bypp, pix_count, row, col, idx;
uint8_t pix_buf[ATI_HOST_DATA_ACC_BITS * sizeof(uint32_t)];
- uint32_t byte_pix_order = s->regs.dp_datatype & DP_BYTE_PIX_ORDER;
uint32_t src_source = s->regs.dp_mix & DP_SRC_SOURCE;
uint32_t src_datatype = s->regs.dp_datatype & DP_SRC_DATATYPE;
@@ -360,21 +372,27 @@ bool ati_host_data_flush(ATIVGAState *s)
}
bypp = ctx.bpp / 8;
-
+ pix_count = ATI_HOST_DATA_ACC_BITS;
if (src_datatype == SRC_COLOR) {
- pix_count = ATI_HOST_DATA_ACC_BITS / ctx.bpp;
- memcpy(pix_buf, &s->host_data.acc[0], sizeof(s->host_data.acc));
+ pix_count /= ctx.bpp;
+ memcpy(pix_buf, s->host_data.acc, sizeof(s->host_data.acc));
} else {
- pix_count = ATI_HOST_DATA_ACC_BITS;
/* Expand monochrome bits to color pixels */
+ uint32_t byte_pix_order = s->regs.dp_datatype & DP_BYTE_PIX_ORDER;
+ uint32_t fg = make_filler(ctx.bpp, s->regs.dp_src_frgd_clr);
+ uint32_t bg = make_filler(ctx.bpp, s->regs.dp_src_bkgd_clr);
+
+ if (ctx.need_swap) {
+ bswap32s(&fg);
+ bswap32s(&bg);
+ }
idx = 0;
for (int word = 0; word < 4; word++) {
for (int byte = 0; byte < 4; byte++) {
uint8_t byte_val = s->host_data.acc[word] >> (byte * 8);
for (int i = 0; i < 8; i++) {
bool is_fg = byte_val & BIT(byte_pix_order ? i : 7 - i);
- uint32_t color = is_fg ? fg : bg;
- stn_he_p(&pix_buf[idx], bypp, color);
+ stn_he_p(&pix_buf[idx], bypp, is_fg ? fg : bg);
idx += bypp;
}
}
--
2.41.3
next prev parent reply other threads:[~2026-03-21 16:31 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-21 16:30 [PATCH v6 0/8] ati-vga fixes BALATON Zoltan
2026-03-21 16:30 ` BALATON Zoltan [this message]
2026-03-21 16:30 ` [PATCH v6 2/8] ati-vga: Also switch mode on HW cursor enable bit change BALATON Zoltan
2026-03-21 16:30 ` [PATCH v6 3/8] ati-vga: Do not add crtc offset to src and dst data address BALATON Zoltan
2026-03-21 16:30 ` [PATCH v6 4/8] ati-vga: Avoid warnings about sign extension BALATON Zoltan
2026-03-21 16:30 ` [PATCH v6 5/8] ati-vga: Fix display updates in non-32 bit modes BALATON Zoltan
2026-03-21 16:30 ` [PATCH v6 6/8] ati-vga: Add work around for fuloong2e BALATON Zoltan
2026-03-21 16:30 ` [PATCH v6 7/8] ati-vga: Simplify pointer image handling BALATON Zoltan
2026-03-23 12:21 ` Philippe Mathieu-Daudé
2026-03-23 12:25 ` Philippe Mathieu-Daudé
2026-03-23 13:39 ` BALATON Zoltan
2026-03-23 13:38 ` BALATON Zoltan
2026-03-24 14:17 ` Chad Jablonski
2026-03-24 14:49 ` BALATON Zoltan
2026-03-25 13:10 ` Chad Jablonski
2026-03-21 16:30 ` [PATCH v6 8/8] ati-vga: Make sure hardware cursor data is within vram BALATON Zoltan
2026-03-24 13:29 ` Chad Jablonski
2026-03-23 12:01 ` [PATCH v6 0/8] ati-vga fixes BALATON Zoltan
2026-03-24 13:38 ` Michael Tokarev
2026-03-24 14:31 ` Michael Tokarev
2026-03-24 14:39 ` BALATON Zoltan
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=759ed5e3b019cce94e9a4ef003f1fc2e0cea2ec1.1774110169.git.balaton@eik.bme.hu \
--to=balaton@eik.bme.hu \
--cc=chad@jablonski.xyz \
--cc=kraxel@redhat.com \
--cc=marcandre.lureau@redhat.com \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox