Texture Handler:
- The 3D renderers are now responsible for managing the texture unpack buffers instead of relying on the TexCacheItem itself to do it. - The OpenGL 3D renderer now uses a fixed 4MB buffer for unpacking textures, instead of maintaining extra copies of each unpacked texture in main memory even after they’ve been uploaded to the GPU.
This commit is contained in:
parent
158f0c561b
commit
812cabb752
|
@ -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<TexFormat_32bpp>();
|
||||
|
||||
//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<TexFormat_32bpp>((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<TexFormat_32bpp>();
|
||||
|
||||
//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<TexFormat_32bpp>((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;
|
||||
|
||||
|
|
|
@ -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<u8> _shadowPolyID;
|
||||
|
|
|
@ -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<TexFormat_32bpp>();
|
||||
|
||||
//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<TexFormat_32bpp>((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;
|
||||
|
||||
|
|
|
@ -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<TexFormat_15bpp>();
|
||||
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<TexFormat_15bpp>(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<TexFormat_15bpp>();
|
||||
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<TexFormat_15bpp>(lastTexItem->unpackData);
|
||||
}
|
||||
|
||||
lastTexParams = thePoly.texParam;
|
||||
|
|
|
@ -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 <TexCache_TexFormat TEXCACHEFORMAT>
|
||||
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<TEXCACHEFORMAT>(this->packSize, this->packData, this->paletteColorTable, this->unpackData);
|
||||
NDSTextureUnpackA3I5<TEXCACHEFORMAT>(this->packSize, this->packData, this->paletteColorTable, unpackBuffer);
|
||||
break;
|
||||
|
||||
case TEXMODE_I2:
|
||||
NDSTextureUnpackI2<TEXCACHEFORMAT>(this->packSize, this->packData, this->paletteColorTable, this->isPalZeroTransparent, this->unpackData);
|
||||
NDSTextureUnpackI2<TEXCACHEFORMAT>(this->packSize, this->packData, this->paletteColorTable, this->isPalZeroTransparent, unpackBuffer);
|
||||
break;
|
||||
|
||||
case TEXMODE_I4:
|
||||
NDSTextureUnpackI4<TEXCACHEFORMAT>(this->packSize, this->packData, this->paletteColorTable, this->isPalZeroTransparent, this->unpackData);
|
||||
NDSTextureUnpackI4<TEXCACHEFORMAT>(this->packSize, this->packData, this->paletteColorTable, this->isPalZeroTransparent, unpackBuffer);
|
||||
break;
|
||||
|
||||
case TEXMODE_I8:
|
||||
NDSTextureUnpackI8<TEXCACHEFORMAT>(this->packSize, this->packData, this->paletteColorTable, this->isPalZeroTransparent, this->unpackData);
|
||||
NDSTextureUnpackI8<TEXCACHEFORMAT>(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<TEXCACHEFORMAT>(this->packSizeFirstSlot, (u32 *)this->packData, (u16 *)this->packIndexData, this->paletteAddress, this->textureAttributes, this->sizeX, this->sizeY, this->unpackData);
|
||||
NDSTextureUnpack4x4<TEXCACHEFORMAT>(this->packSizeFirstSlot, (u32 *)this->packData, (u16 *)this->packIndexData, this->paletteAddress, this->textureAttributes, this->sizeX, this->sizeY, unpackBuffer);
|
||||
break;
|
||||
}
|
||||
|
||||
case TEXMODE_A5I3:
|
||||
NDSTextureUnpackA5I3<TEXCACHEFORMAT>(this->packSize, this->packData, this->paletteColorTable, this->unpackData);
|
||||
NDSTextureUnpackA5I3<TEXCACHEFORMAT>(this->packSize, this->packData, this->paletteColorTable, unpackBuffer);
|
||||
break;
|
||||
|
||||
case TEXMODE_16BPP:
|
||||
NDSTextureUnpackDirect16Bit<TEXCACHEFORMAT>(this->packSize, (u16 *)this->packData, this->unpackData);
|
||||
NDSTextureUnpackDirect16Bit<TEXCACHEFORMAT>(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<TexFormat_15bpp>();
|
||||
template void TexCacheItem::Unpack<TexFormat_32bpp>();
|
||||
template void TexCacheItem::Unpack<TexFormat_15bpp>(u32 *unpackBuffer);
|
||||
template void TexCacheItem::Unpack<TexFormat_32bpp>(u32 *unpackBuffer);
|
||||
|
|
|
@ -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<TexCache_TexFormat TEXCACHEFORMAT> void Unpack();
|
||||
size_t GetUnpackSizeUsingFormat(const TexCache_TexFormat texCacheFormat) const;
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void Unpack(u32 *unpackBuffer);
|
||||
|
||||
void DebugDump();
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue