Rewrite of the Voodoo update code.
- Moved Banshee/Voodoo3 desktop update code to banshee.cc. - Added desktop / overlay mode testing code for the 16 bpp case. - Added basic UYUV format decoding for black and white output. - Only the fullscreen overlay mode is handled in voodoo.cc. - Reduce BX_ERROR messages when writing to vidProcCfg register.
This commit is contained in:
parent
e9cdc92542
commit
365c45bd80
@ -379,7 +379,7 @@ void bx_banshee_c::draw_hwcursor(unsigned xc, unsigned yc, bx_svga_tileinfo_t *i
|
||||
}
|
||||
if ((xc <= hwcx) && ((int)(xc + X_TILESIZE) > (hwcx - hwcw)) &&
|
||||
(yc <= hwcy) && ((int)(yc + Y_TILESIZE) > (hwcy - 63))) {
|
||||
if ((v->banshee.io[io_vidProcCfg] & 0x181) == 0x81) {
|
||||
if ((v->banshee.io[io_vidProcCfg] & 0x81) == 0x81) {
|
||||
start = v->banshee.io[io_vidDesktopStartAddr];
|
||||
pitch = v->banshee.io[io_vidDesktopOverlayStride] & 0x7fff;
|
||||
} else {
|
||||
@ -457,8 +457,17 @@ void bx_banshee_c::draw_hwcursor(unsigned xc, unsigned yc, bx_svga_tileinfo_t *i
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
index = *(vid_ptr++);
|
||||
index |= *(vid_ptr++) << 8;
|
||||
if (v->banshee.overlay.enabled &&
|
||||
(x >= v->banshee.overlay.x0) &&
|
||||
(x <= v->banshee.overlay.x1) &&
|
||||
(y >= v->banshee.overlay.y0) &&
|
||||
(y <= v->banshee.overlay.y1)) {
|
||||
index = get_overlay_pixel(x, y);
|
||||
} else {
|
||||
index = *(vid_ptr);
|
||||
index |= *(vid_ptr + 1) << 8;
|
||||
}
|
||||
vid_ptr += 2;
|
||||
colour = v->fbi.pen[index];
|
||||
break;
|
||||
case 24:
|
||||
@ -500,6 +509,348 @@ void bx_banshee_c::draw_hwcursor(unsigned xc, unsigned yc, bx_svga_tileinfo_t *i
|
||||
}
|
||||
}
|
||||
|
||||
Bit16u bx_banshee_c::get_overlay_pixel(unsigned x, unsigned y)
|
||||
{
|
||||
Bit16u index;
|
||||
unsigned ox, oy;
|
||||
Bit8u *vid_ptr, yy;
|
||||
|
||||
ox = x - v->banshee.overlay.x0;
|
||||
oy = y - v->banshee.overlay.y0;
|
||||
vid_ptr = &v->fbi.ram[v->banshee.overlay.start & v->fbi.mask] + (ox << 1)
|
||||
+ (oy * v->banshee.overlay.pitch);
|
||||
if (v->banshee.overlay.format == 6) {
|
||||
yy = *(vid_ptr + 1);
|
||||
index = ((yy >> 3) << 11) | ((yy >> 2) << 5) | (yy >> 3);
|
||||
} else {
|
||||
index = *(vid_ptr);
|
||||
index |= *(vid_ptr + 1) << 8;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
void bx_banshee_c::update(void)
|
||||
{
|
||||
Bit32u start;
|
||||
unsigned iHeight, iWidth, riHeight, riWidth;
|
||||
unsigned pitch, xc, yc, xti, yti;
|
||||
unsigned r, c, w, h;
|
||||
int i;
|
||||
Bit32u red, green, blue, colour;
|
||||
Bit8u *vid_ptr, *vid_ptr2;
|
||||
Bit8u *tile_ptr, *tile_ptr2;
|
||||
Bit8u bpp;
|
||||
Bit16u index;
|
||||
bx_svga_tileinfo_t info;
|
||||
|
||||
if ((v->banshee.io[io_vidProcCfg] & 0x81) == 0x81) {
|
||||
BX_LOCK(render_mutex);
|
||||
bpp = v->banshee.disp_bpp;
|
||||
start = v->banshee.io[io_vidDesktopStartAddr];
|
||||
pitch = v->banshee.io[io_vidDesktopOverlayStride] & 0x7fff;
|
||||
if (v->banshee.desktop_tiled) {
|
||||
pitch *= 128;
|
||||
}
|
||||
v->banshee.overlay.enabled = ((v->banshee.io[io_vidProcCfg] & 0x100) != 0);
|
||||
if (v->banshee.overlay.enabled) {
|
||||
v->banshee.overlay.start = v->reg[leftOverlayBuf].u;
|
||||
v->banshee.overlay.pitch = (v->banshee.io[io_vidDesktopOverlayStride] >> 16) & 0x7fff;
|
||||
if (v->banshee.overlay_tiled) {
|
||||
v->banshee.overlay.pitch *= 128;
|
||||
}
|
||||
v->banshee.overlay.format = (v->banshee.io[io_vidProcCfg] >> 21) & 0x07;
|
||||
v->banshee.overlay.x0 = v->banshee.io[io_vidOverlayStartCoord] & 0xfff;
|
||||
v->banshee.overlay.y0 = (v->banshee.io[io_vidOverlayStartCoord] >> 12) & 0xfff;
|
||||
v->banshee.overlay.x1 = v->banshee.io[io_vidOverlayEndScreen] & 0xfff;
|
||||
v->banshee.overlay.y1 = (v->banshee.io[io_vidOverlayEndScreen] >> 12) & 0xfff;
|
||||
}
|
||||
iWidth = s.vdraw.width;
|
||||
iHeight = s.vdraw.height;
|
||||
if (v->banshee.half_mode) {
|
||||
riHeight = iHeight / 2;
|
||||
if (v->banshee.double_width) {
|
||||
riWidth = iWidth / 2;
|
||||
} else {
|
||||
riWidth = iWidth;
|
||||
}
|
||||
} else {
|
||||
riHeight = iHeight;
|
||||
riWidth = iWidth;
|
||||
}
|
||||
start &= v->fbi.mask;
|
||||
Bit8u *disp_ptr = &v->fbi.ram[start];
|
||||
if ((start + pitch * (riHeight - 1) + riWidth) > (v->fbi.mask + 1)) {
|
||||
BX_ERROR(("skip address wrap during update() (start = 0x%08x)", start));
|
||||
BX_UNLOCK(render_mutex);
|
||||
return;
|
||||
}
|
||||
if (bx_gui->graphics_tile_info_common(&info)) {
|
||||
if (info.snapshot_mode) {
|
||||
vid_ptr = disp_ptr;
|
||||
tile_ptr = bx_gui->get_snapshot_buffer();
|
||||
if (tile_ptr != NULL) {
|
||||
for (yc = 0; yc < iHeight; yc++) {
|
||||
memcpy(tile_ptr, vid_ptr, info.pitch);
|
||||
vid_ptr += pitch;
|
||||
tile_ptr += info.pitch;
|
||||
}
|
||||
}
|
||||
} else if (info.is_indexed) {
|
||||
if ((bpp == 8) && (info.bpp == 8)) {
|
||||
for (yc=0, yti = 0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
|
||||
for (xc=0, xti = 0; xc<iWidth; xc+=X_TILESIZE, xti++) {
|
||||
if (GET_TILE_UPDATED (xti, yti)) {
|
||||
vid_ptr = disp_ptr + (yc * pitch + xc);
|
||||
tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
|
||||
for (r=0; r<h; r++) {
|
||||
vid_ptr2 = vid_ptr;
|
||||
tile_ptr2 = tile_ptr;
|
||||
for (c=0; c<w; c++) {
|
||||
*(tile_ptr2++) = *(vid_ptr2++);
|
||||
}
|
||||
vid_ptr += pitch;
|
||||
tile_ptr += info.pitch;
|
||||
}
|
||||
if (v->banshee.hwcursor.enabled) {
|
||||
draw_hwcursor(xc, yc, &info);
|
||||
}
|
||||
set_tile_updated(xti, yti, 0);
|
||||
bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BX_ERROR(("current guest pixel format is unsupported on indexed colour host displays"));
|
||||
}
|
||||
} else {
|
||||
switch (bpp) {
|
||||
case 8:
|
||||
for (yc=0, yti = 0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
|
||||
for (xc=0, xti = 0; xc<iWidth; xc+=X_TILESIZE, xti++) {
|
||||
if (GET_TILE_UPDATED(xti, yti)) {
|
||||
if (v->banshee.half_mode) {
|
||||
if (v->banshee.double_width) {
|
||||
vid_ptr = disp_ptr + ((yc >> 1) * pitch + (xc >> 1));
|
||||
} else {
|
||||
vid_ptr = disp_ptr + ((yc >> 1) * pitch + xc);
|
||||
}
|
||||
} else {
|
||||
vid_ptr = disp_ptr + (yc * pitch + xc);
|
||||
}
|
||||
tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
|
||||
for (r=0; r<h; r++) {
|
||||
vid_ptr2 = vid_ptr;
|
||||
tile_ptr2 = tile_ptr;
|
||||
for (c=0; c<w; c++) {
|
||||
colour = v->fbi.clut[*(vid_ptr2)];
|
||||
if (!v->banshee.double_width || (c & 1)) {
|
||||
vid_ptr2++;
|
||||
}
|
||||
colour = MAKE_COLOUR(
|
||||
colour & 0xff0000, 24, info.red_shift, info.red_mask,
|
||||
colour & 0x00ff00, 16, info.green_shift, info.green_mask,
|
||||
colour & 0x0000ff, 8, info.blue_shift, info.blue_mask);
|
||||
if (info.is_little_endian) {
|
||||
for (i=0; i<info.bpp; i+=8) {
|
||||
*(tile_ptr2++) = (Bit8u)(colour >> i);
|
||||
}
|
||||
} else {
|
||||
for (i=info.bpp-8; i>-8; i-=8) {
|
||||
*(tile_ptr2++) = (Bit8u)(colour >> i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!v->banshee.half_mode || (r & 1)) {
|
||||
vid_ptr += pitch;
|
||||
}
|
||||
tile_ptr += info.pitch;
|
||||
}
|
||||
if (v->banshee.hwcursor.enabled) {
|
||||
draw_hwcursor(xc, yc, &info);
|
||||
}
|
||||
set_tile_updated(xti, yti, 0);
|
||||
bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
for (yc=0, yti = 0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
|
||||
for (xc=0, xti = 0; xc<iWidth; xc+=X_TILESIZE, xti++) {
|
||||
if (GET_TILE_UPDATED(xti, yti)) {
|
||||
if (v->banshee.half_mode) {
|
||||
if (v->banshee.double_width) {
|
||||
vid_ptr = disp_ptr + ((yc >> 1) * pitch + xc);
|
||||
} else {
|
||||
vid_ptr = disp_ptr + ((yc >> 1) * pitch + (xc << 1));
|
||||
}
|
||||
} else {
|
||||
vid_ptr = disp_ptr + (yc * pitch + (xc << 1));
|
||||
}
|
||||
tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
|
||||
for (r=0; r<h; r++) {
|
||||
vid_ptr2 = vid_ptr;
|
||||
tile_ptr2 = tile_ptr;
|
||||
for (c=0; c<w; c++) {
|
||||
if (v->banshee.overlay.enabled &&
|
||||
((xc + c) >= v->banshee.overlay.x0) &&
|
||||
((xc + c) <= v->banshee.overlay.x1) &&
|
||||
((yc + r) >= v->banshee.overlay.y0) &&
|
||||
((yc + r) <= v->banshee.overlay.y1)) {
|
||||
index = get_overlay_pixel(xc + c, yc + r);
|
||||
} else {
|
||||
index = *(vid_ptr2);
|
||||
index |= *(vid_ptr2 + 1) << 8;
|
||||
}
|
||||
if (!v->banshee.double_width || (c & 1)) {
|
||||
vid_ptr2 += 2;
|
||||
}
|
||||
colour = MAKE_COLOUR(
|
||||
v->fbi.pen[index] & 0x0000ff, 8, info.blue_shift, info.blue_mask,
|
||||
v->fbi.pen[index] & 0x00ff00, 16, info.green_shift, info.green_mask,
|
||||
v->fbi.pen[index] & 0xff0000, 24, info.red_shift, info.red_mask);
|
||||
if (info.is_little_endian) {
|
||||
for (i=0; i<info.bpp; i+=8) {
|
||||
*(tile_ptr2++) = (Bit8u)(colour >> i);
|
||||
}
|
||||
} else {
|
||||
for (i=info.bpp-8; i>-8; i-=8) {
|
||||
*(tile_ptr2++) = (Bit8u)(colour >> i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!v->banshee.half_mode || (r & 1)) {
|
||||
vid_ptr += pitch;
|
||||
}
|
||||
tile_ptr += info.pitch;
|
||||
}
|
||||
if (v->banshee.hwcursor.enabled) {
|
||||
draw_hwcursor(xc, yc, &info);
|
||||
}
|
||||
set_tile_updated(xti, yti, 0);
|
||||
bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
for (yc=0, yti = 0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
|
||||
for (xc=0, xti = 0; xc<iWidth; xc+=X_TILESIZE, xti++) {
|
||||
if (GET_TILE_UPDATED(xti, yti)) {
|
||||
if (v->banshee.half_mode) {
|
||||
if (v->banshee.double_width) {
|
||||
vid_ptr = disp_ptr + ((yc >> 1) * pitch + 3 * (xc >> 1));
|
||||
} else {
|
||||
vid_ptr = disp_ptr + ((yc >> 1) * pitch + 3 * xc);
|
||||
}
|
||||
} else {
|
||||
vid_ptr = disp_ptr + (yc * pitch + 3*xc);
|
||||
}
|
||||
tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
|
||||
for (r=0; r<h; r++) {
|
||||
vid_ptr2 = vid_ptr;
|
||||
tile_ptr2 = tile_ptr;
|
||||
for (c=0; c<w; c++) {
|
||||
blue = *(vid_ptr2);
|
||||
green = *(vid_ptr2 + 1);
|
||||
red = *(vid_ptr2 + 2);
|
||||
if (!v->banshee.double_width || (c & 1)) {
|
||||
vid_ptr2 += 3;
|
||||
}
|
||||
colour = MAKE_COLOUR(
|
||||
red, 8, info.red_shift, info.red_mask,
|
||||
green, 8, info.green_shift, info.green_mask,
|
||||
blue, 8, info.blue_shift, info.blue_mask);
|
||||
if (info.is_little_endian) {
|
||||
for (i=0; i<info.bpp; i+=8) {
|
||||
*(tile_ptr2++) = (Bit8u)(colour >> i);
|
||||
}
|
||||
} else {
|
||||
for (i=info.bpp-8; i>-8; i-=8) {
|
||||
*(tile_ptr2++) = (Bit8u)(colour >> i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!v->banshee.half_mode || (r & 1)) {
|
||||
vid_ptr += pitch;
|
||||
}
|
||||
tile_ptr += info.pitch;
|
||||
}
|
||||
if (v->banshee.hwcursor.enabled) {
|
||||
draw_hwcursor(xc, yc, &info);
|
||||
}
|
||||
set_tile_updated(xti, yti, 0);
|
||||
bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
for (yc=0, yti = 0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
|
||||
for (xc=0, xti = 0; xc<iWidth; xc+=X_TILESIZE, xti++) {
|
||||
if (GET_TILE_UPDATED(xti, yti)) {
|
||||
if (v->banshee.half_mode) {
|
||||
if (v->banshee.double_width) {
|
||||
vid_ptr = disp_ptr + ((yc >> 1) * pitch + (xc << 1));
|
||||
} else {
|
||||
vid_ptr = disp_ptr + ((yc >> 1) * pitch + (xc << 2));
|
||||
}
|
||||
} else {
|
||||
vid_ptr = disp_ptr + (yc * pitch + (xc << 2));
|
||||
}
|
||||
tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
|
||||
for (r=0; r<h; r++) {
|
||||
vid_ptr2 = vid_ptr;
|
||||
tile_ptr2 = tile_ptr;
|
||||
for (c=0; c<w; c++) {
|
||||
blue = *(vid_ptr2);
|
||||
green = *(vid_ptr2 + 1);
|
||||
red = *(vid_ptr2 + 2);
|
||||
if (!v->banshee.double_width || (c & 1)) {
|
||||
vid_ptr2 += 4;
|
||||
}
|
||||
colour = MAKE_COLOUR(
|
||||
red, 8, info.red_shift, info.red_mask,
|
||||
green, 8, info.green_shift, info.green_mask,
|
||||
blue, 8, info.blue_shift, info.blue_mask);
|
||||
if (info.is_little_endian) {
|
||||
for (i=0; i<info.bpp; i+=8) {
|
||||
*(tile_ptr2++) = (Bit8u)(colour >> i);
|
||||
}
|
||||
} else {
|
||||
for (i=info.bpp-8; i>-8; i-=8) {
|
||||
*(tile_ptr2++) = (Bit8u)(colour >> i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!v->banshee.half_mode || (r & 1)) {
|
||||
vid_ptr += pitch;
|
||||
}
|
||||
tile_ptr += info.pitch;
|
||||
}
|
||||
if (v->banshee.hwcursor.enabled) {
|
||||
draw_hwcursor(xc, yc, &info);
|
||||
}
|
||||
set_tile_updated(xti, yti, 0);
|
||||
bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BX_ERROR(("Ignoring reserved pixel format"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BX_PANIC(("cannot get svga tile info"));
|
||||
}
|
||||
s.vdraw.gui_update_pending = 0;
|
||||
BX_UNLOCK(render_mutex);
|
||||
} else {
|
||||
bx_voodoo_base_c::update();
|
||||
}
|
||||
}
|
||||
|
||||
Bit32u bx_banshee_c::get_retrace(bool hv)
|
||||
{
|
||||
return theVoodooVga->get_retrace();
|
||||
@ -732,7 +1083,7 @@ void bx_banshee_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
||||
BX_INFO(("3D overlay mode enabled"));
|
||||
v->vtimer_running = 1;
|
||||
} else if ((v->banshee.io[reg] & 0x180) == 0x180) {
|
||||
BX_ERROR(("Desktop / overlay mode not supported yet"));
|
||||
BX_ERROR(("Desktop / overlay mode not yet complete"));
|
||||
}
|
||||
}
|
||||
v->banshee.hwcursor.enabled = ((v->banshee.io[reg] >> 27) & 1);
|
||||
@ -749,16 +1100,16 @@ void bx_banshee_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
||||
if ((v->banshee.io[reg] >> 2) & 1) {
|
||||
BX_ERROR(("vidProcCfg: overlay stereo mode not supported yet"));
|
||||
}
|
||||
if ((v->banshee.io[reg] >> 5) & 1) {
|
||||
if (((v->banshee.io[reg] >> 5) & 1) && !((old >> 5) & 1)) {
|
||||
BX_ERROR(("vidProcCfg: chromaKey mode not supported yet"));
|
||||
}
|
||||
if ((v->banshee.io[reg] >> 14) & 1) {
|
||||
if (((v->banshee.io[reg] >> 14) & 1) && !((old >> 14) & 1)) {
|
||||
BX_ERROR(("vidProcCfg: overlay horizontal scaling not supported yet"));
|
||||
}
|
||||
if ((v->banshee.io[reg] >> 15) & 1) {
|
||||
if (((v->banshee.io[reg] >> 15) & 1) && !((old >> 15) & 1)) {
|
||||
BX_ERROR(("vidProcCfg: overlay vertical scaling not supported yet"));
|
||||
}
|
||||
if ((v->banshee.io[reg] >> 16) & 3) {
|
||||
if (((v->banshee.io[reg] >> 16) & 3) != ((old >> 16) & 3)) {
|
||||
BX_ERROR(("vidProcCfg: overlay filter mode %d not supported yet", (v->banshee.io[reg] >> 16) & 3));
|
||||
}
|
||||
v->banshee.desktop_tiled = ((v->banshee.io[reg] >> 24) & 1);
|
||||
|
@ -556,65 +556,37 @@ void bx_voodoo_base_c::redraw_area(unsigned x0, unsigned y0, unsigned width,
|
||||
void bx_voodoo_base_c::update(void)
|
||||
{
|
||||
Bit32u start;
|
||||
unsigned iHeight, iWidth, riHeight, riWidth;
|
||||
unsigned iHeight, iWidth;
|
||||
unsigned pitch, xc, yc, xti, yti;
|
||||
unsigned r, c, w, h;
|
||||
int i;
|
||||
Bit32u red, green, blue, colour;
|
||||
Bit32u colour;
|
||||
Bit8u *vid_ptr, *vid_ptr2;
|
||||
Bit8u *tile_ptr, *tile_ptr2;
|
||||
Bit8u bpp;
|
||||
Bit16u index;
|
||||
bx_svga_tileinfo_t info;
|
||||
|
||||
BX_LOCK(render_mutex);
|
||||
if ((s.model >= VOODOO_BANSHEE) &&
|
||||
((v->banshee.io[io_vidProcCfg] & 0x181) == 0x81)) {
|
||||
bpp = v->banshee.disp_bpp;
|
||||
start = v->banshee.io[io_vidDesktopStartAddr];
|
||||
pitch = v->banshee.io[io_vidDesktopOverlayStride] & 0x7fff;
|
||||
if (v->banshee.desktop_tiled) {
|
||||
pitch *= 128;
|
||||
}
|
||||
} else {
|
||||
if (!s.vdraw.gui_update_pending) {
|
||||
BX_UNLOCK(render_mutex);
|
||||
return;
|
||||
}
|
||||
bpp = 16;
|
||||
BX_LOCK(fifo_mutex);
|
||||
if (s.model >= VOODOO_BANSHEE) {
|
||||
start = v->fbi.rgboffs[0];
|
||||
pitch = (v->banshee.io[io_vidDesktopOverlayStride] >> 16) & 0x7fff;
|
||||
if (v->banshee.overlay_tiled) {
|
||||
pitch *= 128;
|
||||
}
|
||||
} else {
|
||||
start = v->fbi.rgboffs[v->fbi.frontbuf];
|
||||
pitch = v->fbi.rowpixels * 2;
|
||||
}
|
||||
BX_UNLOCK(fifo_mutex);
|
||||
}
|
||||
iWidth = s.vdraw.width;
|
||||
iHeight = s.vdraw.height;
|
||||
if (v->banshee.half_mode) {
|
||||
riHeight = iHeight / 2;
|
||||
if (v->banshee.double_width) {
|
||||
riWidth = iWidth / 2;
|
||||
} else {
|
||||
riWidth = iWidth;
|
||||
}
|
||||
} else {
|
||||
riHeight = iHeight;
|
||||
riWidth = iWidth;
|
||||
}
|
||||
start &= v->fbi.mask;
|
||||
Bit8u *disp_ptr = &v->fbi.ram[start];
|
||||
if ((start + pitch * (riHeight - 1) + riWidth) > (v->fbi.mask + 1)) {
|
||||
BX_ERROR(("skip address wrap during update() (start = 0x%08x)", start));
|
||||
if (!s.vdraw.gui_update_pending) {
|
||||
BX_UNLOCK(render_mutex);
|
||||
return;
|
||||
}
|
||||
BX_LOCK(fifo_mutex);
|
||||
if (s.model >= VOODOO_BANSHEE) {
|
||||
start = v->fbi.rgboffs[0];
|
||||
pitch = (v->banshee.io[io_vidDesktopOverlayStride] >> 16) & 0x7fff;
|
||||
if (v->banshee.overlay_tiled) {
|
||||
pitch *= 128;
|
||||
}
|
||||
} else {
|
||||
start = v->fbi.rgboffs[v->fbi.frontbuf];
|
||||
pitch = v->fbi.rowpixels * 2;
|
||||
}
|
||||
BX_UNLOCK(fifo_mutex);
|
||||
iWidth = s.vdraw.width;
|
||||
iHeight = s.vdraw.height;
|
||||
start &= v->fbi.mask;
|
||||
Bit8u *disp_ptr = &v->fbi.ram[start];
|
||||
|
||||
if (bx_gui->graphics_tile_info_common(&info)) {
|
||||
if (info.snapshot_mode) {
|
||||
@ -628,241 +600,56 @@ void bx_voodoo_base_c::update(void)
|
||||
}
|
||||
}
|
||||
} else if (info.is_indexed) {
|
||||
if ((bpp == 8) && (info.bpp == 8)) {
|
||||
for (yc=0, yti = 0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
|
||||
for (xc=0, xti = 0; xc<iWidth; xc+=X_TILESIZE, xti++) {
|
||||
if (GET_TILE_UPDATED (xti, yti)) {
|
||||
vid_ptr = disp_ptr + (yc * pitch + xc);
|
||||
tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
|
||||
for (r=0; r<h; r++) {
|
||||
vid_ptr2 = vid_ptr;
|
||||
tile_ptr2 = tile_ptr;
|
||||
for (c=0; c<w; c++) {
|
||||
*(tile_ptr2++) = *(vid_ptr2++);
|
||||
}
|
||||
vid_ptr += pitch;
|
||||
tile_ptr += info.pitch;
|
||||
BX_ERROR(("current guest pixel format is unsupported on indexed colour host displays"));
|
||||
} else {
|
||||
for (yc=0, yti = 0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
|
||||
for (xc=0, xti = 0; xc<iWidth; xc+=X_TILESIZE, xti++) {
|
||||
if (GET_TILE_UPDATED(xti, yti)) {
|
||||
if (v->banshee.half_mode) {
|
||||
if (v->banshee.double_width) {
|
||||
vid_ptr = disp_ptr + ((yc >> 1) * pitch + xc);
|
||||
} else {
|
||||
vid_ptr = disp_ptr + ((yc >> 1) * pitch + (xc << 1));
|
||||
}
|
||||
if (v->banshee.hwcursor.enabled) {
|
||||
draw_hwcursor(xc, yc, &info);
|
||||
}
|
||||
SET_TILE_UPDATED(BX_VOODOO_THIS, xti, yti, 0);
|
||||
bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
|
||||
} else {
|
||||
vid_ptr = disp_ptr + (yc * pitch + (xc << 1));
|
||||
}
|
||||
tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
|
||||
for (r=0; r<h; r++) {
|
||||
vid_ptr2 = vid_ptr;
|
||||
tile_ptr2 = tile_ptr;
|
||||
for (c=0; c<w; c++) {
|
||||
index = *(vid_ptr2);
|
||||
index |= *(vid_ptr2 + 1) << 8;
|
||||
if (!v->banshee.double_width || (c & 1)) {
|
||||
vid_ptr2 += 2;
|
||||
}
|
||||
colour = MAKE_COLOUR(
|
||||
v->fbi.pen[index] & 0x0000ff, 8, info.blue_shift, info.blue_mask,
|
||||
v->fbi.pen[index] & 0x00ff00, 16, info.green_shift, info.green_mask,
|
||||
v->fbi.pen[index] & 0xff0000, 24, info.red_shift, info.red_mask);
|
||||
if (info.is_little_endian) {
|
||||
for (i=0; i<info.bpp; i+=8) {
|
||||
*(tile_ptr2++) = (Bit8u)(colour >> i);
|
||||
}
|
||||
} else {
|
||||
for (i=info.bpp-8; i>-8; i-=8) {
|
||||
*(tile_ptr2++) = (Bit8u)(colour >> i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!v->banshee.half_mode || (r & 1)) {
|
||||
vid_ptr += pitch;
|
||||
}
|
||||
tile_ptr += info.pitch;
|
||||
}
|
||||
if (v->banshee.hwcursor.enabled) {
|
||||
draw_hwcursor(xc, yc, &info);
|
||||
}
|
||||
SET_TILE_UPDATED(BX_VOODOO_THIS, xti, yti, 0);
|
||||
bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BX_ERROR(("current guest pixel format is unsupported on indexed colour host displays"));
|
||||
}
|
||||
} else {
|
||||
switch (bpp) {
|
||||
case 8:
|
||||
for (yc=0, yti = 0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
|
||||
for (xc=0, xti = 0; xc<iWidth; xc+=X_TILESIZE, xti++) {
|
||||
if (GET_TILE_UPDATED(xti, yti)) {
|
||||
if (v->banshee.half_mode) {
|
||||
if (v->banshee.double_width) {
|
||||
vid_ptr = disp_ptr + ((yc >> 1) * pitch + (xc >> 1));
|
||||
} else {
|
||||
vid_ptr = disp_ptr + ((yc >> 1) * pitch + xc);
|
||||
}
|
||||
} else {
|
||||
vid_ptr = disp_ptr + (yc * pitch + xc);
|
||||
}
|
||||
tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
|
||||
for (r=0; r<h; r++) {
|
||||
vid_ptr2 = vid_ptr;
|
||||
tile_ptr2 = tile_ptr;
|
||||
for (c=0; c<w; c++) {
|
||||
colour = v->fbi.clut[*(vid_ptr2)];
|
||||
if (!v->banshee.double_width || (c & 1)) {
|
||||
vid_ptr2++;
|
||||
}
|
||||
colour = MAKE_COLOUR(
|
||||
colour & 0xff0000, 24, info.red_shift, info.red_mask,
|
||||
colour & 0x00ff00, 16, info.green_shift, info.green_mask,
|
||||
colour & 0x0000ff, 8, info.blue_shift, info.blue_mask);
|
||||
if (info.is_little_endian) {
|
||||
for (i=0; i<info.bpp; i+=8) {
|
||||
*(tile_ptr2++) = (Bit8u)(colour >> i);
|
||||
}
|
||||
} else {
|
||||
for (i=info.bpp-8; i>-8; i-=8) {
|
||||
*(tile_ptr2++) = (Bit8u)(colour >> i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!v->banshee.half_mode || (r & 1)) {
|
||||
vid_ptr += pitch;
|
||||
}
|
||||
tile_ptr += info.pitch;
|
||||
}
|
||||
if (v->banshee.hwcursor.enabled) {
|
||||
draw_hwcursor(xc, yc, &info);
|
||||
}
|
||||
SET_TILE_UPDATED(BX_VOODOO_THIS, xti, yti, 0);
|
||||
bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
for (yc=0, yti = 0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
|
||||
for (xc=0, xti = 0; xc<iWidth; xc+=X_TILESIZE, xti++) {
|
||||
if (GET_TILE_UPDATED(xti, yti)) {
|
||||
if (v->banshee.half_mode) {
|
||||
if (v->banshee.double_width) {
|
||||
vid_ptr = disp_ptr + ((yc >> 1) * pitch + xc);
|
||||
} else {
|
||||
vid_ptr = disp_ptr + ((yc >> 1) * pitch + (xc << 1));
|
||||
}
|
||||
} else {
|
||||
vid_ptr = disp_ptr + (yc * pitch + (xc << 1));
|
||||
}
|
||||
tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
|
||||
for (r=0; r<h; r++) {
|
||||
vid_ptr2 = vid_ptr;
|
||||
tile_ptr2 = tile_ptr;
|
||||
for (c=0; c<w; c++) {
|
||||
index = *(vid_ptr2);
|
||||
index |= *(vid_ptr2 + 1) << 8;
|
||||
if (!v->banshee.double_width || (c & 1)) {
|
||||
vid_ptr2 += 2;
|
||||
}
|
||||
colour = MAKE_COLOUR(
|
||||
v->fbi.pen[index] & 0x0000ff, 8, info.blue_shift, info.blue_mask,
|
||||
v->fbi.pen[index] & 0x00ff00, 16, info.green_shift, info.green_mask,
|
||||
v->fbi.pen[index] & 0xff0000, 24, info.red_shift, info.red_mask);
|
||||
if (info.is_little_endian) {
|
||||
for (i=0; i<info.bpp; i+=8) {
|
||||
*(tile_ptr2++) = (Bit8u)(colour >> i);
|
||||
}
|
||||
} else {
|
||||
for (i=info.bpp-8; i>-8; i-=8) {
|
||||
*(tile_ptr2++) = (Bit8u)(colour >> i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!v->banshee.half_mode || (r & 1)) {
|
||||
vid_ptr += pitch;
|
||||
}
|
||||
tile_ptr += info.pitch;
|
||||
}
|
||||
if (v->banshee.hwcursor.enabled) {
|
||||
draw_hwcursor(xc, yc, &info);
|
||||
}
|
||||
SET_TILE_UPDATED(BX_VOODOO_THIS, xti, yti, 0);
|
||||
bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
for (yc=0, yti = 0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
|
||||
for (xc=0, xti = 0; xc<iWidth; xc+=X_TILESIZE, xti++) {
|
||||
if (GET_TILE_UPDATED(xti, yti)) {
|
||||
if (v->banshee.half_mode) {
|
||||
if (v->banshee.double_width) {
|
||||
vid_ptr = disp_ptr + ((yc >> 1) * pitch + 3 * (xc >> 1));
|
||||
} else {
|
||||
vid_ptr = disp_ptr + ((yc >> 1) * pitch + 3 * xc);
|
||||
}
|
||||
} else {
|
||||
vid_ptr = disp_ptr + (yc * pitch + 3*xc);
|
||||
}
|
||||
tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
|
||||
for (r=0; r<h; r++) {
|
||||
vid_ptr2 = vid_ptr;
|
||||
tile_ptr2 = tile_ptr;
|
||||
for (c=0; c<w; c++) {
|
||||
blue = *(vid_ptr2);
|
||||
green = *(vid_ptr2 + 1);
|
||||
red = *(vid_ptr2 + 2);
|
||||
if (!v->banshee.double_width || (c & 1)) {
|
||||
vid_ptr2 += 3;
|
||||
}
|
||||
colour = MAKE_COLOUR(
|
||||
red, 8, info.red_shift, info.red_mask,
|
||||
green, 8, info.green_shift, info.green_mask,
|
||||
blue, 8, info.blue_shift, info.blue_mask);
|
||||
if (info.is_little_endian) {
|
||||
for (i=0; i<info.bpp; i+=8) {
|
||||
*(tile_ptr2++) = (Bit8u)(colour >> i);
|
||||
}
|
||||
} else {
|
||||
for (i=info.bpp-8; i>-8; i-=8) {
|
||||
*(tile_ptr2++) = (Bit8u)(colour >> i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!v->banshee.half_mode || (r & 1)) {
|
||||
vid_ptr += pitch;
|
||||
}
|
||||
tile_ptr += info.pitch;
|
||||
}
|
||||
if (v->banshee.hwcursor.enabled) {
|
||||
draw_hwcursor(xc, yc, &info);
|
||||
}
|
||||
SET_TILE_UPDATED(BX_VOODOO_THIS, xti, yti, 0);
|
||||
bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
for (yc=0, yti = 0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
|
||||
for (xc=0, xti = 0; xc<iWidth; xc+=X_TILESIZE, xti++) {
|
||||
if (GET_TILE_UPDATED(xti, yti)) {
|
||||
if (v->banshee.half_mode) {
|
||||
if (v->banshee.double_width) {
|
||||
vid_ptr = disp_ptr + ((yc >> 1) * pitch + (xc << 1));
|
||||
} else {
|
||||
vid_ptr = disp_ptr + ((yc >> 1) * pitch + (xc << 2));
|
||||
}
|
||||
} else {
|
||||
vid_ptr = disp_ptr + (yc * pitch + (xc << 2));
|
||||
}
|
||||
tile_ptr = bx_gui->graphics_tile_get(xc, yc, &w, &h);
|
||||
for (r=0; r<h; r++) {
|
||||
vid_ptr2 = vid_ptr;
|
||||
tile_ptr2 = tile_ptr;
|
||||
for (c=0; c<w; c++) {
|
||||
blue = *(vid_ptr2);
|
||||
green = *(vid_ptr2 + 1);
|
||||
red = *(vid_ptr2 + 2);
|
||||
if (!v->banshee.double_width || (c & 1)) {
|
||||
vid_ptr2 += 4;
|
||||
}
|
||||
colour = MAKE_COLOUR(
|
||||
red, 8, info.red_shift, info.red_mask,
|
||||
green, 8, info.green_shift, info.green_mask,
|
||||
blue, 8, info.blue_shift, info.blue_mask);
|
||||
if (info.is_little_endian) {
|
||||
for (i=0; i<info.bpp; i+=8) {
|
||||
*(tile_ptr2++) = (Bit8u)(colour >> i);
|
||||
}
|
||||
} else {
|
||||
for (i=info.bpp-8; i>-8; i-=8) {
|
||||
*(tile_ptr2++) = (Bit8u)(colour >> i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!v->banshee.half_mode || (r & 1)) {
|
||||
vid_ptr += pitch;
|
||||
}
|
||||
tile_ptr += info.pitch;
|
||||
}
|
||||
if (v->banshee.hwcursor.enabled) {
|
||||
draw_hwcursor(xc, yc, &info);
|
||||
}
|
||||
SET_TILE_UPDATED(BX_VOODOO_THIS, xti, yti, 0);
|
||||
bx_gui->graphics_tile_update_in_place(xc, yc, w, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BX_ERROR(("Ignoring reserved pixel format"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -127,6 +127,7 @@ public:
|
||||
virtual void register_state(void);
|
||||
virtual void after_restore_state(void);
|
||||
|
||||
virtual void update(void);
|
||||
virtual bool update_timing(void);
|
||||
virtual Bit32u get_retrace(bool hv);
|
||||
|
||||
@ -179,6 +180,8 @@ private:
|
||||
void blt_line(bool pline);
|
||||
void blt_polygon_fill(bool force);
|
||||
|
||||
Bit16u get_overlay_pixel(unsigned x, unsigned y);
|
||||
|
||||
bx_ddc_c ddc;
|
||||
bool is_agp;
|
||||
};
|
||||
|
@ -846,8 +846,8 @@ static const char *const banshee_reg_name[] =
|
||||
#define io_vidChromaMax (0x090/4) /* */
|
||||
#define io_vidCurrentLine (0x094/4) /* */
|
||||
#define io_vidScreenSize (0x098/4) /* */
|
||||
#define io_vidOverlayStartCoords (0x09c/4) /* */
|
||||
#define io_vidOverlayEndScreenCoord (0x0a0/4) /* */
|
||||
#define io_vidOverlayStartCoord (0x09c/4) /* */
|
||||
#define io_vidOverlayEndScreen (0x0a0/4) /* */
|
||||
#define io_vidOverlayDudx (0x0a4/4) /* */
|
||||
#define io_vidOverlayDudxOffsetSrcWidth (0x0a8/4) /* */
|
||||
#define io_vidOverlayDvdy (0x0ac/4) /* */
|
||||
@ -898,8 +898,8 @@ static const char *const banshee_io_reg_name[] =
|
||||
|
||||
/* 0x080 */
|
||||
"vidInDecimInitErrs","vidInYDecimDeltas","vidPixelBufThold","vidChromaMin",
|
||||
"vidChromaMax", "vidCurrentLine","vidScreenSize","vidOverlayStartCoords",
|
||||
"vidOverlayEndScreenCoord","vidOverlayDudx","vidOverlayDudxOffsetSrcWidth","vidOverlayDvdy",
|
||||
"vidChromaMax", "vidCurrentLine","vidScreenSize","vidOverlayStartCoord",
|
||||
"vidOverlayEndScreen","vidOverlayDudx","vidOverlayDudxOffsetSrcWidth","vidOverlayDvdy",
|
||||
"vga[b0]", "vga[b4]", "vga[b8]", "vga[bc]",
|
||||
|
||||
/* 0x0c0 */
|
||||
@ -1799,6 +1799,16 @@ struct _banshee_info
|
||||
Bit32u laidx;
|
||||
Bit8u *lamem;
|
||||
} blt;
|
||||
struct {
|
||||
bool enabled;
|
||||
Bit8u format;
|
||||
Bit32u start;
|
||||
Bit16u pitch;
|
||||
Bit16u x0;
|
||||
Bit16u y0;
|
||||
Bit16u x1;
|
||||
Bit16u y1;
|
||||
} overlay;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user