backport 864691defbc55453071050b5cc8408079a8f3199 to fix llvm 13 build engine: use inthash_t for _prprograminfo lookups instead of a 300MB array Index: source/build/src/polymer.cpp --- source/build/src/polymer.cpp.orig +++ source/build/src/polymer.cpp @@ -84,6 +84,9 @@ const GLbitfield prindexringmapflags = GL_MAP_WRITE_BI _prbucket *prbuckethead; int32_t prcanbucket; +static inthashtable_t prprogramtable = { nullptr, INTHASH_SIZE(256) }; +static GrowArray<_prprograminfo *> prprogramptrs; + static const _prvert vertsprite[4] = { { @@ -691,8 +694,6 @@ static const _prprogrambit prprogrambits[PR_BIT_COUN } }; -_prprograminfo prprograms[1 << PR_BIT_COUNT]; - int32_t overridematerial; int32_t globaloldoverridematerial; @@ -797,17 +798,12 @@ int32_t polymer_init(void) i++; } - i = 0; - while (i < (1 << PR_BIT_COUNT)) - { - prprograms[i].handle = 0; - i++; - } - overridematerial = 0xFFFFFFFF; polymersearching = FALSE; + inthash_init(&prprogramtable); + polymer_initrendertargets(pr_shadowcount + 1); // Prime highpalookup maps @@ -868,7 +864,6 @@ void polymer_uninit(void) } polymer_freeboard(); - polymer_initrendertargets(0); i = 0; @@ -901,6 +896,19 @@ void polymer_uninit(void) if (pr_verbosity >= 3) OSD_Printf("PR: freed %d planelists\n", i); + + inthash_free(&prprogramtable); + + for (auto &pr : prprogramptrs) + { + glDeleteProgram(pr->handle); + DO_FREE_AND_NULL(pr); + } + + if (pr_verbosity >= 2) + OSD_Printf("PR: freed %" PRIi64 " programs\n", prprogramptrs.size()); + + prprogramptrs.clear(); } void polymer_setaspect(int32_t ang) @@ -2307,6 +2315,12 @@ static void polymer_bucketplane(_prplane* plan } } +static inline _prprograminfo *polymer_getprogram(int32_t materialbits) +{ + intptr_t progptr = inthash_find(&prprogramtable, materialbits); + return (progptr != -1) ? (_prprograminfo *)progptr : polymer_compileprogram(materialbits); +} + static void polymer_drawplane(_prplane* plane) { int32_t materialbits; @@ -2390,12 +2404,13 @@ static void polymer_drawplane(_prplane* plane) curlight = 0; do { materialbits = polymer_bindmaterial(&plane->material, plane->lights, plane->lightcount); + auto &prprogram = *polymer_getprogram(materialbits); if (materialbits & prprogrambits[PR_BIT_NORMAL_MAP].bit) { - glVertexAttrib3fv(prprograms[materialbits].attrib_T, &plane->tbn[0][0]); - glVertexAttrib3fv(prprograms[materialbits].attrib_B, &plane->tbn[1][0]); - glVertexAttrib3fv(prprograms[materialbits].attrib_N, &plane->tbn[2][0]); + glVertexAttrib3fv(prprogram.attrib_T, &plane->tbn[0][0]); + glVertexAttrib3fv(prprogram.attrib_B, &plane->tbn[1][0]); + glVertexAttrib3fv(prprogram.attrib_N, &plane->tbn[2][0]); } if (plane->indices) @@ -5228,10 +5243,9 @@ static int32_t polymer_bindmaterial(const _prmate programbits |= prprogrambits[PR_BIT_FOOTER].bit; // --------- program compiling - if (!prprograms[programbits].handle) - polymer_compileprogram(programbits); + auto &prprogram = *polymer_getprogram(programbits); - polymost_useShaderProgram(prprograms[programbits].handle); + polymost_useShaderProgram(prprogram.handle); // --------- bit setup @@ -5240,20 +5254,20 @@ static int32_t polymer_bindmaterial(const _prmate // PR_BIT_ANIM_INTERPOLATION if (programbits & prprogrambits[PR_BIT_ANIM_INTERPOLATION].bit) { - glEnableVertexAttribArray(prprograms[programbits].attrib_nextFrameData); - if (prprograms[programbits].attrib_nextFrameNormal != -1) - glEnableVertexAttribArray(prprograms[programbits].attrib_nextFrameNormal); - glVertexAttribPointer(prprograms[programbits].attrib_nextFrameData, + glEnableVertexAttribArray(prprogram.attrib_nextFrameData); + if (prprogram.attrib_nextFrameNormal != -1) + glEnableVertexAttribArray(prprogram.attrib_nextFrameNormal); + glVertexAttribPointer(prprogram.attrib_nextFrameData, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 15, material->nextframedata); - if (prprograms[programbits].attrib_nextFrameNormal != -1) - glVertexAttribPointer(prprograms[programbits].attrib_nextFrameNormal, + if (prprogram.attrib_nextFrameNormal != -1) + glVertexAttribPointer(prprogram.attrib_nextFrameNormal, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 15, material->nextframedata + 3); - glUniform1f(prprograms[programbits].uniform_frameProgress, material->frameprogress); + glUniform1f(prprogram.uniform_frameProgress, material->frameprogress); } // PR_BIT_LIGHTING_PASS @@ -5283,31 +5297,31 @@ static int32_t polymer_bindmaterial(const _prmate if (material->mdspritespace == GL_TRUE) { float mdspritespacepos[3]; polymer_transformpoint(pos, mdspritespacepos, (float *)mdspritespace); - glUniform3fv(prprograms[programbits].uniform_eyePosition, 1, mdspritespacepos); + glUniform3fv(prprogram.uniform_eyePosition, 1, mdspritespacepos); } else - glUniform3fv(prprograms[programbits].uniform_eyePosition, 1, pos); - glUniform1i(prprograms[programbits].uniform_normalMap, texunit); + glUniform3fv(prprogram.uniform_eyePosition, 1, pos); + glUniform1i(prprogram.uniform_normalMap, texunit); if (pr_overrideparallax) { bias[0] = pr_parallaxscale; bias[1] = pr_parallaxbias; - glUniform2fv(prprograms[programbits].uniform_normalBias, 1, bias); + glUniform2fv(prprogram.uniform_normalBias, 1, bias); } else - glUniform2fv(prprograms[programbits].uniform_normalBias, 1, material->normalbias); + glUniform2fv(prprogram.uniform_normalBias, 1, material->normalbias); if (material->tbn) { - glEnableVertexAttribArray(prprograms[programbits].attrib_T); - glEnableVertexAttribArray(prprograms[programbits].attrib_B); - glEnableVertexAttribArray(prprograms[programbits].attrib_N); + glEnableVertexAttribArray(prprogram.attrib_T); + glEnableVertexAttribArray(prprogram.attrib_B); + glEnableVertexAttribArray(prprogram.attrib_N); - glVertexAttribPointer(prprograms[programbits].attrib_T, + glVertexAttribPointer(prprogram.attrib_T, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 15, material->tbn); - glVertexAttribPointer(prprograms[programbits].attrib_B, + glVertexAttribPointer(prprogram.attrib_B, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 15, material->tbn + 3); - glVertexAttribPointer(prprograms[programbits].attrib_N, + glVertexAttribPointer(prprogram.attrib_N, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 15, material->tbn + 6); @@ -5322,29 +5336,29 @@ static int32_t polymer_bindmaterial(const _prmate polymost_activeTexture(texunit + GL_TEXTURE0); polymost_bindTexture(GL_TEXTURE_2D, material->artmap); - glUniform1i(prprograms[programbits].uniform_artMap, texunit); + glUniform1i(prprogram.uniform_artMap, texunit); texunit++; polymost_activeTexture(texunit + GL_TEXTURE0); polymost_bindTexture(GL_TEXTURE_2D, material->basepalmap); - glUniform1i(prprograms[programbits].uniform_basePalMap, texunit); + glUniform1i(prprogram.uniform_basePalMap, texunit); texunit++; polymost_activeTexture(texunit + GL_TEXTURE0); polymost_bindTexture(GL_TEXTURE_RECTANGLE_ARB, material->lookupmap); - glUniform1i(prprograms[programbits].uniform_lookupMap, texunit); + glUniform1i(prprogram.uniform_lookupMap, texunit); texunit++; - glUniform1f(prprograms[programbits].uniform_shadeOffset, (GLfloat)material->shadeoffset); + glUniform1f(prprogram.uniform_shadeOffset, (GLfloat)material->shadeoffset); if (r_usenewshading == 4) { // the fog in Polymer is a sphere insted of a plane, the furthest visible point should be the same as Polymost - glUniform1f(prprograms[programbits].uniform_visibility, globalvisibility / 262144.f * material->visibility); + glUniform1f(prprogram.uniform_visibility, globalvisibility / 262144.f * material->visibility); } else { @@ -5358,7 +5372,7 @@ static int32_t polymer_bindmaterial(const _prmate static constexpr float factor_old = 1.f / ((2048.f * (1.07f / 1.024f) / 35.f) * material_visibility_divisor); - glUniform1f(prprograms[programbits].uniform_visibility, globalvisibility * material->visibility * r_usenewshading > 1 ? factor_new : factor_old); + glUniform1f(prprogram.uniform_visibility, globalvisibility * material->visibility * r_usenewshading > 1 ? factor_new : factor_old); } } @@ -5368,8 +5382,8 @@ static int32_t polymer_bindmaterial(const _prmate polymost_activeTexture(texunit + GL_TEXTURE0); polymost_bindTexture(GL_TEXTURE_2D, material->diffusemap); - glUniform1i(prprograms[programbits].uniform_diffuseMap, texunit); - glUniform2fv(prprograms[programbits].uniform_diffuseScale, 1, material->diffusescale); + glUniform1i(prprogram.uniform_diffuseMap, texunit); + glUniform2fv(prprogram.uniform_diffuseScale, 1, material->diffusescale); texunit++; } @@ -5380,7 +5394,7 @@ static int32_t polymer_bindmaterial(const _prmate polymost_activeTexture(texunit + GL_TEXTURE0); polymost_bindTexture(GL_TEXTURE_3D, material->highpalookupmap); - glUniform1i(prprograms[programbits].uniform_highPalookupMap, texunit); + glUniform1i(prprogram.uniform_highPalookupMap, texunit); texunit++; } @@ -5403,8 +5417,8 @@ static int32_t polymer_bindmaterial(const _prmate polymost_activeTexture(texunit + GL_TEXTURE0); polymost_bindTexture(GL_TEXTURE_2D, material->detailmap); - glUniform1i(prprograms[programbits].uniform_detailMap, texunit); - glUniform2fv(prprograms[programbits].uniform_detailScale, 1, scale); + glUniform1i(prprogram.uniform_detailMap, texunit); + glUniform2fv(prprogram.uniform_detailScale, 1, scale); texunit++; } @@ -5424,7 +5438,7 @@ static int32_t polymer_bindmaterial(const _prmate polymost_activeTexture(texunit + GL_TEXTURE0); polymost_bindTexture(GL_TEXTURE_2D, material->specmap); - glUniform1i(prprograms[programbits].uniform_specMap, texunit); + glUniform1i(prprogram.uniform_specMap, texunit); texunit++; } @@ -5437,9 +5451,9 @@ static int32_t polymer_bindmaterial(const _prmate if (pr_overridespecular) { specmaterial[0] = pr_specularpower; specmaterial[1] = pr_specularfactor; - glUniform2fv(prprograms[programbits].uniform_specMaterial, 1, specmaterial); + glUniform2fv(prprogram.uniform_specMaterial, 1, specmaterial); } else - glUniform2fv(prprograms[programbits].uniform_specMaterial, 1, material->specmaterial); + glUniform2fv(prprogram.uniform_specMaterial, 1, material->specmaterial); } // PR_BIT_MIRROR_MAP @@ -5448,14 +5462,14 @@ static int32_t polymer_bindmaterial(const _prmate polymost_activeTexture(texunit + GL_TEXTURE0); polymost_bindTexture(GL_TEXTURE_RECTANGLE_ARB, material->mirrormap); - glUniform1i(prprograms[programbits].uniform_mirrorMap, texunit); + glUniform1i(prprogram.uniform_mirrorMap, texunit); texunit++; } #ifdef PR_LINEAR_FOG if (programbits & prprogrambits[PR_BIT_FOG].bit) { - glUniform1i(prprograms[programbits].uniform_linearFog, r_usenewshading >= 2); + glUniform1i(prprogram.uniform_linearFog, r_usenewshading >= 2); } #endif // PR_BIT_GLOW_MAP @@ -5464,7 +5478,7 @@ static int32_t polymer_bindmaterial(const _prmate polymost_activeTexture(texunit + GL_TEXTURE0); polymost_bindTexture(GL_TEXTURE_2D, material->glowmap); - glUniform1i(prprograms[programbits].uniform_glowMap, texunit); + glUniform1i(prprogram.uniform_glowMap, texunit); texunit++; } @@ -5507,8 +5521,8 @@ static int32_t polymer_bindmaterial(const _prmate indir[1] = (float)(sintable[(prlights[lights[curlight]].faderadius+512)&2047]) / 16383.0f; indir[1] = 1.0 / (indir[1] - indir[0]); - glUniform3fv(prprograms[programbits].uniform_spotDir, 1, dir); - glUniform2fv(prprograms[programbits].uniform_spotRadius, 1, indir); + glUniform3fv(prprogram.uniform_spotDir, 1, dir); + glUniform2fv(prprogram.uniform_spotRadius, 1, indir); // PR_BIT_PROJECTION_MAP if (programbits & prprogrambits[PR_BIT_PROJECTION_MAP].bit) @@ -5525,7 +5539,7 @@ static int32_t polymer_bindmaterial(const _prmate glLoadIdentity(); glMatrixMode(GL_MODELVIEW); - glUniformMatrix4fv(prprograms[programbits].uniform_shadowProjMatrix, 1, GL_FALSE, matrix); + glUniformMatrix4fv(prprogram.uniform_shadowProjMatrix, 1, GL_FALSE, matrix); // PR_BIT_SHADOW_MAP if (programbits & prprogrambits[PR_BIT_SHADOW_MAP].bit) @@ -5533,7 +5547,7 @@ static int32_t polymer_bindmaterial(const _prmate polymost_activeTexture(texunit + GL_TEXTURE0); polymost_bindTexture(prrts[prlights[lights[curlight]].rtindex].target, prrts[prlights[lights[curlight]].rtindex].z); - glUniform1i(prprograms[programbits].uniform_shadowMap, texunit); + glUniform1i(prprogram.uniform_shadowMap, texunit); texunit++; } @@ -5544,7 +5558,7 @@ static int32_t polymer_bindmaterial(const _prmate polymost_activeTexture(texunit + GL_TEXTURE0); polymost_bindTexture(GL_TEXTURE_2D, prlights[lights[curlight]].lightmap); - glUniform1i(prprograms[programbits].uniform_lightMap, texunit); + glUniform1i(prprogram.uniform_lightMap, texunit); texunit++; } @@ -5584,14 +5598,15 @@ static int32_t polymer_bindmaterial(const _prmate static void polymer_unbindmaterial(int32_t programbits) { + auto &prprogram = *polymer_getprogram(programbits); // repair any dirty GL state here // PR_BIT_ANIM_INTERPOLATION if (programbits & prprogrambits[PR_BIT_ANIM_INTERPOLATION].bit) { - if (prprograms[programbits].attrib_nextFrameNormal != -1) - glDisableVertexAttribArray(prprograms[programbits].attrib_nextFrameNormal); - glDisableVertexAttribArray(prprograms[programbits].attrib_nextFrameData); + if (prprogram.attrib_nextFrameNormal != -1) + glDisableVertexAttribArray(prprogram.attrib_nextFrameNormal); + glDisableVertexAttribArray(prprogram.attrib_nextFrameData); } // PR_BIT_LIGHTING_PASS @@ -5603,15 +5618,15 @@ static void polymer_unbindmaterial(int32_t pro // PR_BIT_NORMAL_MAP if (programbits & prprogrambits[PR_BIT_NORMAL_MAP].bit) { - glDisableVertexAttribArray(prprograms[programbits].attrib_T); - glDisableVertexAttribArray(prprograms[programbits].attrib_B); - glDisableVertexAttribArray(prprograms[programbits].attrib_N); + glDisableVertexAttribArray(prprogram.attrib_T); + glDisableVertexAttribArray(prprogram.attrib_B); + glDisableVertexAttribArray(prprogram.attrib_N); } polymost_useShaderProgram(0); } -static void polymer_compileprogram(int32_t programbits) +static _prprograminfo *polymer_compileprogram(int32_t programbits) { int32_t i, enabledbits; GLuint vert, frag, program; @@ -5675,8 +5690,10 @@ static void polymer_compileprogram(int32_t pro glGetProgramInfoLog(program, PR_INFO_LOG_BUFFER_SIZE, NULL, infobuffer); - prprograms[programbits].handle = program; + auto &prprogram = *(_prprograminfo *)Xcalloc(1, sizeof(_prprograminfo)); + prprogram.handle = program; + #ifdef DEBUGGINGAIDS if (pr_verbosity >= 1) #else @@ -5697,105 +5714,109 @@ static void polymer_compileprogram(int32_t pro // PR_BIT_ANIM_INTERPOLATION if (programbits & prprogrambits[PR_BIT_ANIM_INTERPOLATION].bit) { - prprograms[programbits].attrib_nextFrameData = glGetAttribLocation(program, "nextFrameData"); - prprograms[programbits].attrib_nextFrameNormal = glGetAttribLocation(program, "nextFrameNormal"); - prprograms[programbits].uniform_frameProgress = glGetUniformLocation(program, "frameProgress"); + prprogram.attrib_nextFrameData = glGetAttribLocation(program, "nextFrameData"); + prprogram.attrib_nextFrameNormal = glGetAttribLocation(program, "nextFrameNormal"); + prprogram.uniform_frameProgress = glGetUniformLocation(program, "frameProgress"); } // PR_BIT_NORMAL_MAP if (programbits & prprogrambits[PR_BIT_NORMAL_MAP].bit) { - prprograms[programbits].attrib_T = glGetAttribLocation(program, "T"); - prprograms[programbits].attrib_B = glGetAttribLocation(program, "B"); - prprograms[programbits].attrib_N = glGetAttribLocation(program, "N"); - prprograms[programbits].uniform_eyePosition = glGetUniformLocation(program, "eyePosition"); - prprograms[programbits].uniform_normalMap = glGetUniformLocation(program, "normalMap"); - prprograms[programbits].uniform_normalBias = glGetUniformLocation(program, "normalBias"); + prprogram.attrib_T = glGetAttribLocation(program, "T"); + prprogram.attrib_B = glGetAttribLocation(program, "B"); + prprogram.attrib_N = glGetAttribLocation(program, "N"); + prprogram.uniform_eyePosition = glGetUniformLocation(program, "eyePosition"); + prprogram.uniform_normalMap = glGetUniformLocation(program, "normalMap"); + prprogram.uniform_normalBias = glGetUniformLocation(program, "normalBias"); } // PR_BIT_ART_MAP if (programbits & prprogrambits[PR_BIT_ART_MAP].bit) { - prprograms[programbits].uniform_artMap = glGetUniformLocation(program, "artMap"); - prprograms[programbits].uniform_basePalMap = glGetUniformLocation(program, "basePalMap"); - prprograms[programbits].uniform_lookupMap = glGetUniformLocation(program, "lookupMap"); - prprograms[programbits].uniform_shadeOffset = glGetUniformLocation(program, "shadeOffset"); - prprograms[programbits].uniform_visibility = glGetUniformLocation(program, "visibility"); + prprogram.uniform_artMap = glGetUniformLocation(program, "artMap"); + prprogram.uniform_basePalMap = glGetUniformLocation(program, "basePalMap"); + prprogram.uniform_lookupMap = glGetUniformLocation(program, "lookupMap"); + prprogram.uniform_shadeOffset = glGetUniformLocation(program, "shadeOffset"); + prprogram.uniform_visibility = glGetUniformLocation(program, "visibility"); } // PR_BIT_DIFFUSE_MAP if (programbits & prprogrambits[PR_BIT_DIFFUSE_MAP].bit) { - prprograms[programbits].uniform_diffuseMap = glGetUniformLocation(program, "diffuseMap"); - prprograms[programbits].uniform_diffuseScale = glGetUniformLocation(program, "diffuseScale"); + prprogram.uniform_diffuseMap = glGetUniformLocation(program, "diffuseMap"); + prprogram.uniform_diffuseScale = glGetUniformLocation(program, "diffuseScale"); } // PR_BIT_HIGHPALOOKUP_MAP if (programbits & prprogrambits[PR_BIT_HIGHPALOOKUP_MAP].bit) { - prprograms[programbits].uniform_highPalookupMap = glGetUniformLocation(program, "highPalookupMap"); + prprogram.uniform_highPalookupMap = glGetUniformLocation(program, "highPalookupMap"); } // PR_BIT_DIFFUSE_DETAIL_MAP if (programbits & prprogrambits[PR_BIT_DIFFUSE_DETAIL_MAP].bit) { - prprograms[programbits].uniform_detailMap = glGetUniformLocation(program, "detailMap"); - prprograms[programbits].uniform_detailScale = glGetUniformLocation(program, "detailScale"); + prprogram.uniform_detailMap = glGetUniformLocation(program, "detailMap"); + prprogram.uniform_detailScale = glGetUniformLocation(program, "detailScale"); } // PR_BIT_SPECULAR_MAP if (programbits & prprogrambits[PR_BIT_SPECULAR_MAP].bit) { - prprograms[programbits].uniform_specMap = glGetUniformLocation(program, "specMap"); + prprogram.uniform_specMap = glGetUniformLocation(program, "specMap"); } // PR_BIT_SPECULAR_MATERIAL if (programbits & prprogrambits[PR_BIT_SPECULAR_MATERIAL].bit) { - prprograms[programbits].uniform_specMaterial = glGetUniformLocation(program, "specMaterial"); + prprogram.uniform_specMaterial = glGetUniformLocation(program, "specMaterial"); } // PR_BIT_MIRROR_MAP if (programbits & prprogrambits[PR_BIT_MIRROR_MAP].bit) { - prprograms[programbits].uniform_mirrorMap = glGetUniformLocation(program, "mirrorMap"); + prprogram.uniform_mirrorMap = glGetUniformLocation(program, "mirrorMap"); } #ifdef PR_LINEAR_FOG if (programbits & prprogrambits[PR_BIT_FOG].bit) { - prprograms[programbits].uniform_linearFog = glGetUniformLocation(program, "linearFog"); + prprogram.uniform_linearFog = glGetUniformLocation(program, "linearFog"); } #endif // PR_BIT_GLOW_MAP if (programbits & prprogrambits[PR_BIT_GLOW_MAP].bit) { - prprograms[programbits].uniform_glowMap = glGetUniformLocation(program, "glowMap"); + prprogram.uniform_glowMap = glGetUniformLocation(program, "glowMap"); } // PR_BIT_PROJECTION_MAP if (programbits & prprogrambits[PR_BIT_PROJECTION_MAP].bit) { - prprograms[programbits].uniform_shadowProjMatrix = glGetUniformLocation(program, "shadowProjMatrix"); + prprogram.uniform_shadowProjMatrix = glGetUniformLocation(program, "shadowProjMatrix"); } // PR_BIT_SHADOW_MAP if (programbits & prprogrambits[PR_BIT_SHADOW_MAP].bit) { - prprograms[programbits].uniform_shadowMap = glGetUniformLocation(program, "shadowMap"); + prprogram.uniform_shadowMap = glGetUniformLocation(program, "shadowMap"); } // PR_BIT_LIGHT_MAP if (programbits & prprogrambits[PR_BIT_LIGHT_MAP].bit) { - prprograms[programbits].uniform_lightMap = glGetUniformLocation(program, "lightMap"); + prprogram.uniform_lightMap = glGetUniformLocation(program, "lightMap"); } // PR_BIT_SPOT_LIGHT if (programbits & prprogrambits[PR_BIT_SPOT_LIGHT].bit) { - prprograms[programbits].uniform_spotDir = glGetUniformLocation(program, "spotDir"); - prprograms[programbits].uniform_spotRadius = glGetUniformLocation(program, "spotRadius"); + prprogram.uniform_spotDir = glGetUniformLocation(program, "spotDir"); + prprogram.uniform_spotRadius = glGetUniformLocation(program, "spotRadius"); } + + inthash_add(&prprogramtable, programbits, (intptr_t)&prprogram, 0); + prprogramptrs.append(&prprogram); + return prprogramptrs.last(); } // LIGHTS