From ec037bfd1a6d1725fdfcf7fe9badfcffcac79a8e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 2 May 2016 19:47:27 +0200 Subject: [PATCH 1/2] - fixed: The check for one-way portals in the renderer was incomplete. --- src/gl/scene/gl_walls.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index e337f1873..ae7cb70c8 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -217,7 +217,7 @@ void GLWall::PutPortal(int ptype) if (!portal) { line_t *otherside = lineportal->lines[0]->mDestination; - if (otherside != NULL) + if (otherside != NULL && otherside->portalindex < linePortals.Size()) { gl_RenderActorsInPortal(linePortalToGL[otherside->portalindex]); } From 6f2b0a62939aa76acf0c671e070c966a82113f22 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 3 May 2016 01:00:52 +0200 Subject: [PATCH 2/2] - rewrote texture caching so that not the base texture but the actually used translations for sprites get precached. --- src/gl/scene/gl_scene.cpp | 61 ++++++++++++++++++++++++-------- src/gl/textures/gl_hwtexture.cpp | 23 ++++++++++++ src/gl/textures/gl_hwtexture.h | 2 ++ src/gl/textures/gl_material.cpp | 33 +++++++++++++++-- src/gl/textures/gl_material.h | 3 ++ src/gl/textures/gl_texture.cpp | 41 --------------------- src/textures/textures.h | 5 --- 7 files changed, 104 insertions(+), 64 deletions(-) diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index a658982bc..a87e522d3 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -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 &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 &actorhitlist) { - BYTE *spritelist = new BYTE[sprites.Size()]; + SpriteHits *spritelist = new SpriteHits[sprites.Size()]; + SpriteHits **spritehitlist = new SpriteHits*[TexMan.NumTextures()]; TMap::Iterator it(actorhitlist); TMap::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 &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 &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 &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; } diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 02ed64290..b964b030e 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -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 diff --git a/src/gl/textures/gl_hwtexture.h b/src/gl/textures/gl_hwtexture.h index 7fa0f0580..6b01fb437 100644 --- a/src/gl/textures/gl_hwtexture.h +++ b/src/gl/textures/gl_hwtexture.h @@ -13,6 +13,7 @@ class FCanvasTexture; class AActor; +typedef TMap 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 diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 74cdcd725..5207ea00d 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -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(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 diff --git a/src/gl/textures/gl_material.h b/src/gl/textures/gl_material.h index 79e5f52e2..dea0d4cf5 100644 --- a/src/gl/textures/gl_material.h +++ b/src/gl/textures/gl_material.h @@ -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; diff --git a/src/gl/textures/gl_texture.cpp b/src/gl/textures/gl_texture.cpp index 50671e4bd..f33fed6a3 100644 --- a/src/gl/textures/gl_texture.cpp +++ b/src/gl/textures/gl_texture.cpp @@ -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 diff --git a/src/textures/textures.h b/src/textures/textures.h index 91246c0fe..a3fd822fd 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -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