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 <benh@kernel.crashing.org>\
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
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 @@
}
}
-
-/* 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 @@
/*
* 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 @@
/*
* 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 @@
/*
* 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 @@
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;