PCem
changeset 133:24b744b9a632
ViRGE S3D triangle rendering now uses worker thread.
Fixed clipping bug on ViRGE.
Fixed status window crash.
| author | TomW |
|---|---|
| date | Tue Jul 22 21:10:39 2014 +0100 |
| parents | 2b9cea0be424 |
| children | ffe477b4639f |
| files | src/device.c src/device.h src/sound_sb.c src/sound_sb_dsp.c src/sound_sb_dsp.h src/vid_ati18800.c src/vid_ati28800.c src/vid_ati_mach64.c src/vid_cl5429.c src/vid_et4000.c src/vid_et4000w32.c src/vid_oti067.c src/vid_paradise.c src/vid_s3.c src/vid_s3_virge.c src/vid_svga.c src/vid_svga.h src/vid_tgui9440.c src/vid_tvga.c src/vid_vga.c src/win-status.c src/win.c |
| diffstat | 22 files changed, 462 insertions(+), 305 deletions(-) [+] |
line diff
1.1 --- a/src/device.c Wed Jul 16 20:44:29 2014 +0100 1.2 +++ b/src/device.c Tue Jul 22 21:10:39 2014 +0100 1.3 @@ -95,18 +95,12 @@ 1.4 { 1.5 int c; 1.6 1.7 - s += strlen(s); 1.8 - 1.9 for (c = 0; c < 256; c++) 1.10 { 1.11 if (devices[c] != NULL) 1.12 { 1.13 if (devices[c]->add_status_info != NULL) 1.14 - { 1.15 - int len = devices[c]->add_status_info(s, max_len, device_priv[c]); 1.16 - s += len; 1.17 - max_len -= len; 1.18 - } 1.19 + devices[c]->add_status_info(s, max_len, device_priv[c]); 1.20 } 1.21 } 1.22 }
2.1 --- a/src/device.h Wed Jul 16 20:44:29 2014 +0100 2.2 +++ b/src/device.h Tue Jul 22 21:10:39 2014 +0100 2.3 @@ -28,7 +28,7 @@ 2.4 int (*available)(); 2.5 void (*speed_changed)(void *p); 2.6 void (*force_redraw)(void *p); 2.7 - int (*add_status_info)(char *s, int max_len, void *p); 2.8 + void (*add_status_info)(char *s, int max_len, void *p); 2.9 device_config_t *config; 2.10 } device_t; 2.11
3.1 --- a/src/sound_sb.c Wed Jul 16 20:44:29 2014 +0100 3.2 +++ b/src/sound_sb.c Tue Jul 22 21:10:39 2014 +0100 3.3 @@ -444,7 +444,7 @@ 3.4 sb_dsp_speed_changed(&sb->dsp); 3.5 } 3.6 3.7 -int sb_add_status_info(char *s, int max_len, void *p) 3.8 +void sb_add_status_info(char *s, int max_len, void *p) 3.9 { 3.10 sb_t *sb = (sb_t *)p; 3.11
4.1 --- a/src/sound_sb_dsp.c Wed Jul 16 20:44:29 2014 +0100 4.2 +++ b/src/sound_sb_dsp.c Tue Jul 22 21:10:39 2014 +0100 4.3 @@ -910,10 +910,9 @@ 4.4 *r = dsp->sbdatr; 4.5 } 4.6 4.7 -int sb_dsp_add_status_info(char *s, int max_len, sb_dsp_t *dsp) 4.8 +void sb_dsp_add_status_info(char *s, int max_len, sb_dsp_t *dsp) 4.9 { 4.10 char temps[128]; 4.11 - int cur_len = max_len; 4.12 int len; 4.13 int freq; 4.14 4.15 @@ -967,15 +966,11 @@ 4.16 } 4.17 else 4.18 strcpy(temps, "SB playback stopped\n"); 4.19 - strncat(s, temps, cur_len); 4.20 - cur_len -= strlen(temps); 4.21 + strncat(s, temps, max_len); 4.22 4.23 if ((dsp->sb_8_enable && dsp->sb_8_output) || (dsp->sb_16_enable && dsp->sb_16_output)) 4.24 { 4.25 sprintf(temps, "SB playback frequency : %iHz\n", freq); 4.26 - strncat(s, temps, cur_len); 4.27 - cur_len -= strlen(temps); 4.28 + strncat(s, temps, max_len); 4.29 } 4.30 - 4.31 - return max_len - cur_len; 4.32 }
5.1 --- a/src/sound_sb_dsp.h Wed Jul 16 20:44:29 2014 +0100 5.2 +++ b/src/sound_sb_dsp.h Tue Jul 22 21:10:39 2014 +0100 5.3 @@ -68,4 +68,4 @@ 5.4 5.5 void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo); 5.6 5.7 -int sb_dsp_add_status_info(char *s, int max_len, sb_dsp_t *dsp); 5.8 +void sb_dsp_add_status_info(char *s, int max_len, sb_dsp_t *dsp);
6.1 --- a/src/vid_ati18800.c Wed Jul 16 20:44:29 2014 +0100 6.2 +++ b/src/vid_ati18800.c Tue Jul 22 21:10:39 2014 +0100 6.3 @@ -171,11 +171,11 @@ 6.4 ati18800->svga.fullchange = changeframecount; 6.5 } 6.6 6.7 -int ati18800_add_status_info(char *s, int max_len, void *p) 6.8 +void ati18800_add_status_info(char *s, int max_len, void *p) 6.9 { 6.10 ati18800_t *ati18800 = (ati18800_t *)p; 6.11 6.12 - return svga_add_status_info(s, max_len, &ati18800->svga); 6.13 + svga_add_status_info(s, max_len, &ati18800->svga); 6.14 } 6.15 6.16 device_t ati18800_device =
7.1 --- a/src/vid_ati28800.c Wed Jul 16 20:44:29 2014 +0100 7.2 +++ b/src/vid_ati28800.c Tue Jul 22 21:10:39 2014 +0100 7.3 @@ -192,11 +192,11 @@ 7.4 ati28800->svga.fullchange = changeframecount; 7.5 } 7.6 7.7 -int ati28800_add_status_info(char *s, int max_len, void *p) 7.8 +void ati28800_add_status_info(char *s, int max_len, void *p) 7.9 { 7.10 ati28800_t *ati28800 = (ati28800_t *)p; 7.11 7.12 - return svga_add_status_info(s, max_len, &ati28800->svga); 7.13 + svga_add_status_info(s, max_len, &ati28800->svga); 7.14 } 7.15 7.16 device_t ati28800_device =
8.1 --- a/src/vid_ati_mach64.c Wed Jul 16 20:44:29 2014 +0100 8.2 +++ b/src/vid_ati_mach64.c Tue Jul 22 21:10:39 2014 +0100 8.3 @@ -2278,10 +2278,9 @@ 8.4 mach64->svga.fullchange = changeframecount; 8.5 } 8.6 8.7 -int mach64_add_status_info(char *s, int max_len, void *p) 8.8 +void mach64_add_status_info(char *s, int max_len, void *p) 8.9 { 8.10 mach64_t *mach64 = (mach64_t *)p; 8.11 - int cur_len = max_len; 8.12 8.13 if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) 8.14 { 8.15 @@ -2289,8 +2288,7 @@ 8.16 char temps[128]; 8.17 int bpp = 4; 8.18 8.19 - strncat(s, "Mach64 in native mode\n", cur_len); 8.20 - cur_len -= strlen("Mach64 in native mode\n"); 8.21 + strncat(s, "Mach64 in native mode\n", max_len); 8.22 8.23 switch ((mach64->crtc_gen_cntl >> 8) & 7) 8.24 { 8.25 @@ -2303,25 +2301,19 @@ 8.26 } 8.27 8.28 sprintf(temps, "Mach64 colour depth : %i bpp\n", bpp); 8.29 - strncat(s, temps, cur_len); 8.30 - cur_len -= strlen(temps); 8.31 + strncat(s, temps, max_len); 8.32 8.33 sprintf(temps, "Mach64 resolution : %i x %i\n", svga->hdisp, svga->dispend); 8.34 - strncat(s, temps, cur_len); 8.35 - cur_len -= strlen(temps); 8.36 + strncat(s, temps, max_len); 8.37 8.38 sprintf(temps, "Mach64 refresh rate : %i Hz\n\n", svga->frames); 8.39 svga->frames = 0; 8.40 - strncat(s, temps, cur_len); 8.41 - cur_len -= strlen(temps); 8.42 - 8.43 - return max_len - cur_len; 8.44 + strncat(s, temps, max_len); 8.45 } 8.46 else 8.47 { 8.48 - strncat(s, "Mach64 in SVGA mode\n", cur_len); 8.49 - cur_len -= strlen("Mach64 in SVGA mode\n"); 8.50 - return svga_add_status_info(s, cur_len, &mach64->svga); 8.51 + strncat(s, "Mach64 in SVGA mode\n", max_len); 8.52 + svga_add_status_info(s, max_len, &mach64->svga); 8.53 } 8.54 } 8.55
9.1 --- a/src/vid_cl5429.c Wed Jul 16 20:44:29 2014 +0100 9.2 +++ b/src/vid_cl5429.c Tue Jul 22 21:10:39 2014 +0100 9.3 @@ -870,11 +870,11 @@ 9.4 gd5429->svga.fullchange = changeframecount; 9.5 } 9.6 9.7 -int gd5429_add_status_info(char *s, int max_len, void *p) 9.8 +void gd5429_add_status_info(char *s, int max_len, void *p) 9.9 { 9.10 gd5429_t *gd5429 = (gd5429_t *)p; 9.11 9.12 - return svga_add_status_info(s, max_len, &gd5429->svga); 9.13 + svga_add_status_info(s, max_len, &gd5429->svga); 9.14 } 9.15 9.16 device_t gd5429_device =
10.1 --- a/src/vid_et4000.c Wed Jul 16 20:44:29 2014 +0100 10.2 +++ b/src/vid_et4000.c Tue Jul 22 21:10:39 2014 +0100 10.3 @@ -174,11 +174,11 @@ 10.4 et4000->svga.fullchange = changeframecount; 10.5 } 10.6 10.7 -int et4000_add_status_info(char *s, int max_len, void *p) 10.8 +void et4000_add_status_info(char *s, int max_len, void *p) 10.9 { 10.10 et4000_t *et4000 = (et4000_t *)p; 10.11 10.12 - return svga_add_status_info(s, max_len, &et4000->svga); 10.13 + svga_add_status_info(s, max_len, &et4000->svga); 10.14 } 10.15 10.16 device_t et4000_device =
11.1 --- a/src/vid_et4000w32.c Wed Jul 16 20:44:29 2014 +0100 11.2 +++ b/src/vid_et4000w32.c Tue Jul 22 21:10:39 2014 +0100 11.3 @@ -1077,11 +1077,11 @@ 11.4 et4000w32p->svga.fullchange = changeframecount; 11.5 } 11.6 11.7 -int et4000w32p_add_status_info(char *s, int max_len, void *p) 11.8 +void et4000w32p_add_status_info(char *s, int max_len, void *p) 11.9 { 11.10 et4000w32p_t *et4000w32p = (et4000w32p_t *)p; 11.11 11.12 - return svga_add_status_info(s, max_len, &et4000w32p->svga); 11.13 + svga_add_status_info(s, max_len, &et4000w32p->svga); 11.14 } 11.15 11.16 static device_config_t et4000w32p_config[] =
12.1 --- a/src/vid_oti067.c Wed Jul 16 20:44:29 2014 +0100 12.2 +++ b/src/vid_oti067.c Tue Jul 22 21:10:39 2014 +0100 12.3 @@ -187,11 +187,11 @@ 12.4 oti067->svga.fullchange = changeframecount; 12.5 } 12.6 12.7 -int oti067_add_status_info(char *s, int max_len, void *p) 12.8 +void oti067_add_status_info(char *s, int max_len, void *p) 12.9 { 12.10 oti067_t *oti067 = (oti067_t *)p; 12.11 12.12 - return svga_add_status_info(s, max_len, &oti067->svga); 12.13 + svga_add_status_info(s, max_len, &oti067->svga); 12.14 } 12.15 12.16 static device_config_t oti067_config[] =
13.1 --- a/src/vid_paradise.c Wed Jul 16 20:44:29 2014 +0100 13.2 +++ b/src/vid_paradise.c Tue Jul 22 21:10:39 2014 +0100 13.3 @@ -372,11 +372,11 @@ 13.4 paradise->svga.fullchange = changeframecount; 13.5 } 13.6 13.7 -int paradise_add_status_info(char *s, int max_len, void *p) 13.8 +void paradise_add_status_info(char *s, int max_len, void *p) 13.9 { 13.10 paradise_t *paradise = (paradise_t *)p; 13.11 13.12 - return svga_add_status_info(s, max_len, ¶dise->svga); 13.13 + svga_add_status_info(s, max_len, ¶dise->svga); 13.14 } 13.15 13.16 device_t paradise_pvga1a_pc2086_device =
14.1 --- a/src/vid_s3.c Wed Jul 16 20:44:29 2014 +0100 14.2 +++ b/src/vid_s3.c Tue Jul 22 21:10:39 2014 +0100 14.3 @@ -2055,11 +2055,11 @@ 14.4 s3->svga.fullchange = changeframecount; 14.5 } 14.6 14.7 -int s3_add_status_info(char *s, int max_len, void *p) 14.8 +void s3_add_status_info(char *s, int max_len, void *p) 14.9 { 14.10 s3_t *s3 = (s3_t *)p; 14.11 14.12 - return svga_add_status_info(s, max_len, &s3->svga); 14.13 + svga_add_status_info(s, max_len, &s3->svga); 14.14 } 14.15 14.16 static device_config_t s3_bahamas64_config[] =
15.1 --- a/src/vid_s3_virge.c Wed Jul 16 20:44:29 2014 +0100 15.2 +++ b/src/vid_s3_virge.c Tue Jul 22 21:10:39 2014 +0100 15.3 @@ -6,6 +6,7 @@ 15.4 #include "mem.h" 15.5 #include "pci.h" 15.6 #include "rom.h" 15.7 +#include "thread.h" 15.8 #include "video.h" 15.9 #include "vid_s3_virge.h" 15.10 #include "vid_svga.h" 15.11 @@ -13,7 +14,7 @@ 15.12 15.13 static uint64_t virge_time = 0; 15.14 static uint64_t status_time = 0; 15.15 -static int reg_writes = 0; 15.16 +static int reg_writes = 0, reg_reads = 0; 15.17 15.18 static int dither[4][4] = 15.19 { 15.20 @@ -23,6 +24,54 @@ 15.21 7, 3, 6, 2, 15.22 }; 15.23 15.24 +#define RB_SIZE 256 15.25 +#define RB_MASK (RB_SIZE - 1) 15.26 + 15.27 +#define RB_ENTRIES (virge->s3d_write_idx - virge->s3d_read_idx) 15.28 +#define RB_FULL (RB_ENTRIES == RB_SIZE) 15.29 +#define RB_EMPTY (!RB_ENTRIES) 15.30 + 15.31 +typedef struct s3d_t 15.32 +{ 15.33 + uint32_t cmd_set; 15.34 + int clip_l, clip_r, clip_t, clip_b; 15.35 + 15.36 + uint32_t dest_base; 15.37 + uint32_t dest_str; 15.38 + 15.39 + uint32_t z_base; 15.40 + uint32_t z_str; 15.41 + 15.42 + uint32_t tex_base; 15.43 + uint32_t tex_bdr_clr; 15.44 + uint32_t tbv, tbu; 15.45 + int32_t TdVdX, TdUdX; 15.46 + int32_t TdVdY, TdUdY; 15.47 + uint32_t tus, tvs; 15.48 + 15.49 + int32_t TdZdX, TdZdY; 15.50 + uint32_t tzs; 15.51 + 15.52 + int32_t TdWdX, TdWdY; 15.53 + uint32_t tws; 15.54 + 15.55 + int32_t TdDdX, TdDdY; 15.56 + uint32_t tds; 15.57 + 15.58 + int16_t TdGdX, TdBdX, TdRdX, TdAdX; 15.59 + int16_t TdGdY, TdBdY, TdRdY, TdAdY; 15.60 + uint32_t tgs, tbs, trs, tas; 15.61 + 15.62 + uint32_t TdXdY12; 15.63 + uint32_t txend12; 15.64 + uint32_t TdXdY01; 15.65 + uint32_t txend01; 15.66 + uint32_t TdXdY02; 15.67 + uint32_t txs; 15.68 + uint32_t tys; 15.69 + int ty01, ty12, tlr; 15.70 +} s3d_t; 15.71 + 15.72 typedef struct virge_t 15.73 { 15.74 mem_mapping_t linear_mapping; 15.75 @@ -51,6 +100,11 @@ 15.76 int memory_size; 15.77 15.78 int pixel_count, tri_count; 15.79 + 15.80 + thread_t *render_thread; 15.81 + event_t *wake_render_thread; 15.82 + event_t *wake_main_thread; 15.83 + event_t *not_full_event; 15.84 15.85 struct 15.86 { 15.87 @@ -86,41 +140,14 @@ 15.88 uint32_t pattern_8[8*8]; 15.89 uint32_t pattern_16[8*8]; 15.90 uint32_t pattern_32[8*8]; 15.91 - 15.92 - 15.93 - uint32_t z_base; 15.94 - uint32_t z_str; 15.95 - 15.96 - uint32_t tex_base; 15.97 - uint32_t tex_bdr_clr; 15.98 - uint32_t tbv, tbu; 15.99 - int32_t TdVdX, TdUdX; 15.100 - int32_t TdVdY, TdUdY; 15.101 - uint32_t tus, tvs; 15.102 - 15.103 - int32_t TdZdX, TdZdY; 15.104 - uint32_t tzs; 15.105 - 15.106 - int32_t TdWdX, TdWdY; 15.107 - uint32_t tws; 15.108 - 15.109 - int32_t TdDdX, TdDdY; 15.110 - uint32_t tds; 15.111 - 15.112 - int16_t TdGdX, TdBdX, TdRdX, TdAdX; 15.113 - int16_t TdGdY, TdBdY, TdRdY, TdAdY; 15.114 - uint32_t tgs, tbs, trs, tas; 15.115 - 15.116 - uint32_t TdXdY12; 15.117 - uint32_t txend12; 15.118 - uint32_t TdXdY01; 15.119 - uint32_t txend01; 15.120 - uint32_t TdXdY02; 15.121 - uint32_t txs; 15.122 - uint32_t tys; 15.123 - int ty01, ty12, tlr; 15.124 } s3d; 15.125 15.126 + s3d_t s3d_tri; 15.127 + 15.128 + s3d_t s3d_buffer[RB_SIZE]; 15.129 + int s3d_read_idx, s3d_write_idx; 15.130 + int s3d_busy; 15.131 + 15.132 struct 15.133 { 15.134 uint32_t pri_ctrl; 15.135 @@ -154,13 +181,13 @@ 15.136 } streams; 15.137 } virge_t; 15.138 15.139 +static void queue_triangle(virge_t *virge); 15.140 + 15.141 static void s3_virge_recalctimings(svga_t *svga); 15.142 static void s3_virge_updatemapping(virge_t *virge); 15.143 15.144 static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat); 15.145 15.146 -static void s3_virge_triangle(virge_t *virge); 15.147 - 15.148 static uint8_t s3_virge_mmio_read(uint32_t addr, void *p); 15.149 static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p); 15.150 static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p); 15.151 @@ -598,7 +625,7 @@ 15.152 15.153 static uint8_t s3_virge_mmio_read(uint32_t addr, void *p) 15.154 { 15.155 - reg_writes++; 15.156 + reg_reads++; 15.157 // pclog("New MMIO readb %08X\n", addr); 15.158 switch (addr & 0xffff) 15.159 { 15.160 @@ -620,7 +647,7 @@ 15.161 } 15.162 static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p) 15.163 { 15.164 - reg_writes++; 15.165 + reg_reads++; 15.166 // pclog("New MMIO readw %08X\n", addr); 15.167 switch (addr & 0xfffe) 15.168 { 15.169 @@ -633,7 +660,7 @@ 15.170 { 15.171 virge_t *virge = (virge_t *)p; 15.172 uint32_t ret = 0xffffffff; 15.173 - reg_writes++; 15.174 + reg_reads++; 15.175 // pclog("New MMIO readl %08X %04X(%08X):%08X ", addr, CS, cs, pc); 15.176 switch (addr & 0xfffc) 15.177 { 15.178 @@ -705,7 +732,11 @@ 15.179 break; 15.180 15.181 case 0x8504: 15.182 - ret = (0x10 << 8) | (1 << 13); 15.183 + if (virge->s3d_busy) 15.184 + ret = (0x10 << 8); 15.185 + else 15.186 + ret = (0x10 << 8) | (1 << 13); 15.187 +// pclog("Read status %04x %i\n", ret, virge->s3d_busy); 15.188 break; 15.189 case 0xa4d4: 15.190 ret = virge->s3d.src_base; 15.191 @@ -756,7 +787,7 @@ 15.192 default: 15.193 ret = s3_virge_mmio_read_w(addr, p) | (s3_virge_mmio_read_w(addr + 2, p) << 16); 15.194 } 15.195 -// pclog("%02x\n", ret); 15.196 +// /*if ((addr & 0xfffc) != 0x8504) */pclog("%02x\n", ret); 15.197 return ret; 15.198 } 15.199 static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p) 15.200 @@ -856,11 +887,13 @@ 15.201 virge->streams.blend_ctrl = val; 15.202 break; 15.203 case 0x81c0: 15.204 +// pclog("Write pri_fb0 %08x\n", val); 15.205 virge->streams.pri_fb0 = val & 0x3fffff; 15.206 s3_virge_recalctimings(svga); 15.207 svga->fullchange = changeframecount; 15.208 break; 15.209 case 0x81c4: 15.210 +// pclog("Write pri_fb1 %08x\n", val); 15.211 virge->streams.pri_fb1 = val & 0x3fffff; 15.212 s3_virge_recalctimings(svga); 15.213 svga->fullchange = changeframecount; 15.214 @@ -871,9 +904,10 @@ 15.215 svga->fullchange = changeframecount; 15.216 break; 15.217 case 0x81cc: 15.218 - pclog("Write buffer_ctrl %08x\n", val); 15.219 +// pclog("Write buffer_ctrl %08x\n", val); 15.220 virge->streams.buffer_ctrl = val; 15.221 s3_virge_recalctimings(svga); 15.222 + svga->fullchange = changeframecount; 15.223 break; 15.224 case 0x81d0: 15.225 virge->streams.sec_fb0 = val; 15.226 @@ -991,22 +1025,21 @@ 15.227 } 15.228 break; 15.229 15.230 - 15.231 case 0xa4d4: case 0xa8d4: 15.232 virge->s3d.src_base = val & 0x3ffff8; 15.233 break; 15.234 - case 0xa4d8: case 0xa8d8: case 0xb4d8: 15.235 + case 0xa4d8: case 0xa8d8: 15.236 virge->s3d.dest_base = val & 0x3ffff8; 15.237 break; 15.238 - case 0xa4dc: case 0xa8dc: case 0xb4dc: 15.239 + case 0xa4dc: case 0xa8dc: 15.240 virge->s3d.clip_l = (val >> 16) & 0x7ff; 15.241 virge->s3d.clip_r = val & 0x7ff; 15.242 break; 15.243 - case 0xa4e0: case 0xa8e0: case 0xb4e0: 15.244 + case 0xa4e0: case 0xa8e0: 15.245 virge->s3d.clip_t = (val >> 16) & 0x7ff; 15.246 virge->s3d.clip_b = val & 0x7ff; 15.247 break; 15.248 - case 0xa4e4: case 0xa8e4: case 0xb4e4: 15.249 + case 0xa4e4: case 0xa8e4: 15.250 virge->s3d.dest_str = (val >> 16) & 0xff8; 15.251 virge->s3d.src_str = val & 0xff8; 15.252 break; 15.253 @@ -1068,125 +1101,151 @@ 15.254 break; 15.255 15.256 case 0xb4d4: 15.257 - virge->s3d.z_base = val & 0x3ffff8; 15.258 + virge->s3d_tri.z_base = val & 0x3ffff8; 15.259 + break; 15.260 + case 0xb4d8: 15.261 + virge->s3d_tri.dest_base = val & 0x3ffff8; 15.262 + break; 15.263 + case 0xb4dc: 15.264 + virge->s3d_tri.clip_l = (val >> 16) & 0x7ff; 15.265 + virge->s3d_tri.clip_r = val & 0x7ff; 15.266 + break; 15.267 + case 0xb4e0: 15.268 + virge->s3d_tri.clip_t = (val >> 16) & 0x7ff; 15.269 + virge->s3d_tri.clip_b = val & 0x7ff; 15.270 + break; 15.271 + case 0xb4e4: 15.272 + virge->s3d_tri.dest_str = (val >> 16) & 0xff8; 15.273 + virge->s3d.src_str = val & 0xff8; 15.274 break; 15.275 case 0xb4e8: 15.276 - virge->s3d.z_str = val & 0xff8; 15.277 + virge->s3d_tri.z_str = val & 0xff8; 15.278 break; 15.279 case 0xb4ec: 15.280 - virge->s3d.tex_base = val & 0x3ffff8; 15.281 + virge->s3d_tri.tex_base = val & 0x3ffff8; 15.282 break; 15.283 case 0xb4f0: 15.284 - virge->s3d.tex_bdr_clr = val & 0xffffff; 15.285 + virge->s3d_tri.tex_bdr_clr = val & 0xffffff; 15.286 break; 15.287 case 0xb500: 15.288 - virge->s3d.cmd_set = val; 15.289 + virge->s3d_tri.cmd_set = val; 15.290 if (!(val & CMD_SET_AE)) 15.291 - s3_virge_triangle(virge); 15.292 + queue_triangle(virge); 15.293 +/* { 15.294 + thread_set_event(virge->wake_render_thread); 15.295 + thread_wait_event(virge->wake_main_thread, -1); 15.296 + } */ 15.297 +// s3_virge_triangle(virge); 15.298 break; 15.299 case 0xb504: 15.300 - virge->s3d.tbv = val & 0xfffff; 15.301 + virge->s3d_tri.tbv = val & 0xfffff; 15.302 break; 15.303 case 0xb508: 15.304 - virge->s3d.tbu = val & 0xfffff; 15.305 + virge->s3d_tri.tbu = val & 0xfffff; 15.306 break; 15.307 case 0xb50c: 15.308 - virge->s3d.TdWdX = val; 15.309 + virge->s3d_tri.TdWdX = val; 15.310 break; 15.311 case 0xb510: 15.312 - virge->s3d.TdWdY = val; 15.313 + virge->s3d_tri.TdWdY = val; 15.314 break; 15.315 case 0xb514: 15.316 - virge->s3d.tws = val; 15.317 + virge->s3d_tri.tws = val; 15.318 break; 15.319 case 0xb518: 15.320 - virge->s3d.TdDdX = val; 15.321 + virge->s3d_tri.TdDdX = val; 15.322 break; 15.323 case 0xb51c: 15.324 - virge->s3d.TdVdX = val; 15.325 + virge->s3d_tri.TdVdX = val; 15.326 break; 15.327 case 0xb520: 15.328 - virge->s3d.TdUdX = val; 15.329 + virge->s3d_tri.TdUdX = val; 15.330 break; 15.331 case 0xb524: 15.332 - virge->s3d.TdDdY = val; 15.333 + virge->s3d_tri.TdDdY = val; 15.334 break; 15.335 case 0xb528: 15.336 - virge->s3d.TdVdY = val; 15.337 + virge->s3d_tri.TdVdY = val; 15.338 break; 15.339 case 0xb52c: 15.340 - virge->s3d.TdUdY = val; 15.341 + virge->s3d_tri.TdUdY = val; 15.342 break; 15.343 case 0xb530: 15.344 - virge->s3d.tds = val; 15.345 + virge->s3d_tri.tds = val; 15.346 break; 15.347 case 0xb534: 15.348 - virge->s3d.tvs = val; 15.349 + virge->s3d_tri.tvs = val; 15.350 break; 15.351 case 0xb538: 15.352 - virge->s3d.tus = val; 15.353 + virge->s3d_tri.tus = val; 15.354 break; 15.355 case 0xb53c: 15.356 - virge->s3d.TdGdX = val >> 16; 15.357 - virge->s3d.TdBdX = val & 0xffff; 15.358 + virge->s3d_tri.TdGdX = val >> 16; 15.359 + virge->s3d_tri.TdBdX = val & 0xffff; 15.360 break; 15.361 case 0xb540: 15.362 - virge->s3d.TdAdX = val >> 16; 15.363 - virge->s3d.TdRdX = val & 0xffff; 15.364 + virge->s3d_tri.TdAdX = val >> 16; 15.365 + virge->s3d_tri.TdRdX = val & 0xffff; 15.366 break; 15.367 case 0xb544: 15.368 - virge->s3d.TdGdY = val >> 16; 15.369 - virge->s3d.TdBdY = val & 0xffff; 15.370 + virge->s3d_tri.TdGdY = val >> 16; 15.371 + virge->s3d_tri.TdBdY = val & 0xffff; 15.372 break; 15.373 case 0xb548: 15.374 - virge->s3d.TdAdY = val >> 16; 15.375 - virge->s3d.TdRdY = val & 0xffff; 15.376 + virge->s3d_tri.TdAdY = val >> 16; 15.377 + virge->s3d_tri.TdRdY = val & 0xffff; 15.378 break; 15.379 case 0xb54c: 15.380 - virge->s3d.tgs = (val >> 16) & 0xffff; 15.381 - virge->s3d.tbs = val & 0xffff; 15.382 + virge->s3d_tri.tgs = (val >> 16) & 0xffff; 15.383 + virge->s3d_tri.tbs = val & 0xffff; 15.384 break; 15.385 case 0xb550: 15.386 - virge->s3d.tas = (val >> 16) & 0xffff; 15.387 - virge->s3d.trs = val & 0xffff; 15.388 + virge->s3d_tri.tas = (val >> 16) & 0xffff; 15.389 + virge->s3d_tri.trs = val & 0xffff; 15.390 break; 15.391 15.392 case 0xb554: 15.393 - virge->s3d.TdZdX = val; 15.394 + virge->s3d_tri.TdZdX = val; 15.395 break; 15.396 case 0xb558: 15.397 - virge->s3d.TdZdY = val; 15.398 + virge->s3d_tri.TdZdY = val; 15.399 break; 15.400 case 0xb55c: 15.401 - virge->s3d.tzs = val; 15.402 + virge->s3d_tri.tzs = val; 15.403 break; 15.404 case 0xb560: 15.405 - virge->s3d.TdXdY12 = val; 15.406 + virge->s3d_tri.TdXdY12 = val; 15.407 break; 15.408 case 0xb564: 15.409 - virge->s3d.txend12 = val; 15.410 + virge->s3d_tri.txend12 = val; 15.411 break; 15.412 case 0xb568: 15.413 - virge->s3d.TdXdY01 = val; 15.414 + virge->s3d_tri.TdXdY01 = val; 15.415 break; 15.416 case 0xb56c: 15.417 - virge->s3d.txend01 = val; 15.418 + virge->s3d_tri.txend01 = val; 15.419 break; 15.420 case 0xb570: 15.421 - virge->s3d.TdXdY02 = val; 15.422 + virge->s3d_tri.TdXdY02 = val; 15.423 break; 15.424 case 0xb574: 15.425 - virge->s3d.txs = val; 15.426 + virge->s3d_tri.txs = val; 15.427 break; 15.428 case 0xb578: 15.429 - virge->s3d.tys = val; 15.430 + virge->s3d_tri.tys = val; 15.431 break; 15.432 case 0xb57c: 15.433 - virge->s3d.ty01 = (val >> 16) & 0x7ff; 15.434 - virge->s3d.ty12 = val & 0x7ff; 15.435 - virge->s3d.tlr = val >> 31; 15.436 - if (virge->s3d.cmd_set & CMD_SET_AE) 15.437 - s3_virge_triangle(virge); 15.438 + virge->s3d_tri.ty01 = (val >> 16) & 0x7ff; 15.439 + virge->s3d_tri.ty12 = val & 0x7ff; 15.440 + virge->s3d_tri.tlr = val >> 31; 15.441 + if (virge->s3d_tri.cmd_set & CMD_SET_AE) 15.442 + queue_triangle(virge); 15.443 +/* { 15.444 + thread_set_event(virge->wake_render_thread); 15.445 + thread_wait_event(virge->wake_main_thread, -1); 15.446 + }*/ 15.447 + 15.448 +// s3_virge_triangle(virge); 15.449 break; 15.450 } 15.451 } 15.452 @@ -1210,24 +1269,35 @@ 15.453 15.454 #define Z_READ(addr) *(uint16_t *)&vram[addr & 0x3fffff] 15.455 15.456 -#define Z_WRITE(addr, val) if (!(virge->s3d.cmd_set & CMD_SET_ZB_MODE)) *(uint16_t *)&vram[addr & 0x3fffff] = val 15.457 +#define Z_WRITE(addr, val) if (!(s3d_tri->cmd_set & CMD_SET_ZB_MODE)) *(uint16_t *)&vram[addr & 0x3fffff] = val 15.458 15.459 #define CLIP(x, y) \ 15.460 do \ 15.461 { \ 15.462 - if ((virge->s3d.cmd_set & CMD_SET_HC) && \ 15.463 - (x < virge->s3d.clip_l || \ 15.464 - x > virge->s3d.clip_r || \ 15.465 - y < virge->s3d.clip_t || \ 15.466 - y > virge->s3d.clip_b)) \ 15.467 + if ((virge->s3d.cmd_set & CMD_SET_HC) && \ 15.468 + (x < virge->s3d.clip_l || \ 15.469 + x > virge->s3d.clip_r || \ 15.470 + y < virge->s3d.clip_t || \ 15.471 + y > virge->s3d.clip_b)) \ 15.472 + update = 0; \ 15.473 + } while (0) 15.474 + 15.475 +#define CLIP_3D(x, y) \ 15.476 + do \ 15.477 + { \ 15.478 + if ((s3d_tri->cmd_set & CMD_SET_HC) && \ 15.479 + (x < s3d_tri->clip_l || \ 15.480 + x > s3d_tri->clip_r || \ 15.481 + y < s3d_tri->clip_t || \ 15.482 + y > s3d_tri->clip_b)) \ 15.483 update = 0; \ 15.484 } while (0) 15.485 15.486 #define Z_CLIP(Zzb, Zs) \ 15.487 do \ 15.488 { \ 15.489 - if (!(virge->s3d.cmd_set & CMD_SET_ZB_MODE)) \ 15.490 - switch ((virge->s3d.cmd_set >> 20) & 7) \ 15.491 + if (!(s3d_tri->cmd_set & CMD_SET_ZB_MODE)) \ 15.492 + switch ((s3d_tri->cmd_set >> 20) & 7) \ 15.493 { \ 15.494 case 0: update = 0; break; \ 15.495 case 1: if (Zs <= Zzb) update = 0; else Zzb = Zs; break; \ 15.496 @@ -2208,51 +2278,53 @@ 15.497 state->dest_rgba.a = a; 15.498 } 15.499 15.500 -static void tri(virge_t *virge, s3d_state_t *state, int yc, int32_t dx1, int32_t dx2) 15.501 +static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int32_t dx2) 15.502 { 15.503 uint8_t *vram = virge->svga.vram; 15.504 15.505 - int x_dir = virge->s3d.tlr ? 1 : -1; 15.506 + int x_dir = s3d_tri->tlr ? 1 : -1; 15.507 15.508 - int use_z = !(virge->s3d.cmd_set & CMD_SET_ZB_MODE); 15.509 + int use_z = !(s3d_tri->cmd_set & CMD_SET_ZB_MODE); 15.510 15.511 int y_count = yc; 15.512 15.513 - int bpp = (virge->s3d.cmd_set >> 2) & 7; 15.514 + int bpp = (s3d_tri->cmd_set >> 2) & 7; 15.515 15.516 uint32_t dest_offset, z_offset; 15.517 15.518 - if (virge->s3d.cmd_set & CMD_SET_HC) 15.519 + if (s3d_tri->cmd_set & CMD_SET_HC) 15.520 { 15.521 - if (state->y < virge->s3d.clip_t) 15.522 + if (state->y < s3d_tri->clip_t) 15.523 return; 15.524 - if (state->y > virge->s3d.clip_b) 15.525 + if (state->y > s3d_tri->clip_b) 15.526 { 15.527 - int diff_y = state->y - virge->s3d.clip_b; 15.528 + int diff_y = state->y - s3d_tri->clip_b; 15.529 15.530 if (diff_y > y_count) 15.531 diff_y = y_count; 15.532 15.533 - state->base_u += (virge->s3d.TdUdY * diff_y); 15.534 - state->base_v += (virge->s3d.TdVdY * diff_y); 15.535 - state->base_z += (virge->s3d.TdZdY * diff_y); 15.536 - state->base_r += (virge->s3d.TdRdY * diff_y); 15.537 - state->base_g += (virge->s3d.TdGdY * diff_y); 15.538 - state->base_b += (virge->s3d.TdBdY * diff_y); 15.539 - state->base_a += (virge->s3d.TdAdY * diff_y); 15.540 - state->base_d += (virge->s3d.TdDdY * diff_y); 15.541 - state->base_w += (virge->s3d.TdWdY * diff_y); 15.542 + state->base_u += (s3d_tri->TdUdY * diff_y); 15.543 + state->base_v += (s3d_tri->TdVdY * diff_y); 15.544 + state->base_z += (s3d_tri->TdZdY * diff_y); 15.545 + state->base_r += (s3d_tri->TdRdY * diff_y); 15.546 + state->base_g += (s3d_tri->TdGdY * diff_y); 15.547 + state->base_b += (s3d_tri->TdBdY * diff_y); 15.548 + state->base_a += (s3d_tri->TdAdY * diff_y); 15.549 + state->base_d += (s3d_tri->TdDdY * diff_y); 15.550 + state->base_w += (s3d_tri->TdWdY * diff_y); 15.551 state->x1 += (dx1 * diff_y); 15.552 state->x2 += (dx2 * diff_y); 15.553 state->y -= diff_y; 15.554 - dest_offset -= virge->s3d.dest_str; 15.555 - z_offset -= virge->s3d.z_str; 15.556 + dest_offset -= s3d_tri->dest_str; 15.557 + z_offset -= s3d_tri->z_str; 15.558 y_count -= diff_y; 15.559 } 15.560 + if ((state->y - y_count) < s3d_tri->clip_t) 15.561 + y_count = state->y - s3d_tri->clip_t; 15.562 } 15.563 15.564 - dest_offset = virge->s3d.dest_base + (state->y * virge->s3d.dest_str); 15.565 - z_offset = virge->s3d.z_base + (state->y * virge->s3d.z_str); 15.566 + dest_offset = s3d_tri->dest_base + (state->y * s3d_tri->dest_str); 15.567 + z_offset = s3d_tri->z_base + (state->y * s3d_tri->z_str); 15.568 15.569 for (; y_count > 0; y_count--) 15.570 { 15.571 @@ -2273,68 +2345,68 @@ 15.572 int xz_offset = x_dir << 1; 15.573 if (x_dir > 0) 15.574 dx += 1; 15.575 - state->r = state->base_r + ((virge->s3d.TdRdX * dx) >> 5); 15.576 - state->g = state->base_g + ((virge->s3d.TdGdX * dx) >> 5); 15.577 - state->b = state->base_b + ((virge->s3d.TdBdX * dx) >> 5); 15.578 - state->a = state->base_a + ((virge->s3d.TdAdX * dx) >> 5); 15.579 - state->u = state->base_u + ((virge->s3d.TdUdX * dx) >> 5); 15.580 - state->v = state->base_v + ((virge->s3d.TdVdX * dx) >> 5); 15.581 - state->w = state->base_w + ((virge->s3d.TdWdX * dx) >> 5); 15.582 - state->d = state->base_d + ((virge->s3d.TdDdX * dx) >> 5); 15.583 - z += ((virge->s3d.TdZdX * dx) >> 5); 15.584 + state->r = state->base_r + ((s3d_tri->TdRdX * dx) >> 5); 15.585 + state->g = state->base_g + ((s3d_tri->TdGdX * dx) >> 5); 15.586 + state->b = state->base_b + ((s3d_tri->TdBdX * dx) >> 5); 15.587 + state->a = state->base_a + ((s3d_tri->TdAdX * dx) >> 5); 15.588 + state->u = state->base_u + ((s3d_tri->TdUdX * dx) >> 5); 15.589 + state->v = state->base_v + ((s3d_tri->TdVdX * dx) >> 5); 15.590 + state->w = state->base_w + ((s3d_tri->TdWdX * dx) >> 5); 15.591 + state->d = state->base_d + ((s3d_tri->TdDdX * dx) >> 5); 15.592 + z += ((s3d_tri->TdZdX * dx) >> 5); 15.593 15.594 // pclog("Draw Y=%i X=%i to XE=%i %i %08x %08x %08x %08x %08x %08x %08x %08x %i %08x\n", state->y, x, xe, dx, state->x1, state->x2, dx1, virge->s3d.TdWdX, state->u, state->v, virge->s3d.TdUdX, virge->s3d.TdUdY, dx, (virge->s3d.TdUdX * dx) >> 4); 15.595 15.596 - if (virge->s3d.cmd_set & CMD_SET_HC) 15.597 + if (s3d_tri->cmd_set & CMD_SET_HC) 15.598 { 15.599 if (x_dir > 0) 15.600 { 15.601 - if (x > virge->s3d.clip_r) 15.602 + if (x > s3d_tri->clip_r) 15.603 goto tri_skip_line; 15.604 - if (xe < virge->s3d.clip_l) 15.605 + if (xe < s3d_tri->clip_l) 15.606 goto tri_skip_line; 15.607 - if (xe > virge->s3d.clip_r) 15.608 - xe = virge->s3d.clip_r; 15.609 - if (x < virge->s3d.clip_l) 15.610 + if (xe > s3d_tri->clip_r) 15.611 + xe = s3d_tri->clip_r; 15.612 + if (x < s3d_tri->clip_l) 15.613 { 15.614 - int diff_x = virge->s3d.clip_l - x; 15.615 + int diff_x = s3d_tri->clip_l - x; 15.616 15.617 - z += (virge->s3d.TdZdX * diff_x); 15.618 - state->u += (virge->s3d.TdUdX * diff_x); 15.619 - state->v += (virge->s3d.TdVdX * diff_x); 15.620 - state->r += (virge->s3d.TdRdX * diff_x); 15.621 - state->g += (virge->s3d.TdGdX * diff_x); 15.622 - state->b += (virge->s3d.TdBdX * diff_x); 15.623 - state->a += (virge->s3d.TdAdX * diff_x); 15.624 - state->d += (virge->s3d.TdDdX * diff_x); 15.625 - state->w += (virge->s3d.TdWdX * diff_x); 15.626 + z += (s3d_tri->TdZdX * diff_x); 15.627 + state->u += (s3d_tri->TdUdX * diff_x); 15.628 + state->v += (s3d_tri->TdVdX * diff_x); 15.629 + state->r += (s3d_tri->TdRdX * diff_x); 15.630 + state->g += (s3d_tri->TdGdX * diff_x); 15.631 + state->b += (s3d_tri->TdBdX * diff_x); 15.632 + state->a += (s3d_tri->TdAdX * diff_x); 15.633 + state->d += (s3d_tri->TdDdX * diff_x); 15.634 + state->w += (s3d_tri->TdWdX * diff_x); 15.635 15.636 - x = virge->s3d.clip_l; 15.637 + x = s3d_tri->clip_l; 15.638 } 15.639 } 15.640 else 15.641 { 15.642 - if (x < virge->s3d.clip_l) 15.643 + if (x < s3d_tri->clip_l) 15.644 goto tri_skip_line; 15.645 - if (xe > virge->s3d.clip_r) 15.646 + if (xe > s3d_tri->clip_r) 15.647 goto tri_skip_line; 15.648 - if (xe < virge->s3d.clip_l) 15.649 - xe = virge->s3d.clip_l; 15.650 - if (x > virge->s3d.clip_r) 15.651 + if (xe < s3d_tri->clip_l) 15.652 + xe = s3d_tri->clip_l; 15.653 + if (x > s3d_tri->clip_r) 15.654 { 15.655 - int diff_x = x - virge->s3d.clip_r; 15.656 + int diff_x = x - s3d_tri->clip_r; 15.657 15.658 - z += (virge->s3d.TdZdX * diff_x); 15.659 - state->u += (virge->s3d.TdUdX * diff_x); 15.660 - state->v += (virge->s3d.TdVdX * diff_x); 15.661 - state->r += (virge->s3d.TdRdX * diff_x); 15.662 - state->g += (virge->s3d.TdGdX * diff_x); 15.663 - state->b += (virge->s3d.TdBdX * diff_x); 15.664 - state->a += (virge->s3d.TdAdX * diff_x); 15.665 - state->d += (virge->s3d.TdDdX * diff_x); 15.666 - state->w += (virge->s3d.TdWdX * diff_x); 15.667 + z += (s3d_tri->TdZdX * diff_x); 15.668 + state->u += (s3d_tri->TdUdX * diff_x); 15.669 + state->v += (s3d_tri->TdVdX * diff_x); 15.670 + state->r += (s3d_tri->TdRdX * diff_x); 15.671 + state->g += (s3d_tri->TdGdX * diff_x); 15.672 + state->b += (s3d_tri->TdBdX * diff_x); 15.673 + state->a += (s3d_tri->TdAdX * diff_x); 15.674 + state->d += (s3d_tri->TdDdX * diff_x); 15.675 + state->w += (s3d_tri->TdWdX * diff_x); 15.676 15.677 - x = virge->s3d.clip_r; 15.678 + x = s3d_tri->clip_r; 15.679 } 15.680 } 15.681 } 15.682 @@ -2362,7 +2434,7 @@ 15.683 15.684 dest_pixel(state); 15.685 15.686 - if (virge->s3d.cmd_set & CMD_SET_ABC_ENABLE) 15.687 + if (s3d_tri->cmd_set & CMD_SET_ABC_ENABLE) 15.688 { 15.689 uint32_t src_col; 15.690 int src_r, src_g, src_b; 15.691 @@ -2404,19 +2476,19 @@ 15.692 break; 15.693 } 15.694 15.695 - if (use_z && (virge->s3d.cmd_set & CMD_SET_ZUP)) 15.696 + if (use_z && (s3d_tri->cmd_set & CMD_SET_ZUP)) 15.697 Z_WRITE(z_addr, src_z); 15.698 } 15.699 15.700 - z += virge->s3d.TdZdX; 15.701 - state->u += virge->s3d.TdUdX; 15.702 - state->v += virge->s3d.TdVdX; 15.703 - state->r += virge->s3d.TdRdX; 15.704 - state->g += virge->s3d.TdGdX; 15.705 - state->b += virge->s3d.TdBdX; 15.706 - state->a += virge->s3d.TdAdX; 15.707 - state->d += virge->s3d.TdDdX; 15.708 - state->w += virge->s3d.TdWdX; 15.709 + z += s3d_tri->TdZdX; 15.710 + state->u += s3d_tri->TdUdX; 15.711 + state->v += s3d_tri->TdVdX; 15.712 + state->r += s3d_tri->TdRdX; 15.713 + state->g += s3d_tri->TdGdX; 15.714 + state->b += s3d_tri->TdBdX; 15.715 + state->a += s3d_tri->TdAdX; 15.716 + state->d += s3d_tri->TdDdX; 15.717 + state->w += s3d_tri->TdWdX; 15.718 dest_addr += x_offset; 15.719 z_addr += xz_offset; 15.720 virge->pixel_count++; 15.721 @@ -2425,18 +2497,18 @@ 15.722 tri_skip_line: 15.723 state->x1 += dx1; 15.724 state->x2 += dx2; 15.725 - state->base_u += virge->s3d.TdUdY; 15.726 - state->base_v += virge->s3d.TdVdY; 15.727 - state->base_z += virge->s3d.TdZdY; 15.728 - state->base_r += virge->s3d.TdRdY; 15.729 - state->base_g += virge->s3d.TdGdY; 15.730 - state->base_b += virge->s3d.TdBdY; 15.731 - state->base_a += virge->s3d.TdAdY; 15.732 - state->base_d += virge->s3d.TdDdY; 15.733 - state->base_w += virge->s3d.TdWdY; 15.734 + state->base_u += s3d_tri->TdUdY; 15.735 + state->base_v += s3d_tri->TdVdY; 15.736 + state->base_z += s3d_tri->TdZdY; 15.737 + state->base_r += s3d_tri->TdRdY; 15.738 + state->base_g += s3d_tri->TdGdY; 15.739 + state->base_b += s3d_tri->TdBdY; 15.740 + state->base_a += s3d_tri->TdAdY; 15.741 + state->base_d += s3d_tri->TdDdY; 15.742 + state->base_w += s3d_tri->TdWdY; 15.743 state->y--; 15.744 - dest_offset -= virge->s3d.dest_str; 15.745 - z_offset -= virge->s3d.z_str; 15.746 + dest_offset -= s3d_tri->dest_str; 15.747 + z_offset -= s3d_tri->z_str; 15.748 } 15.749 } 15.750 15.751 @@ -2452,7 +2524,7 @@ 15.752 1*2 15.753 }; 15.754 15.755 -static void s3_virge_triangle(virge_t *virge) 15.756 +static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) 15.757 { 15.758 s3d_state_t state; 15.759 15.760 @@ -2462,34 +2534,34 @@ 15.761 uint64_t start_time = timer_read(); 15.762 uint64_t end_time; 15.763 15.764 - state.tbu = virge->s3d.tbu << 11; 15.765 - state.tbv = virge->s3d.tbv << 11; 15.766 + state.tbu = s3d_tri->tbu << 11; 15.767 + state.tbv = s3d_tri->tbv << 11; 15.768 15.769 - state.max_d = (virge->s3d.cmd_set >> 8) & 15; 15.770 + state.max_d = (s3d_tri->cmd_set >> 8) & 15; 15.771 15.772 - state.tex_bdr_clr = virge->s3d.tex_bdr_clr; 15.773 + state.tex_bdr_clr = s3d_tri->tex_bdr_clr; 15.774 15.775 - state.cmd_set = virge->s3d.cmd_set; 15.776 + state.cmd_set = s3d_tri->cmd_set; 15.777 15.778 - state.base_u = virge->s3d.tus; 15.779 - state.base_v = virge->s3d.tvs; 15.780 - state.base_z = virge->s3d.tzs; 15.781 - state.base_r = (int32_t)virge->s3d.trs; 15.782 - state.base_g = (int32_t)virge->s3d.tgs; 15.783 - state.base_b = (int32_t)virge->s3d.tbs; 15.784 - state.base_a = (int32_t)virge->s3d.tas; 15.785 - state.base_d = virge->s3d.tds; 15.786 - state.base_w = virge->s3d.tws; 15.787 + state.base_u = s3d_tri->tus; 15.788 + state.base_v = s3d_tri->tvs; 15.789 + state.base_z = s3d_tri->tzs; 15.790 + state.base_r = (int32_t)s3d_tri->trs; 15.791 + state.base_g = (int32_t)s3d_tri->tgs; 15.792 + state.base_b = (int32_t)s3d_tri->tbs; 15.793 + state.base_a = (int32_t)s3d_tri->tas; 15.794 + state.base_d = s3d_tri->tds; 15.795 + state.base_w = s3d_tri->tws; 15.796 15.797 - tex_base = virge->s3d.tex_base; 15.798 + tex_base = s3d_tri->tex_base; 15.799 for (c = 9; c >= 0; c--) 15.800 { 15.801 state.texture[c] = (uint16_t *)&virge->svga.vram[tex_base]; 15.802 if (c <= state.max_d) 15.803 - tex_base += ((1 << (c*2)) * tex_size[(virge->s3d.cmd_set >> 5) & 7]) / 2; 15.804 + tex_base += ((1 << (c*2)) * tex_size[(s3d_tri->cmd_set >> 5) & 7]) / 2; 15.805 } 15.806 15.807 - switch ((virge->s3d.cmd_set >> 27) & 0xf) 15.808 + switch ((s3d_tri->cmd_set >> 27) & 0xf) 15.809 { 15.810 case 0: 15.811 dest_pixel = dest_pixel_gouraud_shaded_triangle; 15.812 @@ -2497,7 +2569,7 @@ 15.813 break; 15.814 case 1: 15.815 case 5: 15.816 - switch ((virge->s3d.cmd_set >> 15) & 0x3) 15.817 + switch ((s3d_tri->cmd_set >> 15) & 0x3) 15.818 { 15.819 case 0: 15.820 dest_pixel = dest_pixel_lit_texture_reflection; 15.821 @@ -2512,7 +2584,7 @@ 15.822 // pclog("dest_pixel_lit_texture_decal\n"); 15.823 break; 15.824 default: 15.825 - pclog("bad triangle type %x\n", (virge->s3d.cmd_set >> 27) & 0xf); 15.826 + pclog("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf); 15.827 return; 15.828 } 15.829 break; 15.830 @@ -2522,11 +2594,11 @@ 15.831 // pclog("dest_pixel_unlit_texture_triangle\n"); 15.832 break; 15.833 default: 15.834 - pclog("bad triangle type %x\n", (virge->s3d.cmd_set >> 27) & 0xf); 15.835 + pclog("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf); 15.836 return; 15.837 } 15.838 15.839 - switch (((virge->s3d.cmd_set >> 12) & 7) | ((virge->s3d.cmd_set & (1 << 29)) ? 8 : 0)) 15.840 + switch (((s3d_tri->cmd_set >> 12) & 7) | ((s3d_tri->cmd_set & (1 << 29)) ? 8 : 0)) 15.841 { 15.842 case 0: case 1: 15.843 tex_sample = tex_sample_mipmap; 15.844 @@ -2574,33 +2646,33 @@ 15.845 break; 15.846 } 15.847 15.848 - switch ((virge->s3d.cmd_set >> 5) & 7) 15.849 + switch ((s3d_tri->cmd_set >> 5) & 7) 15.850 { 15.851 case 0: 15.852 - tex_read = (virge->s3d.cmd_set & CMD_SET_TWE) ? tex_ARGB8888 : tex_ARGB8888_nowrap; 15.853 + tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB8888 : tex_ARGB8888_nowrap; 15.854 break; 15.855 case 1: 15.856 - tex_read = (virge->s3d.cmd_set & CMD_SET_TWE) ? tex_ARGB4444 : tex_ARGB4444_nowrap; 15.857 + tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB4444 : tex_ARGB4444_nowrap; 15.858 // pclog("tex_ARGB4444\n"); 15.859 break; 15.860 case 2: 15.861 - tex_read = (virge->s3d.cmd_set & CMD_SET_TWE) ? tex_ARGB1555 : tex_ARGB1555_nowrap; 15.862 -// pclog("tex_ARGB1555 %i\n", (virge->s3d.cmd_set >> 5) & 7); 15.863 + tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB1555 : tex_ARGB1555_nowrap; 15.864 +// pclog("tex_ARGB1555 %i\n", (s3d_tri->cmd_set >> 5) & 7); 15.865 break; 15.866 default: 15.867 - pclog("bad texture type %i\n", (virge->s3d.cmd_set >> 5) & 7); 15.868 - tex_read = (virge->s3d.cmd_set & CMD_SET_TWE) ? tex_ARGB1555 : tex_ARGB1555_nowrap; 15.869 + pclog("bad texture type %i\n", (s3d_tri->cmd_set >> 5) & 7); 15.870 + tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB1555 : tex_ARGB1555_nowrap; 15.871 break; 15.872 } 15.873 15.874 -// pclog("Triangle %i %i,%i to %i,%i %08x\n", y, x1 >> 20, y, virge->s3d.txend01 >> 20, y - (virge->s3d.ty01 + virge->s3d.ty12), state.cmd_set); 15.875 +// pclog("Triangle %i %i,%i to %i,%i %08x\n", y, x1 >> 20, y, s3d_tri->txend01 >> 20, y - (s3d_tri->ty01 + s3d_tri->ty12), state.cmd_set); 15.876 15.877 - state.y = virge->s3d.tys; 15.878 - state.x1 = virge->s3d.txs; 15.879 - state.x2 = virge->s3d.txend01; 15.880 - tri(virge, &state, virge->s3d.ty01, virge->s3d.TdXdY02, virge->s3d.TdXdY01); 15.881 - state.x2 = virge->s3d.txend12; 15.882 - tri(virge, &state, virge->s3d.ty12, virge->s3d.TdXdY02, virge->s3d.TdXdY12); 15.883 + state.y = s3d_tri->tys; 15.884 + state.x1 = s3d_tri->txs; 15.885 + state.x2 = s3d_tri->txend01; 15.886 + tri(virge, s3d_tri, &state, s3d_tri->ty01, s3d_tri->TdXdY02, s3d_tri->TdXdY01); 15.887 + state.x2 = s3d_tri->txend12; 15.888 + tri(virge, s3d_tri, &state, s3d_tri->ty12, s3d_tri->TdXdY02, s3d_tri->TdXdY12); 15.889 15.890 virge->tri_count++; 15.891 15.892 @@ -2609,6 +2681,43 @@ 15.893 virge_time += end_time - start_time; 15.894 } 15.895 15.896 +static void render_thread(void *param) 15.897 +{ 15.898 + virge_t *virge = (virge_t *)param; 15.899 + 15.900 + while (1) 15.901 + { 15.902 + thread_wait_event(virge->wake_render_thread, -1); 15.903 + thread_reset_event(virge->wake_render_thread); 15.904 + virge->s3d_busy = 1; 15.905 + while (!RB_EMPTY) 15.906 + { 15.907 + s3_virge_triangle(virge, &virge->s3d_buffer[virge->s3d_read_idx & RB_MASK]); 15.908 + virge->s3d_read_idx++; 15.909 + 15.910 + if (RB_ENTRIES == RB_SIZE - 1) 15.911 + thread_set_event(virge->not_full_event); 15.912 + } 15.913 + virge->s3d_busy = 0; 15.914 + } 15.915 +} 15.916 + 15.917 +static void queue_triangle(virge_t *virge) 15.918 +{ 15.919 + int c; 15.920 +// pclog("queue_triangle: read=%i write=%i RB_ENTRIES=%i RB_FULL=%i\n", virge->s3d_read_idx, virge->s3d_write_idx, RB_ENTRIES, RB_FULL); 15.921 + if (RB_FULL) 15.922 + { 15.923 + thread_reset_event(virge->not_full_event); 15.924 + if (RB_FULL) 15.925 + thread_wait_event(virge->not_full_event, -1); /*Wait for room in ringbuffer*/ 15.926 + } 15.927 +// pclog(" add at read=%i write=%i %i\n", virge->s3d_read_idx, virge->s3d_write_idx, virge->s3d_write_idx & RB_MASK); 15.928 + virge->s3d_buffer[virge->s3d_write_idx & RB_MASK] = virge->s3d_tri; 15.929 + virge->s3d_write_idx++; 15.930 + if (!virge->s3d_busy) 15.931 + thread_set_event(virge->wake_render_thread); /*Wake up render thread if moving from idle*/ 15.932 +} 15.933 15.934 static void s3_virge_hwcursor_draw(svga_t *svga, int displine) 15.935 { 15.936 @@ -3098,6 +3207,11 @@ 15.937 virge->is_375 = 0; 15.938 15.939 pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); 15.940 + 15.941 + virge->wake_render_thread = thread_create_event(); 15.942 + virge->wake_main_thread = thread_create_event(); 15.943 + virge->not_full_event = thread_create_event(); 15.944 + virge->render_thread = thread_create(render_thread, virge); 15.945 15.946 return virge; 15.947 } 15.948 @@ -3186,6 +3300,11 @@ 15.949 15.950 pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); 15.951 15.952 + virge->wake_render_thread = thread_create_event(); 15.953 + virge->wake_main_thread = thread_create_event(); 15.954 + virge->not_full_event = thread_create_event(); 15.955 + virge->render_thread = thread_create(render_thread, virge); 15.956 + 15.957 return virge; 15.958 } 15.959 15.960 @@ -3196,6 +3315,11 @@ 15.961 fwrite(virge->svga.vram, 4 << 20, 1, f); 15.962 fclose(f); 15.963 15.964 + thread_kill(virge->render_thread); 15.965 + thread_destroy_event(virge->not_full_event); 15.966 + thread_destroy_event(virge->wake_main_thread); 15.967 + thread_destroy_event(virge->wake_render_thread); 15.968 + 15.969 svga_close(&virge->svga); 15.970 15.971 free(virge); 15.972 @@ -3225,12 +3349,10 @@ 15.973 virge->svga.fullchange = changeframecount; 15.974 } 15.975 15.976 -static int s3_virge_add_status_info(char *s, int max_len, void *p) 15.977 +static void s3_virge_add_status_info(char *s, int max_len, void *p) 15.978 { 15.979 virge_t *virge = (virge_t *)p; 15.980 - int cur_len; 15.981 char temps[256]; 15.982 - 15.983 uint64_t new_time = timer_read(); 15.984 uint64_t status_diff = new_time - status_time; 15.985 status_time = new_time; 15.986 @@ -3238,15 +3360,14 @@ 15.987 if (!status_diff) 15.988 status_diff = 1; 15.989 15.990 - cur_len = svga_add_status_info(s, cur_len, &virge->svga); 15.991 - sprintf(temps, "%f Mpixels/sec\n%f ktris/sec\n%f%% CPU\n%f%% CPU (real)\n%d writes", (double)virge->pixel_count/1000000.0, (double)virge->tri_count/1000.0, ((double)virge_time * 100.0) / timer_freq, ((double)virge_time * 100.0) / status_diff, reg_writes); 15.992 - strncat(s, temps, cur_len); 15.993 - cur_len -= strlen(temps); 15.994 + svga_add_status_info(s, max_len, &virge->svga); 15.995 + sprintf(temps, "%f Mpixels/sec\n%f ktris/sec\n%f%% CPU\n%f%% CPU (real)\n%d writes %i reads\n\n", (double)virge->pixel_count/1000000.0, (double)virge->tri_count/1000.0, ((double)virge_time * 100.0) / timer_freq, ((double)virge_time * 100.0) / status_diff, reg_writes, reg_reads); 15.996 + strncat(s, temps, max_len); 15.997 + 15.998 virge->pixel_count = virge->tri_count = 0; 15.999 virge_time = 0; 15.1000 + reg_reads = 0; 15.1001 reg_writes = 0; 15.1002 - 15.1003 - return max_len - cur_len; 15.1004 } 15.1005 15.1006 static device_config_t s3_virge_config[] =
16.1 --- a/src/vid_svga.c Wed Jul 16 20:44:29 2014 +0100 16.2 +++ b/src/vid_svga.c Tue Jul 22 21:10:39 2014 +0100 16.3 @@ -1181,8 +1181,6 @@ 16.4 void svga_writew(uint32_t addr, uint16_t val, void *p) 16.5 { 16.6 svga_t *svga = (svga_t *)p; 16.7 - if (!svga) 16.8 - exit(-1); 16.9 if (!svga->fast) 16.10 { 16.11 svga_write(addr, val, p); 16.12 @@ -1363,30 +1361,23 @@ 16.13 } 16.14 16.15 16.16 -int svga_add_status_info(char *s, int max_len, void *p) 16.17 +void svga_add_status_info(char *s, int max_len, void *p) 16.18 { 16.19 svga_t *svga = (svga_t *)p; 16.20 char temps[128]; 16.21 - int cur_len = max_len; 16.22 16.23 if (svga->chain4) strcpy(temps, "SVGA chained (possibly mode 13h)\n"); 16.24 else strcpy(temps, "SVGA unchained (possibly mode-X)\n"); 16.25 - strncat(s, temps, cur_len); 16.26 - cur_len -= strlen(temps); 16.27 + strncat(s, temps, max_len); 16.28 16.29 if (!svga->video_bpp) strcpy(temps, "SVGA in text mode\n"); 16.30 else sprintf(temps, "SVGA colour depth : %i bpp\n", svga->video_bpp); 16.31 - strncat(s, temps, cur_len); 16.32 - cur_len -= strlen(temps); 16.33 + strncat(s, temps, max_len); 16.34 16.35 sprintf(temps, "SVGA resolution : %i x %i\n", svga->video_res_x, svga->video_res_y); 16.36 - strncat(s, temps, cur_len); 16.37 - cur_len -= strlen(temps); 16.38 + strncat(s, temps, max_len); 16.39 16.40 sprintf(temps, "SVGA refresh rate : %i Hz\n\n", svga->frames); 16.41 svga->frames = 0; 16.42 - strncat(s, temps, cur_len); 16.43 - cur_len -= strlen(temps); 16.44 - 16.45 - return max_len - cur_len; 16.46 + strncat(s, temps, max_len); 16.47 }
17.1 --- a/src/vid_svga.h Wed Jul 16 20:44:29 2014 +0100 17.2 +++ b/src/vid_svga.h Tue Jul 22 21:10:39 2014 +0100 17.3 @@ -128,7 +128,7 @@ 17.4 void svga_writew_linear(uint32_t addr, uint16_t val, void *p); 17.5 void svga_writel_linear(uint32_t addr, uint32_t val, void *p); 17.6 17.7 -int svga_add_status_info(char *s, int max_len, void *p); 17.8 +void svga_add_status_info(char *s, int max_len, void *p); 17.9 17.10 extern uint8_t svga_rotate[8][256]; 17.11
18.1 --- a/src/vid_tgui9440.c Wed Jul 16 20:44:29 2014 +0100 18.2 +++ b/src/vid_tgui9440.c Tue Jul 22 21:10:39 2014 +0100 18.3 @@ -1111,11 +1111,11 @@ 18.4 tgui_accel_command(32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), tgui); 18.5 } 18.6 18.7 -int tgui_add_status_info(char *s, int max_len, void *p) 18.8 +void tgui_add_status_info(char *s, int max_len, void *p) 18.9 { 18.10 tgui_t *tgui = (tgui_t *)p; 18.11 18.12 - return svga_add_status_info(s, max_len, &tgui->svga); 18.13 + svga_add_status_info(s, max_len, &tgui->svga); 18.14 } 18.15 18.16 static device_config_t tgui9440_config[] =
19.1 --- a/src/vid_tvga.c Wed Jul 16 20:44:29 2014 +0100 19.2 +++ b/src/vid_tvga.c Tue Jul 22 21:10:39 2014 +0100 19.3 @@ -300,11 +300,11 @@ 19.4 tvga->svga.fullchange = changeframecount; 19.5 } 19.6 19.7 -int tvga_add_status_info(char *s, int max_len, void *p) 19.8 +void tvga_add_status_info(char *s, int max_len, void *p) 19.9 { 19.10 tvga_t *tvga = (tvga_t *)p; 19.11 19.12 - return svga_add_status_info(s, max_len, &tvga->svga); 19.13 + svga_add_status_info(s, max_len, &tvga->svga); 19.14 } 19.15 19.16 static device_config_t tvga_config[] =
20.1 --- a/src/vid_vga.c Wed Jul 16 20:44:29 2014 +0100 20.2 +++ b/src/vid_vga.c Tue Jul 22 21:10:39 2014 +0100 20.3 @@ -125,11 +125,11 @@ 20.4 vga->svga.fullchange = changeframecount; 20.5 } 20.6 20.7 -int vga_add_status_info(char *s, int max_len, void *p) 20.8 +void vga_add_status_info(char *s, int max_len, void *p) 20.9 { 20.10 vga_t *vga = (vga_t *)p; 20.11 20.12 - return svga_add_status_info(s, max_len, &vga->svga); 20.13 + svga_add_status_info(s, max_len, &vga->svga); 20.14 } 20.15 20.16 device_t vga_device =
21.1 --- a/src/win-status.c Wed Jul 16 20:44:29 2014 +0100 21.2 +++ b/src/win-status.c Tue Jul 22 21:10:39 2014 +0100 21.3 @@ -13,10 +13,8 @@ 21.4 int status_is_open = 0; 21.5 21.6 extern int sreadlnum, swritelnum, segareads, segawrites, scycles_lost; 21.7 - 21.8 static BOOL CALLBACK status_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) 21.9 { 21.10 - char s[256]; 21.11 char device_s[4096]; 21.12 switch (message) 21.13 { 21.14 @@ -28,7 +26,7 @@ 21.15 "FPU speed : %f MFLOPS\n\n" 21.16 "Cache misses (read) : %i/sec\n" 21.17 "Cache misses (write) : %i/sec\n\n" 21.18 - "Video throughput (read) : %i bytes/sec\n\n" 21.19 + "Video throughput (read) : %i bytes/sec\n" 21.20 "Video throughput (write) : %i bytes/sec\n\n" 21.21 "Effective clockspeed : %iHz\n\n" 21.22 "Timer 0 frequency : %fHz\n\n", 21.23 @@ -57,6 +55,7 @@ 21.24 } 21.25 break; 21.26 } 21.27 + 21.28 return FALSE; 21.29 } 21.30
22.1 --- a/src/win.c Wed Jul 16 20:44:29 2014 +0100 22.2 +++ b/src/win.c Tue Jul 22 21:10:39 2014 +0100 22.3 @@ -21,6 +21,7 @@ 22.4 #include "model.h" 22.5 #include "nvr.h" 22.6 #include "sound.h" 22.7 +#include "thread.h" 22.8 22.9 #include "plat-midi.h" 22.10 #include "plat-keyboard.h" 22.11 @@ -183,6 +184,70 @@ 22.12 } 22.13 } 22.14 22.15 +void *thread_create(void (*thread_rout)(void *param), void *param) 22.16 +{ 22.17 + return (void *)_beginthread(thread_rout, 0, param); 22.18 +} 22.19 + 22.20 +void thread_kill(void *handle) 22.21 +{ 22.22 + TerminateThread(handle, 0); 22.23 +} 22.24 + 22.25 +void thread_sleep(int t) 22.26 +{ 22.27 + Sleep(t); 22.28 +} 22.29 + 22.30 +typedef struct win_event_t 22.31 +{ 22.32 + HANDLE handle; 22.33 +} win_event_t; 22.34 + 22.35 +event_t *thread_create_event() 22.36 +{ 22.37 + win_event_t *event = malloc(sizeof(win_event_t)); 22.38 + 22.39 + event->handle = CreateEvent(NULL, FALSE, FALSE, NULL); 22.40 + 22.41 + return (event_t *)event; 22.42 +} 22.43 + 22.44 +void thread_set_event(event_t *_event) 22.45 +{ 22.46 + win_event_t *event = (win_event_t *)_event; 22.47 + 22.48 + SetEvent(event->handle); 22.49 +} 22.50 + 22.51 +void thread_reset_event(event_t *_event) 22.52 +{ 22.53 + win_event_t *event = (win_event_t *)_event; 22.54 + 22.55 + ResetEvent(event->handle); 22.56 +} 22.57 + 22.58 +int thread_wait_event(event_t *_event, int timeout) 22.59 +{ 22.60 + win_event_t *event = (win_event_t *)_event; 22.61 + 22.62 + if (timeout == -1) 22.63 + timeout = INFINITE; 22.64 + 22.65 + if (WaitForSingleObject(event->handle, timeout)) 22.66 + return 1; 22.67 + return 0; 22.68 +} 22.69 + 22.70 +void thread_destroy_event(event_t *_event) 22.71 +{ 22.72 + win_event_t *event = (win_event_t *)_event; 22.73 + 22.74 + CloseHandle(event->handle); 22.75 + 22.76 + free(event); 22.77 +} 22.78 + 22.79 static void initmenu(void) 22.80 { 22.81 int c;
