From 70c540b0737d9a2a37aa1cdebc7781a199676600 Mon Sep 17 00:00:00 2001 From: Sergey Lipskiy Date: Fri, 29 Sep 2017 22:24:30 +0700 Subject: [PATCH] Rewrite fix for #1539 : keep in tile descriptor start address of frame buffer, not pointer on it. Should be more safe. --- src/FrameBuffer.cpp | 19 ++++++++++++------ src/FrameBuffer.h | 5 +++-- .../glsl_CombinerProgramUniformFactory.cpp | 20 +++++++++++-------- src/GraphicsDrawer.cpp | 4 ++-- src/Textures.cpp | 4 ++-- src/gDP.cpp | 10 +++++----- src/gDP.h | 2 +- src/gSP.cpp | 4 ++-- 8 files changed, 40 insertions(+), 28 deletions(-) diff --git a/src/FrameBuffer.cpp b/src/FrameBuffer.cpp index 3db61d16..8727f441 100644 --- a/src/FrameBuffer.cpp +++ b/src/FrameBuffer.cpp @@ -46,10 +46,6 @@ FrameBuffer::FrameBuffer() : FrameBuffer::~FrameBuffer() { - for (u32 i = 0; i < 8; ++i) { - if (gDP.tiles[i].frameBuffer == this) - gDP.tiles[i].frameBuffer = nullptr; - } gfxContext.deleteFramebuffer(m_FBO); gfxContext.deleteFramebuffer(m_resolveFBO); gfxContext.deleteFramebuffer(m_SubFBO); @@ -519,6 +515,15 @@ FrameBuffer * FrameBufferList::findBuffer(u32 _startAddress) return nullptr; } +FrameBuffer * FrameBufferList::getBuffer(u32 _startAddress) +{ + for (auto iter = m_list.begin(); iter != m_list.end(); ++iter) { + if (iter->m_startAddress == _startAddress) + return &(*iter); + } + return nullptr; +} + inline bool isOverlapping(const FrameBuffer * _buf1, const FrameBuffer * _buf2) { @@ -1243,8 +1248,9 @@ void FrameBufferList::fillRDRAM(s32 ulx, s32 uly, s32 lrx, s32 lry) m_pCurrent->setBufferClearParams(gDP.fillColor.color, ulx, uly, lrx, lry); } -void FrameBuffer_ActivateBufferTexture(u32 t, FrameBuffer *pBuffer) +void FrameBuffer_ActivateBufferTexture(u32 t, u32 _frameBufferAddress) { + FrameBuffer * pBuffer = frameBufferList().getBuffer(_frameBufferAddress); if (pBuffer == nullptr) return; @@ -1257,8 +1263,9 @@ void FrameBuffer_ActivateBufferTexture(u32 t, FrameBuffer *pBuffer) gDP.changed |= CHANGED_FB_TEXTURE; } -void FrameBuffer_ActivateBufferTextureBG(u32 t, FrameBuffer *pBuffer ) +void FrameBuffer_ActivateBufferTextureBG(u32 t, u32 _frameBufferAddress) { + FrameBuffer * pBuffer = frameBufferList().getBuffer(_frameBufferAddress); if (pBuffer == nullptr) return; diff --git a/src/FrameBuffer.h b/src/FrameBuffer.h index b149a09c..4bf54f86 100644 --- a/src/FrameBuffer.h +++ b/src/FrameBuffer.h @@ -89,6 +89,7 @@ public: void attachDepthBuffer(); void clearDepthBuffer(DepthBuffer * _pDepthBuffer); FrameBuffer * findBuffer(u32 _startAddress); + FrameBuffer * getBuffer(u32 _startAddress); FrameBuffer * findTmpBuffer(u32 _address); FrameBuffer * getCurrent() const {return m_pCurrent;} void renderBuffer(); @@ -138,7 +139,7 @@ void FrameBuffer_CopyFromRDRAM(u32 address, bool bUseAlpha); void FrameBuffer_AddAddress(u32 address, u32 _size); bool FrameBuffer_CopyDepthBuffer(u32 address); bool FrameBuffer_CopyDepthBufferChunk(u32 address); -void FrameBuffer_ActivateBufferTexture(u32 t, FrameBuffer *pBuffer); -void FrameBuffer_ActivateBufferTextureBG(u32 t, FrameBuffer *pBuffer); +void FrameBuffer_ActivateBufferTexture(u32 t, u32 _frameBufferAddress); +void FrameBuffer_ActivateBufferTextureBG(u32 t, u32 _frameBufferAddress); #endif diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactory.cpp b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactory.cpp index 21f3b44f..69496c26 100644 --- a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactory.cpp +++ b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramUniformFactory.cpp @@ -710,24 +710,28 @@ public: if (!m_useTile[t]) continue; - if (gSP.textureTile[t] != NULL) { + if (gSP.textureTile[t] != nullptr) { if (gSP.textureTile[t]->textureMode == TEXTUREMODE_BGIMAGE || gSP.textureTile[t]->textureMode == TEXTUREMODE_FRAMEBUFFER_BG) uTexOffset[t].set(0.0f, 0.0f, _force); else { float fuls = gSP.textureTile[t]->fuls; float fult = gSP.textureTile[t]->fult; - FrameBuffer * pBuffer = gSP.textureTile[t]->frameBuffer; - if (pBuffer != NULL) { - if (gSP.textureTile[t]->masks > 0 && gSP.textureTile[t]->clamps == 0) - fuls = float(gSP.textureTile[t]->uls % (1 << gSP.textureTile[t]->masks)); - if (gSP.textureTile[t]->maskt > 0 && gSP.textureTile[t]->clampt == 0) - fult = float(gSP.textureTile[t]->ult % (1 << gSP.textureTile[t]->maskt)); + if (gSP.textureTile[t]->frameBufferAddress > 0) { + FrameBuffer * pBuffer = frameBufferList().getBuffer(gSP.textureTile[t]->frameBufferAddress); + if (pBuffer != nullptr) { + if (gSP.textureTile[t]->masks > 0 && gSP.textureTile[t]->clamps == 0) + fuls = float(gSP.textureTile[t]->uls % (1 << gSP.textureTile[t]->masks)); + if (gSP.textureTile[t]->maskt > 0 && gSP.textureTile[t]->clampt == 0) + fult = float(gSP.textureTile[t]->ult % (1 << gSP.textureTile[t]->maskt)); + } else { + gSP.textureTile[t]->frameBufferAddress = 0; + } } uTexOffset[t].set(fuls, fult, _force); } } - if (cache.current[t] != NULL) { + if (cache.current[t] != nullptr) { f32 shiftScaleS = 1.0f; f32 shiftScaleT = 1.0f; getTextureShiftScale(t, cache, shiftScaleS, shiftScaleT); diff --git a/src/GraphicsDrawer.cpp b/src/GraphicsDrawer.cpp index d9b24988..310aa010 100644 --- a/src/GraphicsDrawer.cpp +++ b/src/GraphicsDrawer.cpp @@ -1002,7 +1002,7 @@ static bool texturedRectCopyToItself(const GraphicsDrawer::TexturedRectParams & _params) { FrameBuffer * pCurrent = frameBufferList().getCurrent(); - if (pCurrent != nullptr && pCurrent->m_size == G_IM_SIZ_8b && gSP.textureTile[0]->frameBuffer == pCurrent) + if (pCurrent != nullptr && pCurrent->m_size == G_IM_SIZ_8b && gSP.textureTile[0]->frameBufferAddress == pCurrent->m_startAddress) return true; return texturedRectDepthBufferCopy(_params); } @@ -1050,7 +1050,7 @@ bool texturedRectPaletteMod(const GraphicsDrawer::TexturedRectParams & _params) if (gDP.textureImage.width == 64) { gDPTile & curTile = gDP.tiles[0]; - curTile.frameBuffer = nullptr; + curTile.frameBufferAddress = 0; curTile.textureMode = TEXTUREMODE_NORMAL; textureCache().update(0); currentCombiner()->update(false); diff --git a/src/Textures.cpp b/src/Textures.cpp index 67d7be87..c4036f95 100644 --- a/src/Textures.cpp +++ b/src/Textures.cpp @@ -1490,10 +1490,10 @@ void TextureCache::update(u32 _t) _updateBackground(); return; case TEXTUREMODE_FRAMEBUFFER: - FrameBuffer_ActivateBufferTexture( _t, pTile->frameBuffer ); + FrameBuffer_ActivateBufferTexture( _t, pTile->frameBufferAddress ); return; case TEXTUREMODE_FRAMEBUFFER_BG: - FrameBuffer_ActivateBufferTextureBG( _t, pTile->frameBuffer ); + FrameBuffer_ActivateBufferTextureBG( _t, pTile->frameBufferAddress ); return; } diff --git a/src/gDP.cpp b/src/gDP.cpp index 5081140c..f5357ad5 100644 --- a/src/gDP.cpp +++ b/src/gDP.cpp @@ -273,7 +273,7 @@ void gDPSetTile( u32 format, u32 size, u32 line, u32 tmem, u32 tile, u32 palette if (nTile > gSP.texture.tile + 1) { gDP.tiles[tile].textureMode = gDP.tiles[nTile].textureMode; gDP.tiles[tile].loadType = gDP.tiles[nTile].loadType; - gDP.tiles[tile].frameBuffer = gDP.tiles[nTile].frameBuffer; + gDP.tiles[tile].frameBufferAddress = gDP.tiles[nTile].frameBufferAddress; gDP.tiles[tile].imageAddress = gDP.tiles[nTile].imageAddress; } } @@ -326,7 +326,7 @@ static bool CheckForFrameBufferTexture(u32 _address, u32 _bytes) { gDP.loadTile->textureMode = TEXTUREMODE_NORMAL; - gDP.loadTile->frameBuffer = nullptr; + gDP.loadTile->frameBufferAddress = 0U; gDP.changed |= CHANGED_TMEM; if (!config.frameBufferEmulation.enable) return false; @@ -376,7 +376,7 @@ bool CheckForFrameBufferTexture(u32 _address, u32 _bytes) pBuffer->m_loadType = gDP.loadTile->loadType; pBuffer->m_loadTileOrigin.uls = gDP.loadTile->uls; pBuffer->m_loadTileOrigin.ult = gDP.loadTile->ult; - gDP.loadTile->frameBuffer = pBuffer; + gDP.loadTile->frameBufferAddress = pBuffer->m_startAddress; gDP.loadTile->textureMode = TEXTUREMODE_FRAMEBUFFER; } } @@ -386,7 +386,7 @@ bool CheckForFrameBufferTexture(u32 _address, u32 _bytes) gDPTile & curTile = gDP.tiles[nTile]; curTile.textureMode = gDP.loadTile->textureMode; curTile.loadType = gDP.loadTile->loadType; - curTile.frameBuffer = gDP.loadTile->frameBuffer; + curTile.frameBufferAddress = gDP.loadTile->frameBufferAddress; curTile.imageAddress = gDP.loadTile->imageAddress; } } @@ -578,7 +578,7 @@ void gDPLoadBlock(u32 tile, u32 uls, u32 ult, u32 lrs, u32 dxt) return; } - gDP.loadTile->frameBuffer = nullptr; + gDP.loadTile->frameBufferAddress = 0; CheckForFrameBufferTexture(address, bytes); // Load data to TMEM even if FB texture is found. See comment to texturedRectDepthBufferCopy if (gDP.loadTile->size == G_IM_SIZ_32b) diff --git a/src/gDP.h b/src/gDP.h index 0ac6684a..8c93e3a0 100644 --- a/src/gDP.h +++ b/src/gDP.h @@ -93,7 +93,7 @@ struct gDPTile u32 textureMode; u32 loadType; u32 imageAddress; - FrameBuffer *frameBuffer; + u32 frameBufferAddress; }; struct gDPLoadTileInfo { diff --git a/src/gSP.cpp b/src/gSP.cpp index 1435c689..f3434673 100644 --- a/src/gSP.cpp +++ b/src/gSP.cpp @@ -2523,7 +2523,7 @@ void _loadBGImage(const uObjScaleBg * _bgInfo, bool _loadScale) return; } - gDP.tiles[0].frameBuffer = pBuffer; + gDP.tiles[0].frameBufferAddress = pBuffer->m_startAddress; gDP.tiles[0].textureMode = TEXTUREMODE_FRAMEBUFFER_BG; gDP.tiles[0].loadType = LOADTYPE_TILE; gDP.changed |= CHANGED_TMEM; @@ -2660,7 +2660,7 @@ void _loadSpriteImage(const uSprite *_pSprite) { FrameBuffer *pBuffer = frameBufferList().findBuffer(gSP.bgImage.address); if (pBuffer != nullptr) { - gDP.tiles[0].frameBuffer = pBuffer; + gDP.tiles[0].frameBufferAddress = pBuffer->m_startAddress; gDP.tiles[0].textureMode = TEXTUREMODE_FRAMEBUFFER_BG; gDP.tiles[0].loadType = LOADTYPE_TILE; gDP.changed |= CHANGED_TMEM;