From 812cabb752d407e55ee8c48df98212147928626e Mon Sep 17 00:00:00 2001 From: rogerman Date: Thu, 3 Nov 2016 00:39:02 +0000 Subject: [PATCH] =?UTF-8?q?Texture=20Handler:=20-=20The=203D=20renderers?= =?UTF-8?q?=20are=20now=20responsible=20for=20managing=20the=20texture=20u?= =?UTF-8?q?npack=20buffers=20instead=20of=20relying=20on=20the=20TexCacheI?= =?UTF-8?q?tem=20itself=20to=20do=20it.=20-=20The=20OpenGL=203D=20renderer?= =?UTF-8?q?=20now=20uses=20a=20fixed=204MB=20buffer=20for=20unpacking=20te?= =?UTF-8?q?xtures,=20instead=20of=20maintaining=20extra=20copies=20of=20ea?= =?UTF-8?q?ch=20unpacked=20texture=20in=20main=20memory=20even=20after=20t?= =?UTF-8?q?hey=E2=80=99ve=20been=20uploaded=20to=20the=20GPU.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- desmume/src/OGLRender.cpp | 27 +++++++++----- desmume/src/OGLRender.h | 3 +- desmume/src/OGLRender_3_2.cpp | 11 +++--- desmume/src/rasterize.cpp | 28 +++++++++++++-- desmume/src/texcache.cpp | 67 +++++++++++++++-------------------- desmume/src/texcache.h | 12 +++---- 6 files changed, 87 insertions(+), 61 deletions(-) diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index 07fb03899..0f20a018b 100644 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -636,7 +636,7 @@ static void OGLGetDriverVersion(const char *oglVersionString, } } -void texDeleteCallback(TexCacheItem *texItem, void *param1, void *param2) +void OGLTextureDeleteCallback(TexCacheItem *texItem, void *param1, void *param2) { OpenGLRenderer *oglRenderer = (OpenGLRenderer *)param1; oglRenderer->DeleteTexture(texItem); @@ -872,6 +872,7 @@ OpenGLRenderer::OpenGLRenderer() ref->selectedRenderingFBO = 0; _mappedFramebuffer = NULL; + _workingTextureUnpackBuffer = (FragmentColor *)malloc_alignedCacheLine(1024 * 1024 * sizeof(FragmentColor)); _pixelReadNeedsFinish = false; _currentPolyIndex = 0; _shadowPolyID.reserve(POLYLIST_SIZE); @@ -880,6 +881,7 @@ OpenGLRenderer::OpenGLRenderer() OpenGLRenderer::~OpenGLRenderer() { free_aligned(_framebufferColor); + free_aligned(_workingTextureUnpackBuffer); // Destroy OpenGL rendering states delete ref; @@ -2417,6 +2419,7 @@ Render3DError OpenGLRenderer_1_2::ReadBackPixels() Render3DError OpenGLRenderer_1_2::DeleteTexture(const TexCacheItem *item) { this->ref->freeTextureIDs.push((GLuint)item->texid); + texCache.cache_size -= item->unpackSize; return OGLERROR_NOERR; } @@ -2970,13 +2973,11 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT if (theTexture->unpackFormat != TexFormat_32bpp) { - theTexture->Unpack(); - //has the ogl renderer initialized the texture? const bool isNewTexture = (theTexture->GetDeleteCallback() == NULL); if (isNewTexture) { - theTexture->SetDeleteCallback(&texDeleteCallback, this, NULL); + theTexture->SetDeleteCallback(&OGLTextureDeleteCallback, this, NULL); if (OGLRef.freeTextureIDs.empty()) { @@ -2985,14 +2986,19 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT theTexture->texid = (u32)OGLRef.freeTextureIDs.front(); OGLRef.freeTextureIDs.pop(); + + theTexture->unpackSize = theTexture->GetUnpackSizeUsingFormat(TexFormat_32bpp); + texCache.cache_size += theTexture->unpackSize; } + theTexture->Unpack((u32 *)this->_workingTextureUnpackBuffer); + glBindTexture(GL_TEXTURE_2D, (GLuint)theTexture->texid); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (params.enableRepeatS ? (params.enableMirroredRepeatS ? OGLRef.stateTexMirroredRepeat : GL_REPEAT) : GL_CLAMP_TO_EDGE)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (params.enableRepeatT ? (params.enableMirroredRepeatT ? OGLRef.stateTexMirroredRepeat : GL_REPEAT) : GL_CLAMP_TO_EDGE)); const NDSTextureFormat texFormat = theTexture->GetTextureFormat(); - const u32 *textureSrc = theTexture->unpackData; + const u32 *textureSrc = (u32 *)this->_workingTextureUnpackBuffer; size_t texWidth = theTexture->sizeX; size_t texHeight = theTexture->sizeY; @@ -4646,13 +4652,11 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT if (theTexture->unpackFormat != TexFormat_32bpp) { - theTexture->Unpack(); - //has the ogl renderer initialized the texture? const bool isNewTexture = (theTexture->GetDeleteCallback() == NULL); if (isNewTexture) { - theTexture->SetDeleteCallback(&texDeleteCallback, this, NULL); + theTexture->SetDeleteCallback(&OGLTextureDeleteCallback, this, NULL); if (OGLRef.freeTextureIDs.empty()) { @@ -4661,14 +4665,19 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT theTexture->texid = (u32)OGLRef.freeTextureIDs.front(); OGLRef.freeTextureIDs.pop(); + + theTexture->unpackSize = theTexture->GetUnpackSizeUsingFormat(TexFormat_32bpp); + texCache.cache_size += theTexture->unpackSize; } + theTexture->Unpack((u32 *)this->_workingTextureUnpackBuffer); + glBindTexture(GL_TEXTURE_2D, (GLuint)theTexture->texid); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (params.enableRepeatS ? (params.enableMirroredRepeatS ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (params.enableRepeatT ? (params.enableMirroredRepeatT ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE)); const NDSTextureFormat texFormat = theTexture->GetTextureFormat(); - const u32 *textureSrc = theTexture->unpackData; + const u32 *textureSrc = (u32 *)this->_workingTextureUnpackBuffer; size_t texWidth = theTexture->sizeX; size_t texHeight = theTexture->sizeY; diff --git a/desmume/src/OGLRender.h b/desmume/src/OGLRender.h index 9ede77cfc..464ec100a 100644 --- a/desmume/src/OGLRender.h +++ b/desmume/src/OGLRender.h @@ -526,7 +526,7 @@ extern CACHE_ALIGN const GLfloat divide6bitBy63_LUT[64]; extern const GLfloat PostprocessVtxBuffer[16]; extern const GLubyte PostprocessElementBuffer[6]; -extern void texDeleteCallback(TexCacheItem *texItem, void *param1, void *param2); +extern void OGLTextureDeleteCallback(TexCacheItem *texItem, void *param1, void *param2); //This is called by OGLRender whenever it initializes. //Platforms, please be sure to set this up. @@ -589,6 +589,7 @@ protected: bool willConvertFramebufferOnGPU; FragmentColor *_mappedFramebuffer; + FragmentColor *_workingTextureUnpackBuffer; bool _pixelReadNeedsFinish; size_t _currentPolyIndex; std::vector _shadowPolyID; diff --git a/desmume/src/OGLRender_3_2.cpp b/desmume/src/OGLRender_3_2.cpp index 84acb6a13..2ef6b2a8a 100644 --- a/desmume/src/OGLRender_3_2.cpp +++ b/desmume/src/OGLRender_3_2.cpp @@ -1698,13 +1698,11 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT TexCacheItem *theTexture = texCache.GetTexture(thePoly.texParam, thePoly.texPalette); if (theTexture->unpackFormat != TexFormat_32bpp) { - theTexture->Unpack(); - //has the ogl renderer initialized the texture? const bool isNewTexture = (theTexture->GetDeleteCallback() == NULL); if (isNewTexture) { - theTexture->SetDeleteCallback(&texDeleteCallback, this, NULL); + theTexture->SetDeleteCallback(&OGLTextureDeleteCallback, this, NULL); if (OGLRef.freeTextureIDs.empty()) { @@ -1713,14 +1711,19 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT theTexture->texid = (u32)OGLRef.freeTextureIDs.front(); OGLRef.freeTextureIDs.pop(); + + theTexture->unpackSize = theTexture->GetUnpackSizeUsingFormat(TexFormat_32bpp); + texCache.cache_size += theTexture->unpackSize; } + theTexture->Unpack((u32 *)this->_workingTextureUnpackBuffer); + glBindTexture(GL_TEXTURE_2D, (GLuint)theTexture->texid); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (params.enableRepeatS ? (params.enableMirroredRepeatS ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (params.enableRepeatT ? (params.enableMirroredRepeatT ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE)); const NDSTextureFormat texFormat = theTexture->GetTextureFormat(); - const u32 *textureSrc = theTexture->unpackData; + const u32 *textureSrc = (u32 *)this->_workingTextureUnpackBuffer; size_t texWidth = theTexture->sizeX; size_t texHeight = theTexture->sizeY; diff --git a/desmume/src/rasterize.cpp b/desmume/src/rasterize.cpp index bb9850f6f..9e33f8490 100644 --- a/desmume/src/rasterize.cpp +++ b/desmume/src/rasterize.cpp @@ -1147,6 +1147,12 @@ static void SoftRasterizerRendererDestroy() } } +void SoftRasterizerTextureDeleteCallback(TexCacheItem *texItem, void *param1, void *param2) +{ + free_aligned(texItem->unpackData); + texCache.cache_size -= texItem->unpackSize; +} + GPU3DInterface gpu3DRasterize = { "SoftRasterizer", SoftRasterizerRendererCreate, @@ -1377,7 +1383,16 @@ void SoftRasterizerRenderer::setupTextures() TexCacheItem *lastTexItem = texCache.GetTexture(firstPoly.texParam, firstPoly.texPalette); if (lastTexItem->unpackFormat != TexFormat_15bpp) { - lastTexItem->Unpack(); + const bool isNewTexture = (lastTexItem->GetDeleteCallback() == NULL); + if (isNewTexture) + { + lastTexItem->SetDeleteCallback(&SoftRasterizerTextureDeleteCallback, this, NULL); + lastTexItem->unpackSize = lastTexItem->GetUnpackSizeUsingFormat(TexFormat_15bpp); + lastTexItem->unpackData = (u32 *)malloc_alignedCacheLine(lastTexItem->unpackSize); + texCache.cache_size += lastTexItem->unpackSize; + } + + lastTexItem->Unpack(lastTexItem->unpackData); } for (size_t i = 0; i < this->_clippedPolyCount; i++) @@ -1394,7 +1409,16 @@ void SoftRasterizerRenderer::setupTextures() lastTexItem = texCache.GetTexture(thePoly.texParam, thePoly.texPalette); if (lastTexItem->unpackFormat != TexFormat_15bpp) { - lastTexItem->Unpack(); + const bool isNewTexture = (lastTexItem->GetDeleteCallback() == NULL); + if (isNewTexture) + { + lastTexItem->SetDeleteCallback(&SoftRasterizerTextureDeleteCallback, this, NULL); + lastTexItem->unpackSize = lastTexItem->GetUnpackSizeUsingFormat(TexFormat_15bpp); + lastTexItem->unpackData = (u32 *)malloc_alignedCacheLine(lastTexItem->unpackSize); + texCache.cache_size += lastTexItem->unpackSize; + } + + lastTexItem->Unpack(lastTexItem->unpackData); } lastTexParams = thePoly.texParam; diff --git a/desmume/src/texcache.cpp b/desmume/src/texcache.cpp index 28403dbb9..a8fe7cad0 100644 --- a/desmume/src/texcache.cpp +++ b/desmume/src/texcache.cpp @@ -204,20 +204,6 @@ TexCache::TexCache() memset(paletteDump, 0, sizeof(paletteDump)); } -void TexCache::list_remove(TexCacheItem *item) -{ - const TexCacheKey key = TexCache::GenerateKey(item->textureAttributes, item->paletteAttributes); - this->cacheTable.erase(key); - this->cache_size -= item->unpackSize; -} - -void TexCache::list_push_front(TexCacheItem *item) -{ - const TexCacheKey key = TexCache::GenerateKey(item->textureAttributes, item->paletteAttributes); - this->cacheTable[key] = item; - this->cache_size += item->unpackSize; -} - void TexCache::Invalidate() { //check whether the palette memory changed @@ -244,7 +230,7 @@ void TexCache::Invalidate() } } -void TexCache::Evict(u32 target) +void TexCache::Evict(size_t target) { //debug print //printf("%d %d/%d\n",index.size(),cache_size/1024,target/1024); @@ -262,7 +248,9 @@ void TexCache::Evict(u32 target) if (this->cacheTable.size() == 0) break; //just in case.. doesnt seem possible, cache_size wouldve been 0 TexCacheItem *item = this->cacheTable.begin()->second; - this->list_remove(item); + const TexCacheKey key = TexCache::GenerateKey(item->textureAttributes, item->paletteAttributes); + this->cacheTable.erase(key); + //printf("evicting! totalsize:%d\n",cache_size); delete item; } @@ -270,7 +258,15 @@ void TexCache::Evict(u32 target) void TexCache::Reset() { - this->Evict(0); + for (TexCacheTable::iterator it(this->cacheTable.begin()); it != this->cacheTable.end(); ++it) + { + TexCacheItem *item = it->second; + delete item; + } + + this->cacheTable.clear(); + this->cache_size = 0; + memset(this->paletteDump, 0, sizeof(paletteDump)); } TexCacheItem* TexCache::GetTexture(u32 texAttributes, u32 palAttributes) @@ -378,7 +374,7 @@ TexCacheItem* TexCache::GetTexture(u32 texAttributes, u32 palAttributes) if (didCreateNewTexture) { - this->list_push_front(theTexture); + this->cacheTable[key] = theTexture; //printf("allocating: up to %d with %d items\n",cache_size,index.size()); } @@ -501,7 +497,6 @@ TexCacheItem::TexCacheItem(const u32 texAttributes, const u32 palAttributes) TexCacheItem::~TexCacheItem() { free_aligned(this->packData); - free_aligned(this->unpackData); free_aligned(this->paletteColorTable); free_aligned(this->packIndexData); if (this->_deleteCallback != NULL) this->_deleteCallback(this, this->_deleteCallbackParam1, this->_deleteCallbackParam2); @@ -535,15 +530,6 @@ void TexCacheItem::SetTextureData(const MemSpan &packedData, const MemSpan &pack { packedIndexData.dump(this->packIndexData, this->packIndexSize); } - - const u32 currentUnpackSize = this->sizeX * this->sizeY * sizeof(u32); - if (this->unpackSize != currentUnpackSize) - { - u32 *oldUnpackData = this->unpackData; - this->unpackSize = currentUnpackSize; - this->unpackData = (u32 *)malloc_alignedCacheLine(currentUnpackSize); - free_aligned(oldUnpackData); - } } void TexCacheItem::SetTexturePalette(const u16 *paletteBuffer) @@ -554,8 +540,13 @@ void TexCacheItem::SetTexturePalette(const u16 *paletteBuffer) } } +size_t TexCacheItem::GetUnpackSizeUsingFormat(const TexCache_TexFormat texCacheFormat) const +{ + return (this->sizeX * this->sizeY * sizeof(u32)); +} + template -void TexCacheItem::Unpack() +void TexCacheItem::Unpack(u32 *unpackBuffer) { this->unpackFormat = TEXCACHEFORMAT; @@ -566,19 +557,19 @@ void TexCacheItem::Unpack() switch (this->packFormat) { case TEXMODE_A3I5: - NDSTextureUnpackA3I5(this->packSize, this->packData, this->paletteColorTable, this->unpackData); + NDSTextureUnpackA3I5(this->packSize, this->packData, this->paletteColorTable, unpackBuffer); break; case TEXMODE_I2: - NDSTextureUnpackI2(this->packSize, this->packData, this->paletteColorTable, this->isPalZeroTransparent, this->unpackData); + NDSTextureUnpackI2(this->packSize, this->packData, this->paletteColorTable, this->isPalZeroTransparent, unpackBuffer); break; case TEXMODE_I4: - NDSTextureUnpackI4(this->packSize, this->packData, this->paletteColorTable, this->isPalZeroTransparent, this->unpackData); + NDSTextureUnpackI4(this->packSize, this->packData, this->paletteColorTable, this->isPalZeroTransparent, unpackBuffer); break; case TEXMODE_I8: - NDSTextureUnpackI8(this->packSize, this->packData, this->paletteColorTable, this->isPalZeroTransparent, this->unpackData); + NDSTextureUnpackI8(this->packSize, this->packData, this->paletteColorTable, this->isPalZeroTransparent, unpackBuffer); break; case TEXMODE_4X4: @@ -588,16 +579,16 @@ void TexCacheItem::Unpack() PROGINFO("Your 4x4 texture has overrun its texture slot.\n"); } - NDSTextureUnpack4x4(this->packSizeFirstSlot, (u32 *)this->packData, (u16 *)this->packIndexData, this->paletteAddress, this->textureAttributes, this->sizeX, this->sizeY, this->unpackData); + NDSTextureUnpack4x4(this->packSizeFirstSlot, (u32 *)this->packData, (u16 *)this->packIndexData, this->paletteAddress, this->textureAttributes, this->sizeX, this->sizeY, unpackBuffer); break; } case TEXMODE_A5I3: - NDSTextureUnpackA5I3(this->packSize, this->packData, this->paletteColorTable, this->unpackData); + NDSTextureUnpackA5I3(this->packSize, this->packData, this->paletteColorTable, unpackBuffer); break; case TEXMODE_16BPP: - NDSTextureUnpackDirect16Bit(this->packSize, (u16 *)this->packData, this->unpackData); + NDSTextureUnpackDirect16Bit(this->packSize, (u16 *)this->packData, unpackBuffer); break; default: @@ -1122,5 +1113,5 @@ void NDSTextureUnpackDirect16Bit(const size_t srcSize, const u16 *__restrict src } } -template void TexCacheItem::Unpack(); -template void TexCacheItem::Unpack(); +template void TexCacheItem::Unpack(u32 *unpackBuffer); +template void TexCacheItem::Unpack(u32 *unpackBuffer); diff --git a/desmume/src/texcache.h b/desmume/src/texcache.h index 5161760a7..7d8bb5eae 100644 --- a/desmume/src/texcache.h +++ b/desmume/src/texcache.h @@ -59,14 +59,11 @@ public: TexCache(); TexCacheTable cacheTable; - u32 cache_size; //this is not really precise, it is off by a constant factor + size_t cache_size; //this is not really precise, it is off by a constant factor u8 paletteDump[PALETTE_DUMP_SIZE]; - - void list_remove(TexCacheItem *item); - void list_push_front(TexCacheItem *item); - + void Invalidate(); - void Evict(u32 target); + void Evict(size_t target); void Reset(); TexCacheItem* GetTexture(u32 texAttributes, u32 palAttributes); @@ -127,7 +124,8 @@ public: void SetTextureData(const MemSpan &packedData, const MemSpan &packedIndexData); void SetTexturePalette(const u16 *paletteBuffer); - template void Unpack(); + size_t GetUnpackSizeUsingFormat(const TexCache_TexFormat texCacheFormat) const; + template void Unpack(u32 *unpackBuffer); void DebugDump(); };