Reply 60 of 64, by ElTentakel
myne wrote on 2026-10-22, 02:17:I was randomly looking at the code, and with my limited understanding it looks like there's some optimisations to be found. […]
I was randomly looking at the code, and with my limited understanding it looks like there's some optimisations to be found.
This, at face value looks like an important function probably called a lot.
If it's not a hot path used thousands of times a second, it doesn't matter.
If it IS, then it looks like it should be broken into different functions and the correct one selected during init.As an example, imagine I ask you to cut 5000 pieces of wood and you're an idiot that can only follow a flow chart.
Every time you are given a piece of wood, your first question is
"what is this?"
"Should I use scissors, a saw or a knife?"
Only after a bunch of decisions for EACH piece, do you start cutting.IF this is a hot path, that's wildly inefficient.
You make the decisions first. Set up a cutting saw function, and just dump wood into the "in box".Again, I could be very wrong. This could be the "upfront" decision tree and the actual drawing function is elsewhere, but it DOES SAY "Apply fog" which is what makes me think it is the thing that adds fog.
If I were to optimise it, I'd split it into "apply_no_fog", "apply_fixed_fog", "Apply_multi_fog" or something like that and then just set the correct one as your current "cutting saw" station and blindly feed it data.
Reusing code is often very useful. But there's a time and a place to get fancy with one flexible multitool, and a time to build 10 custom single purpose factories.
https://github.com/ElTentakel/Glidulator/blob … voodoo_render.h
#define APPLY_FOG(src_r, src_g, src_b, z, ia, w) \do { \if (params->fogMode & FOG_CONSTANT) { \src_r += params->fogColor.r; \src_g += params->fogColor.g; \src_b += params->fogColor.b; \} else { \int fog_r, fog_g, fog_b, fog_a = 0; \int fog_idx; \\if (!(params->fogMode & FOG_ADD)) { \fog_r = params->fogColor.r; \fog_g = params->fogColor.g; \fog_b = params->fogColor.b; \} else \fog_r = fog_g = fog_b = 0; \\if (!(params->fogMode & FOG_MULT)) { \fog_r -= src_r; \fog_g -= src_g; \fog_b -= src_b; \} \\switch (params->fogMode & (FOG_Z | FOG_ALPHA)) { \case 0: \fog_idx = (w_depth >> 10) & 0x3f; \\fog_a = params->fogTable[fog_idx].fog; \fog_a += (params->fogTable[fog_idx].dfog * ((w_depth >> 2) & 0xff)) >> 10; \break; \case FOG_Z: \fog_a = (z >> 20) & 0xff; \break; \case FOG_ALPHA: \fog_a = CLAMP(ia >> 12); \break; \case FOG_W: \fog_a = CLAMP((w >> 32) & 0xff); \break; \} \fog_a++; \\fog_r = (fog_r * fog_a) >> 8; \fog_g = (fog_g * fog_a) >> 8; \fog_b = (fog_b * fog_a) >> 8; \\if (params->fogMode & FOG_MULT) { \src_r = fog_r; \src_g = fog_g; \src_b = fog_b; \} else { \src_r += fog_r; \src_g += fog_g; \src_b += fog_b; \} \} \\src_r = CLAMP(src_r); \src_g = CLAMP(src_g); \src_b = CLAMP(src_b); \} while (0)
I've tested it, but it seems that there is not much difference. It seems that the branch prediction is good enough, so there is no need to optimize the decision. And the JIT version doesn't even make those decisions, so there is no need to optimize it either. But thank you for sharing this idea 😀.