1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-04 10:03:36 +00:00

New FB validity check based on checksum of RDRAM content.

This commit is contained in:
Sergey Lipskiy 2015-03-09 15:28:43 +06:00
parent 0b0adb2f5e
commit 4a9e7cdc1f
3 changed files with 40 additions and 30 deletions

View File

@ -95,7 +95,9 @@ DepthBufferToRDRAM g_dbToRDRAM;
#endif
RDRAMtoFrameBuffer g_RDRAMtoFB;
FrameBuffer::FrameBuffer() : m_cleared(false), m_changed(false), m_isDepthBuffer(false), m_copiedToRDRAM(false), m_needHeightCorrection(false), m_pLoadTile(NULL), m_pDepthBuffer(NULL), m_pResolveTexture(NULL), m_resolveFBO(0), m_resolved(false)
FrameBuffer::FrameBuffer() : m_RdramCrc(0), m_validityChecked(0), m_cleared(false), m_changed(false), m_isDepthBuffer(false),
m_needHeightCorrection(false), m_pLoadTile(NULL), m_pDepthBuffer(NULL),
m_pResolveTexture(NULL), m_resolveFBO(0), m_resolved(false)
{
m_pTexture = textureCache().addFrameBufferTexture();
glGenFramebuffers(1, &m_FBO);
@ -105,7 +107,7 @@ FrameBuffer::FrameBuffer(FrameBuffer && _other) :
m_startAddress(_other.m_startAddress), m_endAddress(_other.m_endAddress),
m_size(_other.m_size), m_width(_other.m_width), m_height(_other.m_height), m_fillcolor(_other.m_fillcolor),
m_scaleX(_other.m_scaleX), m_scaleY(_other.m_scaleY), m_cleared(_other.m_cleared), m_changed(_other.m_changed), m_cfb(_other.m_cfb), m_isDepthBuffer(_other.m_isDepthBuffer),
m_copiedToRDRAM(_other.m_copiedToRDRAM), m_needHeightCorrection(_other.m_needHeightCorrection),
m_RdramCrc(_other.m_RdramCrc), m_needHeightCorrection(_other.m_needHeightCorrection), m_validityChecked(_other.m_validityChecked),
m_FBO(_other.m_FBO), m_pLoadTile(_other.m_pLoadTile), m_pTexture(_other.m_pTexture), m_pDepthBuffer(_other.m_pDepthBuffer),
m_pResolveTexture(_other.m_pResolveTexture), m_resolveFBO(_other.m_resolveFBO), m_resolved(_other.m_resolved)
{
@ -328,7 +330,7 @@ void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _widt
if (m_pCurrent->m_width == VI.width)
gDP.colorImage.height = min(gDP.colorImage.height, VI.height);
m_pCurrent->m_endAddress = min(RDRAMSize, m_pCurrent->m_startAddress + (((m_pCurrent->m_width * gDP.colorImage.height) << m_pCurrent->m_size >> 1) - 1));
if (!config.frameBufferEmulation.copyToRDRAM && !config.frameBufferEmulation.copyFromRDRAM && !m_pCurrent->m_cfb && !m_pCurrent->m_cleared && gDP.colorImage.height > 1)
if (!config.frameBufferEmulation.copyFromRDRAM && m_pCurrent->m_RdramCrc == 0 && !m_pCurrent->m_cfb && !m_pCurrent->m_cleared && gDP.colorImage.height > 1)
gDPFillRDRAM(m_pCurrent->m_startAddress, 0, 0, m_pCurrent->m_width, gDP.colorImage.height, m_pCurrent->m_width, m_pCurrent->m_size, m_pCurrent->m_fillcolor, false);
}
@ -384,9 +386,8 @@ void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _widt
if (!_cfb)
*(u32*)&RDRAM[m_pCurrent->m_startAddress] = m_pCurrent->m_startAddress;
m_pCurrent->m_cleared = false;
m_pCurrent->m_isDepthBuffer = false;
m_pCurrent->m_copiedToRDRAM = false;
m_pCurrent->m_cleared = m_pCurrent->m_isDepthBuffer = false;
m_pCurrent->m_RdramCrc = m_pCurrent->m_validityChecked = 0;
gSP.changed |= CHANGED_TEXTURE;
}
@ -796,7 +797,8 @@ void FrameBufferToRDRAM::CopyToRDRAM(u32 _address) {
}
}
}
pBuffer->m_copiedToRDRAM = true;
pBuffer->m_RdramCrc = CRC_Calculate(0xFFFFFFFF, RDRAM + _address, (VI.width*VI.height) << pBuffer->m_size>>1);
pBuffer->m_cleared = false;
#ifndef GLES2
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
@ -949,6 +951,13 @@ bool DepthBufferToRDRAM::CopyToRDRAM( u32 _address) {
}
}
pDepthBuffer->m_cleared = false;
pBuffer = frameBufferList().findBuffer(pDepthBuffer->m_address);
if (pBuffer != NULL) {
pBuffer->m_RdramCrc = CRC_Calculate(0xFFFFFFFF, RDRAM + pDepthBuffer->m_address, (VI.width*VI.height) << pBuffer->m_size >> 1);
pBuffer->m_cleared = false;
}
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);

