VOGONS


Reply 80 of 104, by ockiller

User metadata
Rank Newbie
Rank
Newbie

My guess is that 32 bit vs 64 bit code would not make a difference if computation is done with SIMD or anything except 64 bit integers. So 32 bit code might be faster, more so on Core 2 which doesn't benefit from macro-fusion in 64 bit.

Also, a pixel pipe contains many operations that are fully pipelined on a Voodoo, which is not the case with CPU emulation so you can't finish one or a multiple of pixels every cycle.

Edit: I forgot a non negligible advantage of 64 bit code, which is double the architectural registers (general and SIMD), but register renaming may help use all the internal registers anyway in 32 bit.

Reply 81 of 104, by myne

User metadata
Rank l33t
Rank
l33t

64bit has more general purpose registers.
It is practically always faster than 32.

SSE is a 128bit wide integer unit which can run 16x8bit integer operations simultaneously.
https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions

Assuming you're working on pairs of RGBA, that means 8 operations, or 2 pixels simultaneously in theory.
Eg, R1+R2, G1+G2, B1+B2, A1+A2, R3+R4, G3+G4, B3+B4, A3+A4

It would depend on the operation, of course, but for a simple addition that is basically how it works.

AVX is similar, but floating point.
It's "wasteful" to work on effectively 8 bit numbers, but with eight 32-bit single-precision floating-point numbers, you effectively repeat the above.
Eg, R1+R2, G1+G2, B1+B2, A1+A2, R3+R4, G3+G4, B3+B4, A3+A4

So if you use both units, you could have a 2 stage "pipeline" in whatever order makes the most sense given converting int > float is implied.

Possibly the FBI is one and TMU the other?

We're talking 2+ghz cpus capable of 16 simultaneous operations trying to emulate a tiny little 50mhz ASIC here. I can't imagine it's not possible to do the equivalent of an SLI voodoo2 comfortably on one core IF the memory can be fetched/cached properly, and both SSE and AVX are pumping.

There has to be a way to break the workload into chunks that suit a CPU's cache/memory architecture.
By function? TMI/FBU =AVX/SSE?
By colour? R first, G, B, then alpha?

I built:
Convert old ASUS ASC boardviews to KICAD PCB!
Re: A comprehensive guide to install and play MechWarrior 2 on new versions on Windows.
Dos+Windows 3.11+tcp+vbe_svga auto-install iso template
Script to backup Win9x\ME drivers from a working install
Re: The thing no one asked for: KICAD 440bx reference schematic

Reply 82 of 104, by RayeR

User metadata
Rank Oldbie
Rank
Oldbie

