Implemented ViRGE 2D Polygon Fill command.
Improvements to ViRGE line draw.
This commit is contained in:
parent
299f6c8dfb
commit
3e314ccdfb
1 changed files with 118 additions and 13 deletions
|
|
@ -143,6 +143,14 @@ typedef struct virge_t
|
|||
uint32_t pattern_8[8*8];
|
||||
uint32_t pattern_16[8*8];
|
||||
uint32_t pattern_32[8*8];
|
||||
|
||||
uint32_t prdx;
|
||||
uint32_t prxstart;
|
||||
uint32_t pldx;
|
||||
uint32_t plxstart;
|
||||
uint32_t pystart;
|
||||
uint32_t pycnt;
|
||||
uint32_t dest_l, dest_r;
|
||||
} s3d;
|
||||
|
||||
s3d_t s3d_tri;
|
||||
|
|
@ -237,6 +245,7 @@ enum
|
|||
CMD_SET_COMMAND_BITBLT = (0 << 27),
|
||||
CMD_SET_COMMAND_RECTFILL = (2 << 27),
|
||||
CMD_SET_COMMAND_LINE = (3 << 27),
|
||||
CMD_SET_COMMAND_POLY = (5 << 27),
|
||||
CMD_SET_COMMAND_NOP = (15 << 27)
|
||||
};
|
||||
|
||||
|
|
@ -790,10 +799,10 @@ static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p)
|
|||
case 0xa4e4:
|
||||
ret = (virge->s3d.dest_str << 16) | virge->s3d.src_str;
|
||||
break;
|
||||
case 0xa4e8:
|
||||
case 0xa4e8: case 0xace8:
|
||||
ret = virge->s3d.mono_pat_0;
|
||||
break;
|
||||
case 0xa4ec:
|
||||
case 0xa4ec: case 0xacec:
|
||||
ret = virge->s3d.mono_pat_1;
|
||||
break;
|
||||
case 0xa4f0:
|
||||
|
|
@ -1080,16 +1089,16 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
|
|||
virge->s3d.dest_str = (val >> 16) & 0xff8;
|
||||
virge->s3d.src_str = val & 0xff8;
|
||||
break;
|
||||
case 0xa4e8:
|
||||
case 0xa4e8: case 0xace8:
|
||||
virge->s3d.mono_pat_0 = val;
|
||||
break;
|
||||
case 0xa4ec:
|
||||
case 0xa4ec: case 0xacec:
|
||||
virge->s3d.mono_pat_1 = val;
|
||||
break;
|
||||
case 0xa4f0:
|
||||
case 0xa4f0: case 0xacf0:
|
||||
virge->s3d.pat_bg_clr = val;
|
||||
break;
|
||||
case 0xa4f4: case 0xa8f4:
|
||||
case 0xa4f4: case 0xa8f4: case 0xacf4:
|
||||
virge->s3d.pat_fg_clr = val;
|
||||
break;
|
||||
case 0xa4f8:
|
||||
|
|
@ -1136,6 +1145,32 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
|
|||
if (virge->s3d.cmd_set & CMD_SET_AE)
|
||||
s3_virge_bitblt(virge, -1, 0);
|
||||
break;
|
||||
|
||||
case 0xad00:
|
||||
virge->s3d.cmd_set = val;
|
||||
if (!(val & CMD_SET_AE))
|
||||
s3_virge_bitblt(virge, -1, 0);
|
||||
break;
|
||||
case 0xad68:
|
||||
virge->s3d.prdx = val;
|
||||
break;
|
||||
case 0xad6c:
|
||||
virge->s3d.prxstart = val;
|
||||
break;
|
||||
case 0xad70:
|
||||
virge->s3d.pldx = val;
|
||||
break;
|
||||
case 0xad74:
|
||||
virge->s3d.plxstart = val;
|
||||
break;
|
||||
case 0xad78:
|
||||
virge->s3d.pystart = val & 0x7ff;
|
||||
break;
|
||||
case 0xad7c:
|
||||
virge->s3d.pycnt = val & 0x300007ff;
|
||||
if (virge->s3d.cmd_set & CMD_SET_AE)
|
||||
s3_virge_bitblt(virge, -1, 0);
|
||||
break;
|
||||
|
||||
case 0xb4d4:
|
||||
virge->s3d_tri.z_base = val & 0x3ffff8;
|
||||
|
|
@ -1651,17 +1686,30 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
|
|||
virge->s3d.dest_y = virge->s3d.lystart;
|
||||
virge->s3d.h = virge->s3d.lycnt;
|
||||
virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff;
|
||||
if (virge->s3d.ldx >= 0)
|
||||
virge->s3d.dest_x -= virge->s3d.ldx / 2;
|
||||
else
|
||||
virge->s3d.dest_x += virge->s3d.ldx / 2;
|
||||
//virge->s3d.dest_dest_x = virge->s3d.dest_x + virge->s3d.ldx;
|
||||
}
|
||||
while (virge->s3d.h)
|
||||
{
|
||||
int x = virge->s3d.dest_x >> 20;
|
||||
int new_x = (virge->s3d.dest_x + virge->s3d.ldx) >> 20;
|
||||
int x;
|
||||
int new_x;
|
||||
int first_pixel = 1;
|
||||
|
||||
x = virge->s3d.dest_x >> 20;
|
||||
|
||||
if (virge->s3d.h == virge->s3d.lycnt &&
|
||||
((virge->s3d.line_dir && x > virge->s3d.lxend0) ||
|
||||
(!virge->s3d.line_dir && x < virge->s3d.lxend0)))
|
||||
x = virge->s3d.lxend0;
|
||||
|
||||
if (virge->s3d.h == 1)
|
||||
new_x = virge->s3d.lxend1 + (virge->s3d.line_dir ? 1 : -1);
|
||||
else
|
||||
new_x = (virge->s3d.dest_x + virge->s3d.ldx) >> 20;
|
||||
|
||||
|
||||
if ((virge->s3d.line_dir && x > new_x) ||
|
||||
(!virge->s3d.line_dir && x < new_x))
|
||||
goto skip_line;
|
||||
|
||||
do
|
||||
{
|
||||
uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str);
|
||||
|
|
@ -1669,6 +1717,16 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
|
|||
uint32_t out = 0;
|
||||
int update = 1;
|
||||
|
||||
if ((virge->s3d.h == virge->s3d.lycnt || !first_pixel) &&
|
||||
((virge->s3d.line_dir && x < virge->s3d.lxend0) ||
|
||||
(!virge->s3d.line_dir && x > virge->s3d.lxend0)))
|
||||
update = 0;
|
||||
|
||||
if ((virge->s3d.h == 1 || !first_pixel) &&
|
||||
((virge->s3d.line_dir && x > virge->s3d.lxend1) ||
|
||||
(!virge->s3d.line_dir && x < virge->s3d.lxend1)))
|
||||
update = 0;
|
||||
|
||||
CLIP(x, virge->s3d.dest_y);
|
||||
|
||||
if (update)
|
||||
|
|
@ -1685,14 +1743,61 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
|
|||
x++;
|
||||
else if (x > new_x)
|
||||
x--;
|
||||
first_pixel = 0;
|
||||
} while (x != new_x);
|
||||
|
||||
skip_line:
|
||||
virge->s3d.dest_x += virge->s3d.ldx;
|
||||
virge->s3d.dest_y--;
|
||||
virge->s3d.h--;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_SET_COMMAND_POLY:
|
||||
/*No source*/
|
||||
if (virge->s3d.pycnt & (1 << 28))
|
||||
virge->s3d.dest_r = virge->s3d.prxstart;
|
||||
if (virge->s3d.pycnt & (1 << 29))
|
||||
virge->s3d.dest_l = virge->s3d.plxstart;
|
||||
virge->s3d.h = virge->s3d.pycnt & 0x7ff;
|
||||
virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff;
|
||||
//pclog("Start poly - l=%08x r=%08x h=%i rop=%02x\n", virge->s3d.dest_l, virge->s3d.dest_r, virge->s3d.h, virge->s3d.rop);
|
||||
while (virge->s3d.h)
|
||||
{
|
||||
int x = virge->s3d.dest_l >> 20;
|
||||
int xend = virge->s3d.dest_r >> 20;
|
||||
int y = virge->s3d.pystart & 0x7ff;
|
||||
int xdir = (x < xend) ? 1 : -1;
|
||||
//pclog(" %03i: %i - %i %08x-%08x\n", y, x, xend, virge->s3d.dest_l, virge->s3d.dest_r);
|
||||
do
|
||||
{
|
||||
uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (y * virge->s3d.dest_str);
|
||||
uint32_t source = 0, dest, pattern;
|
||||
uint32_t out = 0;
|
||||
int update = 1;
|
||||
|
||||
CLIP(x, y);
|
||||
|
||||
if (update)
|
||||
{
|
||||
READ(dest_addr, dest);
|
||||
pattern = pattern_data[(y & 7)*8 + (x & 7)];
|
||||
MIX();
|
||||
|
||||
WRITE(dest_addr, out);
|
||||
}
|
||||
|
||||
x = (x + xdir) & 0x7ff;
|
||||
}
|
||||
while (x != (xend + xdir));
|
||||
|
||||
virge->s3d.dest_l += virge->s3d.pldx;
|
||||
virge->s3d.dest_r += virge->s3d.prdx;
|
||||
virge->s3d.h--;
|
||||
virge->s3d.pystart = (virge->s3d.pystart - 1) & 0x7ff;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("s3_virge_bitblt : blit command %i %08x\n", (virge->s3d.cmd_set >> 27) & 0xf, virge->s3d.cmd_set);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue