jdmclark / jkgfxmod

Graphics enhancement and compatibility tool for Dark Forces II
MIT License
74 stars 7 forks source link

HUD texture update does not scale at high resolutions #63

Closed jdmclark closed 3 years ago

jdmclark commented 3 years ago

I already have a planned solution for this problem. I am opening this bug to log some details (and to open discussion).

One of the more persistent scalability problems in JkGfxMod concerns the way JK renders its HUD: The original game draws the HUD elements, in software, by writing directly into display memory. This is obviously not a feasible approach anymore. As a workaround, JkGfxMod intercepts this attempt to write to display memory, and instead substitutes the framebuffer with its own in-RAM buffer. This buffer is then streamed to the GPU every frame and drawn over the scene, as a textured mesh.

Unfortunately, JK still thinks it's drawing directly to the screen. In order for all of this to work, the fake framebuffer needs to be the same resolution as the screen. In turn, the texture that's streamed to the GPU has to be the same resolution as the screen. This gets very expensive at high resolutions.

On my test machine (i7 6700k with GTX 1080 non-Ti), updating the HUD texture at 4k consumes 3.24 ms of the 10.99 ms frame time (nearly 30%). In other words, it's the difference between about 130 fps without HUD or 90 fps with it.

This scalability problem should be addressed.

jdmclark commented 3 years ago

I was able to reduce the per-frame overhead from 3.24ms to 0.72ms by amortizing HUD texture update over 4 frames (i.e. 90 fps to 118 fps in the above scenario). 4 seems to be the sweet spot: amortizing over more frames did not yield a significant performance benefit, but the cost increases quickly below that number.

This change significantly reduces JkGfxMod's overhead at higher resolutions, but the cost for this improvement is a max 4, expected 2 frame lag to HUD updates. In practical terms, in my particular test scenario this was equivalent to capping the HUD to 30 FPS. I doubt I would have even noticed normally, and even if I had, I would definitely be happy with the tradeoff.