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