diff options
Diffstat (limited to 'src/emu/video/voodoo.c')
-rw-r--r-- | src/emu/video/voodoo.c | 197 |
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 |