Texture Handler:
- Do some heavy cleanup and code refactoring. - Add SSE2-enabled unpacking function for direct 16-bit color textures.
This commit is contained in:
parent
318613e783
commit
95db2317b9
|
@ -1196,7 +1196,8 @@ OpenGLRenderer_1_2::~OpenGLRenderer_1_2()
|
|||
DestroyMultisampledFBO();
|
||||
|
||||
// Kill the texture cache now before all of our texture IDs disappear.
|
||||
TexCache_Reset();
|
||||
texCache.Reset();
|
||||
texCache.Reset();
|
||||
|
||||
while(!ref->freeTextureIDs.empty())
|
||||
{
|
||||
|
@ -2694,7 +2695,7 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry(const GFX3D_State &renderState,
|
|||
Render3DError OpenGLRenderer_1_2::EndRender(const u64 frameCount)
|
||||
{
|
||||
//needs to happen before endgl because it could free some textureids for expired cache items
|
||||
TexCache_EvictFrame();
|
||||
texCache.Evict(TEXCACHE_MAX_SIZE);
|
||||
|
||||
this->ReadBackPixels();
|
||||
|
||||
|
@ -2967,21 +2968,21 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
|
|||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
TexCacheItem *newTexture = TexCache_SetTexture(TexFormat_32bpp, thePoly.texParam, thePoly.texPalette);
|
||||
if(newTexture != this->currTexture)
|
||||
TexCacheItem *newTexture = texCache.GetTexture(TexFormat_32bpp, thePoly.texParam, thePoly.texPalette);
|
||||
if (newTexture != this->currTexture)
|
||||
{
|
||||
this->currTexture = newTexture;
|
||||
//has the ogl renderer initialized the texture?
|
||||
if(this->currTexture->GetDeleteCallback() == NULL)
|
||||
if (this->currTexture->GetDeleteCallback() == NULL)
|
||||
{
|
||||
this->currTexture->SetDeleteCallback(&texDeleteCallback, this, NULL);
|
||||
|
||||
if(OGLRef.freeTextureIDs.empty())
|
||||
if (OGLRef.freeTextureIDs.empty())
|
||||
{
|
||||
this->ExpandFreeTextures();
|
||||
}
|
||||
|
||||
this->currTexture->texid = (u64)OGLRef.freeTextureIDs.front();
|
||||
this->currTexture->texid = (u32)OGLRef.freeTextureIDs.front();
|
||||
OGLRef.freeTextureIDs.pop();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)this->currTexture->texid);
|
||||
|
@ -2989,7 +2990,7 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (params.enableRepeatT ? (params.enableMirroredRepeatT ? OGLRef.stateTexMirroredRepeat : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
|
||||
const NDSTextureFormat texFormat = this->currTexture->GetTextureFormat();
|
||||
const u32 *textureSrc = (u32 *)this->currTexture->decoded;
|
||||
const u32 *textureSrc = this->currTexture->unpackData;
|
||||
size_t texWidth = this->currTexture->sizeX;
|
||||
size_t texHeight = this->currTexture->sizeY;
|
||||
|
||||
|
@ -3133,7 +3134,7 @@ Render3DError OpenGLRenderer_1_2::Reset()
|
|||
memset(this->clearImagePolyIDBuffer, 0, sizeof(this->clearImagePolyIDBuffer));
|
||||
memset(this->clearImageFogBuffer, 0, sizeof(this->clearImageFogBuffer));
|
||||
|
||||
TexCache_Reset();
|
||||
texCache.Reset();
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
@ -4618,21 +4619,21 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT
|
|||
glUniform1i(OGLRef.uniformPolyEnableTexture, GL_TRUE);
|
||||
glUniform1i(OGLRef.uniformTexSingleBitAlpha, (params.texFormat != TEXMODE_A3I5 && params.texFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE);
|
||||
|
||||
TexCacheItem *newTexture = TexCache_SetTexture(TexFormat_32bpp, thePoly.texParam, thePoly.texPalette);
|
||||
if(newTexture != this->currTexture)
|
||||
TexCacheItem *newTexture = texCache.GetTexture(TexFormat_32bpp, thePoly.texParam, thePoly.texPalette);
|
||||
if (newTexture != this->currTexture)
|
||||
{
|
||||
this->currTexture = newTexture;
|
||||
//has the ogl renderer initialized the texture?
|
||||
if(this->currTexture->GetDeleteCallback() == NULL)
|
||||
if (this->currTexture->GetDeleteCallback() == NULL)
|
||||
{
|
||||
this->currTexture->SetDeleteCallback(&texDeleteCallback, this, NULL);
|
||||
|
||||
if(OGLRef.freeTextureIDs.empty())
|
||||
if (OGLRef.freeTextureIDs.empty())
|
||||
{
|
||||
this->ExpandFreeTextures();
|
||||
}
|
||||
|
||||
this->currTexture->texid = (u64)OGLRef.freeTextureIDs.front();
|
||||
this->currTexture->texid = (u32)OGLRef.freeTextureIDs.front();
|
||||
OGLRef.freeTextureIDs.pop();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)this->currTexture->texid);
|
||||
|
@ -4640,7 +4641,7 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (params.enableRepeatT ? (params.enableMirroredRepeatT ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
|
||||
const NDSTextureFormat texFormat = this->currTexture->GetTextureFormat();
|
||||
const u32 *textureSrc = (u32 *)this->currTexture->decoded;
|
||||
const u32 *textureSrc = this->currTexture->unpackData;
|
||||
size_t texWidth = this->currTexture->sizeX;
|
||||
size_t texHeight = this->currTexture->sizeY;
|
||||
|
||||
|
|
|
@ -1695,21 +1695,21 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
TexCacheItem *newTexture = TexCache_SetTexture(TexFormat_32bpp, thePoly.texParam, thePoly.texPalette);
|
||||
if(newTexture != this->currTexture)
|
||||
TexCacheItem *newTexture = texCache.GetTexture(TexFormat_32bpp, thePoly.texParam, thePoly.texPalette);
|
||||
if (newTexture != this->currTexture)
|
||||
{
|
||||
this->currTexture = newTexture;
|
||||
//has the ogl renderer initialized the texture?
|
||||
if(this->currTexture->GetDeleteCallback() == NULL)
|
||||
if (this->currTexture->GetDeleteCallback() == NULL)
|
||||
{
|
||||
this->currTexture->SetDeleteCallback(&texDeleteCallback, this, NULL);
|
||||
|
||||
if(OGLRef.freeTextureIDs.empty())
|
||||
if (OGLRef.freeTextureIDs.empty())
|
||||
{
|
||||
this->ExpandFreeTextures();
|
||||
}
|
||||
|
||||
this->currTexture->texid = (u64)OGLRef.freeTextureIDs.front();
|
||||
this->currTexture->texid = (u32)OGLRef.freeTextureIDs.front();
|
||||
OGLRef.freeTextureIDs.pop();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)this->currTexture->texid);
|
||||
|
@ -1717,7 +1717,7 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (params.enableRepeatT ? (params.enableMirroredRepeatT ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE));
|
||||
|
||||
const NDSTextureFormat texFormat = this->currTexture->GetTextureFormat();
|
||||
const u32 *textureSrc = (u32 *)this->currTexture->decoded;
|
||||
const u32 *textureSrc = this->currTexture->unpackData;
|
||||
size_t texWidth = this->currTexture->sizeX;
|
||||
size_t texHeight = this->currTexture->sizeY;
|
||||
|
||||
|
|
|
@ -461,7 +461,7 @@ public:
|
|||
|
||||
sampler.dowrap(iu, iv);
|
||||
FragmentColor color;
|
||||
color.color = ((u32*)lastTexKey->decoded)[(iv<<sampler.wshift)+iu];
|
||||
color.color = lastTexKey->unpackData[(iv<<sampler.wshift)+iu];
|
||||
return color;
|
||||
}
|
||||
|
||||
|
@ -1373,7 +1373,7 @@ void SoftRasterizerRenderer::setupTextures()
|
|||
const POLY &firstPoly = *firstClippedPoly.poly;
|
||||
u32 lastTexParams = firstPoly.texParam;
|
||||
u32 lastTexPalette = firstPoly.texPalette;
|
||||
TexCacheItem *lastTexKey = TexCache_SetTexture(TexFormat_15bpp, firstPoly.texParam, firstPoly.texPalette);
|
||||
TexCacheItem *lastTexKey = texCache.GetTexture(TexFormat_15bpp, firstPoly.texParam, firstPoly.texPalette);
|
||||
|
||||
for (size_t i = 0; i < this->_clippedPolyCount; i++)
|
||||
{
|
||||
|
@ -1386,7 +1386,7 @@ void SoftRasterizerRenderer::setupTextures()
|
|||
//and then it won't be safe.
|
||||
if (lastTexParams != thePoly.texParam || lastTexPalette != thePoly.texPalette)
|
||||
{
|
||||
lastTexKey = TexCache_SetTexture(TexFormat_15bpp, thePoly.texParam, thePoly.texPalette);
|
||||
lastTexKey = texCache.GetTexture(TexFormat_15bpp, thePoly.texParam, thePoly.texPalette);
|
||||
lastTexParams = thePoly.texParam;
|
||||
lastTexPalette = thePoly.texPalette;
|
||||
}
|
||||
|
@ -1537,7 +1537,7 @@ Render3DError SoftRasterizerRenderer::RenderGeometry(const GFX3D_State &renderSt
|
|||
{
|
||||
rasterizerUnit[0].mainLoop<false>();
|
||||
this->_renderGeometryNeedsFinish = false;
|
||||
TexCache_EvictFrame(); // Since we're finishing geometry rendering here and now, also check the texture cache now.
|
||||
texCache.Evict(TEXCACHE_MAX_SIZE); // Since we're finishing geometry rendering here and now, also check the texture cache now.
|
||||
}
|
||||
|
||||
// printf("rendered %d of %d polys after backface culling\n",gfx3d.polylist->count-culled,gfx3d.polylist->count);
|
||||
|
@ -1888,7 +1888,7 @@ Render3DError SoftRasterizerRenderer::Reset()
|
|||
memset(this->clearImagePolyIDBuffer, 0, sizeof(this->clearImagePolyIDBuffer));
|
||||
memset(this->clearImageFogBuffer, 0, sizeof(this->clearImageFogBuffer));
|
||||
|
||||
TexCache_Reset();
|
||||
texCache.Reset();
|
||||
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
@ -1947,7 +1947,7 @@ Render3DError SoftRasterizerRenderer::RenderFinish()
|
|||
}
|
||||
|
||||
// Now that geometry rendering is finished on all threads, check the texture cache.
|
||||
TexCache_EvictFrame();
|
||||
texCache.Evict(TEXCACHE_MAX_SIZE);
|
||||
|
||||
// Do multithreaded post-processing.
|
||||
if (this->currentRenderState->enableEdgeMarking || this->currentRenderState->enableFog)
|
||||
|
|
|
@ -389,7 +389,7 @@ void Render3D::SetTextureProcessingProperties(size_t scalingFactor, bool willDep
|
|||
|
||||
if (needTexCacheReset)
|
||||
{
|
||||
TexCache_Reset();
|
||||
texCache.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -616,7 +616,7 @@ Render3DError Render3D::Reset()
|
|||
this->_willFlushFramebufferRGBA6665 = true;
|
||||
this->_willFlushFramebufferRGBA5551 = true;
|
||||
|
||||
TexCache_Reset();
|
||||
texCache.Reset();
|
||||
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
@ -658,7 +658,7 @@ Render3DError Render3D::RenderFinish()
|
|||
|
||||
Render3DError Render3D::VramReconfigureSignal()
|
||||
{
|
||||
TexCache_Invalidate();
|
||||
texCache.Invalidate();
|
||||
return RENDER3DERROR_NOERR;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,6 +26,14 @@
|
|||
#include "common.h"
|
||||
#include "gfx3d.h"
|
||||
|
||||
//this ought to be enough for anyone
|
||||
//#define TEXCACHE_MAX_SIZE (64*1024*1024);
|
||||
//changed by zeromus on 15-dec. I couldnt find any games that were getting anywhere NEAR 64
|
||||
//metal slug burns through sprites so fast, it can test it pretty quickly though
|
||||
#define TEXCACHE_MAX_SIZE (16*1024*1024)
|
||||
|
||||
#define PALETTE_DUMP_SIZE ((64+16+16)*1024)
|
||||
|
||||
enum TexCache_TexFormat
|
||||
{
|
||||
TexFormat_None, //used when nothing yet is cached
|
||||
|
@ -33,11 +41,31 @@ enum TexCache_TexFormat
|
|||
TexFormat_15bpp //used by rasterizer
|
||||
};
|
||||
|
||||
class MemSpan;
|
||||
class TexCacheItem;
|
||||
|
||||
typedef std::multimap<u32,TexCacheItem*> TTexCacheItemMultimap;
|
||||
typedef void (*TexCacheItemDeleteCallback)(TexCacheItem *texItem, void *param1, void *param2);
|
||||
|
||||
class TexCache
|
||||
{
|
||||
public:
|
||||
TexCache();
|
||||
|
||||
TTexCacheItemMultimap index;
|
||||
u32 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 Reset();
|
||||
|
||||
TexCacheItem* GetTexture(TexCache_TexFormat texCacheFormat, u32 texAttributes, u32 palAttributes);
|
||||
};
|
||||
|
||||
class TexCacheItem
|
||||
{
|
||||
private:
|
||||
|
@ -46,65 +74,68 @@ private:
|
|||
void *_deleteCallbackParam2;
|
||||
|
||||
public:
|
||||
TexCacheItem()
|
||||
: decode_len(0)
|
||||
, decoded(NULL)
|
||||
, suspectedInvalid(false)
|
||||
, assumedInvalid(false)
|
||||
, _deleteCallback(NULL)
|
||||
, _deleteCallbackParam1(NULL)
|
||||
, _deleteCallbackParam2(NULL)
|
||||
, cacheFormat(TexFormat_None)
|
||||
{}
|
||||
TexCacheItem();
|
||||
~TexCacheItem();
|
||||
|
||||
NDSTextureFormat packFormat;
|
||||
u32 packSize;
|
||||
u8 *packData;
|
||||
u16 *paletteColorTable;
|
||||
|
||||
TexCache_TexFormat unpackFormat;
|
||||
u32 unpackSize;
|
||||
u32 *unpackData;
|
||||
|
||||
~TexCacheItem()
|
||||
{
|
||||
free_aligned(this->decoded);
|
||||
if (this->_deleteCallback != NULL) this->_deleteCallback(this, this->_deleteCallbackParam1, this->_deleteCallbackParam2);
|
||||
}
|
||||
u32 decode_len;
|
||||
NDSTextureFormat format;
|
||||
u8* decoded; //decoded texture data
|
||||
bool suspectedInvalid;
|
||||
bool assumedInvalid;
|
||||
TTexCacheItemMultimap::iterator iterator;
|
||||
|
||||
NDSTextureFormat GetTextureFormat() const { return this->format; }
|
||||
|
||||
u32 texformat, texpal;
|
||||
u32 sizeX, sizeY;
|
||||
float invSizeX, invSizeY;
|
||||
|
||||
u32 texid; //used by ogl renderer for the texid
|
||||
TexCache_TexFormat cacheFormat;
|
||||
|
||||
struct Dump {
|
||||
~Dump() {
|
||||
delete[] texture;
|
||||
}
|
||||
int textureSize, indexSize;
|
||||
static const int maxTextureSize=128*1024;
|
||||
u8* texture;
|
||||
u8 palette[256*2];
|
||||
} dump;
|
||||
u32 textureAttributes;
|
||||
u32 paletteAttributes;
|
||||
u32 paletteAddress;
|
||||
u32 paletteSize;
|
||||
u32 sizeX;
|
||||
u32 sizeY;
|
||||
float invSizeX;
|
||||
float invSizeY;
|
||||
|
||||
TexCacheItemDeleteCallback GetDeleteCallback()
|
||||
{
|
||||
return this->_deleteCallback;
|
||||
}
|
||||
// Only used by 4x4 formatted textures
|
||||
u8 *packIndexData;
|
||||
u32 packSizeFirstSlot;
|
||||
u32 packIndexSize;
|
||||
|
||||
void SetDeleteCallback(TexCacheItemDeleteCallback callbackFunc, void *inParam1, void *inParam2)
|
||||
{
|
||||
this->_deleteCallback = callbackFunc;
|
||||
this->_deleteCallbackParam1 = inParam1;
|
||||
this->_deleteCallbackParam2 = inParam2;
|
||||
}
|
||||
// Only used by the OpenGL renderer for the texture ID
|
||||
u32 texid;
|
||||
|
||||
TexCacheItemDeleteCallback GetDeleteCallback() const;
|
||||
void SetDeleteCallback(TexCacheItemDeleteCallback callbackFunc, void *inParam1, void *inParam2);
|
||||
|
||||
NDSTextureFormat GetTextureFormat() const;
|
||||
void SetTextureData(const u32 attr, const MemSpan &packedData, const MemSpan &packedIndexData);
|
||||
void SetTexturePalette(const u32 attr, const u16 *paletteBuffer);
|
||||
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void Unpack(const MemSpan &packedData);
|
||||
|
||||
void DebugDump();
|
||||
};
|
||||
|
||||
void TexCache_Invalidate();
|
||||
void TexCache_Reset();
|
||||
void TexCache_EvictFrame();
|
||||
// TODO: Delete these MemSpan based functions after testing confirms that using the dumped texture data works properly.
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackI2(const MemSpan &ms, const u16 *pal, const bool isPalZeroTransparent, u32 *dstBuffer);
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackI4(const MemSpan &ms, const u16 *pal, const bool isPalZeroTransparent, u32 *dstBuffer);
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackI8(const MemSpan &ms, const u16 *pal, const bool isPalZeroTransparent, u32 *dstBuffer);
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackA3I5(const MemSpan &ms, const u16 *pal, u32 *dstBuffer);
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackA5I3(const MemSpan &ms, const u16 *pal, u32 *dstBuffer);
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpack4x4(const MemSpan &ms, const u32 palAddress, const u32 texAttributes, const u32 sizeX, const u32 sizeY, u32 *dstBuffer);
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackDirect16Bit(const MemSpan &ms, u32 *dstBuffer);
|
||||
|
||||
TexCacheItem* TexCache_SetTexture(TexCache_TexFormat TEXFORMAT, u32 format, u32 texpal);
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackI2(const size_t srcSize, const u8 *srcData, const u16 *srcPal, const bool isPalZeroTransparent, u32 *dstBuffer);
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackI4(const size_t srcSize, const u8 *srcData, const u16 *srcPal, const bool isPalZeroTransparent, u32 *dstBuffer);
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackI8(const size_t srcSize, const u8 *srcData, const u16 *srcPal, const bool isPalZeroTransparent, u32 *dstBuffer);
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackA3I5(const size_t srcSize, const u8 *srcData, const u16 *srcPal, u32 *dstBuffer);
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackA5I3(const size_t srcSize, const u8 *srcData, const u16 *srcPal, u32 *dstBuffer);
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpack4x4(const size_t srcSize, const u8 *srcData, const u8 *srcIndex, const u32 palAddress, const u32 texAttributes, const u32 sizeX, const u32 sizeY, u32 *dstBuffer);
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackDirect16Bit(const size_t srcSize, const u8 *srcData, u32 *dstBuffer);
|
||||
|
||||
extern TexCache texCache;
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue