summary refs log tree commit diff stats
path: root/hw/display
diff options
context:
space:
mode:
Diffstat (limited to 'hw/display')
-rw-r--r--hw/display/cirrus_vga.c79
-rw-r--r--hw/display/cirrus_vga_template.h102
-rw-r--r--hw/display/vga-helpers.h (renamed from hw/display/vga_template.h)318
-rw-r--r--hw/display/vga.c382
-rw-r--r--hw/display/vga_int.h5
5 files changed, 296 insertions, 590 deletions
diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
index db330e9548..8a5b76c403 100644
--- a/hw/display/cirrus_vga.c
+++ b/hw/display/cirrus_vga.c
@@ -29,6 +29,7 @@
 #include "hw/hw.h"
 #include "hw/pci/pci.h"
 #include "ui/console.h"
+#include "ui/pixel_ops.h"
 #include "vga_int.h"
 #include "hw/loader.h"
 
@@ -2170,20 +2171,44 @@ static void cirrus_cursor_invalidate(VGACommonState *s1)
     }
 }
 
-#define DEPTH 8
-#include "cirrus_vga_template.h"
-
-#define DEPTH 16
-#include "cirrus_vga_template.h"
-
-#define DEPTH 32
-#include "cirrus_vga_template.h"
+static void vga_draw_cursor_line(uint8_t *d1,
+                                 const uint8_t *src1,
+                                 int poffset, int w,
+                                 unsigned int color0,
+                                 unsigned int color1,
+                                 unsigned int color_xor)
+{
+    const uint8_t *plane0, *plane1;
+    int x, b0, b1;
+    uint8_t *d;
+
+    d = d1;
+    plane0 = src1;
+    plane1 = src1 + poffset;
+    for (x = 0; x < w; x++) {
+        b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
+        b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
+        switch (b0 | (b1 << 1)) {
+        case 0:
+            break;
+        case 1:
+            ((uint32_t *)d)[0] ^= color_xor;
+            break;
+        case 2:
+            ((uint32_t *)d)[0] = color0;
+            break;
+        case 3:
+            ((uint32_t *)d)[0] = color1;
+            break;
+        }
+        d += 4;
+    }
+}
 
 static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y)
 {
     CirrusVGAState *s = container_of(s1, CirrusVGAState, vga);
-    DisplaySurface *surface = qemu_console_surface(s->vga.con);
-    int w, h, bpp, x1, x2, poffset;
+    int w, h, x1, x2, poffset;
     unsigned int color0, color1;
     const uint8_t *palette, *src;
     uint32_t content;
@@ -2212,6 +2237,8 @@ static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y)
     } else {
         src += (s->vga.sr[0x13] & 0x3f) * 256;
         src += (scr_y - s->hw_cursor_y) * 4;
+
+
         poffset = 128;
         content = ((uint32_t *)src)[0] |
             ((uint32_t *)(src + 128))[0];
@@ -2229,30 +2256,14 @@ static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y)
         x2 = s->vga.last_scr_width;
     w = x2 - x1;
     palette = s->cirrus_hidden_palette;
-    color0 = s->vga.rgb_to_pixel(c6_to_8(palette[0x0 * 3]),
-                                 c6_to_8(palette[0x0 * 3 + 1]),
-                                 c6_to_8(palette[0x0 * 3 + 2]));
-    color1 = s->vga.rgb_to_pixel(c6_to_8(palette[0xf * 3]),
-                                 c6_to_8(palette[0xf * 3 + 1]),
-                                 c6_to_8(palette[0xf * 3 + 2]));
-    bpp = surface_bytes_per_pixel(surface);
-    d1 += x1 * bpp;
-    switch (surface_bits_per_pixel(surface)) {
-    default:
-        break;
-    case 8:
-        vga_draw_cursor_line_8(d1, src, poffset, w, color0, color1, 0xff);
-        break;
-    case 15:
-        vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0x7fff);
-        break;
-    case 16:
-        vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0xffff);
-        break;
-    case 32:
-        vga_draw_cursor_line_32(d1, src, poffset, w, color0, color1, 0xffffff);
-        break;
-    }
+    color0 = rgb_to_pixel32(c6_to_8(palette[0x0 * 3]),
+                            c6_to_8(palette[0x0 * 3 + 1]),
+                            c6_to_8(palette[0x0 * 3 + 2]));
+    color1 = rgb_to_pixel32(c6_to_8(palette[0xf * 3]),
+                            c6_to_8(palette[0xf * 3 + 1]),
+                            c6_to_8(palette[0xf * 3 + 2]));
+    d1 += x1 * 4;
+    vga_draw_cursor_line(d1, src, poffset, w, color0, color1, 0xffffff);
 }
 
 /***************************************
diff --git a/hw/display/cirrus_vga_template.h b/hw/display/cirrus_vga_template.h
deleted file mode 100644
index 3b28280588..0000000000
--- a/hw/display/cirrus_vga_template.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * QEMU Cirrus VGA Emulator templates
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#if DEPTH == 8
-#define BPP 1
-#elif DEPTH == 15 || DEPTH == 16
-#define BPP 2
-#elif DEPTH == 32
-#define BPP 4
-#else
-#error unsupported depth
-#endif
-
-static void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1,
-                                               const uint8_t *src1,
-                                               int poffset, int w,
-                                               unsigned int color0,
-                                               unsigned int color1,
-                                               unsigned int color_xor)
-{
-    const uint8_t *plane0, *plane1;
-    int x, b0, b1;
-    uint8_t *d;
-
-    d = d1;
-    plane0 = src1;
-    plane1 = src1 + poffset;
-    for (x = 0; x < w; x++) {
-        b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
-        b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
-#if DEPTH == 8
-        switch (b0 | (b1 << 1)) {
-        case 0:
-            break;
-        case 1:
-            d[0] ^= color_xor;
-            break;
-        case 2:
-            d[0] = color0;
-            break;
-        case 3:
-            d[0] = color1;
-            break;
-        }
-#elif DEPTH == 16
-        switch (b0 | (b1 << 1)) {
-        case 0:
-            break;
-        case 1:
-            ((uint16_t *)d)[0] ^= color_xor;
-            break;
-        case 2:
-            ((uint16_t *)d)[0] = color0;
-            break;
-        case 3:
-            ((uint16_t *)d)[0] = color1;
-            break;
-        }
-#elif DEPTH == 32
-        switch (b0 | (b1 << 1)) {
-        case 0:
-            break;
-        case 1:
-            ((uint32_t *)d)[0] ^= color_xor;
-            break;
-        case 2:
-            ((uint32_t *)d)[0] = color0;
-            break;
-        case 3:
-            ((uint32_t *)d)[0] = color1;
-            break;
-        }
-#else
-#error unsupported depth
-#endif
-        d += BPP;
-    }
-}
-
-#undef DEPTH
-#undef BPP
diff --git a/hw/display/vga_template.h b/hw/display/vga-helpers.h
index 90ec9c208f..94f6de2046 100644
--- a/hw/display/vga_template.h
+++ b/hw/display/vga-helpers.h
@@ -22,41 +22,9 @@
  * THE SOFTWARE.
  */
 
-#if DEPTH == 8
-#define BPP 1
-#define PIXEL_TYPE uint8_t
-#elif DEPTH == 15 || DEPTH == 16
-#define BPP 2
-#define PIXEL_TYPE uint16_t
-#elif DEPTH == 32
-#define BPP 4
-#define PIXEL_TYPE uint32_t
-#else
-#error unsupport depth
-#endif
-
-#ifdef BGR_FORMAT
-#define PIXEL_NAME glue(DEPTH, bgr)
-#else
-#define PIXEL_NAME DEPTH
-#endif /* BGR_FORMAT */
-
-#if DEPTH != 15 && !defined(BGR_FORMAT)
-
-static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d,
-                                                     uint32_t font_data,
-                                                     uint32_t xorcol,
-                                                     uint32_t bgcol)
+static inline void vga_draw_glyph_line(uint8_t *d, uint32_t font_data,
+                                       uint32_t xorcol, uint32_t bgcol)
 {
-#if BPP == 1
-        ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
-        ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
-#elif BPP == 2
-        ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
-        ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
-        ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
-        ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
-#else
         ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
         ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
         ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
@@ -65,25 +33,24 @@ static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d,
         ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
         ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
         ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
-#endif
 }
 
-static void glue(vga_draw_glyph8_, DEPTH)(uint8_t *d, int linesize,
-                                          const uint8_t *font_ptr, int h,
-                                          uint32_t fgcol, uint32_t bgcol)
+static void vga_draw_glyph8(uint8_t *d, int linesize,
+                            const uint8_t *font_ptr, int h,
+                            uint32_t fgcol, uint32_t bgcol)
 {
     uint32_t font_data, xorcol;
 
     xorcol = bgcol ^ fgcol;
     do {
         font_data = font_ptr[0];
-        glue(vga_draw_glyph_line_, DEPTH)(d, font_data, xorcol, bgcol);
+        vga_draw_glyph_line(d, font_data, xorcol, bgcol);
         font_ptr += 4;
         d += linesize;
     } while (--h);
 }
 
-static void glue(vga_draw_glyph16_, DEPTH)(uint8_t *d, int linesize,
+static void vga_draw_glyph16(uint8_t *d, int linesize,
                                           const uint8_t *font_ptr, int h,
                                           uint32_t fgcol, uint32_t bgcol)
 {
@@ -92,48 +59,24 @@ static void glue(vga_draw_glyph16_, DEPTH)(uint8_t *d, int linesize,
     xorcol = bgcol ^ fgcol;
     do {
         font_data = font_ptr[0];
-        glue(vga_draw_glyph_line_, DEPTH)(d,
-                                          expand4to8[font_data >> 4],
-                                          xorcol, bgcol);
-        glue(vga_draw_glyph_line_, DEPTH)(d + 8 * BPP,
-                                          expand4to8[font_data & 0x0f],
-                                          xorcol, bgcol);
+        vga_draw_glyph_line(d, expand4to8[font_data >> 4],
+                            xorcol, bgcol);
+        vga_draw_glyph_line(d + 32, expand4to8[font_data & 0x0f],
+                            xorcol, bgcol);
         font_ptr += 4;
         d += linesize;
     } while (--h);
 }
 
-static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
-                                          const uint8_t *font_ptr, int h,
-                                          uint32_t fgcol, uint32_t bgcol, int dup9)
+static void vga_draw_glyph9(uint8_t *d, int linesize,
+                            const uint8_t *font_ptr, int h,
+                            uint32_t fgcol, uint32_t bgcol, int dup9)
 {
     uint32_t font_data, xorcol, v;
 
     xorcol = bgcol ^ fgcol;
     do {
         font_data = font_ptr[0];
-#if BPP == 1
-        stl_p((uint32_t *)d, (dmask16[(font_data >> 4)] & xorcol) ^ bgcol);
-        v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
-        stl_p(((uint32_t *)d)+1, v);
-        if (dup9)
-            ((uint8_t *)d)[8] = v >> (24 * (1 - BIG));
-        else
-            ((uint8_t *)d)[8] = bgcol;
-
-#elif BPP == 2
-        stl_p(((uint32_t *)d)+0, (dmask4[(font_data >> 6)] & xorcol) ^ bgcol);
-        stl_p(((uint32_t *)d)+1,
-              (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol);
-        stl_p(((uint32_t *)d)+2,
-              (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol);
-        v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
-        stl_p(((uint32_t *)d)+3, v);
-        if (dup9)
-            ((uint16_t *)d)[8] = v >> (16 * (1 - BIG));
-        else
-            ((uint16_t *)d)[8] = bgcol;
-#else
         ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
         ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
         ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
@@ -147,7 +90,6 @@ static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
             ((uint32_t *)d)[8] = v;
         else
             ((uint32_t *)d)[8] = bgcol;
-#endif
         font_ptr += 4;
         d += linesize;
     } while (--h);
@@ -156,8 +98,8 @@ static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
 /*
  * 4 color mode
  */
-static void glue(vga_draw_line2_, DEPTH)(VGACommonState *s1, uint8_t *d,
-                                         const uint8_t *s, int width)
+static void vga_draw_line2(VGACommonState *s1, uint8_t *d,
+                           const uint8_t *s, int width)
 {
     uint32_t plane_mask, *palette, data, v;
     int x;
@@ -170,36 +112,30 @@ static void glue(vga_draw_line2_, DEPTH)(VGACommonState *s1, uint8_t *d,
         data &= plane_mask;
         v = expand2[GET_PLANE(data, 0)];
         v |= expand2[GET_PLANE(data, 2)] << 2;
-        ((PIXEL_TYPE *)d)[0] = palette[v >> 12];
-        ((PIXEL_TYPE *)d)[1] = palette[(v >> 8) & 0xf];
-        ((PIXEL_TYPE *)d)[2] = palette[(v >> 4) & 0xf];
-        ((PIXEL_TYPE *)d)[3] = palette[(v >> 0) & 0xf];
+        ((uint32_t *)d)[0] = palette[v >> 12];
+        ((uint32_t *)d)[1] = palette[(v >> 8) & 0xf];
+        ((uint32_t *)d)[2] = palette[(v >> 4) & 0xf];
+        ((uint32_t *)d)[3] = palette[(v >> 0) & 0xf];
 
         v = expand2[GET_PLANE(data, 1)];
         v |= expand2[GET_PLANE(data, 3)] << 2;
-        ((PIXEL_TYPE *)d)[4] = palette[v >> 12];
-        ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
-        ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
-        ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
-        d += BPP * 8;
+        ((uint32_t *)d)[4] = palette[v >> 12];
+        ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf];
+        ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
+        ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
+        d += 32;
         s += 4;
     }
 }
 
-#if BPP == 1
-#define PUT_PIXEL2(d, n, v) ((uint16_t *)d)[(n)] = (v)
-#elif BPP == 2
-#define PUT_PIXEL2(d, n, v) ((uint32_t *)d)[(n)] = (v)
-#else
 #define PUT_PIXEL2(d, n, v) \
 ((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v)
-#endif
 
 /*
  * 4 color mode, dup2 horizontal
  */
-static void glue(vga_draw_line2d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
-                                           const uint8_t *s, int width)
+static void vga_draw_line2d2(VGACommonState *s1, uint8_t *d,
+                             const uint8_t *s, int width)
 {
     uint32_t plane_mask, *palette, data, v;
     int x;
@@ -223,7 +159,7 @@ static void glue(vga_draw_line2d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
         PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
         PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
         PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
-        d += BPP * 16;
+        d += 64;
         s += 4;
     }
 }
@@ -231,8 +167,8 @@ static void glue(vga_draw_line2d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
 /*
  * 16 color mode
  */
-static void glue(vga_draw_line4_, DEPTH)(VGACommonState *s1, uint8_t *d,
-                                         const uint8_t *s, int width)
+static void vga_draw_line4(VGACommonState *s1, uint8_t *d,
+                           const uint8_t *s, int width)
 {
     uint32_t plane_mask, data, v, *palette;
     int x;
@@ -247,15 +183,15 @@ static void glue(vga_draw_line4_, DEPTH)(VGACommonState *s1, uint8_t *d,
         v |= expand4[GET_PLANE(data, 1)] << 1;
         v |= expand4[GET_PLANE(data, 2)] << 2;
         v |= expand4[GET_PLANE(data, 3)] << 3;
-        ((PIXEL_TYPE *)d)[0] = palette[v >> 28];
-        ((PIXEL_TYPE *)d)[1] = palette[(v >> 24) & 0xf];
-        ((PIXEL_TYPE *)d)[2] = palette[(v >> 20) & 0xf];
-        ((PIXEL_TYPE *)d)[3] = palette[(v >> 16) & 0xf];
-        ((PIXEL_TYPE *)d)[4] = palette[(v >> 12) & 0xf];
-        ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
-        ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
-        ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
-        d += BPP * 8;
+        ((uint32_t *)d)[0] = palette[v >> 28];
+        ((uint32_t *)d)[1] = palette[(v >> 24) & 0xf];
+        ((uint32_t *)d)[2] = palette[(v >> 20) & 0xf];
+        ((uint32_t *)d)[3] = palette[(v >> 16) & 0xf];
+        ((uint32_t *)d)[4] = palette[(v >> 12) & 0xf];
+        ((uint32_t *)d)[5] = palette[(v >> 8) & 0xf];
+        ((uint32_t *)d)[6] = palette[(v >> 4) & 0xf];
+        ((uint32_t *)d)[7] = palette[(v >> 0) & 0xf];
+        d += 32;
         s += 4;
     }
 }
@@ -263,8 +199,8 @@ static void glue(vga_draw_line4_, DEPTH)(VGACommonState *s1, uint8_t *d,
 /*
  * 16 color mode, dup2 horizontal
  */
-static void glue(vga_draw_line4d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
-                                           const uint8_t *s, int width)
+static void vga_draw_line4d2(VGACommonState *s1, uint8_t *d,
+                             const uint8_t *s, int width)
 {
     uint32_t plane_mask, data, v, *palette;
     int x;
@@ -287,7 +223,7 @@ static void glue(vga_draw_line4d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
         PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
         PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
         PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
-        d += BPP * 16;
+        d += 64;
         s += 4;
     }
 }
@@ -297,8 +233,8 @@ static void glue(vga_draw_line4d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
  *
  * XXX: add plane_mask support (never used in standard VGA modes)
  */
-static void glue(vga_draw_line8d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
-                                           const uint8_t *s, int width)
+static void vga_draw_line8d2(VGACommonState *s1, uint8_t *d,
+                             const uint8_t *s, int width)
 {
     uint32_t *palette;
     int x;
@@ -310,7 +246,7 @@ static void glue(vga_draw_line8d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
         PUT_PIXEL2(d, 1, palette[s[1]]);
         PUT_PIXEL2(d, 2, palette[s[2]]);
         PUT_PIXEL2(d, 3, palette[s[3]]);
-        d += BPP * 8;
+        d += 32;
         s += 4;
     }
 }
@@ -320,8 +256,8 @@ static void glue(vga_draw_line8d2_, DEPTH)(VGACommonState *s1, uint8_t *d,
  *
  * XXX: add plane_mask support (never used in standard VGA modes)
  */
-static void glue(vga_draw_line8_, DEPTH)(VGACommonState *s1, uint8_t *d,
-                                         const uint8_t *s, int width)
+static void vga_draw_line8(VGACommonState *s1, uint8_t *d,
+                           const uint8_t *s, int width)
 {
     uint32_t *palette;
     int x;
@@ -329,107 +265,141 @@ static void glue(vga_draw_line8_, DEPTH)(VGACommonState *s1, uint8_t *d,
     palette = s1->last_palette;
     width >>= 3;
     for(x = 0; x < width; x++) {
-        ((PIXEL_TYPE *)d)[0] = palette[s[0]];
-        ((PIXEL_TYPE *)d)[1] = palette[s[1]];
-        ((PIXEL_TYPE *)d)[2] = palette[s[2]];
-        ((PIXEL_TYPE *)d)[3] = palette[s[3]];
-        ((PIXEL_TYPE *)d)[4] = palette[s[4]];
-        ((PIXEL_TYPE *)d)[5] = palette[s[5]];
-        ((PIXEL_TYPE *)d)[6] = palette[s[6]];
-        ((PIXEL_TYPE *)d)[7] = palette[s[7]];
-        d += BPP * 8;
+        ((uint32_t *)d)[0] = palette[s[0]];
+        ((uint32_t *)d)[1] = palette[s[1]];
+        ((uint32_t *)d)[2] = palette[s[2]];
+        ((uint32_t *)d)[3] = palette[s[3]];
+        ((uint32_t *)d)[4] = palette[s[4]];
+        ((uint32_t *)d)[5] = palette[s[5]];
+        ((uint32_t *)d)[6] = palette[s[6]];
+        ((uint32_t *)d)[7] = palette[s[7]];
+        d += 32;
         s += 8;
     }
 }
 
-#endif /* DEPTH != 15 */
-
-
-/* XXX: optimize */
-
 /*
  * 15 bit color
  */
-static void glue(vga_draw_line15_, PIXEL_NAME)(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)
 {
-#if DEPTH == 15 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
-    memcpy(d, s, width * 2);
-#else
     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;
-        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
+        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
         s += 2;
-        d += BPP;
+        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;
+        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
+        s += 2;
+        d += 4;
     } while (--w != 0);
-#endif
 }
 
 /*
  * 16 bit color
  */
-static void glue(vga_draw_line16_, PIXEL_NAME)(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)
 {
-#if DEPTH == 16 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
-    memcpy(d, s, width * 2);
-#else
     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;
-        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
+        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
         s += 2;
-        d += BPP;
+        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;
+        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
+        s += 2;
+        d += 4;
     } while (--w != 0);
-#endif
 }
 
 /*
  * 24 bit color
  */
-static void glue(vga_draw_line24_, PIXEL_NAME)(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
-        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
+        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
         s += 3;
-        d += BPP;
+        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;
     } while (--w != 0);
 }
 
 /*
  * 32 bit color
  */
-static void glue(vga_draw_line32_, PIXEL_NAME)(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 DEPTH == 32 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) && !defined(BGR_FORMAT)
+#ifndef HOST_WORDS_BIGENDIAN
     memcpy(d, s, width * 4);
 #else
     int w;
@@ -437,25 +407,33 @@ static void glue(vga_draw_line32_, PIXEL_NAME)(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];
-#endif
-        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, PIXEL_NAME)(r, g, b);
+        ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
         s += 4;
-        d += BPP;
+        d += 4;
     } while (--w != 0);
 #endif
 }
 
-#undef PUT_PIXEL2
-#undef DEPTH
-#undef BPP
-#undef PIXEL_TYPE
-#undef PIXEL_NAME
-#undef BGR_FORMAT
+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;
+    } while (--w != 0);
+#endif
+}
diff --git a/hw/display/vga.c b/hw/display/vga.c
index df0c010823..19e7f23bd3 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -761,14 +761,13 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
                 s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED;
                 vbe_fixup_regs(s);
 
-                /* clear the screen (should be done in BIOS) */
+                /* clear the screen */
                 if (!(val & VBE_DISPI_NOCLEARMEM)) {
                     memset(s->vram_ptr, 0,
                            s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
                 }
 
-                /* we initialize the VGA graphic mode (should be done
-                   in BIOS) */
+                /* we initialize the VGA graphic mode */
                 /* graphic mode + memory map 1 */
                 s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
                     VGA_GR06_GRAPHICS_MODE;
@@ -801,7 +800,6 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
                     (shift_control << 5);
                 s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
             } else {
-                /* XXX: the bios should do that */
                 s->bank_offset = 0;
             }
             s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0;
@@ -1006,95 +1004,10 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
     }
 }
 
