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:
parent
0b0adb2f5e
commit
4a9e7cdc1f
|
@ -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);
|
||||
|
|
|
@ -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
44
gDP.cpp
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user