vooddefs.h - Small correction in genTexture.

voodoo.c - Separate direct fb write to help performance.
vrc4373.c - Clean up dma routine.
This commit is contained in:
ted green 2015-06-21 09:40:04 -06:00
parent 9bb341b6b7
commit 1314fc9823
3 changed files with 97 additions and 55 deletions

View File

@ -269,22 +269,39 @@ void vrc4373_device::dma_transfer(int which)
if (LOG_NILE)
logerror("%08X:nile Start dma PCI: %08X MEM: %08X Words: %X\n", m_cpu->space(AS_PROGRAM).device().safe_pc(), m_cpu_regs[NREG_DMA_CPAR], m_cpu_regs[NREG_DMA_CMAR], m_cpu_regs[NREG_DMA_REM]);
int pciSel = (m_cpu_regs[NREG_DMACR1+which*0xC] & DMA_MIO) ? AS_DATA : AS_IO;
UINT32 mem_mask = 0xffffffff;
while (m_cpu_regs[NREG_DMA_REM]>0) {
if (0 && LOG_NILE)
logerror("dma_transfer PCI: %08X Mem: %08X Words Remaining: %X\n", m_cpu_regs[NREG_DMA_CPAR], m_cpu_regs[NREG_DMA_CMAR], m_cpu_regs[NREG_DMA_REM]);
if (m_cpu_regs[NREG_DMACR1+which*0xC]&DMA_RW) {
// Read data from PCI and write to local
m_cpu->space(AS_PROGRAM).write_dword(m_cpu_regs[NREG_DMA_CMAR], this->space(pciSel).read_dword(m_cpu_regs[NREG_DMA_CPAR], mem_mask), mem_mask);
} else {
// Read data from local and write to PCI
this->space(pciSel).write_dword(m_cpu_regs[NREG_DMA_CPAR], m_cpu->space(AS_PROGRAM).read_dword(m_cpu_regs[NREG_DMA_CMAR], mem_mask), mem_mask);
}
m_cpu_regs[NREG_DMA_CMAR] += 0x4;
m_cpu_regs[NREG_DMA_CPAR] += 0x4;
m_cpu_regs[NREG_DMA_REM]--;
address_space *src, *dst;
UINT32 srcAddr, dstAddr;
if (m_cpu_regs[NREG_DMACR1+which*0xC]&DMA_RW) {
// Read data from PCI and write to cpu
src = &this->space(pciSel);
dst = &m_cpu->space(AS_PROGRAM);
srcAddr = m_cpu_regs[NREG_DMA_CPAR];
dstAddr = m_cpu_regs[NREG_DMA_CMAR];
} else {
// Read data from cpu and write to PCI
src = &m_cpu->space(AS_PROGRAM);
dst = &this->space(pciSel);
srcAddr = m_cpu_regs[NREG_DMA_CMAR];
dstAddr = m_cpu_regs[NREG_DMA_CPAR];
}
int count = m_cpu_regs[NREG_DMA_REM];
while (count>0) {
dst->write_dword(dstAddr, src->read_dword(srcAddr));
dstAddr += 0x4;
srcAddr += 0x4;
--count;
}
if (m_cpu_regs[NREG_DMACR1+which*0xC]&DMA_RW) {
m_cpu_regs[NREG_DMA_CPAR] = srcAddr;
m_cpu_regs[NREG_DMA_CMAR] = dstAddr;
} else {
m_cpu_regs[NREG_DMA_CMAR] = srcAddr;
m_cpu_regs[NREG_DMA_CPAR] = dstAddr;
}
m_cpu_regs[NREG_DMA_REM] = 0;
}
// CPU I/F
READ32_MEMBER (vrc4373_device::cpu_if_r)
{

View File

@ -4635,12 +4635,7 @@ ATTR_FORCE_INLINE UINT32 genTexture(tmu_state *TT, const UINT8 ditherX, const UI
/* determine the S/T/LOD values for this texture */
lod = (LODBASE);
/* clamp W */
if (TEXMODE_CLAMP_NEG_W(TEXMODE) && (ITERW) < 0)
{
s = t = 0;
}
else if (TEXMODE_ENABLE_PERSPECTIVE(TEXMODE))
if (TEXMODE_ENABLE_PERSPECTIVE(TEXMODE))
{
INT32 wLog;
oow = fast_reciplog((ITERW), &wLog);
@ -4654,6 +4649,11 @@ ATTR_FORCE_INLINE UINT32 genTexture(tmu_state *TT, const UINT8 ditherX, const UI
t = (ITERT) >> 14;
}
/* clamp W */
if (TEXMODE_CLAMP_NEG_W(TEXMODE) && (ITERW) < 0)
{
s = t = 0;
}
/* clamp the LOD */
lod += (TT)->lodbias;

View File

@ -211,7 +211,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);
@ -1943,7 +1944,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 +2932,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;
static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask, bool lfb_3d)
/* 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);
}
/* 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 +2988,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 +3209,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 +3228,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++)
{
@ -3349,7 +3371,7 @@ static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask,
if (USE_OLD_RASTER) {
/* Perform depth testing */
DEPTH_TEST(v, stats, x, v->reg[fbzMode].u);
/* 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);
@ -3358,7 +3380,7 @@ static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask,
/* Perform depth testing */
if (!depthTest((UINT16) v->reg[zaColor].u, stats, depth[x], v->reg[fbzMode].u, biasdepth))
goto nextpixel;
/* handle chroma key */
if (!chromaKeyTest(v, stats, v->reg[fbzMode].u, color))
goto nextpixel;
@ -3370,6 +3392,9 @@ static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask,
goto nextpixel;
}
/* 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,
@ -3606,7 +3631,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);
}
}
@ -3732,7 +3757,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)
@ -4769,7 +4794,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);
}
@ -4803,7 +4828,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);
}