Add option for Voodoo to use 4 render threads.

This commit is contained in:
SarahW 2020-10-05 19:34:20 +01:00
commit 52a79fbb57
7 changed files with 185 additions and 93 deletions

View file

@ -820,35 +820,38 @@ static void voodoo_add_status_info(char *s, int max_len, void *p)
voodoo_t *voodoo = voodoo_set->voodoos[0]; voodoo_t *voodoo = voodoo_set->voodoos[0];
voodoo_t *voodoo_slave = voodoo_set->voodoos[1]; voodoo_t *voodoo_slave = voodoo_set->voodoos[1];
char temps[512], temps2[256]; char temps[512], temps2[256];
int pixel_count_current[2]; int pixel_count_current[4];
int pixel_count_total; int pixel_count_total;
int texel_count_current[2]; int texel_count_current[4];
int texel_count_total; int texel_count_total;
int render_time[2]; int render_time[4];
uint64_t new_time = timer_read(); uint64_t new_time = timer_read();
uint64_t status_diff = new_time - status_time; uint64_t status_diff = new_time - status_time;
status_time = new_time; status_time = new_time;
int c;
if (!status_diff) if (!status_diff)
status_diff = 1; status_diff = 1;
pixel_count_current[0] = voodoo->pixel_count[0]; for (c = 0; c < 4; c++)
pixel_count_current[1] = voodoo->pixel_count[1]; {
texel_count_current[0] = voodoo->texel_count[0]; pixel_count_current[c] = voodoo->pixel_count[c];
texel_count_current[1] = voodoo->texel_count[1]; texel_count_current[c] = voodoo->texel_count[c];
render_time[0] = voodoo->render_time[0]; render_time[c] = voodoo->render_time[c];
render_time[1] = voodoo->render_time[1]; }
if (voodoo_set->nr_cards == 2) if (voodoo_set->nr_cards == 2)
{ {
pixel_count_current[0] += voodoo_slave->pixel_count[0]; for (c = 0; c < 4; c++)
pixel_count_current[1] += voodoo_slave->pixel_count[1]; {
texel_count_current[0] += voodoo_slave->texel_count[0]; pixel_count_current[c] += voodoo_slave->pixel_count[c];
texel_count_current[1] += voodoo_slave->texel_count[1]; texel_count_current[c] += voodoo_slave->texel_count[c];
render_time[0] = (render_time[0] + voodoo_slave->render_time[0]) / 2; render_time[c] = (render_time[c] + voodoo_slave->render_time[c]) / 2;
render_time[1] = (render_time[1] + voodoo_slave->render_time[1]) / 2; }
} }
pixel_count_total = (pixel_count_current[0] + pixel_count_current[1]) - (voodoo->pixel_count_old[0] + voodoo->pixel_count_old[1]); pixel_count_total = (pixel_count_current[0] + pixel_count_current[1] + pixel_count_current[2] + pixel_count_current[3]) -
texel_count_total = (texel_count_current[0] + texel_count_current[1]) - (voodoo->texel_count_old[0] + voodoo->texel_count_old[1]); (voodoo->pixel_count_old[0] + voodoo->pixel_count_old[1] + voodoo->pixel_count_old[2] + voodoo->pixel_count_old[3]);
texel_count_total = (texel_count_current[0] + texel_count_current[1] + texel_count_current[2] + texel_count_current[3]) -
(voodoo->texel_count_old[0] + voodoo->texel_count_old[1] + voodoo->texel_count_old[2] + voodoo->texel_count_old[3]);
sprintf(temps, "%f Mpixels/sec (%f)\n%f Mtexels/sec (%f)\n%f ktris/sec\n%f%% CPU (%f%% real)\n%d frames/sec (%i)\n%f%% CPU (%f%% real)\n"/*%d reads/sec\n%d write/sec\n%d tex/sec\n*/, sprintf(temps, "%f Mpixels/sec (%f)\n%f Mtexels/sec (%f)\n%f ktris/sec\n%f%% CPU (%f%% real)\n%d frames/sec (%i)\n%f%% CPU (%f%% real)\n"/*%d reads/sec\n%d write/sec\n%d tex/sec\n*/,
(double)pixel_count_total/1000000.0, (double)pixel_count_total/1000000.0,
((double)pixel_count_total/1000000.0) / ((double)render_time[0] / status_diff), ((double)pixel_count_total/1000000.0) / ((double)render_time[0] / status_diff),
@ -856,45 +859,61 @@ static void voodoo_add_status_info(char *s, int max_len, void *p)
((double)texel_count_total/1000000.0) / ((double)render_time[0] / status_diff), ((double)texel_count_total/1000000.0) / ((double)render_time[0] / status_diff),
(double)voodoo->tri_count/1000.0, ((double)voodoo->time * 100.0) / timer_freq, ((double)voodoo->time * 100.0) / status_diff, voodoo->frame_count, voodoo_recomp, (double)voodoo->tri_count/1000.0, ((double)voodoo->time * 100.0) / timer_freq, ((double)voodoo->time * 100.0) / status_diff, voodoo->frame_count, voodoo_recomp,
((double)voodoo->render_time[0] * 100.0) / timer_freq, ((double)voodoo->render_time[0] * 100.0) / status_diff); ((double)voodoo->render_time[0] * 100.0) / timer_freq, ((double)voodoo->render_time[0] * 100.0) / status_diff);
if (voodoo->render_threads == 2) if (voodoo->render_threads >= 2)
{ {
sprintf(temps2, "%f%% CPU (%f%% real)\n", sprintf(temps2, "%f%% CPU (%f%% real)\n",
((double)voodoo->render_time[1] * 100.0) / timer_freq, ((double)voodoo->render_time[1] * 100.0) / status_diff); ((double)voodoo->render_time[1] * 100.0) / timer_freq, ((double)voodoo->render_time[1] * 100.0) / status_diff);
strncat(temps, temps2, sizeof(temps)-1); strncat(temps, temps2, sizeof(temps)-1);
} }
if (voodoo->render_threads == 4)
{
sprintf(temps2, "%f%% CPU (%f%% real)\n%f%% CPU (%f%% real)\n",
((double)voodoo->render_time[2] * 100.0) / timer_freq, ((double)voodoo->render_time[2] * 100.0) / status_diff,
((double)voodoo->render_time[3] * 100.0) / timer_freq, ((double)voodoo->render_time[3] * 100.0) / status_diff);
strncat(temps, temps2, sizeof(temps)-1);
}
if (voodoo_set->nr_cards == 2) if (voodoo_set->nr_cards == 2)
{ {
sprintf(temps2, "%f%% CPU (%f%% real)\n", sprintf(temps2, "%f%% CPU (%f%% real)\n",
((double)voodoo_slave->render_time[0] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[0] * 100.0) / status_diff); ((double)voodoo_slave->render_time[0] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[0] * 100.0) / status_diff);
strncat(temps, temps2, sizeof(temps)-1); strncat(temps, temps2, sizeof(temps)-1);
if (voodoo_slave->render_threads == 2) if (voodoo_slave->render_threads >= 2)
{ {
sprintf(temps2, "%f%% CPU (%f%% real)\n", sprintf(temps2, "%f%% CPU (%f%% real)\n",
((double)voodoo_slave->render_time[1] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[1] * 100.0) / status_diff); ((double)voodoo_slave->render_time[1] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[1] * 100.0) / status_diff);
strncat(temps, temps2, sizeof(temps)-1); strncat(temps, temps2, sizeof(temps)-1);
} }
if (voodoo_slave->render_threads == 4)
{
sprintf(temps2, "%f%% CPU (%f%% real)\n%f%% CPU (%f%% real)\n",
((double)voodoo_slave->render_time[2] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[2] * 100.0) / status_diff,
((double)voodoo_slave->render_time[3] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[3] * 100.0) / status_diff);
strncat(temps, temps2, sizeof(temps)-1);
}
} }
strncat(s, temps, max_len); strncat(s, temps, max_len);
voodoo->pixel_count_old[0] = pixel_count_current[0]; for (c = 0; c < 4; c++)
voodoo->pixel_count_old[1] = pixel_count_current[1]; {
voodoo->texel_count_old[0] = texel_count_current[0]; voodoo->pixel_count_old[c] = pixel_count_current[c];
voodoo->texel_count_old[1] = texel_count_current[1]; voodoo->texel_count_old[c] = texel_count_current[c];
voodoo->render_time[c] = 0;
}
voodoo->tri_count = voodoo->frame_count = 0; voodoo->tri_count = voodoo->frame_count = 0;
voodoo->rd_count = voodoo->wr_count = voodoo->tex_count = 0; voodoo->rd_count = voodoo->wr_count = voodoo->tex_count = 0;
voodoo->time = 0; voodoo->time = 0;
voodoo->render_time[0] = voodoo->render_time[1] = 0;
if (voodoo_set->nr_cards == 2) if (voodoo_set->nr_cards == 2)
{ {
voodoo_slave->pixel_count_old[0] = pixel_count_current[0]; for (c = 0; c < 4; c++)
voodoo_slave->pixel_count_old[1] = pixel_count_current[1]; {
voodoo_slave->texel_count_old[0] = texel_count_current[0]; voodoo_slave->pixel_count_old[c] = pixel_count_current[c];
voodoo_slave->texel_count_old[1] = texel_count_current[1]; voodoo_slave->texel_count_old[c] = texel_count_current[c];
voodoo_slave->render_time[c] = 0;
}
voodoo_slave->tri_count = voodoo_slave->frame_count = 0; voodoo_slave->tri_count = voodoo_slave->frame_count = 0;
voodoo_slave->rd_count = voodoo_slave->wr_count = voodoo_slave->tex_count = 0; voodoo_slave->rd_count = voodoo_slave->wr_count = voodoo_slave->tex_count = 0;
voodoo_slave->time = 0; voodoo_slave->time = 0;
voodoo_slave->render_time[0] = voodoo_slave->render_time[1] = 0;
} }
voodoo_recomp = 0; voodoo_recomp = 0;
} }
@ -985,15 +1004,23 @@ void *voodoo_card_init()
voodoo->wake_fifo_thread = thread_create_event(); voodoo->wake_fifo_thread = thread_create_event();
voodoo->wake_render_thread[0] = thread_create_event(); voodoo->wake_render_thread[0] = thread_create_event();
voodoo->wake_render_thread[1] = thread_create_event(); voodoo->wake_render_thread[1] = thread_create_event();
voodoo->wake_render_thread[2] = thread_create_event();
voodoo->wake_render_thread[3] = thread_create_event();
voodoo->wake_main_thread = thread_create_event(); voodoo->wake_main_thread = thread_create_event();
voodoo->fifo_not_full_event = thread_create_event(); voodoo->fifo_not_full_event = thread_create_event();
voodoo->render_not_full_event[0] = thread_create_event(); voodoo->render_not_full_event[0] = thread_create_event();
voodoo->render_not_full_event[1] = thread_create_event(); voodoo->render_not_full_event[1] = thread_create_event();
voodoo->render_not_full_event[2] = thread_create_event();
voodoo->render_not_full_event[3] = thread_create_event();
voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo); voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo);
voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo); voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo);
if (voodoo->render_threads == 2) if (voodoo->render_threads >= 2)
voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo); voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo);
if (voodoo->render_threads == 4)
{
voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo);
voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo);
}
timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0); timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0);
for (c = 0; c < 0x100; c++) for (c = 0; c < 0x100; c++)
@ -1093,14 +1120,23 @@ void *voodoo_2d3d_card_init(int type)
voodoo->wake_fifo_thread = thread_create_event(); voodoo->wake_fifo_thread = thread_create_event();
voodoo->wake_render_thread[0] = thread_create_event(); voodoo->wake_render_thread[0] = thread_create_event();
voodoo->wake_render_thread[1] = thread_create_event(); voodoo->wake_render_thread[1] = thread_create_event();
voodoo->wake_render_thread[2] = thread_create_event();
voodoo->wake_render_thread[3] = thread_create_event();
voodoo->wake_main_thread = thread_create_event(); voodoo->wake_main_thread = thread_create_event();
voodoo->fifo_not_full_event = thread_create_event(); voodoo->fifo_not_full_event = thread_create_event();
voodoo->render_not_full_event[0] = thread_create_event(); voodoo->render_not_full_event[0] = thread_create_event();
voodoo->render_not_full_event[1] = thread_create_event(); voodoo->render_not_full_event[1] = thread_create_event();
voodoo->render_not_full_event[2] = thread_create_event();
voodoo->render_not_full_event[3] = thread_create_event();
voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo); voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo);
voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo); voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo);
if (voodoo->render_threads == 2) if (voodoo->render_threads >= 2)
voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo); voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo);
if (voodoo->render_threads == 4)
{
voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo);
voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo);
}
timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0); timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0);
@ -1244,8 +1280,13 @@ void voodoo_card_close(voodoo_t *voodoo)
thread_kill(voodoo->fifo_thread); thread_kill(voodoo->fifo_thread);
thread_kill(voodoo->render_thread[0]); thread_kill(voodoo->render_thread[0]);
if (voodoo->render_threads == 2) if (voodoo->render_threads >= 2)
thread_kill(voodoo->render_thread[1]); thread_kill(voodoo->render_thread[1]);
if (voodoo->render_threads == 4)
{
thread_kill(voodoo->render_thread[2]);
thread_kill(voodoo->render_thread[3]);
}
thread_destroy_event(voodoo->fifo_not_full_event); thread_destroy_event(voodoo->fifo_not_full_event);
thread_destroy_event(voodoo->wake_main_thread); thread_destroy_event(voodoo->wake_main_thread);
thread_destroy_event(voodoo->wake_fifo_thread); thread_destroy_event(voodoo->wake_fifo_thread);
@ -1376,6 +1417,10 @@ static device_config_t voodoo_config[] =
.description = "2", .description = "2",
.value = 2 .value = 2
}, },
{
.description = "4",
.value = 4
},
{ {
.description = "" .description = ""
} }

