From 133f19fe39d1f98ec261e19f063838ce7ad74713 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 12 Aug 2020 15:13:48 +0100 Subject: [PATCH] Implement Banshee tiled surfaces --- src/vid_voodoo.c | 1 + src/vid_voodoo_banshee.c | 82 +++++++++++++++++++--- src/vid_voodoo_banshee_blitter.c | 116 +++++++++++++++++++------------ src/vid_voodoo_blitter.c | 44 +++++++++--- src/vid_voodoo_codegen_x86-64.h | 96 ++++++++++++++++++------- src/vid_voodoo_codegen_x86.h | 96 ++++++++++++++++++------- src/vid_voodoo_common.h | 8 ++- src/vid_voodoo_reg.c | 25 +++++-- src/vid_voodoo_render.c | 32 ++++++--- 9 files changed, 373 insertions(+), 127 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 79fac67..310014e 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -100,6 +100,7 @@ void voodoo_recalc(voodoo_t *voodoo) if (voodoo->fbiInit1 & (1 << 24)) voodoo->block_width += 32; voodoo->row_width = voodoo->block_width * 32 * 2; + voodoo->aux_row_width = voodoo->row_width; /* pclog("voodoo_recalc : front_offset %08X back_offset %08X aux_offset %08X draw_offset %08x\n", voodoo->params.front_offset, voodoo->back_offset, voodoo->params.aux_offset, voodoo->params.draw_offset); pclog(" fb_read_offset %08X fb_write_offset %08X row_width %i %08x %08x\n", voodoo->fb_read_offset, voodoo->fb_write_offset, voodoo->row_width, voodoo->lfbMode, voodoo->params.fbzMode);*/ diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 26c14c8..8c0e02b 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -66,6 +66,10 @@ typedef struct banshee_t mem_mapping_t reg_mapping_high; /*0c00000-1ffffff - Windows 2000 puts the BIOS ROM in between these two areas*/ voodoo_t *voodoo; + + uint32_t desktop_addr; + int desktop_y; + uint32_t desktop_stride_tiled; } banshee_t; enum @@ -275,6 +279,35 @@ static void banshee_updatemapping(banshee_t *banshee) mem_mapping_set_addr(&banshee->reg_mapping_high, banshee->memBaseAddr0 + 0xc00000, 20 << 20); } +static void banshee_render_16bpp_tiled(svga_t *svga) +{ + banshee_t *banshee = (banshee_t *)svga->p; + int x; + int offset = 32; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + uint32_t addr = banshee->desktop_addr + (banshee->desktop_y & 31) * 128 + ((banshee->desktop_y >> 5) * banshee->desktop_stride_tiled); + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= svga->hdisp; x += 64) + { + int xx; + + for (xx = 0; xx < 64; xx += 2) + { + uint32_t dat = *(uint32_t *)(&svga->vram[(addr + (xx << 1)) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } + + addr += 128*32; + } + + banshee->desktop_y++; +} + static void banshee_recalctimings(svga_t *svga) { banshee_t *banshee = (banshee_t *)svga->p; @@ -312,7 +345,7 @@ static void banshee_recalctimings(svga_t *svga) svga->bpp = 8; break; case PIX_FORMAT_RGB565: - svga->render = svga_render_16bpp_highres; + svga->render = (banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) ? banshee_render_16bpp_tiled : svga_render_16bpp_highres; svga->bpp = 16; break; case PIX_FORMAT_RGB24: @@ -331,6 +364,7 @@ static void banshee_recalctimings(svga_t *svga) else svga->rowoffset = (banshee->vidDesktopOverlayStride & 0x3fff) >> 3; svga->ma_latch = banshee->vidDesktopStartAddr >> 2; + banshee->desktop_stride_tiled = (banshee->vidDesktopOverlayStride & 0x3fff) * 128 * 32; pclog("Extended shift out %i rowoffset=%i %02x\n", VIDPROCCFG_DESKTOP_PIX_FORMAT, svga->rowoffset, svga->crtc[1]); svga->char_width = 8; @@ -350,7 +384,7 @@ static void banshee_recalctimings(svga_t *svga) svga->overlay.ysize = voodoo->overlay.size_y; svga->overlay.pitch = (banshee->vidDesktopOverlayStride & VID_STRIDE_OVERLAY_MASK) >> VID_STRIDE_OVERLAY_SHIFT; if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) - svga->overlay.pitch *= 128; + svga->overlay.pitch *= 128*32; if (svga->overlay.xsize <= 0 || svga->overlay.ysize <= 0) svga->overlay.ena = 0; if (svga->overlay.ena) @@ -440,6 +474,7 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p) voodoo->tile_stride = 1024 << ((val >> 13) & 7); voodoo->tile_stride_shift = 10 + ((val >> 13) & 7); voodoo->tile_x = ((val >> 16) & 0x7f) * 128; + voodoo->tile_x_real = ((val >> 16) & 0x7f) * 128*32; break; case Init_miscInit0: @@ -1180,7 +1215,7 @@ static uint8_t banshee_read_linear(uint32_t addr, void *p) x = addr & (voodoo->tile_stride-1); y = addr >> voodoo->tile_stride_shift; - addr = voodoo->tile_base + x + y*voodoo->tile_x; + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*voodoo->tile_x_real; // pclog(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); } if (addr >= svga->vram_max) @@ -1213,7 +1248,7 @@ static uint16_t banshee_read_linear_w(uint32_t addr, void *p) x = addr & (voodoo->tile_stride-1); y = addr >> voodoo->tile_stride_shift; - addr = voodoo->tile_base + x + y*voodoo->tile_x; + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*voodoo->tile_x_real; // pclog(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); } if (addr >= svga->vram_max) @@ -1246,7 +1281,7 @@ static uint32_t banshee_read_linear_l(uint32_t addr, void *p) x = addr & (voodoo->tile_stride-1); y = addr >> voodoo->tile_stride_shift; - addr = voodoo->tile_base + x + y*voodoo->tile_x; + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*voodoo->tile_x_real; // pclog(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); } if (addr >= svga->vram_max) @@ -1280,7 +1315,7 @@ static void banshee_write_linear(uint32_t addr, uint8_t val, void *p) x = addr & (voodoo->tile_stride-1); y = addr >> voodoo->tile_stride_shift; - addr = voodoo->tile_base + x + y*voodoo->tile_x; + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*voodoo->tile_x_real; // pclog(" Tile b %08x->%08x %i %i\n", old_addr, addr, x, y); } if (addr >= svga->vram_max) @@ -1314,7 +1349,7 @@ static void banshee_write_linear_w(uint32_t addr, uint16_t val, void *p) x = addr & (voodoo->tile_stride-1); y = addr >> voodoo->tile_stride_shift; - addr = voodoo->tile_base + x + y*voodoo->tile_x; + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*voodoo->tile_x_real; // pclog(" Tile b %08x->%08x %i %i\n", old_addr, addr, x, y); } if (addr >= svga->vram_max) @@ -1355,9 +1390,9 @@ static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p) x = addr & (voodoo->tile_stride-1); y = addr >> voodoo->tile_stride_shift; - addr = voodoo->tile_base + x + y*voodoo->tile_x; + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*voodoo->tile_x_real; addr2 = x + y*voodoo->tile_x; -// pclog(" Tile %08x->%08x->%08x->%08x %i %i stride=%i tile_x=%i\n", old_addr, addr_off, addr2, addr, x, y, voodoo->tile_stride, voodoo->tile_x); +// pclog(" Tile %08x->%08x->%08x->%08x %i %i tile_x=%i\n", old_addr, addr_off, addr2, addr, x, y, voodoo->tile_x_real); } if (addr >= svga->vram_max) @@ -1443,6 +1478,23 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) } \ } while (0) +#define DECODE_RGB565_TILED() \ + do \ + { \ + int c; \ + int wp = 0; \ + \ + for (c = 0; c < voodoo->overlay.overlay_bytes; c += 2) \ + { \ + uint16_t data = *(uint16_t *)&src[(c & 127) + (c >> 7)*128*32]; \ + int r = data & 0x1f; \ + int g = (data >> 5) & 0x3f; \ + int b = data >> 11; \ + \ + banshee->overlay_buffer[wp++] = (r << 3) | (g << 10) | (b << 19); \ + } \ + } while (0) + #define DECODE_YUYV422() \ do \ { \ @@ -1543,7 +1595,10 @@ void banshee_hwcursor_draw(svga_t *svga, int displine) break; \ \ case OVERLAY_FMT_565_DITHER: \ - DECODE_RGB565(); \ + if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) \ + DECODE_RGB565_TILED(); \ + else \ + DECODE_RGB565(); \ break; \ \ default: \ @@ -1557,7 +1612,10 @@ static void banshee_overlay_draw(svga_t *svga, int displine) voodoo_t *voodoo = banshee->voodoo; uint32_t *p; int x; - uint32_t src_addr = svga->overlay_latch.addr + svga->overlay_latch.pitch * (voodoo->overlay.src_y >> 20); + int y = voodoo->overlay.src_y >> 20; + uint32_t src_addr = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? + ((y & 31) * 128 + (y >> 5) * svga->overlay_latch.pitch) : + y * svga->overlay_latch.pitch); uint8_t *src = &svga->vram[src_addr & svga->vram_mask]; uint32_t src_x = 0; @@ -1616,6 +1674,8 @@ static void banshee_vsync_callback(svga_t *svga) } voodoo->overlay.src_y = 0; + banshee->desktop_addr = banshee->vidDesktopStartAddr; + banshee->desktop_y = 0; } static uint8_t banshee_pci_read(int func, int addr, void *p) diff --git a/src/vid_voodoo_banshee_blitter.c b/src/vid_voodoo_banshee_blitter.c index 032215b..6a3204d 100644 --- a/src/vid_voodoo_banshee_blitter.c +++ b/src/vid_voodoo_banshee_blitter.c @@ -151,13 +151,24 @@ static uint32_t MIX(voodoo_t *voodoo, uint32_t dest, uint32_t src, uint32_t patt return result; } +static uint32_t get_addr(voodoo_t *voodoo, int x, int y, int src_notdst, uint32_t src_stride) +{ + uint32_t stride = src_notdst ? src_stride : voodoo->banshee_blt.dst_stride; + uint32_t base_addr = src_notdst ? voodoo->banshee_blt.srcBaseAddr : voodoo->banshee_blt.dstBaseAddr; + + if (src_notdst ? voodoo->banshee_blt.srcBaseAddr_tiled : voodoo->banshee_blt.dstBaseAddr_tiled) + return (base_addr + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*stride) & voodoo->fb_mask; + else + return (base_addr + x + y*stride) & voodoo->fb_mask; +} + static void PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask, uint8_t rop, uint32_t src, int src_colorkey) { switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) { case DST_FORMAT_COL_8_BPP: { - uint32_t addr = (voodoo->banshee_blt.dstBaseAddr + x + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t addr = get_addr(voodoo, x, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t dest = voodoo->vram[addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : @@ -169,7 +180,7 @@ static void PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t p } case DST_FORMAT_COL_16_BPP: { - uint32_t addr = (voodoo->banshee_blt.dstBaseAddr + x*2 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t addr = get_addr(voodoo, x*2, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*2 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t dest = *(uint16_t *)&voodoo->vram[addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : @@ -181,7 +192,7 @@ static void PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t p } case DST_FORMAT_COL_24_BPP: { - uint32_t addr = (voodoo->banshee_blt.dstBaseAddr + x*3 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t addr = get_addr(voodoo, x*3, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*3 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : @@ -193,7 +204,7 @@ static void PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t p } case DST_FORMAT_COL_32_BPP: { - uint32_t addr = (voodoo->banshee_blt.dstBaseAddr + x*4 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t addr = get_addr(voodoo, x*4, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*4 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : @@ -309,7 +320,7 @@ static void banshee_do_rectfill(voodoo_t *voodoo) } -static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int src_x) +static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int src_x, int src_tiled) { clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; int dst_y = voodoo->banshee_blt.dstY; @@ -346,6 +357,10 @@ static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) { int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; + int src_x_real = (src_x * voodoo->banshee_blt.src_bpp) >> 3; + + if (src_tiled) + src_x_real = (src_x_real & 127) + ((src_x_real >> 7) * 128*32); if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) { @@ -353,8 +368,8 @@ static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x { case DST_FORMAT_COL_8_BPP: { - uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = src_p[src_x]; + uint32_t dst_addr = get_addr(voodoo, dst_x, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = src_p[src_x_real]; uint32_t dest = voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : @@ -366,8 +381,8 @@ static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x } case DST_FORMAT_COL_16_BPP: { - uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint16_t *)&src_p[src_x*2]; + uint32_t dst_addr = get_addr(voodoo, dst_x*2, dst_y, 0, 0);//dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint16_t *)&src_p[src_x_real]; uint32_t dest = *(uint16_t *)&voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : @@ -379,8 +394,8 @@ static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x } case DST_FORMAT_COL_24_BPP: { - uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint32_t *)&src_p[src_x*3]; + uint32_t dst_addr = get_addr(voodoo, dst_x*3, dst_y, 0, 0);//dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint32_t *)&src_p[src_x_real]; uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : @@ -392,8 +407,8 @@ static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x } case DST_FORMAT_COL_32_BPP: { - uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint32_t *)&src_p[src_x*4]; + uint32_t dst_addr = get_addr(voodoo, dst_x*4, dst_y, 0, 0);//dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint32_t *)&src_p[src_x_real]; uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : @@ -435,6 +450,10 @@ static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) { int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; + int src_x_real = (src_x * voodoo->banshee_blt.src_bpp) >> 3; + + if (src_tiled) + src_x_real = (src_x_real & 127) + ((src_x_real >> 7) * 128*32); if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) { @@ -445,7 +464,7 @@ static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x { case SRC_FORMAT_COL_1_BPP: { - uint8_t src_byte = src_p[src_x >> 3]; + uint8_t src_byte = src_p[src_x_real]; src_data = (src_byte & (0x80 >> (src_x & 7))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack; if (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) transparent = !(src_byte & (0x80 >> (src_x & 7))); @@ -454,12 +473,12 @@ static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x } case SRC_FORMAT_COL_8_BPP: { - src_data = src_p[src_x]; + src_data = src_p[src_x_real]; break; } case SRC_FORMAT_COL_16_BPP: { - uint16_t src_16 = *(uint16_t *)&src_p[src_x*2]; + uint16_t src_16 = *(uint16_t *)&src_p[src_x_real]; int r = (src_16 >> 11); int g = (src_16 >> 5) & 0x3f; int b = src_16 & 0x1f; @@ -472,12 +491,12 @@ static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x } case SRC_FORMAT_COL_24_BPP: { - src_data = *(uint32_t *)&src_p[src_x*3]; + src_data = *(uint32_t *)&src_p[src_x_real]; break; } case SRC_FORMAT_COL_32_BPP: { - src_data = *(uint32_t *)&src_p[src_x*4]; + src_data = *(uint32_t *)&src_p[src_x_real]; break; } @@ -523,10 +542,10 @@ static void banshee_do_screen_to_screen_blt(voodoo_t *voodoo) // return; for (voodoo->banshee_blt.cur_y = 0; voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY; voodoo->banshee_blt.cur_y++) { - uint32_t src_addr = (voodoo->banshee_blt.srcBaseAddr + voodoo->banshee_blt.srcY*/*voodoo->banshee_blt.src_stride*/voodoo->banshee_blt.src_stride_dest) & voodoo->fb_mask; + uint32_t src_addr = get_addr(voodoo, 0, voodoo->banshee_blt.srcY, 1, voodoo->banshee_blt.src_stride_dest); // if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) // pclog(" srcY=%i src_addr=%08x\n", voodoo->banshee_blt.srcY, src_addr); - do_screen_to_screen_line(voodoo, &voodoo->vram[src_addr], 1, voodoo->banshee_blt.srcX); + do_screen_to_screen_line(voodoo, &voodoo->vram[src_addr], 1, voodoo->banshee_blt.srcX, voodoo->banshee_blt.srcBaseAddr_tiled); } } @@ -552,9 +571,9 @@ static void banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) { if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) - do_screen_to_screen_line(voodoo, &voodoo->banshee_blt.host_data[(voodoo->banshee_blt.srcX >> 3) & 3], 0, voodoo->banshee_blt.srcX & 7); + do_screen_to_screen_line(voodoo, &voodoo->banshee_blt.host_data[(voodoo->banshee_blt.srcX >> 3) & 3], 0, voodoo->banshee_blt.srcX & 7, 0); else - do_screen_to_screen_line(voodoo, &voodoo->banshee_blt.host_data[voodoo->banshee_blt.srcX & 3], 0, 0); + do_screen_to_screen_line(voodoo, &voodoo->banshee_blt.host_data[voodoo->banshee_blt.srcX & 3], 0, 0, 0); voodoo->banshee_blt.cur_y++; } @@ -563,20 +582,7 @@ static void banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t else voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK); -// pclog(" %i %i %i %i %i\n", (voodoo->banshee_blt.srcX & 3), (last_byte & 3), (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK)); -#if 0 - if ((voodoo->banshee_blt.srcX & 3) >= last_byte)// & 3) && (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) < 4) - { - *(uint32_t *)voodoo->banshee_blt.host_data = *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count-4]; - voodoo->banshee_blt.host_data_count = 4; - } - else - { -#endif voodoo->banshee_blt.host_data_count = 0; -// } -// last_byte = (voodoo->banshee_blt.srcX & 3) + voodoo->banshee_blt.host_data_size_dest; -// pclog(" host_data_count=%i last_byte=%i srcX=%i\n", voodoo->banshee_blt.host_data_count, last_byte, voodoo->banshee_blt.srcX); } } else @@ -590,7 +596,7 @@ static void banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t // pclog(" %i %i\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY); if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) { - do_screen_to_screen_line(voodoo, voodoo->banshee_blt.host_data, 0, 0); + do_screen_to_screen_line(voodoo, voodoo->banshee_blt.host_data, 0, 0, 0); voodoo->banshee_blt.cur_y++; } @@ -638,7 +644,7 @@ static void do_screen_to_screen_stretch_line(voodoo_t *voodoo,uint8_t *src_p, in { case DST_FORMAT_COL_8_BPP: { - uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dst_addr = get_addr(voodoo, dst_x, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t src = src_p[src_x]; uint32_t dest = voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? @@ -652,7 +658,7 @@ static void do_screen_to_screen_stretch_line(voodoo_t *voodoo,uint8_t *src_p, in } case DST_FORMAT_COL_16_BPP: { - uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dst_addr = get_addr(voodoo, dst_x*2, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t src = *(uint16_t *)&src_p[src_x*2]; uint32_t dest = *(uint16_t *)&voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? @@ -666,7 +672,7 @@ static void do_screen_to_screen_stretch_line(voodoo_t *voodoo,uint8_t *src_p, in } case DST_FORMAT_COL_24_BPP: { - uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dst_addr = get_addr(voodoo, dst_x*3, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t src = *(uint32_t *)&src_p[src_x*3]; uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? @@ -680,7 +686,7 @@ static void do_screen_to_screen_stretch_line(voodoo_t *voodoo,uint8_t *src_p, in } case DST_FORMAT_COL_32_BPP: { - uint32_t dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dst_addr = get_addr(voodoo, dst_x*4, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; uint32_t src = *(uint32_t *)&src_p[src_x*4]; uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? @@ -723,8 +729,8 @@ static void banshee_do_screen_to_screen_stretch_blt(voodoo_t *voodoo) // return; for (voodoo->banshee_blt.cur_y = 0; voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY; voodoo->banshee_blt.cur_y++) { - uint32_t src_addr = (voodoo->banshee_blt.srcBaseAddr + voodoo->banshee_blt.srcY*voodoo->banshee_blt.src_stride_src) & voodoo->fb_mask; - pclog("scale_blit %i %08x %08x\n", voodoo->banshee_blt.cur_y, src_addr, voodoo->banshee_blt.command); + uint32_t src_addr = get_addr(voodoo, 0, voodoo->banshee_blt.srcY, 1, voodoo->banshee_blt.src_stride_src);//(voodoo->banshee_blt.srcBaseAddr + voodoo->banshee_blt.srcY*voodoo->banshee_blt.src_stride_src) & voodoo->fb_mask; +// pclog("scale_blit %i %08x %08x\n", voodoo->banshee_blt.cur_y, src_addr, voodoo->banshee_blt.command); // if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) // pclog(" srcY=%i src_addr=%08x\n", voodoo->banshee_blt.srcY, src_addr); do_screen_to_screen_stretch_line(voodoo, &voodoo->vram[src_addr], voodoo->banshee_blt.srcX, &voodoo->banshee_blt.srcY); @@ -1018,7 +1024,7 @@ void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) voodoo->banshee_blt.dstBaseAddr = val & 0xffffff; voodoo->banshee_blt.dstBaseAddr_tiled = val & 0x80000000; if (voodoo->banshee_blt.dstBaseAddr_tiled) - voodoo->banshee_blt.dst_stride = (voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK) * 128; + voodoo->banshee_blt.dst_stride = (voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK) * 128*32; else voodoo->banshee_blt.dst_stride = voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK; // pclog("dstBaseAddr=%08x\n", val); @@ -1026,7 +1032,7 @@ void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) case 0x14: voodoo->banshee_blt.dstFormat = val; if (voodoo->banshee_blt.dstBaseAddr_tiled) - voodoo->banshee_blt.dst_stride = (voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK) * 128; + voodoo->banshee_blt.dst_stride = (voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK) * 128*32; else voodoo->banshee_blt.dst_stride = voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK; // pclog("dstFormat=%08x\n", val); @@ -1065,7 +1071,7 @@ void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) voodoo->banshee_blt.srcBaseAddr = val & 0xffffff; voodoo->banshee_blt.srcBaseAddr_tiled = val & 0x80000000; if (voodoo->banshee_blt.srcBaseAddr_tiled) - voodoo->banshee_blt.src_stride = (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) * 128; + voodoo->banshee_blt.src_stride = (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) * 128*32; else voodoo->banshee_blt.src_stride = voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; update_src_stride(voodoo); @@ -1112,10 +1118,28 @@ void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) case 0x54: voodoo->banshee_blt.srcFormat = val; if (voodoo->banshee_blt.srcBaseAddr_tiled) - voodoo->banshee_blt.src_stride = (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) * 128; + voodoo->banshee_blt.src_stride = (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) * 128*32; else voodoo->banshee_blt.src_stride = voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; update_src_stride(voodoo); + switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) + { + case SRC_FORMAT_COL_1_BPP: + voodoo->banshee_blt.src_bpp = 1; + break; + case SRC_FORMAT_COL_8_BPP: + voodoo->banshee_blt.src_bpp = 8; + break; + case SRC_FORMAT_COL_24_BPP: + voodoo->banshee_blt.src_bpp = 24; + break; + case SRC_FORMAT_COL_32_BPP: + voodoo->banshee_blt.src_bpp = 32; + break; + case SRC_FORMAT_COL_16_BPP: default: + voodoo->banshee_blt.src_bpp = 16; + break; + } // pclog("srcFormat=%08x\n", val); break; case 0x58: diff --git a/src/vid_voodoo_blitter.c b/src/vid_voodoo_blitter.c index f9b7538..01048f9 100644 --- a/src/vid_voodoo_blitter.c +++ b/src/vid_voodoo_blitter.c @@ -443,11 +443,25 @@ void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params) { for (y = low_y; y < high_y; y++) { - uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + y*voodoo->row_width) & voodoo->fb_mask]; - int x; + if (voodoo->col_tiled) + { + uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + (y >> 5) * voodoo->row_width + (y & 31) * 128) & voodoo->fb_mask]; + int x; - for (x = params->clipLeft; x < params->clipRight; x++) - cbuf[x] = col; + for (x = params->clipLeft; x < params->clipRight; x++) + { + int x2 = (x & 63) | ((x >> 6) * 128*32/2); + cbuf[x2] = col; + } + } + else + { + uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + y * voodoo->row_width) & voodoo->fb_mask]; + int x; + + for (x = params->clipLeft; x < params->clipRight; x++) + cbuf[x] = col; + } } } } @@ -468,11 +482,25 @@ void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params) { for (y = low_y; y < high_y; y++) { - uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + y*voodoo->row_width) & voodoo->fb_mask]; - int x; + if (voodoo->aux_tiled) + { + uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (y >> 5) * voodoo->aux_row_width + (y & 31) * 128) & voodoo->fb_mask]; + int x; - for (x = params->clipLeft; x < params->clipRight; x++) - abuf[x] = params->zaColor & 0xffff; + for (x = params->clipLeft; x < params->clipRight; x++) + { + int x2 = (x & 63) | ((x >> 6) * 128*32/2); + abuf[x2] = params->zaColor & 0xffff; + } + } + else + { + uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + y * voodoo->aux_row_width) & voodoo->fb_mask]; + int x; + + for (x = params->clipLeft; x < params->clipRight; x++) + abuf[x] = params->zaColor & 0xffff; + } } } } diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/vid_voodoo_codegen_x86-64.h index 4b5335b..716e684 100644 --- a/src/vid_voodoo_codegen_x86-64.h +++ b/src/vid_voodoo_codegen_x86-64.h @@ -41,28 +41,36 @@ typedef struct voodoo_x86_data_t static int last_block[2] = {0, 0}; static int next_block_to_write[2] = {0, 0}; -#define addbyte(val) \ - code_block[block_pos++] = val; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") +#define addbyte(val) \ + do { \ + code_block[block_pos++] = val; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ + } while (0) -#define addword(val) \ - *(uint16_t *)&code_block[block_pos] = val; \ - block_pos += 2; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") +#define addword(val) \ + do { \ + *(uint16_t *)&code_block[block_pos] = val; \ + block_pos += 2; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ + } while (0) -#define addlong(val) \ - *(uint32_t *)&code_block[block_pos] = val; \ - block_pos += 4; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") +#define addlong(val) \ + do { \ + *(uint32_t *)&code_block[block_pos] = val; \ + block_pos += 4; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ + } while (0) -#define addquad(val) \ - *(uint64_t *)&code_block[block_pos] = val; \ - block_pos += 8; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") +#define addquad(val) \ + do { \ + *(uint64_t *)&code_block[block_pos] = val; \ + block_pos += 8; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ + } while (0) static __m128i xmm_01_w;// = 0x0001000100010001ull; @@ -782,6 +790,28 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x4c); /*MOV RSI, R15*/ addbyte(0x89); addbyte(0xfe); + if (voodoo->col_tiled || voodoo->aux_tiled) + { + addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ + addbyte(0x87); + addlong(offsetof(voodoo_state_t, x)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + addbyte(0x83); /*AND EAX, 63*/ + addbyte(0xe0); + addbyte(63); + addbyte(0xc1); /*SHR EBX, 6*/ + addbyte(0xeb); + addbyte(6); + addbyte(0xc1); /*SHL EBX, 11 - tile is 128*32, << 12, div 2 because word index*/ + addbyte(0xe3); + addbyte(11); + addbyte(0x01); /*ADD EAX, EBX*/ + addbyte(0xd8); + addbyte(0x89); /*MOV state->x_tiled[EDI], EAX*/ + addbyte(0x87); + addlong(offsetof(voodoo_state_t, x_tiled)); + } addbyte(0x66); /*PXOR XMM2, XMM2*/ addbyte(0x0f); addbyte(0xef); @@ -899,7 +929,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo { addbyte(0x8b); /*MOV EBX, state->x[EDI]*/ addbyte(0x9f); - addlong(offsetof(voodoo_state_t, x)); + if (voodoo->aux_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); addbyte(0x48); /*MOV RCX, aux_mem[RDI]*/ addbyte(0x8b); addbyte(0x8f); @@ -2483,7 +2516,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addquad((uintptr_t)rgb565); addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ addbyte(0x87); - addlong(offsetof(voodoo_state_t, x)); + if (voodoo->col_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); addbyte(0x48); /*MOV RBP, fb_mem*/ addbyte(0x8b); addbyte(0xaf); @@ -2865,8 +2901,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); - addlong(offsetof(voodoo_state_t, x)); - + if (voodoo->col_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); + addbyte(0x66); /*MOV EAX, XMM0*/ addbyte(0x0f); addbyte(0x7e); @@ -2932,7 +2971,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo } addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); - addlong(offsetof(voodoo_state_t, x)); + if (voodoo->col_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); addbyte(0x4c); /*ADD RSI, R8*/ addbyte(0x01); addbyte(0xc6); @@ -3018,6 +3060,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) { + addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ + addbyte(0x97); + if (voodoo->aux_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); addbyte(0x66); /*MOV AX, new_depth*/ addbyte(0x8b); addbyte(0x87); diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index 193e1b9..3fe0335 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -39,28 +39,36 @@ typedef struct voodoo_x86_data_t static int last_block[2] = {0, 0}; static int next_block_to_write[2] = {0, 0}; -#define addbyte(val) \ - code_block[block_pos++] = val; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") +#define addbyte(val) \ + do { \ + code_block[block_pos++] = val; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ + } while (0) -#define addword(val) \ - *(uint16_t *)&code_block[block_pos] = val; \ - block_pos += 2; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") +#define addword(val) \ + do { \ + *(uint16_t *)&code_block[block_pos] = val; \ + block_pos += 2; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ + } while (0) -#define addlong(val) \ - *(uint32_t *)&code_block[block_pos] = val; \ - block_pos += 4; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") +#define addlong(val) \ + do { \ + *(uint32_t *)&code_block[block_pos] = val; \ + block_pos += 4; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ + } while (0) -#define addquad(val) \ - *(uint64_t *)&code_block[block_pos] = val; \ - block_pos += 8; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n") +#define addquad(val) \ + do { \ + *(uint64_t *)&code_block[block_pos] = val; \ + block_pos += 8; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ + } while (0) static __m128i xmm_01_w;// = 0x0001000100010001ull; @@ -694,6 +702,28 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x74); addbyte(0x24); addbyte(8+16); + if (voodoo->col_tiled || voodoo->aux_tiled) + { + addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ + addbyte(0x87); + addlong(offsetof(voodoo_state_t, x)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + addbyte(0x83); /*AND EAX, 63*/ + addbyte(0xe0); + addbyte(63); + addbyte(0xc1); /*SHR EBX, 6*/ + addbyte(0xeb); + addbyte(6); + addbyte(0xc1); /*SHL EBX, 11 - tile is 128*32, << 12, div 2 because word index*/ + addbyte(0xe3); + addbyte(11); + addbyte(0x01); /*ADD EAX, EBX*/ + addbyte(0xd8); + addbyte(0x89); /*MOV state->x_tiled[EDI], EAX*/ + addbyte(0x87); + addlong(offsetof(voodoo_state_t, x_tiled)); + } addbyte(0x66); /*PXOR XMM2, XMM2*/ addbyte(0x0f); addbyte(0xef); @@ -826,7 +856,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo { addbyte(0x8b); /*MOV EBX, state->x[EDI]*/ addbyte(0x9f); - addlong(offsetof(voodoo_state_t, x)); + if (voodoo->aux_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); addbyte(0x8b);/*MOV ECX, aux_mem[EDI]*/ addbyte(0x8f); addlong(offsetof(voodoo_state_t, aux_mem)); @@ -2439,7 +2472,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo { addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ addbyte(0x87); - addlong(offsetof(voodoo_state_t, x)); + if (voodoo->col_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); addbyte(0x8b); /*MOV EBP, fb_mem*/ addbyte(0xaf); addlong(offsetof(voodoo_state_t, fb_mem)); @@ -2818,8 +2854,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); - addlong(offsetof(voodoo_state_t, x)); - + if (voodoo->col_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); + addbyte(0x66); /*MOV EAX, XMM0*/ addbyte(0x0f); addbyte(0x7e); @@ -2887,7 +2926,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo } addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); - addlong(offsetof(voodoo_state_t, x)); + if (voodoo->col_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); if (dither2x2) { addbyte(0xc1); /*SHL ECX, 2*/ @@ -2971,6 +3013,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) { + addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ + addbyte(0x97); + if (voodoo->aux_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); addbyte(0x66); /*MOV AX, new_depth*/ addbyte(0x8b); addbyte(0x87); diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h index 4d3a809..1c296c2 100644 --- a/src/vid_voodoo_common.h +++ b/src/vid_voodoo_common.h @@ -217,8 +217,10 @@ typedef struct voodoo_t uint32_t fb_read_offset, fb_write_offset; - int row_width; + int row_width, aux_row_width; int block_width; + + int col_tiled, aux_tiled; uint8_t *fb_mem, *tex_mem[2]; uint16_t *tex_mem_w[2]; @@ -409,6 +411,8 @@ typedef struct voodoo_t int host_data_count; int host_data_size_src, host_data_size_dest; int src_stride_src, src_stride_dest; + + int src_bpp; } banshee_blt; struct @@ -439,7 +443,7 @@ typedef struct voodoo_t int buffer_cutoff; uint32_t tile_base, tile_stride; - int tile_stride_shift, tile_x; + int tile_stride_shift, tile_x, tile_x_real; int read_time, write_time, burst_time; diff --git a/src/vid_voodoo_reg.c b/src/vid_voodoo_reg.c index fc0626c..97b1c2e 100644 --- a/src/vid_voodoo_reg.c +++ b/src/vid_voodoo_reg.c @@ -562,15 +562,16 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) case SST_colBufferStride: if (voodoo->type == VOODOO_BANSHEE) { - if (val & (1 << 15)) + voodoo->col_tiled = val & (1 << 15); + if (voodoo->col_tiled) { - voodoo->row_width = (val & 0x7f) * 128; -// pclog("colBufferStride = %i bytes, tiled\n", voodoo->row_width); + voodoo->row_width = (val & 0x7f) * 128*32; +// pclog("colBufferStride tiled = %i bytes, tiled %08x\n", voodoo->row_width, val); } else { voodoo->row_width = val & 0x3fff; -// pclog("colBufferStride = %i bytes, linear\n", voodoo->row_width); +// pclog("colBufferStride linear = %i bytes, linear\n", voodoo->row_width); } } break; @@ -581,6 +582,22 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) // pclog("auxBufferAddr=%06x\n", voodoo->params.aux_offset); } break; + case SST_auxBufferStride: + if (voodoo->type == VOODOO_BANSHEE) + { + voodoo->aux_tiled = val & (1 << 15); + if (voodoo->aux_tiled) + { + voodoo->aux_row_width = (val & 0x7f) * 128*32; +// pclog("auxBufferStride tiled = %i bytes, tiled\n", voodoo->aux_row_width); + } + else + { + voodoo->aux_row_width = val & 0x3fff; +// pclog("auxBufferStride linear = %i bytes, linear\n", voodoo->aux_row_width); + } + } + break; case SST_clutData: voodoo->clutData[(val >> 24) & 0x3f].b = val & 0xff; diff --git a/src/vid_voodoo_render.c b/src/vid_voodoo_render.c index b348ad5..8de9489 100644 --- a/src/vid_voodoo_render.c +++ b/src/vid_voodoo_render.c @@ -56,7 +56,7 @@ typedef struct voodoo_state_t int64_t w; int pixel_count, texel_count; - int x, x2; + int x, x2, x_tiled; uint32_t w_depth; @@ -920,8 +920,14 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood } else { - state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y * voodoo->row_width)]; - state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y * voodoo->row_width)) & voodoo->fb_mask]; + if (voodoo->col_tiled) + state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y >> 5) * voodoo->row_width + (real_y & 31) * 128]; + else + state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y * voodoo->row_width)]; + if (voodoo->aux_tiled) + state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y >> 5) * voodoo->aux_row_width + (real_y & 31) * 128) & voodoo->fb_mask]; + else + state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y * voodoo->row_width)) & voodoo->fb_mask]; } if (voodoo_output) @@ -940,6 +946,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood #endif do { + int x_tiled = (x & 63) | ((x >> 6) * 128*32/2); start_x = x; state->x = x; voodoo->pixel_count[odd_even]++; @@ -985,12 +992,12 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood if (params->fbzMode & FBZ_DEPTH_ENABLE) { - uint16_t old_depth = aux_mem[x]; + uint16_t old_depth = voodoo->aux_tiled ? aux_mem[x_tiled] : aux_mem[x]; DEPTH_TEST((params->fbzMode & FBZ_DEPTH_SOURCE) ? (params->zaColor & 0xffff) : new_depth); } - dat = fb_mem[x]; + dat = voodoo->col_tiled ? fb_mem[x_tiled] : fb_mem[x]; dest_r = (dat >> 8) & 0xf8; dest_g = (dat >> 3) & 0xfc; dest_b = (dat << 3) & 0xf8; @@ -1303,10 +1310,19 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood } if (params->fbzMode & FBZ_RGB_WMASK) - fb_mem[x] = src_b | (src_g << 5) | (src_r << 11); - + { + if (voodoo->col_tiled) + fb_mem[x_tiled] = src_b | (src_g << 5) | (src_r << 11); + else + fb_mem[x] = src_b | (src_g << 5) | (src_r << 11); + } if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) - aux_mem[x] = new_depth; + { + if (voodoo->aux_tiled) + aux_mem[x_tiled] = new_depth; + else + aux_mem[x] = new_depth; + } } } voodoo_output &= ~2;