Browse Source

ref: Improve model unloading, fix texture leak

pull/2/head
mittorn 6 years ago
parent
commit
8339096ad8
  1. 4
      engine/client/cl_game.c
  2. 4
      engine/client/cl_parse.c
  3. 6
      engine/client/ref_common.c
  4. 36
      engine/common/mod_bmodel.c
  5. 2
      engine/common/mod_local.h
  6. 26
      engine/common/mod_sprite.c
  7. 19
      engine/common/mod_studio.c
  8. 30
      engine/common/model.c
  9. 3
      engine/ref_api.h
  10. 17
      ref_gl/gl_alias.c
  11. 62
      ref_gl/gl_context.c
  12. 5
      ref_gl/gl_local.h
  13. 4
      ref_gl/gl_sprite.c
  14. 2
      ref_gl/gl_studio.c

4
engine/client/cl_game.c

@ -1226,7 +1226,7 @@ static qboolean CL_LoadHudSprite( const char *szSpriteName, model_t *m_pSprite, @@ -1226,7 +1226,7 @@ static qboolean CL_LoadHudSprite( const char *szSpriteName, model_t *m_pSprite,
else
{
Con_Reportf( S_ERROR "Could not load HUD sprite %s\n", szSpriteName );
ref.dllFuncs.Mod_UnloadModel( m_pSprite );
Mod_FreeModel( m_pSprite );
return false;
}
}
@ -1242,7 +1242,7 @@ static qboolean CL_LoadHudSprite( const char *szSpriteName, model_t *m_pSprite, @@ -1242,7 +1242,7 @@ static qboolean CL_LoadHudSprite( const char *szSpriteName, model_t *m_pSprite,
if( !loaded )
{
ref.dllFuncs.Mod_UnloadModel( m_pSprite );
Mod_FreeModel( m_pSprite );
return false;
}

4
engine/client/cl_parse.c

@ -1561,7 +1561,7 @@ void CL_RegisterResources( sizebuf_t *msg ) @@ -1561,7 +1561,7 @@ void CL_RegisterResources( sizebuf_t *msg )
for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ )
{
if( mod->needload == NL_UNREFERENCED && COM_CheckString( mod->name ))
ref.dllFuncs.Mod_UnloadModel( mod );
Mod_FreeModel( mod );
}
Mod_FreeUnused ();
@ -3145,7 +3145,7 @@ void CL_LegacyPrecache_f( void ) @@ -3145,7 +3145,7 @@ void CL_LegacyPrecache_f( void )
for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ )
{
if( mod->needload == NL_UNREFERENCED && COM_CheckString( mod->name ))
ref.dllFuncs.Mod_UnloadModel( mod );
Mod_FreeModel( mod );
}
// Mod_FreeUnused ();

6
engine/client/ref_common.c

@ -403,6 +403,7 @@ static void R_UnloadProgs( void ) @@ -403,6 +403,7 @@ static void R_UnloadProgs( void )
ref.hInstance = NULL;
memset( &refState, 0, sizeof( refState ));
memset( &ref.dllFuncs, 0, sizeof( ref.dllFuncs ));
Cvar_Unlink( FCVAR_RENDERINFO | FCVAR_GLCONFIG );
Cmd_Unlink( CMD_REFDLL );
@ -507,10 +508,13 @@ void R_Shutdown( void ) @@ -507,10 +508,13 @@ void R_Shutdown( void )
for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ )
{
if( !mod->name[0] ) continue;
Mod_UnloadSpriteModel( mod );
Mod_FreeModel( mod );
}
memset( clgame.sprites, 0, sizeof( clgame.sprites ));
// correctly free all models before render unload
// change this if need add online render changing
Mod_FreeAll();
R_UnloadProgs();
ref.initialized = false;
}

36
engine/common/mod_bmodel.c

@ -2797,42 +2797,6 @@ void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *loaded ) @@ -2797,42 +2797,6 @@ void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *loaded )
if( loaded ) *loaded = true; // all done
}
/*
=================
Mod_UnloadBrushModel
Release all uploaded textures
=================
*/
void Mod_UnloadBrushModel( model_t *mod )
{
texture_t *tx;
int i;
Assert( mod != NULL );
if( mod->type != mod_brush )
return; // not a bmodel
if( mod->name[0] != '*' )
{
#ifndef XASH_DEDICATED
for( i = 0; i < mod->numtextures; i++ )
{
tx = mod->textures[i];
if( !tx || tx->gl_texturenum == ref.dllFuncs.R_GetBuiltinTexture( REF_DEFAULT_TEXTURE ) )
continue; // free slot
ref.dllFuncs.GL_FreeTexture( tx->gl_texturenum ); // main texture
ref.dllFuncs.GL_FreeTexture( tx->fb_texturenum ); // luma texture
}
#endif
Mem_FreePool( &mod->mempool );
}
memset( mod, 0, sizeof( *mod ));
}
/*
==================
Mod_CheckLump

2
engine/common/mod_local.h

@ -118,6 +118,7 @@ extern convar_t *r_showhull; @@ -118,6 +118,7 @@ extern convar_t *r_showhull;
// model.c
//
void Mod_Init( void );
void Mod_FreeModel( model_t *mod );
void Mod_FreeAll( void );
void Mod_Shutdown( void );
void Mod_ClearUserData( void );
@ -189,7 +190,6 @@ void Mod_ClearStudioCache( void ); @@ -189,7 +190,6 @@ void Mod_ClearStudioCache( void );
// mod_sprite.c
//
void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, uint texFlags );
void Mod_UnloadSpriteModel( model_t *mod );
#endif
#endif//MOD_LOCAL_H

26
engine/common/mod_sprite.c

@ -113,29 +113,3 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui @@ -113,29 +113,3 @@ void Mod_LoadSpriteModel( model_t *mod, const void *buffer, qboolean *loaded, ui
ref.dllFuncs.Mod_LoadModel( mod_sprite, mod, buffer, loaded, texFlags );
#endif
}
/*
====================
Mod_UnloadSpriteModel
release sprite model and frames
====================
*/
void Mod_UnloadSpriteModel( model_t *mod )
{
Assert( mod != NULL );
if( mod->type == mod_sprite )
{
#ifndef XASH_DEDICATED
if( host.type != HOST_DEDICATED )
{
ref.dllFuncs.Mod_UnloadModel( mod );
}
#endif
Mem_FreePool( &mod->mempool );
memset( mod, 0, sizeof( *mod ));
}
}

19
engine/common/mod_studio.c

@ -1139,25 +1139,6 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded ) @@ -1139,25 +1139,6 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded )
if( loaded ) *loaded = true;
}
/*
=================
Mod_UnloadStudioModel
=================
*/
void Mod_UnloadStudioModel( model_t *mod )
{
Assert( mod != NULL );
if( mod->type != mod_studio )
return; // not a studio
if( Host_IsDedicated() )
ref.dllFuncs.Mod_StudioUnloadTextures( mod->cache.data );
Mem_FreePool( &mod->mempool );
memset( mod, 0, sizeof( *mod ));
}
static sv_blending_interface_t gBlendAPI =
{
SV_BLENDING_INTERFACE_VERSION,

30
engine/common/model.c

@ -102,37 +102,21 @@ static void Mod_FreeUserData( model_t *mod ) @@ -102,37 +102,21 @@ static void Mod_FreeUserData( model_t *mod )
Mod_FreeModel
================
*/
static void Mod_FreeModel( model_t *mod )
void Mod_FreeModel( model_t *mod )
{
// already freed?
if( !mod || !mod->name[0] )
return;
if( mod->name[0] != '*' )
Mod_FreeUserData( mod );
// notify renderer about unloading
if( ref.dllFuncs.Mod_UnloadModel )
ref.dllFuncs.Mod_UnloadModel( mod );
switch( mod->type )
if( mod->type != mod_brush || mod->name[0] != '*' )
{
case mod_studio:
Mod_UnloadStudioModel( mod );
break;
case mod_alias:
// REFTODO:
// Mod_UnloadAliasModel( mod );
break;
case mod_sprite:
Mod_UnloadSpriteModel( mod );
break;
case mod_brush:
Mod_UnloadBrushModel( mod );
break;
Mod_FreeUserData( mod );
#ifndef XASH_DEDICATED
ref.dllFuncs.Mod_UnloadTextures( mod );
#endif
Mem_FreePool( &mod->mempool );
}
memset( mod, 0, sizeof( *mod ));
}

3
engine/ref_api.h

@ -520,9 +520,8 @@ typedef struct ref_interface_s @@ -520,9 +520,8 @@ typedef struct ref_interface_s
// flags ignored for everything except spritemodels
void (*Mod_LoadModel)( modtype_t desiredType, model_t *mod, const byte *buf, qboolean *loaded, int flags );
void (*Mod_LoadMapSprite)( struct model_s *mod, const void *buffer, size_t size, qboolean *loaded );
void (*Mod_UnloadModel)( model_t *mod );
void (*Mod_UnloadTextures)( model_t *mod );
void (*Mod_StudioLoadTextures)( model_t *mod, void *data );
void (*Mod_StudioUnloadTextures)( void *data );
// efx implementation
void (*CL_DrawParticles)( double frametime, particle_t *particles, float partsize );

17
ref_gl/gl_alias.c

@ -729,22 +729,12 @@ void Mod_LoadAliasModel( model_t *mod, const void *buffer, qboolean *loaded ) @@ -729,22 +729,12 @@ void Mod_LoadAliasModel( model_t *mod, const void *buffer, qboolean *loaded )
if( loaded ) *loaded = true; // done
}
/*
=================
Mod_UnloadAliasModel
=================
*/
void Mod_UnloadAliasModel( model_t *mod )
void Mod_AliasUnloadTextures( void *data )
{
aliashdr_t *palias;
int i, j;
Assert( mod != NULL );
if( mod->type != mod_alias )
return; // not an alias
palias = mod->cache.data;
palias = data;
if( !palias ) return; // already freed
for( i = 0; i < MAX_SKINS; i++ )
@ -758,9 +748,6 @@ void Mod_UnloadAliasModel( model_t *mod ) @@ -758,9 +748,6 @@ void Mod_UnloadAliasModel( model_t *mod )
GL_FreeTexture( palias->fb_texturenum[i][j] );
}
}
Mem_FreePool( &mod->mempool );
memset( mod, 0, sizeof( *mod ));
}
/*

62
ref_gl/gl_context.c

@ -164,26 +164,6 @@ static void Mod_LoadModel( modtype_t desiredType, model_t *mod, const byte *buf, @@ -164,26 +164,6 @@ static void Mod_LoadModel( modtype_t desiredType, model_t *mod, const byte *buf,
}
}
static void Mod_UnloadModel( model_t *mod )
{
switch( mod->type )
{
case mod_studio:
// Mod_UnloadStudioModel( mod );
break;
case mod_alias:
Mod_UnloadAliasModel( mod );
break;
case mod_brush:
// Mod_UnloadBrushModel( mod );
break;
case mod_sprite:
Mod_UnloadSpriteModel( mod );
break;
default: gEngfuncs.Host_Error( "Mod_UnloadModel: unsupported type %d\n", mod->type );
}
}
static int GL_RenderGetParm( int parm, int arg )
{
gl_texture_t *glt;
@ -320,6 +300,45 @@ const byte *GL_TextureData( unsigned int texnum ) @@ -320,6 +300,45 @@ const byte *GL_TextureData( unsigned int texnum )
return NULL;
}
void Mod_BrushUnloadTextures( model_t *mod )
{
int i;
for( i = 0; i < mod->numtextures; i++ )
{
texture_t *tx = mod->textures[i];
if( !tx || tx->gl_texturenum == tr.defaultTexture )
continue; // free slot
GL_FreeTexture( tx->gl_texturenum ); // main texture
GL_FreeTexture( tx->fb_texturenum ); // luma texture
}
}
void Mod_UnloadTextures( model_t *mod )
{
int i, j;
Assert( mod != NULL );
switch( mod->type )
{
case mod_studio:
Mod_StudioUnloadTextures( mod->cache.data );
break;
case mod_alias:
Mod_AliasUnloadTextures( mod->cache.data );
break;
case mod_brush:
Mod_BrushUnloadTextures( mod );
break;
case mod_sprite:
Mod_SpriteUnloadTextures( mod->cache.data );
break;
default: gEngfuncs.Host_Error( "Mod_UnloadModel: unsupported type %d\n", mod->type );
}
}
ref_interface_t gReffuncs =
{
R_Init,
@ -390,9 +409,8 @@ ref_interface_t gReffuncs = @@ -390,9 +409,8 @@ ref_interface_t gReffuncs =
Mod_LoadModel,
Mod_LoadMapSprite,
Mod_UnloadModel,
Mod_UnloadTextures,
Mod_StudioLoadTextures,
Mod_StudioUnloadTextures,
CL_DrawParticles,
CL_DrawTracers,

5
ref_gl/gl_local.h

@ -541,10 +541,9 @@ int R_WorldToScreen( const vec3_t point, vec3_t screen ); @@ -541,10 +541,9 @@ int R_WorldToScreen( const vec3_t point, vec3_t screen );
void R_ScreenToWorld( const vec3_t screen, vec3_t point );
qboolean R_AddEntity( struct cl_entity_s *pRefEntity, int entityType );
void Mod_LoadMapSprite( struct model_s *mod, const void *buffer, size_t size, qboolean *loaded );
void Mod_UnloadSpriteModel( struct model_s *mod );
void Mod_UnloadStudioModel( struct model_s *mod );
void Mod_UnloadBrushModel( struct model_s *mod );
void Mod_SpriteUnloadTextures( void *data );
void Mod_UnloadAliasModel( struct model_s *mod );
void Mod_AliasUnloadTextures( void *data );
void GL_SetRenderMode( int mode );
void R_RunViewmodelEvents( void );
void R_DrawViewModel( void );

4
ref_gl/gl_sprite.c

@ -356,14 +356,14 @@ Mod_UnloadSpriteModel @@ -356,14 +356,14 @@ Mod_UnloadSpriteModel
release sprite model and frames
====================
*/
void Mod_UnloadSpriteModel( model_t *mod )
void Mod_SpriteUnloadTextures( void *data )
{
msprite_t *psprite;
mspritegroup_t *pspritegroup;
mspriteframe_t *pspriteframe;
int i, j;
psprite = mod->cache.data;
psprite = data;
if( psprite )
{

2
ref_gl/gl_studio.c

@ -3584,7 +3584,7 @@ void Mod_StudioLoadTextures( model_t *mod, void *data ) @@ -3584,7 +3584,7 @@ void Mod_StudioLoadTextures( model_t *mod, void *data )
/*
=================
Mod_StudioLoadTextures
Mod_StudioUnloadTextures
=================
*/
void Mod_StudioUnloadTextures( void *data )

Loading…
Cancel
Save