1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-02 09:03:37 +00:00

Rewrite fix for #1539 : keep in tile descriptor start address of frame buffer, not pointer on it.

Should be more safe.
This commit is contained in:
Sergey Lipskiy 2017-09-29 22:24:30 +07:00
parent 203c53307d
commit 70c540b073
8 changed files with 40 additions and 28 deletions

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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)

View File

@ -93,7 +93,7 @@ struct gDPTile
u32 textureMode;
u32 loadType;
u32 imageAddress;
FrameBuffer *frameBuffer;
u32 frameBufferAddress;
};
struct gDPLoadTileInfo {

View File

@ -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;