Skip to content

Commit

Permalink
Merge pull request #511 from fzurita/GLideN64_update_nov_9
Browse files Browse the repository at this point in the history
GLideN64 update nov 9
  • Loading branch information
Gillou68310 committed Nov 15, 2015
2 parents 2b3866c + 17999c5 commit f8da4c1
Show file tree
Hide file tree
Showing 13 changed files with 127 additions and 59 deletions.
7 changes: 7 additions & 0 deletions assets/mupen64plus_data/profiles/emulation.cfg
Expand Up @@ -18,6 +18,7 @@ videoSubPlugin=-gles20
MultiSampling=0
EnableLOD=False
EnableCopyColorToRDRAM=2
EnableCopyAuxiliaryToRDRAM=False
EnableCopyDepthToRDRAM=False
EnableN64DepthCompare=False

Expand All @@ -27,13 +28,19 @@ r4300Emulator=2
videoPlugin=libmupen64plus-video-gliden64%1$s.so
videoSubPlugin=-gles30
MultiSampling=0
EnableCopyColorToRDRAM=2
EnableCopyAuxiliaryToRDRAM=False
EnableCopyDepthToRDRAM=False
EnableN64DepthCompare=False

[GlideN64-GLES-3.1]
comment=gliden64 video with recommended settings for Android 5.0+ devices with OpenGL ES 3.1 support
r4300Emulator=2
videoPlugin=libmupen64plus-video-gliden64%1$s.so
videoSubPlugin=-gles31
EnableCopyColorToRDRAM=2
EnableCopyAuxiliaryToRDRAM=False
EnableCopyDepthToRDRAM=False

[Gln64-Accurate]
comment=gln64 video with recommended settings for quality
Expand Down
1 change: 1 addition & 0 deletions jni/mupen64plus-video-gliden64/src/Config.cpp
Expand Up @@ -51,6 +51,7 @@ void Config::resetToDefaults()
#endif
frameBufferEmulation.copyDepthToRDRAM = ctDisable;
frameBufferEmulation.copyFromRDRAM = 0;
frameBufferEmulation.copyAuxToRDRAM = 0;
frameBufferEmulation.copyToRDRAM = ctAsync;
frameBufferEmulation.detectCFB = 0;
frameBufferEmulation.N64DepthCompare = 0;
Expand Down
1 change: 1 addition & 0 deletions jni/mupen64plus-video-gliden64/src/Config.h
Expand Up @@ -73,6 +73,7 @@ struct Config

