From 4a9e7cdc1f657d0397a9480ec35f3213bfe0f817 Mon Sep 17 00:00:00 2001 From: Sergey Lipskiy Date: Mon, 9 Mar 2015 15:28:43 +0600 Subject: [PATCH] New FB validity check based on checksum of RDRAM content. --- FrameBuffer.cpp | 23 ++++++++++++++++------- FrameBuffer.h | 3 +-- gDP.cpp | 44 +++++++++++++++++++++++--------------------- 3 files changed, 40 insertions(+), 30 deletions(-) diff --git a/FrameBuffer.cpp b/FrameBuffer.cpp index 34b0f7b0..b7d880b7 100644 --- a/FrameBuffer.cpp +++ b/FrameBuffer.cpp @@ -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); diff --git a/FrameBuffer.h b/FrameBuffer.h index eb146fbf..216602fb 100644 --- a/FrameBuffer.h +++ b/FrameBuffer.h @@ -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; diff --git a/gDP.cpp b/gDP.cpp index a56b5876..99c38f6e 100644 --- a/gDP.cpp +++ b/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); } }