Although the skin pointer was being advanced after recording the
information in for the batch array, it was being reset the next time
around the loop (due to a mistranslation of the previous code). This
fixes the segfault while loading (gl, glsl, vulkan) or rendering (sw)
the sphere model from Rogue.
Some very much needed comments :P Still, nicely, I now have a much
better understanding of how the display lists are created (10 years
is a long time to remember how intricate code works (I do remember
fighting to get it working back then))
This makes it much easier to see just what is being done to build a
polygon to be passed to the GPU, and it served as a test for the
lightmap st changes since Vulkan currently never used them.
Many modders use negative lights for interesting effects, but vulkan
doesn't like the result of a negative int treated as unsigned when it
comes to texture sizes.
However, this time it doesn't modify the light array when it sorts the
lights by size since the lights are now located before the renderer gets
to see them, and having the fix up the light leafs array would be too
painful (and probably the completely wrong thing to do anyway: the light
array should be treated as constant by the renderer). 1.6GB of memory
for gmsp3v2's lights (a little better than marcher: more smaller lights?).
For reference:
gmsp3v2: shadow maps: 8330 layers in 29 images: 1647706112
marcher: shadow maps: 2440 layers in 11 images: 2358575104
While it wasn't the root cause of the disappearing lights (even after
sorting out the light limit issue), because the cause of that was
everything working as designed, I suspect sunlight wasn't reaching as
far as it should. Even it it was, this should be slightly faster
(especially for larger maps) as leafs can be tested 32 or 64 at a time
rather than individually.
They should probably be cause leafsurfaces since they are the actual
surfaces of the leaf: ie, the faces of the leaf mesh if each leaf was
sub-sub-model.
For now, at least (I have some ideas to possibly reduce the numbers and
also to avoid the need for actual limits). I've seen gmsp3v2 use over
500 lights at once (it has over 1300), and I spent too long figuring out
that weird light behavior was due to the limit being hit and lights
getting dropped (and even longer figuring out that more weird behavior
was due to the lack of shadows and the world being too bright in the
first place).
Moving the negation into the calculation of the sun angle prevents -0
getting into the vector (not that it makes much difference other than
minor confusion when reading the light data).
I got tired of being disappointed that nq didn't have colored lights for
the power-ups (especially when I'd waste time thinking it was a bug).
The problem is that the server (progs code) specifies only DIMLIGHT (qw
adds in the colors). Another problem is that the server tells us only
our own stats, so the colors are disabled for multiplayer otherwise it
might be confusing.
This is similar to the change in nq (and for the same reason), making
sure that client shutdown (and thus config writing) happens before input
system shutdown.
I really need to play more while working on the code.
Anyway, ca_active works nicely for the status bar in general, and
CL_ClearMemory needs to be called before Host_ClearMemory when doing
single-player.
Since the staging buffer allocates the command buffers it uses, it
needs to free them when it is freed. I think I was confused by the
validation layers not complaining about unfreed buffers when shutting
down, but that's because destroying the pool (during program shutdown,
when the validation layers would complain) frees all the buffers. Thus,
due to staging buffers being created and destroyed during the level load
process, (rather large) command buffers were piling up like imps in a
Doom level.
In the process, it was necessary to rearrange some of the shutdown code
because vulkan_vid_render_shutdown destroys the shared command pool, but
the pool is required for freeing the command buffers, but there was a
minor mess of long-lived staging buffers being freed afterwards. That
didn't end particularly well.
This ensures that the plugin's shutdown function won't get called twice
in the event of an error in the plugin's unload sequence triggering a
second Sys_Shutdown, especially if the plugin is being unloaded as a
part of another sub-system's shutdown sequence (which is probably in
itself a design mistake, need to look into that).
While gcc was quite correct in its warning, all I needed was to
explicitly truncate the string. I don't remember why I didn't do that
back when I made the changes in 4f58429137, but it works now, and the
surrounding code does expect the string to be no more than 15 chars
long. This fixes yet another memory leak (but timedemo over multiple
runs still leaks like a sieve).
Nasty because it was caused by spaghetti (normally, I like the stuff).
Drinking-age spaghetti at that. Nicely, this removes the need for one
function in sv_ded.c (which is what I think I was trying to achieve).
The error was introduced by the input memory leak fixes, but the
solution is to ensure CL_Shutdown is called before IN_Shutdown.
Some of the memory leaks were quite legitimate this time.
This is meant for a "permanent" tear-down before freeing the memory
holding the VM state or at program shutdown. As a consequence, builtin
sub-systems registering resources are now required to pass a "destroy"
function pointer that will be called just before the memory holding
those resources is freed by the VM resource manager (ie, the manager
owns the resource memory block, but each subsystem is responsible for
cleaning up any resources held within that block).
This even enhances thread-safety in rua_obj (there are some problems
with cmd, cvar, and gib).
This gives a rather significant speed boost to timedemo demo1: from
about 2300-2360fps up to 2520-2600fps, at least when using
multi-texture.
Since it was necessary for testing the scrap, gl got the ability to set
the console background texture, too.
It's down to 128 bytes from 184, which fits nicely in two cache lines.
This made a nice difference to glsl, unknown to vulkan (it crashed after
about 31/51 timedemo loops), and was a was for sw and gl.
While it takes one extra step to grab the marksurface pointer,
R_MarkLeaves and R_MarkLights (the two actual users) seem to be either
the same speed or fractionally faster (by a few microseconds). I imagine
the loss gone to the extra fetch is made up for by better bandwidth
while traversing the leafs array (mleaf_t now fits in a single cache
line, so leafs are cache-aligned since hunk allocations are aligned).
The palette is a modified version of the default VGA colormap as
explained by Noah Johnson (https://github.com/canidlogic/vgapal) and the
generation code is heavily influenced by his code. However, I've
reversed the HSV groups so I could have the pure bright colors in the
fullbright range and added a few colors in the 248-255 range (mostly
greens and ambers meant to be close to the old phosphor monitors).
The colormap is generated by laying the colors from the palette across
the middle of the map (rows 31 and 32) then linearly interpolating from
0 to the color, and the color to 2x the color (clamped) and then
converting back to a palette. Mr Fixit actually looks ok still in the
software renderer (unaffected in the others) though quakeguy is a hoot
in all the renderers :).
Unfortunately, the animations are pre-baked (by the loader) blocking
run-time determined animations (IK etc). However, this at least gets
everything working so the basics can be verified (the shader posed some
issue resulting in horror movies ;).