Texture Handler:

- Rework TexCacheItem::GetTexture() so that instantiating a new object, dumping the packed data, and dumping the palette are performed as separate operations.
- Invalid OpenGL textures are now updated instead of being completely replaced.
- NDSTextureUnpack4x4() now uses the srcIndex pointer parameter instead of recalculating the palette address.
- Delete the now obsolete MemSpan-based texture unpacking functions.
This commit is contained in:
rogerman 2016-11-02 07:25:11 +00:00
parent 2c82d4b7b4
commit df60214b26
5 changed files with 502 additions and 1007 deletions

View File

@ -871,7 +871,6 @@ OpenGLRenderer::OpenGLRenderer()
ref->fboPostprocessID = 0; ref->fboPostprocessID = 0;
ref->selectedRenderingFBO = 0; ref->selectedRenderingFBO = 0;
currTexture = NULL;
_mappedFramebuffer = NULL; _mappedFramebuffer = NULL;
_pixelReadNeedsFinish = false; _pixelReadNeedsFinish = false;
_currentPolyIndex = 0; _currentPolyIndex = 0;
@ -2418,10 +2417,6 @@ Render3DError OpenGLRenderer_1_2::ReadBackPixels()
Render3DError OpenGLRenderer_1_2::DeleteTexture(const TexCacheItem *item) Render3DError OpenGLRenderer_1_2::DeleteTexture(const TexCacheItem *item)
{ {
this->ref->freeTextureIDs.push((GLuint)item->texid); this->ref->freeTextureIDs.push((GLuint)item->texid);
if(this->currTexture == item)
{
this->currTexture = NULL;
}
return OGLERROR_NOERR; return OGLERROR_NOERR;
} }
@ -2956,47 +2951,50 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
return OGLERROR_NOERR; return OGLERROR_NOERR;
} }
TexCacheItem *theTexture = texCache.GetTexture(thePoly.texParam, thePoly.texPalette);
// 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, (params.texFormat != TEXMODE_A3I5 && params.texFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE); glUniform1i(OGLRef.uniformTexSingleBitAlpha, (theTexture->packFormat != TEXMODE_A3I5 && theTexture->packFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE);
glUniform2f(OGLRef.uniformPolyTexScale, theTexture->invSizeX, theTexture->invSizeY);
} }
else else
{ {
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glScalef(theTexture->invSizeX, theTexture->invSizeY, 1.0f);
} }
TexCacheItem *newTexture = texCache.GetTexture(thePoly.texParam, thePoly.texPalette); if (theTexture->unpackFormat != TexFormat_32bpp)
if (newTexture->unpackFormat != TexFormat_32bpp)
{ {
newTexture->Unpack<TexFormat_32bpp>(); theTexture->Unpack<TexFormat_32bpp>();
}
if (newTexture != this->currTexture)
{
this->currTexture = newTexture;
//has the ogl renderer initialized the texture? //has the ogl renderer initialized the texture?
if (this->currTexture->GetDeleteCallback() == NULL) const bool isNewTexture = (theTexture->GetDeleteCallback() == NULL);
if (isNewTexture)
{ {
this->currTexture->SetDeleteCallback(&texDeleteCallback, this, NULL); theTexture->SetDeleteCallback(&texDeleteCallback, this, NULL);
if (OGLRef.freeTextureIDs.empty()) if (OGLRef.freeTextureIDs.empty())
{ {
this->ExpandFreeTextures(); this->ExpandFreeTextures();
} }
this->currTexture->texid = (u32)OGLRef.freeTextureIDs.front(); theTexture->texid = (u32)OGLRef.freeTextureIDs.front();
OGLRef.freeTextureIDs.pop(); OGLRef.freeTextureIDs.pop();
}
glBindTexture(GL_TEXTURE_2D, (GLuint)this->currTexture->texid); 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_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)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (params.enableRepeatT ? (params.enableMirroredRepeatT ? OGLRef.stateTexMirroredRepeat : GL_REPEAT) : GL_CLAMP_TO_EDGE));
const NDSTextureFormat texFormat = this->currTexture->GetTextureFormat(); const NDSTextureFormat texFormat = theTexture->GetTextureFormat();
const u32 *textureSrc = this->currTexture->unpackData; const u32 *textureSrc = theTexture->unpackData;
size_t texWidth = this->currTexture->sizeX; size_t texWidth = theTexture->sizeX;
size_t texHeight = this->currTexture->sizeY; size_t texHeight = theTexture->sizeY;
if (this->_textureDeposterizeDstSurface.Surface != NULL) if (this->_textureDeposterizeDstSurface.Surface != NULL)
{ {
@ -3007,10 +3005,20 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
switch (this->_textureScalingFactor) switch (this->_textureScalingFactor)
{ {
case 1: case 1:
{
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, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc);
if (isNewTexture)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 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, textureSrc);
}
break; break;
}
case 2: case 2:
{ {
@ -3018,9 +3026,17 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
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>(texFormat, textureSrc, texWidth, texHeight);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, this->currTexture->sizeX, this->currTexture->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc); 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);
}
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);
}
break; break;
} }
@ -3030,14 +3046,29 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
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>(texFormat, textureSrc, texWidth, texHeight);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
texWidth = this->currTexture->sizeX; if (isNewTexture)
texHeight = this->currTexture->sizeY; {
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); this->TextureUpscale<2>(texFormat, textureSrc, texWidth, texHeight);
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 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, this->currTexture->sizeX, this->currTexture->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc); glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, theTexture->sizeX, theTexture->sizeY, 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);
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);
}
break; break;
} }
@ -3061,19 +3092,7 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
else else
{ {
//otherwise, just bind it //otherwise, just bind it
glBindTexture(GL_TEXTURE_2D, (GLuint)this->currTexture->texid); glBindTexture(GL_TEXTURE_2D, (GLuint)theTexture->texid);
}
if (this->isShaderSupported)
{
glUniform2f(OGLRef.uniformPolyTexScale, this->currTexture->invSizeX, this->currTexture->invSizeY);
}
else
{
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glScalef(this->currTexture->invSizeX, this->currTexture->invSizeY, 1.0f);
}
} }
return OGLERROR_NOERR; return OGLERROR_NOERR;
@ -3126,7 +3145,6 @@ Render3DError OpenGLRenderer_1_2::Reset()
memset(OGLRef.vertIndexBuffer, 0, OGLRENDER_VERT_INDEX_BUFFER_COUNT * sizeof(GLushort)); memset(OGLRef.vertIndexBuffer, 0, OGLRENDER_VERT_INDEX_BUFFER_COUNT * sizeof(GLushort));
} }
this->currTexture = NULL;
this->_currentPolyIndex = 0; this->_currentPolyIndex = 0;
OGLRef.vtxPtrPosition = (GLvoid *)offsetof(VERT, coord); OGLRef.vtxPtrPosition = (GLvoid *)offsetof(VERT, coord);
@ -4620,39 +4638,39 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT
return OGLERROR_NOERR; return OGLERROR_NOERR;
} }
TexCacheItem *theTexture = texCache.GetTexture(thePoly.texParam, thePoly.texPalette);
glUniform1i(OGLRef.uniformPolyEnableTexture, GL_TRUE); glUniform1i(OGLRef.uniformPolyEnableTexture, GL_TRUE);
glUniform1i(OGLRef.uniformTexSingleBitAlpha, (params.texFormat != TEXMODE_A3I5 && params.texFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE); glUniform1i(OGLRef.uniformTexSingleBitAlpha, (theTexture->packFormat != TEXMODE_A3I5 && theTexture->packFormat != TEXMODE_A5I3) ? GL_TRUE : GL_FALSE);
glUniform2f(OGLRef.uniformPolyTexScale, theTexture->invSizeX, theTexture->invSizeY);
TexCacheItem *newTexture = texCache.GetTexture(thePoly.texParam, thePoly.texPalette); if (theTexture->unpackFormat != TexFormat_32bpp)
if (newTexture->unpackFormat != TexFormat_32bpp)
{ {
newTexture->Unpack<TexFormat_32bpp>(); theTexture->Unpack<TexFormat_32bpp>();
}
if (newTexture != this->currTexture)
{
this->currTexture = newTexture;
//has the ogl renderer initialized the texture? //has the ogl renderer initialized the texture?
if (this->currTexture->GetDeleteCallback() == NULL) const bool isNewTexture = (theTexture->GetDeleteCallback() == NULL);
if (isNewTexture)
{ {
this->currTexture->SetDeleteCallback(&texDeleteCallback, this, NULL); theTexture->SetDeleteCallback(&texDeleteCallback, this, NULL);
if (OGLRef.freeTextureIDs.empty()) if (OGLRef.freeTextureIDs.empty())
{ {
this->ExpandFreeTextures(); this->ExpandFreeTextures();
} }
this->currTexture->texid = (u32)OGLRef.freeTextureIDs.front(); theTexture->texid = (u32)OGLRef.freeTextureIDs.front();
OGLRef.freeTextureIDs.pop(); OGLRef.freeTextureIDs.pop();
}
glBindTexture(GL_TEXTURE_2D, (GLuint)this->currTexture->texid); 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_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)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (params.enableRepeatT ? (params.enableMirroredRepeatT ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE));
const NDSTextureFormat texFormat = this->currTexture->GetTextureFormat(); const NDSTextureFormat texFormat = theTexture->GetTextureFormat();
const u32 *textureSrc = this->currTexture->unpackData; const u32 *textureSrc = theTexture->unpackData;
size_t texWidth = this->currTexture->sizeX; size_t texWidth = theTexture->sizeX;
size_t texHeight = this->currTexture->sizeY; size_t texHeight = theTexture->sizeY;
if (this->_textureDeposterizeDstSurface.Surface != NULL) if (this->_textureDeposterizeDstSurface.Surface != NULL)
{ {
@ -4663,20 +4681,36 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT
switch (this->_textureScalingFactor) switch (this->_textureScalingFactor)
{ {
case 1: case 1:
{
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, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc);
if (isNewTexture)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 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, textureSrc);
}
break; break;
}
case 2: case 2:
{ {
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); if (isNewTexture)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 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, this->currTexture->sizeX, this->currTexture->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc); glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, theTexture->sizeX, theTexture->sizeY, 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);
}
break; break;
} }
@ -4686,14 +4720,29 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT
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>(texFormat, textureSrc, texWidth, texHeight);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
texWidth = this->currTexture->sizeX; if (isNewTexture)
texHeight = this->currTexture->sizeY; {
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); this->TextureUpscale<2>(texFormat, textureSrc, texWidth, texHeight);
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 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, this->currTexture->sizeX, this->currTexture->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc); glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, theTexture->sizeX, theTexture->sizeY, 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);
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);
}
break; break;
} }
@ -4717,10 +4766,7 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT
else else
{ {
//otherwise, just bind it //otherwise, just bind it
glBindTexture(GL_TEXTURE_2D, (GLuint)this->currTexture->texid); glBindTexture(GL_TEXTURE_2D, (GLuint)theTexture->texid);
}
glUniform2f(OGLRef.uniformPolyTexScale, this->currTexture->invSizeX, this->currTexture->invSizeY);
} }
return OGLERROR_NOERR; return OGLERROR_NOERR;

