Ported the latest bunch of Voodoo related commits from PCem.

This commit is contained in:
TC1995
2020-11-26 22:32:43 +01:00
parent 55ed92f801
commit 8671351c84
2 changed files with 85 additions and 13 deletions

View File

@@ -385,6 +385,8 @@ typedef struct voodoo_t
uint32_t dstFormat; uint32_t dstFormat;
uint32_t dstSize; uint32_t dstSize;
uint32_t dstXY; uint32_t dstXY;
uint32_t lineStipple;
uint32_t lineStyle;
uint32_t rop; uint32_t rop;
uint32_t srcBaseAddr; uint32_t srcBaseAddr;
uint32_t srcFormat; uint32_t srcFormat;
@@ -432,6 +434,9 @@ typedef struct voodoo_t
int src_stride_src, src_stride_dest; int src_stride_src, src_stride_dest;
int src_bpp; int src_bpp;
int line_pix_pos, line_bit_pos;
int line_rep_cnt, line_bit_mask_size;
} banshee_blt; } banshee_blt;
struct struct

View File

@@ -43,6 +43,7 @@
#define COMMAND_INITIATE (1 << 8) #define COMMAND_INITIATE (1 << 8)
#define COMMAND_INC_X_START (1 << 10) #define COMMAND_INC_X_START (1 << 10)
#define COMMAND_INC_Y_START (1 << 11) #define COMMAND_INC_Y_START (1 << 11)
#define COMMAND_STIPPLE_LINE (1 << 12)
#define COMMAND_PATTERN_MONO (1 << 13) #define COMMAND_PATTERN_MONO (1 << 13)
#define COMMAND_DX (1 << 14) #define COMMAND_DX (1 << 14)
#define COMMAND_DY (1 << 15) #define COMMAND_DY (1 << 15)
@@ -246,6 +247,50 @@ static void PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t p
} }
} }
static void PLOT_LINE(voodoo_t *voodoo, int x, int y, uint8_t rop, uint32_t pattern, int src_colorkey)
{
switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK)
{
case DST_FORMAT_COL_8_BPP:
{
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];
voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_8);
voodoo->changedvram[addr >> 12] = changeframecount;
break;
}
case DST_FORMAT_COL_16_BPP:
{
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];
*(uint16_t *)&voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_16);
voodoo->changedvram[addr >> 12] = changeframecount;
break;
}
case DST_FORMAT_COL_24_BPP:
{
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 *)&voodoo->vram[addr] = (MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_32) & 0xffffff) | (dest & 0xff000000);
voodoo->changedvram[addr >> 12] = changeframecount;
break;
}
case DST_FORMAT_COL_32_BPP:
{
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 *)&voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_32);
voodoo->changedvram[addr >> 12] = changeframecount;
break;
}
}
}
static void update_src_stride(voodoo_t *voodoo) static void update_src_stride(voodoo_t *voodoo)
{ {
int bpp; int bpp;
@@ -858,14 +903,24 @@ static void banshee_do_host_to_screen_stretch_blt(voodoo_t *voodoo, int count, u
} }
} }
static void step_line(voodoo_t *voodoo)
{
if (voodoo->banshee_blt.line_pix_pos == voodoo->banshee_blt.line_rep_cnt)
{
voodoo->banshee_blt.line_pix_pos = 0;
if (voodoo->banshee_blt.line_bit_pos == voodoo->banshee_blt.line_bit_mask_size)
voodoo->banshee_blt.line_bit_pos = 0;
else
voodoo->banshee_blt.line_bit_pos++;
}
else
voodoo->banshee_blt.line_pix_pos++;
}
static void banshee_do_line(voodoo_t *voodoo) static void banshee_do_line(voodoo_t *voodoo)
{ {
clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0];
uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern;
int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.srcY);
int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.srcX;
int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) ==
(COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO);
uint8_t rop = voodoo->banshee_blt.command >> 24; uint8_t rop = voodoo->banshee_blt.command >> 24;
int dx = ABS(voodoo->banshee_blt.dstX - voodoo->banshee_blt.srcX); int dx = ABS(voodoo->banshee_blt.dstX - voodoo->banshee_blt.srcX);
int dy = ABS(voodoo->banshee_blt.dstY - voodoo->banshee_blt.srcY); int dy = ABS(voodoo->banshee_blt.dstY - voodoo->banshee_blt.srcY);
@@ -874,17 +929,19 @@ static void banshee_do_line(voodoo_t *voodoo)
int x = voodoo->banshee_blt.srcX; int x = voodoo->banshee_blt.srcX;
int y = voodoo->banshee_blt.srcY; int y = voodoo->banshee_blt.srcY;
int error; int error;
uint32_t stipple = (voodoo->banshee_blt.command & COMMAND_STIPPLE_LINE) ?
voodoo->banshee_blt.lineStipple : ~0;
if (dx > dy) /*X major*/ if (dx > dy) /*X major*/
{ {
error = dx/2; error = dx/2;
while (x != voodoo->banshee_blt.dstX) while (x != voodoo->banshee_blt.dstX)
{ {
uint8_t pattern_mask = pattern_mono[pat_y & 7]; int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos);
int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1;
if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans) if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans)
PLOT(voodoo, x, y, pat_x, pat_y, pattern_mask, rop, voodoo->banshee_blt.colorFore, COLORKEY_32); PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, COLORKEY_32);
error -= dy; error -= dy;
if (error < 0) if (error < 0)
@@ -894,7 +951,7 @@ static void banshee_do_line(voodoo_t *voodoo)
pat_y += y_inc; pat_y += y_inc;
} }
x += x_inc; x += x_inc;
pat_x += x_inc; step_line(voodoo);
} }
} }
else /*Y major*/ else /*Y major*/
@@ -902,11 +959,11 @@ static void banshee_do_line(voodoo_t *voodoo)
error = dy/2; error = dy/2;
while (y != voodoo->banshee_blt.dstY) while (y != voodoo->banshee_blt.dstY)
{ {
uint8_t pattern_mask = pattern_mono[pat_y & 7]; int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos);
int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1;
if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans) if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans)
PLOT(voodoo, x, y, pat_x, pat_y, pattern_mask, rop, voodoo->banshee_blt.colorFore, COLORKEY_32); PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, COLORKEY_32);
error -= dx; error -= dx;
if (error < 0) if (error < 0)
@@ -916,7 +973,7 @@ static void banshee_do_line(voodoo_t *voodoo)
pat_x += x_inc; pat_x += x_inc;
} }
y += y_inc; y += y_inc;
pat_y += y_inc; step_line(voodoo);
} }
} }
@@ -1141,6 +1198,16 @@ void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val)
case 0x38: case 0x38:
voodoo->banshee_blt.commandExtra = val; voodoo->banshee_blt.commandExtra = val;
// bansheeblt_log("commandExtra=%08x\n", val); // bansheeblt_log("commandExtra=%08x\n", val);
break;
case 0x3c:
voodoo->banshee_blt.lineStipple = val;
break;
case 0x40:
voodoo->banshee_blt.lineStyle = val;
voodoo->banshee_blt.line_rep_cnt = val & 0xff;
voodoo->banshee_blt.line_bit_mask_size = (val >> 8) & 0x1f;
voodoo->banshee_blt.line_pix_pos = (val >> 16) & 0xff;
voodoo->banshee_blt.line_bit_pos = (val >> 24) & 0x1f;
break; break;
case 0x44: case 0x44:
voodoo->banshee_blt.colorPattern[0] = val; voodoo->banshee_blt.colorPattern[0] = val;