diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 19c5467..5d556df 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -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++) diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 2026d8e..d705c57 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.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; diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h index 637ccca..364407f 100644 --- a/src/vid_voodoo_common.h +++ b/src/vid_voodoo_common.h @@ -229,6 +229,7 @@ typedef struct voodoo_t uint32_t tmuConfig; + mutex_t *swap_mutex; int swap_count; int disp_buffer, draw_buffer; diff --git a/src/vid_voodoo_display.c b/src/vid_voodoo_display.c index d643d5d..a8cda43 100644 --- a/src/vid_voodoo_display.c +++ b/src/vid_voodoo_display.c @@ -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; } diff --git a/src/vid_voodoo_fifo.c b/src/vid_voodoo_fifo.c index 0d35b3a..1c807d4 100644 --- a/src/vid_voodoo_fifo.c +++ b/src/vid_voodoo_fifo.c @@ -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); } } diff --git a/src/vid_voodoo_reg.c b/src/vid_voodoo_reg.c index 965c6f6..82f4bac 100644 --- a/src/vid_voodoo_reg.c +++ b/src/vid_voodoo_reg.c @@ -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) {