struct {
u32 enable;
u32 copyAuxToRDRAM;
u32 copyToRDRAM;
u32 copyDepthToRDRAM;
u32 copyFromRDRAM;
Expand Down
144 changes: 94 additions & 50 deletions jni/mupen64plus-video-gliden64/src/FrameBuffer.cpp
Expand Up @@ -23,15 +23,15 @@ class FrameBufferToRDRAM
{
public:
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 Destroy();

void CopyToRDRAM(u32 _address);
void CopyToRDRAM(u32 _address, bool _sync);

private:
union RGBA {
Expand All @@ -41,11 +41,10 @@ class FrameBufferToRDRAM
u32 raw;
};

bool m_bSync;
GLuint m_FBO;
CachedTexture * m_pTexture;
u32 m_curIndex;
GLuint m_aPBO[2];
GLuint m_PBO[3];
};

class DepthBufferToRDRAM
Expand Down Expand Up @@ -193,8 +192,13 @@ void FrameBuffer::init(u32 _address, u32 _endAddress, u16 _format, u16 _size, u1
m_width = _width;
m_height = _height;
m_size = _size;
m_scaleX = ogl.getScaleX();
m_scaleY = ogl.getScaleY();
if (m_width != VI.width && config.frameBufferEmulation.copyAuxToRDRAM != 0) {
m_scaleX = 1.0f;
m_scaleY = 1.0f;
} else {
m_scaleX = ogl.getScaleX();
m_scaleY = ogl.getScaleY();
}
m_fillcolor = 0;
m_cfb = _cfb;
m_needHeightCorrection = _width != VI.width && _width != *REG.VI_WIDTH;
Expand Down Expand Up @@ -263,7 +267,7 @@ void FrameBuffer::copyRdram()
const u32 dataSize = stride * height;

// Auxiliary frame buffer
if (m_width != VI.width) {
if (m_width != VI.width && config.frameBufferEmulation.copyAuxToRDRAM == 0) {
// Write small amount of data to the start of the buffer.
// This is necessary for auxilary buffers: game can restore content of RDRAM when buffer is not needed anymore
// Thus content of RDRAM on moment of buffer creation will be the same as when buffer becomes obsolete.
Expand Down Expand Up @@ -453,6 +457,13 @@ FrameBuffer * FrameBufferList::findTmpBuffer(u32 _address)

void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _width, u16 _height, bool _cfb)
{
if (m_pCurrent != NULL && config.frameBufferEmulation.copyAuxToRDRAM != 0) {
if (m_pCurrent->m_width != VI.width) {
FrameBuffer_CopyToRDRAM(m_pCurrent->m_startAddress, true);
removeBuffer(m_pCurrent->m_startAddress);
}
}

if (VI.width == 0 || _height == 0) {
m_pCurrent = NULL;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
Expand Down Expand Up @@ -533,6 +544,29 @@ void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _widt
m_pCurrent->m_postProcessed = false;
}

void FrameBufferList::copyAux()
{
for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) {
if (iter->m_width != VI.width && iter->m_height != VI.height)
FrameBuffer_CopyToRDRAM(iter->m_startAddress, true);
}
}

void FrameBufferList::removeAux()
{
for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) {
while (iter->m_width != VI.width && iter->m_height != VI.height) {
if (&(*iter) == m_pCurrent) {
m_pCurrent = NULL;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}
iter = m_list.erase(iter);
if (iter == m_list.end())
return;
}
}
}

void FrameBufferList::removeBuffer(u32 _address )
{
for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter)
Expand Down Expand Up @@ -932,13 +966,12 @@ void FrameBufferToRDRAM::Init()
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

// Generate and initialize Pixel Buffer Objects
glGenBuffers(2, m_aPBO);
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_aPBO[0]);
glBufferData(GL_PIXEL_PACK_BUFFER, m_pTexture->textureBytes, NULL, GL_DYNAMIC_READ);
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_aPBO[1]);
glBufferData(GL_PIXEL_PACK_BUFFER, m_pTexture->textureBytes, NULL, GL_DYNAMIC_READ);
glGenBuffers(3, m_PBO);
for (u32 i = 0; i < 3; ++i) {
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_PBO[i]);
glBufferData(GL_PIXEL_PACK_BUFFER, m_pTexture->textureBytes, NULL, GL_DYNAMIC_READ);
}
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
m_bSync = config.frameBufferEmulation.copyToRDRAM == Config::ctSync;
m_curIndex = 0;
}

Expand All @@ -952,20 +985,24 @@ void FrameBufferToRDRAM::Destroy() {
textureCache().removeFrameBufferTexture(m_pTexture);
m_pTexture = NULL;
}
glDeleteBuffers(2, m_aPBO);
m_aPBO[0] = m_aPBO[1] = 0;
glDeleteBuffers(3, m_PBO);
m_PBO[0] = m_PBO[1] = m_PBO[2] = 0;
}

void FrameBufferToRDRAM::CopyToRDRAM(u32 _address)
void FrameBufferToRDRAM::CopyToRDRAM(u32 _address, bool _sync)
{
const u32 numPixels = VI.width * VI.height;
if (numPixels == 0 || frameBufferList().getCurrent() == NULL) // Incorrect buffer size or no current buffer. Don't copy
if (VI.width == 0 || frameBufferList().getCurrent() == NULL)
return;

FrameBuffer *pBuffer = frameBufferList().findBuffer(_address);
if (pBuffer == NULL || pBuffer->m_width < VI.width || pBuffer->m_isOBScreen)
if (pBuffer == NULL || pBuffer->m_isOBScreen)
return;

if ((config.generalEmulation.hacks & hack_subscreen) != 0) {
const u32 numPixels = pBuffer->m_width * pBuffer->m_height;
if (numPixels == 0)
return;

if ((config.generalEmulation.hacks & hack_subscreen) != 0 && pBuffer->m_width == VI.width && pBuffer->m_height == VI.height) {
copyWhiteToRDRAM(pBuffer);
return;
}
Expand All @@ -976,56 +1013,62 @@ void FrameBufferToRDRAM::CopyToRDRAM(u32 _address)
glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_resolveFBO);
} else
glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_FBO);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO);
glScissor(0, 0, pBuffer->m_pTexture->realWidth, pBuffer->m_pTexture->realHeight);
glBlitFramebuffer(
0, 0, video().getWidth(), video().getHeight(),
0, 0, VI.width, VI.height,
GL_COLOR_BUFFER_BIT, GL_NEAREST
);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().getCurrent()->m_FBO);

glBindFramebuffer(GL_READ_FRAMEBUFFER, m_FBO);
glReadBuffer(GL_COLOR_ATTACHMENT0);
if (pBuffer->m_scaleX > 1.0f) {
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO);
glScissor(0, 0, pBuffer->m_pTexture->realWidth, pBuffer->m_pTexture->realHeight);
glBlitFramebuffer(
0, 0, video().getWidth(), video().getHeight(),
0, 0, VI.width, VI.height,
GL_COLOR_BUFFER_BIT, GL_NEAREST
);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().getCurrent()->m_FBO);
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_FBO);
}
#ifndef GLES2
// 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.
m_curIndex ^= 1;
const u32 nextIndex = m_bSync ? m_curIndex : m_curIndex^1;
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_aPBO[m_curIndex]);
glReadPixels(0, 0, VI.width, VI.height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
PBOBinder binder(GL_PIXEL_PACK_BUFFER, m_aPBO[nextIndex]);
if (!_sync) {
m_curIndex ^= 1;
const u32 nextIndex = m_curIndex^1;
glBindBuffer(GL_PIXEL_PACK_BUFFER, m_PBO[m_curIndex]);
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);
if(pixelData == NULL)
if (pixelData == NULL)
return;
#else
GLubyte* pixelData = (GLubyte* )malloc(numPixels * 4);
if(pixelData == NULL)
if (pixelData == NULL)
return;
glReadPixels( 0, 0, VI.width, VI.height, GL_RGBA, GL_UNSIGNED_BYTE, pixelData );
glReadPixels(0, 0, VI.width, VI.height, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);
#endif // GLES2

const u32 stride = pBuffer->m_width << pBuffer->m_size >> 1;
const u32 height = _cutHeight(_address, VI.height, stride);
const u32 height = _cutHeight(_address, pBuffer->m_height, stride);

if (pBuffer->m_size == G_IM_SIZ_32b) {
u32 *ptr_dst = (u32*)(RDRAM + _address);
u32 *ptr_src = (u32*)pixelData;

for (u32 y = 0; y < height; ++y) {
for (u32 x = 0; x < VI.width; ++x)
ptr_dst[x + y*VI.width] = ptr_src[x + (height - y - 1)*VI.width];
for (u32 x = 0; x < pBuffer->m_width; ++x)
ptr_dst[x + y*pBuffer->m_width] = ptr_src[x + (height - y - 1)*pBuffer->m_width];
}
} else {
} else if (pBuffer->m_size == G_IM_SIZ_16b) {
u16 *ptr_dst = (u16*)(RDRAM + _address);
u32 * ptr_src = (u32*)pixelData;
RGBA c;

for (u32 y = 0; y < height; ++y) {
for (u32 x = 0; x < VI.width; ++x) {
c.raw = ptr_src[x + (height - y - 1)*VI.width];
ptr_dst[(x + y*VI.width)^1] = ((c.r>>3)<<11) | ((c.g>>3)<<6) | ((c.b>>3)<<1) | (c.a == 0 ? 0 : 1);
for (u32 x = 0; x < pBuffer->m_width; ++x) {
c.raw = ptr_src[x + (height - y - 1)*pBuffer->m_width];
ptr_dst[(x + y*pBuffer->m_width) ^ 1] = ((c.r >> 3) << 11) | ((c.g >> 3) << 6) | ((c.b >> 3) << 1) | (c.a == 0 ? 0 : 1);
}
}
}
Expand All @@ -1034,6 +1077,7 @@ void FrameBufferToRDRAM::CopyToRDRAM(u32 _address)
pBuffer->m_cleared = false;
#ifndef GLES2
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
#else
free(pixelData);
#endif
Expand All @@ -1042,10 +1086,10 @@ void FrameBufferToRDRAM::CopyToRDRAM(u32 _address)
}
#endif // GLES2

void FrameBuffer_CopyToRDRAM(u32 _address)
void FrameBuffer_CopyToRDRAM(u32 _address, bool _sync)
{
#ifndef GLES2
g_fbToRDRAM.CopyToRDRAM(_address);
g_fbToRDRAM.CopyToRDRAM(_address, _sync);
#else
if ((config.generalEmulation.hacks & hack_subscreen) == 0)
return;
Expand Down Expand Up @@ -1208,7 +1252,7 @@ bool FrameBuffer_CopyDepthBuffer( u32 address ) {
FrameBuffer * pCopyBuffer = frameBufferList().getCopyBuffer();
if (pCopyBuffer != NULL) {
// 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.
frameBufferList().setCopyBuffer(NULL);
return true;
Expand Down
4 changes: 3 additions & 1 deletion jni/mupen64plus-video-gliden64/src/FrameBuffer.h
Expand Up @@ -60,6 +60,8 @@ class FrameBufferList
void init();
void destroy();
void saveBuffer(u32 _address, u16 _format, u16 _size, u16 _width, u16 _height, bool _cfb);
void removeAux();
void copyAux();
void removeBuffer(u32 _address);
void removeBuffers(u32 _width);
void attachDepthBuffer();
Expand Down Expand Up @@ -113,7 +115,7 @@ FrameBufferList & frameBufferList()

void FrameBuffer_Init();
void FrameBuffer_Destroy();
void FrameBuffer_CopyToRDRAM( u32 _address );
void FrameBuffer_CopyToRDRAM( u32 _address , bool _sync );
void FrameBuffer_CopyFromRDRAM( u32 address, bool bUseAlpha );
bool FrameBuffer_CopyDepthBuffer( u32 address );
void FrameBuffer_ActivateBufferTexture(s16 t, FrameBuffer *pBuffer);
Expand Down
2 changes: 0 additions & 2 deletions jni/mupen64plus-video-gliden64/src/RSP.cpp
Expand Up @@ -209,8 +209,6 @@ void RSP_ProcessDList()
}
}

if (config.frameBufferEmulation.copyToRDRAM != Config::ctDisable)
FrameBuffer_CopyToRDRAM(gDP.colorImage.address);
if (config.frameBufferEmulation.copyDepthToRDRAM != Config::ctDisable)
FrameBuffer_CopyDepthBuffer(gDP.colorImage.address);

Expand Down
2 changes: 1 addition & 1 deletion jni/mupen64plus-video-gliden64/src/Revision.h
@@ -1 +1 @@
#define PLUGIN_REVISION "c926c8c"
#define PLUGIN_REVISION "142ad0b"
4 changes: 2 additions & 2 deletions jni/mupen64plus-video-gliden64/src/VI.cpp
Expand Up @@ -46,8 +46,8 @@ void VI_UpdateSize()
}
if (VI.real_height % 2 == 1)
--VI.real_height;
} else if (hEnd != 0 && *REG.VI_WIDTH != 0)
VI.width = min((u32)floorf((hEnd - hStart)*xScale + 0.5f), *REG.VI_WIDTH);
} //else if (hEnd != 0 && *REG.VI_WIDTH != 0)
//VI.width = min((u32)floorf((hEnd - hStart)*xScale + 0.5f), *REG.VI_WIDTH);

VI.PAL = (*REG.VI_V_SYNC & 0x3ff) > 550;
if (VI.PAL && (vEnd - vStart) > 478) {
Expand Down
11 changes: 9 additions & 2 deletions jni/mupen64plus-video-gliden64/src/gDP.cpp
Expand Up @@ -882,9 +882,16 @@ void gDPTextureRectangleFlip( f32 ulx, f32 uly, f32 lrx, f32 lry, s32 tile, f32

void gDPFullSync()
{
if (config.frameBufferEmulation.copyAuxToRDRAM != 0) {
frameBufferList().copyAux();
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 (config.frameBufferEmulation.copyToRDRAM != Config::ctDisable)
FrameBuffer_CopyToRDRAM(gDP.colorImage.address);
if (config.frameBufferEmulation.copyDepthToRDRAM != Config::ctDisable)
FrameBuffer_CopyDepthBuffer(gDP.colorImage.address);
}
Expand Down
Expand Up @@ -83,6 +83,8 @@ bool Config_SetDefault()
//#Frame Buffer Settings:"
res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableFBEmulation", config.frameBufferEmulation.enable, "Enable frame and|or depth buffer emulation.");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableCopyAuxiliaryToRDRAM", config.frameBufferEmulation.copyAuxToRDRAM, "Copy auxiliary buffers to RDRAM");
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)");
assert(res == M64ERR_SUCCESS);
res = ConfigSetDefaultBool(g_configVideoGliden64, "EnableCopyDepthToRDRAM", config.frameBufferEmulation.copyDepthToRDRAM, "Enable depth buffer copy to RDRAM.");
Expand Down Expand Up @@ -195,6 +197,7 @@ void Config_LoadConfig()
#endif
//#Frame Buffer Settings:"
config.frameBufferEmulation.enable = ConfigGetParamBool(g_configVideoGliden64, "EnableFBEmulation");
config.frameBufferEmulation.copyAuxToRDRAM = ConfigGetParamBool(g_configVideoGliden64, "EnableCopyAuxiliaryToRDRAM");
config.frameBufferEmulation.copyToRDRAM = ConfigGetParamInt(g_configVideoGliden64, "EnableCopyColorToRDRAM");
config.frameBufferEmulation.copyDepthToRDRAM = ConfigGetParamBool(g_configVideoGliden64, "EnableCopyDepthToRDRAM");
config.frameBufferEmulation.copyFromRDRAM = ConfigGetParamBool(g_configVideoGliden64, "EnableCopyColorFromRDRAM");
Expand Down

0 comments on commit f8da4c1

Please sign in to comment.