halflife icon indicating copy to clipboard operation
halflife copied to clipboard

[GoldSource] Texture overflow: GL_MAXTEXTURES crash

Open metita opened this issue 5 years ago • 26 comments

Sometimes when you are on a server with a lot of textures (I guess this is the reason based on the error code) and you keep switching between servers, your client will crash randomly. I can't really tell how to reproduce it so if someone has extra info would be amazing.

metita avatar Apr 24 '19 00:04 metita

This is a common issue on a lot of mod servers when switching between servers continuously, if someone got the original output on when this crash occurs, would help a lot.

metita avatar Apr 25 '19 20:04 metita

There are a maximum of 4800 textures that can be loaded. Normally textures are unloaded when the client starts preparing to load a new map. It looks like this part works fine.

Edit: everything below here is wrong, see comment below.

The part that doesn't is the code that reuses texture entries that were freed:

while ( HIBYTE(v12->servercount) & 0x80 )
{
  if ( !v9 )
    v9 = v12;
  ++v13;
  ++v12;
  if ( v13 >= v11 )
    goto LABEL_10;
}

//Other stuff that is ignored

LABEL_10:
if ( !v9 )
{
    v9 = &gltextures[numgltextures++];
    if ( numgltextures >= 4800 )
      Sys_Error("Texture Overflow: MAX_GLTEXTURES");
}

This is from GL_LoadTexture2. It translates to this:

gltexture_t* pSlot = nullptr;

for( int i = 0; i < numgltextures; ++i )
{
    if( gltextures[ i ].servercount >= 0 )
        break;

    if( !pSlot  )
        pSlot  = &gltextures[ i ];
}

//Other stuff that is ignored

if ( !pSlot )
{
    pSlot = &gltextures[numgltextures++];
    if ( numgltextures >= 4800 )
      Sys_Error("Texture Overflow: MAX_GLTEXTURES");
}

This code is supposed to find the first free entry (servercount < 0), but it instead stops searching when it encounters a single texture in use.

As a result GL_LoadTexture2 will almost never reuse freed entries and will keep allocating new entries until it runs out, resulting in the fatal error.

To fix this, the loop needs to be changed to this:

for( int i = 0; i < numgltextures; ++i )
{
    if( gltextures[ i ].servercount >= 0 )
        continue;

    if( !pSlot  )
        pSlot  = &gltextures[ i ];
}

Now it will skip entries in use and correctly reuse free entries.

@mikela-valve This should be fairly simple to fix and test.

SamVanheer avatar Apr 25 '19 22:04 SamVanheer

Thanks @SamVanheer appreciated your work.

@kisak-valve fix proposed? Thanks.

metita avatar Apr 25 '19 22:04 metita

Sorry, i got this wrong. There's an outer loop that ensures it iterates over each texture.

I did find what i think is the problem: in GL_LoadTexture2 the servercount variable is set depending on the texture type:

if ( textureType == GLT_WORLD )
{
  slot->servercount = gHostSpawnCount;
}
else
{
  slot->servercount = 0;
}

And in GL_UnloadTextures:

if ( pTexture->servercount > 0 && pTexture->servercount != gHostSpawnCount )

All textures other than the world (map textures) are never unloaded. An easy fix is to always use gHostSpawnCount and let all textures unload, but then there's the risk of unloading textures that are only loaded once (e.g. Draw_PicFromWad).

GLT_SYSTEM and GLT_DECAL texture types definitely shouldn't be unloaded, it looks like all others are resources that are loaded once per map. Maybe allowing all of these to be unloaded is the safest bet:

  • GLT_STUDIO
  • GLT_WORLD
  • GLT_SPRITE

It looks like hud sprites are always GLT_HUDSPRITE so they should be safe.

SamVanheer avatar Apr 25 '19 23:04 SamVanheer

I'm going to delay this until after the next release as I'd like it to be in a beta that has fewer changes in it to make it easier to notice if any issues arise from unloading these other texture types.

mikela-valve avatar May 16 '19 16:05 mikela-valve

@mikela-valve Now that we got a clean beta and the latest update got released officially would like you to take a look at this issue because is a very common one on modded servers.

metita avatar Oct 23 '19 20:10 metita

Any news about this? It's a bit annoying nowadays

dystopm avatar Nov 17 '19 20:11 dystopm

@mikela-valve can you fix this?

zorkenJB avatar Jan 19 '20 18:01 zorkenJB

I would also gladly see this fix applied as it is a common issue nowadays.

TheDoctor0 avatar Jul 18 '20 16:07 TheDoctor0

Nothing? @mikela-valve it is a frequent error this days, will this ever be considerated on a future release?

dystopm avatar Jul 19 '20 03:07 dystopm

@mikela-valve Sorry for bothering you with this one, is there a chance for this issue to be somehow added into the beta now that there are almost 0 issues with it? It is a annoying bug that is pretty common nowadays.

metita avatar Aug 03 '20 21:08 metita

considerating we're getting updates for the game, can you please take a look at this issue? @mikela-valve thanks in advance

Roccoxx avatar Aug 04 '20 01:08 Roccoxx

This is very annoying, can you take a look at it please? @mikela-valve

Maria22s avatar Aug 04 '20 01:08 Maria22s

You don't all have to get his attention, one person calling for him is more than enough. And the issue is already assigned to the next release milestone so it's a priority issue anyway.

SamVanheer avatar Aug 04 '20 09:08 SamVanheer

When will it be? after 5 years? or will not at all. @mikela-valve

P.S Do you have an idea how to fix it? Texture overflow: GL_MAXTEXTURES.

orinasa avatar Oct 15 '20 21:10 orinasa

This is a high priority issue which is ruining actual gameplay, and also an excuse for players to use pirate software (to fix it) because most servers are modded nowadays with lots of resources, bringing a high chance to suffer this crash - @mikela-valve may I ask again, is there a chance to get this fixed?

dystopm avatar Oct 15 '20 22:10 dystopm

Agreed with @PM32, got this error on most of servers (i have my own modded server and my client suffers with this error)

cyb3rm4n avatar Nov 13 '20 23:11 cyb3rm4n

@mikela-valve can you please fix it? is not that hard On Saturday, November 14, 2020, 01:42:51 AM GMT+2, Alexander Zhukov [email protected] wrote:

Agreed with @PM32, got this error on most of servers (i have my own modded server and my client suffers with this error)

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

zorkenJB avatar Nov 14 '20 09:11 zorkenJB

@mikela-valve can you please fix it? is not that hard On Saturday, November 14, 2020, 01:42:51 AM GMT+2, Alexander Zhukov [email protected] wrote: Agreed with @PM32, got this error on most of servers (i have my own modded server and my client suffers with this error) — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.

Is not about difficulty, he doesn't have time to work on goldsrc.

Maxi605 avatar Nov 14 '20 19:11 Maxi605

@mikela-valve can you please fix it? is not that hard On Saturday, November 14, 2020, 01:42:51 AM GMT+2, Alexander Zhukov [email protected] wrote: Agreed with @PM32, got this error on most of servers (i have my own modded server and my client suffers with this error) — You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe. Is not about difficulty, he doesn't have time to work on goldsrc.

15 minutes work. and you say he doesn't have time to work? Lol...

orinasa avatar Nov 16 '20 04:11 orinasa

Supporting a 22 year old game is about as low priority as it gets, and chances are the source code isn't even accessible remotely so they can't work on it until the pandemic is under control. All you can do is be patient.

SamVanheer avatar Nov 16 '20 10:11 SamVanheer

Sorry, i got this wrong. There's an outer loop that ensures it iterates over each texture.

I did find what i think is the problem: in GL_LoadTexture2 the servercount variable is set depending on the texture type:

if ( textureType == GLT_WORLD )
{
  slot->servercount = gHostSpawnCount;
}
else
{
  slot->servercount = 0;
}

And in GL_UnloadTextures:

if ( pTexture->servercount > 0 && pTexture->servercount != gHostSpawnCount )

All textures other than the world (map textures) are never unloaded. An easy fix is to always use gHostSpawnCount and let all textures unload, but then there's the risk of unloading textures that are only loaded once (e.g. Draw_PicFromWad).

GLT_SYSTEM and GLT_DECAL texture types definitely shouldn't be unloaded, it looks like all others are resources that are loaded once per map. Maybe allowing all of these to be unloaded is the safest bet:

  • GLT_STUDIO
  • GLT_WORLD
  • GLT_SPRITE

It looks like hud sprites are always GLT_HUDSPRITE so they should be safe.

@Solokiller IMHO, it looks like the issue is that the numgltextures global counter never decreases, and also textures potentially can be unloaded from the middle of the gltexture_t gltextures[4800] without shifting elements

s1lentq avatar Nov 20 '20 17:11 s1lentq

True, it doesn't seem to ever decrement that variable. However it does reuse texture slots that were unloaded so the error should only occur if all 4800 slots are in use at the same time. If the error occurs after a certain amount of time rather than when loading a particular map or other assets then it isn't clearing those slots correctly.

SamVanheer avatar Nov 20 '20 17:11 SamVanheer

three years later, without news, we also provide the code with the solution ... they just have to implement and test it.

Matiarguello avatar Aug 04 '21 13:08 Matiarguello

@MatiasEsf, because nobody cares more about this game

hajimura avatar Aug 04 '21 13:08 hajimura

@mikela-valve up?

lexzor avatar May 30 '22 19:05 lexzor