View file

@ -1998,6 +1998,10 @@ static device_config_t banshee_sgram_config[] =
.description = "2", .description = "2",
.value = 2 .value = 2
}, },
{
.description = "4",
.value = 4
},
{ {
.description = "" .description = ""
} }
@ -2039,6 +2043,10 @@ static device_config_t banshee_sdram_config[] =
.description = "2", .description = "2",
.value = 2 .value = 2
}, },
{
.description = "4",
.value = 4
},
{ {
.description = "" .description = ""
} }
@ -2182,27 +2190,30 @@ static void banshee_add_status_info(char *s, int max_len, void *p)
banshee_t *banshee = (banshee_t *)p; banshee_t *banshee = (banshee_t *)p;
voodoo_t *voodoo = banshee->voodoo; voodoo_t *voodoo = banshee->voodoo;
char temps[512]; char temps[512];
int pixel_count_current[2]; int pixel_count_current[4];
int pixel_count_total; int pixel_count_total;
int texel_count_current[2]; int texel_count_current[4];
int texel_count_total; int texel_count_total;
int render_time[2]; int render_time[4];
uint64_t new_time = timer_read(); uint64_t new_time = timer_read();
uint64_t status_diff = new_time - status_time; uint64_t status_diff = new_time - status_time;
int c;
status_time = new_time; status_time = new_time;
svga_add_status_info(s, max_len, &banshee->svga); svga_add_status_info(s, max_len, &banshee->svga);
pixel_count_current[0] = voodoo->pixel_count[0]; for (c = 0; c < 4; c++)
pixel_count_current[1] = voodoo->pixel_count[1]; {
texel_count_current[0] = voodoo->texel_count[0]; pixel_count_current[c] = voodoo->pixel_count[c];
texel_count_current[1] = voodoo->texel_count[1]; texel_count_current[c] = voodoo->texel_count[c];
render_time[0] = voodoo->render_time[0]; render_time[c] = voodoo->render_time[c];
render_time[1] = voodoo->render_time[1]; }
pixel_count_total = (pixel_count_current[0] + pixel_count_current[1]) - (voodoo->pixel_count_old[0] + voodoo->pixel_count_old[1]); pixel_count_total = (pixel_count_current[0] + pixel_count_current[1] + pixel_count_current[2] + pixel_count_current[3]) -
texel_count_total = (texel_count_current[0] + texel_count_current[1]) - (voodoo->texel_count_old[0] + voodoo->texel_count_old[1]); (voodoo->pixel_count_old[0] + voodoo->pixel_count_old[1] + voodoo->pixel_count_old[2] + voodoo->pixel_count_old[3]);
texel_count_total = (texel_count_current[0] + texel_count_current[1] + texel_count_current[2] + texel_count_current[3]) -
(voodoo->texel_count_old[0] + voodoo->texel_count_old[1] + voodoo->texel_count_old[2] + voodoo->texel_count_old[3]);
sprintf(temps, "%f Mpixels/sec (%f)\n%f Mtexels/sec (%f)\n%f ktris/sec\n%f%% CPU (%f%% real)\n%d frames/sec (%i)\n%f%% CPU (%f%% real)\n"/*%d reads/sec\n%d write/sec\n%d tex/sec\n*/, sprintf(temps, "%f Mpixels/sec (%f)\n%f Mtexels/sec (%f)\n%f ktris/sec\n%f%% CPU (%f%% real)\n%d frames/sec (%i)\n%f%% CPU (%f%% real)\n"/*%d reads/sec\n%d write/sec\n%d tex/sec\n*/,
(double)pixel_count_total/1000000.0, (double)pixel_count_total/1000000.0,
((double)pixel_count_total/1000000.0) / ((double)render_time[0] / status_diff), ((double)pixel_count_total/1000000.0) / ((double)render_time[0] / status_diff),
@ -2210,25 +2221,35 @@ static void banshee_add_status_info(char *s, int max_len, void *p)
((double)texel_count_total/1000000.0) / ((double)render_time[0] / status_diff), ((double)texel_count_total/1000000.0) / ((double)render_time[0] / status_diff),
(double)voodoo->tri_count/1000.0, ((double)voodoo->time * 100.0) / timer_freq, ((double)voodoo->time * 100.0) / status_diff, voodoo->frame_count, voodoo_recomp, (double)voodoo->tri_count/1000.0, ((double)voodoo->time * 100.0) / timer_freq, ((double)voodoo->time * 100.0) / status_diff, voodoo->frame_count, voodoo_recomp,
((double)voodoo->render_time[0] * 100.0) / timer_freq, ((double)voodoo->render_time[0] * 100.0) / status_diff); ((double)voodoo->render_time[0] * 100.0) / timer_freq, ((double)voodoo->render_time[0] * 100.0) / status_diff);
if (voodoo->render_threads == 2) if (voodoo->render_threads >= 2)
{ {
char temps2[512]; char temps2[512];
sprintf(temps2, "%f%% CPU (%f%% real)\n", sprintf(temps2, "%f%% CPU (%f%% real)\n",
((double)voodoo->render_time[1] * 100.0) / timer_freq, ((double)voodoo->render_time[1] * 100.0) / status_diff); ((double)voodoo->render_time[1] * 100.0) / timer_freq, ((double)voodoo->render_time[1] * 100.0) / status_diff);
strncat(temps, temps2, sizeof(temps)-1); strncat(temps, temps2, sizeof(temps)-1);
} }
if (voodoo->render_threads == 4)
{
char temps2[512];
sprintf(temps2, "%f%% CPU (%f%% real)\n%f%% CPU (%f%% real)\n",
((double)voodoo->render_time[2] * 100.0) / timer_freq, ((double)voodoo->render_time[2] * 100.0) / status_diff,
((double)voodoo->render_time[3] * 100.0) / timer_freq, ((double)voodoo->render_time[3] * 100.0) / status_diff);
strncat(temps, temps2, sizeof(temps)-1);
}
strncat(s, temps, max_len); strncat(s, temps, max_len);
strncat(s, "\n", max_len); strncat(s, "\n", max_len);
voodoo->pixel_count_old[0] = pixel_count_current[0]; for (c = 0; c < 4; c++)
voodoo->pixel_count_old[1] = pixel_count_current[1]; {
voodoo->texel_count_old[0] = texel_count_current[0]; voodoo->pixel_count_old[c] = pixel_count_current[c];
voodoo->texel_count_old[1] = texel_count_current[1]; voodoo->texel_count_old[c] = texel_count_current[c];
voodoo->render_time[c] = 0;
}
voodoo->tri_count = voodoo->frame_count = 0; voodoo->tri_count = voodoo->frame_count = 0;
voodoo->rd_count = voodoo->wr_count = voodoo->tex_count = 0; voodoo->rd_count = voodoo->wr_count = voodoo->tex_count = 0;
voodoo->time = 0; voodoo->time = 0;
voodoo->render_time[0] = voodoo->render_time[1] = 0;
voodoo->read_time = pci_nonburst_time + pci_burst_time; voodoo->read_time = pci_nonburst_time + pci_burst_time;

