OpenGL backend: Manage uploaded GPU textures with an internal list

Indirectly fixes the game doing whatever after freeing a patch.
This commit implements a FTextureInfo struct type, instead of it being a typedef to the GLMipmap_s struct type.
This commit is contained in:
Jaime Ita Passos 2021-01-27 17:48:57 -03:00
parent 29b6bd5df9
commit 5501d495c7
11 changed files with 106 additions and 86 deletions

View File

@ -2546,28 +2546,28 @@ static void F_UnloadAlacroixGraphics(SINT8 oldttscale)
oldttscale--; // zero-based index
for (i = 0; i < TTMAX_ALACROIX; i++)
{
if(ttembl[oldttscale][i]) { Z_Free(ttembl[oldttscale][i]); ttembl[oldttscale][i] = 0; }
if(ttribb[oldttscale][i]) { Z_Free(ttribb[oldttscale][i]); ttribb[oldttscale][i] = 0; }
if(ttsont[oldttscale][i]) { Z_Free(ttsont[oldttscale][i]); ttsont[oldttscale][i] = 0; }
if(ttrobo[oldttscale][i]) { Z_Free(ttrobo[oldttscale][i]); ttrobo[oldttscale][i] = 0; }
if(tttwot[oldttscale][i]) { Z_Free(tttwot[oldttscale][i]); tttwot[oldttscale][i] = 0; }
if(ttrbtx[oldttscale][i]) { Z_Free(ttrbtx[oldttscale][i]); ttrbtx[oldttscale][i] = 0; }
if(ttsoib[oldttscale][i]) { Z_Free(ttsoib[oldttscale][i]); ttsoib[oldttscale][i] = 0; }
if(ttsoif[oldttscale][i]) { Z_Free(ttsoif[oldttscale][i]); ttsoif[oldttscale][i] = 0; }
if(ttsoba[oldttscale][i]) { Z_Free(ttsoba[oldttscale][i]); ttsoba[oldttscale][i] = 0; }
if(ttsobk[oldttscale][i]) { Z_Free(ttsobk[oldttscale][i]); ttsobk[oldttscale][i] = 0; }
if(ttsodh[oldttscale][i]) { Z_Free(ttsodh[oldttscale][i]); ttsodh[oldttscale][i] = 0; }
if(tttaib[oldttscale][i]) { Z_Free(tttaib[oldttscale][i]); tttaib[oldttscale][i] = 0; }
if(tttaif[oldttscale][i]) { Z_Free(tttaif[oldttscale][i]); tttaif[oldttscale][i] = 0; }
if(tttaba[oldttscale][i]) { Z_Free(tttaba[oldttscale][i]); tttaba[oldttscale][i] = 0; }
if(tttabk[oldttscale][i]) { Z_Free(tttabk[oldttscale][i]); tttabk[oldttscale][i] = 0; }
if(tttabt[oldttscale][i]) { Z_Free(tttabt[oldttscale][i]); tttabt[oldttscale][i] = 0; }
if(tttaft[oldttscale][i]) { Z_Free(tttaft[oldttscale][i]); tttaft[oldttscale][i] = 0; }
if(ttknib[oldttscale][i]) { Z_Free(ttknib[oldttscale][i]); ttknib[oldttscale][i] = 0; }
if(ttknif[oldttscale][i]) { Z_Free(ttknif[oldttscale][i]); ttknif[oldttscale][i] = 0; }
if(ttknba[oldttscale][i]) { Z_Free(ttknba[oldttscale][i]); ttknba[oldttscale][i] = 0; }
if(ttknbk[oldttscale][i]) { Z_Free(ttknbk[oldttscale][i]); ttknbk[oldttscale][i] = 0; }
if(ttkndh[oldttscale][i]) { Z_Free(ttkndh[oldttscale][i]); ttkndh[oldttscale][i] = 0; }
if(ttembl[oldttscale][i]) { Patch_Free(ttembl[oldttscale][i]); ttembl[oldttscale][i] = 0; }
if(ttribb[oldttscale][i]) { Patch_Free(ttribb[oldttscale][i]); ttribb[oldttscale][i] = 0; }
if(ttsont[oldttscale][i]) { Patch_Free(ttsont[oldttscale][i]); ttsont[oldttscale][i] = 0; }
if(ttrobo[oldttscale][i]) { Patch_Free(ttrobo[oldttscale][i]); ttrobo[oldttscale][i] = 0; }
if(tttwot[oldttscale][i]) { Patch_Free(tttwot[oldttscale][i]); tttwot[oldttscale][i] = 0; }
if(ttrbtx[oldttscale][i]) { Patch_Free(ttrbtx[oldttscale][i]); ttrbtx[oldttscale][i] = 0; }
if(ttsoib[oldttscale][i]) { Patch_Free(ttsoib[oldttscale][i]); ttsoib[oldttscale][i] = 0; }
if(ttsoif[oldttscale][i]) { Patch_Free(ttsoif[oldttscale][i]); ttsoif[oldttscale][i] = 0; }
if(ttsoba[oldttscale][i]) { Patch_Free(ttsoba[oldttscale][i]); ttsoba[oldttscale][i] = 0; }
if(ttsobk[oldttscale][i]) { Patch_Free(ttsobk[oldttscale][i]); ttsobk[oldttscale][i] = 0; }
if(ttsodh[oldttscale][i]) { Patch_Free(ttsodh[oldttscale][i]); ttsodh[oldttscale][i] = 0; }
if(tttaib[oldttscale][i]) { Patch_Free(tttaib[oldttscale][i]); tttaib[oldttscale][i] = 0; }
if(tttaif[oldttscale][i]) { Patch_Free(tttaif[oldttscale][i]); tttaif[oldttscale][i] = 0; }
if(tttaba[oldttscale][i]) { Patch_Free(tttaba[oldttscale][i]); tttaba[oldttscale][i] = 0; }
if(tttabk[oldttscale][i]) { Patch_Free(tttabk[oldttscale][i]); tttabk[oldttscale][i] = 0; }
if(tttabt[oldttscale][i]) { Patch_Free(tttabt[oldttscale][i]); tttabt[oldttscale][i] = 0; }
if(tttaft[oldttscale][i]) { Patch_Free(tttaft[oldttscale][i]); tttaft[oldttscale][i] = 0; }
if(ttknib[oldttscale][i]) { Patch_Free(ttknib[oldttscale][i]); ttknib[oldttscale][i] = 0; }
if(ttknif[oldttscale][i]) { Patch_Free(ttknif[oldttscale][i]); ttknif[oldttscale][i] = 0; }
if(ttknba[oldttscale][i]) { Patch_Free(ttknba[oldttscale][i]); ttknba[oldttscale][i] = 0; }
if(ttknbk[oldttscale][i]) { Patch_Free(ttknbk[oldttscale][i]); ttknbk[oldttscale][i] = 0; }
if(ttkndh[oldttscale][i]) { Patch_Free(ttkndh[oldttscale][i]); ttkndh[oldttscale][i] = 0; }
}
ttloaded[oldttscale] = false;
}

View File

@ -1091,7 +1091,6 @@ void HWR_UnlockCachedPatch(GLPatch_t *gpatch)
return;
Z_ChangeTag(gpatch->mipmap->data, PU_HWRCACHE_UNLOCKED);
Z_ChangeTag(gpatch, PU_HWRPATCHINFO_UNLOCKED);
}
static const INT32 picmode2GR[] =

View File

@ -48,18 +48,19 @@ struct GLColormap_s
typedef struct GLColormap_s GLColormap_t;
// data holds the address of the graphics data cached in heap memory
// NULL if the texture is not in Doom heap cache.
// Texture information (misleadingly named "mipmap" all over the code.)
// The *data pointer holds the address of the graphics data cached in heap memory.
// NULL if the texture is not in SRB2's heap cache.
struct GLMipmap_s
{
// for TexDownloadMipMap
// for UpdateTexture
GLTextureFormat_t format;
void *data;
UINT32 flags;
UINT16 height;
UINT16 width;
UINT32 downloaded; // The GPU has this texture.
UINT32 downloaded; // The GPU has this texture.
struct GLMipmap_s *nextcolormap;
struct GLColormap_s *colormap;
@ -70,22 +71,22 @@ typedef struct GLMipmap_s GLMipmap_t;
//
// Doom texture info, as cached for hardware rendering
// Level textures, as cached for hardware rendering.
//
struct GLMapTexture_s
{
GLMipmap_t mipmap;
float scaleX; //used for scaling textures on walls
float scaleX; // Used for scaling textures on walls
float scaleY;
};
typedef struct GLMapTexture_s GLMapTexture_t;
// a cached patch as converted to hardware format
// Patch information for the hardware renderer.
struct GLPatch_s
{
float max_s,max_t;
GLMipmap_t *mipmap;
GLMipmap_t *mipmap; // Texture data. Allocated whenever the patch is.
float max_s, max_t;
};
typedef struct GLPatch_s GLPatch_t;

View File

@ -255,7 +255,16 @@ enum ETextureFlags
TF_TRANSPARENT = 0x00000040, // texture with some alpha == 0
};
typedef struct GLMipmap_s FTextureInfo;
struct FTextureInfo
{
UINT32 width, height;
UINT32 downloaded;
UINT32 format;
struct GLMipmap_s *texture;
struct FTextureInfo *prev, *next;
};
typedef struct FTextureInfo FTextureInfo;
// jimita 14032019
struct FLightInfo

View File

@ -40,13 +40,12 @@ EXPORT void HWRAPI(DrawIndexedTriangles) (FSurfaceInfo *pSurf, FOutVector *pOutV
EXPORT void HWRAPI(RenderSkyDome) (gl_sky_t *sky);
EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags);
EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor);
EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo);
EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *TexInfo);
EXPORT void HWRAPI(DeleteTexture) (FTextureInfo *TexInfo);
EXPORT void HWRAPI(SetTexture) (GLMipmap_t *TexInfo);
EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *TexInfo);
EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *TexInfo);
EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 *dst_data);
EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip);
EXPORT void HWRAPI(ClearMipMapCache) (void);
EXPORT void HWRAPI(ClearCacheList) (void);
//Hurdler: added for backward compatibility
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value);
@ -101,7 +100,6 @@ struct hwdriver_s
ReadRect pfnReadRect;
GClipRect pfnGClipRect;
ClearMipMapCache pfnClearMipMapCache;
ClearCacheList pfnClearCacheList;
SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility
DrawModel pfnDrawModel;
CreateModelVBOs pfnCreateModelVBOs;

View File

@ -58,8 +58,9 @@ static GLuint tex_downloaded = 0;
static GLfloat fov = 90.0f;
static FBITFIELD CurrentPolyFlags;
static FTextureInfo *gl_cachetail = NULL;
static FTextureInfo *gl_cachehead = NULL;
// Linked list of all textures.
static FTextureInfo *TexCacheTail = NULL;
static FTextureInfo *TexCacheHead = NULL;
RGBA_t myPaletteData[256];
GLint screen_width = 0; // used by Draw2DLine()
@ -1287,10 +1288,30 @@ void SetStates(void)
// -----------------+
// DeleteTexture : Deletes a texture from the GPU and frees its data
// -----------------+
EXPORT void HWRAPI(DeleteTexture) (FTextureInfo *pTexInfo)
EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *pTexInfo)
{
if (pTexInfo->downloaded)
FTextureInfo *head = TexCacheHead;
if (!pTexInfo)
return;
else if (pTexInfo->downloaded)
pglDeleteTextures(1, (GLuint *)&pTexInfo->downloaded);
while (head)
{
if (head->downloaded == pTexInfo->downloaded)
{
if (head->next)
head->next->prev = head->prev;
if (head->prev)
head->prev->next = head->next;
free(head);
break;
}
head = head->next;
}
pTexInfo->downloaded = 0;
}
@ -1303,26 +1324,29 @@ void Flush(void)
{
//GL_DBG_Printf ("HWR_Flush()\n");
while (gl_cachehead)
while (TexCacheHead)
{
DeleteTexture(gl_cachehead);
gl_cachehead = gl_cachehead->nextmipmap;
FTextureInfo *pTexInfo = TexCacheHead;
GLMipmap_t *texture = pTexInfo->texture;
if (pTexInfo->downloaded)
{
pglDeleteTextures(1, (GLuint *)&pTexInfo->downloaded);
pTexInfo->downloaded = 0;
}
if (texture)
texture->downloaded = 0;
TexCacheHead = pTexInfo->next;
free(pTexInfo);
}
ClearCacheList(); //Hurdler: well, gl_cachehead is already NULL
TexCacheTail = TexCacheHead = NULL; //Hurdler: well, TexCacheHead is already NULL
tex_downloaded = 0;
}
// -----------------+
// ClearCacheList : Clears the texture cache tail and head
// -----------------+
EXPORT void HWRAPI(ClearCacheList) (void)
{
gl_cachetail = gl_cachehead = NULL;
}
// -----------------+
// isExtAvailable : Look if an OpenGL extension is available
// Returns : true if extension available
@ -1718,7 +1742,7 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags)
// -----------------+
// UpdateTexture : Updates the texture data.
// -----------------+
EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo)
EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
{
// Download a mipmap
boolean updatemipmap = true;
@ -1920,7 +1944,7 @@ EXPORT void HWRAPI(UpdateTexture) (FTextureInfo *pTexInfo)
// -----------------+
// SetTexture : The mipmap becomes the current texture source
// -----------------+
EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
EXPORT void HWRAPI(SetTexture) (GLMipmap_t *pTexInfo)
{
if (!pTexInfo)
{
@ -1937,17 +1961,25 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
}
else
{
FTextureInfo *newTex = calloc(1, sizeof (*newTex));
UpdateTexture(pTexInfo);
pTexInfo->nextmipmap = NULL;
newTex->texture = pTexInfo;
newTex->downloaded = (UINT32)pTexInfo->downloaded;
newTex->width = (UINT32)pTexInfo->width;
newTex->height = (UINT32)pTexInfo->height;
newTex->format = (UINT32)pTexInfo->format;
// insertion at the tail
if (gl_cachetail)
if (TexCacheTail)
{
gl_cachetail->nextmipmap = pTexInfo;
gl_cachetail = pTexInfo;
newTex->prev = TexCacheTail;
TexCacheTail->next = newTex;
TexCacheTail = newTex;
}
else // initialization of the linked list
gl_cachetail = gl_cachehead = pTexInfo;
TexCacheTail = TexCacheHead = newTex;
}
}
@ -3011,7 +3043,7 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
EXPORT INT32 HWRAPI(GetTextureUsed) (void)
{
FTextureInfo *tmp = gl_cachehead;
FTextureInfo *tmp = TexCacheHead;
INT32 res = 0;
while (tmp)
@ -3028,7 +3060,7 @@ EXPORT INT32 HWRAPI(GetTextureUsed) (void)
// Add it up!
res += tmp->height*tmp->width*bpp;
tmp = tmp->nextmipmap;
tmp = tmp->next;
}
return res;

View File

@ -90,7 +90,6 @@ void *hwSym(const char *funcName,void *handle)
GETFUNC(ReadRect);
GETFUNC(GClipRect);
GETFUNC(ClearMipMapCache);
GETFUNC(ClearCacheList);
GETFUNC(SetSpecialState);
GETFUNC(GetTextureUsed);
GETFUNC(DrawModel);

View File

@ -1862,7 +1862,6 @@ void VID_StartupOpenGL(void)
HWD.pfnReadRect = hwSym("ReadRect",NULL);
HWD.pfnGClipRect = hwSym("GClipRect",NULL);
HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL);
HWD.pfnClearCacheList = hwSym("ClearCacheList",NULL);
HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL);
HWD.pfnSetPalette = hwSym("SetPalette",NULL);
HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL);

