Don't wake up Voodoo FIFO thread on every write, instead add a delay. This prevents the situation where it is woken up for every single access. Major speedup on many 3DFX games.

This commit is contained in:
SarahW 2016-12-12 21:12:35 +00:00
commit 6ddc017987

View file

@ -371,6 +371,8 @@ typedef struct voodoo_t
int read_time, write_time, burst_time; int read_time, write_time, burst_time;
int wake_timer;
uint16_t thefilter[1024][1024]; // pixel filter, feeding from one or two uint16_t thefilter[1024][1024]; // pixel filter, feeding from one or two
uint16_t thefilterg[1024][1024]; // for green uint16_t thefilterg[1024][1024]; // for green
@ -5467,8 +5469,32 @@ static void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p)
*(uint32_t *)(&voodoo->tex_mem[tmu][addr & voodoo->texture_mask]) = val; *(uint32_t *)(&voodoo->tex_mem[tmu][addr & voodoo->texture_mask]) = val;
} }
#define WAKE_DELAY (TIMER_USEC * 100)
static inline void wake_fifo_thread(voodoo_t *voodoo) static inline void wake_fifo_thread(voodoo_t *voodoo)
{ {
if (!voodoo->wake_timer)
{
/*Don't wake FIFO thread immediately - if we do that it will probably
process one word and go back to sleep, requiring it to be woken on
almost every write. Instead, wait a short while so that the CPU
emulation writes more data so we have more batched-up work.*/
timer_process();
voodoo->wake_timer = WAKE_DELAY;
timer_update_outstanding();
}
}
static inline void wake_fifo_thread_now(voodoo_t *voodoo)
{
thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/
}
static void voodoo_wake_timer(void *p)
{
voodoo_t *voodoo = (voodoo_t *)p;
voodoo->wake_timer = 0;
thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/
} }
@ -5508,7 +5534,7 @@ static uint16_t voodoo_readw(uint32_t addr, void *p)
voodoo->flush = 1; voodoo->flush = 1;
while (!FIFO_EMPTY) while (!FIFO_EMPTY)
{ {
wake_fifo_thread(voodoo); wake_fifo_thread_now(voodoo);
thread_wait_event(voodoo->fifo_not_full_event, 1); thread_wait_event(voodoo->fifo_not_full_event, 1);
} }
wait_for_render_thread_idle(voodoo); wait_for_render_thread_idle(voodoo);
@ -5538,7 +5564,7 @@ static uint32_t voodoo_readl(uint32_t addr, void *p)
voodoo->flush = 1; voodoo->flush = 1;
while (!FIFO_EMPTY) while (!FIFO_EMPTY)
{ {
wake_fifo_thread(voodoo); wake_fifo_thread_now(voodoo);
thread_wait_event(voodoo->fifo_not_full_event, 1); thread_wait_event(voodoo->fifo_not_full_event, 1);
} }
wait_for_render_thread_idle(voodoo); wait_for_render_thread_idle(voodoo);
@ -5568,7 +5594,7 @@ static uint32_t voodoo_readl(uint32_t addr, void *p)
voodoo->flush = 1; voodoo->flush = 1;
while (!FIFO_EMPTY) while (!FIFO_EMPTY)
{ {
wake_fifo_thread(voodoo); wake_fifo_thread_now(voodoo);
thread_wait_event(voodoo->fifo_not_full_event, 1); thread_wait_event(voodoo->fifo_not_full_event, 1);
} }
wait_for_render_thread_idle(voodoo); wait_for_render_thread_idle(voodoo);
@ -5729,7 +5755,7 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p)
*(uint32_t *)&voodoo->fb_mem[(voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask] = val; *(uint32_t *)&voodoo->fb_mem[(voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask] = val;
voodoo->cmdfifo_depth_wr++; voodoo->cmdfifo_depth_wr++;
if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20) if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20)
thread_set_event(voodoo->wake_fifo_thread); wake_fifo_thread(voodoo);
} }
else switch (addr & 0x3fc) else switch (addr & 0x3fc)
{ {
@ -6663,6 +6689,8 @@ void *voodoo_init()
if (voodoo->render_threads == 2) if (voodoo->render_threads == 2)
voodoo->render_thread[1] = thread_create(render_thread_2, voodoo); voodoo->render_thread[1] = thread_create(render_thread_2, voodoo);
timer_add(voodoo_wake_timer, &voodoo->wake_timer, &voodoo->wake_timer, (void *)voodoo);
for (c = 0; c < 0x100; c++) for (c = 0; c < 0x100; c++)
{ {
rgb332[c].r = c & 0xe0; rgb332[c].r = c & 0xe0;