View File

@ -588,9 +588,6 @@ protected:
bool willFlipFramebufferOnGPU; bool willFlipFramebufferOnGPU;
bool willConvertFramebufferOnGPU; bool willConvertFramebufferOnGPU;
// Textures
TexCacheItem *currTexture;
FragmentColor *_mappedFramebuffer; FragmentColor *_mappedFramebuffer;
bool _pixelReadNeedsFinish; bool _pixelReadNeedsFinish;
size_t _currentPolyIndex; size_t _currentPolyIndex;

View File

@ -1695,36 +1695,34 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT
return OGLERROR_NOERR; return OGLERROR_NOERR;
} }
TexCacheItem *newTexture = texCache.GetTexture(thePoly.texParam, thePoly.texPalette); TexCacheItem *theTexture = texCache.GetTexture(thePoly.texParam, thePoly.texPalette);
if (newTexture->unpackFormat != TexFormat_32bpp) if (theTexture->unpackFormat != TexFormat_32bpp)
{ {
newTexture->Unpack<TexFormat_32bpp>(); theTexture->Unpack<TexFormat_32bpp>();
}
if (newTexture != this->currTexture)
{
this->currTexture = newTexture;
//has the ogl renderer initialized the texture? //has the ogl renderer initialized the texture?
if (this->currTexture->GetDeleteCallback() == NULL) const bool isNewTexture = (theTexture->GetDeleteCallback() == NULL);
if (isNewTexture)
{ {
this->currTexture->SetDeleteCallback(&texDeleteCallback, this, NULL); theTexture->SetDeleteCallback(&texDeleteCallback, this, NULL);
if (OGLRef.freeTextureIDs.empty()) if (OGLRef.freeTextureIDs.empty())
{ {
this->ExpandFreeTextures(); this->ExpandFreeTextures();
} }
this->currTexture->texid = (u32)OGLRef.freeTextureIDs.front(); theTexture->texid = (u32)OGLRef.freeTextureIDs.front();
OGLRef.freeTextureIDs.pop(); OGLRef.freeTextureIDs.pop();
}
glBindTexture(GL_TEXTURE_2D, (GLuint)this->currTexture->texid); 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_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)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (params.enableRepeatT ? (params.enableMirroredRepeatT ? GL_MIRRORED_REPEAT : GL_REPEAT) : GL_CLAMP_TO_EDGE));
const NDSTextureFormat texFormat = this->currTexture->GetTextureFormat(); const NDSTextureFormat texFormat = theTexture->GetTextureFormat();
const u32 *textureSrc = this->currTexture->unpackData; const u32 *textureSrc = theTexture->unpackData;
size_t texWidth = this->currTexture->sizeX; size_t texWidth = theTexture->sizeX;
size_t texHeight = this->currTexture->sizeY; size_t texHeight = theTexture->sizeY;
if (this->_textureDeposterizeDstSurface.Surface != NULL) if (this->_textureDeposterizeDstSurface.Surface != NULL)
{ {
@ -1735,10 +1733,20 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT
switch (this->_textureScalingFactor) switch (this->_textureScalingFactor)
{ {
case 1: case 1:
{
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, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc);
if (isNewTexture)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 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, textureSrc);
}
break; break;
}
case 2: case 2:
{ {
@ -1746,9 +1754,17 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT
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>(texFormat, textureSrc, texWidth, texHeight);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, this->currTexture->sizeX, this->currTexture->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc); 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);
}
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);
}
break; break;
} }
@ -1758,14 +1774,29 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT
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>(texFormat, textureSrc, texWidth, texHeight);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->_textureUpscaleBuffer);
texWidth = this->currTexture->sizeX; if (isNewTexture)
texHeight = this->currTexture->sizeY; {
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); this->TextureUpscale<2>(texFormat, textureSrc, texWidth, texHeight);
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 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, this->currTexture->sizeX, this->currTexture->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureSrc); glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, theTexture->sizeX, theTexture->sizeY, 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);
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);
}
break; break;
} }
@ -1789,8 +1820,7 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT
else else
{ {
//otherwise, just bind it //otherwise, just bind it
glBindTexture(GL_TEXTURE_2D, (GLuint)this->currTexture->texid); glBindTexture(GL_TEXTURE_2D, (GLuint)theTexture->texid);
}
} }
return OGLERROR_NOERR; return OGLERROR_NOERR;

