|
|
5d360b |
From 83678480936d5e15ffb30321a6f61e443bc1012f Mon Sep 17 00:00:00 2001
|
|
|
12e206 |
From: Gerd Hoffmann <kraxel@redhat.com>
|
|
|
12e206 |
Date: Thu, 5 Oct 2017 14:51:17 +0200
|
|
|
5d360b |
Subject: [PATCH 21/27] vga: Separate LE and BE conversion functions
|
|
|
12e206 |
|
|
|
12e206 |
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
|
|
|
12e206 |
Message-id: <20171005145119.15277-6-kraxel@redhat.com>
|
|
|
12e206 |
Patchwork-id: 76824
|
|
|
12e206 |
O-Subject: [RHEL-7.5 qemu-kvm PATCH 5/7] vga: Separate LE and BE conversion functions
|
|
|
5d360b |
Bugzilla: 1486642
|
|
|
12e206 |
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
|
|
12e206 |
RH-Acked-by: Thomas Huth <thuth@redhat.com>
|
|
|
12e206 |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
12e206 |
|
|
|
12e206 |
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
|
|
12e206 |
|
|
|
12e206 |
Provide different functions for converting from an LE vs a BE
|
|
|
12e206 |
framebuffer. We cannot rely on the simple cases always being
|
|
|
12e206 |
shared surfaces since cirrus will need to always shadow for
|
|
|
12e206 |
cursor emulation, so we need the full set of functions to
|
|
|
12e206 |
be able to later handle runtime switching.
|
|
|
12e206 |
|
|
|
12e206 |
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>\
|
|
|
12e206 |
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
|
|
12e206 |
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
|
|
|
12e206 |
(cherry picked from commit 46c3a8c8ebe2966cc1f7af12626f89c83d547bfb)
|
|
|
12e206 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
12e206 |
---
|
|
|
12e206 |
hw/display/vga.c | 43 +++++++++++-------
|
|
|
12e206 |
hw/display/vga_template.h | 109 +++++++++++++++++++++++++++++++++++-----------
|
|
|
12e206 |
2 files changed, 112 insertions(+), 40 deletions(-)
|
|
|
12e206 |
|
|
|
12e206 |
diff --git a/hw/display/vga.c b/hw/display/vga.c
|
|
|
12e206 |
index 1a292a9..50999ee 100644
|
|
|
12e206 |
--- a/hw/display/vga.c
|
|
|
12e206 |
+++ b/hw/display/vga.c
|
|
|
12e206 |
@@ -1412,10 +1412,14 @@ enum {
|
|
|
12e206 |
VGA_DRAW_LINE4D2,
|
|
|
12e206 |
VGA_DRAW_LINE8D2,
|
|
|
12e206 |
VGA_DRAW_LINE8,
|
|
|
12e206 |
- VGA_DRAW_LINE15,
|
|
|
12e206 |
- VGA_DRAW_LINE16,
|
|
|
12e206 |
- VGA_DRAW_LINE24,
|
|
|
12e206 |
- VGA_DRAW_LINE32,
|
|
|
12e206 |
+ VGA_DRAW_LINE15_LE,
|
|
|
12e206 |
+ VGA_DRAW_LINE16_LE,
|
|
|
12e206 |
+ VGA_DRAW_LINE24_LE,
|
|
|
12e206 |
+ VGA_DRAW_LINE32_LE,
|
|
|
12e206 |
+ VGA_DRAW_LINE15_BE,
|
|
|
12e206 |
+ VGA_DRAW_LINE16_BE,
|
|
|
12e206 |
+ VGA_DRAW_LINE24_BE,
|
|
|
12e206 |
+ VGA_DRAW_LINE32_BE,
|
|
|
12e206 |
VGA_DRAW_LINE_NB,
|
|
|
12e206 |
};
|
|
|
12e206 |
|
|
|
12e206 |
@@ -1426,10 +1430,14 @@ static vga_draw_line_func * const vga_draw_line_table[VGA_DRAW_LINE_NB] = {
|
|
|
12e206 |
vga_draw_line4d2,
|
|
|
12e206 |
vga_draw_line8d2,
|
|
|
12e206 |
vga_draw_line8,
|
|
|
12e206 |
- vga_draw_line15,
|
|
|
12e206 |
- vga_draw_line16,
|
|
|
12e206 |
- vga_draw_line24,
|
|
|
12e206 |
- vga_draw_line32,
|
|
|
12e206 |
+ vga_draw_line15_le,
|
|
|
12e206 |
+ vga_draw_line16_le,
|
|
|
12e206 |
+ vga_draw_line24_le,
|
|
|
12e206 |
+ vga_draw_line32_le,
|
|
|
12e206 |
+ vga_draw_line15_be,
|
|
|
12e206 |
+ vga_draw_line16_be,
|
|
|
12e206 |
+ vga_draw_line24_be,
|
|
|
12e206 |
+ vga_draw_line32_be,
|
|
|
12e206 |
};
|
|
|
12e206 |
|
|
|
12e206 |
static int vga_get_bpp(VGACommonState *s)
|
|
|
12e206 |
@@ -1502,10 +1510,15 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|
|
12e206 |
uint8_t *d;
|
|
|
12e206 |
uint32_t v, addr1, addr;
|
|
|
12e206 |
vga_draw_line_func *vga_draw_line;
|
|
|
12e206 |
-#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
|
|
|
12e206 |
- static const bool byteswap = false;
|
|
|
12e206 |
+#if defined(TARGET_WORDS_BIGENDIAN)
|
|
|
12e206 |
+ static const bool big_endian_fb = true;
|
|
|
12e206 |
#else
|
|
|
12e206 |
- static const bool byteswap = true;
|
|
|
12e206 |
+ static const bool big_endian_fb = false;
|
|
|
12e206 |
+#endif
|
|
|
12e206 |
+#if defined(HOST_WORDS_BIGENDIAN)
|
|
|
12e206 |
+ static const bool byteswap = !big_endian_fb;
|
|
|
12e206 |
+#else
|
|
|
12e206 |
+ static const bool byteswap = big_endian_fb;
|
|
|
12e206 |
#endif
|
|
|
12e206 |
|
|
|
12e206 |
full_update |= update_basic_params(s);
|
|
|
12e206 |
@@ -1606,19 +1619,19 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
|
|
|
12e206 |
bits = 8;
|
|
|
12e206 |
break;
|
|
|
12e206 |
case 15:
|
|
|
12e206 |
- v = VGA_DRAW_LINE15;
|
|
|
12e206 |
+ v = big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE;
|
|
|
12e206 |
bits = 16;
|
|
|
12e206 |
break;
|
|
|
12e206 |
case 16:
|
|
|
12e206 |
- v = VGA_DRAW_LINE16;
|
|
|
12e206 |
+ v = big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE;
|
|
|
12e206 |
bits = 16;
|
|
|
12e206 |
break;
|
|
|
12e206 |
case 24:
|
|
|
12e206 |
- v = VGA_DRAW_LINE24;
|
|
|
12e206 |
+ v = big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE;
|
|
|
12e206 |
bits = 24;
|
|
|
12e206 |
break;
|
|
|
12e206 |
case 32:
|
|
|
12e206 |
- v = VGA_DRAW_LINE32;
|
|
|
12e206 |
+ v = big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE;
|
|
|
12e206 |
bits = 32;
|
|
|
12e206 |
break;
|
|
|
12e206 |
}
|
|
|
12e206 |
diff --git a/hw/display/vga_template.h b/hw/display/vga_template.h
|
|
|
12e206 |
index 0660b52..94f6de2 100644
|
|
|
12e206 |
--- a/hw/display/vga_template.h
|
|
|
12e206 |
+++ b/hw/display/vga_template.h
|
|
|
12e206 |
@@ -278,21 +278,36 @@ static void vga_draw_line8(VGACommonState *s1, uint8_t *d,
|
|
|
12e206 |
}
|
|
|
12e206 |
}
|
|
|
12e206 |
|
|
|
12e206 |
-
|
|
|
12e206 |
-/* XXX: optimize */
|
|
|
12e206 |
-
|
|
|
12e206 |
/*
|
|
|
12e206 |
* 15 bit color
|
|
|
12e206 |
*/
|
|
|
12e206 |
-static void vga_draw_line15(VGACommonState *s1, uint8_t *d,
|
|
|
12e206 |
- const uint8_t *s, int width)
|
|
|
12e206 |
+static void vga_draw_line15_le(VGACommonState *s1, uint8_t *d,
|
|
|
12e206 |
+ const uint8_t *s, int width)
|
|
|
12e206 |
{
|
|
|
12e206 |
int w;
|
|
|
12e206 |
uint32_t v, r, g, b;
|
|
|
12e206 |
|
|
|
12e206 |
w = width;
|
|
|
12e206 |
do {
|
|
|
12e206 |
- v = lduw_p((void *)s);
|
|
|
12e206 |
+ v = lduw_le_p((void *)s);
|
|
|
12e206 |
+ r = (v >> 7) & 0xf8;
|
|
|
12e206 |
+ g = (v >> 2) & 0xf8;
|
|
|
12e206 |
+ b = (v << 3) & 0xf8;
|
|
|
12e206 |
+ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
|
|
|
12e206 |
+ s += 2;
|
|
|
12e206 |
+ d += 4;
|
|
|
12e206 |
+ } while (--w != 0);
|
|
|
12e206 |
+}
|
|
|
12e206 |
+
|
|
|
12e206 |
+static void vga_draw_line15_be(VGACommonState *s1, uint8_t *d,
|
|
|
12e206 |
+ const uint8_t *s, int width)
|
|
|
12e206 |
+{
|
|
|
12e206 |
+ int w;
|
|
|
12e206 |
+ uint32_t v, r, g, b;
|
|
|
12e206 |
+
|
|
|
12e206 |
+ w = width;
|
|
|
12e206 |
+ do {
|
|
|
12e206 |
+ v = lduw_be_p((void *)s);
|
|
|
12e206 |
r = (v >> 7) & 0xf8;
|
|
|
12e206 |
g = (v >> 2) & 0xf8;
|
|
|
12e206 |
b = (v << 3) & 0xf8;
|
|
|
12e206 |
@@ -305,15 +320,33 @@ static void vga_draw_line15(VGACommonState *s1, uint8_t *d,
|
|
|
12e206 |
/*
|
|
|
12e206 |
* 16 bit color
|
|
|
12e206 |
*/
|
|
|
12e206 |
-static void vga_draw_line16(VGACommonState *s1, uint8_t *d,
|
|
|
12e206 |
- const uint8_t *s, int width)
|
|
|
12e206 |
+static void vga_draw_line16_le(VGACommonState *s1, uint8_t *d,
|
|
|
12e206 |
+ const uint8_t *s, int width)
|
|
|
12e206 |
{
|
|
|
12e206 |
int w;
|
|
|
12e206 |
uint32_t v, r, g, b;
|
|
|
12e206 |
|
|
|
12e206 |
w = width;
|
|
|
12e206 |
do {
|
|
|
12e206 |
- v = lduw_p((void *)s);
|
|
|
12e206 |
+ v = lduw_le_p((void *)s);
|
|
|
12e206 |
+ r = (v >> 8) & 0xf8;
|
|
|
12e206 |
+ g = (v >> 3) & 0xfc;
|
|
|
12e206 |
+ b = (v << 3) & 0xf8;
|
|
|
12e206 |
+ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
|
|
|
12e206 |
+ s += 2;
|
|
|
12e206 |
+ d += 4;
|
|
|
12e206 |
+ } while (--w != 0);
|
|
|
12e206 |
+}
|
|
|
12e206 |
+
|
|
|
12e206 |
+static void vga_draw_line16_be(VGACommonState *s1, uint8_t *d,
|
|
|
12e206 |
+ const uint8_t *s, int width)
|
|
|
12e206 |
+{
|
|
|
12e206 |
+ int w;
|
|
|
12e206 |
+ uint32_t v, r, g, b;
|
|
|
12e206 |
+
|
|
|
12e206 |
+ w = width;
|
|
|
12e206 |
+ do {
|
|
|
12e206 |
+ v = lduw_be_p((void *)s);
|
|
|
12e206 |
r = (v >> 8) & 0xf8;
|
|
|
12e206 |
g = (v >> 3) & 0xfc;
|
|
|
12e206 |
b = (v << 3) & 0xf8;
|
|
|
12e206 |
@@ -326,23 +359,34 @@ static void vga_draw_line16(VGACommonState *s1, uint8_t *d,
|
|
|
12e206 |
/*
|
|
|
12e206 |
* 24 bit color
|
|
|
12e206 |
*/
|
|
|
12e206 |
-static void vga_draw_line24(VGACommonState *s1, uint8_t *d,
|
|
|
12e206 |
- const uint8_t *s, int width)
|
|
|
12e206 |
+static void vga_draw_line24_le(VGACommonState *s1, uint8_t *d,
|
|
|
12e206 |
+ const uint8_t *s, int width)
|
|
|
12e206 |
{
|
|
|
12e206 |
int w;
|
|
|
12e206 |
uint32_t r, g, b;
|
|
|
12e206 |
|
|
|
12e206 |
w = width;
|
|
|
12e206 |
do {
|
|
|
12e206 |
-#if defined(TARGET_WORDS_BIGENDIAN)
|
|
|
12e206 |
- r = s[0];
|
|
|
12e206 |
- g = s[1];
|
|
|
12e206 |
- b = s[2];
|
|
|
12e206 |
-#else
|
|
|
12e206 |
b = s[0];
|
|
|
12e206 |
g = s[1];
|
|
|
12e206 |
r = s[2];
|
|
|
12e206 |
-#endif
|
|
|
12e206 |
+ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
|
|
|
12e206 |
+ s += 3;
|
|
|
12e206 |
+ d += 4;
|
|
|
12e206 |
+ } while (--w != 0);
|
|
|
12e206 |
+}
|
|
|
12e206 |
+
|
|
|
12e206 |
+static void vga_draw_line24_be(VGACommonState *s1, uint8_t *d,
|
|
|
12e206 |
+ const uint8_t *s, int width)
|
|
|
12e206 |
+{
|
|
|
12e206 |
+ int w;
|
|
|
12e206 |
+ uint32_t r, g, b;
|
|
|
12e206 |
+
|
|
|
12e206 |
+ w = width;
|
|
|
12e206 |
+ do {
|
|
|
12e206 |
+ r = s[0];
|
|
|
12e206 |
+ g = s[1];
|
|
|
12e206 |
+ b = s[2];
|
|
|
12e206 |
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
|
|
|
12e206 |
s += 3;
|
|
|
12e206 |
d += 4;
|
|
|
12e206 |
@@ -352,10 +396,10 @@ static void vga_draw_line24(VGACommonState *s1, uint8_t *d,
|
|
|
12e206 |
/*
|
|
|
12e206 |
* 32 bit color
|
|
|
12e206 |
*/
|
|
|
12e206 |
-static void vga_draw_line32(VGACommonState *s1, uint8_t *d,
|
|
|
12e206 |
- const uint8_t *s, int width)
|
|
|
12e206 |
+static void vga_draw_line32_le(VGACommonState *s1, uint8_t *d,
|
|
|
12e206 |
+ const uint8_t *s, int width)
|
|
|
12e206 |
{
|
|
|
12e206 |
-#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
|
|
|
12e206 |
+#ifndef HOST_WORDS_BIGENDIAN
|
|
|
12e206 |
memcpy(d, s, width * 4);
|
|
|
12e206 |
#else
|
|
|
12e206 |
int w;
|
|
|
12e206 |
@@ -363,15 +407,30 @@ static void vga_draw_line32(VGACommonState *s1, uint8_t *d,
|
|
|
12e206 |
|
|
|
12e206 |
w = width;
|
|
|
12e206 |
do {
|
|
|
12e206 |
-#if defined(TARGET_WORDS_BIGENDIAN)
|
|
|
12e206 |
- r = s[1];
|
|
|
12e206 |
- g = s[2];
|
|
|
12e206 |
- b = s[3];
|
|
|
12e206 |
-#else
|
|
|
12e206 |
b = s[0];
|
|
|
12e206 |
g = s[1];
|
|
|
12e206 |
r = s[2];
|
|
|
12e206 |
+ ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
|
|
|
12e206 |
+ s += 4;
|
|
|
12e206 |
+ d += 4;
|
|
|
12e206 |
+ } while (--w != 0);
|
|
|
12e206 |
#endif
|
|
|
12e206 |
+}
|
|
|
12e206 |
+
|
|
|
12e206 |
+static void vga_draw_line32_be(VGACommonState *s1, uint8_t *d,
|
|
|
12e206 |
+ const uint8_t *s, int width)
|
|
|
12e206 |
+{
|
|
|
12e206 |
+#ifdef HOST_WORDS_BIGENDIAN
|
|
|
12e206 |
+ memcpy(d, s, width * 4);
|
|
|
12e206 |
+#else
|
|
|
12e206 |
+ int w;
|
|
|
12e206 |
+ uint32_t r, g, b;
|
|
|
12e206 |
+
|
|
|
12e206 |
+ w = width;
|
|
|
12e206 |
+ do {
|
|
|
12e206 |
+ r = s[1];
|
|
|
12e206 |
+ g = s[2];
|
|
|
12e206 |
+ b = s[3];
|
|
|
12e206 |
((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
|
|
|
12e206 |
s += 4;
|
|
|
12e206 |
d += 4;
|
|
|
12e206 |
--
|
|
|
12e206 |
1.8.3.1
|
|
|
12e206 |
|