View File

@ -18,13 +18,12 @@ struct FrameBuffer
CachedTexture * getTexture();
u32 m_startAddress, m_endAddress;
u32 m_size, m_width, m_height, m_fillcolor;
u32 m_size, m_width, m_height, m_fillcolor, m_RdramCrc, m_validityChecked;
float m_scaleX, m_scaleY;
bool m_cleared;
bool m_changed;
bool m_cfb;
bool m_isDepthBuffer;
bool m_copiedToRDRAM;
bool m_needHeightCorrection;
GLuint m_FBO;

44
gDP.cpp
View File

@ -520,39 +520,41 @@ bool CheckForFrameBufferTexture(u32 _address, u32 _bytes)
//&& ((*(u32*)&RDRAM[pBuffer->startAddress] & 0xFFFEFFFE) == (pBuffer->startAddress & 0xFFFEFFFE)) // Does not work for Jet Force Gemini
)
{
if (noDepthBuffers && gDP.colorImage.address == gDP.depthImageAddress && pBuffer->m_copiedToRDRAM)
{
if (noDepthBuffers && gDP.colorImage.address == gDP.depthImageAddress && pBuffer->m_RdramCrc != 0) {
memcpy(RDRAM + gDP.depthImageAddress, RDRAM + pBuffer->m_startAddress, (pBuffer->m_width*pBuffer->m_height) << pBuffer->m_size >> 1);
pBuffer->m_copiedToRDRAM = false;
pBuffer->m_RdramCrc = 0;
}
const u32 texEndAddress = _address + _bytes - 1;
u32 height = (int)gDP.scissor.lry;
if (height % 2 != 0)
++height;
const u32 bufEndAddress = pBuffer->m_startAddress + (((pBuffer->m_width * height) << pBuffer->m_size >> 1) - 1);
if (_address > pBuffer->m_startAddress && texEndAddress > bufEndAddress) {
// FrameBuffer_RemoveBuffer(pBuffer->startAddress);
if (_address > pBuffer->m_startAddress && texEndAddress > (pBuffer->m_endAddress + (pBuffer->m_width << pBuffer->m_size >> 1))) {
//frameBufferList().removeBuffer(pBuffer->m_startAddress);
bRes = false;
}
if (bRes && gDP.loadTile->loadType == LOADTYPE_TILE && gDP.textureImage.width != pBuffer->m_width && gDP.textureImage.size != pBuffer->m_size) {
//FrameBuffer_RemoveBuffer(pBuffer->startAddress); // Does not work with Zelda MM
//frameBufferList().removeBuffer(pBuffer->m_startAddress); // Does not work with Zelda MM
bRes = false;
}
if (bRes && pBuffer->m_cleared && pBuffer->m_size == 2
&& !config.frameBufferEmulation.copyToRDRAM
&& (!config.frameBufferEmulation.copyDepthToRDRAM || pBuffer->m_fillcolor != DepthClearColor)
) {
const u32 endAddress = min(texEndAddress, pBuffer->m_endAddress);
const u32 color = pBuffer->m_fillcolor&0xFFFEFFFE;
for (u32 i = _address + 4; i < endAddress; i+=4) {
if (((*(u32*)&RDRAM[i])&0xFFFEFFFE) != color) {
frameBufferList().removeBuffer(pBuffer->m_startAddress);
bRes = false;
break;
if (bRes && pBuffer->m_validityChecked != RSP.DList) {
if (pBuffer->m_cleared) {
const u32 color = pBuffer->m_fillcolor & 0xFFFEFFFE;
for (u32 i = pBuffer->m_startAddress + 4; i < pBuffer->m_endAddress; i += 4) {
if (((*(u32*)&RDRAM[i]) & 0xFFFEFFFE) != color) {
frameBufferList().removeBuffer(pBuffer->m_startAddress);
bRes = false;
break;
}
}
if (bRes)
pBuffer->m_validityChecked = RSP.DList;
} else if (pBuffer->m_RdramCrc != 0) {
const u32 crc = CRC_Calculate(0xFFFFFFFF, RDRAM + pBuffer->m_startAddress, (VI.width*VI.height) << pBuffer->m_size >> 1);
bRes = (pBuffer->m_RdramCrc == crc);
if (bRes)
pBuffer->m_validityChecked = RSP.DList;
else
frameBufferList().removeBuffer(pBuffer->m_startAddress);
}
}