File diff suppressed because it is too large Load Diff

View File

@ -78,34 +78,39 @@ private:
public: public:
TexCacheItem(); TexCacheItem();
TexCacheItem(const u32 texAttributes, const u32 palAttributes);
~TexCacheItem(); ~TexCacheItem();
u32 textureAttributes;
u32 paletteAttributes;
u32 sizeX;
u32 sizeY;
float invSizeX;
float invSizeY;
bool isPalZeroTransparent;
bool suspectedInvalid;
bool assumedInvalid;
NDSTextureFormat packFormat; NDSTextureFormat packFormat;
u32 packAddress;
u32 packSize; u32 packSize;
u8 *packData; u8 *packData;
u32 paletteAddress;
u32 paletteSize;
u16 *paletteColorTable; u16 *paletteColorTable;
bool isPalZeroTransparent;
TexCache_TexFormat unpackFormat; TexCache_TexFormat unpackFormat;
u32 unpackSize; u32 unpackSize;
u32 *unpackData; u32 *unpackData;
bool suspectedInvalid;
bool assumedInvalid;
u32 textureAttributes;
u32 paletteAttributes;
u32 paletteAddress;
u32 paletteSize;
u32 sizeX;
u32 sizeY;
float invSizeX;
float invSizeY;
// Only used by 4x4 formatted textures // Only used by 4x4 formatted textures
u32 packIndexAddress;
u32 packIndexSize;
u8 *packIndexData; u8 *packIndexData;
u32 packSizeFirstSlot; u32 packSizeFirstSlot;
u32 packIndexSize;
// Only used by the OpenGL renderer for the texture ID // Only used by the OpenGL renderer for the texture ID
u32 texid; u32 texid;
@ -114,30 +119,21 @@ public:
void SetDeleteCallback(TexCacheItemDeleteCallback callbackFunc, void *inParam1, void *inParam2); void SetDeleteCallback(TexCacheItemDeleteCallback callbackFunc, void *inParam1, void *inParam2);
NDSTextureFormat GetTextureFormat() const; NDSTextureFormat GetTextureFormat() const;
void SetTextureData(const u32 attr, const MemSpan &packedData, const MemSpan &packedIndexData); void SetTextureData(const MemSpan &packedData, const MemSpan &packedIndexData);
void SetTexturePalette(const u32 attr, const u16 *paletteBuffer); void SetTexturePalette(const u16 *paletteBuffer);
template<TexCache_TexFormat TEXCACHEFORMAT> void Unpack(); template<TexCache_TexFormat TEXCACHEFORMAT> void Unpack();
void DebugDump(); void DebugDump();
}; };
// TODO: Delete these MemSpan based functions after testing confirms that using the dumped texture data works properly.
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackI2(const MemSpan &ms, const u16 *pal, const bool isPalZeroTransparent, u32 *dstBuffer);
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackI4(const MemSpan &ms, const u16 *pal, const bool isPalZeroTransparent, u32 *dstBuffer);
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackI8(const MemSpan &ms, const u16 *pal, const bool isPalZeroTransparent, u32 *dstBuffer);
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackA3I5(const MemSpan &ms, const u16 *pal, u32 *dstBuffer);
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackA5I3(const MemSpan &ms, const u16 *pal, u32 *dstBuffer);
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpack4x4(const MemSpan &ms, const u32 palAddress, const u32 texAttributes, const u32 sizeX, const u32 sizeY, u32 *dstBuffer);
template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackDirect16Bit(const MemSpan &ms, u32 *dstBuffer);
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 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 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 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 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 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 u8 *__restrict srcData, const u8 *__restrict srcIndex, const u32 palAddress, const u32 texAttributes, const u32 sizeX, const u32 sizeY, 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 u8 *__restrict srcData, u32 *__restrict dstBuffer); template<TexCache_TexFormat TEXCACHEFORMAT> void NDSTextureUnpackDirect16Bit(const size_t srcSize, const u16 *__restrict srcData, u32 *__restrict dstBuffer);
extern TexCache texCache; extern TexCache texCache;