View file

@ -38,8 +38,8 @@ typedef struct voodoo_x86_data_t
//static voodoo_x86_data_t voodoo_x86_data[2][BLOCK_NUM]; //static voodoo_x86_data_t voodoo_x86_data[2][BLOCK_NUM];
static int last_block[2] = {0, 0}; static int last_block[4] = {0, 0};
static int next_block_to_write[2] = {0, 0}; static int next_block_to_write[4] = {0, 0};
#define addbyte(val) \ #define addbyte(val) \
do { \ do { \
@ -3346,7 +3346,7 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params,
for (c = 0; c < 8; c++) for (c = 0; c < 8; c++)
{ {
data = &voodoo_x86_data[odd_even + c*2]; //&voodoo_x86_data[odd_even][b]; data = &voodoo_x86_data[odd_even + c*4]; //&voodoo_x86_data[odd_even][b];
if (state->xdir == data->xdir && if (state->xdir == data->xdir &&
params->alphaMode == data->alphaMode && params->alphaMode == data->alphaMode &&
@ -3366,7 +3366,7 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params,
b = (b + 1) & 7; b = (b + 1) & 7;
} }
voodoo_recomp++; voodoo_recomp++;
data = &voodoo_x86_data[odd_even + next_block_to_write[odd_even]*2]; data = &voodoo_x86_data[odd_even + next_block_to_write[odd_even]*4];
// code_block = data->code_block; // code_block = data->code_block;
voodoo_generate(data->code_block, voodoo, params, state, depth_op); voodoo_generate(data->code_block, voodoo, params, state, depth_op);
@ -3392,9 +3392,9 @@ void voodoo_codegen_init(voodoo_t *voodoo)
int c; int c;
#if WIN64 #if WIN64
voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM * 2, MEM_COMMIT, PAGE_EXECUTE_READWRITE); voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM * 4, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#else #else
voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0);
#endif #endif
for (c = 0; c < 256; c++) for (c = 0; c < 256; c++)
@ -3424,7 +3424,7 @@ void voodoo_codegen_close(voodoo_t *voodoo)
#if WIN64 #if WIN64
VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE); VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE);
#else #else
munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2); munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4);
#endif #endif
} }

