From 0cc298d3c03cc31166905b782f9f6545f8eee742 Mon Sep 17 00:00:00 2001 From: havoc Date: Sun, 23 Oct 2005 20:02:31 +0000 Subject: [PATCH] got rid of Mod_CheckLoaded, changed how model system restart works to make this work properly disabled model purging on level change, now only the world model is unloaded, this should improve slightly load times from level to level if a model is used in an early level, then not used in the next, and then used again in the next after that, however it also increases memory usage git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@5758 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_collision.c | 2 -- cl_main.c | 2 -- cl_parse.c | 1 - gl_rmain.c | 2 -- gl_rsurf.c | 1 - model_brush.c | 3 --- model_shared.c | 63 ++++++++++++++++++++++++++------------------------ model_shared.h | 2 -- portals.c | 3 --- sv_main.c | 3 --- world.c | 3 --- 11 files changed, 33 insertions(+), 52 deletions(-) diff --git a/cl_collision.c b/cl_collision.c index 81cc2a38..8f381860 100644 --- a/cl_collision.c +++ b/cl_collision.c @@ -48,7 +48,6 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co cliptrace.fraction = 1; cliptrace.realfraction = 1; - Mod_CheckLoaded(cl.worldmodel); if (cl.worldmodel && cl.worldmodel->TraceBox) cl.worldmodel->TraceBox(cl.worldmodel, 0, &cliptrace, startmins, startmaxs, endmins, endmaxs, hitsupercontentsmask); @@ -196,7 +195,6 @@ float CL_SelectTraceLine(const vec3_t start, const vec3_t end, vec3_t impact, ve if (hitent) *hitent = 0; - Mod_CheckLoaded(cl.worldmodel); if (cl.worldmodel && cl.worldmodel->TraceBox) cl.worldmodel->TraceBox(cl.worldmodel, 0, &trace, start, start, end, end, SUPERCONTENTS_SOLID); diff --git a/cl_main.c b/cl_main.c index 2cae309c..908c8d15 100644 --- a/cl_main.c +++ b/cl_main.c @@ -708,7 +708,6 @@ void CL_LinkNetworkEntity(entity_t *e) e->render.model = cl.model_precache[e->state_current.modelindex]; if (e->render.model) { - Mod_CheckLoaded(e->render.model); // if model is alias or this is a tenebrae-like dlight, reverse pitch direction if (e->render.model->type == mod_alias || (e->state_current.lightpflags & PFLAGS_FULLDYNAMIC)) angles[0] = -angles[0]; @@ -1015,7 +1014,6 @@ static void CL_RelinkStaticEntities(void) entity_t *e; for (i = 0, e = cl_static_entities;i < cl_num_static_entities && r_refdef.numentities < r_refdef.maxentities;i++, e++) { - Mod_CheckLoaded(e->render.model); e->render.flags = 0; // transparent stuff can't be lit during the opaque stage if (e->render.effects & (EF_ADDITIVE | EF_NODEPTHTEST) || e->render.alpha < 1) diff --git a/cl_parse.c b/cl_parse.c index 5580300f..5933c863 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -511,7 +511,6 @@ void CL_ValidateState(entity_state_t *s) } model = cl.model_precache[s->modelindex]; - Mod_CheckLoaded(model); if (model && model->type && s->frame >= model->numframes) { Con_DPrintf("CL_ValidateState: no such frame %i in \"%s\" (which has %i frames)\n", s->frame, model->name, model->numframes); diff --git a/gl_rmain.c b/gl_rmain.c index fc65bbc3..b40dea36 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -582,7 +582,6 @@ static void R_MarkEntities (void) for (i = 0;i < r_refdef.numentities;i++) { ent = r_refdef.entities[i]; - Mod_CheckLoaded(ent->model); // some of the renderer still relies on origin... Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin); // some of the renderer still relies on scale... @@ -600,7 +599,6 @@ static void R_MarkEntities (void) for (i = 0;i < r_refdef.numentities;i++) { ent = r_refdef.entities[i]; - Mod_CheckLoaded(ent->model); // some of the renderer still relies on origin... Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin); // some of the renderer still relies on scale... diff --git a/gl_rsurf.c b/gl_rsurf.c index f6573fb8..82655907 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -275,7 +275,6 @@ void R_Stain (const vec3_t origin, float radius, int cr1, int cg1, int cb1, int model = ent->model; if (model && model->name[0] == '*') { - Mod_CheckLoaded(model); if (model->brush.data_nodes) { Matrix4x4_Transform(&ent->inversematrix, origin, org); diff --git a/model_brush.c b/model_brush.c index f7bb4243..68554e0d 100644 --- a/model_brush.c +++ b/model_brush.c @@ -74,8 +74,6 @@ static mleaf_t *Mod_Q1BSP_PointInLeaf(model_t *model, const vec3_t p) if (model == NULL) return NULL; - Mod_CheckLoaded(model); - // LordHavoc: modified to start at first clip node, // in other words: first node of the (sub)model node = model->brush.data_nodes + model->brushq1.hulls[0].firstclipnode; @@ -2855,7 +2853,6 @@ static void Mod_Q1BSP_BuildLightmapUpdateChains(mempool_t *mempool, model_t *mod static qbyte *Mod_Q1BSP_GetPVS(model_t *model, const vec3_t p) { mnode_t *node; - Mod_CheckLoaded(model); node = model->brush.data_nodes; while (node->plane) node = node->children[(node->plane->type < 3 ? p[node->plane->type] : DotProduct(p,node->plane->normal)) < node->plane->dist]; diff --git a/model_shared.c b/model_shared.c index b8b83586..0fee3712 100644 --- a/model_shared.c +++ b/model_shared.c @@ -37,18 +37,22 @@ static model_t mod_known[MAX_MOD_KNOWN]; static void mod_start(void) { int i; - for (i = 0;i < MAX_MOD_KNOWN;i++) - if (mod_known[i].name[0]) - Mod_UnloadModel(&mod_known[i]); - Mod_LoadModels(); + model_t *mod; + + for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++) + if (mod->name[0]) + if (mod->used) + Mod_LoadModel(mod, true, false, mod->isworldmodel); } static void mod_shutdown(void) { int i; - for (i = 0;i < MAX_MOD_KNOWN;i++) - if (mod_known[i].name[0]) - Mod_UnloadModel(&mod_known[i]); + model_t *mod; + + for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++) + if (mod->loaded) + Mod_UnloadModel(mod); } static void mod_newmap(void) @@ -100,15 +104,6 @@ void Mod_RenderInit(void) R_RegisterModule("Models", mod_start, mod_shutdown, mod_newmap); } -void Mod_FreeModel (model_t *mod) -{ - R_FreeTexturePool(&mod->texturepool); - Mem_FreePool(&mod->mempool); - - // clear the struct to make it available - memset(mod, 0, sizeof(model_t)); -} - void Mod_UnloadModel (model_t *mod) { char name[MAX_QPATH]; @@ -117,7 +112,12 @@ void Mod_UnloadModel (model_t *mod) strcpy(name, mod->name); isworldmodel = mod->isworldmodel; used = mod->used; - Mod_FreeModel(mod); + // free textures/memory attached to the model + R_FreeTexturePool(&mod->texturepool); + Mem_FreePool(&mod->mempool); + // clear the struct to make it available + memset(mod, 0, sizeof(model_t)); + // restore the fields we want to preserve strcpy(mod->name, name); mod->isworldmodel = isworldmodel; mod->used = used; @@ -230,12 +230,14 @@ void Mod_ClearAll(void) void Mod_ClearUsed(void) { +#if 0 int i; model_t *mod; for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++) if (mod->name[0]) mod->used = false; +#endif } void Mod_PurgeUnused(void) @@ -246,27 +248,24 @@ void Mod_PurgeUnused(void) for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++) if (mod->name[0]) if (!mod->used) - Mod_FreeModel(mod); + Mod_UnloadModel(mod); } // only used during loading! void Mod_RemoveStaleWorldModels(model_t *skip) -{ - int i; - for (i = 0;i < MAX_MOD_KNOWN;i++) - if (mod_known[i].isworldmodel && skip != &mod_known[i]) - Mod_UnloadModel(mod_known + i); -} - -void Mod_LoadModels(void) { int i; model_t *mod; for (i = 0, mod = mod_known;i < MAX_MOD_KNOWN;i++, mod++) - if (mod->name[0]) - if (mod->used) - Mod_CheckLoaded(mod); + { + if (mod->isworldmodel && mod->loaded && skip != mod) + { + Mod_UnloadModel(mod); + mod->isworldmodel = false; + mod->used = false; + } + } } /* @@ -321,7 +320,11 @@ Loads in a model for the given name */ model_t *Mod_ForName(const char *name, qboolean crash, qboolean checkdisk, qboolean isworldmodel) { - return Mod_LoadModel(Mod_FindName(name), crash, checkdisk, isworldmodel); + model_t *model; + model = Mod_FindName(name); + if (!model->loaded || checkdisk) + Mod_LoadModel(model, crash, checkdisk, isworldmodel); + return model; } qbyte *mod_base; diff --git a/model_shared.h b/model_shared.h index 3d3d86bc..8746c4d0 100644 --- a/model_shared.h +++ b/model_shared.h @@ -584,7 +584,6 @@ extern qbyte *mod_base; extern cvar_t r_fullbrights; void Mod_Init (void); -#define Mod_CheckLoaded(mod) (mod ? (mod->loaded ? (mod->used = true) : (Mod_LoadModel(mod, true, true, mod->isworldmodel), true)) : false) model_t *Mod_LoadModel(model_t *mod, qboolean crash, qboolean checkdisk, qboolean isworldmodel); void Mod_ClearAll (void); model_t *Mod_FindName (const char *name); @@ -594,7 +593,6 @@ void Mod_UnloadModel (model_t *mod); void Mod_ClearUsed(void); void Mod_PurgeUnused(void); void Mod_RemoveStaleWorldModels(model_t *skip); // only used during loading! -void Mod_LoadModels(void); extern model_t *loadmodel; extern char loadname[32]; // for hunk tags diff --git a/portals.c b/portals.c index 427a15a8..98d742f4 100644 --- a/portals.c +++ b/portals.c @@ -140,7 +140,6 @@ int Portal_CheckPolygon(model_t *model, vec3_t eye, float *polypoints, int numpo portal_markid++; - Mod_CheckLoaded(model); Portal_PolygonRecursiveMarkLeafs(model->brush.data_nodes, polypoints, numpoints); eyeleaf = model->brush.PointInLeaf(model, eye); @@ -432,8 +431,6 @@ void Portal_Visibility(model_t *model, const vec3_t eye, int *leaflist, qbyte *l return; } - Mod_CheckLoaded(model); - if (!model->brush.data_nodes) { Con_Print("Portal_Visibility: not a brush model\n"); diff --git a/sv_main.c b/sv_main.c index e6e1c32e..fe072186 100644 --- a/sv_main.c +++ b/sv_main.c @@ -763,7 +763,6 @@ void SV_MarkWriteEntityStateToClient(entity_state_t *s) // generate much traffic (in old protocols they hog bandwidth) else if (!(s->effects & EF_NODEPTHTEST) && !((isbmodel = (model = sv.models[s->modelindex]) != NULL && model->name[0] == '*') && (sv.protocol != PROTOCOL_QUAKE && sv.protocol != PROTOCOL_QUAKEDP && sv.protocol != PROTOCOL_NEHAHRAMOVIE))) { - Mod_CheckLoaded(model); // entity has survived every check so far, check if visible ed = PRVM_EDICT_NUM(s->number); @@ -861,8 +860,6 @@ void SV_WriteEntitiesToClient(client_t *client, prvm_edict_t *clent, sizebuf_t * sv_writeentitiestoclient_visibleentities = 0; sv_writeentitiestoclient_totalentities = 0; - Mod_CheckLoaded(sv.worldmodel); - // find the client's PVS // the real place being tested from VectorAdd(clent->fields.server->origin, clent->fields.server->view_ofs, sv_writeentitiestoclient_testeye); diff --git a/world.c b/world.c index d9959eb0..ff129dfd 100644 --- a/world.c +++ b/world.c @@ -135,7 +135,6 @@ SV_ClearWorld */ void SV_ClearWorld (void) { - Mod_CheckLoaded(sv.worldmodel); SV_CreateAreaGrid(sv.worldmodel->normalmins, sv.worldmodel->normalmaxs); } @@ -329,7 +328,6 @@ void SV_LinkEdict (prvm_edict_t *ent, qboolean touch_triggers) model = sv.models[modelindex]; if (model != NULL) { - Mod_CheckLoaded(model); if (!model->TraceBox) Con_Printf("edict %i: SOLID_BSP with non-collidable model\n", PRVM_NUM_FOR_EDICT(ent)); @@ -469,7 +467,6 @@ trace_t SV_ClipMoveToEntity(prvm_edict_t *ent, const vec3_t start, const vec3_t return trace; } - Mod_CheckLoaded(model); if ((int) ent->fields.server->solid == SOLID_BSP) { if (!model->TraceBox) -- 2.39.2