From: "Philippe Mathieu-Daudé" <philmd@linaro.org>
To: qemu-devel@nongnu.org
Subject: [PULL 17/27] ati-vga: Fix colors when frame buffer endianness does not match host
Date: Mon, 23 Mar 2026 17:52:08 +0100 [thread overview]
Message-ID: <20260323165218.96607-18-philmd@linaro.org> (raw)
In-Reply-To: <20260323165218.96607-1-philmd@linaro.org>
From: BALATON Zoltan <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>
Message-ID: <759ed5e3b019cce94e9a4ef003f1fc2e0cea2ec1.1774110169.git.balaton@eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
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 37fe6c17ee9..0cbbdc33f47 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.53.0
next prev parent reply other threads:[~2026-03-23 16:54 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-23 16:51 [PULL 00/27] Misc HW patches for 2026-03-23 Philippe Mathieu-Daudé
2026-03-23 16:51 ` [PULL 01/27] hw/riscv: Mark RISC-V specific peripherals as little-endian Philippe Mathieu-Daudé
2026-03-23 16:51 ` [PULL 02/27] hw/cxl: Use HPA in cxl_cfmws_find_device() rather than offset in window Philippe Mathieu-Daudé
2026-03-23 16:51 ` [PULL 03/27] hw/char/virtio-console: clear dangling GLib event source tag Philippe Mathieu-Daudé
2026-03-23 16:51 ` [PULL 04/27] hw/i3c/dw-i3c: Fix uninitialized data use in short transfer Philippe Mathieu-Daudé
2026-03-23 16:51 ` [PULL 05/27] hw/core/loader: fix error handling for load_image_targphys callers Philippe Mathieu-Daudé
2026-03-23 16:51 ` [PULL 06/27] hw/core/loader: fix error handling for get_image_size callers Philippe Mathieu-Daudé
2026-03-23 16:51 ` [PULL 07/27] util/event_notifier: fix error handling for event_notifier_init callers Philippe Mathieu-Daudé
2026-03-23 16:51 ` [PULL 08/27] hw/pci/msix: fix error handling for msix_init callers Philippe Mathieu-Daudé
2026-03-23 16:52 ` [PULL 09/27] hw/i386/pc_sysfw: stub out x86_firmware_configure Philippe Mathieu-Daudé
2026-03-23 16:52 ` [PULL 10/27] hw/i386/hyperv: add stubs for synic enablement Philippe Mathieu-Daudé
2026-03-23 16:52 ` [PULL 11/27] hw/cxl: Respect Media Operation max ops discovery semantics Philippe Mathieu-Daudé
2026-03-23 16:52 ` [PULL 12/27] hw/cxl: Exclude Discovery from Media Operation Discovery output Philippe Mathieu-Daudé
2026-03-23 16:52 ` [PULL 13/27] backends/iommufd: report error when /dev/iommu is not available Philippe Mathieu-Daudé
2026-03-23 16:52 ` [PULL 14/27] hw/vfio/iommufd: report hint to user when vfio-dev/vfio*/dev is missing Philippe Mathieu-Daudé
2026-03-23 16:52 ` [PULL 15/27] hw/hyperv: Fix SynIC not initialized except on first vCPU Philippe Mathieu-Daudé
2026-03-23 16:52 ` [PULL 16/27] hw/usb/hcd-ohci: check for MPS=0 to avoid infinite loop Philippe Mathieu-Daudé
2026-03-23 16:52 ` Philippe Mathieu-Daudé [this message]
2026-03-24 19:06 ` [PULL 17/27] ati-vga: Fix colors when frame buffer endianness does not match host Peter Maydell
2026-03-24 20:21 ` BALATON Zoltan
2026-03-23 16:52 ` [PULL 18/27] ati-vga: Also switch mode on HW cursor enable bit change Philippe Mathieu-Daudé
2026-03-23 16:52 ` [PULL 19/27] ati-vga: Do not add crtc offset to src and dst data address Philippe Mathieu-Daudé
2026-03-23 16:52 ` [PULL 20/27] ati-vga: Avoid warnings about sign extension Philippe Mathieu-Daudé
2026-03-23 16:52 ` [PULL 21/27] ati-vga: Fix display updates in non-32 bit modes Philippe Mathieu-Daudé
2026-03-23 16:52 ` [PULL 22/27] ati-vga: Add work around for fuloong2e Philippe Mathieu-Daudé
2026-03-23 16:52 ` [PULL 23/27] ati-vga: Simplify pointer image handling Philippe Mathieu-Daudé
2026-03-23 16:52 ` [PULL 24/27] ati-vga: Make sure hardware cursor data is within vram Philippe Mathieu-Daudé
2026-03-23 16:52 ` [PULL 25/27] hw/net/ftgmac100: Improve DMA error handling Philippe Mathieu-Daudé
2026-03-24 8:03 ` Cédric Le Goater
2026-03-24 19:21 ` Philippe Mathieu-Daudé
2026-03-24 21:59 ` Cédric Le Goater
2026-03-23 16:52 ` [PULL 26/27] monitor: Correctly display virtual addresses while dumping memory Philippe Mathieu-Daudé
2026-03-23 16:52 ` [PULL 27/27] hw/hyperv: add QEMU_PACKED to uapi structs Philippe Mathieu-Daudé
2026-03-24 10:08 ` [PULL 00/27] Misc HW patches for 2026-03-23 Peter Maydell
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=20260323165218.96607-18-philmd@linaro.org \
--to=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