Implement out-of-order CMDFIFO handling on Banshee.

This commit is contained in:
SarahW 2020-08-15 15:57:39 +01:00
commit 2212b9a470
2 changed files with 50 additions and 3 deletions

View file

@ -1403,10 +1403,56 @@ static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p)
*(uint32_t *)&svga->vram[addr & svga->vram_mask] = val;
if (addr >= voodoo->cmdfifo_base && addr < voodoo->cmdfifo_end)
{
// pclog("CMDFIFO write %08x %08x %04x:%08x\n", addr, val, CS,cpu_state.pc);
voodoo->cmdfifo_depth_wr++;
// if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20)
// pclog("CMDFIFO write %08x %08x old amin=%08x amax=%08x hlcnt=%i depth_wr=%i rp=%08x\n", addr, val, voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount, voodoo->cmdfifo_depth_wr, voodoo->cmdfifo_rp);
if (addr == voodoo->cmdfifo_base && !voodoo->cmdfifo_holecount)
{
// if (voodoo->cmdfifo_holecount)
// fatal("CMDFIFO reset pointers while outstanding holes\n");
/*Reset pointers*/
voodoo->cmdfifo_amin = voodoo->cmdfifo_base;
voodoo->cmdfifo_amax = voodoo->cmdfifo_base;
voodoo->cmdfifo_depth_wr++;
voodoo_wake_fifo_thread(voodoo);
}
else if (voodoo->cmdfifo_holecount)
{
// if ((addr <= voodoo->cmdfifo_amin && voodoo->cmdfifo_amin != -4) || addr >= voodoo->cmdfifo_amax)
// fatal("CMDFIFO holecount write outside of amin/amax - amin=%08x amax=%08x holecount=%i\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount);
// pclog("holecount %i\n", voodoo->cmdfifo_holecount);
voodoo->cmdfifo_holecount--;
if (!voodoo->cmdfifo_holecount)
{
int words_to_add = ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2) + 1;
/*Filled in holes, resume normal operation*/
voodoo->cmdfifo_depth_wr += ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2);
voodoo->cmdfifo_amin = voodoo->cmdfifo_amax;
voodoo_wake_fifo_thread(voodoo);
// pclog("hole filled! amin=%08x amax=%08x added %i words\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, words_to_add);
}
}
else if (addr == voodoo->cmdfifo_amax+4)
{
/*In-order write*/
voodoo->cmdfifo_amin = addr;
voodoo->cmdfifo_amax = addr;
voodoo->cmdfifo_depth_wr++;
voodoo_wake_fifo_thread(voodoo);
}
else
{
/*Out-of-order write*/
if (addr < voodoo->cmdfifo_amin)
{
/*Reset back to start. Note that write is still out of order!*/
voodoo->cmdfifo_amin = voodoo->cmdfifo_base-4;
}
// else if (addr < voodoo->cmdfifo_amax)
// fatal("Out-of-order write really out of order\n");
voodoo->cmdfifo_amax = addr;
voodoo->cmdfifo_holecount = ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2) - 1;
// pclog("CMDFIFO out of order: amin=%08x amax=%08x holecount=%i\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount);
}
}
}

View file

@ -302,6 +302,7 @@ typedef struct voodoo_t
int cmdfifo_rp;
volatile int cmdfifo_depth_rd, cmdfifo_depth_wr;
uint32_t cmdfifo_amin, cmdfifo_amax;
int cmdfifo_holecount;
uint32_t sSetupMode;
vert_t verts[4];