From 29b63b2cb34f534d3105edfc5a74ddd45ef90205 Mon Sep 17 00:00:00 2001 From: Volker Ruppert Date: Sat, 9 Nov 2024 13:47:51 +0100 Subject: [PATCH] Banshee/Voodoo3: Some optimizations for the desktop / overlay mode. - Redraw the overlay region only instead of full screen. - Set up overlay parameters at register writes. TODO list: - 24 / 32 bpp desktop support - Overlay color conversion YUV -> RGB - Overlay scaling support --- bochs/iodev/display/banshee.cc | 26 +++++++++++++++++--------- bochs/iodev/display/voodoo.cc | 8 +++++++- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/bochs/iodev/display/banshee.cc b/bochs/iodev/display/banshee.cc index db7da9b08..2fdc1f99b 100644 --- a/bochs/iodev/display/banshee.cc +++ b/bochs/iodev/display/banshee.cc @@ -551,18 +551,12 @@ void bx_banshee_c::update(void) 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; @@ -1077,6 +1071,7 @@ void bx_banshee_c::write(Bit32u address, Bit32u value, unsigned io_len) mode_change = true; } if (mode_change) { + v->banshee.overlay.enabled = ((v->banshee.io[reg] & 0x100) != 0); if ((v->banshee.io[reg] & 0x180) == 0x080) { BX_INFO(("2D desktop mode enabled")); } else if ((v->banshee.io[reg] & 0x180) == 0x100) { @@ -1084,6 +1079,7 @@ void bx_banshee_c::write(Bit32u address, Bit32u value, unsigned io_len) v->vtimer_running = 1; } else if ((v->banshee.io[reg] & 0x180) == 0x180) { BX_ERROR(("Desktop / overlay mode not yet complete")); + v->banshee.overlay.format = (v->banshee.io[reg] >> 21) & 0x07; } } v->banshee.hwcursor.enabled = ((v->banshee.io[reg] >> 27) & 1); @@ -1175,6 +1171,18 @@ void bx_banshee_c::write(Bit32u address, Bit32u value, unsigned io_len) v->fbi.height = (value >> 12) & 0xfff; break; + case io_vidOverlayStartCoord: + v->banshee.io[reg] = value; + v->banshee.overlay.x0 = value & 0xfff; + v->banshee.overlay.y0 = (value >> 12) & 0xfff; + break; + + case io_vidOverlayEndScreen: + v->banshee.io[reg] = value; + v->banshee.overlay.x1 = value & 0xfff; + v->banshee.overlay.y1 = (value >> 12) & 0xfff; + break; + case io_vgab0: case io_vgab4: case io_vgab8: case io_vgabc: case io_vgac0: case io_vgac4: case io_vgac8: case io_vgacc: case io_vgad0: case io_vgad4: case io_vgad8: case io_vgadc: @@ -1190,7 +1198,7 @@ void bx_banshee_c::write(Bit32u address, Bit32u value, unsigned io_len) case io_vidDesktopStartAddr: case io_vidDesktopOverlayStride: if ((v->banshee.io[io_vidProcCfg] & 0x01) && (v->banshee.io[reg] != value)) { - v->fbi.video_changed = 1; + theVoodooVga->redraw_area(0, 0, s.vdraw.width, s.vdraw.height); } v->banshee.io[reg] = value; break; @@ -2022,7 +2030,7 @@ void bx_banshee_c::blt_complete() bool yinc = (cmd >> 11) & 1; int x, y, w, h; - if ((v->banshee.io[io_vidProcCfg] & 0x101) == 0x101) { + if ((v->banshee.io[io_vidProcCfg] & 0x181) == 0x101) { if (v->banshee.overlay_tiled) { vpitch *= 128; } @@ -2069,7 +2077,7 @@ void bx_banshee_c::blt_complete() x <<= 1; w <<= 1; } - if ((v->banshee.io[io_vidProcCfg] & 0x101) == 0x101) { + if ((v->banshee.io[io_vidProcCfg] & 0x181) == 0x101) { v->fbi.video_changed = 1; } else { theVoodooVga->redraw_area(x, y, w, h); diff --git a/bochs/iodev/display/voodoo.cc b/bochs/iodev/display/voodoo.cc index 1308f909a..87b985c4e 100644 --- a/bochs/iodev/display/voodoo.cc +++ b/bochs/iodev/display/voodoo.cc @@ -690,7 +690,13 @@ void bx_voodoo_base_c::vertical_timer(void) if (v->fbi.video_changed || v->fbi.clut_dirty) { // TODO: use tile-based update mechanism - redraw_area(0, 0, s.vdraw.width, s.vdraw.height); + if (v->fbi.clut_dirty || (s.model < VOODOO_BANSHEE)) { + redraw_area(0, 0, s.vdraw.width, s.vdraw.height); + } else { + redraw_area(v->banshee.overlay.x0, v->banshee.overlay.y0, + v->banshee.overlay.x1 - v->banshee.overlay.x0 + 1, + v->banshee.overlay.y1 - v->banshee.overlay.y0 + 1); + } BX_LOCK(fifo_mutex); if (v->fbi.clut_dirty) { update_pens();