Improve GPU texture management.

This commit is contained in:
Jaime Ita Passos 2020-11-22 18:18:26 -03:00
parent abe35fd008
commit 0645c642d2
7 changed files with 37 additions and 45 deletions

View file

@ -585,6 +585,21 @@ static GLMapTexture_t *gl_textures; // For all textures
static GLMapTexture_t *gl_flats; // For all (texture) flats, as normal flats don't need to be cached
boolean gl_maptexturesloaded = false;
void HWR_FreeTextureData(patch_t *patch)
{
GLPatch_t *grPatch;
if (!patch || !patch->hardware)
return;
grPatch = patch->hardware;
if (vid.glstate == VID_GL_LIBRARY_LOADED)
HWD.pfnDeleteTexture(grPatch->mipmap);
if (grPatch->mipmap->data)
Z_Free(grPatch->mipmap->data);
}
void HWR_FreeTexture(patch_t *patch)
{
if (!patch)
@ -598,10 +613,7 @@ void HWR_FreeTexture(patch_t *patch)
if (grPatch->mipmap)
{
if (vid.glstate == VID_GL_LIBRARY_LOADED)
HWD.pfnDeleteTexture(grPatch->mipmap);
if (grPatch->mipmap->data)
Z_Free(grPatch->mipmap->data);
HWR_FreeTextureData(patch);
Z_Free(grPatch->mipmap);
}
@ -636,15 +648,12 @@ void HWR_FreeTextureColormaps(patch_t *patch)
if (!pat->mipmap)
break;
// No colormap mipmap either.
// No colormap mipmaps either.
if (!pat->mipmap->nextcolormap)
break;
// Set the first colormap to the one that comes after it.
next = pat->mipmap->nextcolormap;
if (!next)
break;
pat->mipmap->nextcolormap = next->nextcolormap;
// Free image data from memory.
@ -670,18 +679,13 @@ static void HWR_FreePatchCache(boolean freeall)
}
}
// free all textures after each level
void HWR_ClearAllTextures(void)
{
HWR_FreeMapTextures();
// Alam: free the Z_Blocks before freeing it's users
HWD.pfnClearMipMapCache(); // free references to the textures
HWR_FreePatchCache(true);
// free references to the textures
HWD.pfnClearCacheList();
}
// free all patch colormaps after each level
void HWR_FreeColormapCache(void)
{
HWR_FreePatchCache(false);

View file

@ -43,19 +43,19 @@ typedef enum GLTextureFormat_e
// NULL if the texture is not in Doom heap cache.
struct GLMipmap_s
{
//for TexDownloadMipMap
GLTextureFormat_t format;
void *data;
// for TexDownloadMipMap
GLTextureFormat_t format;
void *data;
UINT32 flags;
UINT16 height;
UINT16 width;
UINT32 downloaded; // the dll driver have it in there cache ?
UINT32 flags;
UINT16 height;
UINT16 width;
UINT32 downloaded; // The GPU has this texture.
struct GLMipmap_s *nextcolormap;
const UINT8 *colormap;
struct GLMipmap_s *prevmipmap, *nextmipmap; // Linked list of all textures
struct GLMipmap_s *nextmipmap; // Linked list of all textures
};
typedef struct GLMipmap_s GLMipmap_t;

View file

@ -121,6 +121,7 @@ void HWR_GetLevelFlat(levelflat_t *levelflat);
void HWR_LiterallyGetFlat(lumpnum_t flatlumpnum);
void HWR_FreeTexture(patch_t *patch);
void HWR_FreeTextureData(patch_t *patch);
void HWR_FreeTextureColormaps(patch_t *patch);
void HWR_ClearAllTextures(void);
void HWR_FreeColormapCache(void);

View file

@ -6221,17 +6221,6 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
void HWR_LoadLevel(void)
{
// Lactozilla (December 8, 2019)
// Level setup used to free EVERY mipmap from memory.
// Even mipmaps that aren't related to level textures.
// Presumably, the hardware render code used to store textures as level data.
// Meaning, they had memory allocated and marked with the PU_LEVEL tag.
// Level textures are only reloaded after R_LoadTextures, which is
// when the texture list is loaded.
// Sal: Unfortunately, NOT freeing them causes the dreaded Color Bug.
HWR_FreeColormapCache();
#ifdef ALAM_LIGHTING
// BP: reset light between levels (we draw preview frame lights on current frame)
HWR_ResetLights();
@ -6394,7 +6383,10 @@ void HWR_Switch(void)
// Create plane polygons
if (!gl_maploaded && (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)))
{
HWR_ClearAllTextures();
HWR_LoadLevel();
}
}
// --------------------------------------------------------------------------

View file

@ -1292,9 +1292,6 @@ EXPORT void HWRAPI(DeleteTexture) (FTextureInfo *pTexInfo)
if (pTexInfo->downloaded)
pglDeleteTextures(1, (GLuint *)&pTexInfo->downloaded);
pTexInfo->downloaded = 0;
if (pTexInfo->prevmipmap)
pTexInfo->prevmipmap->nextmipmap = pTexInfo->nextmipmap;
}
@ -1941,15 +1938,12 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
else
{
UpdateTexture(pTexInfo);
pTexInfo->prevmipmap = NULL;
pTexInfo->nextmipmap = NULL;
// insertion at the tail
if (gl_cachetail)
{
gl_cachetail->nextmipmap = pTexInfo;
pTexInfo->prevmipmap = gl_cachetail;
gl_cachetail = pTexInfo;
}
else // initialization of the linked list

View file

@ -4133,6 +4133,12 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
// Clear pointers that would be left dangling by the purge
R_FlushTranslationColormapCache();
#ifdef HWRENDER
// Free GPU textures before freeing patches.
if (vid.glstate == VID_GL_LIBRARY_LOADED)
HWR_ClearAllTextures();
#endif
Patch_FreeTag(PU_PATCH_LOWPRIORITY);
Patch_FreeTag(PU_PATCH_ROTATED);
Z_FreeTags(PU_LEVEL, PU_PURGELEVEL - 1);

View file

@ -1568,11 +1568,6 @@ boolean VID_CheckRenderer(void)
bufSurface = NULL;
}
#ifdef HWRENDER
if (rendererchanged && vid.glstate == VID_GL_LIBRARY_LOADED) // Only if OpenGL ever loaded!
HWR_ClearAllTextures();
#endif
SCR_SetDrawFuncs();
}
#ifdef HWRENDER