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

Allow triple buffering in async copy mode

This commit is contained in:
Logan McNaughton 2018-02-20 23:29:10 -07:00 committed by Sergey Lipskiy
parent 892290b304
commit d2d0e9aafc
9 changed files with 37 additions and 28 deletions

View File

@ -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;

View File

@ -78,8 +78,9 @@ struct Config
enum CopyToRDRAM {
ctDisable = 0,
ctSync,
ctAsync
ctSync = 1,
ctDoubleBuffer = 2,
ctTripleBuffer = 3
};
enum BufferSwapMode {

View File

@ -1,3 +1,4 @@
#include <Config.h>
#include <Graphics/Context.h>
#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);

View File

@ -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];
};
}

View File

@ -1,3 +1,4 @@
#include <Config.h>
#include <Graphics/Context.h>
#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;

View File

@ -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;
};

View File

@ -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

View File

@ -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");
}

View File

@ -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);