mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-07 03:13:49 +00:00
Allow triple buffering in async copy mode
This commit is contained in:
parent
892290b304
commit
d2d0e9aafc
|
@ -54,7 +54,7 @@ void Config::resetToDefaults()
|
||||||
frameBufferEmulation.copyDepthToRDRAM = cdSoftwareRender;
|
frameBufferEmulation.copyDepthToRDRAM = cdSoftwareRender;
|
||||||
frameBufferEmulation.copyFromRDRAM = 0;
|
frameBufferEmulation.copyFromRDRAM = 0;
|
||||||
frameBufferEmulation.copyAuxToRDRAM = 0;
|
frameBufferEmulation.copyAuxToRDRAM = 0;
|
||||||
frameBufferEmulation.copyToRDRAM = ctAsync;
|
frameBufferEmulation.copyToRDRAM = ctDoubleBuffer;
|
||||||
frameBufferEmulation.N64DepthCompare = 0;
|
frameBufferEmulation.N64DepthCompare = 0;
|
||||||
frameBufferEmulation.aspect = a43;
|
frameBufferEmulation.aspect = a43;
|
||||||
frameBufferEmulation.bufferSwapMode = bsOnVerticalInterrupt;
|
frameBufferEmulation.bufferSwapMode = bsOnVerticalInterrupt;
|
||||||
|
|
|
@ -78,8 +78,9 @@ struct Config
|
||||||
|
|
||||||
enum CopyToRDRAM {
|
enum CopyToRDRAM {
|
||||||
ctDisable = 0,
|
ctDisable = 0,
|
||||||
ctSync,
|
ctSync = 1,
|
||||||
ctAsync
|
ctDoubleBuffer = 2,
|
||||||
|
ctTripleBuffer = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BufferSwapMode {
|
enum BufferSwapMode {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <Config.h>
|
||||||
#include <Graphics/Context.h>
|
#include <Graphics/Context.h>
|
||||||
#include "opengl_ColorBufferReaderWithBufferStorage.h"
|
#include "opengl_ColorBufferReaderWithBufferStorage.h"
|
||||||
|
|
||||||
|
@ -18,12 +19,16 @@ ColorBufferReaderWithBufferStorage::~ColorBufferReaderWithBufferStorage()
|
||||||
|
|
||||||
void ColorBufferReaderWithBufferStorage::_initBuffers()
|
void ColorBufferReaderWithBufferStorage::_initBuffers()
|
||||||
{
|
{
|
||||||
|
m_numPBO = config.frameBufferEmulation.copyToRDRAM;
|
||||||
|
if (m_numPBO > _maxPBO)
|
||||||
|
m_numPBO = _maxPBO;
|
||||||
|
|
||||||
// Generate Pixel Buffer Objects
|
// Generate Pixel Buffer Objects
|
||||||
glGenBuffers(_numPBO, m_PBO);
|
glGenBuffers(m_numPBO, m_PBO);
|
||||||
m_curIndex = 0;
|
m_curIndex = 0;
|
||||||
|
|
||||||
// Initialize Pixel Buffer Objects
|
// 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_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[index]));
|
||||||
m_fence[index] = 0;
|
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);
|
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()
|
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;
|
m_PBO[index] = 0;
|
||||||
glDeleteSync(m_fence[index]);
|
glDeleteSync(m_fence[index]);
|
||||||
}
|
}
|
||||||
|
@ -55,7 +60,7 @@ const u8 * ColorBufferReaderWithBufferStorage::_readPixels(const ReadColorBuffer
|
||||||
if (!_params.sync) {
|
if (!_params.sync) {
|
||||||
//Setup a fence sync object so that we know when glReadPixels completes
|
//Setup a fence sync object so that we know when glReadPixels completes
|
||||||
m_fence[m_curIndex] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
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
|
//Wait for glReadPixels to complete for the currently selected PBO
|
||||||
if (m_fence[m_curIndex] != 0) {
|
if (m_fence[m_curIndex] != 0) {
|
||||||
glClientWaitSync(m_fence[m_curIndex], 0, 100000000);
|
glClientWaitSync(m_fence[m_curIndex], 0, 100000000);
|
||||||
|
|
|
@ -24,11 +24,12 @@ namespace opengl {
|
||||||
|
|
||||||
CachedBindBuffer * m_bindBuffer;
|
CachedBindBuffer * m_bindBuffer;
|
||||||
|
|
||||||
static const int _numPBO = 2;
|
static const int _maxPBO = 3;
|
||||||
GLuint m_PBO[_numPBO];
|
u32 m_numPBO;
|
||||||
void* m_PBOData[_numPBO];
|
GLuint m_PBO[_maxPBO];
|
||||||
|
void* m_PBOData[_maxPBO];
|
||||||
u32 m_curIndex;
|
u32 m_curIndex;
|
||||||
GLsync m_fence[_numPBO];
|
GLsync m_fence[_maxPBO];
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <Config.h>
|
||||||
#include <Graphics/Context.h>
|
#include <Graphics/Context.h>
|
||||||
#include "opengl_ColorBufferReaderWithPixelBuffer.h"
|
#include "opengl_ColorBufferReaderWithPixelBuffer.h"
|
||||||
|
|
||||||
|
@ -19,20 +20,24 @@ ColorBufferReaderWithPixelBuffer::~ColorBufferReaderWithPixelBuffer()
|
||||||
|
|
||||||
void ColorBufferReaderWithPixelBuffer::_destroyBuffers()
|
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;
|
m_PBO[index] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorBufferReaderWithPixelBuffer::_initBuffers()
|
void ColorBufferReaderWithPixelBuffer::_initBuffers()
|
||||||
{
|
{
|
||||||
|
m_numPBO = config.frameBufferEmulation.copyToRDRAM;
|
||||||
|
if (m_numPBO > _maxPBO)
|
||||||
|
m_numPBO = _maxPBO;
|
||||||
|
|
||||||
// Generate Pixel Buffer Objects
|
// Generate Pixel Buffer Objects
|
||||||
glGenBuffers(_numPBO, m_PBO);
|
glGenBuffers(m_numPBO, m_PBO);
|
||||||
m_curIndex = 0;
|
m_curIndex = 0;
|
||||||
|
|
||||||
// Initialize Pixel Buffer Objects
|
// 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]));
|
m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[i]));
|
||||||
glBufferData(GL_PIXEL_PACK_BUFFER, m_pTexture->textureBytes, nullptr, GL_DYNAMIC_READ);
|
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 format = GLenum(_params.colorFormat);
|
||||||
GLenum type = GLenum(_params.colorType);
|
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 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.
|
||||||
if (!_params.sync) {
|
if (!_params.sync) {
|
||||||
m_curIndex ^= 1;
|
m_curIndex = (m_curIndex + 1) % m_numPBO;
|
||||||
const u32 nextIndex = m_curIndex ^ 1;
|
|
||||||
m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[m_curIndex]));
|
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;
|
_heightOffset = 0;
|
||||||
|
|
|
@ -21,8 +21,9 @@ private:
|
||||||
|
|
||||||
CachedBindBuffer * m_bindBuffer;
|
CachedBindBuffer * m_bindBuffer;
|
||||||
|
|
||||||
static const int _numPBO = 3;
|
u32 m_numPBO;
|
||||||
GLuint m_PBO[_numPBO];
|
static const int _maxPBO = 3;
|
||||||
|
GLuint m_PBO[_maxPBO];
|
||||||
u32 m_curIndex;
|
u32 m_curIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -305,7 +305,7 @@ graphics::ColorBufferReader * ContextImpl::createColorBufferReader(CachedTexture
|
||||||
return new ColorBufferReaderWithPixelBuffer(_pTexture, m_cachedFunctions->getCachedBindBuffer());
|
return new ColorBufferReaderWithPixelBuffer(_pTexture, m_cachedFunctions->getCachedBindBuffer());
|
||||||
|
|
||||||
#if defined(EGL) && defined(OS_ANDROID)
|
#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());
|
return new ColorBufferReaderWithEGLImage(_pTexture, m_cachedFunctions->getCachedBindTexture());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ void GLInfo::init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef OS_ANDROID
|
#ifndef OS_ANDROID
|
||||||
if (isGLES2 && config.frameBufferEmulation.copyToRDRAM == Config::ctAsync) {
|
if (isGLES2 && config.frameBufferEmulation.copyToRDRAM > Config::ctSync) {
|
||||||
config.frameBufferEmulation.copyToRDRAM = Config::ctDisable;
|
config.frameBufferEmulation.copyToRDRAM = Config::ctDisable;
|
||||||
LOG(LOG_WARNING, "Async color buffer copies are not supported on GLES2\n");
|
LOG(LOG_WARNING, "Async color buffer copies are not supported on GLES2\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ bool Config_SetDefault()
|
||||||
assert(res == M64ERR_SUCCESS);
|
assert(res == M64ERR_SUCCESS);
|
||||||
res = ConfigSetDefaultBool(g_configVideoGliden64, "FBInfoReadDepthChunk", config.frameBufferEmulation.fbInfoReadDepthChunk, "Read depth buffer by 4kb chunks (strict follow to FBRead specification)");
|
res = ConfigSetDefaultBool(g_configVideoGliden64, "FBInfoReadDepthChunk", config.frameBufferEmulation.fbInfoReadDepthChunk, "Read depth buffer by 4kb chunks (strict follow to FBRead specification)");
|
||||||
assert(res == M64ERR_SUCCESS);
|
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);
|
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)");
|
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);
|
assert(res == M64ERR_SUCCESS);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user