From 4e80e2fbfce871a92e60ba766bee2bb849d86fdb Mon Sep 17 00:00:00 2001 From: Volker Ruppert Date: Sun, 20 Aug 2017 20:25:45 +0000 Subject: [PATCH] Started preparing the Voodoo code for the PCI FIFO / memory FIFO implementation. - Initialize the thread and event stuff for both Voodoo models. - Rewrite of the event handling code to manage different events. --- bochs/iodev/display/voodoo.cc | 49 ++++++++++++++++-------------- bochs/iodev/display/voodoo_data.h | 50 +++++++++++++++++++++++++++---- bochs/iodev/display/voodoo_func.h | 42 +++++--------------------- 3 files changed, 77 insertions(+), 64 deletions(-) diff --git a/bochs/iodev/display/voodoo.cc b/bochs/iodev/display/voodoo.cc index b4c7d53ef..5dff3c2bc 100644 --- a/bochs/iodev/display/voodoo.cc +++ b/bochs/iodev/display/voodoo.cc @@ -153,19 +153,22 @@ void CDECL libvoodoo_LTX_plugin_fini(void) delete theVoodooDevice; } -// cmdfifo thread (Voodoo2) +// FIFO thread -BX_THREAD_FUNC(cmdfifo_thread, indata) +BX_THREAD_FUNC(fifo_thread, indata) { UNUSED(indata); while (1) { - if (cmdfifo_wait_for_event()) { - while (v->fbi.cmdfifo[0].enable && (v->fbi.cmdfifo[0].depth >= v->fbi.cmdfifo[0].depth_needed)) { - cmdfifo_process(); + if (fifo_wait_for_event(&fifo_wakeup)) { + // TODO: process PCI FIFO / memory FIFO data here + if (v->fbi.cmdfifo[0].enable) { + while (v->fbi.cmdfifo[0].enable && (v->fbi.cmdfifo[0].depth >= v->fbi.cmdfifo[0].depth_needed)) { + cmdfifo_process(); + } + BX_LOCK(cmdfifo_mutex); + v->fbi.cmdfifo[0].cmd_ready = 0; + BX_UNLOCK(cmdfifo_mutex); } - BX_LOCK(cmdfifo_mutex); - v->fbi.cmdfifo[0].cmd_ready = 0; - BX_UNLOCK(cmdfifo_mutex); } } BX_THREAD_EXIT; @@ -183,16 +186,16 @@ bx_voodoo_c::bx_voodoo_c() bx_voodoo_c::~bx_voodoo_c() { + BX_THREAD_KILL(fifo_thread_var); if (BX_VOODOO_THIS s.model == VOODOO_2) { - BX_THREAD_KILL(cmdfifo_thread_var); BX_FINI_MUTEX(cmdfifo_mutex); -#ifdef WIN32 - CloseHandle(v->fbi.cmdfifo[0].event); -#else - pthread_cond_destroy(&v->fbi.cmdfifo[0].cond); - pthread_mutex_destroy(&v->fbi.cmdfifo[0].mutex); -#endif } +#ifdef WIN32 + CloseHandle(fifo_wakeup.event); +#else + pthread_cond_destroy(&fifo_wakeup.cond); + pthread_mutex_destroy(&fifo_wakeup.mutex); +#endif if (v != NULL) { free(v->fbi.ram); free(v->tmu[0].ram); @@ -249,14 +252,14 @@ void bx_voodoo_c::init(void) if (BX_VOODOO_THIS s.model == VOODOO_2) { v->fbi.cmdfifo[0].depth_needed = BX_MAX_BIT32U; BX_INIT_MUTEX(cmdfifo_mutex); -#ifdef WIN32 - v->fbi.cmdfifo[0].event = CreateEvent(NULL, FALSE, FALSE, "cmdfifo_event"); -#else - pthread_cond_init(&v->fbi.cmdfifo[0].cond, NULL); - pthread_mutex_init(&v->fbi.cmdfifo[0].mutex, NULL); -#endif - BX_THREAD_CREATE(cmdfifo_thread, this, cmdfifo_thread_var); } +#ifdef WIN32 + fifo_wakeup.event = CreateEvent(NULL, FALSE, FALSE, "fifo_wakeup"); +#else + pthread_cond_init(&fifo_wakeup.cond, NULL); + pthread_mutex_init(&fifo_wakeup.mutex, NULL); +#endif + BX_THREAD_CREATE(fifo_thread, this, fifo_thread_var); BX_INFO(("3dfx Voodoo Graphics adapter (model=%s) initialized", SIM->get_param_enum("model", base)->get_selected())); @@ -602,7 +605,7 @@ void bx_voodoo_c::vertical_timer_handler(void *this_ptr) BX_VOODOO_THIS s.vdraw.frame_start = bx_virt_timer.time_usec(0); if (v->fbi.cmdfifo[0].cmd_ready) { - cmdfifo_set_event(); + fifo_set_event(&fifo_wakeup); } if (v->fbi.vblank_swap_pending) { diff --git a/bochs/iodev/display/voodoo_data.h b/bochs/iodev/display/voodoo_data.h index 0f849e5a0..9d433213f 100644 --- a/bochs/iodev/display/voodoo_data.h +++ b/bochs/iodev/display/voodoo_data.h @@ -1416,6 +1416,17 @@ struct _stats_block }; +typedef struct +{ +#ifdef WIN32 + HANDLE event; +#else + pthread_cond_t cond; + pthread_mutex_t mutex; +#endif +} fifo_event_t; + + typedef struct _fifo_state fifo_state; struct _fifo_state { @@ -1440,12 +1451,6 @@ struct _cmdfifo_info Bit32u depth_needed; /* depth needed for command */ Bit32u holes; /* number of holes */ bx_bool cmd_ready; -#ifdef WIN32 - HANDLE event; -#else - pthread_cond_t cond; - pthread_mutex_t mutex; -#endif }; @@ -1725,6 +1730,39 @@ struct _voodoo_state }; +// FIFO event handling + +fifo_event_t fifo_wakeup; + + +void fifo_set_event(fifo_event_t *fifo_ev) +{ +#ifdef WIN32 + SetEvent(fifo_ev->event); +#else + pthread_mutex_lock(&fifo_ev->mutex); + pthread_cond_signal(&fifo_ev->cond); + pthread_mutex_unlock(&fifo_ev->mutex); +#endif +} + + +bx_bool fifo_wait_for_event(fifo_event_t *fifo_ev) +{ +#ifdef WIN32 + if (WaitForSingleObject(fifo_ev->event, 1) == WAIT_OBJECT_0) { + return 1; + } else { + return 0; + } +#else + pthread_mutex_lock(&fifo_ev->mutex); + pthread_cond_wait(&fifo_ev->cond, &fifo_ev->mutex); + pthread_mutex_unlock(&fifo_ev->mutex); + return 1; +#endif +} + /************************************* * diff --git a/bochs/iodev/display/voodoo_func.h b/bochs/iodev/display/voodoo_func.h index 188e6d21c..8b17e285a 100644 --- a/bochs/iodev/display/voodoo_func.h +++ b/bochs/iodev/display/voodoo_func.h @@ -60,8 +60,9 @@ Bit32u voodoo_last_msg = 255; #define MODIFY_PIXEL(VV) -/* cmdfifo thread (Voodoo2) */ -BX_THREAD_VAR(cmdfifo_thread_var); +/* fifo thread variable */ +BX_THREAD_VAR(fifo_thread_var); +/* CMDFIFO thread mutex (Voodoo2) */ BX_MUTEX(cmdfifo_mutex); /* fast dither lookup */ @@ -2669,35 +2670,6 @@ void cmdfifo_process(void) } -void cmdfifo_set_event() -{ -#ifdef WIN32 - SetEvent(v->fbi.cmdfifo[0].event); -#else - pthread_mutex_lock(&v->fbi.cmdfifo[0].mutex); - pthread_cond_signal(&v->fbi.cmdfifo[0].cond); - pthread_mutex_unlock(&v->fbi.cmdfifo[0].mutex); -#endif -} - - -bx_bool cmdfifo_wait_for_event() -{ -#ifdef WIN32 - if (WaitForSingleObject(v->fbi.cmdfifo[0].event, 1) == WAIT_OBJECT_0) { - return 1; - } else { - return 0; - } -#else - pthread_mutex_lock(&v->fbi.cmdfifo[0].mutex); - pthread_cond_wait(&v->fbi.cmdfifo[0].cond, &v->fbi.cmdfifo[0].mutex); - pthread_mutex_unlock(&v->fbi.cmdfifo[0].mutex); - return 1; -#endif -} - - void register_w_common(Bit32u offset, Bit32u data) { Bit32u regnum = (offset) & 0xff; @@ -3110,8 +3082,8 @@ Bit32u lfb_r(Bit32u offset) return data; } -void voodoo_w(Bit32u offset, Bit32u data, Bit32u mask) { - +void voodoo_w(Bit32u offset, Bit32u data, Bit32u mask) +{ if ((offset & (0xc00000/4)) == 0) register_w_common(offset, data); else if (offset & (0x800000/4)) @@ -3120,8 +3092,8 @@ void voodoo_w(Bit32u offset, Bit32u data, Bit32u mask) { lfb_w(offset, data, mask); } -Bit32u voodoo_r(Bit32u offset) { - +Bit32u voodoo_r(Bit32u offset) +{ if (!(offset & (0xc00000/4))) return register_r(offset); else