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