Add mutex to protect Voodoo swap count and pending. Should fix hangs
sometimes changing video mode on Voodoo 3.
This commit is contained in:
parent
984437dfa9
commit
193645a426
6 changed files with 37 additions and 6 deletions
|
|
@ -414,7 +414,9 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p)
|
|||
|
||||
case SST_swapbufferCMD:
|
||||
voodoo->cmd_written++;
|
||||
thread_lock_mutex(voodoo->swap_mutex);
|
||||
voodoo->swap_count++;
|
||||
thread_unlock_mutex(voodoo->swap_mutex);
|
||||
if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)
|
||||
return;
|
||||
voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val);
|
||||
|
|
@ -495,7 +497,9 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p)
|
|||
if ((voodoo->fbiInit1 & FBIINIT1_VIDEO_RESET) && !(val & FBIINIT1_VIDEO_RESET))
|
||||
{
|
||||
voodoo->line = 0;
|
||||
thread_lock_mutex(voodoo->swap_mutex);
|
||||
voodoo->swap_count = 0;
|
||||
thread_unlock_mutex(voodoo->swap_mutex);
|
||||
voodoo->retrace_count = 0;
|
||||
}
|
||||
voodoo->fbiInit1 = (val & ~5) | (voodoo->fbiInit1 & 5);
|
||||
|
|
@ -1024,6 +1028,7 @@ void *voodoo_card_init()
|
|||
voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo);
|
||||
voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo);
|
||||
}
|
||||
voodoo->swap_mutex = thread_create_mutex();
|
||||
timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0);
|
||||
|
||||
for (c = 0; c < 0x100; c++)
|
||||
|
|
@ -1140,7 +1145,7 @@ void *voodoo_2d3d_card_init(int type)
|
|||
voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo);
|
||||
voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo);
|
||||
}
|
||||
|
||||
voodoo->swap_mutex = thread_create_mutex();
|
||||
timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0);
|
||||
|
||||
for (c = 0; c < 0x100; c++)
|
||||
|
|
|
|||
|
|
@ -1239,7 +1239,9 @@ static void banshee_reg_writel(uint32_t addr, uint32_t val, void *p)
|
|||
break;
|
||||
|
||||
case SST_swapPending:
|
||||
thread_lock_mutex(voodoo->swap_mutex);
|
||||
voodoo->swap_count++;
|
||||
thread_unlock_mutex(voodoo->swap_mutex);
|
||||
// voodoo->cmd_written++;
|
||||
break;
|
||||
|
||||
|
|
@ -1842,17 +1844,22 @@ static void banshee_vsync_callback(svga_t *svga)
|
|||
voodoo_t *voodoo = banshee->voodoo;
|
||||
|
||||
voodoo->retrace_count++;
|
||||
thread_lock_mutex(voodoo->swap_mutex);
|
||||
if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval))
|
||||
{
|
||||
memset(voodoo->dirty_line, 1, 1024);
|
||||
voodoo->retrace_count = 0;
|
||||
banshee_set_overlay_addr(banshee, voodoo->swap_offset);
|
||||
if (voodoo->swap_count > 0)
|
||||
voodoo->swap_count--;
|
||||
voodoo->swap_pending = 0;
|
||||
thread_unlock_mutex(voodoo->swap_mutex);
|
||||
|
||||
memset(voodoo->dirty_line, 1, 1024);
|
||||
voodoo->retrace_count = 0;
|
||||
banshee_set_overlay_addr(banshee, voodoo->swap_offset);
|
||||
thread_set_event(voodoo->wake_fifo_thread);
|
||||
voodoo->frame_count++;
|
||||
}
|
||||
else
|
||||
thread_unlock_mutex(voodoo->swap_mutex);
|
||||
|
||||
voodoo->overlay.src_y = 0;
|
||||
banshee->desktop_addr = banshee->vidDesktopStartAddr;
|
||||
|
|
|
|||
|
|
@ -229,6 +229,7 @@ typedef struct voodoo_t
|
|||
|
||||
uint32_t tmuConfig;
|
||||
|
||||
mutex_t *swap_mutex;
|
||||
int swap_count;
|
||||
|
||||
int disp_buffer, draw_buffer;
|
||||
|
|
|
|||
|
|
@ -531,6 +531,7 @@ skip_draw:
|
|||
{
|
||||
voodoo_t *voodoo_1 = voodoo->set->voodoos[1];
|
||||
|
||||
thread_lock_mutex(voodoo->swap_mutex);
|
||||
/*Only swap if both Voodoos are waiting for buffer swap*/
|
||||
if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval) &&
|
||||
voodoo_1->swap_pending && (voodoo_1->retrace_count > voodoo_1->swap_interval))
|
||||
|
|
@ -548,6 +549,7 @@ skip_draw:
|
|||
if (voodoo_1->swap_count > 0)
|
||||
voodoo_1->swap_count--;
|
||||
voodoo_1->swap_pending = 0;
|
||||
thread_unlock_mutex(voodoo->swap_mutex);
|
||||
|
||||
thread_set_event(voodoo->wake_fifo_thread);
|
||||
thread_set_event(voodoo_1->wake_fifo_thread);
|
||||
|
|
@ -555,21 +557,28 @@ skip_draw:
|
|||
voodoo->frame_count++;
|
||||
voodoo_1->frame_count++;
|
||||
}
|
||||
else
|
||||
thread_unlock_mutex(voodoo->swap_mutex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
thread_lock_mutex(voodoo->swap_mutex);
|
||||
if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval))
|
||||
{
|
||||
memset(voodoo->dirty_line, 1, 1024);
|
||||
voodoo->retrace_count = 0;
|
||||
voodoo->front_offset = voodoo->swap_offset;
|
||||
if (voodoo->swap_count > 0)
|
||||
voodoo->swap_count--;
|
||||
voodoo->swap_pending = 0;
|
||||
thread_unlock_mutex(voodoo->swap_mutex);
|
||||
|
||||
memset(voodoo->dirty_line, 1, 1024);
|
||||
voodoo->retrace_count = 0;
|
||||
thread_set_event(voodoo->wake_fifo_thread);
|
||||
voodoo->frame_count++;
|
||||
}
|
||||
else
|
||||
thread_unlock_mutex(voodoo->swap_mutex);
|
||||
}
|
||||
voodoo->v_retrace = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,6 +90,8 @@ void voodoo_wait_for_swap_complete(voodoo_t *voodoo)
|
|||
{
|
||||
thread_wait_event(voodoo->wake_fifo_thread, -1);
|
||||
thread_reset_event(voodoo->wake_fifo_thread);
|
||||
|
||||
thread_lock_mutex(voodoo->swap_mutex);
|
||||
if ((voodoo->swap_pending && voodoo->flush) || FIFO_FULL)
|
||||
{
|
||||
/*Main thread is waiting for FIFO to empty, so skip vsync wait and just swap*/
|
||||
|
|
@ -98,8 +100,11 @@ void voodoo_wait_for_swap_complete(voodoo_t *voodoo)
|
|||
if (voodoo->swap_count > 0)
|
||||
voodoo->swap_count--;
|
||||
voodoo->swap_pending = 0;
|
||||
thread_unlock_mutex(voodoo->swap_mutex);
|
||||
break;
|
||||
}
|
||||
else
|
||||
thread_unlock_mutex(voodoo->swap_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,8 +56,10 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p)
|
|||
if (!(val & 1))
|
||||
{
|
||||
banshee_set_overlay_addr(voodoo->p, voodoo->leftOverlayBuf);
|
||||
thread_lock_mutex(voodoo->swap_mutex);
|
||||
if (voodoo->swap_count > 0)
|
||||
voodoo->swap_count--;
|
||||
thread_unlock_mutex(voodoo->swap_mutex);
|
||||
voodoo->frame_count++;
|
||||
}
|
||||
else if (TRIPLE_BUFFER)
|
||||
|
|
@ -102,8 +104,10 @@ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p)
|
|||
{
|
||||
memset(voodoo->dirty_line, 1, 1024);
|
||||
voodoo->front_offset = voodoo->params.front_offset;
|
||||
thread_lock_mutex(voodoo->swap_mutex);
|
||||
if (voodoo->swap_count > 0)
|
||||
voodoo->swap_count--;
|
||||
thread_unlock_mutex(voodoo->swap_mutex);
|
||||
}
|
||||
else if (TRIPLE_BUFFER)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue