Implement Banshee tiled surfaces

This commit is contained in:
SarahW 2020-08-12 15:13:48 +01:00
commit 133f19fe39
9 changed files with 379 additions and 133 deletions

View file

@ -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);*/

View file

@ -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)

View file

@ -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:

View file

@ -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;
}
}
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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;