-typedef void vga_draw_glyph8_func(uint8_t *d, int linesize,
-                             const uint8_t *font_ptr, int h,
-                             uint32_t fgcol, uint32_t bgcol);
-typedef void vga_draw_glyph9_func(uint8_t *d, int linesize,
-                                  const uint8_t *font_ptr, int h,
-                                  uint32_t fgcol, uint32_t bgcol, int dup9);
 typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
                                 const uint8_t *s, int width);
 
-#define DEPTH 8
-#include "vga_template.h"
-
-#define DEPTH 15
-#include "vga_template.h"
-
-#define BGR_FORMAT
-#define DEPTH 15
-#include "vga_template.h"
-
-#define DEPTH 16
-#include "vga_template.h"
-
-#define BGR_FORMAT
-#define DEPTH 16
-#include "vga_template.h"
-
-#define DEPTH 32
-#include "vga_template.h"
-
-#define BGR_FORMAT
-#define DEPTH 32
-#include "vga_template.h"
-
-static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b)
-{
-    unsigned int col;
-    col = rgb_to_pixel8(r, g, b);
-    col |= col << 8;
-    col |= col << 16;
-    return col;
-}
-
-static unsigned int rgb_to_pixel15_dup(unsigned int r, unsigned int g, unsigned b)
-{
-    unsigned int col;
-    col = rgb_to_pixel15(r, g, b);
-    col |= col << 16;
-    return col;
-}
-
-static unsigned int rgb_to_pixel15bgr_dup(unsigned int r, unsigned int g,
-                                          unsigned int b)
-{
-    unsigned int col;
-    col = rgb_to_pixel15bgr(r, g, b);
-    col |= col << 16;
-    return col;
-}
-
-static unsigned int rgb_to_pixel16_dup(unsigned int r, unsigned int g, unsigned b)
-{
-    unsigned int col;
-    col = rgb_to_pixel16(r, g, b);
-    col |= col << 16;
-    return col;
-}
-
-static unsigned int rgb_to_pixel16bgr_dup(unsigned int r, unsigned int g,
-                                          unsigned int b)
-{
-    unsigned int col;
-    col = rgb_to_pixel16bgr(r, g, b);
-    col |= col << 16;
-    return col;
-}
-
-static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned b)
-{
-    unsigned int col;
-    col = rgb_to_pixel32(r, g, b);
-    return col;
-}
-
-static unsigned int rgb_to_pixel32bgr_dup(unsigned int r, unsigned int g, unsigned b)
-{
-    unsigned int col;
-    col = rgb_to_pixel32bgr(r, g, b);
-    return col;
-}
+#include "vga-helpers.h"
 
 /* return true if the palette was modified */
 static int update_palette16(VGACommonState *s)
