Texture Handler:
- Finish refactoring and cleaning up TexCache (now renamed to “TextureCache”) and TexCacheItem (now renamed to “TextureStore”). - TextureCache items are now evicted based on age and usage instead of arbitrarily.
This commit is contained in:
parent
c75b9ed62b
commit
02645310b4
|
@ -636,10 +636,42 @@ static void OGLGetDriverVersion(const char *oglVersionString,
|
|||
}
|
||||
}
|
||||
|
||||
void OGLTextureDeleteCallback(TexCacheItem *texItem, void *param1, void *param2)
|
||||
OpenGLTexture::OpenGLTexture()
|
||||
{
|
||||
OpenGLRenderer *oglRenderer = (OpenGLRenderer *)param1;
|
||||
oglRenderer->DeleteTexture(texItem);
|
||||
_cacheSize = GetUnpackSizeUsingFormat(TexFormat_32bpp);
|
||||
_invSizeS = 0.0f;
|
||||
_invSizeT = 0.0f;
|
||||
|
||||
glGenTextures(1, &_texID);
|
||||
}
|
||||
|
||||
OpenGLTexture::OpenGLTexture(u32 texAttributes, u32 palAttributes) : TextureStore(texAttributes, palAttributes)
|
||||
{
|
||||
_cacheSize = GetUnpackSizeUsingFormat(TexFormat_32bpp);
|
||||
_invSizeS = 1.0f / (float)_sizeS;
|
||||
_invSizeT = 1.0f / (float)_sizeT;
|
||||
|
||||
glGenTextures(1, &_texID);
|
||||
}
|
||||
|
||||
OpenGLTexture::~OpenGLTexture()
|
||||
{
|
||||
glDeleteTextures(1, &this->_texID);
|
||||
}
|
||||
|
||||
GLuint OpenGLTexture::GetID() const
|
||||
{
|
||||
return this->_texID;
|
||||
}
|
||||
|
||||
GLfloat OpenGLTexture::GetInvWidth() const
|
||||
{
|
||||
return this->_invSizeS;
|
||||
}
|
||||
|
||||
GLfloat OpenGLTexture::GetInvHeight() const
|
||||
{
|
||||
return this->_invSizeT;
|
||||
}
|
||||
|
||||
template<bool require_profile, bool enable_3_2>
|
||||
|
@ -1199,13 +1231,6 @@ OpenGLRenderer_1_2::~OpenGLRenderer_1_2()
|
|||
// Kill the texture cache now before all of our texture IDs disappear.
|
||||
texCache.Reset();
|
||||
|
||||
while(!ref->freeTextureIDs.empty())
|
||||
{
|
||||
GLuint temp = ref->freeTextureIDs.front();
|
||||
ref->freeTextureIDs.pop();
|
||||
glDeleteTextures(1, &temp);
|
||||
}
|
||||
|
||||
glFinish();
|
||||
}
|
||||
|
||||
|
@ -1352,7 +1377,6 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
|
|||
INFO("OpenGL: Multisampled FBOs are unsupported. Multisample antialiasing will be disabled.\n");
|
||||
}
|
||||
|
||||
this->InitTextures();
|
||||
this->InitFinalRenderStates(&oglExtensionSet); // This must be done last
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
|
@ -2063,13 +2087,6 @@ Render3DError OpenGLRenderer_1_2::InitFinalRenderStates(const std::set<std::stri
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_1_2::InitTextures()
|
||||
{
|
||||
this->ExpandFreeTextures();
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_1_2::InitTables()
|
||||
{
|
||||
static bool needTableInit = true;
|
||||
|
@ -2228,20 +2245,6 @@ void OpenGLRenderer_1_2::GetExtensionSet(std::set<std::string> *oglExtensionSet)
|
|||
}
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_1_2::ExpandFreeTextures()
|
||||
{
|
||||
static const GLsizei kInitTextures = 128;
|
||||
GLuint oglTempTextureID[kInitTextures];
|
||||
glGenTextures(kInitTextures, oglTempTextureID);
|
||||
|
||||
for(GLsizei i = 0; i < kInitTextures; i++)
|
||||
{
|
||||
this->ref->freeTextureIDs.push(oglTempTextureID[i]);
|
||||
}
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_1_2::EnableVertexAttributes()
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
@ -2416,14 +2419,6 @@ Render3DError OpenGLRenderer_1_2::ReadBackPixels()
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_1_2::DeleteTexture(const TexCacheItem *item)
|
||||
{
|
||||
this->ref->freeTextureIDs.push((GLuint)item->texid);
|
||||
texCache.cache_size -= item->unpackSize;
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
|
@ -2692,7 +2687,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.Evict(TEXCACHE_MAX_SIZE);
|
||||
texCache.Evict();
|
||||
|
||||
this->ReadBackPixels();
|
||||
|
||||
|
@ -2953,54 +2948,44 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
|
|||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
OpenGLTexture *theTexture = (OpenGLTexture *)texCache.GetTexture(thePoly.texParam, thePoly.texPalette);
|
||||
const bool isNewTexture = (theTexture == NULL);
|
||||
|
||||
TexCacheItem *theTexture = texCache.GetTexture(thePoly.texParam, thePoly.texPalette);
|
||||
if (isNewTexture)
|
||||
{
|
||||
theTexture = new OpenGLTexture(thePoly.texParam, thePoly.texPalette);
|
||||
texCache.Add(theTexture);
|
||||
}
|
||||
|
||||
const NDSTextureFormat packFormat = theTexture->GetPackFormat();
|
||||
|
||||
// Enable textures if they weren't already enabled
|
||||
if (this->isShaderSupported)
|
||||
{
|
||||
glUniform1i(OGLRef.uniformPolyEnableTexture, GL_TRUE);
|
||||
glUniform1i(OGLRef.uniformTexSingleBitAlpha, (theTexture->packFormat != TEXMODE_A3I5 && theTexture->packFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE);
|
||||
glUniform2f(OGLRef.uniformPolyTexScale, theTexture->invSizeX, theTexture->invSizeY);
|
||||
glUniform1i(OGLRef.uniformTexSingleBitAlpha, (packFormat != TEXMODE_A3I5 && packFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE);
|
||||
glUniform2f(OGLRef.uniformPolyTexScale, theTexture->GetInvWidth(), theTexture->GetInvHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
glScalef(theTexture->invSizeX, theTexture->invSizeY, 1.0f);
|
||||
glScalef(theTexture->GetInvWidth(), theTexture->GetInvHeight(), 1.0f);
|
||||
}
|
||||
|
||||
if (theTexture->unpackFormat != TexFormat_32bpp)
|
||||
glBindTexture(GL_TEXTURE_2D, theTexture->GetID());
|
||||
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));
|
||||
|
||||
if (theTexture->IsLoadNeeded())
|
||||
{
|
||||
//has the ogl renderer initialized the texture?
|
||||
const bool isNewTexture = (theTexture->GetDeleteCallback() == NULL);
|
||||
if (isNewTexture)
|
||||
{
|
||||
theTexture->SetDeleteCallback(&OGLTextureDeleteCallback, this, NULL);
|
||||
|
||||
if (OGLRef.freeTextureIDs.empty())
|
||||
{
|
||||
this->ExpandFreeTextures();
|
||||
}
|
||||
|
||||
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 = (u32 *)this->_workingTextureUnpackBuffer;
|
||||
size_t texWidth = theTexture->sizeX;
|
||||
size_t texHeight = theTexture->sizeY;
|
||||
size_t texWidth = theTexture->GetWidth();
|
||||
size_t texHeight = theTexture->GetHeight();
|
||||
|
||||
if (this->_textureDeposterizeDstSurface.Surface != NULL)
|
||||
{
|
||||
|
@ -3031,17 +3016,17 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
||||
|
||||
this->TextureUpscale<2>(texFormat, textureSrc, texWidth, texHeight);
|
||||
this->TextureUpscale<2>(packFormat, textureSrc, texWidth, texHeight);
|
||||
|
||||
if (isNewTexture)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, theTexture->sizeX, theTexture->sizeY, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, theTexture->GetWidth(), theTexture->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, theTexture->sizeX, theTexture->sizeY, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, theTexture->GetWidth(), theTexture->GetHeight(), GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3051,29 +3036,29 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
|
||||
|
||||
this->TextureUpscale<4>(texFormat, textureSrc, texWidth, texHeight);
|
||||
this->TextureUpscale<4>(packFormat, textureSrc, texWidth, texHeight);
|
||||
|
||||
if (isNewTexture)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||
|
||||
texWidth = theTexture->sizeX;
|
||||
texHeight = theTexture->sizeY;
|
||||
this->TextureUpscale<2>(texFormat, textureSrc, texWidth, texHeight);
|
||||
texWidth = theTexture->GetWidth();
|
||||
texHeight = theTexture->GetHeight();
|
||||
this->TextureUpscale<2>(packFormat, textureSrc, texWidth, texHeight);
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, theTexture->sizeX, theTexture->sizeY, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, theTexture->GetWidth(), theTexture->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||
|
||||
texWidth = theTexture->sizeX;
|
||||
texHeight = theTexture->sizeY;
|
||||
this->TextureUpscale<2>(texFormat, textureSrc, texWidth, texHeight);
|
||||
texWidth = theTexture->GetWidth();
|
||||
texHeight = theTexture->GetHeight();
|
||||
this->TextureUpscale<2>(packFormat, textureSrc, texWidth, texHeight);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, theTexture->sizeX, theTexture->sizeY, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, theTexture->GetWidth(), theTexture->GetHeight(), GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3095,11 +3080,9 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
|
|||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//otherwise, just bind it
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)theTexture->texid);
|
||||
}
|
||||
|
||||
theTexture->ResetCacheAge();
|
||||
theTexture->IncreaseCacheUsageCount(1);
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
@ -3867,7 +3850,6 @@ Render3DError OpenGLRenderer_2_0::InitExtensions()
|
|||
INFO("OpenGL: Multisampled FBOs are unsupported. Multisample antialiasing will be disabled.\n");
|
||||
}
|
||||
|
||||
this->InitTextures();
|
||||
this->InitFinalRenderStates(&oglExtensionSet); // This must be done last
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
|
@ -4644,42 +4626,32 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
TexCacheItem *theTexture = texCache.GetTexture(thePoly.texParam, thePoly.texPalette);
|
||||
OpenGLTexture *theTexture = (OpenGLTexture *)texCache.GetTexture(thePoly.texParam, thePoly.texPalette);
|
||||
const bool isNewTexture = (theTexture == NULL);
|
||||
|
||||
if (isNewTexture)
|
||||
{
|
||||
theTexture = new OpenGLTexture(thePoly.texParam, thePoly.texPalette);
|
||||
texCache.Add(theTexture);
|
||||
}
|
||||
|
||||
const NDSTextureFormat packFormat = theTexture->GetPackFormat();
|
||||
|
||||
glUniform1i(OGLRef.uniformPolyEnableTexture, GL_TRUE);
|
||||
glUniform1i(OGLRef.uniformTexSingleBitAlpha, (theTexture->packFormat != TEXMODE_A3I5 && theTexture->packFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE);
|
||||
glUniform2f(OGLRef.uniformPolyTexScale, theTexture->invSizeX, theTexture->invSizeY);
|
||||
glUniform1i(OGLRef.uniformTexSingleBitAlpha, (packFormat != TEXMODE_A3I5 && packFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE);
|
||||
glUniform2f(OGLRef.uniformPolyTexScale, theTexture->GetInvWidth(), theTexture->GetInvHeight());
|
||||
|
||||
if (theTexture->unpackFormat != TexFormat_32bpp)
|
||||
glBindTexture(GL_TEXTURE_2D, theTexture->GetID());
|
||||
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));
|
||||
|
||||
if (theTexture->IsLoadNeeded())
|
||||
{
|
||||
//has the ogl renderer initialized the texture?
|
||||
const bool isNewTexture = (theTexture->GetDeleteCallback() == NULL);
|
||||
if (isNewTexture)
|
||||
{
|
||||
theTexture->SetDeleteCallback(&OGLTextureDeleteCallback, this, NULL);
|
||||
|
||||
if (OGLRef.freeTextureIDs.empty())
|
||||
{
|
||||
this->ExpandFreeTextures();
|
||||
}
|
||||
|
||||
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 = (u32 *)this->_workingTextureUnpackBuffer;
|
||||
size_t texWidth = theTexture->sizeX;
|
||||
size_t texHeight = theTexture->sizeY;
|
||||
size_t texWidth = theTexture->GetWidth();
|
||||
size_t texHeight = theTexture->GetHeight();
|
||||
|
||||
if (this->_textureDeposterizeDstSurface.Surface != NULL)
|
||||
{
|
||||
|
@ -4710,15 +4682,17 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
||||
|
||||
this->TextureUpscale<2>(packFormat, textureSrc, texWidth, texHeight);
|
||||
|
||||
if (isNewTexture)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, theTexture->sizeX, theTexture->sizeY, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, theTexture->GetWidth(), theTexture->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, theTexture->sizeX, theTexture->sizeY, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, theTexture->GetWidth(), theTexture->GetHeight(), GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -4728,29 +4702,29 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
|
||||
|
||||
this->TextureUpscale<4>(texFormat, textureSrc, texWidth, texHeight);
|
||||
this->TextureUpscale<4>(packFormat, textureSrc, texWidth, texHeight);
|
||||
|
||||
if (isNewTexture)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||
|
||||
texWidth = theTexture->sizeX;
|
||||
texHeight = theTexture->sizeY;
|
||||
this->TextureUpscale<2>(texFormat, textureSrc, texWidth, texHeight);
|
||||
texWidth = theTexture->GetWidth();
|
||||
texHeight = theTexture->GetHeight();
|
||||
this->TextureUpscale<2>(packFormat, textureSrc, texWidth, texHeight);
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, theTexture->sizeX, theTexture->sizeY, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, theTexture->GetWidth(), theTexture->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||
|
||||
texWidth = theTexture->sizeX;
|
||||
texHeight = theTexture->sizeY;
|
||||
this->TextureUpscale<2>(texFormat, textureSrc, texWidth, texHeight);
|
||||
texWidth = theTexture->GetWidth();
|
||||
texHeight = theTexture->GetHeight();
|
||||
this->TextureUpscale<2>(packFormat, textureSrc, texWidth, texHeight);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, theTexture->sizeX, theTexture->sizeY, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, theTexture->GetWidth(), theTexture->GetHeight(), GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -4772,11 +4746,9 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT
|
|||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//otherwise, just bind it
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)theTexture->texid);
|
||||
}
|
||||
|
||||
theTexture->ResetCacheAge();
|
||||
theTexture->IncreaseCacheUsageCount(1);
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <set>
|
||||
#include <string>
|
||||
#include "render3D.h"
|
||||
#include "texcache.h"
|
||||
#include "types.h"
|
||||
|
||||
#ifndef OGLRENDER_3_2_H
|
||||
|
@ -491,9 +492,6 @@ struct OGLRenderRef
|
|||
GLuint vaoGeometryStatesID;
|
||||
GLuint vaoPostprocessStatesID;
|
||||
|
||||
// Textures
|
||||
std::queue<GLuint> freeTextureIDs;
|
||||
|
||||
// Client-side Buffers
|
||||
GLfloat *color4fBuffer;
|
||||
GLushort *vertIndexBuffer;
|
||||
|
@ -526,8 +524,6 @@ extern CACHE_ALIGN const GLfloat divide6bitBy63_LUT[64];
|
|||
extern const GLfloat PostprocessVtxBuffer[16];
|
||||
extern const GLubyte PostprocessElementBuffer[6];
|
||||
|
||||
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.
|
||||
//return true if you successfully init.
|
||||
|
@ -559,6 +555,23 @@ extern void (*OGLCreateRenderer_3_2_Func)(OpenGLRenderer **rendererPtr);
|
|||
|
||||
bool IsVersionSupported(unsigned int checkVersionMajor, unsigned int checkVersionMinor, unsigned int checkVersionRevision);
|
||||
|
||||
class OpenGLTexture : public TextureStore
|
||||
{
|
||||
private:
|
||||
GLuint _texID;
|
||||
GLfloat _invSizeS;
|
||||
GLfloat _invSizeT;
|
||||
|
||||
public:
|
||||
OpenGLTexture();
|
||||
OpenGLTexture(u32 texAttributes, u32 palAttributes);
|
||||
virtual ~OpenGLTexture();
|
||||
|
||||
GLuint GetID() const;
|
||||
GLfloat GetInvWidth() const;
|
||||
GLfloat GetInvHeight() const;
|
||||
};
|
||||
|
||||
#if defined(ENABLE_SSE2)
|
||||
class OpenGLRenderer : public Render3D_SSE2
|
||||
#else
|
||||
|
@ -609,7 +622,6 @@ protected:
|
|||
virtual void DestroyGeometryProgram() = 0;
|
||||
virtual Render3DError CreateVAOs() = 0;
|
||||
virtual void DestroyVAOs() = 0;
|
||||
virtual Render3DError InitTextures() = 0;
|
||||
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet) = 0;
|
||||
virtual Render3DError InitTables() = 0;
|
||||
virtual Render3DError InitPostprocessingPrograms(const std::string &edgeMarkVtxShader,
|
||||
|
@ -635,7 +647,6 @@ protected:
|
|||
virtual Render3DError UploadClearImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthBuffer, const u8 *__restrict fogBuffer, const u8 *__restrict polyIDBuffer) = 0;
|
||||
|
||||
virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet) = 0;
|
||||
virtual Render3DError ExpandFreeTextures() = 0;
|
||||
virtual Render3DError EnableVertexAttributes() = 0;
|
||||
virtual Render3DError DisableVertexAttributes() = 0;
|
||||
virtual Render3DError DownsampleFBO() = 0;
|
||||
|
@ -648,7 +659,6 @@ public:
|
|||
virtual ~OpenGLRenderer();
|
||||
|
||||
virtual Render3DError InitExtensions() = 0;
|
||||
virtual Render3DError DeleteTexture(const TexCacheItem *item) = 0;
|
||||
|
||||
bool IsExtensionPresent(const std::set<std::string> *oglExtensionSet, const std::string extensionName) const;
|
||||
bool ValidateShaderCompile(GLuint theShader) const;
|
||||
|
@ -673,7 +683,6 @@ protected:
|
|||
virtual void DestroyMultisampledFBO();
|
||||
virtual Render3DError CreateVAOs();
|
||||
virtual void DestroyVAOs();
|
||||
virtual Render3DError InitTextures();
|
||||
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet);
|
||||
virtual Render3DError InitTables();
|
||||
|
||||
|
@ -702,7 +711,6 @@ protected:
|
|||
virtual Render3DError UploadClearImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthBuffer, const u8 *__restrict fogBuffer, const u8 *__restrict polyIDBuffer);
|
||||
|
||||
virtual void GetExtensionSet(std::set<std::string> *oglExtensionSet);
|
||||
virtual Render3DError ExpandFreeTextures();
|
||||
virtual Render3DError EnableVertexAttributes();
|
||||
virtual Render3DError DisableVertexAttributes();
|
||||
virtual Render3DError DownsampleFBO();
|
||||
|
@ -729,8 +737,6 @@ public:
|
|||
virtual Render3DError Reset();
|
||||
virtual Render3DError RenderFinish();
|
||||
virtual Render3DError SetFramebufferSize(size_t w, size_t h);
|
||||
|
||||
virtual Render3DError DeleteTexture(const TexCacheItem *item);
|
||||
};
|
||||
|
||||
class OpenGLRenderer_1_3 : public OpenGLRenderer_1_2
|
||||
|
|
|
@ -609,7 +609,6 @@ Render3DError OpenGLRenderer_3_2::InitExtensions()
|
|||
}
|
||||
}
|
||||
|
||||
this->InitTextures();
|
||||
this->InitFinalRenderStates(&oglExtensionSet); // This must be done last
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
|
@ -1686,7 +1685,6 @@ Render3DError OpenGLRenderer_3_2::SetupPolygon(const POLY &thePoly)
|
|||
|
||||
Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableTexturing)
|
||||
{
|
||||
OGLRenderRef &OGLRef = *this->ref;
|
||||
const PolygonTexParams params = thePoly.getTexParams();
|
||||
|
||||
// Check if we need to use textures
|
||||
|
@ -1695,37 +1693,27 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT
|
|||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
||||
TexCacheItem *theTexture = texCache.GetTexture(thePoly.texParam, thePoly.texPalette);
|
||||
if (theTexture->unpackFormat != TexFormat_32bpp)
|
||||
OpenGLTexture *theTexture = (OpenGLTexture *)texCache.GetTexture(thePoly.texParam, thePoly.texPalette);
|
||||
const bool isNewTexture = (theTexture == NULL);
|
||||
|
||||
if (isNewTexture)
|
||||
{
|
||||
theTexture = new OpenGLTexture(thePoly.texParam, thePoly.texPalette);
|
||||
texCache.Add(theTexture);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, theTexture->GetID());
|
||||
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));
|
||||
|
||||
if (theTexture->IsLoadNeeded())
|
||||
{
|
||||
//has the ogl renderer initialized the texture?
|
||||
const bool isNewTexture = (theTexture->GetDeleteCallback() == NULL);
|
||||
if (isNewTexture)
|
||||
{
|
||||
theTexture->SetDeleteCallback(&OGLTextureDeleteCallback, this, NULL);
|
||||
|
||||
if (OGLRef.freeTextureIDs.empty())
|
||||
{
|
||||
this->ExpandFreeTextures();
|
||||
}
|
||||
|
||||
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 = (u32 *)this->_workingTextureUnpackBuffer;
|
||||
size_t texWidth = theTexture->sizeX;
|
||||
size_t texHeight = theTexture->sizeY;
|
||||
const NDSTextureFormat packFormat = theTexture->GetPackFormat();
|
||||
size_t texWidth = theTexture->GetWidth();
|
||||
size_t texHeight = theTexture->GetHeight();
|
||||
|
||||
if (this->_textureDeposterizeDstSurface.Surface != NULL)
|
||||
{
|
||||
|
@ -1756,17 +1744,17 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
||||
|
||||
this->TextureUpscale<2>(texFormat, textureSrc, texWidth, texHeight);
|
||||
this->TextureUpscale<2>(packFormat, textureSrc, texWidth, texHeight);
|
||||
|
||||
if (isNewTexture)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, theTexture->sizeX, theTexture->sizeY, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, theTexture->GetWidth(), theTexture->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, theTexture->sizeX, theTexture->sizeY, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, theTexture->GetWidth(), theTexture->GetHeight(), GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1776,29 +1764,29 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
|
||||
|
||||
this->TextureUpscale<4>(texFormat, textureSrc, texWidth, texHeight);
|
||||
this->TextureUpscale<4>(packFormat, textureSrc, texWidth, texHeight);
|
||||
|
||||
if (isNewTexture)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||
|
||||
texWidth = theTexture->sizeX;
|
||||
texHeight = theTexture->sizeY;
|
||||
this->TextureUpscale<2>(texFormat, textureSrc, texWidth, texHeight);
|
||||
texWidth = theTexture->GetWidth();
|
||||
texHeight = theTexture->GetHeight();
|
||||
this->TextureUpscale<2>(packFormat, textureSrc, texWidth, texHeight);
|
||||
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, theTexture->sizeX, theTexture->sizeY, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, theTexture->GetWidth(), theTexture->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||
|
||||
texWidth = theTexture->sizeX;
|
||||
texHeight = theTexture->sizeY;
|
||||
this->TextureUpscale<2>(texFormat, textureSrc, texWidth, texHeight);
|
||||
texWidth = theTexture->GetWidth();
|
||||
texHeight = theTexture->GetHeight();
|
||||
this->TextureUpscale<2>(packFormat, textureSrc, texWidth, texHeight);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, theTexture->sizeX, theTexture->sizeY, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, theTexture->GetWidth(), theTexture->GetHeight(), GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, textureSrc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1820,11 +1808,9 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT
|
|||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//otherwise, just bind it
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)theTexture->texid);
|
||||
}
|
||||
|
||||
theTexture->ResetCacheAge();
|
||||
theTexture->IncreaseCacheUsageCount(1);
|
||||
|
||||
return OGLERROR_NOERR;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,6 @@
|
|||
#include "matrix.h"
|
||||
#include "render3D.h"
|
||||
#include "gfx3d.h"
|
||||
#include "texcache.h"
|
||||
#include "MMU.h"
|
||||
#include "NDSSystem.h"
|
||||
#include "utils/task.h"
|
||||
|
@ -331,7 +330,7 @@ class RasterizerUnit
|
|||
{
|
||||
protected:
|
||||
SoftRasterizerRenderer *_softRender;
|
||||
TexCacheItem *lastTexKey;
|
||||
SoftRasterizerTexture *lastTexKey;
|
||||
VERT* verts[MAX_CLIPPED_VERTS];
|
||||
int polynum;
|
||||
|
||||
|
@ -351,19 +350,16 @@ public:
|
|||
int width, height;
|
||||
s32 wmask, hmask;
|
||||
int wrap;
|
||||
int wshift;
|
||||
int texFormat;
|
||||
|
||||
void setup(u32 texParam)
|
||||
void setup(SoftRasterizerTexture *theTexture, u32 texParam)
|
||||
{
|
||||
texFormat = (texParam>>26)&7;
|
||||
wshift = ((texParam>>20)&0x07) + 3;
|
||||
width=(1 << wshift);
|
||||
height=(8 << ((texParam>>23)&0x07));
|
||||
wmask = width-1;
|
||||
hmask = height-1;
|
||||
width = theTexture->GetRenderWidth();
|
||||
height = theTexture->GetRenderHeight();
|
||||
wmask = theTexture->GetRenderWidthMask();
|
||||
hmask = theTexture->GetRenderHeightMask();
|
||||
|
||||
wrap = (texParam>>16)&0xF;
|
||||
enabled = gfx3d.renderState.enableTexturing && (texFormat!=0);
|
||||
enabled = gfx3d.renderState.enableTexturing && (theTexture->GetPackFormat() != TEXMODE_NONE);
|
||||
}
|
||||
|
||||
FORCEINLINE void clamp(s32 &val, const int size, const s32 sizemask)
|
||||
|
@ -461,7 +457,10 @@ public:
|
|||
|
||||
sampler.dowrap(iu, iv);
|
||||
FragmentColor color;
|
||||
color.color = lastTexKey->unpackData[(iv<<sampler.wshift)+iu];
|
||||
const u32 *textureData = lastTexKey->GetUnpackData();
|
||||
|
||||
color.color = textureData[( iv << lastTexKey->GetRenderWidthShift() ) + iu];
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
|
@ -1006,15 +1005,15 @@ public:
|
|||
const size_t dstWidth = this->_softRender->GetFramebufferWidth();
|
||||
const size_t dstHeight = this->_softRender->GetFramebufferHeight();
|
||||
|
||||
lastTexKey = NULL;
|
||||
|
||||
const GFX3D_Clipper::TClippedPoly &firstClippedPoly = this->_softRender->clippedPolys[0];
|
||||
const POLY &firstPoly = *firstClippedPoly.poly;
|
||||
PolygonAttributes polyAttr = firstPoly.getAttributes();
|
||||
u32 lastPolyAttr = firstPoly.polyAttr;
|
||||
u32 lastTexParams = firstPoly.texParam;
|
||||
u32 lastTexPalette = firstPoly.texPalette;
|
||||
sampler.setup(firstPoly.texParam);
|
||||
|
||||
lastTexKey = this->_softRender->polyTexKeys[0];
|
||||
sampler.setup(lastTexKey, firstPoly.texParam);
|
||||
|
||||
//iterate over polys
|
||||
for (size_t i = 0; i < polyCount; i++)
|
||||
|
@ -1035,13 +1034,15 @@ public:
|
|||
|
||||
if (lastTexParams != thePoly.texParam || lastTexPalette != thePoly.texPalette)
|
||||
{
|
||||
sampler.setup(thePoly.texParam);
|
||||
lastTexParams = thePoly.texParam;
|
||||
lastTexPalette = thePoly.texPalette;
|
||||
|
||||
lastTexKey = this->_softRender->polyTexKeys[i];
|
||||
sampler.setup(lastTexKey, thePoly.texParam);
|
||||
lastTexKey->ResetCacheAge();
|
||||
lastTexKey->IncreaseCacheUsageCount(1);
|
||||
}
|
||||
|
||||
lastTexKey = this->_softRender->polyTexKeys[i];
|
||||
|
||||
for (int j = 0; j < type; j++)
|
||||
this->verts[j] = &clippedPoly.clipVerts[j];
|
||||
for (int j = type; j < MAX_CLIPPED_VERTS; j++)
|
||||
|
@ -1147,10 +1148,58 @@ static void SoftRasterizerRendererDestroy()
|
|||
}
|
||||
}
|
||||
|
||||
void SoftRasterizerTextureDeleteCallback(TexCacheItem *texItem, void *param1, void *param2)
|
||||
SoftRasterizerTexture::SoftRasterizerTexture(u32 texAttributes, u32 palAttributes) : TextureStore(texAttributes, palAttributes)
|
||||
{
|
||||
free_aligned(texItem->unpackData);
|
||||
texCache.cache_size -= texItem->unpackSize;
|
||||
_cacheSize = GetUnpackSizeUsingFormat(TexFormat_15bpp);
|
||||
_unpackData = (u32 *)malloc_alignedCacheLine(_cacheSize);
|
||||
_renderWidth = _sizeS;
|
||||
_renderHeight = _sizeT;
|
||||
_renderWidthMask = _renderWidth - 1;
|
||||
_renderHeightMask = _renderHeight - 1;
|
||||
|
||||
_renderWidthShift = 0;
|
||||
|
||||
u32 tempWidth = _renderWidth;
|
||||
while ( (tempWidth & 1) == 0)
|
||||
{
|
||||
tempWidth >>= 1;
|
||||
_renderWidthShift++;
|
||||
}
|
||||
}
|
||||
|
||||
SoftRasterizerTexture::~SoftRasterizerTexture()
|
||||
{
|
||||
free_aligned(this->_unpackData);
|
||||
}
|
||||
|
||||
u32* SoftRasterizerTexture::GetUnpackData()
|
||||
{
|
||||
return this->_unpackData;
|
||||
}
|
||||
|
||||
u32 SoftRasterizerTexture::GetRenderWidth() const
|
||||
{
|
||||
return this->_renderWidth;
|
||||
}
|
||||
|
||||
u32 SoftRasterizerTexture::GetRenderHeight() const
|
||||
{
|
||||
return this->_renderHeight;
|
||||
}
|
||||
|
||||
u32 SoftRasterizerTexture::GetRenderWidthMask() const
|
||||
{
|
||||
return this->_renderWidthMask;
|
||||
}
|
||||
|
||||
u32 SoftRasterizerTexture::GetRenderHeightMask() const
|
||||
{
|
||||
return this->_renderHeightMask;
|
||||
}
|
||||
|
||||
u32 SoftRasterizerTexture::GetRenderWidthShift() const
|
||||
{
|
||||
return this->_renderWidthShift;
|
||||
}
|
||||
|
||||
GPU3DInterface gpu3DRasterize = {
|
||||
|
@ -1380,19 +1429,16 @@ void SoftRasterizerRenderer::setupTextures()
|
|||
u32 lastTexParams = firstPoly.texParam;
|
||||
u32 lastTexPalette = firstPoly.texPalette;
|
||||
|
||||
TexCacheItem *lastTexItem = texCache.GetTexture(firstPoly.texParam, firstPoly.texPalette);
|
||||
if (lastTexItem->unpackFormat != TexFormat_15bpp)
|
||||
SoftRasterizerTexture *lastTexItem = (SoftRasterizerTexture *)texCache.GetTexture(firstPoly.texParam, firstPoly.texPalette);
|
||||
if (lastTexItem == NULL)
|
||||
{
|
||||
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);
|
||||
lastTexItem = new SoftRasterizerTexture(firstPoly.texParam, firstPoly.texPalette);
|
||||
texCache.Add(lastTexItem);
|
||||
}
|
||||
|
||||
if (lastTexItem->IsLoadNeeded())
|
||||
{
|
||||
lastTexItem->Unpack<TexFormat_15bpp>(lastTexItem->GetUnpackData());
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < this->_clippedPolyCount; i++)
|
||||
|
@ -1406,19 +1452,16 @@ void SoftRasterizerRenderer::setupTextures()
|
|||
//and then it won't be safe.
|
||||
if (lastTexParams != thePoly.texParam || lastTexPalette != thePoly.texPalette)
|
||||
{
|
||||
lastTexItem = texCache.GetTexture(thePoly.texParam, thePoly.texPalette);
|
||||
if (lastTexItem->unpackFormat != TexFormat_15bpp)
|
||||
lastTexItem = (SoftRasterizerTexture *)texCache.GetTexture(thePoly.texParam, thePoly.texPalette);
|
||||
if (lastTexItem == NULL)
|
||||
{
|
||||
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);
|
||||
lastTexItem = new SoftRasterizerTexture(thePoly.texParam, thePoly.texPalette);
|
||||
texCache.Add(lastTexItem);
|
||||
}
|
||||
|
||||
if (lastTexItem->IsLoadNeeded())
|
||||
{
|
||||
lastTexItem->Unpack<TexFormat_15bpp>(lastTexItem->GetUnpackData());
|
||||
}
|
||||
|
||||
lastTexParams = thePoly.texParam;
|
||||
|
@ -1571,7 +1614,7 @@ Render3DError SoftRasterizerRenderer::RenderGeometry(const GFX3D_State &renderSt
|
|||
{
|
||||
rasterizerUnit[0].mainLoop<false>();
|
||||
this->_renderGeometryNeedsFinish = false;
|
||||
texCache.Evict(TEXCACHE_MAX_SIZE); // Since we're finishing geometry rendering here and now, also check the texture cache now.
|
||||
texCache.Evict(); // 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);
|
||||
|
@ -1981,7 +2024,7 @@ Render3DError SoftRasterizerRenderer::RenderFinish()
|
|||
}
|
||||
|
||||
// Now that geometry rendering is finished on all threads, check the texture cache.
|
||||
texCache.Evict(TEXCACHE_MAX_SIZE);
|
||||
texCache.Evict();
|
||||
|
||||
// Do multithreaded post-processing.
|
||||
if (this->currentRenderState->enableEdgeMarking || this->currentRenderState->enableFog)
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "render3D.h"
|
||||
#include "gfx3d.h"
|
||||
#include "texcache.h"
|
||||
|
||||
#define SOFTRASTERIZER_DEPTH_EQUAL_TEST_TOLERANCE 0x200
|
||||
|
||||
|
@ -39,6 +40,28 @@ struct SoftRasterizerPostProcessParams
|
|||
bool fogAlphaOnly;
|
||||
};
|
||||
|
||||
class SoftRasterizerTexture : public TextureStore
|
||||
{
|
||||
protected:
|
||||
u32 *_unpackData;
|
||||
u32 _renderWidth;
|
||||
u32 _renderHeight;
|
||||
u32 _renderWidthMask;
|
||||
u32 _renderHeightMask;
|
||||
u32 _renderWidthShift;
|
||||
|
||||
public:
|
||||
SoftRasterizerTexture(u32 texAttributes, u32 palAttributes);
|
||||
virtual ~SoftRasterizerTexture();
|
||||
|
||||
u32* GetUnpackData();
|
||||
u32 GetRenderWidth() const;
|
||||
u32 GetRenderHeight() const;
|
||||
u32 GetRenderWidthMask() const;
|
||||
u32 GetRenderHeightMask() const;
|
||||
u32 GetRenderWidthShift() const;
|
||||
};
|
||||
|
||||
#if defined(ENABLE_SSE2)
|
||||
class SoftRasterizerRenderer : public Render3D_SSE2
|
||||
#else
|
||||
|
@ -75,7 +98,7 @@ public:
|
|||
FragmentColor toonColor32LUT[32];
|
||||
GFX3D_Clipper::TClippedPoly *clippedPolys;
|
||||
FragmentAttributesBuffer *_framebufferAttributes;
|
||||
TexCacheItem *polyTexKeys[POLYLIST_SIZE];
|
||||
SoftRasterizerTexture *polyTexKeys[POLYLIST_SIZE];
|
||||
bool polyVisible[POLYLIST_SIZE];
|
||||
bool polyBackfacing[POLYLIST_SIZE];
|
||||
GFX3D_State *currentRenderState;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -21,25 +21,26 @@
|
|||
#define _TEXCACHE_H_
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "types.h"
|
||||
#include "common.h"
|
||||
#include "gfx3d.h"
|
||||
|
||||
//this ought to be enough for anyone
|
||||
//#define TEXCACHE_MAX_SIZE (64*1024*1024)
|
||||
//#define TEXCACHE_DEFAULT_THRESHOLD (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 TEXCACHE_DEFAULT_THRESHOLD (16*1024*1024)
|
||||
|
||||
// rogerman, 2016-11-02: Increase this to 32MB for games that use many large textures, such
|
||||
// as Umihara Kawase Shun, which can cache over 20MB in the first level.
|
||||
#define TEXCACHE_MAX_SIZE (32*1024*1024)
|
||||
#define TEXCACHE_DEFAULT_THRESHOLD (32*1024*1024)
|
||||
|
||||
#define PALETTE_DUMP_SIZE ((64+16+16)*1024)
|
||||
|
||||
enum TexCache_TexFormat
|
||||
enum TextureStoreUnpackFormat
|
||||
{
|
||||
TexFormat_None, //used when nothing yet is cached
|
||||
TexFormat_32bpp, //used by ogl renderer
|
||||
|
@ -47,97 +48,142 @@ enum TexCache_TexFormat
|
|||
};
|
||||
|
||||
class MemSpan;
|
||||
class TexCacheItem;
|
||||
class TextureStore;
|
||||
|
||||
typedef u64 TexCacheKey;
|
||||
typedef std::map<TexCacheKey, TexCacheItem *> TexCacheTable;
|
||||
typedef void (*TexCacheItemDeleteCallback)(TexCacheItem *texItem, void *param1, void *param2);
|
||||
typedef u64 TextureCacheKey;
|
||||
typedef std::map<TextureCacheKey, TextureStore *> TextureCacheMap; // Key = A TextureCacheKey that includes a combination of the texture's NDS texture attributes and palette attributes; Value = Pointer to the texture item
|
||||
typedef std::vector<TextureStore *> TextureCacheList;
|
||||
//typedef u32 TextureFingerprint;
|
||||
|
||||
class TexCache
|
||||
class TextureCache
|
||||
{
|
||||
public:
|
||||
TexCache();
|
||||
protected:
|
||||
TextureCacheMap _texCacheMap; // Used to quickly find a texture item by using a key of type TextureCacheKey
|
||||
TextureCacheList _texCacheList; // Used to sort existing texture items for various operations
|
||||
size_t _actualCacheSize;
|
||||
size_t _cacheSizeThreshold;
|
||||
u8 _paletteDump[PALETTE_DUMP_SIZE];
|
||||
|
||||
public:
|
||||
TextureCache();
|
||||
|
||||
size_t GetActualCacheSize() const;
|
||||
size_t GetCacheSizeThreshold() const;
|
||||
void SetCacheSizeThreshold(size_t newThreshold);
|
||||
|
||||
TexCacheTable cacheTable;
|
||||
size_t cache_size; //this is not really precise, it is off by a constant factor
|
||||
u8 paletteDump[PALETTE_DUMP_SIZE];
|
||||
|
||||
void Invalidate();
|
||||
void Evict(size_t target);
|
||||
void Evict();
|
||||
void Reset();
|
||||
|
||||
TexCacheItem* GetTexture(u32 texAttributes, u32 palAttributes);
|
||||
TextureStore* GetTexture(u32 texAttributes, u32 palAttributes);
|
||||
|
||||
static TexCacheKey GenerateKey(const u32 texAttributes, const u32 palAttributes);
|
||||
void Add(TextureStore *texItem);
|
||||
void Remove(TextureStore *texItem);
|
||||
|
||||
static TextureCacheKey GenerateKey(const u32 texAttributes, const u32 palAttributes);
|
||||
};
|
||||
|
||||
class TexCacheItem
|
||||
class TextureStore
|
||||
{
|
||||
private:
|
||||
TexCacheItemDeleteCallback _deleteCallback;
|
||||
void *_deleteCallbackParam1;
|
||||
void *_deleteCallbackParam2;
|
||||
protected:
|
||||
u32 _textureAttributes;
|
||||
u32 _paletteAttributes;
|
||||
|
||||
public:
|
||||
TexCacheItem();
|
||||
TexCacheItem(const u32 texAttributes, const u32 palAttributes);
|
||||
~TexCacheItem();
|
||||
u32 _sizeS;
|
||||
u32 _sizeT;
|
||||
bool _isPalZeroTransparent;
|
||||
|
||||
u32 textureAttributes;
|
||||
u32 paletteAttributes;
|
||||
NDSTextureFormat _packFormat;
|
||||
u32 _packAddress;
|
||||
u32 _packSize;
|
||||
u8 *_packData;
|
||||
|
||||
u32 sizeX;
|
||||
u32 sizeY;
|
||||
float invSizeX;
|
||||
float invSizeY;
|
||||
bool isPalZeroTransparent;
|
||||
|
||||
bool suspectedInvalid;
|
||||
bool assumedInvalid;
|
||||
|
||||
NDSTextureFormat packFormat;
|
||||
u32 packAddress;
|
||||
u32 packSize;
|
||||
u8 *packData;
|
||||
|
||||
u32 paletteAddress;
|
||||
u32 paletteSize;
|
||||
u16 *paletteColorTable;
|
||||
|
||||
TexCache_TexFormat unpackFormat;
|
||||
u32 unpackSize;
|
||||
u32 *unpackData;
|
||||
u32 _paletteAddress;
|
||||
u32 _paletteSize;
|
||||
u16 *_paletteColorTable;
|
||||
|
||||
// Only used by 4x4 formatted textures
|
||||
u32 packIndexAddress;
|
||||
u32 packIndexSize;
|
||||
u8 *packIndexData;
|
||||
u32 packSizeFirstSlot;
|
||||
u32 _packIndexAddress;
|
||||
u32 _packIndexSize;
|
||||
u8 *_packIndexData;
|
||||
u32 _packSizeFirstSlot;
|
||||
|
||||
// Only used by the OpenGL renderer for the texture ID
|
||||
u32 texid;
|
||||
bool _suspectedInvalid;
|
||||
bool _assumedInvalid;
|
||||
bool _isLoadNeeded;
|
||||
|
||||
TexCacheItemDeleteCallback GetDeleteCallback() const;
|
||||
void SetDeleteCallback(TexCacheItemDeleteCallback callbackFunc, void *inParam1, void *inParam2);
|
||||
TextureCacheKey _cacheKey;
|
||||
size_t _cacheSize;
|
||||
size_t _cacheAge; // A value of 0 means the texture was just used. The higher this value, the older the texture.
|
||||
size_t _cacheUsageCount;
|
||||
|
||||
public:
|
||||
TextureStore();
|
||||
TextureStore(const u32 texAttributes, const u32 palAttributes);
|
||||
virtual ~TextureStore();
|
||||
|
||||
u32 GetTextureAttributes() const;
|
||||
u32 GetPaletteAttributes() const;
|
||||
|
||||
u32 GetWidth() const;
|
||||
u32 GetHeight() const;
|
||||
bool IsPalZeroTransparent() const;
|
||||
|
||||
NDSTextureFormat GetPackFormat() const;
|
||||
u32 GetPackAddress() const;
|
||||
u32 GetPackSize() const;
|
||||
u8* GetPackData();
|
||||
|
||||
u32 GetPaletteAddress() const;
|
||||
u32 GetPaletteSize() const;
|
||||
u16* GetPaletteColorTable() const;
|
||||
|
||||
u32 GetPackIndexAddress() const;
|
||||
u32 GetPackIndexSize() const;
|
||||
u8* GetPackIndexData();
|
||||
|
||||
NDSTextureFormat GetTextureFormat() const;
|
||||
void SetTextureData(const MemSpan &packedData, const MemSpan &packedIndexData);
|
||||
void SetTexturePalette(const MemSpan &packedPalette);
|
||||
void SetTexturePalette(const u16 *paletteBuffer);
|
||||
|
||||
size_t GetUnpackSizeUsingFormat(const TexCache_TexFormat texCacheFormat) const;
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void Unpack(u32 *unpackBuffer);
|
||||
size_t GetUnpackSizeUsingFormat(const TextureStoreUnpackFormat texCacheFormat) const;
|
||||
template<TextureStoreUnpackFormat TEXCACHEFORMAT> void Unpack(u32 *unpackBuffer);
|
||||
|
||||
bool IsSuspectedInvalid() const;
|
||||
void SetSuspectedInvalid();
|
||||
|
||||
bool IsAssumedInvalid() const;
|
||||
void SetAssumedInvalid();
|
||||
|
||||
void SetLoadNeeded();
|
||||
bool IsLoadNeeded() const;
|
||||
|
||||
TextureCacheKey GetCacheKey() const;
|
||||
|
||||
size_t GetCacheSize() const;
|
||||
void SetCacheSize(size_t cacheSize);
|
||||
|
||||
size_t GetCacheAge() const;
|
||||
void IncreaseCacheAge(const size_t ageAmount);
|
||||
void ResetCacheAge();
|
||||
|
||||
size_t GetCacheUseCount() const;
|
||||
void IncreaseCacheUsageCount(const size_t usageCount);
|
||||
void ResetCacheUsageCount();
|
||||
|
||||
void Update();
|
||||
void VRAMCompareAndUpdate();
|
||||
void DebugDump();
|
||||
};
|
||||
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackI2(const size_t srcSize, const u8 *__restrict srcData, const u16 *__restrict srcPal, const bool isPalZeroTransparent, u32 *__restrict dstBuffer);
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackI4(const size_t srcSize, const u8 *__restrict srcData, const u16 *__restrict srcPal, const bool isPalZeroTransparent, u32 *__restrict dstBuffer);
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackI8(const size_t srcSize, const u8 *__restrict srcData, const u16 *__restrict srcPal, const bool isPalZeroTransparent, u32 *__restrict dstBuffer);
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackA3I5(const size_t srcSize, const u8 *__restrict srcData, const u16 *__restrict srcPal, u32 *__restrict dstBuffer);
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackA5I3(const size_t srcSize, const u8 *__restrict srcData, const u16 *__restrict srcPal, u32 *__restrict dstBuffer);
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpack4x4(const size_t srcSize, const u32 *__restrict srcData, const u16 *__restrict srcIndex, const u32 palAddress, const u32 texAttributes, const u32 sizeX, const u32 sizeY, u32 *__restrict dstBuffer);
|
||||
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackDirect16Bit(const size_t srcSize, const u16 *__restrict srcData, u32 *__restrict dstBuffer);
|
||||
template<TextureStoreUnpackFormat TEXCACHEFORMAT> void NDSTextureUnpackI2(const size_t srcSize, const u8 *__restrict srcData, const u16 *__restrict srcPal, const bool isPalZeroTransparent, u32 *__restrict dstBuffer);
|
||||
template<TextureStoreUnpackFormat TEXCACHEFORMAT> void NDSTextureUnpackI4(const size_t srcSize, const u8 *__restrict srcData, const u16 *__restrict srcPal, const bool isPalZeroTransparent, u32 *__restrict dstBuffer);
|
||||
template<TextureStoreUnpackFormat TEXCACHEFORMAT> void NDSTextureUnpackI8(const size_t srcSize, const u8 *__restrict srcData, const u16 *__restrict srcPal, const bool isPalZeroTransparent, u32 *__restrict dstBuffer);
|
||||
template<TextureStoreUnpackFormat TEXCACHEFORMAT> void NDSTextureUnpackA3I5(const size_t srcSize, const u8 *__restrict srcData, const u16 *__restrict srcPal, u32 *__restrict dstBuffer);
|
||||
template<TextureStoreUnpackFormat TEXCACHEFORMAT> void NDSTextureUnpackA5I3(const size_t srcSize, const u8 *__restrict srcData, const u16 *__restrict srcPal, u32 *__restrict dstBuffer);
|
||||
template<TextureStoreUnpackFormat TEXCACHEFORMAT> void NDSTextureUnpack4x4(const size_t srcSize, const u32 *__restrict srcData, const u16 *__restrict srcIndex, const u32 palAddress, const u32 texAttributes, const u32 sizeX, const u32 sizeY, u32 *__restrict dstBuffer);
|
||||
template<TextureStoreUnpackFormat TEXCACHEFORMAT> void NDSTextureUnpackDirect16Bit(const size_t srcSize, const u16 *__restrict srcData, u32 *__restrict dstBuffer);
|
||||
|
||||
extern TexCache texCache;
|
||||
extern TextureCache texCache;
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue