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.
This commit is contained in:
Volker Ruppert 2017-08-20 20:25:45 +00:00
parent e187f3907a
commit 4e80e2fbfc
3 changed files with 77 additions and 64 deletions

View File

@ -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) {

View File

@ -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
}
/*************************************
*

View File

@ -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