I just found that Glidulator can run on multiple cores under Crazii's VDPMI (I though it's impossible in V86 mode at general).
So I could get it running with SBEMU VDPMI version. And it runs fine with Tomb Raider (using PC No-CD 😀 Rendering seems to be capped at 30FPS @640x480 accodring to HUD info, it's playable smoothly...

Gigabyte GA-P67-DS3-B3, Core i7-2600K @4,5GHz, 8GB DDR3, 128GB SSD, GTX970(GF7900GT), SB Audigy + YMF724F + DreamBlaster combo + LPC2ISA

Reply 83 of 104, by myne

User metadata
Rank l33t
Rank
l33t

Feel like trying out Descent II or Carmageddon? Apparently they're "intensive" and not frame capped.
NFI if it's true or slopscination

What CPU?

I built:
Convert old ASUS ASC boardviews to KICAD PCB!
Re: A comprehensive guide to install and play MechWarrior 2 on new versions on Windows.
Dos+Windows 3.11+tcp+vbe_svga auto-install iso template
Script to backup Win9x\ME drivers from a working install
Re: The thing no one asked for: KICAD 440bx reference schematic

Reply 84 of 104, by ElTentakel

User metadata
Rank Newbie
Rank
Newbie

I think you are both right: Glidulator doesn't depend on the OS running on CPU0, and the other cores act just like microcontrollers. But 64-bit is not the holy grail, even if it shines from a distance. The Voodoo doesn't calculate with 8 bits but with 12.12 fixed-point, and Z is even 20.12. So you need 16- or 32-bit lanes, which means 4-8 pixels per vector. And as ockiller stated, the Voodoo does many things in parallel within a single clock, which takes a CPU roughly 50-200 clocks per pixel (according to Claude). Or, to look at it from another angle: for 90 MPix/s on a single 3.4 GHz core, there are only about 38 clocks left per pixel. Also, the Voodoo1 processes only about 1 pixel per clock, and the Voodoo2 only adds a second TMU for a second texture in the same pass. SLI is not relevant here, since Glidulator already spreads the load across multiple cores in an SLI'isch way (it turned out that grouping lines into blocks is much more efficient than interleaving single lines).

Also, SSE and AVX use the same ports and registers, so using them "in parallel" is not possible. Instead, mixing legacy SSE and AVX code causes heavy transition penalties, especially on Haswell (which is a very nice target for this software). Cache misses are not the problem: the cache should be big enough to hold the textures, and spans are written sequentially. The real costs are the branches for the many render modes, plus texture fetches with filtering and the perspective division.

I will try winsimd, it looks quite promising. But if SIMD math is not the bottleneck, the renderer won't benefit much from it anyway. So 64-bit and AVX would work on the worker cores, but I think the gains are elsewhere

Reply 85 of 104, by myne

User metadata
Rank l33t
Rank
l33t

Tell us more about the branches.
And which are the hottest functions in the code?

I built:
Convert old ASUS ASC boardviews to KICAD PCB!
Re: A comprehensive guide to install and play MechWarrior 2 on new versions on Windows.
Dos+Windows 3.11+tcp+vbe_svga auto-install iso template
Script to backup Win9x\ME drivers from a working install
Re: The thing no one asked for: KICAD 440bx reference schematic

Reply 86 of 104, by ElTentakel

User metadata
Rank Newbie
Rank
Newbie
RayeR wrote on Yesterday, 04:44:

I just found that Glidulator can run on multiple cores under Crazii's VDPMI (I though it's impossible in V86 mode at general).
So I could get it running with SBEMU VDPMI version. And it runs fine with Tomb Raider (using PC No-CD 😀 Rendering seems to be capped at 30FPS @640x480 accodring to HUD info, it's playable smoothly...

I`m very happy to hear that 😀.

myne wrote on Yesterday, 07:24:

Feel like trying out Descent II or Carmageddon? Apparently they're "intensive" and not frame capped.
NFI if it's true or slopscination

What CPU?

For Descent II you have to use D2_3DFX, but I haven't tested that yet.

A sidenote: I tried to replace the ddraw.dll to support early DX5-6 titles, but this turns out to be very difficult. I'm thinking to maaaaybe do that for some very specific titles like FF7 or games which have issues with table fog. But I think the best solution is a driver like velocity9x, which does the proper rendering at the right place.

Reply 87 of 104, by ElTentakel

User metadata
Rank Newbie
Rank
Newbie
myne wrote on Yesterday, 10:27:

Tell us more about the branches.
And which are the hottest functions in the code?

I'll get to that, but first I have to play NFS 5 😁. It seems to run fine, but table fog is missing. I need to test more titles before I can say whether it's worthwhile to support Glide3.

Reply 88 of 104, by zyzzle

User metadata
Rank Oldbie
Rank
Oldbie
myne wrote on Yesterday, 07:24:

Feel like trying out Descent II or Carmageddon? Apparently they're "intensive" and not frame capped.
NFI if it's true or slopscination

What CPU?

I thought Glidulator won't work in DOS Tomb Raider or Carmageddon. Has this changed since the release of 0.9.1?

And in Screamer 2 and Screamer Rally 3DFX DOS .exe's, I get 50-60fps on an i7-8600 with MTRRs enabled. With 2x antialsing and the screen AR set to 4:3 centered on the native 1920x1080 display, this drops to 30 fps. All 4 cores are active.

I got about 190-210 fps in 800x600 on RayeR's test30 program posted above. With MTRRs enabled, same system @ 4.2 Ghz.

The difference between disabling MTRRs and enabling them is massive... at least 400-500% faster with MTRRs enabled! Unplayable without MTRR write-cache combining in LFB.

Reply 89 of 104, by myne

User metadata
Rank l33t
Rank
l33t

That's more like it.
I was under the impression it was struggling to hit 60.
All good then.
Prune the branches back and it'll be comfortable on one core as it should be.
And 64 bit has another advantage. You can reserve above 4gb and never worry about conflicts.

I built:
Convert old ASUS ASC boardviews to KICAD PCB!
Re: A comprehensive guide to install and play MechWarrior 2 on new versions on Windows.
Dos+Windows 3.11+tcp+vbe_svga auto-install iso template
Script to backup Win9x\ME drivers from a working install
Re: The thing no one asked for: KICAD 440bx reference schematic

Reply 90 of 104, by myne

User metadata
Rank l33t
Rank
l33t

ElTentakel this might be of some interest to you.
https://github.com/nand2mario/zSST linked in the post I linked a few pages ago.

Well, I ran it through verilator.
https://verilator.org/
After more than a few fails, I got source with the following command:

..\verilator -Wno-WIDTHEXPAND -Wno-WIDTHtrunc -cc .\sst1_pkg.sv .\generated\sst1_regs_pkg.sv .\generated\sst1_tmu_tables_pkg.sv .\frontend\sst1_addr_decode.sv .\frontend\sst1_float_to_fixed.sv .\frontend\sst1_pci_fifo.sv .\frontend\sst1_regfile.sv .\frontend\sst1_frontend.sv .\tmu\sst1_texture_layout.sv .\tmu\sst1_tmu_front_staged.sv .\tmu\sst1_texture_cache_ram.sv .\tmu\sst1_texture_cache.sv .\tmu\sst1_texture_address.sv .\tmu\sst1_texel_decode.sv .\tmu\sst1_texture_combine.sv .\tmu\sst1_tmu.sv .\fbi\sst1_pixel_pipeline.sv .\fbi\sst1_fb_write_combine.sv .\fbi\sst1_fb_read_cache.sv .\fbi\sst1_fbi.sv .\video\sst1_video_control.sv .\sst1_perf_counters.sv .\sst1_core.sv .\sst1_device.sv

-Wno-WIDTHEXPAND -Wno-WIDTHtrunc ignore word size changes. -cc outputs to c++

I built:
Convert old ASUS ASC boardviews to KICAD PCB!
Re: A comprehensive guide to install and play MechWarrior 2 on new versions on Windows.
Dos+Windows 3.11+tcp+vbe_svga auto-install iso template
Script to backup Win9x\ME drivers from a working install
Re: The thing no one asked for: KICAD 440bx reference schematic

Reply 91 of 104, by Kahenraz

User metadata
Rank l33t
Rank
l33t

Am I reading this right? It implements native multi-core support in pure DOS, as long as the system is real-mode?

Reply 92 of 104, by RayeR

User metadata
Rank Oldbie
Rank
Oldbie
Kahenraz wrote on Yesterday, 17:06:

Am I reading this right? It implements native multi-core support in pure DOS, as long as the system is real-mode?

Yes, even it's not have to be in real mode.
BTW there was a proof of concept multicore code for DOS many years ago but so long it was not utilized for some real app, till now...

Gigabyte GA-P67-DS3-B3, Core i7-2600K @4,5GHz, 8GB DDR3, 128GB SSD, GTX970(GF7900GT), SB Audigy + YMF724F + DreamBlaster combo + LPC2ISA

Reply 93 of 104, by BitWrangler

User metadata
Rank l33t++
Rank
l33t++
Kahenraz wrote on Yesterday, 17:06:

Am I reading this right? It implements native multi-core support in pure DOS, as long as the system is real-mode?

Further info on origins... fascinating Plain DOS 2 Core Demo.

Unicorn herding operations are proceeding, but all the totes of hens teeth and barrels of rocking horse poop give them plenty of hiding spots.

Reply 94 of 104, by RayeR

User metadata
Rank Oldbie
Rank
Oldbie

I mean the true origin was here (now it's gone but thanks to webarchive still can be found):
https://web.archive.org/web/20221007133135/ht … ore-Programming

Gigabyte GA-P67-DS3-B3, Core i7-2600K @4,5GHz, 8GB DDR3, 128GB SSD, GTX970(GF7900GT), SB Audigy + YMF724F + DreamBlaster combo + LPC2ISA

Reply 95 of 104, by RayeR

User metadata
Rank Oldbie
Rank
Oldbie
zyzzle wrote on Yesterday, 11:19:

I thought Glidulator won't work in DOS Tomb Raider or Carmageddon. Has this changed since the release of 0.9.1?

Yes it works. You just have to pick up the right Tombraider 3Dfx patch for Voodoo Rush - this one is dynamic-linked so it could load glide2x.ovl (smaller file). That bigger one patch for voodoo1 is static-linked and cannot be used. No-CD patch works as a TSR so it don't patch the exe, it make's it easier...

zyzzle wrote on Yesterday, 11:19:

I got about 190-210 fps in 800x600 on RayeR's test30 program posted above. With MTRRs enabled, same system @ 4.2 Ghz.

I got cca 250 @4,5GHz. Last version 0.9.5 made significant speed up by some 20-30%. Windows version makes more FPS, cca 500 (both with 4 cores).

Gigabyte GA-P67-DS3-B3, Core i7-2600K @4,5GHz, 8GB DDR3, 128GB SSD, GTX970(GF7900GT), SB Audigy + YMF724F + DreamBlaster combo + LPC2ISA

Reply 96 of 104, by myne

User metadata
Rank l33t
Rank
l33t
Kahenraz wrote on Yesterday, 17:06:

Am I reading this right? It implements native multi-core support in pure DOS, as long as the system is real-mode?

I'm not sure it matters what mode dos is in as long as they respect memory ranges.
A chip on the board gets allocated some memory, is loaded with a program and it blindy runs.

It could just as easily be a printer or gpu.

I built:
Convert old ASUS ASC boardviews to KICAD PCB!
Re: A comprehensive guide to install and play MechWarrior 2 on new versions on Windows.
Dos+Windows 3.11+tcp+vbe_svga auto-install iso template
Script to backup Win9x\ME drivers from a working install
Re: The thing no one asked for: KICAD 440bx reference schematic

Reply 97 of 104, by ElTentakel

User metadata
Rank Newbie
Rank
Newbie

Here are the requested hot paths with the relating runs:

Pixel pipeline

The pixel pipeline is the hottest path:

per frame
+- per triangle ........ voodoo_triangle setup, base LOD per TMU
+- per row (span) .. (inside voodoo_triangle) clipping, start values
+- per 8-pixel part voodoo_update_span_part_lod
| 2 double divisions + log2 per TMU
| (only perspective textures with several mip levels)
+- one call into the generated (JIT) code per part, or per row
+- per pixel: depth test
per TMU: vj_persp_fetch (S/W, T/W: two 64x64-bit
multiplications + __udivdi3), texel fetch
colour combine, fog, alpha, dither, write

Quantities per frame:

+-----------------------------+-----------+-----------+-----------+
| | GLQuake | Nature | UT intro |
| | 2 TMUs | 1 TMU | 2 TMUs |
+-----------------------------+-----------+-----------+-----------+
| capture resolution | 640x480 | 512x384 | 640x480 |
| triangles | 274 | 2,191 | 783 |
| rows (spans) | 14,898 | 45,974 | 26,205 |
| 8-pixel LOD parts | 19,936 | 37,108 | 79,017 |
| calls into JIT code | 27,848 | 63,600 | 90,064 |
| pixels covered | 738,946 | 709,393 | 995,232 |
| overdraw | 2.4 x | 3.6 x | 3.2 x |
| vj_persp_fetch calls | 1,235,882 | 275,361 | 1,339,430 |
+-----------------------------+-----------+-----------+-----------+
| pixels per triangle | 2,697 | 324 | 1,271 |
| pixels per row | 50 | 15 | 38 |
| pixels per JIT call | 26.5 | 11.2 | 11.1 |
| vj_persp_fetch per pixel | 1.67 | 0.39 | 1.35 |
+-----------------------------+-----------+-----------+-----------+

required time

+-----------------------------+-------------+-------------+-------------+
| | GLQuake | Nature | UT intro |
+-----------------------------+-------------+-------------+-------------+
| one frame, one thread | 33.0 ms | 21.2 ms | 56.9 ms |
+-----------------------------+-------------+-------------+-------------+
| generated pixel code | 50 % 16.6ms | 41 % 8.8ms | 53 % 29.9ms |
| per JIT call | 596 ns | 138 ns | 332 ns |
| per pixel | 22.5 ns | 12.4 ns | 30.0 ns |
+-----------------------------+-------------+-------------+-------------+
| vj_persp_fetch + __udivdi3 | 37 % 12.3ms | 20 % 4.2ms | 29 % 16.5ms |
| per call | 10.0 ns | 15.3 ns | 12.3 ns |
+-----------------------------+-------------+-------------+-------------+
| voodoo_triangle + log2 | 7 % 2.2ms | 24 % 5.0ms | 13 % 7.6ms |
| (setup, rows, LOD parts) | | | |
| per row + LOD part | 63 ns | 60 ns | 72 ns |
+-----------------------------+-------------+-------------+-------------+
| everything per pixel | 45 ns | 30 ns | 57 ns |
+-----------------------------+-------------+-------------+-------------+

GLQuake draws few, large triangles, so almost all time is spent per pixel. Nature draws many small ones (15 pixels per row), so the per-row and per-part work (voodoo_triangle) takes a quarter of the time. vj_persp_fetch is the single most expensive function. It is called once per pixel and TMU, 10-15 ns each. With two TMUs it is cheaper per call because both TMUs nearly always have the same W and the reciprocal of the last W is cached. Inside the generated code for GLQuake and Nature the texel fetch is 60 % / 45 %, colour combine 16 %, fog/alpha/dither/write 16 % and depth test 9-15 %.

Where the game waits
(glide_mt_idle)

- grBufferSwap, grBufferClear
- every grLfbLock and grLfbWriteRegion
- when the texture cache needs an entry a worker is still using
- vsync

Optimisation Results for Windows 98

+-----------------------------------+------------------------------------------+
| Optimisation | Effect |
+-----------------------------------+------------------------------------------+
| WC (GLIDULATOR_WC, default on; | GLQuake: 37.6 -> 56 fps |
| only needed with VBEMP/generic | GDI copy 9-10 ms -> 0.1 ms per frame |
| drivers) | |
+-----------------------------------+------------------------------------------+
| JIT instead of C path (SSE2) | renderer 1.8-1.9x as fast (replay) |
+-----------------------------------+------------------------------------------+
| Multi-core with GLSMP.VXD | GLQuake (0.9.1): 1 core 15.4 fps, |
| | 4 cores 38.8 fps |
+-----------------------------------+------------------------------------------+
| Hyper-threading (GLIDULATOR_HT=1) | no gain |
+-----------------------------------+------------------------------------------+
| Two TMUs (now default) | GLQuake timedemo 76.6 -> 93.8 fps |
| | UT intro 40-46 -> 51-55 fps |
| | Undying 26 -> 37 fps |
+-----------------------------------+------------------------------------------+
| LOD only where needed (0.9.5) | GLQuake 67.5 -> 76.0 fps |
+-----------------------------------+------------------------------------------+
| 4 MB texture memory | Undying: uploads 12 MB -> 0.4 MB/frame, |
| | 22 -> 26 fps |
+-----------------------------------+------------------------------------------+
| New texture cache | Undying 37 -> 42 fps |
+-----------------------------------+------------------------------------------+
| Voodoo video filter (costs) | GLQuake 69.1 -> 64.8 fps (+0.3 ms out) |
+-----------------------------------+------------------------------------------+
| FSAA 2x (costs) | halves the fps (GLQuake 38.8 -> 19.4) |
+-----------------------------------+------------------------------------------+

Optimisation Results for DOS

+-----------------------------------+------------------------------------------+
| Optimisation | Effect |
+-----------------------------------+------------------------------------------+
| WC (via MTRR, needs ring 0) | output 17.1 -> 2.8 ms per frame |
| | 26 -> 49 fps at the same spot |
+-----------------------------------+------------------------------------------+
| Ring 0 instead of ring 3 | render 9.1 -> 7.1 ms; ring 3 also has |
| (HDPMI32i) | no WC (42 vs 128 fps on average) |
+-----------------------------------+------------------------------------------+
| JIT instead of C | 1.8-1.9x as under Windows; needs ring 0 |
| | or a DPMI host that enables SSE |
+-----------------------------------+------------------------------------------+
| Multi-core, game's core draws too | 2 cores 75 -> 98 fps |
| | 4 cores 125 -> 143 fps |
+-----------------------------------+------------------------------------------+
| Hyper-threading | slower (114 -> 88 fps) |
+-----------------------------------+------------------------------------------+
| LOD only where needed | 104 -> 117 fps |
+-----------------------------------+------------------------------------------+
| Two TMUs | not measured under DOS; |
| | costs about 10 MB more memory |
+-----------------------------------+------------------------------------------+

Open points

- per pixel perspective division (vj_persp_fetch, 20-37 % of the render time). A reciprocal table as on the real hardware would improve ~10 %, but it would change the visual outcome
- LOD calculation per 8-pixel part, most impact for games with many small triangles (Nature: 24 %).

These results are based on the next release, where some caching issues where fixed.

Reply 98 of 104, by ElTentakel

User metadata
Rank Newbie
Rank
Newbie
RayeR wrote on Yesterday, 04:44:

I just found that Glidulator can run on multiple cores under Crazii's VDPMI (I though it's impossible in V86 mode at general).
So I could get it running with SBEMU VDPMI version. And it runs fine with Tomb Raider (using PC No-CD 😀 Rendering seems to be capped at 30FPS @640x480 accodring to HUD info, it's playable smoothly...

How much RAM do you have? I can not get VDPMI+Glidulator running on my Hasswell machine with 32GB of RAM.

Last edited by ElTentakel on 2026-11-08, 14:35. Edited 1 time in total.

Reply 99 of 104, by ElTentakel

User metadata
Rank Newbie
Rank
Newbie
zyzzle wrote on Yesterday, 11:19:
I thought Glidulator won't work in DOS Tomb Raider or Carmageddon. Has this changed since the release of 0.9.1? […]
Show full quote
myne wrote on Yesterday, 07:24:

Feel like trying out Descent II or Carmageddon? Apparently they're "intensive" and not frame capped.
NFI if it's true or slopscination

What CPU?

I thought Glidulator won't work in DOS Tomb Raider or Carmageddon. Has this changed since the release of 0.9.1?

And in Screamer 2 and Screamer Rally 3DFX DOS .exe's, I get 50-60fps on an i7-8600 with MTRRs enabled. With 2x antialsing and the screen AR set to 4:3 centered on the native 1920x1080 display, this drops to 30 fps. All 4 cores are active.

I got about 190-210 fps in 800x600 on RayeR's test30 program posted above. With MTRRs enabled, same system @ 4.2 Ghz.

The difference between disabling MTRRs and enabling them is massive... at least 400-500% faster with MTRRs enabled! Unplayable without MTRR write-cache combining in LFB.

Enabling MTRRs is very important especially with higher resolutions. You can see the impact inside the OSD, look at "Output" time.

Last edited by ElTentakel on 2026-11-08, 15:09. Edited 2 times in total.