mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-29 07:22:05 +00:00
- rewrote texture caching so that not the base texture but the actually used translations for sprites get precached.
This commit is contained in:
parent
ec037bfd1a
commit
6f2b0a6293
7 changed files with 104 additions and 64 deletions
|
@ -73,6 +73,7 @@
|
|||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/stereo3d/gl_stereo3d.h"
|
||||
#include "gl/stereo3d/scoped_view_shifter.h"
|
||||
#include "gl/textures/gl_translate.h"
|
||||
#include "gl/textures/gl_material.h"
|
||||
#include "gl/textures/gl_skyboxtexture.h"
|
||||
#include "gl/utility/gl_clock.h"
|
||||
|
@ -979,6 +980,7 @@ struct FGLInterface : public FRenderer
|
|||
{
|
||||
bool UsesColormap() const;
|
||||
void PrecacheTexture(FTexture *tex, int cache);
|
||||
void PrecacheSprite(FTexture *tex, SpriteHits &hits);
|
||||
void Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhitlist);
|
||||
void RenderView(player_t *player);
|
||||
void WriteSavePic (player_t *player, FILE *file, int width, int height);
|
||||
|
@ -1021,20 +1023,54 @@ void FGLInterface::PrecacheTexture(FTexture *tex, int cache)
|
|||
{
|
||||
if (cache)
|
||||
{
|
||||
tex->PrecacheGL(cache);
|
||||
if (gl_precache)
|
||||
{
|
||||
if (cache & (FTextureManager::HIT_Wall | FTextureManager::HIT_Flat | FTextureManager::HIT_Sky))
|
||||
{
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(tex, false);
|
||||
if (gltex) gltex->Precache();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tex->UncacheGL();
|
||||
if (tex->gl_info.Material[0]) tex->gl_info.Material[0]->Clean(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DFrameBuffer :: PrecacheSprite
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLInterface::PrecacheSprite(FTexture *tex, SpriteHits &hits)
|
||||
{
|
||||
if (hits.CountUsed() == 0)
|
||||
{
|
||||
if (tex->gl_info.Material[1]) tex->gl_info.Material[1]->Clean(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(tex, true);
|
||||
if (gltex) gltex->PrecacheList(hits);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DFrameBuffer :: Precache
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLInterface::Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhitlist)
|
||||
{
|
||||
BYTE *spritelist = new BYTE[sprites.Size()];
|
||||
SpriteHits *spritelist = new SpriteHits[sprites.Size()];
|
||||
SpriteHits **spritehitlist = new SpriteHits*[TexMan.NumTextures()];
|
||||
TMap<PClassActor*, bool>::Iterator it(actorhitlist);
|
||||
TMap<PClassActor*, bool>::Pair *pair;
|
||||
memset(spritehitlist, 0, sizeof(SpriteHits**) * TexMan.NumTextures());
|
||||
|
||||
// this isn't done by the main code so it needs to be done here first:
|
||||
// check skybox textures and mark the separate faces as used
|
||||
|
@ -1059,19 +1095,14 @@ void FGLInterface::Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhit
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
memset(spritelist, 0, sprites.Size());
|
||||
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
PClassActor *cls = pair->Key;
|
||||
int gltrans = GLTranslationPalette::GetInternalTranslation(GetDefaultByType(cls)->Translation);
|
||||
|
||||
for (int i = 0; i < cls->NumOwnedStates; i++)
|
||||
{
|
||||
spritelist[cls->OwnedStates[i].sprite] = true;
|
||||
spritelist[cls->OwnedStates[i].sprite].Insert(gltrans, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1079,7 +1110,7 @@ void FGLInterface::Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhit
|
|||
|
||||
for (int i = (int)(sprites.Size() - 1); i >= 0; i--)
|
||||
{
|
||||
if (spritelist[i])
|
||||
if (spritelist[i].CountUsed())
|
||||
{
|
||||
int j, k;
|
||||
for (j = 0; j < sprites[i].numframes; j++)
|
||||
|
@ -1091,21 +1122,21 @@ void FGLInterface::Precache(BYTE *texhitlist, TMap<PClassActor*, bool> &actorhit
|
|||
FTextureID pic = frame->Texture[k];
|
||||
if (pic.isValid())
|
||||
{
|
||||
texhitlist[pic.GetIndex()] = FTextureManager::HIT_Sprite;
|
||||
spritehitlist[pic.GetIndex()] = &spritelist[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete[] spritelist;
|
||||
|
||||
TexMan.precacheTime = I_FPSTime();
|
||||
|
||||
int cnt = TexMan.NumTextures();
|
||||
for (int i = cnt - 1; i >= 0; i--)
|
||||
{
|
||||
PrecacheTexture(TexMan.ByIndex(i), texhitlist[i]);
|
||||
if (spritehitlist[i] != nullptr) PrecacheSprite(TexMan.ByIndex(i), *spritehitlist[i]);
|
||||
}
|
||||
delete[] spritehitlist;
|
||||
delete[] spritelist;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -306,6 +306,29 @@ void FHardwareTexture::Clean(bool all)
|
|||
if (glDepthID != 0) glDeleteRenderbuffers(1, &glDepthID);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Deletes all allocated resources and considers translations
|
||||
// This will only be called for sprites
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FHardwareTexture::CleanUnused(SpriteHits &usedtranslations)
|
||||
{
|
||||
if (usedtranslations.CheckKey(0) != nullptr)
|
||||
{
|
||||
glDefTex.Delete();
|
||||
}
|
||||
for (int i = glTex_Translated.Size()-1; i>= 0; i--)
|
||||
{
|
||||
if (usedtranslations.CheckKey(glTex_Translated[i].translation) != nullptr)
|
||||
{
|
||||
glTex_Translated[i].Delete();
|
||||
glTex_Translated.Delete(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Destroys the texture
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
class FCanvasTexture;
|
||||
class AActor;
|
||||
typedef TMap<int, bool> SpriteHits;
|
||||
|
||||
// For error catching while changing parameters.
|
||||
enum EInvalid
|
||||
|
@ -79,6 +80,7 @@ public:
|
|||
unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation);
|
||||
|
||||
void Clean(bool all);
|
||||
void CleanUnused(SpriteHits &usedtranslations);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -91,6 +91,7 @@ FGLTexture::FGLTexture(FTexture * tx, bool expandpatches)
|
|||
bIsTransparent = -1;
|
||||
bExpandFlag = expandpatches;
|
||||
lastSampler = 254;
|
||||
lastTranslation = -1;
|
||||
tex->gl_info.SystemTexture[expandpatches] = this;
|
||||
}
|
||||
|
||||
|
@ -165,16 +166,28 @@ unsigned char *FGLTexture::LoadHiresTexture(FTexture *tex, int *width, int *heig
|
|||
|
||||
void FGLTexture::Clean(bool all)
|
||||
{
|
||||
if (mHwTexture)
|
||||
if (mHwTexture != nullptr)
|
||||
{
|
||||
if (!all) mHwTexture->Clean(false);
|
||||
else
|
||||
{
|
||||
delete mHwTexture;
|
||||
mHwTexture = NULL;
|
||||
mHwTexture = nullptr;
|
||||
}
|
||||
|
||||
lastSampler = 253;
|
||||
lastTranslation = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FGLTexture::CleanUnused(SpriteHits &usedtranslations)
|
||||
{
|
||||
if (mHwTexture != nullptr)
|
||||
{
|
||||
mHwTexture->CleanUnused(usedtranslations);
|
||||
lastSampler = 253;
|
||||
lastTranslation = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,8 +347,9 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla
|
|||
}
|
||||
if (!needmipmap) clampmode = CLAMP_XY_NOMIP;
|
||||
if (tex->bHasCanvas) static_cast<FCanvasTexture*>(tex)->NeedUpdate();
|
||||
if (lastSampler != clampmode)
|
||||
if (lastSampler != clampmode || lastTranslation != translation)
|
||||
lastSampler = GLRenderer->mSamplerManager->Bind(texunit, clampmode, lastSampler);
|
||||
lastTranslation = translation;
|
||||
return hwtex;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -710,6 +724,19 @@ void FMaterial::Precache()
|
|||
Bind(0, 0);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
void FMaterial::PrecacheList(SpriteHits &translations)
|
||||
{
|
||||
if (mBaseLayer != nullptr) mBaseLayer->CleanUnused(translations);
|
||||
SpriteHits::Iterator it(translations);
|
||||
SpriteHits::Pair *pair;
|
||||
while(it.NextPair(pair)) Bind(0, pair->Key);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Retrieve texture coordinate info for per-wall scaling
|
||||
|
|
|
@ -66,6 +66,7 @@ private:
|
|||
bool bHasColorkey; // only for hires
|
||||
bool bExpandFlag;
|
||||
BYTE lastSampler;
|
||||
int lastTranslation;
|
||||
|
||||
unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height);
|
||||
|
||||
|
@ -80,6 +81,7 @@ public:
|
|||
unsigned char * CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck, bool createexpanded = true, bool alphatrans = false);
|
||||
|
||||
void Clean(bool all);
|
||||
void CleanUnused(SpriteHits &usedtranslations);
|
||||
int Dump(int i);
|
||||
|
||||
};
|
||||
|
@ -127,6 +129,7 @@ public:
|
|||
FMaterial(FTexture *tex, bool forceexpand);
|
||||
~FMaterial();
|
||||
void Precache();
|
||||
void PrecacheList(SpriteHits &translations);
|
||||
bool isMasked() const
|
||||
{
|
||||
return !!mBaseLayer->tex->bMasked;
|
||||
|
|
|
@ -240,7 +240,6 @@ FTexture::MiscGLInfo::MiscGLInfo() throw()
|
|||
mIsTransparent = -1;
|
||||
shaderspeed = 1.f;
|
||||
shaderindex = 0;
|
||||
precacheTime = 0;
|
||||
|
||||
Material[1] = Material[0] = NULL;
|
||||
SystemTexture[1] = SystemTexture[0] = NULL;
|
||||
|
@ -310,46 +309,6 @@ void FTexture::CreateDefaultBrightmap()
|
|||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Precaches a GL texture
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FTexture::PrecacheGL(int cache)
|
||||
{
|
||||
if (gl_precache)
|
||||
{
|
||||
if (cache & (FTextureManager::HIT_Wall | FTextureManager::HIT_Flat | FTextureManager::HIT_Sky))
|
||||
{
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(this, false);
|
||||
if (gltex) gltex->Precache();
|
||||
}
|
||||
if (cache & FTextureManager::HIT_Sprite)
|
||||
{
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(this, true);
|
||||
if (gltex) gltex->Precache();
|
||||
}
|
||||
gl_info.precacheTime = TexMan.precacheTime;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Precaches a GL texture
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FTexture::UncacheGL()
|
||||
{
|
||||
if (gl_info.precacheTime != TexMan.precacheTime)
|
||||
{
|
||||
if (gl_info.Material[0]) gl_info.Material[0]->Clean(true);
|
||||
if (gl_info.Material[1]) gl_info.Material[1]->Clean(true);
|
||||
gl_info.precacheTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Calculates glow color for a texture
|
||||
|
|
|
@ -310,7 +310,6 @@ public:
|
|||
FloatRect *areas;
|
||||
int areacount;
|
||||
int shaderindex;
|
||||
unsigned int precacheTime;
|
||||
float shaderspeed;
|
||||
int mIsTransparent:2;
|
||||
bool bGlowing:1; // Texture glows
|
||||
|
@ -328,8 +327,6 @@ public:
|
|||
};
|
||||
MiscGLInfo gl_info;
|
||||
|
||||
virtual void PrecacheGL(int cache);
|
||||
virtual void UncacheGL();
|
||||
void GetGlowColor(float *data);
|
||||
PalEntry GetSkyCapColor(bool bottom);
|
||||
bool isGlowing() { return gl_info.bGlowing; }
|
||||
|
@ -458,8 +455,6 @@ public:
|
|||
FSwitchDef *FindSwitch (FTextureID texture);
|
||||
FDoorAnimation *FindAnimatedDoor (FTextureID picnum);
|
||||
|
||||
unsigned int precacheTime;
|
||||
|
||||
private:
|
||||
|
||||
// texture counting
|
||||
|
|
Loading…
Reference in a new issue