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;
|
_cacheSize = GetUnpackSizeUsingFormat(TexFormat_32bpp);
|
||||||
oglRenderer->DeleteTexture(texItem);
|
_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>
|
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.
|
// Kill the texture cache now before all of our texture IDs disappear.
|
||||||
texCache.Reset();
|
texCache.Reset();
|
||||||
|
|
||||||
while(!ref->freeTextureIDs.empty())
|
|
||||||
{
|
|
||||||
GLuint temp = ref->freeTextureIDs.front();
|
|
||||||
ref->freeTextureIDs.pop();
|
|
||||||
glDeleteTextures(1, &temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
glFinish();
|
glFinish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1352,7 +1377,6 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
|
||||||
INFO("OpenGL: Multisampled FBOs are unsupported. Multisample antialiasing will be disabled.\n");
|
INFO("OpenGL: Multisampled FBOs are unsupported. Multisample antialiasing will be disabled.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
this->InitTextures();
|
|
||||||
this->InitFinalRenderStates(&oglExtensionSet); // This must be done last
|
this->InitFinalRenderStates(&oglExtensionSet); // This must be done last
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
return OGLERROR_NOERR;
|
||||||
|
@ -2063,13 +2087,6 @@ Render3DError OpenGLRenderer_1_2::InitFinalRenderStates(const std::set<std::stri
|
||||||
return OGLERROR_NOERR;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
Render3DError OpenGLRenderer_1_2::InitTextures()
|
|
||||||
{
|
|
||||||
this->ExpandFreeTextures();
|
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
Render3DError OpenGLRenderer_1_2::InitTables()
|
Render3DError OpenGLRenderer_1_2::InitTables()
|
||||||
{
|
{
|
||||||
static bool needTableInit = true;
|
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()
|
Render3DError OpenGLRenderer_1_2::EnableVertexAttributes()
|
||||||
{
|
{
|
||||||
OGLRenderRef &OGLRef = *this->ref;
|
OGLRenderRef &OGLRef = *this->ref;
|
||||||
|
@ -2416,14 +2419,6 @@ Render3DError OpenGLRenderer_1_2::ReadBackPixels()
|
||||||
return OGLERROR_NOERR;
|
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)
|
Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
|
||||||
{
|
{
|
||||||
OGLRenderRef &OGLRef = *this->ref;
|
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)
|
Render3DError OpenGLRenderer_1_2::EndRender(const u64 frameCount)
|
||||||
{
|
{
|
||||||
//needs to happen before endgl because it could free some textureids for expired cache items
|
//needs to happen before endgl because it could free some textureids for expired cache items
|
||||||
texCache.Evict(TEXCACHE_MAX_SIZE);
|
texCache.Evict();
|
||||||
|
|
||||||
this->ReadBackPixels();
|
this->ReadBackPixels();
|
||||||
|
|
||||||
|
@ -2953,54 +2948,44 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
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
|
// Enable textures if they weren't already enabled
|
||||||
if (this->isShaderSupported)
|
if (this->isShaderSupported)
|
||||||
{
|
{
|
||||||
glUniform1i(OGLRef.uniformPolyEnableTexture, GL_TRUE);
|
glUniform1i(OGLRef.uniformPolyEnableTexture, GL_TRUE);
|
||||||
glUniform1i(OGLRef.uniformTexSingleBitAlpha, (theTexture->packFormat != TEXMODE_A3I5 && theTexture->packFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE);
|
glUniform1i(OGLRef.uniformTexSingleBitAlpha, (packFormat != TEXMODE_A3I5 && packFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE);
|
||||||
glUniform2f(OGLRef.uniformPolyTexScale, theTexture->invSizeX, theTexture->invSizeY);
|
glUniform2f(OGLRef.uniformPolyTexScale, theTexture->GetInvWidth(), theTexture->GetInvHeight());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glMatrixMode(GL_TEXTURE);
|
glMatrixMode(GL_TEXTURE);
|
||||||
glLoadIdentity();
|
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);
|
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;
|
const u32 *textureSrc = (u32 *)this->_workingTextureUnpackBuffer;
|
||||||
size_t texWidth = theTexture->sizeX;
|
size_t texWidth = theTexture->GetWidth();
|
||||||
size_t texHeight = theTexture->sizeY;
|
size_t texHeight = theTexture->GetHeight();
|
||||||
|
|
||||||
if (this->_textureDeposterizeDstSurface.Surface != NULL)
|
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_BASE_LEVEL, 0);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
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)
|
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, 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
|
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, 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;
|
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_BASE_LEVEL, 0);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
|
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)
|
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, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||||
|
|
||||||
texWidth = theTexture->sizeX;
|
texWidth = theTexture->GetWidth();
|
||||||
texHeight = theTexture->sizeY;
|
texHeight = theTexture->GetHeight();
|
||||||
this->TextureUpscale<2>(texFormat, textureSrc, texWidth, texHeight);
|
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, 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
|
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, 0, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||||
|
|
||||||
texWidth = theTexture->sizeX;
|
texWidth = theTexture->GetWidth();
|
||||||
texHeight = theTexture->sizeY;
|
texHeight = theTexture->GetHeight();
|
||||||
this->TextureUpscale<2>(texFormat, textureSrc, texWidth, texHeight);
|
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, 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;
|
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);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
theTexture->ResetCacheAge();
|
||||||
//otherwise, just bind it
|
theTexture->IncreaseCacheUsageCount(1);
|
||||||
glBindTexture(GL_TEXTURE_2D, (GLuint)theTexture->texid);
|
|
||||||
}
|
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
@ -3867,7 +3850,6 @@ Render3DError OpenGLRenderer_2_0::InitExtensions()
|
||||||
INFO("OpenGL: Multisampled FBOs are unsupported. Multisample antialiasing will be disabled.\n");
|
INFO("OpenGL: Multisampled FBOs are unsupported. Multisample antialiasing will be disabled.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
this->InitTextures();
|
|
||||||
this->InitFinalRenderStates(&oglExtensionSet); // This must be done last
|
this->InitFinalRenderStates(&oglExtensionSet); // This must be done last
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
return OGLERROR_NOERR;
|
||||||
|
@ -4644,42 +4626,32 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT
|
||||||
return OGLERROR_NOERR;
|
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.uniformPolyEnableTexture, GL_TRUE);
|
||||||
glUniform1i(OGLRef.uniformTexSingleBitAlpha, (theTexture->packFormat != TEXMODE_A3I5 && theTexture->packFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE);
|
glUniform1i(OGLRef.uniformTexSingleBitAlpha, (packFormat != TEXMODE_A3I5 && packFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE);
|
||||||
glUniform2f(OGLRef.uniformPolyTexScale, theTexture->invSizeX, theTexture->invSizeY);
|
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);
|
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;
|
const u32 *textureSrc = (u32 *)this->_workingTextureUnpackBuffer;
|
||||||
size_t texWidth = theTexture->sizeX;
|
size_t texWidth = theTexture->GetWidth();
|
||||||
size_t texHeight = theTexture->sizeY;
|
size_t texHeight = theTexture->GetHeight();
|
||||||
|
|
||||||
if (this->_textureDeposterizeDstSurface.Surface != NULL)
|
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_BASE_LEVEL, 0);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
||||||
|
|
||||||
|
this->TextureUpscale<2>(packFormat, textureSrc, texWidth, texHeight);
|
||||||
|
|
||||||
if (isNewTexture)
|
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, 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
|
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, 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;
|
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_BASE_LEVEL, 0);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
|
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)
|
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, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||||
|
|
||||||
texWidth = theTexture->sizeX;
|
texWidth = theTexture->GetWidth();
|
||||||
texHeight = theTexture->sizeY;
|
texHeight = theTexture->GetHeight();
|
||||||
this->TextureUpscale<2>(texFormat, textureSrc, texWidth, texHeight);
|
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, 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
|
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, 0, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||||
|
|
||||||
texWidth = theTexture->sizeX;
|
texWidth = theTexture->GetWidth();
|
||||||
texHeight = theTexture->sizeY;
|
texHeight = theTexture->GetHeight();
|
||||||
this->TextureUpscale<2>(texFormat, textureSrc, texWidth, texHeight);
|
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, 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;
|
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);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
theTexture->ResetCacheAge();
|
||||||
//otherwise, just bind it
|
theTexture->IncreaseCacheUsageCount(1);
|
||||||
glBindTexture(GL_TEXTURE_2D, (GLuint)theTexture->texid);
|
|
||||||
}
|
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "render3D.h"
|
#include "render3D.h"
|
||||||
|
#include "texcache.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#ifndef OGLRENDER_3_2_H
|
#ifndef OGLRENDER_3_2_H
|
||||||
|
@ -491,9 +492,6 @@ struct OGLRenderRef
|
||||||
GLuint vaoGeometryStatesID;
|
GLuint vaoGeometryStatesID;
|
||||||
GLuint vaoPostprocessStatesID;
|
GLuint vaoPostprocessStatesID;
|
||||||
|
|
||||||
// Textures
|
|
||||||
std::queue<GLuint> freeTextureIDs;
|
|
||||||
|
|
||||||
// Client-side Buffers
|
// Client-side Buffers
|
||||||
GLfloat *color4fBuffer;
|
GLfloat *color4fBuffer;
|
||||||
GLushort *vertIndexBuffer;
|
GLushort *vertIndexBuffer;
|
||||||
|
@ -526,8 +524,6 @@ extern CACHE_ALIGN const GLfloat divide6bitBy63_LUT[64];
|
||||||
extern const GLfloat PostprocessVtxBuffer[16];
|
extern const GLfloat PostprocessVtxBuffer[16];
|
||||||
extern const GLubyte PostprocessElementBuffer[6];
|
extern const GLubyte PostprocessElementBuffer[6];
|
||||||
|
|
||||||
extern void OGLTextureDeleteCallback(TexCacheItem *texItem, void *param1, void *param2);
|
|
||||||
|
|
||||||
//This is called by OGLRender whenever it initializes.
|
//This is called by OGLRender whenever it initializes.
|
||||||
//Platforms, please be sure to set this up.
|
//Platforms, please be sure to set this up.
|
||||||
//return true if you successfully init.
|
//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);
|
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)
|
#if defined(ENABLE_SSE2)
|
||||||
class OpenGLRenderer : public Render3D_SSE2
|
class OpenGLRenderer : public Render3D_SSE2
|
||||||
#else
|
#else
|
||||||
|
@ -609,7 +622,6 @@ protected:
|
||||||
virtual void DestroyGeometryProgram() = 0;
|
virtual void DestroyGeometryProgram() = 0;
|
||||||
virtual Render3DError CreateVAOs() = 0;
|
virtual Render3DError CreateVAOs() = 0;
|
||||||
virtual void DestroyVAOs() = 0;
|
virtual void DestroyVAOs() = 0;
|
||||||
virtual Render3DError InitTextures() = 0;
|
|
||||||
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet) = 0;
|
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet) = 0;
|
||||||
virtual Render3DError InitTables() = 0;
|
virtual Render3DError InitTables() = 0;
|
||||||
virtual Render3DError InitPostprocessingPrograms(const std::string &edgeMarkVtxShader,
|
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 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 void GetExtensionSet(std::set<std::string> *oglExtensionSet) = 0;
|
||||||
virtual Render3DError ExpandFreeTextures() = 0;
|
|
||||||
virtual Render3DError EnableVertexAttributes() = 0;
|
virtual Render3DError EnableVertexAttributes() = 0;
|
||||||
virtual Render3DError DisableVertexAttributes() = 0;
|
virtual Render3DError DisableVertexAttributes() = 0;
|
||||||
virtual Render3DError DownsampleFBO() = 0;
|
virtual Render3DError DownsampleFBO() = 0;
|
||||||
|
@ -648,7 +659,6 @@ public:
|
||||||
virtual ~OpenGLRenderer();
|
virtual ~OpenGLRenderer();
|
||||||
|
|
||||||
virtual Render3DError InitExtensions() = 0;
|
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 IsExtensionPresent(const std::set<std::string> *oglExtensionSet, const std::string extensionName) const;
|
||||||
bool ValidateShaderCompile(GLuint theShader) const;
|
bool ValidateShaderCompile(GLuint theShader) const;
|
||||||
|
@ -673,7 +683,6 @@ protected:
|
||||||
virtual void DestroyMultisampledFBO();
|
virtual void DestroyMultisampledFBO();
|
||||||
virtual Render3DError CreateVAOs();
|
virtual Render3DError CreateVAOs();
|
||||||
virtual void DestroyVAOs();
|
virtual void DestroyVAOs();
|
||||||
virtual Render3DError InitTextures();
|
|
||||||
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet);
|
virtual Render3DError InitFinalRenderStates(const std::set<std::string> *oglExtensionSet);
|
||||||
virtual Render3DError InitTables();
|
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 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 void GetExtensionSet(std::set<std::string> *oglExtensionSet);
|
||||||
virtual Render3DError ExpandFreeTextures();
|
|
||||||
virtual Render3DError EnableVertexAttributes();
|
virtual Render3DError EnableVertexAttributes();
|
||||||
virtual Render3DError DisableVertexAttributes();
|
virtual Render3DError DisableVertexAttributes();
|
||||||
virtual Render3DError DownsampleFBO();
|
virtual Render3DError DownsampleFBO();
|
||||||
|
@ -729,8 +737,6 @@ public:
|
||||||
virtual Render3DError Reset();
|
virtual Render3DError Reset();
|
||||||
virtual Render3DError RenderFinish();
|
virtual Render3DError RenderFinish();
|
||||||
virtual Render3DError SetFramebufferSize(size_t w, size_t h);
|
virtual Render3DError SetFramebufferSize(size_t w, size_t h);
|
||||||
|
|
||||||
virtual Render3DError DeleteTexture(const TexCacheItem *item);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class OpenGLRenderer_1_3 : public OpenGLRenderer_1_2
|
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
|
this->InitFinalRenderStates(&oglExtensionSet); // This must be done last
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
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)
|
Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableTexturing)
|
||||||
{
|
{
|
||||||
OGLRenderRef &OGLRef = *this->ref;
|
|
||||||
const PolygonTexParams params = thePoly.getTexParams();
|
const PolygonTexParams params = thePoly.getTexParams();
|
||||||
|
|
||||||
// Check if we need to use textures
|
// Check if we need to use textures
|
||||||
|
@ -1695,37 +1693,27 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT
|
||||||
return OGLERROR_NOERR;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
TexCacheItem *theTexture = texCache.GetTexture(thePoly.texParam, thePoly.texPalette);
|
OpenGLTexture *theTexture = (OpenGLTexture *)texCache.GetTexture(thePoly.texParam, thePoly.texPalette);
|
||||||
if (theTexture->unpackFormat != TexFormat_32bpp)
|
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);
|
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;
|
const u32 *textureSrc = (u32 *)this->_workingTextureUnpackBuffer;
|
||||||
size_t texWidth = theTexture->sizeX;
|
const NDSTextureFormat packFormat = theTexture->GetPackFormat();
|
||||||
size_t texHeight = theTexture->sizeY;
|
size_t texWidth = theTexture->GetWidth();
|
||||||
|
size_t texHeight = theTexture->GetHeight();
|
||||||
|
|
||||||
if (this->_textureDeposterizeDstSurface.Surface != NULL)
|
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_BASE_LEVEL, 0);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
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)
|
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, 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
|
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, 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;
|
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_BASE_LEVEL, 0);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
|
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)
|
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, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||||
|
|
||||||
texWidth = theTexture->sizeX;
|
texWidth = theTexture->GetWidth();
|
||||||
texHeight = theTexture->sizeY;
|
texHeight = theTexture->GetHeight();
|
||||||
this->TextureUpscale<2>(texFormat, textureSrc, texWidth, texHeight);
|
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, 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
|
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, 0, 0, 0, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, this->_textureUpscaleBuffer);
|
||||||
|
|
||||||
texWidth = theTexture->sizeX;
|
texWidth = theTexture->GetWidth();
|
||||||
texHeight = theTexture->sizeY;
|
texHeight = theTexture->GetHeight();
|
||||||
this->TextureUpscale<2>(texFormat, textureSrc, texWidth, texHeight);
|
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, 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;
|
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);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
theTexture->ResetCacheAge();
|
||||||
//otherwise, just bind it
|
theTexture->IncreaseCacheUsageCount(1);
|
||||||
glBindTexture(GL_TEXTURE_2D, (GLuint)theTexture->texid);
|
|
||||||
}
|
|
||||||
|
|
||||||
return OGLERROR_NOERR;
|
return OGLERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,6 @@
|
||||||
#include "matrix.h"
|
#include "matrix.h"
|
||||||
#include "render3D.h"
|
#include "render3D.h"
|
||||||
#include "gfx3d.h"
|
#include "gfx3d.h"
|
||||||
#include "texcache.h"
|
|
||||||
#include "MMU.h"
|
#include "MMU.h"
|
||||||
#include "NDSSystem.h"
|
#include "NDSSystem.h"
|
||||||
#include "utils/task.h"
|
#include "utils/task.h"
|
||||||
|
@ -331,7 +330,7 @@ class RasterizerUnit
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
SoftRasterizerRenderer *_softRender;
|
SoftRasterizerRenderer *_softRender;
|
||||||
TexCacheItem *lastTexKey;
|
SoftRasterizerTexture *lastTexKey;
|
||||||
VERT* verts[MAX_CLIPPED_VERTS];
|
VERT* verts[MAX_CLIPPED_VERTS];
|
||||||
int polynum;
|
int polynum;
|
||||||
|
|
||||||
|
@ -351,19 +350,16 @@ public:
|
||||||
int width, height;
|
int width, height;
|
||||||
s32 wmask, hmask;
|
s32 wmask, hmask;
|
||||||
int wrap;
|
int wrap;
|
||||||
int wshift;
|
|
||||||
int texFormat;
|
|
||||||
|
|
||||||
void setup(u32 texParam)
|
void setup(SoftRasterizerTexture *theTexture, u32 texParam)
|
||||||
{
|
{
|
||||||
texFormat = (texParam>>26)&7;
|
width = theTexture->GetRenderWidth();
|
||||||
wshift = ((texParam>>20)&0x07) + 3;
|
height = theTexture->GetRenderHeight();
|
||||||
width=(1 << wshift);
|
wmask = theTexture->GetRenderWidthMask();
|
||||||
height=(8 << ((texParam>>23)&0x07));
|
hmask = theTexture->GetRenderHeightMask();
|
||||||
wmask = width-1;
|
|
||||||
hmask = height-1;
|
|
||||||
wrap = (texParam>>16)&0xF;
|
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)
|
FORCEINLINE void clamp(s32 &val, const int size, const s32 sizemask)
|
||||||
|
@ -461,7 +457,10 @@ public:
|
||||||
|
|
||||||
sampler.dowrap(iu, iv);
|
sampler.dowrap(iu, iv);
|
||||||
FragmentColor color;
|
FragmentColor color;
|
||||||
color.color = lastTexKey->unpackData[(iv<<sampler.wshift)+iu];
|
const u32 *textureData = lastTexKey->GetUnpackData();
|
||||||
|
|
||||||
|
color.color = textureData[( iv << lastTexKey->GetRenderWidthShift() ) + iu];
|
||||||
|
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1006,15 +1005,15 @@ public:
|
||||||
const size_t dstWidth = this->_softRender->GetFramebufferWidth();
|
const size_t dstWidth = this->_softRender->GetFramebufferWidth();
|
||||||
const size_t dstHeight = this->_softRender->GetFramebufferHeight();
|
const size_t dstHeight = this->_softRender->GetFramebufferHeight();
|
||||||
|
|
||||||
lastTexKey = NULL;
|
|
||||||
|
|
||||||
const GFX3D_Clipper::TClippedPoly &firstClippedPoly = this->_softRender->clippedPolys[0];
|
const GFX3D_Clipper::TClippedPoly &firstClippedPoly = this->_softRender->clippedPolys[0];
|
||||||
const POLY &firstPoly = *firstClippedPoly.poly;
|
const POLY &firstPoly = *firstClippedPoly.poly;
|
||||||
PolygonAttributes polyAttr = firstPoly.getAttributes();
|
PolygonAttributes polyAttr = firstPoly.getAttributes();
|
||||||
u32 lastPolyAttr = firstPoly.polyAttr;
|
u32 lastPolyAttr = firstPoly.polyAttr;
|
||||||
u32 lastTexParams = firstPoly.texParam;
|
u32 lastTexParams = firstPoly.texParam;
|
||||||
u32 lastTexPalette = firstPoly.texPalette;
|
u32 lastTexPalette = firstPoly.texPalette;
|
||||||
sampler.setup(firstPoly.texParam);
|
|
||||||
|
lastTexKey = this->_softRender->polyTexKeys[0];
|
||||||
|
sampler.setup(lastTexKey, firstPoly.texParam);
|
||||||
|
|
||||||
//iterate over polys
|
//iterate over polys
|
||||||
for (size_t i = 0; i < polyCount; i++)
|
for (size_t i = 0; i < polyCount; i++)
|
||||||
|
@ -1035,13 +1034,15 @@ public:
|
||||||
|
|
||||||
if (lastTexParams != thePoly.texParam || lastTexPalette != thePoly.texPalette)
|
if (lastTexParams != thePoly.texParam || lastTexPalette != thePoly.texPalette)
|
||||||
{
|
{
|
||||||
sampler.setup(thePoly.texParam);
|
|
||||||
lastTexParams = thePoly.texParam;
|
lastTexParams = thePoly.texParam;
|
||||||
lastTexPalette = thePoly.texPalette;
|
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++)
|
for (int j = 0; j < type; j++)
|
||||||
this->verts[j] = &clippedPoly.clipVerts[j];
|
this->verts[j] = &clippedPoly.clipVerts[j];
|
||||||
for (int j = type; j < MAX_CLIPPED_VERTS; 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);
|
_cacheSize = GetUnpackSizeUsingFormat(TexFormat_15bpp);
|
||||||
texCache.cache_size -= texItem->unpackSize;
|
_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 = {
|
GPU3DInterface gpu3DRasterize = {
|
||||||
|
@ -1380,19 +1429,16 @@ void SoftRasterizerRenderer::setupTextures()
|
||||||
u32 lastTexParams = firstPoly.texParam;
|
u32 lastTexParams = firstPoly.texParam;
|
||||||
u32 lastTexPalette = firstPoly.texPalette;
|
u32 lastTexPalette = firstPoly.texPalette;
|
||||||
|
|
||||||
TexCacheItem *lastTexItem = texCache.GetTexture(firstPoly.texParam, firstPoly.texPalette);
|
SoftRasterizerTexture *lastTexItem = (SoftRasterizerTexture *)texCache.GetTexture(firstPoly.texParam, firstPoly.texPalette);
|
||||||
if (lastTexItem->unpackFormat != TexFormat_15bpp)
|
if (lastTexItem == NULL)
|
||||||
{
|
{
|
||||||
const bool isNewTexture = (lastTexItem->GetDeleteCallback() == NULL);
|
lastTexItem = new SoftRasterizerTexture(firstPoly.texParam, firstPoly.texPalette);
|
||||||
if (isNewTexture)
|
texCache.Add(lastTexItem);
|
||||||
{
|
}
|
||||||
lastTexItem->SetDeleteCallback(&SoftRasterizerTextureDeleteCallback, this, NULL);
|
|
||||||
lastTexItem->unpackSize = lastTexItem->GetUnpackSizeUsingFormat(TexFormat_15bpp);
|
if (lastTexItem->IsLoadNeeded())
|
||||||
lastTexItem->unpackData = (u32 *)malloc_alignedCacheLine(lastTexItem->unpackSize);
|
{
|
||||||
texCache.cache_size += lastTexItem->unpackSize;
|
lastTexItem->Unpack<TexFormat_15bpp>(lastTexItem->GetUnpackData());
|
||||||
}
|
|
||||||
|
|
||||||
lastTexItem->Unpack<TexFormat_15bpp>(lastTexItem->unpackData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < this->_clippedPolyCount; i++)
|
for (size_t i = 0; i < this->_clippedPolyCount; i++)
|
||||||
|
@ -1406,19 +1452,16 @@ void SoftRasterizerRenderer::setupTextures()
|
||||||
//and then it won't be safe.
|
//and then it won't be safe.
|
||||||
if (lastTexParams != thePoly.texParam || lastTexPalette != thePoly.texPalette)
|
if (lastTexParams != thePoly.texParam || lastTexPalette != thePoly.texPalette)
|
||||||
{
|
{
|
||||||
lastTexItem = texCache.GetTexture(thePoly.texParam, thePoly.texPalette);
|
lastTexItem = (SoftRasterizerTexture *)texCache.GetTexture(thePoly.texParam, thePoly.texPalette);
|
||||||
if (lastTexItem->unpackFormat != TexFormat_15bpp)
|
if (lastTexItem == NULL)
|
||||||
{
|
{
|
||||||
const bool isNewTexture = (lastTexItem->GetDeleteCallback() == NULL);
|
lastTexItem = new SoftRasterizerTexture(thePoly.texParam, thePoly.texPalette);
|
||||||
if (isNewTexture)
|
texCache.Add(lastTexItem);
|
||||||
{
|
}
|
||||||
lastTexItem->SetDeleteCallback(&SoftRasterizerTextureDeleteCallback, this, NULL);
|
|
||||||
lastTexItem->unpackSize = lastTexItem->GetUnpackSizeUsingFormat(TexFormat_15bpp);
|
if (lastTexItem->IsLoadNeeded())
|
||||||
lastTexItem->unpackData = (u32 *)malloc_alignedCacheLine(lastTexItem->unpackSize);
|
{
|
||||||
texCache.cache_size += lastTexItem->unpackSize;
|
lastTexItem->Unpack<TexFormat_15bpp>(lastTexItem->GetUnpackData());
|
||||||
}
|
|
||||||
|
|
||||||
lastTexItem->Unpack<TexFormat_15bpp>(lastTexItem->unpackData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lastTexParams = thePoly.texParam;
|
lastTexParams = thePoly.texParam;
|
||||||
|
@ -1571,7 +1614,7 @@ Render3DError SoftRasterizerRenderer::RenderGeometry(const GFX3D_State &renderSt
|
||||||
{
|
{
|
||||||
rasterizerUnit[0].mainLoop<false>();
|
rasterizerUnit[0].mainLoop<false>();
|
||||||
this->_renderGeometryNeedsFinish = 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);
|
// 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.
|
// Now that geometry rendering is finished on all threads, check the texture cache.
|
||||||
texCache.Evict(TEXCACHE_MAX_SIZE);
|
texCache.Evict();
|
||||||
|
|
||||||
// Do multithreaded post-processing.
|
// Do multithreaded post-processing.
|
||||||
if (this->currentRenderState->enableEdgeMarking || this->currentRenderState->enableFog)
|
if (this->currentRenderState->enableEdgeMarking || this->currentRenderState->enableFog)
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "render3D.h"
|
#include "render3D.h"
|
||||||
#include "gfx3d.h"
|
#include "gfx3d.h"
|
||||||
|
#include "texcache.h"
|
||||||
|
|
||||||
#define SOFTRASTERIZER_DEPTH_EQUAL_TEST_TOLERANCE 0x200
|
#define SOFTRASTERIZER_DEPTH_EQUAL_TEST_TOLERANCE 0x200
|
||||||
|
|
||||||
|
@ -39,6 +40,28 @@ struct SoftRasterizerPostProcessParams
|
||||||
bool fogAlphaOnly;
|
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)
|
#if defined(ENABLE_SSE2)
|
||||||
class SoftRasterizerRenderer : public Render3D_SSE2
|
class SoftRasterizerRenderer : public Render3D_SSE2
|
||||||
#else
|
#else
|
||||||
|
@ -75,7 +98,7 @@ public:
|
||||||
FragmentColor toonColor32LUT[32];
|
FragmentColor toonColor32LUT[32];
|
||||||
GFX3D_Clipper::TClippedPoly *clippedPolys;
|
GFX3D_Clipper::TClippedPoly *clippedPolys;
|
||||||
FragmentAttributesBuffer *_framebufferAttributes;
|
FragmentAttributesBuffer *_framebufferAttributes;
|
||||||
TexCacheItem *polyTexKeys[POLYLIST_SIZE];
|
SoftRasterizerTexture *polyTexKeys[POLYLIST_SIZE];
|
||||||
bool polyVisible[POLYLIST_SIZE];
|
bool polyVisible[POLYLIST_SIZE];
|
||||||
bool polyBackfacing[POLYLIST_SIZE];
|
bool polyBackfacing[POLYLIST_SIZE];
|
||||||
GFX3D_State *currentRenderState;
|
GFX3D_State *currentRenderState;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -21,25 +21,26 @@
|
||||||
#define _TEXCACHE_H_
|
#define _TEXCACHE_H_
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "gfx3d.h"
|
#include "gfx3d.h"
|
||||||
|
|
||||||
//this ought to be enough for anyone
|
//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
|
//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
|
//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
|
// 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.
|
// 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)
|
#define PALETTE_DUMP_SIZE ((64+16+16)*1024)
|
||||||
|
|
||||||
enum TexCache_TexFormat
|
enum TextureStoreUnpackFormat
|
||||||
{
|
{
|
||||||
TexFormat_None, //used when nothing yet is cached
|
TexFormat_None, //used when nothing yet is cached
|
||||||
TexFormat_32bpp, //used by ogl renderer
|
TexFormat_32bpp, //used by ogl renderer
|
||||||
|
@ -47,97 +48,142 @@ enum TexCache_TexFormat
|
||||||
};
|
};
|
||||||
|
|
||||||
class MemSpan;
|
class MemSpan;
|
||||||
class TexCacheItem;
|
class TextureStore;
|
||||||
|
|
||||||
typedef u64 TexCacheKey;
|
typedef u64 TextureCacheKey;
|
||||||
typedef std::map<TexCacheKey, TexCacheItem *> TexCacheTable;
|
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 void (*TexCacheItemDeleteCallback)(TexCacheItem *texItem, void *param1, void *param2);
|
typedef std::vector<TextureStore *> TextureCacheList;
|
||||||
|
//typedef u32 TextureFingerprint;
|
||||||
|
|
||||||
class TexCache
|
class TextureCache
|
||||||
{
|
{
|
||||||
public:
|
protected:
|
||||||
TexCache();
|
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 Invalidate();
|
||||||
void Evict(size_t target);
|
void Evict();
|
||||||
void Reset();
|
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:
|
protected:
|
||||||
TexCacheItemDeleteCallback _deleteCallback;
|
u32 _textureAttributes;
|
||||||
void *_deleteCallbackParam1;
|
u32 _paletteAttributes;
|
||||||
void *_deleteCallbackParam2;
|
|
||||||
|
|
||||||
public:
|
u32 _sizeS;
|
||||||
TexCacheItem();
|
u32 _sizeT;
|
||||||
TexCacheItem(const u32 texAttributes, const u32 palAttributes);
|
bool _isPalZeroTransparent;
|
||||||
~TexCacheItem();
|
|
||||||
|
|
||||||
u32 textureAttributes;
|
NDSTextureFormat _packFormat;
|
||||||
u32 paletteAttributes;
|
u32 _packAddress;
|
||||||
|
u32 _packSize;
|
||||||
|
u8 *_packData;
|
||||||
|
|
||||||
u32 sizeX;
|
u32 _paletteAddress;
|
||||||
u32 sizeY;
|
u32 _paletteSize;
|
||||||
float invSizeX;
|
u16 *_paletteColorTable;
|
||||||
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;
|
|
||||||
|
|
||||||
// Only used by 4x4 formatted textures
|
// Only used by 4x4 formatted textures
|
||||||
u32 packIndexAddress;
|
u32 _packIndexAddress;
|
||||||
u32 packIndexSize;
|
u32 _packIndexSize;
|
||||||
u8 *packIndexData;
|
u8 *_packIndexData;
|
||||||
u32 packSizeFirstSlot;
|
u32 _packSizeFirstSlot;
|
||||||
|
|
||||||
// Only used by the OpenGL renderer for the texture ID
|
bool _suspectedInvalid;
|
||||||
u32 texid;
|
bool _assumedInvalid;
|
||||||
|
bool _isLoadNeeded;
|
||||||
|
|
||||||
TexCacheItemDeleteCallback GetDeleteCallback() const;
|
TextureCacheKey _cacheKey;
|
||||||
void SetDeleteCallback(TexCacheItemDeleteCallback callbackFunc, void *inParam1, void *inParam2);
|
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 SetTextureData(const MemSpan &packedData, const MemSpan &packedIndexData);
|
||||||
|
void SetTexturePalette(const MemSpan &packedPalette);
|
||||||
void SetTexturePalette(const u16 *paletteBuffer);
|
void SetTexturePalette(const u16 *paletteBuffer);
|
||||||
|
|
||||||
size_t GetUnpackSizeUsingFormat(const TexCache_TexFormat texCacheFormat) const;
|
size_t GetUnpackSizeUsingFormat(const TextureStoreUnpackFormat texCacheFormat) const;
|
||||||
template<TexCache_TexFormat TEXCACHEFORMAT> void Unpack(u32 *unpackBuffer);
|
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();
|
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<TextureStoreUnpackFormat 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<TextureStoreUnpackFormat 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<TextureStoreUnpackFormat 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<TextureStoreUnpackFormat 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<TextureStoreUnpackFormat 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<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<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackDirect16Bit(const size_t srcSize, const u16 *__restrict srcData, 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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue