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) 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]); 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; int pciSel = (m_cpu_regs[NREG_DMACR1+which*0xC] & DMA_MIO) ? AS_DATA : AS_IO;
UINT32 mem_mask = 0xffffffff; address_space *src, *dst;
while (m_cpu_regs[NREG_DMA_REM]>0) { UINT32 srcAddr, dstAddr;
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) { if (m_cpu_regs[NREG_DMACR1+which*0xC]&DMA_RW) {
// Read data from PCI and write to local // Read data from PCI and write to cpu
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); 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 { } else {
// Read data from local and write to PCI // Read data from cpu 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); src = &m_cpu->space(AS_PROGRAM);
dst = &this->space(pciSel);
srcAddr = m_cpu_regs[NREG_DMA_CMAR];
dstAddr = m_cpu_regs[NREG_DMA_CPAR];
} }
m_cpu_regs[NREG_DMA_CMAR] += 0x4; int count = m_cpu_regs[NREG_DMA_REM];
m_cpu_regs[NREG_DMA_CPAR] += 0x4; while (count>0) {
m_cpu_regs[NREG_DMA_REM]--; 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 // CPU I/F
READ32_MEMBER (vrc4373_device::cpu_if_r) 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 */ /* determine the S/T/LOD values for this texture */
lod = (LODBASE); lod = (LODBASE);
/* clamp W */ if (TEXMODE_ENABLE_PERSPECTIVE(TEXMODE))
if (TEXMODE_CLAMP_NEG_W(TEXMODE) && (ITERW) < 0)
{
s = t = 0;
}
else if (TEXMODE_ENABLE_PERSPECTIVE(TEXMODE))
{ {
INT32 wLog; INT32 wLog;
oow = fast_reciplog((ITERW), &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; t = (ITERT) >> 14;
} }
/* clamp W */
if (TEXMODE_CLAMP_NEG_W(TEXMODE) && (ITERW) < 0)
{
s = t = 0;
}
/* clamp the LOD */ /* clamp the LOD */
lod += (TT)->lodbias; 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 void stall_cpu(voodoo_state *v, int state, attotime current_time);
static TIMER_CALLBACK( vblank_callback ); static TIMER_CALLBACK( vblank_callback );
static INT32 register_w(voodoo_state *v, offs_t offset, UINT32 data); 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 texture_w(voodoo_state *v, offs_t offset, UINT32 data);
static INT32 banshee_2d_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 */ /* loop over words */
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
cycles += lfb_w(v, target++, *src++, 0xffffffff, true); cycles += lfb_w(v, target++, *src++, 0xffffffff);
break; break;
} }
@ -2931,8 +2932,52 @@ default_case:
* Voodoo LFB writes * 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; UINT16 *dest, *depth;
UINT32 destmax, depthmax; UINT32 destmax, depthmax;
@ -2943,29 +2988,6 @@ static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask,
/* statistics */ /* statistics */
v->stats.lfb_writes++; 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 */ /* byte swizzling */
if (LFBMODE_BYTE_SWIZZLE_WRITES(v->reg[lfbMode].u)) 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); depth = (UINT16 *)(v->fbi.ram + v->fbi.auxoffs);
depthmax = (v->fbi.mask + 1 - v->fbi.auxoffs) / 2; 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 */ /* simple case: no pipeline */
if (!LFBMODE_ENABLE_PIXEL_PIPELINE(v->reg[lfbMode].u)) 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 dithering */
COMPUTE_DITHER_POINTERS_NO_DITHER_VAR(v->reg[fbzMode].u, y); 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 */ /* loop over up to two pixels */
for (pix = 0; mask; pix++) for (pix = 0; mask; pix++)
{ {
@ -3370,6 +3392,9 @@ static INT32 lfb_w(voodoo_state *v, offs_t offset, UINT32 data, UINT32 mem_mask,
goto nextpixel; 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 part 2 handles color combine, fog, alpha, and final output */
PIXEL_PIPELINE_END(v, stats, dither, dither4, dither_lookup, x, dest, depth, 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, 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; mem_mask &= 0xffff0000;
address &= 0xffffff; 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)) else if (offset & (0x800000/4))
cycles = texture_w(v, offset, data); cycles = texture_w(v, offset, data);
else 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 we ended up with cycles, mark the operation pending */
if (cycles) 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); logerror("%s:banshee_w(YUV:%X) = %08X & %08X\n", machine().describe_context(), (offset*4) & 0x3fffff, data, mem_mask);
else if (offset < 0x2000000/4) 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 { } else {
logerror("%s:banshee_w Address out of range %08X = %08X & %08X\n", machine().describe_context(), (offset*4), data, mem_mask); 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 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);
} }