mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-04-11 12:40:45 +00:00
Free Unused Image and Models only if we are near to limit
This commit is contained in:
parent
b0cc97e6f3
commit
2c00502b0b
3 changed files with 176 additions and 24 deletions
|
@ -232,9 +232,15 @@ void Vk_TextureMode( char *string );
|
|||
void Vk_LmapTextureMode( char *string );
|
||||
void Vk_ImageList_f (void);
|
||||
|
||||
void Vk_BuildPolygonFromSurface(msurface_t *fa, model_t *currentmodel);
|
||||
void Vk_CreateSurfaceLightmap (msurface_t *surf);
|
||||
void Vk_EndBuildingLightmaps (void);
|
||||
void Vk_BeginBuildingLightmaps (model_t *m);
|
||||
|
||||
void Vk_InitImages (void);
|
||||
void Vk_ShutdownImages (void);
|
||||
void Vk_FreeUnusedImages (void);
|
||||
qboolean Vk_ImageHasFreeSpace(void);
|
||||
|
||||
void RE_BeginRegistration (char *model);
|
||||
struct model_s *RE_RegisterModel (char *name);
|
||||
|
|
|
@ -21,7 +21,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "header/local.h"
|
||||
|
||||
image_t vktextures[MAX_VKTEXTURES];
|
||||
int numvktextures;
|
||||
int numvktextures = 0;
|
||||
static int img_loaded = 0;
|
||||
static int image_max = 0;
|
||||
|
||||
// texture for storing raw image data (cinematics, endscreens, etc.)
|
||||
qvktexture_t vk_rawTexture = QVVKTEXTURE_INIT;
|
||||
|
||||
|
@ -530,17 +533,26 @@ Vk_ImageList_f
|
|||
*/
|
||||
void Vk_ImageList_f (void)
|
||||
{
|
||||
int i;
|
||||
int i, used, texels;
|
||||
image_t *image;
|
||||
int texels;
|
||||
|
||||
R_Printf(PRINT_ALL, "------------------\n");
|
||||
texels = 0;
|
||||
used = 0;
|
||||
|
||||
for (i = 0, image = vktextures; i < numvktextures; i++, image++)
|
||||
{
|
||||
char *in_use = "";
|
||||
|
||||
if (image->vk_texture.resource.image == VK_NULL_HANDLE)
|
||||
continue;
|
||||
|
||||
if (image->registration_sequence == registration_sequence)
|
||||
{
|
||||
in_use = "*";
|
||||
used++;
|
||||
}
|
||||
|
||||
texels += image->upload_width*image->upload_height;
|
||||
switch (image->type)
|
||||
{
|
||||
|
@ -561,11 +573,12 @@ void Vk_ImageList_f (void)
|
|||
break;
|
||||
}
|
||||
|
||||
R_Printf(PRINT_ALL, " %4i %4i RGB: %s (%dx%d)\n",
|
||||
R_Printf(PRINT_ALL, " %4i %4i RGB: %s (%dx%d) %s\n",
|
||||
image->upload_width, image->upload_height, image->name,
|
||||
image->width, image->height);
|
||||
image->width, image->height, in_use);
|
||||
}
|
||||
R_Printf(PRINT_ALL, "Total texel count (not counting mipmaps): %i\n", texels);
|
||||
R_Printf(PRINT_ALL, "Total texel count (not counting mipmaps): %i in %d images\n", texels, img_loaded);
|
||||
R_Printf(PRINT_ALL, "Used %d of %d images.\n", used, image_max);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
|
@ -978,6 +991,12 @@ Vk_LoadPic(char *name, byte *pic, int width, int realwidth,
|
|||
image->width = realwidth;
|
||||
image->height = realheight;
|
||||
image->type = type;
|
||||
// update count of loaded images
|
||||
img_loaded ++;
|
||||
if (vk_validation->value)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "%s: Load %s[%d]\n", __func__, image->name, img_loaded);
|
||||
}
|
||||
|
||||
if (type == it_skin && bits == 8)
|
||||
FloodFillSkin(pic, width, height);
|
||||
|
@ -1310,6 +1329,31 @@ struct image_s *RE_RegisterSkin (char *name)
|
|||
return Vk_FindImage (name, it_skin);
|
||||
}
|
||||
|
||||
qboolean Vk_ImageHasFreeSpace(void)
|
||||
{
|
||||
int i, used;
|
||||
image_t *image;
|
||||
|
||||
used = 0;
|
||||
|
||||
for (i = 0, image = vktextures; i < numvktextures; i++, image++)
|
||||
{
|
||||
if (!image->name[0])
|
||||
continue;
|
||||
if (image->registration_sequence == registration_sequence)
|
||||
{
|
||||
used ++;
|
||||
}
|
||||
}
|
||||
|
||||
if (image_max < used)
|
||||
{
|
||||
image_max = used;
|
||||
}
|
||||
|
||||
// should same size of free slots as currently used
|
||||
return (img_loaded + used) < MAX_VKTEXTURES;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
|
@ -1324,6 +1368,12 @@ void Vk_FreeUnusedImages (void)
|
|||
int i;
|
||||
image_t *image;
|
||||
|
||||
if (Vk_ImageHasFreeSpace())
|
||||
{
|
||||
// should be enough space for load next images
|
||||
return;
|
||||
}
|
||||
|
||||
// never free r_notexture or particle texture
|
||||
r_notexture->registration_sequence = registration_sequence;
|
||||
r_particletexture->registration_sequence = registration_sequence;
|
||||
|
@ -1337,9 +1387,21 @@ void Vk_FreeUnusedImages (void)
|
|||
continue; // free image_t slot
|
||||
if (image->type == it_pic)
|
||||
continue; // don't free pics
|
||||
|
||||
if (vk_validation->value)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "%s: Unload %s[%d]\n", __func__, image->name, img_loaded);
|
||||
}
|
||||
|
||||
// free it
|
||||
QVk_ReleaseTexture(&image->vk_texture);
|
||||
memset(image, 0, sizeof(*image));
|
||||
|
||||
img_loaded --;
|
||||
if (img_loaded < 0)
|
||||
{
|
||||
ri.Sys_Error (ERR_DROP, "%s: Broken unload", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
// free all unused blocks
|
||||
|
@ -1396,6 +1458,9 @@ void Vk_InitImages (void)
|
|||
int i;
|
||||
float overbright;
|
||||
|
||||
numvktextures = 0;
|
||||
img_loaded = 0;
|
||||
image_max = 0;
|
||||
registration_sequence = 1;
|
||||
|
||||
// init intensity conversions
|
||||
|
@ -1455,8 +1520,19 @@ void Vk_ShutdownImages (void)
|
|||
if (!image->registration_sequence)
|
||||
continue; // free image_t slot
|
||||
|
||||
if (vk_validation->value)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "%s: Unload %s[%d]\n", __func__, image->name, img_loaded);
|
||||
}
|
||||
|
||||
QVk_ReleaseTexture(&image->vk_texture);
|
||||
memset(image, 0, sizeof(*image));
|
||||
|
||||
img_loaded --;
|
||||
if (img_loaded < 0)
|
||||
{
|
||||
ri.Sys_Error (ERR_DROP, "%s: Broken unload", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
QVk_ReleaseTexture(&vk_rawTexture);
|
||||
|
|
|
@ -25,11 +25,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
YQ2_ALIGNAS_TYPE(int) static byte mod_novis[MAX_MAP_LEAFS/8];
|
||||
|
||||
#define MAX_MOD_KNOWN 512
|
||||
model_t mod_known[MAX_MOD_KNOWN];
|
||||
int mod_numknown;
|
||||
static model_t mod_known[MAX_MOD_KNOWN];
|
||||
static int mod_numknown = 0;
|
||||
static int mod_loaded = 0;
|
||||
static int mod_max = 0;
|
||||
|
||||
// the inline * models from the current map are kept seperate
|
||||
model_t mod_inline[MAX_MOD_KNOWN];
|
||||
static model_t mod_inline[MAX_MOD_KNOWN];
|
||||
|
||||
int registration_sequence;
|
||||
|
||||
|
@ -43,7 +45,7 @@ mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
|
|||
mnode_t *node;
|
||||
|
||||
if (!model || !model->nodes)
|
||||
ri.Sys_Error (ERR_DROP, "Mod_PointInLeaf: bad model");
|
||||
ri.Sys_Error (ERR_DROP, "%s: bad model", __func__);
|
||||
|
||||
node = model->nodes;
|
||||
while (1)
|
||||
|
@ -90,20 +92,31 @@ Mod_Modellist_f
|
|||
*/
|
||||
void Mod_Modellist_f (void)
|
||||
{
|
||||
int i;
|
||||
int i, total, used;
|
||||
model_t *mod;
|
||||
int total;
|
||||
|
||||
total = 0;
|
||||
used = 0;
|
||||
|
||||
R_Printf(PRINT_ALL,"Loaded models:\n");
|
||||
for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++)
|
||||
{
|
||||
char *in_use = "";
|
||||
|
||||
if (mod->registration_sequence == registration_sequence)
|
||||
{
|
||||
in_use = "*";
|
||||
used ++;
|
||||
}
|
||||
|
||||
if (!mod->name[0])
|
||||
continue;
|
||||
R_Printf(PRINT_ALL, "%8i : %s\n",mod->extradatasize, mod->name);
|
||||
R_Printf(PRINT_ALL, "%8i : %s %s\n",
|
||||
mod->extradatasize, mod->name, in_use);
|
||||
total += mod->extradatasize;
|
||||
}
|
||||
R_Printf(PRINT_ALL, "Total resident: %i\n", total);
|
||||
R_Printf(PRINT_ALL, "Total resident: %i in %d models\n", total, mod_loaded);
|
||||
R_Printf(PRINT_ALL, "Used %d of %d models.\n", used, mod_max);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -114,6 +127,9 @@ Mod_Init
|
|||
void Mod_Init (void)
|
||||
{
|
||||
memset (mod_novis, 0xff, sizeof(mod_novis));
|
||||
mod_numknown = 0;
|
||||
mod_loaded = 0;
|
||||
mod_max = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -123,8 +139,25 @@ Mod_Free
|
|||
*/
|
||||
static void Mod_Free (model_t *mod)
|
||||
{
|
||||
if (!mod->extradata)
|
||||
{
|
||||
// looks as empty model
|
||||
memset (mod, 0, sizeof(*mod));
|
||||
return;
|
||||
}
|
||||
|
||||
if (vk_validation->value)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "%s: Unload %s[%d]\n", __func__, mod->name, mod_loaded);
|
||||
}
|
||||
|
||||
Hunk_Free (mod->extradata);
|
||||
memset (mod, 0, sizeof(*mod));
|
||||
mod_loaded --;
|
||||
if (mod_loaded < 0)
|
||||
{
|
||||
ri.Sys_Error (ERR_DROP, "%s: Broken unload", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -435,12 +468,6 @@ static void CalcSurfaceExtents (model_t *loadmodel, msurface_t *s)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void Vk_BuildPolygonFromSurface(msurface_t *fa, model_t *currentmodel);
|
||||
void Vk_CreateSurfaceLightmap (msurface_t *surf);
|
||||
void Vk_EndBuildingLightmaps (void);
|
||||
void Vk_BeginBuildingLightmaps (model_t *m);
|
||||
|
||||
static int calcTexinfoAndFacesSize(const lump_t *fl, byte *mod_base, const lump_t *tl)
|
||||
{
|
||||
dface_t* face_in = (void *)(mod_base + fl->fileofs);
|
||||
|
@ -1207,7 +1234,7 @@ Mod_ForName
|
|||
Loads in a model for the given name
|
||||
==================
|
||||
*/
|
||||
static model_t *Mod_ForName (char *name, qboolean crash)
|
||||
static model_t *Mod_ForName (char *name, model_t *parent_model, qboolean crash)
|
||||
{
|
||||
model_t *mod;
|
||||
unsigned *buf;
|
||||
|
@ -1224,7 +1251,7 @@ static model_t *Mod_ForName (char *name, qboolean crash)
|
|||
if (name[0] == '*')
|
||||
{
|
||||
i = atoi(name+1);
|
||||
if (i < 1 || !r_worldmodel || i >= r_worldmodel->numsubmodels)
|
||||
if (i < 1 || !parent_model || i >= parent_model->numsubmodels)
|
||||
ri.Sys_Error (ERR_DROP, "bad inline model number");
|
||||
return &mod_inline[i];
|
||||
}
|
||||
|
@ -1268,10 +1295,21 @@ static model_t *Mod_ForName (char *name, qboolean crash)
|
|||
__func__, mod->name);
|
||||
}
|
||||
|
||||
if (vk_validation->value)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "%s: Can't load %s\n", __func__, mod->name);
|
||||
}
|
||||
memset (mod->name, 0, sizeof(mod->name));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// update count of loaded models
|
||||
mod_loaded ++;
|
||||
if (vk_validation->value)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "%s: Load %s[%d]\n", __func__, mod->name, mod_loaded);
|
||||
}
|
||||
|
||||
//
|
||||
// fill it in
|
||||
//
|
||||
|
@ -1328,7 +1366,7 @@ RE_BeginRegistration (char *model)
|
|||
flushmap = ri.Cvar_Get ("flushmap", "0", 0);
|
||||
if ( strcmp(mod_known[0].name, fullname) || flushmap->value)
|
||||
Mod_Free (&mod_known[0]);
|
||||
r_worldmodel = Mod_ForName(fullname, true);
|
||||
r_worldmodel = Mod_ForName(fullname, NULL, true);
|
||||
|
||||
r_viewcluster = -1;
|
||||
}
|
||||
|
@ -1343,7 +1381,7 @@ struct model_s *RE_RegisterModel (char *name)
|
|||
{
|
||||
model_t *mod;
|
||||
|
||||
mod = Mod_ForName (name, false);
|
||||
mod = Mod_ForName (name, r_worldmodel, false);
|
||||
if (mod)
|
||||
{
|
||||
int i;
|
||||
|
@ -1379,6 +1417,32 @@ struct model_s *RE_RegisterModel (char *name)
|
|||
return mod;
|
||||
}
|
||||
|
||||
static qboolean
|
||||
Mod_HasFreeSpace(void)
|
||||
{
|
||||
int i, used;
|
||||
model_t *mod;
|
||||
|
||||
used = 0;
|
||||
|
||||
for (i=0, mod=mod_known ; i<mod_numknown ; i++, mod++)
|
||||
{
|
||||
if (!mod->name[0])
|
||||
continue;
|
||||
if (mod->registration_sequence == registration_sequence)
|
||||
{
|
||||
used ++;
|
||||
}
|
||||
}
|
||||
|
||||
if (mod_max < used)
|
||||
{
|
||||
mod_max = used;
|
||||
}
|
||||
|
||||
// should same size of free slots as currently used
|
||||
return (mod_loaded + mod_max) < MAX_MOD_KNOWN;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
|
@ -1391,6 +1455,12 @@ void RE_EndRegistration (void)
|
|||
int i;
|
||||
model_t *mod;
|
||||
|
||||
if (Mod_HasFreeSpace() && Vk_ImageHasFreeSpace())
|
||||
{
|
||||
// should be enough space for load next maps
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0, mod=mod_known ; i<mod_numknown ; i++, mod++)
|
||||
{
|
||||
if (!mod->name[0])
|
||||
|
|
Loading…
Reference in a new issue