View File

@ -1682,26 +1682,12 @@ void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
// read the lump in full
W_ReadLumpHeaderPwad(wad, lump, lumpdata, 0, 0);
ptr = lumpdata;
#ifndef NO_PNG_LUMPS
// lump is a png so convert it
if (Picture_IsLumpPNG((UINT8 *)lumpdata, len))
{
size_t newlen;
void *converted = Picture_PNGConvert((UINT8 *)lumpdata, PICFMT_DOOMPATCH, NULL, NULL, NULL, NULL, len, &newlen, 0);
ptr = Z_Malloc(newlen, PU_STATIC, NULL);
M_Memcpy(ptr, converted, newlen);
Z_Free(converted);
len = newlen;
}
else // just copy it into the patch cache
ptr = Picture_PNGConvert((UINT8 *)lumpdata, PICFMT_DOOMPATCH, NULL, NULL, NULL, NULL, len, &len, 0);
#endif
{
ptr = Z_Malloc(len, PU_STATIC, NULL);
M_Memcpy(ptr, lumpdata, len);
}
Z_Free(lumpdata);
dest = Z_Calloc(sizeof(patch_t), tag, &lumpcache[lump]);
Patch_Create(ptr, len, dest);

View File

@ -111,7 +111,6 @@ static loadfunc_t hwdFuncTable[] = {
{"ReadRect@24", &hwdriver.pfnReadRect},
{"GClipRect@20", &hwdriver.pfnGClipRect},
{"ClearMipMapCache@0", &hwdriver.pfnClearMipMapCache},
{"ClearCacheList@0", &hwdriver.pfnClearCacheList},
{"SetSpecialState@8", &hwdriver.pfnSetSpecialState},
{"DrawModel@16", &hwdriver.pfnDrawModel},
{"SetTransform@4", &hwdriver.pfnSetTransform},
@ -145,7 +144,6 @@ static loadfunc_t hwdFuncTable[] = {
{"ReadRect", &hwdriver.pfnReadRect},
{"GClipRect", &hwdriver.pfnGClipRect},
{"ClearMipMapCache", &hwdriver.pfnClearMipMapCache},
{"ClearCacheList", &hwdriver.pfnClearCacheList},
{"SetSpecialState", &hwdriver.pfnSetSpecialState},
{"DrawModel", &hwdriver.pfnDrawModel},
{"SetTransform", &hwdriver.pfnSetTransform},

View File

@ -68,8 +68,7 @@ enum
PU_HWRCACHE_UNLOCKED = 102, // 'unlocked' PU_HWRCACHE memory:
// 'second-level' cache for graphics
// stored in hardware format and downloaded as needed
PU_HWRPATCHINFO_UNLOCKED = 103, // 'unlocked' PU_HWRPATCHINFO memory
PU_HWRMODELTEXTURE_UNLOCKED = 104, // 'unlocked' PU_HWRMODELTEXTURE memory
PU_HWRMODELTEXTURE_UNLOCKED = 103, // 'unlocked' PU_HWRMODELTEXTURE memory
};
//