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>
This commit is contained in:
Benjamin Herrenschmidt 2014-07-07 09:48:28 +10:00 committed by Gerd Hoffmann
parent d2e043a804
commit 46c3a8c8eb
2 changed files with 113 additions and 41 deletions

View File

@ -1374,10 +1374,14 @@ enum {
VGA_DRAW_LINE4D2, VGA_DRAW_LINE4D2,
VGA_DRAW_LINE8D2, VGA_DRAW_LINE8D2,
VGA_DRAW_LINE8, VGA_DRAW_LINE8,
VGA_DRAW_LINE15, VGA_DRAW_LINE15_LE,
VGA_DRAW_LINE16, VGA_DRAW_LINE16_LE,
VGA_DRAW_LINE24, VGA_DRAW_LINE24_LE,
VGA_DRAW_LINE32, VGA_DRAW_LINE32_LE,
VGA_DRAW_LINE15_BE,
VGA_DRAW_LINE16_BE,
VGA_DRAW_LINE24_BE,
VGA_DRAW_LINE32_BE,
VGA_DRAW_LINE_NB, VGA_DRAW_LINE_NB,
}; };
@ -1388,10 +1392,14 @@ static vga_draw_line_func * const vga_draw_line_table[VGA_DRAW_LINE_NB] = {
vga_draw_line4d2, vga_draw_line4d2,
vga_draw_line8d2, vga_draw_line8d2,
vga_draw_line8, vga_draw_line8,
vga_draw_line15, vga_draw_line15_le,
vga_draw_line16, vga_draw_line16_le,
vga_draw_line24, vga_draw_line24_le,
vga_draw_line32, 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) static int vga_get_bpp(VGACommonState *s)
@ -1464,10 +1472,15 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
uint8_t *d; uint8_t *d;
uint32_t v, addr1, addr; uint32_t v, addr1, addr;
vga_draw_line_func *vga_draw_line; vga_draw_line_func *vga_draw_line;
#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) #if defined(TARGET_WORDS_BIGENDIAN)
static const bool byteswap = false; static const bool big_endian_fb = true;
#else #else
static const bool byteswap = true; static const bool big_endian_fb = false;
#endif
#if defined(HOST_WORDS_BIGENDIAN)
static const bool byteswap = !big_endian_fb;
#else
static const bool byteswap = big_endian_fb;
#endif #endif
full_update |= update_basic_params(s); full_update |= update_basic_params(s);
@ -1572,19 +1585,19 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
bits = 8; bits = 8;
break; break;
case 15: case 15:
v = VGA_DRAW_LINE15; v = big_endian_fb ? VGA_DRAW_LINE15_BE : VGA_DRAW_LINE15_LE;
bits = 16; bits = 16;
break; break;
case 16: case 16:
v = VGA_DRAW_LINE16; v = big_endian_fb ? VGA_DRAW_LINE16_BE : VGA_DRAW_LINE16_LE;
bits = 16; bits = 16;
break; break;
case 24: case 24:
v = VGA_DRAW_LINE24; v = big_endian_fb ? VGA_DRAW_LINE24_BE : VGA_DRAW_LINE24_LE;
bits = 24; bits = 24;
break; break;
case 32: case 32:
v = VGA_DRAW_LINE32; v = big_endian_fb ? VGA_DRAW_LINE32_BE : VGA_DRAW_LINE32_LE;
bits = 32; bits = 32;
break; break;
} }

View File

@ -278,13 +278,10 @@ static void vga_draw_line8(VGACommonState *s1, uint8_t *d,
} }
} }
/* XXX: optimize */
/* /*
* 15 bit color * 15 bit color
*/ */
static void vga_draw_line15(VGACommonState *s1, uint8_t *d, static void vga_draw_line15_le(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width) const uint8_t *s, int width)
{ {
int w; int w;
@ -292,7 +289,25 @@ static void vga_draw_line15(VGACommonState *s1, uint8_t *d,
w = width; w = width;
do { 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; r = (v >> 7) & 0xf8;
g = (v >> 2) & 0xf8; g = (v >> 2) & 0xf8;
b = (v << 3) & 0xf8; b = (v << 3) & 0xf8;
@ -305,7 +320,7 @@ static void vga_draw_line15(VGACommonState *s1, uint8_t *d,
/* /*
* 16 bit color * 16 bit color
*/ */
static void vga_draw_line16(VGACommonState *s1, uint8_t *d, static void vga_draw_line16_le(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width) const uint8_t *s, int width)
{ {
int w; int w;
@ -313,7 +328,25 @@ static void vga_draw_line16(VGACommonState *s1, uint8_t *d,
w = width; w = width;
do { 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; r = (v >> 8) & 0xf8;
g = (v >> 3) & 0xfc; g = (v >> 3) & 0xfc;
b = (v << 3) & 0xf8; b = (v << 3) & 0xf8;
@ -326,7 +359,7 @@ static void vga_draw_line16(VGACommonState *s1, uint8_t *d,
/* /*
* 24 bit color * 24 bit color
*/ */
static void vga_draw_line24(VGACommonState *s1, uint8_t *d, static void vga_draw_line24_le(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width) const uint8_t *s, int width)
{ {
int w; int w;
@ -334,15 +367,26 @@ static void vga_draw_line24(VGACommonState *s1, uint8_t *d,
w = width; w = width;
do { do {
#if defined(TARGET_WORDS_BIGENDIAN)
r = s[0];
g = s[1];
b = s[2];
#else
b = s[0]; b = s[0];
g = s[1]; g = s[1];
r = s[2]; 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); ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
s += 3; s += 3;
d += 4; d += 4;
@ -352,10 +396,10 @@ static void vga_draw_line24(VGACommonState *s1, uint8_t *d,
/* /*
* 32 bit color * 32 bit color
*/ */
static void vga_draw_line32(VGACommonState *s1, uint8_t *d, static void vga_draw_line32_le(VGACommonState *s1, uint8_t *d,
const uint8_t *s, int width) const uint8_t *s, int width)
{ {
#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) #ifndef HOST_WORDS_BIGENDIAN
memcpy(d, s, width * 4); memcpy(d, s, width * 4);
#else #else
int w; int w;
@ -363,15 +407,30 @@ static void vga_draw_line32(VGACommonState *s1, uint8_t *d,
w = width; w = width;
do { do {
#if defined(TARGET_WORDS_BIGENDIAN)
r = s[1];
g = s[2];
b = s[3];
#else
b = s[0]; b = s[0];
g = s[1]; g = s[1];
r = s[2]; r = s[2];
#endif ((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); ((uint32_t *)d)[0] = rgb_to_pixel32(r, g, b);
s += 4; s += 4;
d += 4; d += 4;