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

Remove async frame buffer reads - it can cause glitches because of wrong frame read.

Example: F-1 PolePosition 99 car tuning menu.
This commit is contained in:
Sergey Lipskiy 2015-02-24 15:57:30 +06:00
parent 296476405a
commit 769ab7ac40
3 changed files with 26 additions and 41 deletions

View File

@ -31,16 +31,13 @@ class FrameBufferToRDRAM
{ {
public: public:
FrameBufferToRDRAM() : FrameBufferToRDRAM() :
m_FBO(0), m_pTexture(NULL), m_curIndex(0) m_FBO(0), m_PBO(0), m_pTexture(NULL)
{ {}
m_aAddress = 0;
m_aPBO[0] = m_aPBO[1] = 0;
}
void Init(); void Init();
void Destroy(); void Destroy();
void CopyToRDRAM( u32 address, bool bSync ); void CopyToRDRAM(u32 _address);
private: private:
struct RGBA { struct RGBA {
@ -48,10 +45,8 @@ private:
}; };
GLuint m_FBO; GLuint m_FBO;
GLuint m_PBO;
CachedTexture * m_pTexture; CachedTexture * m_pTexture;
u32 m_aAddress;
u32 m_curIndex;
GLuint m_aPBO[2];
}; };
class DepthBufferToRDRAM class DepthBufferToRDRAM
@ -679,36 +674,36 @@ void FrameBufferToRDRAM::Init()
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
// Generate and initialize Pixel Buffer Objects // Generate and initialize Pixel Buffer Objects
glGenBuffers(2, m_aPBO); glGenBuffers(1, &m_PBO);
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_aPBO[0]); glBindBuffer(GL_PIXEL_PACK_BUFFER, m_PBO);
glBufferData(GL_PIXEL_PACK_BUFFER, 640*480*4, NULL, GL_DYNAMIC_DRAW); glBufferData(GL_PIXEL_PACK_BUFFER, m_pTexture->textureBytes, NULL, GL_DYNAMIC_DRAW);
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_aPBO[1]);
glBufferData(GL_PIXEL_PACK_BUFFER, 640*480*4, NULL, GL_DYNAMIC_DRAW);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
} }
void FrameBufferToRDRAM::Destroy() { void FrameBufferToRDRAM::Destroy() {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &m_FBO); if (m_FBO != 0) {
m_FBO = 0; glDeleteFramebuffers(1, &m_FBO);
m_FBO = 0;
}
if (m_pTexture != NULL) { if (m_pTexture != NULL) {
textureCache().removeFrameBufferTexture(m_pTexture); textureCache().removeFrameBufferTexture(m_pTexture);
m_pTexture = NULL; m_pTexture = NULL;
} }
glDeleteBuffers(2, m_aPBO); if (m_PBO != 0) {
m_aPBO[0] = m_aPBO[1] = 0; glDeleteBuffers(1, &m_PBO);
m_curIndex = 0; m_PBO = 0;
m_aAddress = 0; }
} }
void FrameBufferToRDRAM::CopyToRDRAM( u32 address, bool bSync ) { void FrameBufferToRDRAM::CopyToRDRAM(u32 _address) {
if (VI.width == 0) // H width is zero. Don't copy if (VI.width == 0) // H width is zero. Don't copy
return; return;
FrameBuffer *pBuffer = frameBufferList().findBuffer(address); FrameBuffer *pBuffer = frameBufferList().findBuffer(_address);
if (pBuffer == NULL || pBuffer->m_width < VI.width) if (pBuffer == NULL || pBuffer->m_width < VI.width)
return; return;
address = pBuffer->m_startAddress; _address = pBuffer->m_startAddress;
if (config.video.multisampling != 0) { if (config.video.multisampling != 0) {
pBuffer->resolveMultisampledTexture(); pBuffer->resolveMultisampledTexture();
glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_resolveFBO); glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_resolveFBO);
@ -727,17 +722,8 @@ void FrameBufferToRDRAM::CopyToRDRAM( u32 address, bool bSync ) {
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_FBO); glBindFramebuffer(GL_READ_FRAMEBUFFER, m_FBO);
glReadBuffer(GL_COLOR_ATTACHMENT0); glReadBuffer(GL_COLOR_ATTACHMENT0);
#ifndef GLES2 #ifndef GLES2
// If Sync, read pixels from the buffer, copy them to RDRAM. glBindBuffer(GL_PIXEL_PACK_BUFFER, m_PBO);
// If not Sync, read pixels from the buffer, copy pixels from the previous buffer to RDRAM.
if (m_aAddress == 0)
bSync = true;
m_curIndex = (m_curIndex + 1) % 2;
const u32 nextIndex = bSync ? m_curIndex : (m_curIndex + 1) % 2;
m_aAddress = address;
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_aPBO[m_curIndex]);
glReadPixels( 0, 0, VI.width, VI.height, GL_RGBA, GL_UNSIGNED_BYTE, 0 ); glReadPixels( 0, 0, VI.width, VI.height, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_aPBO[nextIndex]);
GLubyte* pixelData = (GLubyte*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); GLubyte* pixelData = (GLubyte*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
if(pixelData == NULL) { if(pixelData == NULL) {
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
@ -745,7 +731,6 @@ void FrameBufferToRDRAM::CopyToRDRAM( u32 address, bool bSync ) {
} }
#else #else
m_curIndex = 0; m_curIndex = 0;
m_aAddress = address;
const u32 nextIndex = 0; const u32 nextIndex = 0;
GLubyte* pixelData = (GLubyte* )malloc(VI.width*VI.height*4); GLubyte* pixelData = (GLubyte* )malloc(VI.width*VI.height*4);
if(pixelData == NULL) if(pixelData == NULL)
@ -754,7 +739,7 @@ void FrameBufferToRDRAM::CopyToRDRAM( u32 address, bool bSync ) {
#endif // GLES2 #endif // GLES2
if (pBuffer->m_size == G_IM_SIZ_32b) { if (pBuffer->m_size == G_IM_SIZ_32b) {
u32 *ptr_dst = (u32*)(RDRAM + m_aAddress); u32 *ptr_dst = (u32*)(RDRAM + _address);
u32 *ptr_src = (u32*)pixelData; u32 *ptr_src = (u32*)pixelData;
for (u32 y = 0; y < VI.height; ++y) { for (u32 y = 0; y < VI.height; ++y) {
@ -762,7 +747,7 @@ void FrameBufferToRDRAM::CopyToRDRAM( u32 address, bool bSync ) {
ptr_dst[x + y*VI.width] = ptr_src[x + (VI.height - y - 1)*VI.width]; ptr_dst[x + y*VI.width] = ptr_src[x + (VI.height - y - 1)*VI.width];
} }
} else { } else {
u16 *ptr_dst = (u16*)(RDRAM + m_aAddress); u16 *ptr_dst = (u16*)(RDRAM + _address);
RGBA * ptr_src = (RGBA*)pixelData; RGBA * ptr_src = (RGBA*)pixelData;
for (u32 y = 0; y < VI.height; ++y) { for (u32 y = 0; y < VI.height; ++y) {
@ -772,7 +757,7 @@ void FrameBufferToRDRAM::CopyToRDRAM( u32 address, bool bSync ) {
} }
} }
} }
#if 1 //ndef GLES2 #ifndef GLES2
glUnmapBuffer(GL_PIXEL_PACK_BUFFER); glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
#else #else
@ -783,10 +768,10 @@ void FrameBufferToRDRAM::CopyToRDRAM( u32 address, bool bSync ) {
} }
#endif // GLES2 #endif // GLES2
void FrameBuffer_CopyToRDRAM( u32 address, bool bSync ) void FrameBuffer_CopyToRDRAM(u32 _address)
{ {
#ifndef GLES2 #ifndef GLES2
g_fbToRDRAM.CopyToRDRAM(address, bSync); g_fbToRDRAM.CopyToRDRAM(_address);
#endif #endif
} }

View File

@ -94,7 +94,7 @@ FrameBufferList & frameBufferList()
void FrameBuffer_Init(); void FrameBuffer_Init();
void FrameBuffer_Destroy(); void FrameBuffer_Destroy();
void FrameBuffer_CopyToRDRAM( u32 address, bool bSync ); void FrameBuffer_CopyToRDRAM( u32 _address );
void FrameBuffer_CopyFromRDRAM( u32 address, bool bUseAlpha ); void FrameBuffer_CopyFromRDRAM( u32 address, bool bUseAlpha );
bool FrameBuffer_CopyDepthBuffer( u32 address ); bool FrameBuffer_CopyDepthBuffer( u32 address );
void FrameBuffer_ActivateBufferTexture(s16 t, FrameBuffer *pBuffer); void FrameBuffer_ActivateBufferTexture(s16 t, FrameBuffer *pBuffer);

View File

@ -212,7 +212,7 @@ void RSP_ProcessDList()
} }
if (config.frameBufferEmulation.copyToRDRAM) if (config.frameBufferEmulation.copyToRDRAM)
FrameBuffer_CopyToRDRAM( gDP.colorImage.address, false ); FrameBuffer_CopyToRDRAM( gDP.colorImage.address );
if (config.frameBufferEmulation.copyDepthToRDRAM) if (config.frameBufferEmulation.copyDepthToRDRAM)
FrameBuffer_CopyDepthBuffer( gDP.colorImage.address ); FrameBuffer_CopyDepthBuffer( gDP.colorImage.address );