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

code refactoring to support async buffer reads

Copy of color buffers is now always done in gDPFullSync. There are no
known disadvantages only advantages. Quake 2 will run faster
This commit is contained in:
purplemarshmallow 2015-10-31 04:11:33 +01:00 committed by Sergey Lipskiy
parent dc3da06a68
commit 142ad0bc3c
4 changed files with 33 additions and 29 deletions

View File

@ -23,15 +23,15 @@ class FrameBufferToRDRAM
{ {
public: public:
FrameBufferToRDRAM() : FrameBufferToRDRAM() :
m_bSync(true), m_FBO(0), m_pTexture(NULL), m_curIndex(0) m_FBO(0), m_pTexture(NULL), m_curIndex(0)
{ {
m_aPBO[0] = m_aPBO[1] = 0; m_PBO[0] = m_PBO[1] = m_PBO[2] = 0;
} }
void Init(); void Init();
void Destroy(); void Destroy();
void CopyToRDRAM(u32 _address); void CopyToRDRAM(u32 _address, bool _sync);
private: private:
union RGBA { union RGBA {
@ -41,11 +41,10 @@ private:
u32 raw; u32 raw;
}; };
bool m_bSync;
GLuint m_FBO; GLuint m_FBO;
CachedTexture * m_pTexture; CachedTexture * m_pTexture;
u32 m_curIndex; u32 m_curIndex;
GLuint m_aPBO[2]; GLuint m_PBO[3];
}; };
class DepthBufferToRDRAM class DepthBufferToRDRAM
@ -460,7 +459,7 @@ void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _widt
{ {
if (m_pCurrent != NULL && config.frameBufferEmulation.copyAuxToRDRAM != 0) { if (m_pCurrent != NULL && config.frameBufferEmulation.copyAuxToRDRAM != 0) {
if (m_pCurrent->m_width != VI.width) { if (m_pCurrent->m_width != VI.width) {
FrameBuffer_CopyToRDRAM(m_pCurrent->m_startAddress); FrameBuffer_CopyToRDRAM(m_pCurrent->m_startAddress, true);
removeBuffer(m_pCurrent->m_startAddress); removeBuffer(m_pCurrent->m_startAddress);
} }
} }
@ -549,7 +548,7 @@ void FrameBufferList::copyAux()
{ {
for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) { for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) {
if (iter->m_width != VI.width && iter->m_height != VI.height) if (iter->m_width != VI.width && iter->m_height != VI.height)
FrameBuffer_CopyToRDRAM(iter->m_startAddress); FrameBuffer_CopyToRDRAM(iter->m_startAddress, true);
} }
} }
@ -967,13 +966,12 @@ 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(3, m_PBO);
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_aPBO[0]); for (u32 i = 0; i < 3; ++i) {
glBufferData(GL_PIXEL_PACK_BUFFER, m_pTexture->textureBytes, NULL, GL_DYNAMIC_READ); glBindBuffer(GL_PIXEL_PACK_BUFFER, m_PBO[i]);
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_aPBO[1]); glBufferData(GL_PIXEL_PACK_BUFFER, m_pTexture->textureBytes, NULL, GL_DYNAMIC_READ);
glBufferData(GL_PIXEL_PACK_BUFFER, m_pTexture->textureBytes, NULL, GL_DYNAMIC_READ); }
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
m_bSync = config.frameBufferEmulation.copyToRDRAM == Config::ctSync;
m_curIndex = 0; m_curIndex = 0;
} }
@ -987,11 +985,11 @@ void FrameBufferToRDRAM::Destroy() {
textureCache().removeFrameBufferTexture(m_pTexture); textureCache().removeFrameBufferTexture(m_pTexture);
m_pTexture = NULL; m_pTexture = NULL;
} }
glDeleteBuffers(2, m_aPBO); glDeleteBuffers(3, m_PBO);
m_aPBO[0] = m_aPBO[1] = 0; m_PBO[0] = m_PBO[1] = m_PBO[2] = 0;
} }
void FrameBufferToRDRAM::CopyToRDRAM(u32 _address) void FrameBufferToRDRAM::CopyToRDRAM(u32 _address, bool _sync)
{ {
if (VI.width == 0 || frameBufferList().getCurrent() == NULL) if (VI.width == 0 || frameBufferList().getCurrent() == NULL)
return; return;
@ -1030,11 +1028,16 @@ void FrameBufferToRDRAM::CopyToRDRAM(u32 _address)
#ifndef GLES2 #ifndef GLES2
// If Sync, read pixels from the buffer, copy them to RDRAM. // If Sync, read pixels from the buffer, copy them to RDRAM.
// If not Sync, read pixels from the buffer, copy pixels from the previous buffer to RDRAM. // If not Sync, read pixels from the buffer, copy pixels from the previous buffer to RDRAM.
m_curIndex ^= 1; if (!_sync) {
const u32 nextIndex = m_bSync ? m_curIndex : m_curIndex^1; m_curIndex ^= 1;
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_aPBO[m_curIndex]); const u32 nextIndex = m_curIndex^1;
glReadPixels(0, 0, pBuffer->m_width, pBuffer->m_height, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindBuffer(GL_PIXEL_PACK_BUFFER, m_PBO[m_curIndex]);
PBOBinder binder(GL_PIXEL_PACK_BUFFER, m_aPBO[nextIndex]); glReadPixels(0, 0, pBuffer->m_width, pBuffer->m_height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_PBO[nextIndex]);
} else {
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_PBO[2]);
glReadPixels(0, 0, pBuffer->m_width, pBuffer->m_height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
}
GLubyte* pixelData = (GLubyte*)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, numPixels * 4, GL_MAP_READ_BIT); GLubyte* pixelData = (GLubyte*)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, numPixels * 4, GL_MAP_READ_BIT);
if (pixelData == NULL) if (pixelData == NULL)
@ -1074,6 +1077,7 @@ void FrameBufferToRDRAM::CopyToRDRAM(u32 _address)
pBuffer->m_cleared = false; pBuffer->m_cleared = false;
#ifndef GLES2 #ifndef GLES2
glUnmapBuffer(GL_PIXEL_PACK_BUFFER); glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
#else #else
free(pixelData); free(pixelData);
#endif #endif
@ -1082,10 +1086,10 @@ void FrameBufferToRDRAM::CopyToRDRAM(u32 _address)
} }
#endif // GLES2 #endif // GLES2
void FrameBuffer_CopyToRDRAM(u32 _address) void FrameBuffer_CopyToRDRAM(u32 _address, bool _sync)
{ {
#ifndef GLES2 #ifndef GLES2
g_fbToRDRAM.CopyToRDRAM(_address); g_fbToRDRAM.CopyToRDRAM(_address, _sync);
#else #else
if ((config.generalEmulation.hacks & hack_subscreen) == 0) if ((config.generalEmulation.hacks & hack_subscreen) == 0)
return; return;
@ -1248,7 +1252,7 @@ bool FrameBuffer_CopyDepthBuffer( u32 address ) {
FrameBuffer * pCopyBuffer = frameBufferList().getCopyBuffer(); FrameBuffer * pCopyBuffer = frameBufferList().getCopyBuffer();
if (pCopyBuffer != NULL) { if (pCopyBuffer != NULL) {
// This code is mainly to emulate Zelda MM camera. // This code is mainly to emulate Zelda MM camera.
g_fbToRDRAM.CopyToRDRAM(pCopyBuffer->m_startAddress); g_fbToRDRAM.CopyToRDRAM(pCopyBuffer->m_startAddress, true);
pCopyBuffer->m_RdramCopy.resize(0); // To disable validity check by RDRAM content. CPU may change content of the buffer for some unknown reason. pCopyBuffer->m_RdramCopy.resize(0); // To disable validity check by RDRAM content. CPU may change content of the buffer for some unknown reason.
frameBufferList().setCopyBuffer(NULL); frameBufferList().setCopyBuffer(NULL);
return true; return true;

View File

@ -115,7 +115,7 @@ FrameBufferList & frameBufferList()
void FrameBuffer_Init(); void FrameBuffer_Init();
void FrameBuffer_Destroy(); void FrameBuffer_Destroy();
void FrameBuffer_CopyToRDRAM( u32 _address ); void FrameBuffer_CopyToRDRAM( u32 _address , bool _sync );
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

@ -209,8 +209,6 @@ void RSP_ProcessDList()
} }
} }
if (config.frameBufferEmulation.copyToRDRAM != Config::ctDisable)
FrameBuffer_CopyToRDRAM(gDP.colorImage.address);
if (config.frameBufferEmulation.copyDepthToRDRAM != Config::ctDisable) if (config.frameBufferEmulation.copyDepthToRDRAM != Config::ctDisable)
FrameBuffer_CopyDepthBuffer(gDP.colorImage.address); FrameBuffer_CopyDepthBuffer(gDP.colorImage.address);

View File

@ -887,9 +887,11 @@ void gDPFullSync()
frameBufferList().removeAux(); frameBufferList().removeAux();
} }
const bool sync = config.frameBufferEmulation.copyToRDRAM == Config::ctSync;
if (config.frameBufferEmulation.copyToRDRAM != Config::ctDisable)
FrameBuffer_CopyToRDRAM(gDP.colorImage.address, sync);
if (RSP.bLLE) { if (RSP.bLLE) {
if (config.frameBufferEmulation.copyToRDRAM != Config::ctDisable)
FrameBuffer_CopyToRDRAM(gDP.colorImage.address);
if (config.frameBufferEmulation.copyDepthToRDRAM != Config::ctDisable) if (config.frameBufferEmulation.copyDepthToRDRAM != Config::ctDisable)
FrameBuffer_CopyDepthBuffer(gDP.colorImage.address); FrameBuffer_CopyDepthBuffer(gDP.colorImage.address);
} }