The mipmap data in some games seems to being sent behind the base textures, and when the base textures are bound and created the mipmap chain is not yet valid in memory. To fix this, we invalidate the base textures, when the mipmap chain is updated.

This commit is contained in:
Ian Curtis 2017-03-25 00:06:24 +00:00
parent 06c1cdcf94
commit ff624afb4d
8 changed files with 36 additions and 22 deletions

View file

@ -14,7 +14,7 @@ public:
virtual void RenderFrame(void) = 0;
virtual void BeginFrame(void) = 0;
virtual void EndFrame(void) = 0;
virtual void UploadTextures(unsigned x, unsigned y, unsigned width, unsigned height) = 0;
virtual void UploadTextures(unsigned level, unsigned x, unsigned y, unsigned width, unsigned height) = 0;
virtual void AttachMemory(const uint32_t *cullingRAMLoPtr, const uint32_t *cullingRAMHiPtr, const uint32_t *polyRAMPtr, const uint32_t *vromPtr, const uint16_t *textureRAMPtr) = 0;
virtual void SetStep(int stepID) = 0;
virtual bool Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yRes, unsigned totalXRes, unsigned totalYRes) = 0;

View file

@ -380,7 +380,7 @@ void CLegacy3D::DecodeTexture(int format, int x, int y, int width, int height)
}
// Signals that new textures have been uploaded. Flushes model caches. Be careful not to exceed bounds!
void CLegacy3D::UploadTextures(unsigned x, unsigned y, unsigned width, unsigned height)
void CLegacy3D::UploadTextures(unsigned level, unsigned x, unsigned y, unsigned width, unsigned height)
{
#ifdef DEBUG
// Make everything red
@ -1285,7 +1285,7 @@ bool CLegacy3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned
glLoadIdentity();
// Mark all textures as dirty
UploadTextures(0,0,2048,2048);
UploadTextures(0, 0, 0, 2048, 2048);
DebugLog("Legacy3D initialized\n");
return OKAY;

View file

@ -293,7 +293,7 @@ public:
* width Width of texture data in texels.
* height Height.
*/
void UploadTextures(unsigned x, unsigned y, unsigned width, unsigned height);
void UploadTextures(unsigned level, unsigned x, unsigned y, unsigned width, unsigned height);
/*
* AttachMemory(cullingRAMLoPtr, cullingRAMHiPtr, polyRAMPtr, vromPtr,

View file

@ -72,15 +72,27 @@ bool CNew3D::Init(unsigned xOffset, unsigned yOffset, unsigned xRes, unsigned yR
return OKAY; // OKAY ? wtf ..
}
void CNew3D::UploadTextures(unsigned x, unsigned y, unsigned width, unsigned height)
void CNew3D::UploadTextures(unsigned level, unsigned x, unsigned y, unsigned width, unsigned height)
{
if (x >= 1024) {
if (y >= 512 && y < 1024 || y >= 1536 && y < 2048) {
return;
}
}
if (level == 0) {
m_texSheet.Invalidate(x, y, width, height); // base textures only
}
else if (level == 1) {
// we want to work out what the base level is, and invalidate the entire texture
// the mipmap data in some cases is being sent later
m_texSheet.Invalidate(x, y, width, height);
int page = y / 1024;
y -= (page * 1024); // remove page from tex y
int xPos = (x - 1024) * 2;
int yPos = (y - 512) * 2;
yPos += page * 1024;
width *= 2;
height *= 2;
m_texSheet.Invalidate(xPos, yPos, width, height);
}
}
void CNew3D::DrawScrollFog()

View file

@ -83,7 +83,7 @@ public:
* width Width of texture data in texels.
* height Height.
*/
void UploadTextures(unsigned x, unsigned y, unsigned width, unsigned height);
void UploadTextures(unsigned level, unsigned x, unsigned y, unsigned width, unsigned height);
/*
* AttachMemory(cullingRAMLoPtr, cullingRAMHiPtr, polyRAMPtr, vromPtr,

View file

@ -369,7 +369,7 @@ void Texture::CreateTextureObject(int format, bool mirrorU, bool mirrorV, int x,
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, count); // 0-5 (real3d only uses 6 possible mipmap levels)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, count);
m_x = x;
m_y = y;

View file

@ -113,7 +113,7 @@ void CReal3D::LoadState(CBlockFile *SaveState)
// If multi-threaded, update read-only snapshots too
if (g_Config.gpuMultiThreaded)
UpdateSnapshots(true);
Render3D->UploadTextures(0, 0, 2048, 2048);
Render3D->UploadTextures(0, 0, 0, 2048, 2048);
SaveState->Read(&fifoIdx, sizeof(fifoIdx));
SaveState->Read(&m_vromTextureFIFO, sizeof(m_vromTextureFIFO));
@ -233,7 +233,7 @@ void CReal3D::BeginFrame(void)
if (g_Config.gpuMultiThreaded)
{
for (const auto &it : queuedUploadTexturesRO) {
Render3D->UploadTextures(it.x, it.y, it.width, it.height);
Render3D->UploadTextures(it.level, it.x, it.y, it.width, it.height);
}
// done syncing data
@ -617,7 +617,7 @@ static void StoreTexelByte(uint16_t *texel, uint32_t byteSelect, uint8_t byte)
*texel = (*texel & 0x00FF) | (uint16_t(byte) << 8);
}
void CReal3D::StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigned height, const uint16_t *texData, uint32_t header)
void CReal3D::StoreTexture(unsigned level, unsigned xPos, unsigned yPos, unsigned width, unsigned height, const uint16_t *texData, uint32_t header)
{
if ((header & 0x00800000)) // 16-bit textures
{
@ -690,6 +690,7 @@ void CReal3D::StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigne
{
// If multi-threaded, then queue calls to UploadTextures for render thread to perform at beginning of next frame
QueuedUploadTextures upl;
upl.level = level;
upl.x = xPos;
upl.y = yPos;
upl.width = width;
@ -697,7 +698,7 @@ void CReal3D::StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigne
queuedUploadTextures.push_back(upl);
}
else
Render3D->UploadTextures(xPos, yPos, width, height);
Render3D->UploadTextures(level, xPos, yPos, width, height);
}
// Texture data will be in little endian format
@ -731,7 +732,7 @@ void CReal3D::UploadTexture(uint32_t header, const uint16_t *texData)
{
case 0x00: // texture w/ mipmaps
{
StoreTexture(x, y, width, height, texData, header);
StoreTexture(0, x, y, width, height, texData, header);
uint32_t mipWidth = width;
uint32_t mipHeight = height;
uint32_t mipNum = 0;
@ -749,12 +750,12 @@ void CReal3D::UploadTexture(uint32_t header, const uint16_t *texData)
if(page)
mipY += 1024;
mipNum++;
StoreTexture(mipX, mipY, mipWidth, mipHeight, (uint16_t *) texData, header);
StoreTexture(mipNum, mipX, mipY, mipWidth, mipHeight, (uint16_t *)texData, header);
}
break;
}
case 0x01: // texture w/out mipmaps
StoreTexture(x, y, width, height, texData, header);
StoreTexture(0, x, y, width, height, texData, header);
break;
case 0x02: // mipmaps only
{
@ -770,7 +771,7 @@ void CReal3D::UploadTexture(uint32_t header, const uint16_t *texData)
if(page)
mipY += 1024;
mipNum++;
StoreTexture(mipX, mipY, mipWidth, mipHeight, texData, header);
StoreTexture(mipNum, mipX, mipY, mipWidth, mipHeight, texData, header);
if (bytesPerTexel == 1)
texData += (mipWidth*mipHeight)/2;
else

View file

@ -40,6 +40,7 @@
*/
struct QueuedUploadTextures
{
unsigned level; // mipmap level of the texture, saves calculating this later
unsigned x;
unsigned y;
unsigned width;
@ -383,7 +384,7 @@ private:
void InsertBit(uint8_t *buf, unsigned bitNum, unsigned bit);
void InsertID(uint32_t id, unsigned startBit);
unsigned Shift(uint8_t *data, unsigned numBits);
void StoreTexture(unsigned xPos, unsigned yPos, unsigned width, unsigned height, const uint16_t *texData, uint32_t header);
void StoreTexture(unsigned level, unsigned xPos, unsigned yPos, unsigned width, unsigned height, const uint16_t *texData, uint32_t header);
void UploadTexture(uint32_t header, const uint16_t *texData);
uint32_t UpdateSnapshots(bool copyWhole);
uint32_t UpdateSnapshot(bool copyWhole, uint8_t *src, uint8_t *dst, unsigned size, uint8_t *dirty);