- fixed texture layer management so that each material layer can decide for itself if it wants to allow upscaling.
- rewrote the hardware texture precacher to use the new texture management to properly track the data to delete.
This commit is contained in:
parent
cedc95c2a5
commit
b2281c38e1
20 changed files with 190 additions and 135 deletions
|
|
@ -50,7 +50,10 @@ static void PrecacheTexture(FGameTexture *tex, int cache)
|
|||
{
|
||||
if (cache & (FTextureManager::HIT_Wall | FTextureManager::HIT_Flat | FTextureManager::HIT_Sky))
|
||||
{
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(tex, false);
|
||||
int scaleflags = 0;
|
||||
if (shouldUpscale(tex, UF_Texture)) scaleflags |= CTF_Upscale;
|
||||
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(tex, scaleflags);
|
||||
if (gltex) screen->PrecacheMaterial(gltex, 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -62,7 +65,6 @@ static void PrecacheTexture(FGameTexture *tex, int cache)
|
|||
//===========================================================================
|
||||
static void PrecacheList(FMaterial *gltex, SpriteHits& translations)
|
||||
{
|
||||
//gltex->BaseLayer()->SystemTextures.CleanUnused(translations, gltex->GetScaleFlags()); this needs to be redone.
|
||||
SpriteHits::Iterator it(translations);
|
||||
SpriteHits::Pair* pair;
|
||||
while (it.NextPair(pair)) screen->PrecacheMaterial(gltex, pair->Key);
|
||||
|
|
@ -76,7 +78,10 @@ static void PrecacheList(FMaterial *gltex, SpriteHits& translations)
|
|||
|
||||
static void PrecacheSprite(FGameTexture *tex, SpriteHits &hits)
|
||||
{
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(tex, true);
|
||||
int scaleflags = CTF_Expand;
|
||||
if (shouldUpscale(tex, UF_Sprite)) scaleflags |= CTF_Upscale;
|
||||
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(tex, scaleflags);
|
||||
if (gltex) PrecacheList(gltex, hits);
|
||||
}
|
||||
|
||||
|
|
@ -88,26 +93,36 @@ static void PrecacheSprite(FGameTexture *tex, SpriteHits &hits)
|
|||
|
||||
void hw_PrecacheTexture(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitlist)
|
||||
{
|
||||
SpriteHits *spritelist = new SpriteHits[sprites.Size()];
|
||||
SpriteHits **spritehitlist = new SpriteHits*[TexMan.NumTextures()];
|
||||
TMap<PClassActor*, bool>::Iterator it(actorhitlist);
|
||||
TMap<PClassActor*, bool>::Pair *pair;
|
||||
uint8_t *modellist = new uint8_t[Models.Size()];
|
||||
memset(modellist, 0, Models.Size());
|
||||
memset(spritehitlist, 0, sizeof(SpriteHits**) * TexMan.NumTextures());
|
||||
TMap<FTexture*, bool> allTextures;
|
||||
TArray<FTexture*> layers;
|
||||
|
||||
// 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
|
||||
for (int i = 0; i<TexMan.NumTextures(); i++)
|
||||
// First collect the potential max. texture set
|
||||
for (unsigned i = 1; i < TexMan.NumTextures(); i++)
|
||||
{
|
||||
// HIT_Wall must be checked for MBF-style sky transfers.
|
||||
auto gametex = TexMan.GameByIndex(i);
|
||||
if (gametex &&
|
||||
gametex->GetTexture()->GetImage() && // only image textures are subject to precaching
|
||||
gametex->GetUseType() != ETextureType::FontChar && // We do not want to delete font characters here as they are very likely to be needed constantly.
|
||||
gametex->GetUseType() < ETextureType::Special) // Any texture marked as 'special' is also out.
|
||||
{
|
||||
gametex->GetLayers(layers);
|
||||
for (auto layer : layers)
|
||||
{
|
||||
allTextures.Insert(layer, true);
|
||||
layer->CleanPrecacheMarker();
|
||||
}
|
||||
}
|
||||
|
||||
// Mark the faces of a skybox as used.
|
||||
// This isn't done by the main code so it needs to be done here.
|
||||
// MBF sky transfers are being checked by the calling code to add HIT_Sky for them.
|
||||
if (texhitlist[i] & (FTextureManager::HIT_Sky))
|
||||
{
|
||||
auto tex = TexMan.GameByIndex(i);
|
||||
auto sb = dynamic_cast<FSkyBox*>(tex->GetTexture());
|
||||
if (sb)
|
||||
{
|
||||
for (int i = 0; i<6; i++)
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (sb->faces[i])
|
||||
{
|
||||
|
|
@ -119,6 +134,14 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitl
|
|||
}
|
||||
}
|
||||
|
||||
SpriteHits *spritelist = new SpriteHits[sprites.Size()];
|
||||
SpriteHits **spritehitlist = new SpriteHits*[TexMan.NumTextures()];
|
||||
TMap<PClassActor*, bool>::Iterator it(actorhitlist);
|
||||
TMap<PClassActor*, bool>::Pair *pair;
|
||||
uint8_t *modellist = new uint8_t[Models.Size()];
|
||||
memset(modellist, 0, Models.Size());
|
||||
memset(spritehitlist, 0, sizeof(SpriteHits**) * TexMan.NumTextures());
|
||||
|
||||
// Check all used actors.
|
||||
// 1. mark all sprites associated with its states
|
||||
// 2. mark all model data and skins associated with its states
|
||||
|
|
@ -190,7 +213,7 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitl
|
|||
screen->StartPrecaching();
|
||||
int cnt = TexMan.NumTextures();
|
||||
|
||||
// prepare the textures for precaching. First collect all used layer textures so that we know which ones should not be deleted.
|
||||
// prepare the textures for precaching. First mark all used layer textures so that we know which ones should not be deleted.
|
||||
for (int i = cnt - 1; i >= 0; i--)
|
||||
{
|
||||
auto tex = TexMan.GameByIndex(i);
|
||||
|
|
@ -198,44 +221,46 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitl
|
|||
{
|
||||
if (texhitlist[i] & (FTextureManager::HIT_Wall | FTextureManager::HIT_Flat | FTextureManager::HIT_Sky))
|
||||
{
|
||||
FMaterial* mat = FMaterial::ValidateTexture(tex, false, false);
|
||||
int scaleflags = 0;
|
||||
if (shouldUpscale(tex, UF_Texture)) scaleflags |= CTF_Upscale;
|
||||
|
||||
FMaterial* mat = FMaterial::ValidateTexture(tex, scaleflags, true);
|
||||
if (mat != nullptr)
|
||||
{
|
||||
for (auto ftex : mat->GetLayerArray())
|
||||
for (auto &layer : mat->GetLayerArray())
|
||||
{
|
||||
usedTextures.Insert(ftex, true);
|
||||
if (layer.layerTexture) layer.layerTexture->MarkForPrecache(0, layer.scaleFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (spritehitlist[i] != nullptr && (*spritehitlist[i]).CountUsed() > 0)
|
||||
{
|
||||
FMaterial *mat = FMaterial::ValidateTexture(tex, true, false);
|
||||
int scaleflags = CTF_Expand;
|
||||
if (shouldUpscale(tex, UF_Sprite)) scaleflags |= CTF_Upscale;
|
||||
|
||||
FMaterial *mat = FMaterial::ValidateTexture(tex, true, true);
|
||||
if (mat != nullptr)
|
||||
{
|
||||
for (auto ftex : mat->GetLayerArray())
|
||||
SpriteHits::Iterator it(*spritehitlist[i]);
|
||||
SpriteHits::Pair* pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
usedSprites.Insert(ftex, true);
|
||||
for (auto& layer : mat->GetLayerArray())
|
||||
{
|
||||
if (layer.layerTexture) layer.layerTexture->MarkForPrecache(pair->Key, layer.scaleFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// delete unused textures (i.e. those which didn't get referenced by any material in the cache list.
|
||||
for (int i = cnt - 1; i >= 0; i--)
|
||||
// delete unused hardware textures (i.e. those which didn't get referenced by any material in the cache list.)
|
||||
decltype(allTextures)::Iterator ita(allTextures);
|
||||
decltype(allTextures)::Pair* paira;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
auto tex = TexMan.GameByIndex(i);
|
||||
if (tex != nullptr && tex->GetUseType() != ETextureType::FontChar)
|
||||
{
|
||||
// This is rather counterproductive in a system that can share hardware textures between game textures.
|
||||
// The precacher needs to be redone to account for that. For now, just skip the deletion, for any normal sized map this won't be a problem.
|
||||
#if 0
|
||||
if (usedTextures.CheckKey(tex->GetTexture()) == nullptr && usedSprites.CheckKey(tex->GetTexture()) == nullptr)
|
||||
{
|
||||
tex->CleanHardwareData();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
paira->Key->CleanUnused();
|
||||
}
|
||||
|
||||
if (gl_precache)
|
||||
|
|
@ -246,7 +271,7 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitl
|
|||
|
||||
FImageSource::BeginPrecaching();
|
||||
|
||||
// cache all used textures
|
||||
// cache all used images
|
||||
for (int i = cnt - 1; i >= 0; i--)
|
||||
{
|
||||
auto gtex = TexMan.GameByIndex(i);
|
||||
|
|
@ -262,7 +287,7 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitl
|
|||
}
|
||||
}
|
||||
|
||||
// Only register untranslated sprites. Translated ones are very unlikely to require data that can be reused.
|
||||
// Only register untranslated sprite images. Translated ones are very unlikely to require data that can be reused so they can just be created on demand.
|
||||
if (spritehitlist[i] != nullptr && (*spritehitlist[i]).CheckKey(0))
|
||||
{
|
||||
FImageSource::RegisterForPrecache(tex->GetImage(), V_IsTrueColor());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue