From c5447f0cddab41462c4d8be23803970ea09666cc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers <coelckers@users.noreply.github.com> Date: Wed, 12 Dec 2018 18:39:38 +0100 Subject: [PATCH] - continued work on texture management. --- src/f_wipe.cpp | 5 +- src/gl/renderer/gl_renderer.cpp | 4 +- src/gl/renderer/gl_renderstate.cpp | 4 +- src/gl/system/gl_framebuffer.cpp | 11 +--- src/gl/system/gl_framebuffer.h | 1 - src/gl/textures/gl_hwtexture.cpp | 23 ------- src/gl/textures/gl_hwtexture.h | 1 - src/hwrenderer/textures/hw_ihwtexture.h | 1 - src/hwrenderer/textures/hw_material.cpp | 78 +++++++---------------- src/hwrenderer/textures/hw_material.h | 22 +------ src/hwrenderer/textures/hw_precache.cpp | 9 +-- src/hwrenderer/textures/hw_texcontainer.h | 15 +++-- src/hwrenderer/utility/hw_cvars.cpp | 4 +- src/textures/hires/hqresize.cpp | 8 +-- src/textures/texture.cpp | 4 +- src/textures/texturemanager.cpp | 25 ++++++++ src/textures/textures.h | 3 + src/v_video.h | 1 - 18 files changed, 79 insertions(+), 140 deletions(-) diff --git a/src/f_wipe.cpp b/src/f_wipe.cpp index cb5544b685..80e5761007 100644 --- a/src/f_wipe.cpp +++ b/src/f_wipe.cpp @@ -372,9 +372,8 @@ bool Wiper_Burn::Run(int ticks) Density = wipe_CalcBurn(BurnArray, WIDTH, HEIGHT, Density); done = (Density < 0); } - - auto mat = FMaterial::ValidateTexture(BurnTexture, false); - mat->Clean(true); + + BurnTexture->SystemTextures.Clean(true, true); const uint8_t *src = BurnArray; uint32_t *dest = (uint32_t *)BurnTexture->GetBuffer(); for (int y = HEIGHT; y != 0; --y) diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 79ae7655f7..44422ad2d0 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -117,7 +117,7 @@ FGLRenderer::~FGLRenderer() { FlushModels(); AActor::DeleteAllAttachedLights(); - FMaterial::FlushAll(); + TexMan.FlushAll(); if (mShaderManager != nullptr) delete mShaderManager; if (mSamplerManager != nullptr) delete mSamplerManager; if (mFBID != 0) glDeleteFramebuffers(1, &mFBID); @@ -288,7 +288,7 @@ sector_t *FGLRenderer::RenderView(player_t* player) void FGLRenderer::BindToFrameBuffer(FMaterial *mat) { - auto BaseLayer = static_cast<FHardwareTexture*>(mat->GetLayer(0)); + auto BaseLayer = static_cast<FHardwareTexture*>(mat->GetLayer(0, 0)); if (BaseLayer == nullptr) { diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 30a2918998..0cc80d073c 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -332,14 +332,14 @@ void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translatio // Textures that are already scaled in the texture lump will not get replaced by hires textures. int flags = mat->isExpanded() ? CTF_Expand : (gl_texture_usehires && !tex->isScaled() && clampmode <= CLAMP_XY) ? CTF_CheckHires : 0; int numLayers = mat->GetLayers(); - auto base = static_cast<FHardwareTexture*>(mat->GetLayer(0)); + auto base = static_cast<FHardwareTexture*>(mat->GetLayer(0, translation)); if (base->BindOrCreate(tex, 0, clampmode, translation, flags)) { for (int i = 1; i<numLayers; i++) { FTexture *layer; - auto systex = static_cast<FHardwareTexture*>(mat->GetLayer(i, &layer)); + auto systex = static_cast<FHardwareTexture*>(mat->GetLayer(i, 0, &layer)); systex->BindOrCreate(layer, i, clampmode, 0, mat->isExpanded() ? CTF_Expand : 0); maxbound = i; } diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index fda8ae9df1..8573a21ddb 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -339,14 +339,14 @@ void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) // Textures that are already scaled in the texture lump will not get replaced by hires textures. int flags = mat->isExpanded() ? CTF_Expand : (gl_texture_usehires && !tex->isScaled()) ? CTF_CheckHires : 0; int numLayers = mat->GetLayers(); - auto base = static_cast<FHardwareTexture*>(mat->GetLayer(0)); + auto base = static_cast<FHardwareTexture*>(mat->GetLayer(0, translation)); if (base->BindOrCreate(tex, 0, CLAMP_NONE, translation, flags)) { for (int i = 1; i < numLayers; i++) { FTexture *layer; - auto systex = static_cast<FHardwareTexture*>(mat->GetLayer(i, &layer)); + auto systex = static_cast<FHardwareTexture*>(mat->GetLayer(i, 0, &layer)); systex->BindOrCreate(layer, i, CLAMP_NONE, 0, mat->isExpanded() ? CTF_Expand : 0); } } @@ -354,13 +354,6 @@ void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) FHardwareTexture::UnbindAll(); } -bool OpenGLFrameBuffer::CheckPrecacheMaterial(FMaterial *mat) -{ - if (!mat->tex->GetImage()) return true; - auto base = static_cast<FHardwareTexture*>(mat->GetLayer(0)); - return base->Exists(0); -} - FModelRenderer *OpenGLFrameBuffer::CreateModelRenderer(int mli) { return new FGLModelRenderer(nullptr, gl_RenderState, mli); diff --git a/src/gl/system/gl_framebuffer.h b/src/gl/system/gl_framebuffer.h index 5ebc586b0d..c77b3af670 100644 --- a/src/gl/system/gl_framebuffer.h +++ b/src/gl/system/gl_framebuffer.h @@ -35,7 +35,6 @@ public: void SetTextureFilterMode() override; IHardwareTexture *CreateHardwareTexture() override; void PrecacheMaterial(FMaterial *mat, int translation) override; - bool CheckPrecacheMaterial(FMaterial *mat) override; FModelRenderer *CreateModelRenderer(int mli) override; void TextureFilterChanged() override; void BeginFrame() override; diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 7f4093af87..b9034b101e 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -265,29 +265,6 @@ void FHardwareTexture::Clean(bool all) glDepthID = 0; } -//=========================================================================== -// -// 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 f864d073b4..46e9cfde4b 100644 --- a/src/gl/textures/gl_hwtexture.h +++ b/src/gl/textures/gl_hwtexture.h @@ -91,7 +91,6 @@ public: unsigned int GetTextureHandle(int translation); void Clean(bool all); - void CleanUnused(SpriteHits &usedtranslations); }; } diff --git a/src/hwrenderer/textures/hw_ihwtexture.h b/src/hwrenderer/textures/hw_ihwtexture.h index 10447e5b1e..07486e147f 100644 --- a/src/hwrenderer/textures/hw_ihwtexture.h +++ b/src/hwrenderer/textures/hw_ihwtexture.h @@ -26,7 +26,6 @@ public: virtual unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const char *name) = 0; virtual void Clean(bool all) = 0; - virtual void CleanUnused(SpriteHits &usedtranslations) = 0; void Resize(int swidth, int sheight, int width, int height, unsigned char *src_data, unsigned char *dst_data); }; diff --git a/src/hwrenderer/textures/hw_material.cpp b/src/hwrenderer/textures/hw_material.cpp index 9c0769b226..13cd9298e9 100644 --- a/src/hwrenderer/textures/hw_material.cpp +++ b/src/hwrenderer/textures/hw_material.cpp @@ -128,26 +128,6 @@ void IHardwareTexture::Resize(int swidth, int sheight, int width, int height, un } } -//=========================================================================== -// -// -// -//=========================================================================== -IHardwareTexture * FMaterial::ValidateSysTexture(FTexture * tex, int translation, bool expand) -{ - if (tex && tex->UseType!=ETextureType::Null) - { - IHardwareTexture *gltex = tex->SystemTextures.GetHardwareTexture(0, expand); - if (gltex == nullptr) - { - tex->SystemTextures.AddHardwareTexture(0, expand, screen->CreateHardwareTexture()); - gltex = tex->SystemTextures.GetHardwareTexture(0, expand); - } - return gltex; - } - return nullptr; -} - //=========================================================================== // // Constructor @@ -183,7 +163,6 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) { for (auto &texture : { tx->Normal, tx->Specular }) { - ValidateSysTexture(texture, 0, expanded); mTextureLayers.Push(texture); } mShaderIndex = SHADER_Specular; @@ -192,7 +171,6 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) { for (auto &texture : { tx->Normal, tx->Metallic, tx->Roughness, tx->AmbientOcclusion }) { - ValidateSysTexture(texture, 0, expanded); mTextureLayers.Push(texture); } mShaderIndex = SHADER_PBR; @@ -201,7 +179,6 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) tx->CreateDefaultBrightmap(); if (tx->Brightmap) { - ValidateSysTexture(tx->Brightmap, 0, expanded); mTextureLayers.Push(tx->Brightmap); if (mShaderIndex == SHADER_Specular) mShaderIndex = SHADER_SpecularBrightmap; @@ -219,16 +196,12 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) for (auto &texture : tx->CustomShaderTextures) { if (texture == nullptr) continue; - ValidateSysTexture(texture, 0, expanded); mTextureLayers.Push(texture); } mShaderIndex = tx->shaderindex; } } } - mBaseLayer = ValidateSysTexture(tx, 0, expanded); - - mWidth = tx->GetWidth(); mHeight = tx->GetHeight(); mLeftOffset = tx->GetLeftOffset(0); // These only get used by decals and decals should not use renderer-specific offsets. @@ -423,6 +396,27 @@ outl: return true; } +//=========================================================================== +// +// +// +//=========================================================================== + +IHardwareTexture *FMaterial::GetLayer(int i, int translation, FTexture **pLayer) +{ + FTexture *texture = i == 0 ? tex : mTextureLayers[i - 1]; + if (pLayer) *pLayer = tex; + + auto hwtex = tex->SystemTextures.GetHardwareTexture(translation, mExpanded); + if (hwtex == nullptr) + { + hwtex = screen->CreateHardwareTexture(); + // Fixme: This needs to create the texture here and not implicitly in BindOrCreate! + tex->SystemTextures.AddHardwareTexture(translation, mExpanded, hwtex); + } + return hwtex; +} + //=========================================================================== // // @@ -440,7 +434,7 @@ void FMaterial::Precache() //=========================================================================== void FMaterial::PrecacheList(SpriteHits &translations) { - if (mBaseLayer != nullptr) mBaseLayer->CleanUnused(translations); + tex->SystemTextures.CleanUnused(translations, mExpanded); SpriteHits::Iterator it(translations); SpriteHits::Pair *pair; while(it.NextPair(pair)) screen->PrecacheMaterial(this, pair->Key); @@ -510,31 +504,3 @@ FMaterial * FMaterial::ValidateTexture(FTextureID no, bool expand, bool translat { return ValidateTexture(TexMan.GetTexture(no, translate), expand, create); } - - -//========================================================================== -// -// Flushes all hardware dependent data. -// Thia must not, under any circumstances, delete the wipe textures, because -// all CCMDs triggering a flush can be executed while a wipe is in progress -// -//========================================================================== - -void FMaterial::FlushAll() -{ - for(int i=TexMan.NumTextures()-1;i>=0;i--) - { - for (int j = 0; j < 2; j++) - { - TexMan.ByIndex(i)->SystemTextures.Clean(true); - } - } - // This must also delete the software renderer's canvas. -} - -void FMaterial::Clean(bool f) -{ - // This somehow needs to deal with the other layers as well, but they probably need some form of reference counting to work properly... - mBaseLayer->Clean(f); -} - diff --git a/src/hwrenderer/textures/hw_material.h b/src/hwrenderer/textures/hw_material.h index b4d24d8a8f..33bf0f9d3f 100644 --- a/src/hwrenderer/textures/hw_material.h +++ b/src/hwrenderer/textures/hw_material.h @@ -39,7 +39,6 @@ class FMaterial static TArray<FMaterial *> mMaterials; static int mMaxBound; - IHardwareTexture *mBaseLayer; TArray<FTexture*> mTextureLayers; int mShaderIndex; @@ -68,7 +67,6 @@ public: void Precache(); void PrecacheList(SpriteHits &translations); int GetShaderIndex() const { return mShaderIndex; } - IHardwareTexture * ValidateSysTexture(FTexture * tex, int translation, bool expand); void AddTextureLayer(FTexture *tex) { ValidateTexture(tex, false); @@ -93,23 +91,7 @@ public: return tex->isHardwareCanvas(); } - IHardwareTexture *GetLayer(int i, FTexture **pLayer = nullptr) - { - if (i == 0) - { - if (pLayer) *pLayer = tex; - return mBaseLayer; - } - else - { - i--; - FTexture *layer = mTextureLayers[i]; - if (pLayer) *pLayer = layer; - return ValidateSysTexture(layer, 0, isExpanded()); - } - } - - void Clean(bool f); + IHardwareTexture *GetLayer(int i, int translation, FTexture **pLayer = nullptr); // Patch drawing utilities @@ -168,8 +150,6 @@ public: float GetSpriteVB() const { return mSpriteV[1]; } - static void DeleteAll(); - static void FlushAll(); static FMaterial *ValidateTexture(FTexture * tex, bool expand, bool create = true); static FMaterial *ValidateTexture(FTextureID no, bool expand, bool trans, bool create = true); }; diff --git a/src/hwrenderer/textures/hw_precache.cpp b/src/hwrenderer/textures/hw_precache.cpp index b927463a26..dc6829dd60 100644 --- a/src/hwrenderer/textures/hw_precache.cpp +++ b/src/hwrenderer/textures/hw_precache.cpp @@ -177,13 +177,11 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitl { if (!texhitlist[i]) { - auto mat = FMaterial::ValidateTexture(tex, false, false); - if (mat) mat->Clean(true); + tex->SystemTextures.Clean(true, false); } if (spritehitlist[i] == nullptr || (*spritehitlist[i]).CountUsed() == 0) { - auto mat = FMaterial::ValidateTexture(tex, true, false); - if (mat) mat->Clean(true); + tex->SystemTextures.Clean(false, true); } } } @@ -200,8 +198,7 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitl { if (texhitlist[i] & (FTextureManager::HIT_Wall | FTextureManager::HIT_Flat | FTextureManager::HIT_Sky)) { - FMaterial * gltex = FMaterial::ValidateTexture(tex, false); - if (gltex && !screen->CheckPrecacheMaterial(gltex)) + if (tex->GetImage() && tex->SystemTextures.GetHardwareTexture(0, false) == nullptr) { FImageSource::RegisterForPrecache(tex->GetImage()); } diff --git a/src/hwrenderer/textures/hw_texcontainer.h b/src/hwrenderer/textures/hw_texcontainer.h index 96cd8fa3c9..65f3561151 100644 --- a/src/hwrenderer/textures/hw_texcontainer.h +++ b/src/hwrenderer/textures/hw_texcontainer.h @@ -65,15 +65,15 @@ private: public: - void Clean(bool all) + void Clean(bool cleannormal, bool cleanexpanded) { - if (all) + if (cleannormal) hwDefTex[0].Delete(); + if (cleanexpanded) hwDefTex[1].Delete(); + for (int i = hwTex_Translated.Size() - 1; i >= 0; i--) { - hwDefTex[0].Delete(); - hwDefTex[1].Delete(); + if (cleannormal && hwTex_Translated[i].translation > 0) hwTex_Translated.Delete(i); + else if (cleanexpanded && hwTex_Translated[i].translation < 0) hwTex_Translated.Delete(i); } - hwTex_Translated.Clear(); - } IHardwareTexture * GetHardwareTexture(int translation, bool expanded) @@ -102,9 +102,10 @@ public: { hwDefTex[expanded].Delete(); } + int fac = expanded ? -1 : 1; for (int i = hwTex_Translated.Size()-1; i>= 0; i--) { - if (usedtranslations.CheckKey(hwTex_Translated[i].translation) == nullptr) + if (usedtranslations.CheckKey(hwTex_Translated[i].translation * fac) == nullptr) { hwTex_Translated.Delete(i); } diff --git a/src/hwrenderer/utility/hw_cvars.cpp b/src/hwrenderer/utility/hw_cvars.cpp index f0a0f8c834..1d11e24b19 100644 --- a/src/hwrenderer/utility/hw_cvars.cpp +++ b/src/hwrenderer/utility/hw_cvars.cpp @@ -92,7 +92,7 @@ CUSTOM_CVAR(Float,gl_texture_filter_anisotropic,8.0f,CVAR_ARCHIVE|CVAR_GLOBALCON CCMD(gl_flush) { - FMaterial::FlushAll(); + TexMan.FlushAll(); } CUSTOM_CVAR(Int, gl_texture_filter, 4, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL) @@ -103,7 +103,7 @@ CUSTOM_CVAR(Int, gl_texture_filter, 4, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINI CUSTOM_CVAR(Bool, gl_texture_usehires, true, CVAR_ARCHIVE|CVAR_NOINITCALL) { - FMaterial::FlushAll(); + TexMan.FlushAll(); } CVAR(Bool, gl_precache, false, CVAR_ARCHIVE) diff --git a/src/textures/hires/hqresize.cpp b/src/textures/hires/hqresize.cpp index cc8a65678b..e6acb49119 100644 --- a/src/textures/hires/hqresize.cpp +++ b/src/textures/hires/hqresize.cpp @@ -52,7 +52,7 @@ CUSTOM_CVAR(Int, gl_texture_hqresizemode, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | self = 0; if ((gl_texture_hqresizemult > 4) && (self < 4) && (self > 0)) gl_texture_hqresizemult = 4; - FMaterial::FlushAll(); + TexMan.FlushAll(); } CUSTOM_CVAR(Int, gl_texture_hqresizemult, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) @@ -61,18 +61,18 @@ CUSTOM_CVAR(Int, gl_texture_hqresizemult, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | self = 1; if ((self > 4) && (gl_texture_hqresizemode < 4) && (gl_texture_hqresizemode > 0)) self = 4; - FMaterial::FlushAll(); + TexMan.FlushAll(); } CUSTOM_CVAR(Int, gl_texture_hqresize_maxinputsize, 512, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { if (self > 1024) self = 1024; - FMaterial::FlushAll(); + TexMan.FlushAll(); } CUSTOM_CVAR(Int, gl_texture_hqresize_targets, 7, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { - FMaterial::FlushAll(); + TexMan.FlushAll(); } CVAR (Flag, gl_texture_hqresize_textures, gl_texture_hqresize_targets, 1); diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 7dfd004843..f8069393ed 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -790,7 +790,9 @@ FWrapperTexture::FWrapperTexture(int w, int h, int bits) Format = bits; UseType = ETextureType::SWCanvas; bNoCompress = true; - SystemTextures.AddHardwareTexture(0, false, screen->CreateHardwareTexture()); + auto hwtex = screen->CreateHardwareTexture(); + // todo: Initialize here. + SystemTextures.AddHardwareTexture(0, false, hwtex); } //=========================================================================== diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 558a6243c6..bb2fe50f2d 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -141,6 +141,31 @@ void FTextureManager::DeleteAll() BuildTileData.Clear(); } +//========================================================================== +// +// Flushes all hardware dependent data. +// Thia must not, under any circumstances, delete the wipe textures, because +// all CCMDs triggering a flush can be executed while a wipe is in progress +// +// This now also deletes the software textures because having the software +// renderer use the texture scalers is a planned feature and that is the +// main reason to call this outside of the destruction code. +// +//========================================================================== + +void FTextureManager::FlushAll() +{ + for (int i = TexMan.NumTextures() - 1; i >= 0; i--) + { + for (int j = 0; j < 2; j++) + { + TexMan.ByIndex(i)->SystemTextures.Clean(true, true); + delete TexMan.ByIndex(i)->SoftwareTexture; + } + } + // This must also delete the software renderer's canvas. +} + //========================================================================== // // FTextureManager :: CheckForTexture diff --git a/src/textures/textures.h b/src/textures/textures.h index 199ce0be88..90d12c0c2e 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -345,7 +345,9 @@ protected: FTextureID id; FMaterial *Material[2] = { nullptr, nullptr }; +public: FHardwareTextureContainer SystemTextures; +protected: //IHardwareTexture *SystemTexture[2] = { nullptr, nullptr }; FSoftwareTexture *SoftwareTexture = nullptr; @@ -540,6 +542,7 @@ public: } FTexture *FindTexture(const char *texname, ETextureType usetype = ETextureType::MiscPatch, BITFIELD flags = TEXMAN_TryAny); + void FlushAll(); //public: diff --git a/src/v_video.h b/src/v_video.h index bbbcb71f96..216fa2d313 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -425,7 +425,6 @@ public: virtual void CleanForRestart() {} virtual void SetTextureFilterMode() {} virtual IHardwareTexture *CreateHardwareTexture() { return nullptr; } - virtual bool CheckPrecacheMaterial(FMaterial *mat) { return true; } virtual void PrecacheMaterial(FMaterial *mat, int translation) {} virtual FModelRenderer *CreateModelRenderer(int mli) { return nullptr; } virtual void UnbindTexUnit(int no) {}