@@ -1112,9 +1025,9 @@ static int update_palette16(VGACommonState *s)
             v = ((s->ar[VGA_ATC_COLOR_PAGE] & 0xc) << 4) | (v & 0x3f);
         }
         v = v * 3;
-        col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
-                              c6_to_8(s->palette[v + 1]),
-                              c6_to_8(s->palette[v + 2]));
+        col = rgb_to_pixel32(c6_to_8(s->palette[v]),
+                             c6_to_8(s->palette[v + 1]),
+                             c6_to_8(s->palette[v + 2]));
         if (col != palette[i]) {
             full_update = 1;
             palette[i] = col;
@@ -1134,13 +1047,13 @@ static int update_palette256(VGACommonState *s)
     v = 0;
     for(i = 0; i < 256; i++) {
         if (s->dac_8bit) {
-          col = s->rgb_to_pixel(s->palette[v],
-                                s->palette[v + 1],
-                                s->palette[v + 2]);
+            col = rgb_to_pixel32(s->palette[v],
+                                 s->palette[v + 1],
+                                 s->palette[v + 2]);
         } else {
-          col = s->rgb_to_pixel(c6_to_8(s->palette[v]),
-                                c6_to_8(s->palette[v + 1]),
-                                c6_to_8(s->palette[v + 2]));
+            col = rgb_to_pixel32(c6_to_8(s->palette[v]),
+                                 c6_to_8(s->palette[v + 1]),
+                                 c6_to_8(s->palette[v + 2]));
         }
         if (col != palette[i]) {
             full_update = 1;
@@ -1202,56 +1115,6 @@ static int update_basic_params(VGACommonState *s)
     return full_update;
 }
 
-#define NB_DEPTHS 7
-
-static inline int get_depth_index(DisplaySurface *s)
-{
-    switch (surface_bits_per_pixel(s)) {
-    default:
-    case 8:
-        return 0;
-    case 15:
-        return 1;
-    case 16:
-        return 2;
-    case 32:
-        if (is_surface_bgr(s)) {
-            return 4;
-        } else {
-            return 3;
-        }
-    }
-}
-
-static vga_draw_glyph8_func * const vga_draw_glyph8_table[NB_DEPTHS] = {
-    vga_draw_glyph8_8,
-    vga_draw_glyph8_16,
-    vga_draw_glyph8_16,
-    vga_draw_glyph8_32,
-    vga_draw_glyph8_32,
-    vga_draw_glyph8_16,
-    vga_draw_glyph8_16,
-};
-
-static vga_draw_glyph8_func * const vga_draw_glyph16_table[NB_DEPTHS] = {
-    vga_draw_glyph16_8,
-    vga_draw_glyph16_16,
-    vga_draw_glyph16_16,
-    vga_draw_glyph16_32,
-    vga_draw_glyph16_32,
-    vga_draw_glyph16_16,
-    vga_draw_glyph16_16,
-};
-
-static vga_draw_glyph9_func * const vga_draw_glyph9_table[NB_DEPTHS] = {
-    vga_draw_glyph9_8,
-    vga_draw_glyph9_16,
-    vga_draw_glyph9_16,
-    vga_draw_glyph9_32,
-    vga_draw_glyph9_32,
-    vga_draw_glyph9_16,
-    vga_draw_glyph9_16,
-};
 
 static const uint8_t cursor_glyph[32 * 4] = {
     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -1303,18 +1166,6 @@ static void vga_get_text_resolution(VGACommonState *s, int *pwidth, int *pheight
     *pcheight = cheight;
 }
 
-typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b);
-
-static rgb_to_pixel_dup_func * const rgb_to_pixel_dup_table[NB_DEPTHS] = {
-    rgb_to_pixel8_dup,
-    rgb_to_pixel15_dup,
-    rgb_to_pixel16_dup,
-    rgb_to_pixel32_dup,
-    rgb_to_pixel32bgr_dup,
-    rgb_to_pixel15bgr_dup,
-    rgb_to_pixel16bgr_dup,
-};
-
 /*
  * Text mode update
  * Missing:
@@ -1331,11 +1182,9 @@ static void vga_draw_text(VGACommonState *s, int full_update)
     uint32_t offset, fgcol, bgcol, v, cursor_offset;
     uint8_t *d1, *d, *src, *dest, *cursor_ptr;
     const uint8_t *font_ptr, *font_base[2];
-    int dup9, line_offset, depth_index;
+    int dup9, line_offset;
     uint32_t *palette;
     uint32_t *ch_attr_ptr;
-    vga_draw_glyph8_func *vga_draw_glyph8;
-    vga_draw_glyph9_func *vga_draw_glyph9;
     int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
 
     /* compute font data address (in plane 2) */
@@ -1387,8 +1236,6 @@ static void vga_draw_text(VGACommonState *s, int full_update)
         s->last_cw = cw;
         full_update = 1;
     }
-    s->rgb_to_pixel =
-        rgb_to_pixel_dup_table[get_depth_index(surface)];
     full_update |= update_palette16(s);
     palette = s->last_palette;
     x_incr = cw * surface_bytes_per_pixel(surface);
@@ -1422,13 +1269,6 @@ static void vga_draw_text(VGACommonState *s, int full_update)
         s->cursor_visible_phase = !s->cursor_visible_phase;
     }
 
-    depth_index = get_depth_index(surface);
-    if (cw == 16)
-        vga_draw_glyph8 = vga_draw_glyph16_table[depth_index];
-    else
-        vga_draw_glyph8 = vga_draw_glyph8_table[depth_index];
-    vga_draw_glyph9 = vga_draw_glyph9_table[depth_index];
-
     dest = surface_data(surface);
     linesize = surface_stride(surface);
     ch_attr_ptr = s->last_ch_attr;
@@ -1458,7 +1298,10 @@ static void vga_draw_text(VGACommonState *s, int full_update)
                 font_ptr += 32 * 4 * ch;
                 bgcol = palette[cattr >> 4];
                 fgcol = palette[cattr & 0x0f];
-                if (cw != 9) {
+                if (cw == 16) {
+                    vga_draw_glyph16(d1, linesize,
+                                     font_ptr, cheight, fgcol, bgcol);
+                } else if (cw != 9) {
                     vga_draw_glyph8(d1, linesize,
                                     font_ptr, cheight, fgcol, bgcol);
                 } else {
@@ -1483,7 +1326,10 @@ static void vga_draw_text(VGACommonState *s, int full_update)
                     if (line_last >= line_start && line_start < cheight) {
                         h = line_last - line_start + 1;
                         d = d1 + linesize * line_start;
-                        if (cw != 9) {
+                        if (cw == 16) {
+                            vga_draw_glyph16(d, linesize,
+                                             cursor_glyph, h, fgcol, bgcol);
+                        } else if (cw != 9) {
                             vga_draw_glyph8(d, linesize,
                                             cursor_glyph, h, fgcol, bgcol);
                         } else {
@@ -1518,93 +1364,32 @@ 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,
 };
 
-static vga_draw_line_func * const vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = {
-    vga_draw_line2_8,
-    vga_draw_line2_16,
-    vga_draw_line2_16,
-    vga_draw_line2_32,
-    vga_draw_line2_32,
-    vga_draw_line2_16,
-    vga_draw_line2_16,
-
-    vga_draw_line2d2_8,
-    vga_draw_line2d2_16,
-    vga_draw_line2d2_16,
-    vga_draw_line2d2_32,
-    vga_draw_line2d2_32,
-    vga_draw_line2d2_16,
-    vga_draw_line2d2_16,
-
-    vga_draw_line4_8,
-    vga_draw_line4_16,
-    vga_draw_line4_16,
-    vga_draw_line4_32,
-    vga_draw_line4_32,
-    vga_draw_line4_16,
-    vga_draw_line4_16,
-
-    vga_draw_line4d2_8,
-    vga_draw_line4d2_16,
-    vga_draw_line4d2_16,
-    vga_draw_line4d2_32,
-    vga_draw_line4d2_32,
-    vga_draw_line4d2_16,
-    vga_draw_line4d2_16,
-
-    vga_draw_line8d2_8,
-    vga_draw_line8d2_16,
-    vga_draw_line8d2_16,
-    vga_draw_line8d2_32,
-    vga_draw_line8d2_32,
-    vga_draw_line8d2_16,
-    vga_draw_line8d2_16,
-
-    vga_draw_line8_8,
-    vga_draw_line8_16,
-    vga_draw_line8_16,
-    vga_draw_line8_32,
-    vga_draw_line8_32,
-    vga_draw_line8_16,
-    vga_draw_line8_16,
-
-    vga_draw_line15_8,
-    vga_draw_line15_15,
-    vga_draw_line15_16,
-    vga_draw_line15_32,
-    vga_draw_line15_32bgr,
-    vga_draw_line15_15bgr,
-    vga_draw_line15_16bgr,
-
-    vga_draw_line16_8,
-    vga_draw_line16_15,
-    vga_draw_line16_16,
-    vga_draw_line16_32,
-    vga_draw_line16_32bgr,
-    vga_draw_line16_15bgr,
-    vga_draw_line16_16bgr,
-
-    vga_draw_line24_8,
-    vga_draw_line24_15,
-    vga_draw_line24_16,
-    vga_draw_line24_32,
-    vga_draw_line24_32bgr,
-    vga_draw_line24_15bgr,
-    vga_draw_line24_16bgr,
-
-    vga_draw_line32_8,
-    vga_draw_line32_15,
-    vga_draw_line32_16,
-    vga_draw_line32_32,
-    vga_draw_line32_32bgr,
-    vga_draw_line32_15bgr,
-    vga_draw_line32_16bgr,
+static vga_draw_line_func * const vga_draw_line_table[VGA_DRAW_LINE_NB] = {
+    vga_draw_line2,
+    vga_draw_line2d2,
+    vga_draw_line4,
+    vga_draw_line4d2,
+    vga_draw_line8d2,
+    vga_draw_line8,
+    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)
@@ -1676,11 +1461,11 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
     int disp_width, multi_scan, multi_run;
     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;
+    vga_draw_line_func *vga_draw_line = NULL;
+#ifdef HOST_WORDS_BIGENDIAN
+    bool byteswap = !s->big_endian_fb;
 #else
-    static const bool byteswap = true;
+    bool byteswap = s->big_endian_fb;
 #endif
 
     full_update |= update_basic_params(s);
@@ -1723,7 +1508,8 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
     if (s->line_offset != s->last_line_offset ||
         disp_width != s->last_width ||
         height != s->last_height ||
-        s->last_depth != depth) {
+        s->last_depth != depth ||
+        s->last_byteswap != byteswap) {
         if (depth == 32 || (depth == 16 && !byteswap)) {
             pixman_format_code_t format =
                 qemu_default_pixman_format(depth, !byteswap);
@@ -1741,6 +1527,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
         s->last_height = height;
         s->last_line_offset = s->line_offset;
         s->last_depth = depth;
+        s->last_byteswap = byteswap;
         full_update = 1;
     } else if (is_buffer_shared(surface) &&
                (full_update || surface_data(surface) != s->vram_ptr
@@ -1753,9 +1540,6 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
         dpy_gfx_replace_surface(s->con, surface);
     }
 
-    s->rgb_to_pixel =
-        rgb_to_pixel_dup_table[get_depth_index(surface)];
-
     if (shift_control == 0) {
         full_update |= update_palette16(s);
         if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
@@ -1786,25 +1570,24 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
             bits = 8;
             break;
         case 15:
-            v = VGA_DRAW_LINE15;
+            v = s->big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE;
             bits = 16;
             break;
         case 16:
-            v = VGA_DRAW_LINE16;
+            v = s->big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE;
             bits = 16;
             break;
         case 24:
-            v = VGA_DRAW_LINE24;
+            v = s->big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE;
             bits = 24;
             break;
         case 32:
-            v = VGA_DRAW_LINE32;
+            v = s->big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE;
             bits = 32;
             break;
         }
     }
-    vga_draw_line = vga_draw_line_table[v * NB_DEPTHS +
-                                        get_depth_index(surface)];
+    vga_draw_line = vga_draw_line_table[v];
 
     if (!is_buffer_shared(surface) && s->cursor_invalidate) {
         s->cursor_invalidate(s);
@@ -1894,7 +1677,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
 static void vga_draw_blank(VGACommonState *s, int full_update)
 {
     DisplaySurface *surface = qemu_console_surface(s->con);
-    int i, w, val;
+    int i, w;
     uint8_t *d;
 
     if (!full_update)
@@ -1902,17 +1685,10 @@ static void vga_draw_blank(VGACommonState *s, int full_update)
     if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
         return;
 
-    s->rgb_to_pixel =
-        rgb_to_pixel_dup_table[get_depth_index(surface)];
-    if (surface_bits_per_pixel(surface) == 8) {
-        val = s->rgb_to_pixel(0, 0, 0);
-    } else {
-        val = 0;
-    }
     w = s->last_scr_width * surface_bytes_per_pixel(surface);
     d = surface_data(surface);
     for(i = 0; i < s->last_scr_height; i++) {
-        memset(d, val, w);
+        memset(d, 0, w);
         d += surface_stride(surface);
     }
     dpy_gfx_update(s->con, 0, 0,
@@ -2015,6 +1791,7 @@ void vga_common_reset(VGACommonState *s)
     s->cursor_start = 0;
     s->cursor_end = 0;
     s->cursor_offset = 0;
+    s->big_endian_fb = s->default_endian_fb;
     memset(s->invalidated_y_table, '\0', sizeof(s->invalidated_y_table));
     memset(s->last_palette, '\0', sizeof(s->last_palette));
     memset(s->last_ch_attr, '\0', sizeof(s->last_ch_attr));
@@ -2246,6 +2023,28 @@ static int vga_common_post_load(void *opaque, int version_id)
     return 0;
 }
 
+static bool vga_endian_state_needed(void *opaque)
+{
+    VGACommonState *s = opaque;
+
+    /*
+     * Only send the endian state if it's different from the
+     * default one, thus ensuring backward compatibility for
+     * migration of the common case
+     */
+    return s->default_endian_fb != s->big_endian_fb;
+}
+
+const VMStateDescription vmstate_vga_endian = {
+    .name = "vga.endian",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_BOOL(big_endian_fb, VGACommonState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 const VMStateDescription vmstate_vga_common = {
     .name = "vga",
     .version_id = 2,
@@ -2282,6 +2081,14 @@ const VMStateDescription vmstate_vga_common = {
         VMSTATE_UINT32(vbe_line_offset, VGACommonState),
         VMSTATE_UINT32(vbe_bank_mask, VGACommonState),
         VMSTATE_END_OF_LIST()
+    },
+    .subsections = (VMStateSubsection []) {
+        {
+            .vmsd = &vmstate_vga_endian,
+            .needed = vga_endian_state_needed,
+        }, {
+            /* empty */
+        }
     }
 };
 
@@ -2350,6 +2157,17 @@ void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate)
         s->update_retrace_info = vga_precise_update_retrace_info;
         break;
     }
+
+    /*
+     * Set default fb endian based on target, could probably be turned
+     * into a device attribute set by the machine/platform to remove
+     * all target endian dependencies from this file.
+     */
+#ifdef TARGET_WORDS_BIGENDIAN
+    s->default_endian_fb = true;
+#else
+    s->default_endian_fb = false;
+#endif
     vga_dirty_log_start(s);
 }
 
diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h
index bbc0cb2ad8..ed69e064a8 100644
--- a/hw/display/vga_int.h
+++ b/hw/display/vga_int.h
@@ -150,15 +150,16 @@ typedef struct VGACommonState {
     uint32_t last_width, last_height; /* in chars or pixels */
     uint32_t last_scr_width, last_scr_height; /* in pixels */
     uint32_t last_depth; /* in bits */
+    bool last_byteswap;
     uint8_t cursor_start, cursor_end;
     bool cursor_visible_phase;
     int64_t cursor_blink_time;
     uint32_t cursor_offset;
-    unsigned int (*rgb_to_pixel)(unsigned int r,
-                                 unsigned int g, unsigned b);
     const GraphicHwOps *hw_ops;
     bool full_update_text;
     bool full_update_gfx;
+    bool big_endian_fb;
+    bool default_endian_fb;
     /* hardware mouse cursor support */
     uint32_t invalidated_y_table[VGA_MAX_HEIGHT / 32];
     void (*cursor_invalidate)(struct VGACommonState *s);