diff --git a/src/include/86box/vid_voodoo_common.h b/src/include/86box/vid_voodoo_common.h index d87c1f731..2870f09ea 100644 --- a/src/include/86box/vid_voodoo_common.h +++ b/src/include/86box/vid_voodoo_common.h @@ -667,6 +667,8 @@ typedef struct voodoo_t { struct voodoo_set_t *set; + uint32_t launch_pending; + uint8_t fifo_thread_run; uint8_t render_thread_run[4]; diff --git a/src/video/vid_voodoo_banshee_blitter.c b/src/video/vid_voodoo_banshee_blitter.c index ac8cb172d..af609d785 100644 --- a/src/video/vid_voodoo_banshee_blitter.c +++ b/src/video/vid_voodoo_banshee_blitter.c @@ -1438,9 +1438,30 @@ banshee_polyfill_continue(voodoo_t *voodoo, uint32_t data) } } +static inline void +banshee_do_2d_launch(voodoo_t *voodoo) +{ + voodoo->launch_pending = 0; + voodoo->banshee_blt.rops[0] = voodoo->banshee_blt.command >> 24; + voodoo->banshee_blt.patoff_x = (voodoo->banshee_blt.command & COMMAND_PATOFF_X_MASK) >> COMMAND_PATOFF_X_SHIFT; + voodoo->banshee_blt.patoff_y = (voodoo->banshee_blt.command & COMMAND_PATOFF_Y_MASK) >> COMMAND_PATOFF_Y_SHIFT; + voodoo->banshee_blt.cur_x = 0; + voodoo->banshee_blt.cur_y = 0; + voodoo->banshee_blt.dstX = ((int32_t) (voodoo->banshee_blt.dstXY << 19)) >> 19; + voodoo->banshee_blt.dstY = ((int32_t) (voodoo->banshee_blt.dstXY << 3)) >> 19; + voodoo->banshee_blt.srcX = ((int32_t) (voodoo->banshee_blt.srcXY << 19)) >> 19; + voodoo->banshee_blt.srcY = ((int32_t) (voodoo->banshee_blt.srcXY << 3)) >> 19; + voodoo->banshee_blt.old_srcX = voodoo->banshee_blt.srcX; + voodoo->banshee_blt.host_data_remainder = 0; + voodoo->banshee_blt.host_data_count = 0; +} + static void banshee_do_2d_blit(voodoo_t *voodoo, int count, uint32_t data) { + if (voodoo->launch_pending) { + banshee_do_2d_launch(voodoo); + } switch (voodoo->banshee_blt.command & COMMAND_CMD_MASK) { case COMMAND_CMD_NOP: break; @@ -1691,21 +1712,7 @@ voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) case 0x70: voodoo_wait_for_render_thread_idle(voodoo); voodoo->banshee_blt.command = val; - voodoo->banshee_blt.rops[0] = val >> 24; -#if 0 - bansheeblt_log("command=%x %08x\n", voodoo->banshee_blt.command & COMMAND_CMD_MASK, val); -#endif - voodoo->banshee_blt.patoff_x = (val & COMMAND_PATOFF_X_MASK) >> COMMAND_PATOFF_X_SHIFT; - voodoo->banshee_blt.patoff_y = (val & COMMAND_PATOFF_Y_MASK) >> COMMAND_PATOFF_Y_SHIFT; - voodoo->banshee_blt.cur_x = 0; - voodoo->banshee_blt.cur_y = 0; - voodoo->banshee_blt.dstX = ((int32_t) (voodoo->banshee_blt.dstXY << 19)) >> 19; - voodoo->banshee_blt.dstY = ((int32_t) (voodoo->banshee_blt.dstXY << 3)) >> 19; - voodoo->banshee_blt.srcX = ((int32_t) (voodoo->banshee_blt.srcXY << 19)) >> 19; - voodoo->banshee_blt.srcY = ((int32_t) (voodoo->banshee_blt.srcXY << 3)) >> 19; - voodoo->banshee_blt.old_srcX = voodoo->banshee_blt.srcX; - voodoo->banshee_blt.host_data_remainder = 0; - voodoo->banshee_blt.host_data_count = 0; + voodoo->launch_pending = 1; switch (voodoo->banshee_blt.command & COMMAND_CMD_MASK) { #if 0 @@ -1725,6 +1732,7 @@ voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) #endif case COMMAND_CMD_POLYFILL: + banshee_do_2d_launch(voodoo); if (val & COMMAND_INITIATE) { voodoo->banshee_blt.dstXY = voodoo->banshee_blt.srcXY; voodoo->banshee_blt.dstX = voodoo->banshee_blt.srcX; @@ -1733,6 +1741,10 @@ voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) banshee_polyfill_start(voodoo); break; + case COMMAND_CMD_HOST_TO_SCREEN_BLT: + case COMMAND_CMD_HOST_TO_SCREEN_STRETCH_BLT: + break; + default: if (val & COMMAND_INITIATE) { banshee_do_2d_blit(voodoo, -1, 0); @@ -1779,6 +1791,9 @@ voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) #if 0 bansheeblt_log("launch %08x %08x %08x %08x\n", voodoo->banshee_blt.command, voodoo->banshee_blt.commandExtra, voodoo->banshee_blt.srcColorkeyMin, voodoo->banshee_blt.srcColorkeyMax); #endif + if (voodoo->launch_pending) { + banshee_do_2d_launch(voodoo); + } switch (voodoo->banshee_blt.command & COMMAND_CMD_MASK) { case COMMAND_CMD_SCREEN_TO_SCREEN_BLT: voodoo->banshee_blt.srcXY = val; diff --git a/src/video/vid_voodoo_blitter.c b/src/video/vid_voodoo_blitter.c index 0d2c9e103..856631637 100644 --- a/src/video/vid_voodoo_blitter.c +++ b/src/video/vid_voodoo_blitter.c @@ -218,14 +218,7 @@ skip_pixel_blit: break; case BLIT_COMMAND_CPU_TO_SCREEN: - voodoo->blt.dst_x = voodoo->bltDstX; - voodoo->blt.dst_y = voodoo->bltDstY; - voodoo->blt.cur_x = 0; - voodoo->blt.size_x = size_x; - voodoo->blt.size_y = size_y; - voodoo->blt.x_dir = x_dir; - voodoo->blt.y_dir = y_dir; - voodoo->blt.dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32 * 2) : (voodoo->bltDstXYStride & 0xff8); + voodoo->launch_pending = 1; break; case BLIT_COMMAND_RECT_FILL: @@ -234,7 +227,7 @@ skip_pixel_blit: int dst_x = voodoo->bltDstX; if (SLI_ENABLED) { - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) || ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1))) + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (dst_y & 1)) || ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(dst_y & 1))) goto skip_line_fill; dst = (uint16_t *) &voodoo->fb_mem[dst_base_addr + (dst_y >> 1) * dst_stride]; } else @@ -303,6 +296,18 @@ voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data) if ((voodoo->bltCommand & BLIT_COMMAND_MASK) != BLIT_COMMAND_CPU_TO_SCREEN) return; + if (voodoo->launch_pending) { + voodoo->blt.dst_x = voodoo->bltDstX; + voodoo->blt.dst_y = voodoo->bltDstY; + voodoo->blt.cur_x = 0; + voodoo->blt.size_x = voodoo->bltSizeX; + voodoo->blt.size_y = voodoo->bltSizeY; + voodoo->blt.x_dir = (voodoo->bltSizeX > 0) ? 1 : -1; + voodoo->blt.y_dir = (voodoo->bltSizeY > 0) ? 1 : -1; + voodoo->blt.dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32 * 2) : (voodoo->bltDstXYStride & 0xff8); + voodoo->launch_pending = 0; + } + if (SLI_ENABLED) { addr = base_addr + (voodoo->blt.dst_y >> 1) * voodoo->blt.dst_stride; dst = (uint16_t *) &voodoo->fb_mem[addr];