summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/video/voodoo.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/video/voodoo.c')
-rw-r--r--src/emu/video/voodoo.c197
1 files changed, 137 insertions, 60 deletions
diff --git a/src/emu/video/voodoo.c b/src/emu/video/voodoo.c
index 1942aaa392f..774387c3921 100644
--- a/src/emu/video/voodoo.c
+++ b/src/emu/video/voodoo.c
@@ -174,7 +174,9 @@ bits(7:4) and bit(24)), X, and Y:
#define MODIFY_PIXEL(VV)
-
+// Need to turn off cycle eating when debugging MIPS drc
+// otherwise timer interrupts won't match nodrc debug mode.
+#define EAT_CYCLES (1)
/*************************************
@@ -211,7 +213,8 @@ static TIMER_CALLBACK( stall_cpu_callback );
static void stall_cpu(voodoo_state *v, int state, attotime current_time);
static TIMER_CALLBACK( vblank_callback );
static INT32 register_w(voodoo_state *v, offs_t offset, UINT32 data);
-static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask, bool lfb_3d);
+static INT32 lfb_direct_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask);
+static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask);
static INT32 texture_w(voodoo_state *v, offs_t offset, UINT32 data);
static INT32 banshee_2d_w(voodoo_state *v, offs_t offset, UINT32 data);
@@ -892,7 +895,7 @@ static void swap_buffers(voodoo_state *v)
/* periodically log rasterizer info */
v->stats.swaps++;
- if (LOG_RASTERIZERS && v->stats.swaps % 100 == 0)
+ if (LOG_RASTERIZERS && v->stats.swaps % 1000 == 0)
dump_rasterizer_stats(v);
/* update the statistics (debug) */
@@ -1457,8 +1460,14 @@ INLINE INT32 prepare_tmu(tmu_state *t)
/* adjust the result: negative to get the log of the original value */
/* plus 12 to account for the extra exponent, and divided by 2 to */
/* get the log of the square root of texdx */
- (void)fast_reciplog(texdx, &lodbase);
- return (-lodbase + (12 << 8)) / 2;
+ #if USE_FAST_RECIP == 1
+ (void)fast_reciplog(texdx, &lodbase);
+ return (-lodbase + (12 << 8)) / 2;
+ #else
+ double tmpTex = texdx;
+ lodbase = new_log2(tmpTex);
+ return (lodbase + (12 << 8)) / 2;
+ #endif
}
@@ -1943,7 +1952,7 @@ static UINT32 cmdfifo_execute(voodoo_state *v, cmdfifo_info *f)
/* loop over words */
for (i = 0; i < count; i++)
- cycles += lfb_w(v, target++, *src++, 0xffffffff, true);
+ cycles += lfb_w(v, target++, *src++, 0xffffffff);
break;
}
@@ -2931,8 +2940,52 @@ default_case:
* Voodoo LFB writes
*
*************************************/
+static INT32 lfb_direct_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask)
+{
+ UINT16 *dest;
+ UINT32 destmax;
+ int x, y;
+ UINT32 bufoffs;
+
+ /* statistics */
+ v->stats.lfb_writes++;
+
+ /* byte swizzling */
+ if (LFBMODE_BYTE_SWIZZLE_WRITES(v->reg[lfbMode].u))
+ {
+ data = FLIPENDIAN_INT32(data);
+ mem_mask = FLIPENDIAN_INT32(mem_mask);
+ }
-static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask, bool lfb_3d)
+ /* word swapping */
+ if (LFBMODE_WORD_SWAP_WRITES(v->reg[lfbMode].u))
+ {
+ data = (data << 16) | (data >> 16);
+ mem_mask = (mem_mask << 16) | (mem_mask >> 16);
+ }
+
+ // TODO: This direct write is not verified.
+ // For direct lfb access just write the data
+ /* compute X,Y */
+ offset <<= 1;
+ x = offset & ((1 << v->fbi.lfb_stride) - 1);
+ y = (offset >> v->fbi.lfb_stride);
+ dest = (UINT16 *)(v->fbi.ram + v->fbi.lfb_base*4);
+ destmax = (v->fbi.mask + 1 - v->fbi.lfb_base*4) / 2;
+ bufoffs = y * v->fbi.rowpixels + x;
+ if (bufoffs >= destmax) {
+ logerror("lfb_direct_w: Buffer offset out of bounds x=%i y=%i offset=%08X bufoffs=%08X data=%08X\n", x, y, offset, (UINT32) bufoffs, data);
+ return 0;
+ }
+ if (ACCESSING_BITS_0_15)
+ dest[bufoffs + 0] = data&0xffff;
+ if (ACCESSING_BITS_16_31)
+ dest[bufoffs + 1] = data>>16;
+ if (LOG_LFB) logerror("VOODOO.%d.LFB:write direct (%d,%d) = %08X & %08X\n", v->index, x, y, data, mem_mask);
+ return 0;
+}
+
+static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask)
{
UINT16 *dest, *depth;
UINT32 destmax, depthmax;
@@ -2943,29 +2996,6 @@ static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask,
/* statistics */
v->stats.lfb_writes++;
- // TODO: This direct write is not verified.
- // For direct lfb access just write the data
- if (!lfb_3d) {
- UINT32 bufoffs;
- /* compute X,Y */
- offset <<= 1;
- x = offset & ((1 << v->fbi.lfb_stride) - 1);
- y = (offset >> v->fbi.lfb_stride);
- dest = (UINT16 *)(v->fbi.ram + v->fbi.lfb_base*4);
- destmax = (v->fbi.mask + 1 - v->fbi.lfb_base*4) / 2;
- bufoffs = y * v->fbi.rowpixels + x;
- if (bufoffs >= destmax) {
- logerror("LFB_W: Buffer offset out of bounds x=%i y=%i lfb_3d=%i offset=%08X bufoffs=%08X data=%08X\n", x, y, lfb_3d, offset, (UINT32) bufoffs, data);
- return 0;
- }
- if (ACCESSING_BITS_0_15)
- dest[bufoffs + 0] = data&0xffff;
- if (ACCESSING_BITS_16_31)
- dest[bufoffs + 1] = data>>16;
- if (LOG_LFB) logerror("VOODOO.%d.LFB:write direct (%d,%d) = %08X & %08X\n", v->index, x, y, data, mem_mask);
- return 0;
- }
-
/* byte swizzling */
if (LFBMODE_BYTE_SWIZZLE_WRITES(v->reg[lfbMode].u))
{
@@ -3187,9 +3217,6 @@ static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask,
depth = (UINT16 *)(v->fbi.ram + v->fbi.auxoffs);
depthmax = (v->fbi.mask + 1 - v->fbi.auxoffs) / 2;
- /* wait for any outstanding work to finish */
- poly_wait(v->poly, "LFB Write");
-
/* simple case: no pipeline */
if (!LFBMODE_ENABLE_PIXEL_PIPELINE(v->reg[lfbMode].u))
{
@@ -3209,6 +3236,9 @@ static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask,
/* compute dithering */
COMPUTE_DITHER_POINTERS_NO_DITHER_VAR(v->reg[fbzMode].u, y);
+ /* wait for any outstanding work to finish */
+ poly_wait(v->poly, "LFB Write");
+
/* loop over up to two pixels */
for (pix = 0; mask; pix++)
{
@@ -3281,8 +3311,6 @@ static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask,
iterw = (UINT32) sw[pix] << 16;
}
INT32 iterz = sw[pix] << 12;
- rgb_union color;
- rgb_union iterargb = { 0 };
/* apply clipping */
if (FBZMODE_ENABLE_CLIPPING(v->reg[fbzMode].u))
@@ -3297,15 +3325,19 @@ static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask,
goto nextpixel;
}
}
+ #if USE_OLD_RASTER == 1
+ rgb_union color;
+ rgb_union iterargb = { 0 };
+ #else
+ rgbaint_t color, preFog;
+ rgbaint_t iterargb(0);
+ #endif
/* pixel pipeline part 1 handles depth testing and stippling */
//PIXEL_PIPELINE_BEGIN(v, stats, x, y, v->reg[fbzColorPath].u, v->reg[fbzMode].u, iterz, iterw);
// Start PIXEL_PIPE_BEGIN copy
//#define PIXEL_PIPELINE_BEGIN(VV, STATS, XX, YY, FBZCOLORPATH, FBZMODE, ITERZ, ITERW)
- do
- {
INT32 fogdepth, biasdepth;
- INT32 prefogr, prefogg, prefogb;
INT32 r, g, b, a;
(stats)->pixels_in++;
@@ -3334,7 +3366,7 @@ static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask,
if (((v->reg[stipple].u >> stipple_index) & 1) == 0)
{
v->stats.total_stippled++;
- goto skipdrawdepth;
+ goto nextpixel;
}
}
}
@@ -3343,25 +3375,46 @@ static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask,
// Depth testing value for lfb pipeline writes is directly from write data, no biasing is used
fogdepth = biasdepth = (UINT32) sw[pix];
- /* Perform depth testing */
- DEPTH_TEST(v, stats, x, v->reg[fbzMode].u);
+ #if USE_OLD_RASTER == 1
+ /* Perform depth testing */
+ DEPTH_TEST(v, stats, x, v->reg[fbzMode].u);
+
+ /* use the RGBA we stashed above */
+ color.rgb.r = r = sr[pix];
+ color.rgb.g = g = sg[pix];
+ color.rgb.b = b = sb[pix];
+ color.rgb.a = a = sa[pix];
+
+ /* apply chroma key, alpha mask, and alpha testing */
+ APPLY_CHROMAKEY(v, stats, v->reg[fbzMode].u, color);
+ APPLY_ALPHAMASK(v, stats, v->reg[fbzMode].u, color.rgb.a);
+ APPLY_ALPHATEST(v, stats, v->reg[alphaMode].u, color.rgb.a);
+ #else
+ /* Perform depth testing */
+ if (!depthTest((UINT16) v->reg[zaColor].u, stats, depth[x], v->reg[fbzMode].u, biasdepth))
+ goto nextpixel;
+
+ /* use the RGBA we stashed above */
+ color.set(sa[pix], sr[pix], sg[pix], sb[pix]);
- /* use the RGBA we stashed above */
- color.rgb.r = r = sr[pix];
- color.rgb.g = g = sg[pix];
- color.rgb.b = b = sb[pix];
- color.rgb.a = a = sa[pix];
+ /* handle chroma key */
+ if (!chromaKeyTest(v, stats, v->reg[fbzMode].u, color))
+ goto nextpixel;
+ /* handle alpha mask */
+ if (!alphaMaskTest(stats, v->reg[fbzMode].u, color.get_a()))
+ goto nextpixel;
+ /* handle alpha test */
+ if (!alphaTest(v, stats, v->reg[alphaMode].u, color.get_a()))
+ goto nextpixel;
+ #endif
- /* apply chroma key, alpha mask, and alpha testing */
- APPLY_CHROMAKEY(v, stats, v->reg[fbzMode].u, color);
- APPLY_ALPHAMASK(v, stats, v->reg[fbzMode].u, color.rgb.a);
- APPLY_ALPHATEST(v, stats, v->reg[alphaMode].u, color.rgb.a);
+ /* wait for any outstanding work to finish */
+ poly_wait(v->poly, "LFB Write");
/* pixel pipeline part 2 handles color combine, fog, alpha, and final output */
PIXEL_PIPELINE_END(v, stats, dither, dither4, dither_lookup, x, dest, depth,
v->reg[fbzMode].u, v->reg[fbzColorPath].u, v->reg[alphaMode].u, v->reg[fogMode].u,
iterz, iterw, iterargb);
- }
nextpixel:
/* advance our pointers */
x++;
@@ -3594,7 +3647,7 @@ static void flush_fifos(voodoo_state *v, attotime current_time)
mem_mask &= 0xffff0000;
address &= 0xffffff;
- cycles = lfb_w(v, address, data, mem_mask, true);
+ cycles = lfb_w(v, address, data, mem_mask);
}
}
@@ -3720,7 +3773,7 @@ WRITE32_MEMBER( voodoo_device::voodoo_w )
else if (offset & (0x800000/4))
cycles = texture_w(v, offset, data);
else
- cycles = lfb_w(v, offset, data, mem_mask, true);
+ cycles = lfb_w(v, offset, data, mem_mask);
/* if we ended up with cycles, mark the operation pending */
if (cycles)
@@ -3900,7 +3953,7 @@ static UINT32 register_r(voodoo_state *v, offs_t offset)
/* bit 31 is not used */
/* eat some cycles since people like polling here */
- v->cpu->execute().eat_cycles(1000);
+ if (EAT_CYCLES) v->cpu->execute().eat_cycles(1000);
break;
/* bit 2 of the initEnable register maps this to dacRead */
@@ -3913,7 +3966,7 @@ static UINT32 register_r(voodoo_state *v, offs_t offset)
case vRetrace:
/* eat some cycles since people like polling here */
- v->cpu->execute().eat_cycles(10);
+ if (EAT_CYCLES) v->cpu->execute().eat_cycles(10);
result = v->screen->vpos();
break;
@@ -3928,7 +3981,7 @@ static UINT32 register_r(voodoo_state *v, offs_t offset)
result = v->fbi.cmdfifo[0].rdptr;
/* eat some cycles since people like polling here */
- v->cpu->execute().eat_cycles(1000);
+ if (EAT_CYCLES) v->cpu->execute().eat_cycles(1000);
break;
case cmdFifoAMin:
@@ -4757,7 +4810,7 @@ WRITE32_MEMBER( voodoo_banshee_device::banshee_w )
logerror("%s:banshee_w(YUV:%X) = %08X & %08X\n", machine().describe_context(), (offset*4) & 0x3fffff, data, mem_mask);
else if (offset < 0x2000000/4)
{
- lfb_w(v, offset & 0xffffff/4, data, mem_mask, true);
+ lfb_w(v, offset & 0xffffff/4, data, mem_mask);
} else {
logerror("%s:banshee_w Address out of range %08X = %08X & %08X\n", machine().describe_context(), (offset*4), data, mem_mask);
}
@@ -4791,7 +4844,7 @@ WRITE32_MEMBER( voodoo_banshee_device::banshee_fb_w )
}
}
else
- lfb_w(v, offset - v->fbi.lfb_base, data, mem_mask, false);
+ lfb_direct_w(v, offset - v->fbi.lfb_base, data, mem_mask);
}
@@ -5658,6 +5711,7 @@ static raster_info *add_rasterizer(voodoo_state *v, const raster_info *cinfo)
/* fill in the data */
info->hits = 0;
info->polys = 0;
+ info->hash = hash;
/* hook us into the hash table */
info->next = v->raster_hash[hash];
@@ -5665,7 +5719,7 @@ static raster_info *add_rasterizer(voodoo_state *v, const raster_info *cinfo)
if (LOG_RASTERIZERS)
printf("Adding rasterizer @ %p : cp=%08X am=%08X %08X fbzM=%08X tm0=%08X tm1=%08X (hash=%d)\n",
- info->callback,
+ (void *)info->callback,
info->eff_color_path, info->eff_alpha_mode, info->eff_fog_mode, info->eff_fbz_mode,
info->eff_tex_mode_0, info->eff_tex_mode_1, hash);
@@ -5760,7 +5814,7 @@ static void dump_rasterizer_stats(voodoo_state *v)
break;
/* print it */
- printf("RASTERIZER_ENTRY( 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X ) /* %c %8d %10d */\n",
+ printf("RASTERIZER_ENTRY( 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X ) /* %c %2d %8d %10d */\n",
best->eff_color_path,
best->eff_alpha_mode,
best->eff_fog_mode,
@@ -5768,6 +5822,7 @@ static void dump_rasterizer_stats(voodoo_state *v)
best->eff_tex_mode_0,
best->eff_tex_mode_1,
best->is_generic ? '*' : ' ',
+ best->hash,
best->polys,
best->hits);
@@ -6436,5 +6491,27 @@ RASTERIZER_ENTRY( 0x00602439, 0x00044119, 0x00000000, 0x000B0379, 0x00000009, 0x
//RASTERIZER_ENTRY( 0x00002809, 0x00004110, 0x00000001, 0x00030FFB, 0x08241AC7, 0xFFFFFFFF ) /* in-game */
//RASTERIZER_ENTRY( 0x00424219, 0x00000000, 0x00000001, 0x00030F7B, 0x08241AC7, 0xFFFFFFFF ) /* in-game */
//RASTERIZER_ENTRY( 0x0200421A, 0x00001510, 0x00000001, 0x00030F7B, 0x08241AC7, 0xFFFFFFFF ) /* in-game */
+/* gtfore06 ----> fbzColorPath alphaMode fogMode, fbzMode, texMode0, texMode1 hash */
+RASTERIZER_ENTRY( 0x00482405, 0x00045119, 0x000000C1, 0x00010F79, 0x0C261ACD, 0x0C261ACD ) /* 18 1064626 69362127 */
+RASTERIZER_ENTRY( 0x00002425, 0x00045119, 0x000000C1, 0x00010F79, 0x0C224A0D, 0x0C261ACD ) /* 47 3272483 31242799 */
+RASTERIZER_ENTRY( 0x00482405, 0x00045119, 0x000000C1, 0x00010F79, 0x00000ACD, 0x0C261ACD ) /* 9 221917 12348555 */
+RASTERIZER_ENTRY( 0x00002425, 0x00045110, 0x000000C1, 0x00010FF9, 0x00000ACD, 0x0C261ACD ) /* 26 57291 9357989 */
+RASTERIZER_ENTRY( 0x00002429, 0x00000000, 0x000000C1, 0x00010FF9, 0x00000A09, 0x0C261A0F ) /* 12 97156 8530607 */
+RASTERIZER_ENTRY( 0x00482405, 0x00045119, 0x000000C1, 0x00010F79, 0x000000C4, 0x0C261ACD ) /* 55 110144 5265532 */
+RASTERIZER_ENTRY( 0x00002425, 0x00045110, 0x000000C1, 0x00010FF9, 0x000000C4, 0x0C261ACD ) /* 61 16644 1079382 */
+RASTERIZER_ENTRY( 0x00002425, 0x00045119, 0x000000C1, 0x00010FF9, 0x000000C4, 0x0C261ACD ) /* 5 8332 1065229 */
+RASTERIZER_ENTRY( 0x00002425, 0x00045119, 0x000000C1, 0x00010F79, 0x0C224A0D, 0x0C261A0D ) /* 45 8148 505013 */
+RASTERIZER_ENTRY( 0x00002425, 0x00045119, 0x00000000, 0x00010F79, 0x0C224A0D, 0x0C261A0D ) /* 84 45233 248267 */
+RASTERIZER_ENTRY( 0x00482405, 0x00045119, 0x000000C1, 0x00010F79, 0x0C261ACD, 0x0C2610C4 ) /* 90 10235 193036 */
+RASTERIZER_ENTRY( 0x00482405, 0x00045119, 0x000000C1, 0x00010FF9, 0x0C261ACD, 0x0C261ACD ) /* * 29 3777 83777 */
+RASTERIZER_ENTRY( 0x00482405, 0x00045119, 0x00000000, 0x00010FF9, 0x0C261ACD, 0x042210C0 ) /* 2 24952 66761 */
+RASTERIZER_ENTRY( 0x00002429, 0x00000000, 0x00000000, 0x00010FF9, 0x00000A09, 0x0C261A0F ) /* 24 661 50222 */
+RASTERIZER_ENTRY( 0x00482405, 0x00045119, 0x00000000, 0x00010FF9, 0x0C261ACD, 0x04221AC9 ) /* 92 12504 43720 */
+RASTERIZER_ENTRY( 0x00482405, 0x00045119, 0x000000C1, 0x00010FF9, 0x0C261ACD, 0x0C2610C4 ) /* 79 2160 43650 */
+RASTERIZER_ENTRY( 0x00482405, 0x00045119, 0x00000000, 0x00010FF9, 0x000000C4, 0x04221AC9 ) /* 19 2796 30377 */
+RASTERIZER_ENTRY( 0x00002425, 0x00045119, 0x000000C1, 0x00010FF9, 0x00000ACD, 0x0C261ACD ) /* 67 1962 14755 */
+RASTERIZER_ENTRY( 0x00482405, 0x00045119, 0x000000C1, 0x00010FF9, 0x000000C4, 0x0C261ACD ) /* * 66 74 3951 */
+RASTERIZER_ENTRY( 0x00482405, 0x00045119, 0x00000000, 0x00010FF9, 0x00000ACD, 0x04221AC9 ) /* 70 374 3691 */
+RASTERIZER_ENTRY( 0x00482405, 0x00045119, 0x000000C1, 0x00010FF9, 0x00000ACD, 0x0C261ACD ) /* * 20 350 7928 */
#endif