From a99aaf187f1b47208d155bc85439b613da5c8f2d Mon Sep 17 00:00:00 2001 From: dgibson Date: Wed, 29 Oct 2014 05:04:02 +0100 Subject: [PATCH 04/48] vga: Separate LE and BE conversion functions Message-id: <1414559050-21089-4-git-send-email-dgibson@redhat.com> Patchwork-id: 61978 O-Subject: [RHEL 7.1 qemu-kvm-rhev 03/11] vga: Separate LE and BE conversion functions Bugzilla: 1146809 RH-Acked-by: Laszlo Ersek RH-Acked-by: Paolo Bonzini RH-Acked-by: Gerd Hoffmann Signed-off-by: David Gibson commit 46c3a8c8ebe2966cc1f7af12626f89c83d547bfb Author: Benjamin Herrenschmidt Date: Mon Jul 7 09:48:28 2014 +1000 vga: Separate LE and BE conversion functions Provide different functions for converting from an LE vs a BE framebuffer. We cannot rely on the simple cases always being shared surfaces since cirrus will need to always shadow for cursor emulation, so we need the full set of functions to be able to later handle runtime switching. Signed-off-by: Benjamin Herrenschmidt \ Signed-off-by: Gerd Hoffmann Reviewed-by: David Gibson Signed-off-by: Miroslav Rezanina --- hw/display/vga.c | 43 +++++++++++------- hw/display/vga_template.h | 109 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 112 insertions(+), 40 deletions(-) diff --git a/hw/display/vga.c b/hw/display/vga.c index 067e330..3ac89d9 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -1378,10 +1378,14 @@ enum { VGA_DRAW_LINE4D2, VGA_DRAW_LINE8D2, VGA_DRAW_LINE8, - VGA_DRAW_LINE15, - VGA_DRAW_LINE16, - VGA_DRAW_LINE24, - VGA_DRAW_LINE32, + VGA_DRAW_LINE15_LE, + VGA_DRAW_LINE16_LE, + VGA_DRAW_LINE24_LE, + VGA_DRAW_LINE32_LE, + VGA_DRAW_LINE15_BE, + VGA_DRAW_LINE16_BE, + VGA_DRAW_LINE24_BE, + VGA_DRAW_LINE32_BE, VGA_DRAW_LINE_NB, }; @@ -1392,10 +1396,14 @@ static vga_draw_line_func * const vga_draw_line_table[VGA_DRAW_LINE_NB] = { vga_draw_line4d2, vga_draw_line8d2, vga_draw_line8, - vga_draw_line15, - vga_draw_line16, - vga_draw_line24, - vga_draw_line32, + vga_draw_line15_le, + vga_draw_line16_le, + vga_draw_line24_le, + vga_draw_line32_le, + vga_draw_line15_be, + vga_draw_line16_be, + vga_draw_line24_be, + vga_draw_line32_be, }; static int vga_get_bpp(VGACommonState *s) @@ -1468,10 +1476,15 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) uint8_t *d; uint32_t v, addr1, addr; vga_draw_line_func *vga_draw_line; -#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) - static const bool byteswap = false; +#if defined(TARGET_WORDS_BIGENDIAN) + static const bool big_endian_fb = true; #else - static const bool byteswap = true; + static const bool big_endian_fb = false; +#endif +#if defined(HOST_WORDS_BIGENDIAN) + static const bool byteswap = !big_endian_fb; +#else + static const bool byteswap = big_endian_fb; #endif full_update |= update_basic_params(s); @@ -1572,19 +1585,19 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) bits = 8; break; case 15: - v = VGA_DRAW_LINE15; + v = big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE; bits = 16; break; case 16: - v = VGA_DRAW_LINE16; + v = big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE; bits = 16; break; case 24: - v = VGA_DRAW_LINE24; + v = big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE; bits = 24; break; case 32: - v = VGA_DRAW_LINE32; + v = big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE; bits = 32; break; } diff --git a/hw/display/vga_template.h b/hw/display/vga_template.h index 0660b52..94f6de2 100644 --- a/hw/display/vga_template.h +++ b/hw/display/vga_template.h @@ -278,21 +278,36 @@ static void vga_draw_line8(VGACommonState *s1, uint8_t *d, } } - -/* XXX: optimize */ - /* * 15 bit color */ -static void vga_draw_line15(VGACommonState *s1, uint8_t *d, - const uint8_t *s, int width) +static void vga_draw_line15_le(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) { int w; uint32_t v, r, g, b; w = width; do { - v = lduw_p((void *)s); + v = lduw_le_p((void *)s); + r = (v >> 7) & 0xf8; + g = (v >> 2) & 0xf8; + b = (v << 3) & 0xf8; + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); + s += 2; + d += 4; + } while (--w != 0); +} + +static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) +{ + int w; + uint32_t v, r, g, b; + + w = width; + do { + v = lduw_be_p((void *)s); r = (v >> 7) & 0xf8; g = (v >> 2) & 0xf8; b = (v << 3) & 0xf8; @@ -305,15 +320,33 @@ static void vga_draw_line15(VGACommonState *s1, uint8_t *d, /* * 16 bit color */ -static void vga_draw_line16(VGACommonState *s1, uint8_t *d, - const uint8_t *s, int width) +static void vga_draw_line16_le(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) { int w; uint32_t v, r, g, b; w = width; do { - v = lduw_p((void *)s); + v = lduw_le_p((void *)s); + r = (v >> 8) & 0xf8; + g = (v >> 3) & 0xfc; + b = (v << 3) & 0xf8; + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); + s += 2; + d += 4; + } while (--w != 0); +} + +static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) +{ + int w; + uint32_t v, r, g, b; + + w = width; + do { + v = lduw_be_p((void *)s); r = (v >> 8) & 0xf8; g = (v >> 3) & 0xfc; b = (v << 3) & 0xf8; @@ -326,23 +359,34 @@ static void vga_draw_line16(VGACommonState *s1, uint8_t *d, /* * 24 bit color */ -static void vga_draw_line24(VGACommonState *s1, uint8_t *d, - const uint8_t *s, int width) +static void vga_draw_line24_le(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) { int w; uint32_t r, g, b; w = width; do { -#if defined(TARGET_WORDS_BIGENDIAN) - r = s[0]; - g = s[1]; - b = s[2]; -#else b = s[0]; g = s[1]; r = s[2]; -#endif + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); + s += 3; + d += 4; + } while (--w != 0); +} + +static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) +{ + int w; + uint32_t r, g, b; + + w = width; + do { + r = s[0]; + g = s[1]; + b = s[2]; ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); s += 3; d += 4; @@ -352,10 +396,10 @@ static void vga_draw_line24(VGACommonState *s1, uint8_t *d, /* * 32 bit color */ -static void vga_draw_line32(VGACommonState *s1, uint8_t *d, - const uint8_t *s, int width) +static void vga_draw_line32_le(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) { -#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) +#ifndef HOST_WORDS_BIGENDIAN memcpy(d, s, width * 4); #else int w; @@ -363,15 +407,30 @@ static void vga_draw_line32(VGACommonState *s1, uint8_t *d, w = width; do { -#if defined(TARGET_WORDS_BIGENDIAN) - r = s[1]; - g = s[2]; - b = s[3]; -#else b = s[0]; g = s[1]; r = s[2]; + ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); + s += 4; + d += 4; + } while (--w != 0); #endif +} + +static void vga_draw_line32_be(VGACommonState *s1, uint8_t *d, + const uint8_t *s, int width) +{ +#ifdef HOST_WORDS_BIGENDIAN + memcpy(d, s, width * 4); +#else + int w; + uint32_t r, g, b; + + w = width; + do { + r = s[1]; + g = s[2]; + b = s[3]; ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b); s += 4; d += 4; -- 1.8.3.1