From 52a79fbb57a00b68b16492e5df3f62a8dda6ae0f Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 5 Oct 2020 19:34:20 +0100 Subject: [PATCH] Add option for Voodoo to use 4 render threads. --- src/vid_voodoo.c | 111 ++++++++++++++++++++++---------- src/vid_voodoo_banshee.c | 55 +++++++++++----- src/vid_voodoo_codegen_x86-64.h | 14 ++-- src/vid_voodoo_codegen_x86.h | 14 ++-- src/vid_voodoo_common.h | 27 ++++---- src/vid_voodoo_render.c | 35 +++++++--- src/vid_voodoo_render.h | 22 +++++-- 7 files changed, 185 insertions(+), 93 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 310014e..414948f 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -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_slave = voodoo_set->voodoos[1]; char temps[512], temps2[256]; - int pixel_count_current[2]; + int pixel_count_current[4]; int pixel_count_total; - int texel_count_current[2]; + int texel_count_current[4]; int texel_count_total; - int render_time[2]; + int render_time[4]; uint64_t new_time = timer_read(); uint64_t status_diff = new_time - status_time; status_time = new_time; + int c; if (!status_diff) status_diff = 1; - pixel_count_current[0] = voodoo->pixel_count[0]; - pixel_count_current[1] = voodoo->pixel_count[1]; - texel_count_current[0] = voodoo->texel_count[0]; - texel_count_current[1] = voodoo->texel_count[1]; - render_time[0] = voodoo->render_time[0]; - render_time[1] = voodoo->render_time[1]; + for (c = 0; c < 4; c++) + { + pixel_count_current[c] = voodoo->pixel_count[c]; + texel_count_current[c] = voodoo->texel_count[c]; + render_time[c] = voodoo->render_time[c]; + } if (voodoo_set->nr_cards == 2) { - pixel_count_current[0] += voodoo_slave->pixel_count[0]; - pixel_count_current[1] += voodoo_slave->pixel_count[1]; - texel_count_current[0] += voodoo_slave->texel_count[0]; - texel_count_current[1] += voodoo_slave->texel_count[1]; - render_time[0] = (render_time[0] + voodoo_slave->render_time[0]) / 2; - render_time[1] = (render_time[1] + voodoo_slave->render_time[1]) / 2; + for (c = 0; c < 4; c++) + { + pixel_count_current[c] += voodoo_slave->pixel_count[c]; + texel_count_current[c] += voodoo_slave->texel_count[c]; + render_time[c] = (render_time[c] + voodoo_slave->render_time[c]) / 2; + } } - pixel_count_total = (pixel_count_current[0] + pixel_count_current[1]) - (voodoo->pixel_count_old[0] + voodoo->pixel_count_old[1]); - texel_count_total = (texel_count_current[0] + texel_count_current[1]) - (voodoo->texel_count_old[0] + voodoo->texel_count_old[1]); + pixel_count_total = (pixel_count_current[0] + pixel_count_current[1] + pixel_count_current[2] + pixel_count_current[3]) - + (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*/, (double)pixel_count_total/1000000.0, ((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)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); - if (voodoo->render_threads == 2) + if (voodoo->render_threads >= 2) { 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); 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) { 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); 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", ((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); } + 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); - voodoo->pixel_count_old[0] = pixel_count_current[0]; - voodoo->pixel_count_old[1] = pixel_count_current[1]; - voodoo->texel_count_old[0] = texel_count_current[0]; - voodoo->texel_count_old[1] = texel_count_current[1]; + for (c = 0; c < 4; c++) + { + voodoo->pixel_count_old[c] = pixel_count_current[c]; + voodoo->texel_count_old[c] = texel_count_current[c]; + voodoo->render_time[c] = 0; + } voodoo->tri_count = voodoo->frame_count = 0; voodoo->rd_count = voodoo->wr_count = voodoo->tex_count = 0; voodoo->time = 0; - voodoo->render_time[0] = voodoo->render_time[1] = 0; if (voodoo_set->nr_cards == 2) { - voodoo_slave->pixel_count_old[0] = pixel_count_current[0]; - voodoo_slave->pixel_count_old[1] = pixel_count_current[1]; - voodoo_slave->texel_count_old[0] = texel_count_current[0]; - voodoo_slave->texel_count_old[1] = texel_count_current[1]; + for (c = 0; c < 4; c++) + { + voodoo_slave->pixel_count_old[c] = pixel_count_current[c]; + 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->rd_count = voodoo_slave->wr_count = voodoo_slave->tex_count = 0; voodoo_slave->time = 0; - voodoo_slave->render_time[0] = voodoo_slave->render_time[1] = 0; } voodoo_recomp = 0; } @@ -985,15 +1004,23 @@ void *voodoo_card_init() voodoo->wake_fifo_thread = thread_create_event(); voodoo->wake_render_thread[0] = 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->fifo_not_full_event = 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[2] = thread_create_event(); + voodoo->render_not_full_event[3] = thread_create_event(); voodoo->fifo_thread = thread_create(voodoo_fifo_thread, 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); - + 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); 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_render_thread[0] = 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->fifo_not_full_event = 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[2] = thread_create_event(); + voodoo->render_not_full_event[3] = thread_create_event(); voodoo->fifo_thread = thread_create(voodoo_fifo_thread, 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); + 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); @@ -1244,8 +1280,13 @@ void voodoo_card_close(voodoo_t *voodoo) thread_kill(voodoo->fifo_thread); thread_kill(voodoo->render_thread[0]); - if (voodoo->render_threads == 2) + if (voodoo->render_threads >= 2) 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->wake_main_thread); thread_destroy_event(voodoo->wake_fifo_thread); @@ -1376,6 +1417,10 @@ static device_config_t voodoo_config[] = .description = "2", .value = 2 }, + { + .description = "4", + .value = 4 + }, { .description = "" } diff --git a/src/vid_voodoo_banshee.c b/src/vid_voodoo_banshee.c index 199f751..a18f412 100644 --- a/src/vid_voodoo_banshee.c +++ b/src/vid_voodoo_banshee.c @@ -1998,6 +1998,10 @@ static device_config_t banshee_sgram_config[] = .description = "2", .value = 2 }, + { + .description = "4", + .value = 4 + }, { .description = "" } @@ -2039,6 +2043,10 @@ static device_config_t banshee_sdram_config[] = .description = "2", .value = 2 }, + { + .description = "4", + .value = 4 + }, { .description = "" } @@ -2182,27 +2190,30 @@ static void banshee_add_status_info(char *s, int max_len, void *p) banshee_t *banshee = (banshee_t *)p; voodoo_t *voodoo = banshee->voodoo; char temps[512]; - int pixel_count_current[2]; + int pixel_count_current[4]; int pixel_count_total; - int texel_count_current[2]; + int texel_count_current[4]; int texel_count_total; - int render_time[2]; + int render_time[4]; uint64_t new_time = timer_read(); uint64_t status_diff = new_time - status_time; + int c; status_time = new_time; svga_add_status_info(s, max_len, &banshee->svga); - pixel_count_current[0] = voodoo->pixel_count[0]; - pixel_count_current[1] = voodoo->pixel_count[1]; - texel_count_current[0] = voodoo->texel_count[0]; - texel_count_current[1] = voodoo->texel_count[1]; - render_time[0] = voodoo->render_time[0]; - render_time[1] = voodoo->render_time[1]; + for (c = 0; c < 4; c++) + { + pixel_count_current[c] = voodoo->pixel_count[c]; + texel_count_current[c] = voodoo->texel_count[c]; + render_time[c] = voodoo->render_time[c]; + } - pixel_count_total = (pixel_count_current[0] + pixel_count_current[1]) - (voodoo->pixel_count_old[0] + voodoo->pixel_count_old[1]); - texel_count_total = (texel_count_current[0] + texel_count_current[1]) - (voodoo->texel_count_old[0] + voodoo->texel_count_old[1]); + pixel_count_total = (pixel_count_current[0] + pixel_count_current[1] + pixel_count_current[2] + pixel_count_current[3]) - + (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*/, (double)pixel_count_total/1000000.0, ((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)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); - if (voodoo->render_threads == 2) + if (voodoo->render_threads >= 2) { char temps2[512]; 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); 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, "\n", max_len); - voodoo->pixel_count_old[0] = pixel_count_current[0]; - voodoo->pixel_count_old[1] = pixel_count_current[1]; - voodoo->texel_count_old[0] = texel_count_current[0]; - voodoo->texel_count_old[1] = texel_count_current[1]; + for (c = 0; c < 4; c++) + { + voodoo->pixel_count_old[c] = pixel_count_current[c]; + voodoo->texel_count_old[c] = texel_count_current[c]; + voodoo->render_time[c] = 0; + } + voodoo->tri_count = voodoo->frame_count = 0; voodoo->rd_count = voodoo->wr_count = voodoo->tex_count = 0; voodoo->time = 0; - voodoo->render_time[0] = voodoo->render_time[1] = 0; voodoo->read_time = pci_nonburst_time + pci_burst_time; diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/vid_voodoo_codegen_x86-64.h index 716e684..ba11ce5 100644 --- a/src/vid_voodoo_codegen_x86-64.h +++ b/src/vid_voodoo_codegen_x86-64.h @@ -38,8 +38,8 @@ typedef struct voodoo_x86_data_t //static voodoo_x86_data_t voodoo_x86_data[2][BLOCK_NUM]; -static int last_block[2] = {0, 0}; -static int next_block_to_write[2] = {0, 0}; +static int last_block[4] = {0, 0}; +static int next_block_to_write[4] = {0, 0}; #define addbyte(val) \ do { \ @@ -3346,7 +3346,7 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, 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 && 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; } 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; voodoo_generate(data->code_block, voodoo, params, state, depth_op); @@ -3392,9 +3392,9 @@ void voodoo_codegen_init(voodoo_t *voodoo) int c; #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 - 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 for (c = 0; c < 256; c++) @@ -3424,7 +3424,7 @@ void voodoo_codegen_close(voodoo_t *voodoo) #if WIN64 VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE); #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 } diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index 5867d85..d49c6ed 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -36,8 +36,8 @@ typedef struct voodoo_x86_data_t uint32_t trexInit1; } voodoo_x86_data_t; -static int last_block[2] = {0, 0}; -static int next_block_to_write[2] = {0, 0}; +static int last_block[4] = {0, 0}; +static int next_block_to_write[4] = {0, 0}; #define addbyte(val) \ do { \ @@ -3286,7 +3286,7 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, 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 && 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; } 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; voodoo_generate(data->code_block, voodoo, params, state, depth_op); @@ -3338,9 +3338,9 @@ void voodoo_codegen_init(voodoo_t *voodoo) #endif #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 - 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 for (c = 0; c < 256; c++) @@ -3370,6 +3370,6 @@ void voodoo_codegen_close(voodoo_t *voodoo) #if defined WIN32 || defined _WIN32 || defined _WIN32 VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE); #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 } diff --git a/src/vid_voodoo_common.h b/src/vid_voodoo_common.h index da64d6e..2bab154 100644 --- a/src/vid_voodoo_common.h +++ b/src/vid_voodoo_common.h @@ -75,12 +75,9 @@ enum #define PARAM_MASK (PARAM_SIZE - 1) #define PARAM_ENTRY_SIZE (1 << 31) -#define PARAM_ENTRIES_1 (voodoo->params_write_idx - voodoo->params_read_idx[0]) -#define PARAM_ENTRIES_2 (voodoo->params_write_idx - voodoo->params_read_idx[1]) -#define PARAM_FULL_1 ((voodoo->params_write_idx - voodoo->params_read_idx[0]) >= PARAM_SIZE) -#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) +#define PARAM_ENTRIES(x) (voodoo->params_write_idx - voodoo->params_read_idx[x]) +#define PARAM_FULL(x) ((voodoo->params_write_idx - voodoo->params_read_idx[x]) >= PARAM_SIZE) +#define PARAM_EMPTY(x) (voodoo->params_read_idx[x] == voodoo->params_write_idx) typedef struct { @@ -164,7 +161,7 @@ typedef struct texture_t { uint32_t base; uint32_t tLOD; - volatile int refcount, refcount_r[2]; + volatile int refcount, refcount_r[4]; int is16; uint32_t palette_checksum; uint32_t addr_start[4], addr_end[4]; @@ -258,21 +255,21 @@ typedef struct voodoo_t int ncc_dirty[2]; thread_t *fifo_thread; - thread_t *render_thread[2]; + thread_t *render_thread[4]; event_t *wake_fifo_thread; event_t *wake_main_thread; event_t *fifo_not_full_event; - event_t *render_not_full_event[2]; - event_t *wake_render_thread[2]; + event_t *render_not_full_event[4]; + event_t *wake_render_thread[4]; int voodoo_busy; - int render_voodoo_busy[2]; + int render_voodoo_busy[4]; int render_threads; int odd_even_mask; - int pixel_count[2], texel_count[2], tri_count, frame_count; - int pixel_count_old[2], texel_count_old[2]; + int pixel_count[4], texel_count[4], tri_count, frame_count; + int pixel_count_old[4], texel_count_old[4]; int wr_count, rd_count, tex_count; int retrace_count; @@ -296,7 +293,7 @@ typedef struct voodoo_t volatile int cmd_read, cmd_written, cmd_written_fifo; 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; int cmdfifo_rp; @@ -466,7 +463,7 @@ typedef struct voodoo_t int palette_dirty[2]; uint64_t time; - int render_time[2]; + int render_time[4]; int use_recompiler; void *codegen_data; diff --git a/src/vid_voodoo_render.c b/src/vid_voodoo_render.c index b2b3e89..a2125cb 100644 --- a/src/vid_voodoo_render.c +++ b/src/vid_voodoo_render.c @@ -1562,7 +1562,7 @@ static void render_thread(void *param, int odd_even) thread_reset_event(voodoo->wake_render_thread[odd_even]); 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 end_time; @@ -1572,7 +1572,7 @@ static void render_thread(void *param, int 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]); end_time = timer_read(); @@ -1591,24 +1591,38 @@ void voodoo_render_thread_2(void *param) { 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) { 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]); - if (voodoo->render_threads == 2) + if (voodoo->render_threads >= 2) 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*/ - } - if (voodoo->render_threads == 2 && PARAM_FULL_2) - { + if (voodoo->render_threads >= 2 && PARAM_FULL(1)) 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); @@ -1619,6 +1633,7 @@ void voodoo_queue_triangle(voodoo_t *voodoo, voodoo_params_t *params) 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); } diff --git a/src/vid_voodoo_render.h b/src/vid_voodoo_render.h index ec8a551..9ba73dc 100644 --- a/src/vid_voodoo_render.h +++ b/src/vid_voodoo_render.h @@ -299,6 +299,8 @@ void voodoo_codegen_close(voodoo_t *voodoo); void voodoo_render_thread_1(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); extern int voodoo_recomp; @@ -307,18 +309,30 @@ extern int tris; 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*/ - 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*/ + 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) { - 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); - 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); - 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); + 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); } }