diff --git a/src/Config.cpp b/src/Config.cpp index f0fb15c6..cd5c2741 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -54,7 +54,7 @@ void Config::resetToDefaults() frameBufferEmulation.copyDepthToRDRAM = cdSoftwareRender; frameBufferEmulation.copyFromRDRAM = 0; frameBufferEmulation.copyAuxToRDRAM = 0; - frameBufferEmulation.copyToRDRAM = ctAsync; + frameBufferEmulation.copyToRDRAM = ctDoubleBuffer; frameBufferEmulation.N64DepthCompare = 0; frameBufferEmulation.aspect = a43; frameBufferEmulation.bufferSwapMode = bsOnVerticalInterrupt; diff --git a/src/Config.h b/src/Config.h index fa434172..46062bd6 100644 --- a/src/Config.h +++ b/src/Config.h @@ -78,8 +78,9 @@ struct Config enum CopyToRDRAM { ctDisable = 0, - ctSync, - ctAsync + ctSync = 1, + ctDoubleBuffer = 2, + ctTripleBuffer = 3 }; enum BufferSwapMode { diff --git a/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithBufferStorage.cpp b/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithBufferStorage.cpp index b63e2941..e3fda939 100644 --- a/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithBufferStorage.cpp +++ b/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithBufferStorage.cpp @@ -1,3 +1,4 @@ +#include #include #include "opengl_ColorBufferReaderWithBufferStorage.h" @@ -18,12 +19,16 @@ ColorBufferReaderWithBufferStorage::~ColorBufferReaderWithBufferStorage() void ColorBufferReaderWithBufferStorage::_initBuffers() { + m_numPBO = config.frameBufferEmulation.copyToRDRAM; + if (m_numPBO > _maxPBO) + m_numPBO = _maxPBO; + // Generate Pixel Buffer Objects - glGenBuffers(_numPBO, m_PBO); + glGenBuffers(m_numPBO, m_PBO); m_curIndex = 0; // Initialize Pixel Buffer Objects - for (int index = 0; index < _numPBO; ++index) { + for (int index = 0; index < m_numPBO; ++index) { m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[index])); m_fence[index] = 0; glBufferStorage(GL_PIXEL_PACK_BUFFER, m_pTexture->textureBytes, nullptr, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); @@ -35,9 +40,9 @@ void ColorBufferReaderWithBufferStorage::_initBuffers() void ColorBufferReaderWithBufferStorage::_destroyBuffers() { - glDeleteBuffers(_numPBO, m_PBO); + glDeleteBuffers(m_numPBO, m_PBO); - for (int index = 0; index < _numPBO; ++index) { + for (int index = 0; index < m_numPBO; ++index) { m_PBO[index] = 0; glDeleteSync(m_fence[index]); } @@ -55,7 +60,7 @@ const u8 * ColorBufferReaderWithBufferStorage::_readPixels(const ReadColorBuffer if (!_params.sync) { //Setup a fence sync object so that we know when glReadPixels completes m_fence[m_curIndex] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - m_curIndex = (m_curIndex + 1) % _numPBO; + m_curIndex = (m_curIndex + 1) % m_numPBO; //Wait for glReadPixels to complete for the currently selected PBO if (m_fence[m_curIndex] != 0) { glClientWaitSync(m_fence[m_curIndex], 0, 100000000); diff --git a/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithBufferStorage.h b/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithBufferStorage.h index 5e144393..499bd581 100644 --- a/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithBufferStorage.h +++ b/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithBufferStorage.h @@ -24,11 +24,12 @@ namespace opengl { CachedBindBuffer * m_bindBuffer; - static const int _numPBO = 2; - GLuint m_PBO[_numPBO]; - void* m_PBOData[_numPBO]; + static const int _maxPBO = 3; + u32 m_numPBO; + GLuint m_PBO[_maxPBO]; + void* m_PBOData[_maxPBO]; u32 m_curIndex; - GLsync m_fence[_numPBO]; + GLsync m_fence[_maxPBO]; }; } diff --git a/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithPixelBuffer.cpp b/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithPixelBuffer.cpp index 3ba380d0..39571527 100644 --- a/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithPixelBuffer.cpp +++ b/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithPixelBuffer.cpp @@ -1,3 +1,4 @@ +#include #include #include "opengl_ColorBufferReaderWithPixelBuffer.h" @@ -19,20 +20,24 @@ ColorBufferReaderWithPixelBuffer::~ColorBufferReaderWithPixelBuffer() void ColorBufferReaderWithPixelBuffer::_destroyBuffers() { - glDeleteBuffers(_numPBO, m_PBO); + glDeleteBuffers(m_numPBO, m_PBO); - for(int index = 0; index < _numPBO; ++index) + for(int index = 0; index < m_numPBO; ++index) m_PBO[index] = 0; } void ColorBufferReaderWithPixelBuffer::_initBuffers() { + m_numPBO = config.frameBufferEmulation.copyToRDRAM; + if (m_numPBO > _maxPBO) + m_numPBO = _maxPBO; + // Generate Pixel Buffer Objects - glGenBuffers(_numPBO, m_PBO); + glGenBuffers(m_numPBO, m_PBO); m_curIndex = 0; // Initialize Pixel Buffer Objects - for (u32 i = 0; i < _numPBO; ++i) { + for (u32 i = 0; i < m_numPBO; ++i) { m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[i])); glBufferData(GL_PIXEL_PACK_BUFFER, m_pTexture->textureBytes, nullptr, GL_DYNAMIC_READ); } @@ -45,17 +50,13 @@ const u8 * ColorBufferReaderWithPixelBuffer::_readPixels(const ReadColorBufferPa GLenum format = GLenum(_params.colorFormat); GLenum type = GLenum(_params.colorType); + m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[m_curIndex])); + glReadPixels(_params.x0, _params.y0, m_pTexture->realWidth, _params.height, format, type, 0); // 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 (!_params.sync) { - m_curIndex ^= 1; - const u32 nextIndex = m_curIndex ^ 1; + m_curIndex = (m_curIndex + 1) % m_numPBO; m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[m_curIndex])); - glReadPixels(_params.x0, _params.y0, m_pTexture->realWidth, _params.height, format, type, 0); - m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[nextIndex])); - } else { - m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[_numPBO -1])); - glReadPixels(_params.x0, _params.y0, m_pTexture->realWidth, _params.height, format, type, 0); } _heightOffset = 0; diff --git a/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithPixelBuffer.h b/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithPixelBuffer.h index 50929162..f2508cde 100644 --- a/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithPixelBuffer.h +++ b/src/Graphics/OpenGLContext/opengl_ColorBufferReaderWithPixelBuffer.h @@ -21,8 +21,9 @@ private: CachedBindBuffer * m_bindBuffer; - static const int _numPBO = 3; - GLuint m_PBO[_numPBO]; + u32 m_numPBO; + static const int _maxPBO = 3; + GLuint m_PBO[_maxPBO]; u32 m_curIndex; }; diff --git a/src/Graphics/OpenGLContext/opengl_ContextImpl.cpp b/src/Graphics/OpenGLContext/opengl_ContextImpl.cpp index e13cf33b..7141d277 100644 --- a/src/Graphics/OpenGLContext/opengl_ContextImpl.cpp +++ b/src/Graphics/OpenGLContext/opengl_ContextImpl.cpp @@ -305,7 +305,7 @@ graphics::ColorBufferReader * ContextImpl::createColorBufferReader(CachedTexture return new ColorBufferReaderWithPixelBuffer(_pTexture, m_cachedFunctions->getCachedBindBuffer()); #if defined(EGL) && defined(OS_ANDROID) - if(config.frameBufferEmulation.copyToRDRAM == Config::ctAsync) + if(config.frameBufferEmulation.copyToRDRAM > Config::ctSync) return new ColorBufferReaderWithEGLImage(_pTexture, m_cachedFunctions->getCachedBindTexture()); #endif diff --git a/src/Graphics/OpenGLContext/opengl_GLInfo.cpp b/src/Graphics/OpenGLContext/opengl_GLInfo.cpp index 9c954004..38a9f103 100644 --- a/src/Graphics/OpenGLContext/opengl_GLInfo.cpp +++ b/src/Graphics/OpenGLContext/opengl_GLInfo.cpp @@ -79,7 +79,7 @@ void GLInfo::init() { } } #ifndef OS_ANDROID - if (isGLES2 && config.frameBufferEmulation.copyToRDRAM == Config::ctAsync) { + if (isGLES2 && config.frameBufferEmulation.copyToRDRAM > Config::ctSync) { config.frameBufferEmulation.copyToRDRAM = Config::ctDisable; LOG(LOG_WARNING, "Async color buffer copies are not supported on GLES2\n"); } diff --git a/src/mupenplus/Config_mupenplus.cpp b/src/mupenplus/Config_mupenplus.cpp index 5bbd2637..de38e267 100644 --- a/src/mupenplus/Config_mupenplus.cpp +++ b/src/mupenplus/Config_mupenplus.cpp @@ -108,7 +108,7 @@ bool Config_SetDefault() assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultBool(g_configVideoGliden64, "FBInfoReadDepthChunk", config.frameBufferEmulation.fbInfoReadDepthChunk, "Read depth buffer by 4kb chunks (strict follow to FBRead specification)"); assert(res == M64ERR_SUCCESS); - res = ConfigSetDefaultInt(g_configVideoGliden64, "EnableCopyColorToRDRAM", config.frameBufferEmulation.copyToRDRAM, "Enable color buffer copy to RDRAM (0=do not copy, 1=copy in sync mode, 2=copy in async mode)"); + res = ConfigSetDefaultInt(g_configVideoGliden64, "EnableCopyColorToRDRAM", config.frameBufferEmulation.copyToRDRAM, "Enable color buffer copy to RDRAM (0=do not copy, 1=copy in sync mode, 2=Double Buffer, 3=Triple Buffer)"); assert(res == M64ERR_SUCCESS); res = ConfigSetDefaultInt(g_configVideoGliden64, "EnableCopyDepthToRDRAM", config.frameBufferEmulation.copyDepthToRDRAM, "Enable depth buffer copy to RDRAM (0=do not copy, 1=copy from video memory, 2=use software render)"); assert(res == M64ERR_SUCCESS);