GL3: Make gl3drawCmd_t smaller. Step 1: shader->shaderidx, char lmtexnum

It was 112 bytes, I aim for <= 40 bytes :)

we only have 17 shaders, so they can easily be indexed with an int8
instead of wasting a full pointer.

we have up to 4 lightmap textures and lmtexnum only is an index anyway,
so that too get be an int8 (char)
This commit is contained in:
Daniel Gibson 2026-07-17 00:04:41 +02:00
parent a40a062186
commit 2013aecee3
4 changed files with 61 additions and 23 deletions

View file

@ -773,6 +773,8 @@ void GL3_Draw3DBatchesNow()
curState.scroll = gl3state.uni3DData.scroll;
curState.lightScaleForTurb = gl3state.uni3DData.lightScaleForTurb;
gl3ShaderInfo_t* shader = NULL;
// .. but at least set the identity mat so DCFlag_IsIdentityMat can be set
// as a sane default
curState.flags |= DCFlag_IsIdentityMat;
@ -787,7 +789,11 @@ void GL3_Draw3DBatchesNow()
int curFlags = curState.flags;
qboolean updateUni3D = false;
GL3_UseProgram(cmd->shader->shaderProgram);
if(cmd->shaderIdx != curState.shaderIdx)
{
shader = GL3_GetDrawCmdShader(cmd);
GL3_UseProgram( shader->shaderProgram );
}
if(cmd->texnum != gl3state.currenttexture)
GL3_Bind(cmd->texnum);
if(cmd->lmtexnum >= 0)
@ -836,7 +842,7 @@ void GL3_Draw3DBatchesNow()
lmScales[map].B = r_newrefdef.lightstyles[cmd->styles[map]].rgb[2];
lmScales[map].A = 1.0f;
}
UpdateLMscales(lmScales, cmd->shader);
UpdateLMscales(lmScales, shader);
}
if(flags & DCFlag_UseColor)
@ -903,7 +909,7 @@ void GL3_Draw3DBatchesNow()
static qboolean drawStateEqual(const gl3drawCmd_t* a, const gl3drawCmd_t* b)
{
if( a->flags != b->flags || a->shader != b->shader
if( a->flags != b->flags || a->shaderIdx != b->shaderIdx
|| a->texnum != b->texnum || a->lmtexnum != b->lmtexnum )
return false;
@ -952,7 +958,7 @@ GL3_BufferAndDraw3D(const gl3_3D_vtx_t* verts, int numVerts, GLenum drawMode, gl
GLushort nextVtxIdx = da_count(vtxBuf);
drawCmd.idxBufOffset = da_count(idxBuf);
assert(drawCmd.shader != NULL);
assert(drawCmd.shaderIdx != -1);
// translate triangle fan/strip to just triangle indices
if(drawMode == GL_TRIANGLE_FAN)
@ -1068,7 +1074,7 @@ GL3_DrawBeam(entity_t *e)
//glDisable(GL_TEXTURE_2D);
drawCmd.flags |= (DCFlag_Blend | DCFlag_DisableDepthMask | DCFlag_UseColor);
drawCmd.shader = &gl3state.si3DcolorOnly;
GL3_SetDrawCmdShader(&drawCmd, &gl3state.si3DcolorOnly);
drawCmd.color[0] = (LittleLong(d_8to24table[e->skinnum & 0xFF])) & 0xFF;
drawCmd.color[1] = (LittleLong(d_8to24table[e->skinnum & 0xFF]) >> 8) & 0xFF;
@ -1135,13 +1141,13 @@ GL3_DrawSpriteModel(entity_t *e, gl3model_t *currentmodel)
if (alpha == 1.0)
{
// use shader with alpha test
drawCmd.shader = &gl3state.si3DspriteAlpha;
GL3_SetDrawCmdShader(&drawCmd, &gl3state.si3DspriteAlpha);
}
else
{
drawCmd.flags |= DCFlag_Blend;
drawCmd.shader = &gl3state.si3Dsprite;
GL3_SetDrawCmdShader(&drawCmd, &gl3state.si3Dsprite);
}
verts[0].texCoord[0] = 0;
@ -1198,8 +1204,7 @@ GL3_DrawNullModel(entity_t *currententity)
}
drawCmd.flags |= DCFlag_UseColor;
drawCmd.shader = &gl3state.si3DcolorOnly;
GL3_SetDrawCmdShader(&drawCmd, &gl3state.si3DcolorOnly);
gl3_3D_vtx_t vtxA[6] = {
{{0, 0, -16}, {0,0}, {0,0}},

View file

@ -270,16 +270,15 @@ RenderBrushPoly(entity_t *currententity, msurface_t *fa, gl3drawCmd_t drawCmd)
// and put fa->styles[] into the 3d draw vertex?
memcpy(drawCmd.styles, fa->styles, sizeof(fa->styles));
drawCmd.flags |= DCFlag_UseLmStyles;
static_assert(sizeof(fa->styles) == 4, "asd"); // TODO: remove
if (fa->texinfo->flags & SURF_FLOWING)
{
drawCmd.shader = &gl3state.si3DlmFlow;
GL3_SetDrawCmdShader(&drawCmd, &gl3state.si3DlmFlow);
GL3_DrawGLFlowingPoly(fa, drawCmd);
}
else
{
drawCmd.shader = &gl3state.si3Dlm;
GL3_SetDrawCmdShader(&drawCmd, &gl3state.si3Dlm);
GL3_DrawGLPoly(fa, drawCmd);
}
@ -323,12 +322,12 @@ GL3_DrawAlphaSurfaces(void)
}
else if (s->texinfo->flags & SURF_FLOWING)
{
drawCmd.shader = &gl3state.si3DtransFlow;
GL3_SetDrawCmdShader(&drawCmd, &gl3state.si3DtransFlow);
GL3_DrawGLFlowingPoly(s, drawCmd);
}
else
{
drawCmd.shader = &gl3state.si3Dtrans;
GL3_SetDrawCmdShader(&drawCmd, &gl3state.si3Dtrans);
GL3_DrawGLPoly(s, drawCmd);
}
}
@ -395,12 +394,12 @@ RenderLightmappedPoly(entity_t *currententity, msurface_t *surf, gl3drawCmd_t dr
if (surf->texinfo->flags & SURF_FLOWING)
{
drawCmd.shader = &gl3state.si3DlmFlow;
GL3_SetDrawCmdShader(&drawCmd, &gl3state.si3DlmFlow);
GL3_DrawGLFlowingPoly(surf, drawCmd);
}
else
{
drawCmd.shader = &gl3state.si3Dlm;
GL3_SetDrawCmdShader(&drawCmd, &gl3state.si3Dlm);
GL3_DrawGLPoly(surf, drawCmd);
}
}

View file

@ -255,7 +255,7 @@ GL3_EmitWaterPolys(msurface_t *fa, gl3drawCmd_t drawCmd)
drawCmd.shader = &gl3state.si3Dturb;
GL3_SetDrawCmdShader(&drawCmd, &gl3state.si3Dturb);
for (bp = fa->polys; bp != NULL; bp = bp->next)
{
@ -699,7 +699,7 @@ GL3_DrawSkyBox(void)
}
drawCmd.transModelMat = modMVmat;
drawCmd.shader = &gl3state.si3Dsky;
GL3_SetDrawCmdShader(&drawCmd, &gl3state.si3Dsky);
// TODO: this could all be done in one drawcall.. but.. whatever, it's <= 6 drawcalls/frame
// also, they use different textures..

View file

@ -56,6 +56,8 @@
#include "../../ref_shared.h"
#include <stddef.h> // offsetof()
#include "HandmadeMath.h"
#define DG_DYNARR_ASSERT(cond, msg) \
@ -231,7 +233,7 @@ typedef struct
GLuint currentShaderProgram;
GLuint currentUBO;
// NOTE: make sure si2D is always the first shaderInfo (or adapt GL3_ShutdownShaders())
// NOTE: make sure si2D is always the first shaderInfo (or adapt GL3_ShutdownShaders() and GL3_SetDrawCmdShader())
gl3ShaderInfo_t si2D; // shader for rendering 2D with textures
gl3ShaderInfo_t si2Dtinted; // shader for rendering 2D with textures and color tinting
gl3ShaderInfo_t si2Dcolor; // shader for rendering 2D with flat colors
@ -277,10 +279,10 @@ typedef struct
// drawcommands using gl3_3D_vtx_t, for batching
typedef struct gl3drawCmd_s {
hmm_mat4 transModelMat;
gl3ShaderInfo_t* shader;
GLuint texnum;
int lmtexnum;
signed char lmtexnum;
signed char shaderIdx;
float scroll; // for gl3state.uni3DData.scroll
float lightScaleForTurb; // for gl3state.uni3DData.lightScaleForTurb
@ -320,16 +322,48 @@ GL3_CreateDrawCmd(qboolean identityTrans)
ret.alpha = 1.0f;
ret.styles[0] = 255;
ret.lmtexnum = -1;
ret.shaderIdx = -1;
// the other values can remain 0/NULL
return ret;
}
extern gl3config_t gl3config;
extern gl3state_t gl3state;
enum {
_gl3_numShaders = 1 + ((offsetof(gl3state_t, siParticle) - offsetof(gl3state_t, si2D)) / sizeof(gl3ShaderInfo_t))
};
static inline void
GL3_SetDrawCmdShader(gl3drawCmd_t* drawCmd, const gl3ShaderInfo_t* shader)
{
if(shader == NULL)
{
drawCmd->shaderIdx = -1;
return;
}
ptrdiff_t offset = shader - &gl3state.si2D;
if( offset >= 0 && offset < _gl3_numShaders)
{
drawCmd->shaderIdx = offset;
}
else
{
assert(0 && "invalid shader!");
drawCmd->shaderIdx = -1;
}
}
static inline gl3ShaderInfo_t*
GL3_GetDrawCmdShader(const gl3drawCmd_t* drawCmd)
{
unsigned shaderIdx = drawCmd->shaderIdx;
if(shaderIdx >= _gl3_numShaders) // because it's unsigned this also handles shaderIdx -1
return NULL;
return &gl3state.si2D + shaderIdx;
}
extern int gl3_visframecount; /* bumped when going to a new PVS */
extern int gl3_framecount; /* used for dlight push checking */