- continued work on texture management.

This commit is contained in:
Christoph Oelckers 2018-12-12 18:39:38 +01:00
parent fb6ee5046c
commit c5447f0cdd
18 changed files with 79 additions and 140 deletions

View file

@ -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)

View file

@ -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)
{

View file

@ -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;
}

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -91,7 +91,6 @@ public:
unsigned int GetTextureHandle(int translation);
void Clean(bool all);
void CleanUnused(SpriteHits &usedtranslations);
};
}

View file

@ -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);
};

View file

@ -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);
}

View file

@ -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);
};

View file

@ -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());
}

View file

@ -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);
}

View file

@ -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)

View file

@ -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);

View file

@ -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);
}
//===========================================================================

View file

@ -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

View file

@ -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:

View file

@ -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) {}