View file

@ -36,8 +36,8 @@ typedef struct voodoo_x86_data_t
uint32_t trexInit1; uint32_t trexInit1;
} voodoo_x86_data_t; } voodoo_x86_data_t;
static int last_block[2] = {0, 0}; static int last_block[4] = {0, 0};
static int next_block_to_write[2] = {0, 0}; static int next_block_to_write[4] = {0, 0};
#define addbyte(val) \ #define addbyte(val) \
do { \ do { \
@ -3286,7 +3286,7 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params,
for (c = 0; c < 8; c++) for (c = 0; c < 8; c++)
{ {
data = &codegen_data[odd_even + b*2]; data = &codegen_data[odd_even + b*4];
if (state->xdir == data->xdir && if (state->xdir == data->xdir &&
params->alphaMode == data->alphaMode && params->alphaMode == data->alphaMode &&
@ -3306,7 +3306,7 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params,
b = (b + 1) & 7; b = (b + 1) & 7;
} }
voodoo_recomp++; voodoo_recomp++;
data = &codegen_data[odd_even + next_block_to_write[odd_even]*2]; data = &codegen_data[odd_even + next_block_to_write[odd_even]*4];
// code_block = data->code_block; // code_block = data->code_block;
voodoo_generate(data->code_block, voodoo, params, state, depth_op); voodoo_generate(data->code_block, voodoo, params, state, depth_op);
@ -3338,9 +3338,9 @@ void voodoo_codegen_init(voodoo_t *voodoo)
#endif #endif
#if defined WIN32 || defined _WIN32 || defined _WIN32 #if defined WIN32 || defined _WIN32 || defined _WIN32
voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2, MEM_COMMIT, PAGE_EXECUTE_READWRITE); voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#else #else
voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0);
#endif #endif
for (c = 0; c < 256; c++) for (c = 0; c < 256; c++)
@ -3370,6 +3370,6 @@ void voodoo_codegen_close(voodoo_t *voodoo)
#if defined WIN32 || defined _WIN32 || defined _WIN32 #if defined WIN32 || defined _WIN32 || defined _WIN32
VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE); VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE);
#else #else
munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2); munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4);
#endif #endif
} }

View file

@ -75,12 +75,9 @@ enum
#define PARAM_MASK (PARAM_SIZE - 1) #define PARAM_MASK (PARAM_SIZE - 1)
#define PARAM_ENTRY_SIZE (1 << 31) #define PARAM_ENTRY_SIZE (1 << 31)
#define PARAM_ENTRIES_1 (voodoo->params_write_idx - voodoo->params_read_idx[0]) #define PARAM_ENTRIES(x) (voodoo->params_write_idx - voodoo->params_read_idx[x])
#define PARAM_ENTRIES_2 (voodoo->params_write_idx - voodoo->params_read_idx[1]) #define PARAM_FULL(x) ((voodoo->params_write_idx - voodoo->params_read_idx[x]) >= PARAM_SIZE)
#define PARAM_FULL_1 ((voodoo->params_write_idx - voodoo->params_read_idx[0]) >= PARAM_SIZE) #define PARAM_EMPTY(x) (voodoo->params_read_idx[x] == voodoo->params_write_idx)
#define PARAM_FULL_2 ((voodoo->params_write_idx - voodoo->params_read_idx[1]) >= PARAM_SIZE)
#define PARAM_EMPTY_1 (voodoo->params_read_idx[0] == voodoo->params_write_idx)
#define PARAM_EMPTY_2 (voodoo->params_read_idx[1] == voodoo->params_write_idx)
typedef struct typedef struct
{ {
@ -164,7 +161,7 @@ typedef struct texture_t
{ {
uint32_t base; uint32_t base;
uint32_t tLOD; uint32_t tLOD;
volatile int refcount, refcount_r[2]; volatile int refcount, refcount_r[4];
int is16; int is16;
uint32_t palette_checksum; uint32_t palette_checksum;
uint32_t addr_start[4], addr_end[4]; uint32_t addr_start[4], addr_end[4];
@ -258,21 +255,21 @@ typedef struct voodoo_t
int ncc_dirty[2]; int ncc_dirty[2];
thread_t *fifo_thread; thread_t *fifo_thread;
thread_t *render_thread[2]; thread_t *render_thread[4];
event_t *wake_fifo_thread; event_t *wake_fifo_thread;
event_t *wake_main_thread; event_t *wake_main_thread;
event_t *fifo_not_full_event; event_t *fifo_not_full_event;
event_t *render_not_full_event[2]; event_t *render_not_full_event[4];
event_t *wake_render_thread[2]; event_t *wake_render_thread[4];
int voodoo_busy; int voodoo_busy;
int render_voodoo_busy[2]; int render_voodoo_busy[4];
int render_threads; int render_threads;
int odd_even_mask; int odd_even_mask;
int pixel_count[2], texel_count[2], tri_count, frame_count; int pixel_count[4], texel_count[4], tri_count, frame_count;
int pixel_count_old[2], texel_count_old[2]; int pixel_count_old[4], texel_count_old[4];
int wr_count, rd_count, tex_count; int wr_count, rd_count, tex_count;
int retrace_count; int retrace_count;
@ -296,7 +293,7 @@ typedef struct voodoo_t
volatile int cmd_read, cmd_written, cmd_written_fifo; volatile int cmd_read, cmd_written, cmd_written_fifo;
voodoo_params_t params_buffer[PARAM_SIZE]; voodoo_params_t params_buffer[PARAM_SIZE];
volatile int params_read_idx[2], params_write_idx; volatile int params_read_idx[4], params_write_idx;
uint32_t cmdfifo_base, cmdfifo_end, cmdfifo_size; uint32_t cmdfifo_base, cmdfifo_end, cmdfifo_size;
int cmdfifo_rp; int cmdfifo_rp;
@ -466,7 +463,7 @@ typedef struct voodoo_t
int palette_dirty[2]; int palette_dirty[2];
uint64_t time; uint64_t time;
int render_time[2]; int render_time[4];
int use_recompiler; int use_recompiler;
void *codegen_data; void *codegen_data;

View file

@ -1562,7 +1562,7 @@ static void render_thread(void *param, int odd_even)
thread_reset_event(voodoo->wake_render_thread[odd_even]); thread_reset_event(voodoo->wake_render_thread[odd_even]);
voodoo->render_voodoo_busy[odd_even] = 1; voodoo->render_voodoo_busy[odd_even] = 1;
while (!(odd_even ? PARAM_EMPTY_2 : PARAM_EMPTY_1)) while (!PARAM_EMPTY(odd_even))
{ {
uint64_t start_time = timer_read(); uint64_t start_time = timer_read();
uint64_t end_time; uint64_t end_time;
@ -1572,7 +1572,7 @@ static void render_thread(void *param, int odd_even)
voodoo->params_read_idx[odd_even]++; voodoo->params_read_idx[odd_even]++;
if ((odd_even ? PARAM_ENTRIES_2 : PARAM_ENTRIES_1) > (PARAM_SIZE - 10)) if (PARAM_ENTRIES(odd_even) > (PARAM_SIZE - 10))
thread_set_event(voodoo->render_not_full_event[odd_even]); thread_set_event(voodoo->render_not_full_event[odd_even]);
end_time = timer_read(); end_time = timer_read();
@ -1591,24 +1591,38 @@ void voodoo_render_thread_2(void *param)
{ {
render_thread(param, 1); render_thread(param, 1);
} }
void voodoo_render_thread_3(void *param)
{
render_thread(param, 2);
}
void voodoo_render_thread_4(void *param)
{
render_thread(param, 3);
}
void voodoo_queue_triangle(voodoo_t *voodoo, voodoo_params_t *params) void voodoo_queue_triangle(voodoo_t *voodoo, voodoo_params_t *params)
{ {
voodoo_params_t *params_new = &voodoo->params_buffer[voodoo->params_write_idx & PARAM_MASK]; voodoo_params_t *params_new = &voodoo->params_buffer[voodoo->params_write_idx & PARAM_MASK];
while (PARAM_FULL_1 || (voodoo->render_threads == 2 && PARAM_FULL_2)) while (PARAM_FULL(0) || (voodoo->render_threads >= 2 && PARAM_FULL(1)) ||
(voodoo->render_threads == 4 && (PARAM_FULL(2) || PARAM_FULL(3))))
{ {
thread_reset_event(voodoo->render_not_full_event[0]); thread_reset_event(voodoo->render_not_full_event[0]);
if (voodoo->render_threads == 2) if (voodoo->render_threads >= 2)
thread_reset_event(voodoo->render_not_full_event[1]); thread_reset_event(voodoo->render_not_full_event[1]);
if (PARAM_FULL_1) if (voodoo->render_threads == 4)
{ {
thread_reset_event(voodoo->render_not_full_event[2]);
thread_reset_event(voodoo->render_not_full_event[3]);
}
if (PARAM_FULL(0))
thread_wait_event(voodoo->render_not_full_event[0], -1); /*Wait for room in ringbuffer*/ thread_wait_event(voodoo->render_not_full_event[0], -1); /*Wait for room in ringbuffer*/
} if (voodoo->render_threads >= 2 && PARAM_FULL(1))
if (voodoo->render_threads == 2 && PARAM_FULL_2)
{
thread_wait_event(voodoo->render_not_full_event[1], -1); /*Wait for room in ringbuffer*/ thread_wait_event(voodoo->render_not_full_event[1], -1); /*Wait for room in ringbuffer*/
} if (voodoo->render_threads == 4 && PARAM_FULL(2))
thread_wait_event(voodoo->render_not_full_event[2], -1); /*Wait for room in ringbuffer*/
if (voodoo->render_threads == 4 && PARAM_FULL(3))
thread_wait_event(voodoo->render_not_full_event[3], -1); /*Wait for room in ringbuffer*/
} }
voodoo_use_texture(voodoo, params, 0); voodoo_use_texture(voodoo, params, 0);
@ -1619,6 +1633,7 @@ void voodoo_queue_triangle(voodoo_t *voodoo, voodoo_params_t *params)
voodoo->params_write_idx++; voodoo->params_write_idx++;
if (PARAM_ENTRIES_1 < 4 || (voodoo->render_threads == 2 && PARAM_ENTRIES_2 < 4)) if (PARAM_ENTRIES(0) < 4 || (voodoo->render_threads >= 2 && PARAM_ENTRIES(1) < 4) ||
(voodoo->render_threads == 4 && (PARAM_ENTRIES(2) < 4 || PARAM_ENTRIES(3) < 4)))
voodoo_wake_render_thread(voodoo); voodoo_wake_render_thread(voodoo);
} }

View file

@ -299,6 +299,8 @@ void voodoo_codegen_close(voodoo_t *voodoo);
void voodoo_render_thread_1(void *param); void voodoo_render_thread_1(void *param);
void voodoo_render_thread_2(void *param); void voodoo_render_thread_2(void *param);
void voodoo_render_thread_3(void *param);
void voodoo_render_thread_4(void *param);
void voodoo_queue_triangle(voodoo_t *voodoo, voodoo_params_t *params); void voodoo_queue_triangle(voodoo_t *voodoo, voodoo_params_t *params);
extern int voodoo_recomp; extern int voodoo_recomp;
@ -307,18 +309,30 @@ extern int tris;
static inline void voodoo_wake_render_thread(voodoo_t *voodoo) static inline void voodoo_wake_render_thread(voodoo_t *voodoo)
{ {
thread_set_event(voodoo->wake_render_thread[0]); /*Wake up render thread if moving from idle*/ thread_set_event(voodoo->wake_render_thread[0]); /*Wake up render thread if moving from idle*/
if (voodoo->render_threads == 2) if (voodoo->render_threads >= 2)
thread_set_event(voodoo->wake_render_thread[1]); /*Wake up render thread if moving from idle*/ thread_set_event(voodoo->wake_render_thread[1]); /*Wake up render thread if moving from idle*/
if (voodoo->render_threads == 4)
{
thread_set_event(voodoo->wake_render_thread[2]); /*Wake up render thread if moving from idle*/
thread_set_event(voodoo->wake_render_thread[3]); /*Wake up render thread if moving from idle*/
}
} }
static inline void voodoo_wait_for_render_thread_idle(voodoo_t *voodoo) static inline void voodoo_wait_for_render_thread_idle(voodoo_t *voodoo)
{ {
while (!PARAM_EMPTY_1 || (voodoo->render_threads == 2 && !PARAM_EMPTY_2) || voodoo->render_voodoo_busy[0] || (voodoo->render_threads == 2 && voodoo->render_voodoo_busy[1])) while (!PARAM_EMPTY(0) || (voodoo->render_threads >= 2 && !PARAM_EMPTY(1)) ||
(voodoo->render_threads == 4 && (!PARAM_EMPTY(2) || !PARAM_EMPTY(3))) ||
voodoo->render_voodoo_busy[0] || (voodoo->render_threads >= 2 && voodoo->render_voodoo_busy[1]) ||
(voodoo->render_threads == 4 && (voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3])))
{ {
voodoo_wake_render_thread(voodoo); voodoo_wake_render_thread(voodoo);
if (!PARAM_EMPTY_1 || voodoo->render_voodoo_busy[0]) if (!PARAM_EMPTY(0) || voodoo->render_voodoo_busy[0])
thread_wait_event(voodoo->render_not_full_event[0], 1); thread_wait_event(voodoo->render_not_full_event[0], 1);
if (voodoo->render_threads == 2 && (!PARAM_EMPTY_2 || voodoo->render_voodoo_busy[1])) if (voodoo->render_threads >= 2 && (!PARAM_EMPTY(1) || voodoo->render_voodoo_busy[1]))
thread_wait_event(voodoo->render_not_full_event[1], 1); thread_wait_event(voodoo->render_not_full_event[1], 1);
if (voodoo->render_threads == 4 && (!PARAM_EMPTY(2) || voodoo->render_voodoo_busy[2]))
thread_wait_event(voodoo->render_not_full_event[2], 1);
if (voodoo->render_threads == 4 && (!PARAM_EMPTY(3) || voodoo->render_voodoo_busy[3]))
thread_wait_event(voodoo->render_not_full_event[3], 1);
} }
} }