raze-gles/source/build/src/texcache.cpp

205 lines
6.6 KiB
C++
Raw Normal View History

#ifdef USE_OPENGL
#include "baselayer.h"
#include "build.h"
#include "lz4.h"
#include "hightile.h"
#include "polymost.h"
#include "texcache.h"
#include "scriptfile.h"
#include "xxhash.h"
#include "kplib.h"
#include "vfs.h"
#define CLEAR_GL_ERRORS() while(glGetError() != GL_NO_ERROR) { }
#define TEXCACHE_FREEBUFS() { Bfree(pic), Bfree(packbuf), Bfree(midbuf); }
globaltexcache texcache;
static pthtyp *texcache_tryart(int32_t const dapicnum, int32_t const dapalnum, int32_t const dashade, int32_t dameth)
{
const int32_t j = dapicnum&(GLTEXCACHEADSIZ-1);
pthtyp *pth;
int32_t tintpalnum = -1;
int32_t searchpalnum = dapalnum;
polytintflags_t const tintflags = hictinting[dapalnum].f;
if (tintflags & (HICTINT_USEONART|HICTINT_ALWAYSUSEART))
{
tintpalnum = dapalnum;
dameth &= ~PTH_INDEXED;
if (!(tintflags & HICTINT_APPLYOVERPALSWAP))
searchpalnum = 0;
}
// load from art
for (pth=texcache.list[j]; pth; pth=pth->next)
if (pth->picnum == dapicnum &&
(dameth & PTH_INDEXED ? (pth->flags & PTH_INDEXED) &&
(pth->flags & PTH_CLAMPED) == TO_PTH_CLAMPED(dameth) :
(pth->palnum == dapalnum && pth->shade == dashade &&
!(pth->flags & PTH_INDEXED) &&
(pth->flags & (PTH_CLAMPED | PTH_HIGHTILE | PTH_NOTRANSFIX)) ==
(TO_PTH_CLAMPED(dameth) | TO_PTH_NOTRANSFIX(dameth)) &&
polymost_want_npotytex(dameth, tilesiz[dapicnum].y) == !!(pth->flags&PTH_NPOTWALL))))
{
if (pth->flags & PTH_INVALIDATED)
{
pth->flags &= ~PTH_INVALIDATED;
gloadtile_art(dapicnum, searchpalnum, tintpalnum, dashade, dameth, pth, 0);
pth->palnum = dapalnum;
}
return pth;
}
pth = (pthtyp *)Xcalloc(1,sizeof(pthtyp));
2019-09-13 19:43:05 +00:00
#ifdef TIMING
cycle_t clock;
clock.Reset();
clock.Clock();
#endif
gloadtile_art(dapicnum, searchpalnum, tintpalnum, dashade, dameth, pth, 1);
//thl.AddToCache(dapicnum, dapalnum, dameth);
#ifdef TIMING
clock.Unclock();
OSD_Printf("Loaded texture %d, palnum %d, meth %d -> %2.3f\n", dapicnum, dapalnum, dameth, clock.TimeMS());
#endif
pth->palnum = dapalnum;
pth->next = texcache.list[j];
texcache.list[j] = pth;
return pth;
}
pthtyp *texcache_fetchmulti(pthtyp *pth, hicreplctyp *si, int32_t dapicnum, int32_t dameth)
{
const int32_t j = dapicnum&(GLTEXCACHEADSIZ-1);
int32_t i;
for (i = 0; i <= (GLTEXCACHEADSIZ - 1); i++)
{
const pthtyp *pth2;
for (pth2=texcache.list[i]; pth2; pth2=pth2->next)
{
if (pth2->hicr && pth2->hicr->filename && si->filename && filnamcmp(pth2->hicr->filename, si->filename) == 0)
{
Bmemcpy(pth, pth2, sizeof(pthtyp));
pth->picnum = dapicnum;
pth->flags = TO_PTH_CLAMPED(dameth) | TO_PTH_NOTRANSFIX(dameth) |
PTH_HIGHTILE | (drawingskybox>0)*PTH_SKYBOX;
if (pth2->flags & PTH_HASALPHA)
pth->flags |= PTH_HASALPHA;
pth->hicr = si;
pth->next = texcache.list[j];
texcache.list[j] = pth;
return pth;
}
}
}
return NULL;
}
// <dashade>: ignored if not in Polymost+r_usetileshades
pthtyp *texcache_fetch(int32_t dapicnum, int32_t dapalnum, int32_t dashade, int32_t dameth)
{
const int32_t j = dapicnum & (GLTEXCACHEADSIZ - 1);
hicreplctyp *si = usehightile ? hicfindsubst(dapicnum, dapalnum, hictinting[dapalnum].f & HICTINT_ALWAYSUSEART) : NULL;
if (drawingskybox && usehightile)
if ((si = hicfindskybox(dapicnum, dapalnum)) == NULL)
return NULL;
if (!r_usetileshades || (globalflags & GLOBAL_NO_GL_TILESHADES) || videoGetRenderMode() != REND_POLYMOST)
dashade = 0;
if (!si)
{
return (dapalnum >= (MAXPALOOKUPS - RESERVEDPALS) || hicprecaching) ?
NULL : texcache_tryart(dapicnum, dapalnum, dashade, dameth);
}
/* if palette > 0 && replacement found
* no effects are applied to the texture
* else if palette > 0 && no replacement found
* effects are applied to the palette 0 texture if it exists
*/
polytintflags_t const tintflags = hictinting[dapalnum].f;
const int32_t checktintpal = (tintflags & HICTINT_APPLYOVERALTPAL) ? 0 : si->palnum;
const int32_t checkcachepal = ((tintflags & HICTINT_IN_MEMORY) || ((tintflags & HICTINT_APPLYOVERALTPAL) && si->palnum > 0)) ? dapalnum : si->palnum;
// load a replacement
for (pthtyp *pth = texcache.list[j]; pth; pth = pth->next)
{
if (pth->picnum == dapicnum && pth->palnum == checkcachepal && (checktintpal > 0 ? 1 : (pth->effects == tintflags))
&& (pth->flags & (PTH_CLAMPED | PTH_HIGHTILE | PTH_SKYBOX | PTH_NOTRANSFIX))
== (TO_PTH_CLAMPED(dameth) | TO_PTH_NOTRANSFIX(dameth) | PTH_HIGHTILE | (drawingskybox > 0) * PTH_SKYBOX)
&& (drawingskybox > 0 ? (pth->skyface == drawingskybox) : 1))
{
if (pth->flags & PTH_INVALIDATED)
{
pth->flags &= ~PTH_INVALIDATED;
int32_t tilestat = gloadtile_hi(dapicnum, dapalnum, drawingskybox, si, dameth, pth, 0,
(checktintpal > 0) ? 0 : tintflags); // reload tile
if (!tilestat)
continue;
if (tilestat == -2) // bad filename
hicclearsubst(dapicnum, dapalnum);
return (drawingskybox || hicprecaching) ? NULL : texcache_tryart(dapicnum, dapalnum, dashade, dameth);
}
return pth;
}
}
pthtyp *pth = (pthtyp *)Xcalloc(1, sizeof(pthtyp));
// possibly fetch an already loaded multitexture :_)
if (dapalnum == DETAILPAL && texcache_fetchmulti(pth, si, dapicnum, dameth))
return pth;
2019-09-13 19:43:05 +00:00
#ifdef TIMING
cycle_t clock;
clock.Reset();
clock.Clock();
#endif
int32_t tilestat = gloadtile_hi(dapicnum, dapalnum, drawingskybox, si, dameth, pth, 1, (checktintpal > 0) ? 0 : tintflags);
#ifdef TIMING
clock.Unclock();
OSD_Printf("Loaded texture %d, palnum %d, meth %d -> %2.3f\n", dapicnum, dapalnum, dameth, clock.TimeMS());
#endif
if (!tilestat)
{
pth->next = texcache.list[j];
pth->palnum = checkcachepal;
texcache.list[j] = pth;
return pth;
}
if (tilestat == -2) // bad filename
hicclearsubst(dapicnum, dapalnum);
Bfree(pth);
return (drawingskybox || hicprecaching) ? NULL : texcache_tryart(dapicnum, dapalnum, dashade, dameth);
}
#endif