diff --git a/CMakeLists.txt b/CMakeLists.txt index f5f3ef4d..75db1a91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,6 @@ set(GLideN64_SOURCES Combiner.cpp CRC.cpp Debug.cpp - Debug_linux.cpp DepthBuffer.cpp F3D.cpp F3DDKR.cpp @@ -44,6 +43,7 @@ if(MUPENPLUSAPI) ) set(GLideN64_SOURCES_LINUX Config_mupen.cpp + Debug_linux.cpp ) else(MUPENPLUSAPI) set(GLideN64_SOURCES_WIN @@ -51,6 +51,7 @@ else(MUPENPLUSAPI) ) set(GLideN64_SOURCES_LINUX Config_linux.cpp + Debug_linux.cpp ) endif(MUPENPLUSAPI) @@ -96,6 +97,20 @@ if(OPT) ) endif(OPT) +# Build type + +if( NOT CMAKE_BUILD_TYPE) + set( CMAKE_BUILD_TYPE Release) +endif( NOT CMAKE_BUILD_TYPE) + +if( CMAKE_BUILD_TYPE STREQUAL "Debug") + set( CMAKE_BUILD_TYPE Debug) + set( DEBUG_BUILD TRUE) +# add_definitions( +# -DDEBUG +# ) +endif( CMAKE_BUILD_TYPE STREQUAL "Debug") + find_package(OpenGL REQUIRED) include_directories(${OpenGL_INCLUDE_DIRS}) link_directories(${OpenGL_LIBRARY_DIRS}) @@ -106,6 +121,9 @@ endif(NOT OPENGL_FOUND) add_library( GLideN64 SHARED ${GLideN64_SOURCES}) +SET(GCC_CPP11_COMPILE_FLAGS "-std=c++0x") +SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_CPP11_COMPILE_FLAGS}" ) + SET_TARGET_PROPERTIES( GLideN64 PROPERTIES diff --git a/DepthBuffer.cpp b/DepthBuffer.cpp index d259c4f8..0575fa87 100644 --- a/DepthBuffer.cpp +++ b/DepthBuffer.cpp @@ -150,10 +150,9 @@ void DepthBuffer_Destroy() void DepthBuffer_SetBuffer( u32 address ) { - FrameBufferList & frameBuffer = frameBufferList(); - FrameBuffer * pFrameBuffer = FrameBuffer_FindBuffer(address); + FrameBuffer * pFrameBuffer = frameBufferList().findBuffer(address); if (pFrameBuffer == NULL) - pFrameBuffer = frameBuffer.top; + pFrameBuffer = frameBufferList().getCurrent(); DepthBuffer *current = depthBuffer.top; @@ -162,7 +161,7 @@ void DepthBuffer_SetBuffer( u32 address ) { if (current->address == address) { - if (pFrameBuffer != NULL && current->width != pFrameBuffer->width) { + if (pFrameBuffer != NULL && current->width != pFrameBuffer->m_width) { DepthBuffer_Remove( current ); current = NULL; break; @@ -177,7 +176,7 @@ void DepthBuffer_SetBuffer( u32 address ) current = DepthBuffer_AddTop(); current->address = address; - current->width = pFrameBuffer != NULL ? pFrameBuffer->width : VI.width; + current->width = pFrameBuffer != NULL ? pFrameBuffer->m_width : VI.width; current->depth_texture = NULL; if (config.frameBufferEmulation.enable) { glGenRenderbuffers(1, ¤t->renderbuf); @@ -188,18 +187,18 @@ void DepthBuffer_SetBuffer( u32 address ) const GLenum format = GL_DEPTH_COMPONENT24_OES; #endif if (pFrameBuffer != NULL) - glRenderbufferStorage(GL_RENDERBUFFER, format, pFrameBuffer->texture->realWidth, pFrameBuffer->texture->realHeight); + glRenderbufferStorage(GL_RENDERBUFFER, format, pFrameBuffer->m_pTexture->realWidth, pFrameBuffer->m_pTexture->realHeight); else glRenderbufferStorage(GL_RENDERBUFFER, format, (u32)pow2(OGL.width), (u32)pow2(OGL.height)); } } if (config.frameBufferEmulation.enable) { - FrameBuffer_AttachDepthBuffer(); + frameBufferList().attachDepthBuffer(); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "DepthBuffer_SetBuffer( 0x%08X ); color buffer is 0x%08X\n", - address, ( frameBuffer.top != NULL && frameBuffer.top->fbo > 0) ? frameBuffer.top->startAddress : 0 + address, ( pFrameBuffer != NULL && pFrameBuffer->m_FBO > 0) ? pFrameBuffer->m_startAddress : 0 ); #endif @@ -233,6 +232,6 @@ void DepthBuffer_ClearBuffer() { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current->fbo); OGL_DrawRect(0,0,VI.width, VI.height, color); glBindImageTexture(depthImageUnit, current->depth_texture->glName, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().top->fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().getCurrent()->m_FBO); #endif // GLES2 } diff --git a/FrameBuffer.cpp b/FrameBuffer.cpp index 2f6d703b..d3cbdebb 100644 --- a/FrameBuffer.cpp +++ b/FrameBuffer.cpp @@ -114,241 +114,140 @@ DepthBufferToRDRAM g_dbToRDRAM; #endif RDRAMtoFrameBuffer g_RDRAMtoFB; -void FrameBuffer_Init() +FrameBuffer::FrameBuffer() : m_cleared(false), m_pLoadTile(NULL), m_pDepthBuffer(NULL) { - FrameBufferList & frameBuffer = frameBufferList(); - frameBuffer.current = NULL; - frameBuffer.top = NULL; - frameBuffer.bottom = NULL; - frameBuffer.numBuffers = 0; - frameBuffer.drawBuffer = GL_BACK; -#ifndef GLES2 - g_fbToRDRAM.Init(); - g_dbToRDRAM.Init(); -#endif - g_RDRAMtoFB.Init(); + m_pTexture = textureCache().addFrameBufferTexture(); + glGenFramebuffers(1, &m_FBO); } -void FrameBuffer_RemoveBottom() +FrameBuffer::FrameBuffer(FrameBuffer && _other) : + m_startAddress(_other.m_startAddress), m_endAddress(_other.m_endAddress), + m_size(_other.m_size), m_width(_other.m_width), m_height(_other.m_height), m_fillcolor(_other.m_fillcolor), + m_scaleX(_other.m_scaleX), m_scaleY(_other.m_scaleY), m_cleared(_other.m_cleared), + m_FBO(_other.m_FBO), m_pTexture(_other.m_pTexture), m_pLoadTile(_other.m_pLoadTile), m_pDepthBuffer(_other.m_pDepthBuffer) { - FrameBufferList & frameBuffer = frameBufferList(); - FrameBuffer *newBottom = frameBuffer.bottom->higher; - - textureCache().removeFrameBufferTexture(frameBuffer.bottom->texture); - if (frameBuffer.bottom->fbo != 0) - glDeleteFramebuffers(1, &frameBuffer.bottom->fbo); - - if (frameBuffer.bottom == frameBuffer.top) - frameBuffer.top = NULL; - - free( frameBuffer.bottom ); - - frameBuffer.bottom = newBottom; - - if (frameBuffer.bottom != NULL) - frameBuffer.bottom->lower = NULL; - - frameBuffer.numBuffers--; + _other.m_FBO = 0; + _other.m_pTexture = NULL; + _other.m_pLoadTile = NULL; + _other.m_pDepthBuffer = NULL; } -void FrameBuffer_Remove( FrameBuffer *buffer ) + +FrameBuffer::~FrameBuffer() { - FrameBufferList & frameBuffer = frameBufferList(); - if ((buffer == frameBuffer.bottom) && - (buffer == frameBuffer.top)) - { - frameBuffer.top = NULL; - frameBuffer.bottom = NULL; - } - else if (buffer == frameBuffer.bottom) - { - frameBuffer.bottom = buffer->higher; - - if (frameBuffer.bottom) - frameBuffer.bottom->lower = NULL; - } - else if (buffer == frameBuffer.top) - { - frameBuffer.top = buffer->lower; - - if (frameBuffer.top) - frameBuffer.top->higher = NULL; - } - else - { - buffer->higher->lower = buffer->lower; - buffer->lower->higher = buffer->higher; - } - - if (buffer->texture != NULL) - textureCache().removeFrameBufferTexture(buffer->texture); - if (buffer->fbo != 0) - glDeleteFramebuffers(1, &buffer->fbo); - - free( buffer ); - - frameBuffer.numBuffers--; + if (m_FBO != 0) + glDeleteFramebuffers(1, &m_FBO); + if (m_pTexture != NULL) + textureCache().removeFrameBufferTexture(m_pTexture); } -void FrameBuffer_RemoveBuffer( u32 address ) +void FrameBufferList::init() { - FrameBuffer *current = frameBufferList().bottom; - - while (current != NULL) - { - if (current->startAddress == address) - { - //current->texture = NULL; - FrameBuffer_Remove( current ); - return; - } - current = current->higher; - } + m_pCurrent = NULL; } -FrameBuffer *FrameBuffer_AddTop() -{ - FrameBufferList & frameBuffer = frameBufferList(); - FrameBuffer *newtop = (FrameBuffer*)malloc( sizeof( FrameBuffer ) ); - - newtop->texture = textureCache().addFrameBufferTexture(); - newtop->pDepthBuffer = NULL; - newtop->fbo = 0; - - newtop->lower = frameBuffer.top; - newtop->higher = NULL; - - if (frameBuffer.top) - frameBuffer.top->higher = newtop; - - if (!frameBuffer.bottom) - frameBuffer.bottom = newtop; - - frameBuffer.top = newtop; - - frameBuffer.numBuffers++; - - return newtop; +void FrameBufferList::destroy() { + m_list.clear(); + m_pCurrent = NULL; } -void FrameBuffer_MoveToTop( FrameBuffer *newtop ) +FrameBuffer * FrameBufferList::findBuffer(u32 _address) { - FrameBufferList & frameBuffer = frameBufferList(); - if (newtop == frameBuffer.top) - return; - - if (newtop == frameBuffer.bottom) - { - frameBuffer.bottom = newtop->higher; - frameBuffer.bottom->lower = NULL; - } - else - { - newtop->higher->lower = newtop->lower; - newtop->lower->higher = newtop->higher; - } - - newtop->higher = NULL; - newtop->lower = frameBuffer.top; - frameBuffer.top->higher = newtop; - frameBuffer.top = newtop; + for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) + if (iter->m_startAddress <= _address && iter->m_endAddress >= _address) + return &(*iter); + return NULL; } -void FrameBuffer_Destroy() +FrameBuffer * FrameBufferList::findTmpBuffer(u32 _address) { - FrameBufferList & frameBuffer = frameBufferList(); - while (frameBuffer.bottom) - FrameBuffer_RemoveBottom(); - frameBuffer.top = frameBuffer.bottom = frameBuffer.current = NULL; -#ifndef GLES2 - g_fbToRDRAM.Destroy(); - g_dbToRDRAM.Destroy(); -#endif - g_RDRAMtoFB.Destroy(); + for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) + if (iter->m_startAddress > _address || iter->m_endAddress < _address) + return &(*iter); + return NULL; } -void FrameBuffer_SaveBuffer( u32 address, u16 format, u16 size, u16 width, u16 height ) +void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _width, u16 _height ) { - FrameBufferList & frameBuffer = frameBufferList(); - frameBuffer.drawBuffer = GL_FRAMEBUFFER; - FrameBuffer *current = frameBuffer.top; - if (current != NULL && gDP.colorImage.height > 1) { - current->endAddress = current->startAddress + (((current->width * gDP.colorImage.height) << current->size >> 1) - 1); - if (!config.frameBufferEmulation.copyToRDRAM && !current->cleared) - gDPFillRDRAM(current->startAddress, 0, 0, current->width, gDP.colorImage.height, current->width, current->size, frameBuffer.top->fillcolor); + m_drawBuffer = GL_FRAMEBUFFER; + if (m_pCurrent != NULL && gDP.colorImage.height > 1) { + m_pCurrent->m_endAddress = m_pCurrent->m_startAddress + (((m_pCurrent->m_width * gDP.colorImage.height) << m_pCurrent->m_size >> 1) - 1); + if (!config.frameBufferEmulation.copyToRDRAM && !m_pCurrent->m_cleared) + gDPFillRDRAM(m_pCurrent->m_startAddress, 0, 0, m_pCurrent->m_width, gDP.colorImage.height, m_pCurrent->m_width, m_pCurrent->m_size, m_pCurrent->m_fillcolor); } - current = FrameBuffer_FindBuffer(address); - if (current != NULL) { - if ((current->startAddress != address) || - (current->width != width) || + if (m_pCurrent == NULL || m_pCurrent->m_startAddress != _address) + m_pCurrent = findBuffer(_address); + if (m_pCurrent != NULL) { + if ((m_pCurrent->m_startAddress != _address) || + (m_pCurrent->m_width != _width) || //(current->height != height) || //(current->size != size) || // TODO FIX ME - (current->scaleX != OGL.scaleX) || - (current->scaleY != OGL.scaleY)) + (m_pCurrent->m_scaleX != OGL.scaleX) || + (m_pCurrent->m_scaleY != OGL.scaleY)) { - FrameBuffer_Remove( current ); - current = NULL; + removeBuffer(m_pCurrent->m_startAddress); + m_pCurrent = NULL; } else { - FrameBuffer_MoveToTop( current ); - glBindFramebuffer(GL_FRAMEBUFFER, current->fbo); - if (current->size != size) { + glBindFramebuffer(GL_FRAMEBUFFER, m_pCurrent->m_FBO); + if (m_pCurrent->m_size != _size) { f32 fillColor[4]; gDPGetFillColor(fillColor); OGL_ClearColorBuffer(fillColor); - current->size = size; - current->texture->format = format; - current->texture->size = size; + m_pCurrent->m_size = _size; + m_pCurrent->m_pTexture->format = _format; + m_pCurrent->m_pTexture->size = _size; } } } - const bool bNew = current == NULL; + const bool bNew = m_pCurrent == NULL; if (bNew) { // Wasn't found or removed, create a new one - current = FrameBuffer_AddTop(); + m_list.emplace_front(); + FrameBuffer & buffer = m_list.front(); - current->startAddress = address; - current->endAddress = address + ((width * height << size >> 1) - 1); - current->width = width; - current->height = height; - current->size = size; - current->scaleX = OGL.scaleX; - current->scaleY = OGL.scaleY; - current->fillcolor = 0; + buffer.m_startAddress = _address; + buffer.m_endAddress = _address + ((_width * _height << _size >> 1) - 1); + buffer.m_width = _width; + buffer.m_height = _height; + buffer.m_size = _size; + buffer.m_scaleX = OGL.scaleX; + buffer.m_scaleY = OGL.scaleY; + buffer.m_fillcolor = 0; - current->texture->width = (u32)(current->width * OGL.scaleX); - current->texture->height = (u32)(current->height * OGL.scaleY); - current->texture->format = format; - current->texture->size = size; - current->texture->clampS = 1; - current->texture->clampT = 1; - current->texture->address = current->startAddress; - current->texture->clampWidth = current->width; - current->texture->clampHeight = current->height; - current->texture->frameBufferTexture = TRUE; - current->texture->maskS = 0; - current->texture->maskT = 0; - current->texture->mirrorS = 0; - current->texture->mirrorT = 0; - current->texture->realWidth = (u32)pow2( current->texture->width ); - current->texture->realHeight = (u32)pow2( current->texture->height ); - current->texture->textureBytes = current->texture->realWidth * current->texture->realHeight * 4; - textureCache().addFrameBufferTextureSize(current->texture->textureBytes); + buffer.m_pTexture->width = (u32)(buffer.m_width * OGL.scaleX); + buffer.m_pTexture->height = (u32)(buffer.m_height * OGL.scaleY); + buffer.m_pTexture->format = _format; + buffer.m_pTexture->size = _size; + buffer.m_pTexture->clampS = 1; + buffer.m_pTexture->clampT = 1; + buffer.m_pTexture->address = buffer.m_startAddress; + buffer.m_pTexture->clampWidth = buffer.m_width; + buffer.m_pTexture->clampHeight = buffer.m_height; + buffer.m_pTexture->frameBufferTexture = TRUE; + buffer.m_pTexture->maskS = 0; + buffer.m_pTexture->maskT = 0; + buffer.m_pTexture->mirrorS = 0; + buffer.m_pTexture->mirrorT = 0; + buffer.m_pTexture->realWidth = (u32)pow2( buffer.m_pTexture->width ); + buffer.m_pTexture->realHeight = (u32)pow2( buffer.m_pTexture->height ); + buffer.m_pTexture->textureBytes = buffer.m_pTexture->realWidth * buffer.m_pTexture->realHeight * 4; + textureCache().addFrameBufferTextureSize(buffer.m_pTexture->textureBytes); - glBindTexture( GL_TEXTURE_2D, current->texture->glName ); - if (size > G_IM_SIZ_8b) - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, current->texture->realWidth, current->texture->realHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture( GL_TEXTURE_2D, buffer.m_pTexture->glName ); + if (_size > G_IM_SIZ_8b) + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, buffer.m_pTexture->realWidth, buffer.m_pTexture->realHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); else - glTexImage2D(GL_TEXTURE_2D, 0, monohromeInternalformat, current->texture->realWidth, current->texture->realHeight, 0, monohromeformat, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, monohromeInternalformat, buffer.m_pTexture->realWidth, buffer.m_pTexture->realHeight, 0, monohromeformat, GL_UNSIGNED_BYTE, NULL); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glBindFramebuffer(GL_FRAMEBUFFER, 0); - glGenFramebuffers(1, ¤t->fbo); - glBindFramebuffer(GL_FRAMEBUFFER, current->fbo); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, current->texture->glName, 0); + glBindFramebuffer(GL_FRAMEBUFFER, buffer.m_FBO); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer.m_pTexture->glName, 0); + m_pCurrent = &buffer; } - FrameBuffer_AttachDepthBuffer(); + attachDepthBuffer(); #ifdef DEBUG DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "FrameBuffer_SaveBuffer( 0x%08X ); depth buffer is 0x%08X\n", @@ -356,31 +255,38 @@ void FrameBuffer_SaveBuffer( u32 address, u16 format, u16 size, u16 width, u16 h ); #endif // HACK ALERT: Dirty hack for Mario Tennis score board - if (bNew && (current->startAddress == 0x13ba50 || current->startAddress == 0x264430)) - g_RDRAMtoFB.CopyFromRDRAM(current->startAddress, false); - *(u32*)&RDRAM[current->startAddress] = current->startAddress; + if (bNew && (m_pCurrent->m_startAddress == 0x13ba50 || m_pCurrent->m_startAddress == 0x264430)) + g_RDRAMtoFB.CopyFromRDRAM(m_pCurrent->m_startAddress, false); + *(u32*)&RDRAM[m_pCurrent->m_startAddress] = m_pCurrent->m_startAddress; - current->cleared = false; + m_pCurrent->m_cleared = false; gSP.changed |= CHANGED_TEXTURE; } -static -void _initDepthTexture() +void FrameBufferList::removeBuffer(u32 _address ) +{ + for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) + if (iter->m_startAddress == _address) { + m_list.erase(iter); + return; + } +} + +void FrameBufferList::_initDepthTexture() { #ifndef GLES2 - FrameBufferList & frameBuffer = frameBufferList(); depthBuffer.top->depth_texture = textureCache().addFrameBufferTexture(); - depthBuffer.top->depth_texture->width = (u32)(frameBuffer.top->width * OGL.scaleX); - depthBuffer.top->depth_texture->height = (u32)(frameBuffer.top->height * OGL.scaleY); + depthBuffer.top->depth_texture->width = (u32)(m_pCurrent->m_width * OGL.scaleX); + depthBuffer.top->depth_texture->height = (u32)(m_pCurrent->m_height * OGL.scaleY); depthBuffer.top->depth_texture->format = 0; depthBuffer.top->depth_texture->size = 2; depthBuffer.top->depth_texture->clampS = 1; depthBuffer.top->depth_texture->clampT = 1; - depthBuffer.top->depth_texture->address = frameBuffer.top->startAddress; - depthBuffer.top->depth_texture->clampWidth = frameBuffer.top->width; - depthBuffer.top->depth_texture->clampHeight = frameBuffer.top->height; + depthBuffer.top->depth_texture->address = m_pCurrent->m_startAddress; + depthBuffer.top->depth_texture->clampWidth = m_pCurrent->m_width; + depthBuffer.top->depth_texture->clampHeight = m_pCurrent->m_height; depthBuffer.top->depth_texture->frameBufferTexture = TRUE; depthBuffer.top->depth_texture->maskS = 0; depthBuffer.top->depth_texture->maskT = 0; @@ -401,21 +307,20 @@ void _initDepthTexture() glBindFramebuffer(GL_DRAW_FRAMEBUFFER, depthBuffer.top->fbo); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, depthBuffer.top->depth_texture->glName, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer.top->fbo); - frameBuffer.top->pDepthBuffer = depthBuffer.top; + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_pCurrent->m_FBO); + m_pCurrent->m_pDepthBuffer = depthBuffer.top; DepthBuffer_ClearBuffer(); #else depthBuffer.top->depth_texture = NULL; #endif // GLES2 } -void FrameBuffer_AttachDepthBuffer() +void FrameBufferList::attachDepthBuffer() { - FrameBufferList & frameBuffer = frameBufferList(); - if ( frameBuffer.top != NULL && frameBuffer.top->fbo > 0 && depthBuffer.top != NULL && depthBuffer.top->renderbuf > 0) { + if (m_pCurrent != NULL && m_pCurrent->m_FBO > 0 && depthBuffer.top != NULL && depthBuffer.top->renderbuf > 0) { if (depthBuffer.top->depth_texture == NULL) _initDepthTexture(); - frameBuffer.top->pDepthBuffer = depthBuffer.top; + m_pCurrent->m_pDepthBuffer = depthBuffer.top; glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer.top->renderbuf); #ifndef GLES2 GLuint attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT }; @@ -423,8 +328,8 @@ void FrameBuffer_AttachDepthBuffer() glBindImageTexture(depthImageUnit, depthBuffer.top->depth_texture->glName, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); #endif assert(checkFBO()); - } else if (frameBuffer.top != NULL) { - frameBuffer.top->pDepthBuffer = NULL; + } else if (m_pCurrent != NULL) { + m_pCurrent->m_pDepthBuffer = NULL; #ifndef GLES2 GLuint attachments[1] = { GL_COLOR_ATTACHMENT0 }; glDrawBuffers(1, attachments); @@ -434,13 +339,33 @@ void FrameBuffer_AttachDepthBuffer() currentCombiner()->updateDepthInfo(true); } +void FrameBuffer_Init() +{ + frameBufferList().init(); #ifndef GLES2 -void FrameBuffer_RenderBuffer( u32 address ) + g_fbToRDRAM.Init(); + g_dbToRDRAM.Init(); +#endif + g_RDRAMtoFB.Init(); +} + +void FrameBuffer_Destroy() +{ + g_RDRAMtoFB.Destroy(); +#ifndef GLES2 + g_dbToRDRAM.Destroy(); + g_fbToRDRAM.Destroy(); +#endif + frameBufferList().destroy(); +} + +#ifndef GLES2 +void FrameBufferList::renderBuffer(u32 _address) { if (_SHIFTR( *REG.VI_H_START, 0, 10 ) == 0) // H width is zero. Don't draw return; - FrameBuffer *current = FrameBuffer_FindBuffer(address); - if (current == NULL) + FrameBuffer *pBuffer = findBuffer(_address); + if (pBuffer == NULL) return; GLint srcY0, srcY1, dstY0, dstY1; GLint partHeight = 0; @@ -452,7 +377,7 @@ void FrameBuffer_RenderBuffer( u32 address ) if (VI.vStart != vStart) dstY0 += vStart - VI.vStart; dstY1 = dstY0 + vEnd - vStart; - srcY0 = ((address - current->startAddress) << 1 >> current->size) / (*REG.VI_WIDTH); + srcY0 = ((_address - pBuffer->m_startAddress) << 1 >> pBuffer->m_size) / (*REG.VI_WIDTH); srcY1 = srcY0 + VI.real_height; if (srcY1 > VI.height) { partHeight = srcY1 - VI.height; @@ -463,7 +388,7 @@ void FrameBuffer_RenderBuffer( u32 address ) // glDisable(GL_SCISSOR_TEST) does not affect glBlitFramebuffer, at least on AMD glScissor( 0, 0, OGL.width, OGL.height ); glDisable(GL_SCISSOR_TEST); - glBindFramebuffer(GL_READ_FRAMEBUFFER, current->fbo); + glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_FBO); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); //glDrawBuffer( GL_BACK ); float clearColor[4] = {0.0f, 0.0f, 0.0f, 0.0f}; @@ -475,13 +400,13 @@ void FrameBuffer_RenderBuffer( u32 address ) ); if (partHeight > 0) { const u32 size = *REG.VI_STATUS & 3; - current = FrameBuffer_FindBuffer(address + (((*REG.VI_WIDTH)*VI.height)<>1)); - if (current != NULL) { + pBuffer = findBuffer(_address + (((*REG.VI_WIDTH)*VI.height)<>1)); + if (pBuffer != NULL) { srcY0 = 0; srcY1 = partHeight; dstY0 = dstY1; dstY1 = dstY0 + partHeight; - glBindFramebuffer(GL_READ_FRAMEBUFFER, current->fbo); + glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_FBO); glBlitFramebuffer( 0, (GLint)(srcY0*OGL.scaleY), OGL.width, (GLint)(srcY1*OGL.scaleY), 0, OGL.heightOffset + (GLint)(dstY0*viScaleY), OGL.width, OGL.heightOffset + (GLint)(dstY1*viScaleY), @@ -491,21 +416,21 @@ void FrameBuffer_RenderBuffer( u32 address ) } glEnable(GL_SCISSOR_TEST); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().top->fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_pCurrent->m_FBO); OGL_SwapBuffers(); gDP.changed |= CHANGED_SCISSOR; } #else -void FrameBuffer_RenderBuffer( u32 address ) +void FrameBufferList::renderBuffer(u32 _address) { if (_SHIFTR( *REG.VI_H_START, 0, 10 ) == 0) // H width is zero. Don't draw return; - FrameBuffer *current = FrameBuffer_FindBuffer(address); - if (current == NULL) + FrameBuffer *pBuffer = findBuffer(_address); + if (pBuffer == NULL) return; - Combiner_SetCombine( EncodeCombineMode( 0, 0, 0, TEXEL0, 0, 0, 0, 1, 0, 0, 0, TEXEL0, 0, 0, 0, 1 ) ); + CombinerInfo::get().setCombine( EncodeCombineMode( 0, 0, 0, TEXEL0, 0, 0, 0, 1, 0, 0, 0, TEXEL0, 0, 0, 0, 1 ) ); glDisable( GL_BLEND ); glDisable(GL_SCISSOR_TEST); glDisable(GL_DEPTH_TEST); @@ -513,97 +438,81 @@ void FrameBuffer_RenderBuffer( u32 address ) glDisable( GL_POLYGON_OFFSET_FILL ); gSP.changed = gDP.changed = 0; - const u32 width = current->width; - const u32 height = current->height; + const u32 width = pBuffer->m_width; + const u32 height = pBuffer->m_height; - current->texture->scaleS = OGL.scaleX / (float)current->texture->realWidth; - current->texture->scaleT = OGL.scaleY / (float)current->texture->realHeight; - current->texture->shiftScaleS = 1.0f; - current->texture->shiftScaleT = 1.0f; - current->texture->offsetS = 0; - current->texture->offsetT = (float)height; - TextureCache_ActivateTexture( 0, current->texture ); + pBuffer->m_pTexture->scaleS = OGL.scaleX / (float)pBuffer->m_pTexture->realWidth; + pBuffer->m_pTexture->scaleT = OGL.scaleY / (float)pBuffer->m_pTexture->realHeight; + pBuffer->m_pTexture->shiftScaleS = 1.0f; + pBuffer->m_pTexture->shiftScaleT = 1.0f; + pBuffer->m_pTexture->offsetS = 0; + pBuffer->m_pTexture->offsetT = (float)height; + textureCache().activateTexture(0, pBuffer->m_pTexture); gSP.textureTile[0]->fuls = gSP.textureTile[0]->fult = 0.0f; - combiner.current->compiled->UpdateTextureInfo(true); + currentCombiner()->updateTextureInfo(true); - FrameBufferList & frameBuffer = frameBufferList(); glBindFramebuffer(GL_FRAMEBUFFER, 0); - frameBuffer.drawBuffer = GL_BACK; + drawBuffer = GL_BACK; OGL_DrawTexturedRect( 0.0f, 0.0f, width, height, 0.0f, 0.0f, width-1.0f, height-1.0f, false ); OGL_SwapBuffers(); - frameBuffer.drawBuffer = GL_FRAMEBUFFER; + drawBuffer = GL_FRAMEBUFFER; glEnable(GL_SCISSOR_TEST); - glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer.top->fbo); + glBindFramebuffer(GL_FRAMEBUFFER, m_pCurrent->m_FBO); gSP.changed |= CHANGED_TEXTURE | CHANGED_VIEWPORT; gDP.changed |= CHANGED_COMBINE; } #endif -FrameBuffer *FrameBuffer_FindBuffer( u32 address ) +void FrameBuffer_ActivateBufferTexture(s16 t, FrameBuffer *pBuffer) { - FrameBuffer *current = frameBufferList().top; - - while (current) - { - if ((current->startAddress <= address) && - (current->endAddress >= address)) - return current; - current = current->lower; - } - - return NULL; -} - -void FrameBuffer_ActivateBufferTexture( s16 t, FrameBuffer *buffer ) -{ - buffer->texture->scaleS = OGL.scaleX / (float)buffer->texture->realWidth; - buffer->texture->scaleT = OGL.scaleY / (float)buffer->texture->realHeight; + pBuffer->m_pTexture->scaleS = OGL.scaleX / (float)pBuffer->m_pTexture->realWidth; + pBuffer->m_pTexture->scaleT = OGL.scaleY / (float)pBuffer->m_pTexture->realHeight; if (gSP.textureTile[t]->shifts > 10) - buffer->texture->shiftScaleS = (float)(1 << (16 - gSP.textureTile[t]->shifts)); + pBuffer->m_pTexture->shiftScaleS = (float)(1 << (16 - gSP.textureTile[t]->shifts)); else if (gSP.textureTile[t]->shifts > 0) - buffer->texture->shiftScaleS = 1.0f / (float)(1 << gSP.textureTile[t]->shifts); + pBuffer->m_pTexture->shiftScaleS = 1.0f / (float)(1 << gSP.textureTile[t]->shifts); else - buffer->texture->shiftScaleS = 1.0f; + pBuffer->m_pTexture->shiftScaleS = 1.0f; if (gSP.textureTile[t]->shiftt > 10) - buffer->texture->shiftScaleT = (float)(1 << (16 - gSP.textureTile[t]->shiftt)); + pBuffer->m_pTexture->shiftScaleT = (float)(1 << (16 - gSP.textureTile[t]->shiftt)); else if (gSP.textureTile[t]->shiftt > 0) - buffer->texture->shiftScaleT = 1.0f / (float)(1 << gSP.textureTile[t]->shiftt); + pBuffer->m_pTexture->shiftScaleT = 1.0f / (float)(1 << gSP.textureTile[t]->shiftt); else - buffer->texture->shiftScaleT = 1.0f; + pBuffer->m_pTexture->shiftScaleT = 1.0f; - const u32 shift = gSP.textureTile[t]->imageAddress - buffer->startAddress; - const u32 factor = buffer->width << buffer->size >> 1; + const u32 shift = gSP.textureTile[t]->imageAddress - pBuffer->m_startAddress; + const u32 factor = pBuffer->m_width << pBuffer->m_size >> 1; if (gSP.textureTile[t]->loadType == LOADTYPE_TILE) { - buffer->texture->offsetS = buffer->loadTile->uls; - buffer->texture->offsetT = (float)(buffer->height - (buffer->loadTile->ult + shift/factor)); + pBuffer->m_pTexture->offsetS = pBuffer->m_pLoadTile->uls; + pBuffer->m_pTexture->offsetT = (float)(pBuffer->m_height - (pBuffer->m_pLoadTile->ult + shift/factor)); } else { - buffer->texture->offsetS = (float)(shift % factor); - buffer->texture->offsetT = (float)(buffer->height - shift/factor); + pBuffer->m_pTexture->offsetS = (float)(shift % factor); + pBuffer->m_pTexture->offsetT = (float)(pBuffer->m_height - shift/factor); } // FrameBuffer_RenderBuffer(buffer->startAddress); - textureCache().activateTexture(t, buffer->texture); + textureCache().activateTexture(t, pBuffer->m_pTexture); gDP.changed |= CHANGED_FB_TEXTURE; } -void FrameBuffer_ActivateBufferTextureBG( s16 t, FrameBuffer *buffer ) +void FrameBuffer_ActivateBufferTextureBG(s16 t, FrameBuffer *pBuffer ) { - buffer->texture->scaleS = OGL.scaleX / (float)buffer->texture->realWidth; - buffer->texture->scaleT = OGL.scaleY / (float)buffer->texture->realHeight; + pBuffer->m_pTexture->scaleS = OGL.scaleX / (float)pBuffer->m_pTexture->realWidth; + pBuffer->m_pTexture->scaleT = OGL.scaleY / (float)pBuffer->m_pTexture->realHeight; - buffer->texture->shiftScaleS = 1.0f; - buffer->texture->shiftScaleT = 1.0f; + pBuffer->m_pTexture->shiftScaleS = 1.0f; + pBuffer->m_pTexture->shiftScaleT = 1.0f; - buffer->texture->offsetS = gSP.bgImage.imageX; - buffer->texture->offsetT = (float)buffer->height - gSP.bgImage.imageY; + pBuffer->m_pTexture->offsetS = gSP.bgImage.imageX; + pBuffer->m_pTexture->offsetT = (float)pBuffer->m_height - gSP.bgImage.imageY; // FrameBuffer_RenderBuffer(buffer->startAddress); - textureCache().activateTexture(t, buffer->texture); + textureCache().activateTexture(t, pBuffer->m_pTexture); gDP.changed |= CHANGED_FB_TEXTURE; } @@ -659,22 +568,22 @@ void FrameBufferToRDRAM::Destroy() { } void FrameBufferToRDRAM::CopyToRDRAM( u32 address, bool bSync ) { - FrameBuffer *current = FrameBuffer_FindBuffer(address); - if (current == NULL) + FrameBuffer *pBuffer = frameBufferList().findBuffer(address); + if (pBuffer == NULL) return; - address = current->startAddress; - glBindFramebuffer(GL_READ_FRAMEBUFFER, current->fbo); + address = pBuffer->m_startAddress; + glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_FBO); glReadBuffer(GL_COLOR_ATTACHMENT0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO); GLuint attachment = GL_COLOR_ATTACHMENT0; glDrawBuffers(1, &attachment); glBlitFramebuffer( 0, 0, OGL.width, OGL.height, - 0, 0, current->width, current->height, + 0, 0, pBuffer->m_width, pBuffer->m_height, GL_COLOR_BUFFER_BIT, GL_LINEAR ); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().top->fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().getCurrent()->m_FBO); glBindFramebuffer(GL_READ_FRAMEBUFFER, m_FBO); glReadBuffer(GL_COLOR_ATTACHMENT0); @@ -705,7 +614,7 @@ void FrameBufferToRDRAM::CopyToRDRAM( u32 address, bool bSync ) { glReadPixels( 0, 0, VI.width, VI.height, GL_RGBA, GL_UNSIGNED_BYTE, pixelData ); #endif // GLES2 - if (current->size == G_IM_SIZ_32b) { + if (pBuffer->m_size == G_IM_SIZ_32b) { u32 *ptr_dst = (u32*)(RDRAM + m_aAddress[nextIndex]); u32 *ptr_src = (u32*)pixelData; @@ -793,11 +702,11 @@ void DepthBufferToRDRAM::Destroy() { } void DepthBufferToRDRAM::CopyToRDRAM( u32 address) { - FrameBuffer *current = FrameBuffer_FindBuffer(address); - if (current == NULL || current->pDepthBuffer == NULL) + FrameBuffer *pBuffer = frameBufferList().findBuffer(address); + if (pBuffer == NULL || pBuffer->m_pDepthBuffer == NULL) return; - DepthBuffer * pDepthBuffer = current->pDepthBuffer; + DepthBuffer * pDepthBuffer = pBuffer->m_pDepthBuffer; address = pDepthBuffer->address; glBindFramebuffer(GL_READ_FRAMEBUFFER, pDepthBuffer->fbo); glReadBuffer(GL_COLOR_ATTACHMENT0); @@ -806,10 +715,10 @@ void DepthBufferToRDRAM::CopyToRDRAM( u32 address) { glDrawBuffers(1, &attachment); glBlitFramebuffer( 0, 0, OGL.width, OGL.height, - 0, 0, current->width, current->height, + 0, 0, pBuffer->m_width, pBuffer->m_height, GL_COLOR_BUFFER_BIT, GL_LINEAR ); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().top->fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().getCurrent()->m_FBO); m_curIndex = (m_curIndex + 1) % 2; const u32 nextIndex = m_aAddress[m_curIndex] == 0 ? m_curIndex : (m_curIndex + 1) % 2; @@ -888,12 +797,12 @@ void RDRAMtoFrameBuffer::Destroy() void RDRAMtoFrameBuffer::CopyFromRDRAM( u32 _address, bool _bUseAlpha) { - FrameBuffer *current = FrameBuffer_FindBuffer(_address); - if (current == NULL || current->size < G_IM_SIZ_16b) + FrameBuffer *pBuffer = frameBufferList().findBuffer(_address); + if (pBuffer == NULL || pBuffer->m_size < G_IM_SIZ_16b) return; - const u32 width = current->width; - const u32 height = current->height; + const u32 width = pBuffer->m_width; + const u32 height = pBuffer->m_height; m_pTexture->width = width; m_pTexture->height = height; const u32 dataSize = width*height*4; @@ -914,7 +823,7 @@ void RDRAMtoFrameBuffer::CopyFromRDRAM( u32 _address, bool _bUseAlpha) u32 empty = 0; u32 r, g, b,a, idx; - if (current->size == G_IM_SIZ_16b) { + if (pBuffer->m_size == G_IM_SIZ_16b) { u16 * src = (u16*)image; u16 col; const u32 bound = (RDRAMSize + 1 - _address) >> 1; @@ -975,7 +884,7 @@ void RDRAMtoFrameBuffer::CopyFromRDRAM( u32 _address, bool _bUseAlpha) glBindFramebuffer(GL_READ_FRAMEBUFFER, m_FBO); const GLuint attachment = GL_COLOR_ATTACHMENT0; glReadBuffer(attachment); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current->fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, pBuffer->m_FBO); glDrawBuffers(1, &attachment); glBlitFramebuffer( 0, 0, width, height, @@ -983,7 +892,7 @@ void RDRAMtoFrameBuffer::CopyFromRDRAM( u32 _address, bool _bUseAlpha) GL_COLOR_BUFFER_BIT, GL_LINEAR ); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().top->fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().getCurrent()->m_FBO); #else if (_bUseAlpha) CombinerInfo::get().setCombine( EncodeCombineMode( 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0 ) ); diff --git a/FrameBuffer.h b/FrameBuffer.h index a0d02db5..dac24cba 100644 --- a/FrameBuffer.h +++ b/FrameBuffer.h @@ -1,6 +1,8 @@ #ifndef FRAMEBUFFER_H #define FRAMEBUFFER_H +#include + #include "Types.h" #include "Textures.h" struct gDPTile; @@ -8,24 +10,34 @@ struct DepthBuffer; struct FrameBuffer { - FrameBuffer *higher, *lower; + FrameBuffer(); + FrameBuffer(FrameBuffer && _other); + ~FrameBuffer(); - CachedTexture *texture; - DepthBuffer *pDepthBuffer; - GLuint fbo; + u32 m_startAddress, m_endAddress; + u32 m_size, m_width, m_height, m_fillcolor; + float m_scaleX, m_scaleY; + bool m_cleared; - u32 startAddress, endAddress; - u32 size, width, height, fillcolor; - bool cleared; - gDPTile *loadTile; - float scaleX, scaleY; + GLuint m_FBO; + gDPTile *m_pLoadTile; + CachedTexture *m_pTexture; + DepthBuffer *m_pDepthBuffer; }; -struct FrameBufferList +class FrameBufferList { - FrameBuffer *top, *bottom, *current; - int numBuffers; - GLenum drawBuffer; +public: + void init(); + void destroy(); + void saveBuffer( u32 _address, u16 _format, u16 _size, u16 _width, u16 _height ); + void removeBuffer( u32 _address ); + void attachDepthBuffer(); + FrameBuffer * findBuffer(u32 _address); + FrameBuffer * findTmpBuffer(u32 _address); + FrameBuffer * getCurrent() const {return m_pCurrent;} + void renderBuffer(u32 _address); + bool isFboMode() const {return m_drawBuffer == GL_FRAMEBUFFER;} static FrameBufferList & get() { @@ -34,8 +46,15 @@ struct FrameBufferList } private: - FrameBufferList() : current(NULL), drawBuffer(GL_BACK) {} + FrameBufferList() : m_pCurrent(NULL), m_drawBuffer(GL_BACK) {} FrameBufferList(const FrameBufferList &); + + void _initDepthTexture(); + + typedef std::list FrameBuffers; + FrameBuffers m_list; + FrameBuffer * m_pCurrent; + GLenum m_drawBuffer; }; inline @@ -46,15 +65,10 @@ FrameBufferList & frameBufferList() void FrameBuffer_Init(); void FrameBuffer_Destroy(); -void FrameBuffer_SaveBuffer( u32 address, u16 format, u16 size, u16 width, u16 height ); -void FrameBuffer_RenderBuffer( u32 address ); -void FrameBuffer_RemoveBuffer( u32 address ); -void FrameBuffer_AttachDepthBuffer(); void FrameBuffer_CopyToRDRAM( u32 address, bool bSync ); void FrameBuffer_CopyFromRDRAM( u32 address, bool bUseAlpha ); void FrameBuffer_CopyDepthBuffer( u32 address ); -FrameBuffer *FrameBuffer_FindBuffer( u32 address ); -void FrameBuffer_ActivateBufferTexture( s16 t, FrameBuffer *buffer ); -void FrameBuffer_ActivateBufferTextureBG( s16 t, FrameBuffer *buffer ); +void FrameBuffer_ActivateBufferTexture(s16 t, FrameBuffer *pBuffer); +void FrameBuffer_ActivateBufferTextureBG(s16 t, FrameBuffer *pBuffer); #endif diff --git a/GLSLCombiner.cpp b/GLSLCombiner.cpp index 0a4498b3..8b2636e8 100644 --- a/GLSLCombiner.cpp +++ b/GLSLCombiner.cpp @@ -693,8 +693,8 @@ void ShaderCombiner::updateDepthInfo(bool _bForce) { if (!OGL.bImageTexture) return; - FrameBufferList & frameBuffer = frameBufferList(); - if (frameBuffer.top == NULL || frameBuffer.top->pDepthBuffer == NULL) + FrameBuffer * pBuffer = frameBufferList().getCurrent(); + if (pBuffer == NULL || pBuffer->m_pDepthBuffer == NULL) return; const int nDepthEnabled = (gSP.geometryMode & G_ZBUFFER) > 0 ? 1 : 0; @@ -728,7 +728,7 @@ void ShaderCombiner::updateAlphaTestInfo(bool _bForce) { void GLSL_RenderDepth() { if (!OGL.bImageTexture) return; - FrameBufferList & frameBuffer = frameBufferList(); + FrameBuffer * pBuffer = frameBufferList().getCurrent(); #if 0 glBindFramebuffer(GL_READ_FRAMEBUFFER, g_zbuf_fbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); @@ -740,15 +740,15 @@ void GLSL_RenderDepth() { ); glDrawBuffer( GL_BACK ); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer.top != NULL ? frameBuffer.top->fbo : 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, pBuffer != NULL ? pBuffer->m_FBO : 0); #else - if (frameBuffer.top == NULL || frameBuffer.top->pDepthBuffer == NULL) + if (pBuffer == NULL || pBuffer->m_pDepthBuffer == NULL) return; glBindImageTexture(depthImageUnit, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); glPushAttrib( GL_ENABLE_BIT | GL_VIEWPORT_BIT ); glActiveTexture( GL_TEXTURE0 ); - glBindTexture(GL_TEXTURE_2D, frameBuffer.top->pDepthBuffer->depth_texture->glName); + glBindTexture(GL_TEXTURE_2D, pBuffer->m_pDepthBuffer->depth_texture->glName); // glBindTexture(GL_TEXTURE_2D, g_zlut_tex); CombinerInfo::get().setCombine( EncodeCombineMode( 0, 0, 0, TEXEL0, 0, 0, 0, 1, 0, 0, 0, TEXEL0, 0, 0, 0, 1 ) ); @@ -794,8 +794,8 @@ void GLSL_RenderDepth() { #else OGL_SwapBuffers(); #endif - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer.top->fbo); - glBindImageTexture(depthImageUnit, frameBuffer.top->pDepthBuffer->depth_texture->glName, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, pBuffer->m_FBO); + glBindImageTexture(depthImageUnit, pBuffer->m_pDepthBuffer->depth_texture->glName, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); glLoadIdentity(); diff --git a/OpenGL.cpp b/OpenGL.cpp index e472189a..095953ec 100644 --- a/OpenGL.cpp +++ b/OpenGL.cpp @@ -589,11 +589,11 @@ void OGL_UpdateCullFace() void OGL_UpdateViewport() { - if (frameBufferList().drawBuffer == GL_BACK) + if (!frameBufferList().isFboMode()) glViewport( gSP.viewport.x * OGL.scaleX, (VI.height - (gSP.viewport.y + gSP.viewport.height)) * OGL.scaleY + OGL.heightOffset, gSP.viewport.width * OGL.scaleX, gSP.viewport.height * OGL.scaleY ); else - glViewport( gSP.viewport.x * OGL.scaleX, (frameBufferList().top->height - (gSP.viewport.y + gSP.viewport.height)) * OGL.scaleY, + glViewport( gSP.viewport.x * OGL.scaleX, (frameBufferList().getCurrent()->m_height - (gSP.viewport.y + gSP.viewport.height)) * OGL.scaleY, gSP.viewport.width * OGL.scaleX, gSP.viewport.height * OGL.scaleY ); } @@ -798,9 +798,9 @@ void OGL_UpdateStates() if (gDP.changed & CHANGED_SCISSOR) { - FrameBufferList & frameBuffer = frameBufferList(); - const u32 screenHeight = (frameBuffer.top == NULL || frameBuffer.top->height == 0 || frameBuffer.drawBuffer == GL_BACK) ? VI.height : frameBuffer.top->height; - glScissor( gDP.scissor.ulx * OGL.scaleX, (screenHeight - gDP.scissor.lry) * OGL.scaleY + (frameBuffer.drawBuffer == GL_BACK ? OGL.heightOffset : 0), + FrameBufferList & fbList = frameBufferList(); + const u32 screenHeight = (fbList.getCurrent() == NULL || fbList.getCurrent()->m_height == 0 || !fbList.isFboMode()) ? VI.height : fbList.getCurrent()->m_height; + glScissor( gDP.scissor.ulx * OGL.scaleX, (screenHeight - gDP.scissor.lry) * OGL.scaleY + (fbList.isFboMode() ? 0 : OGL.heightOffset), (gDP.scissor.lrx - gDP.scissor.ulx) * OGL.scaleX, (gDP.scissor.lry - gDP.scissor.uly) * OGL.scaleY ); } @@ -1017,16 +1017,18 @@ void OGL_DrawRect( int ulx, int uly, int lrx, int lry, float *color ) currentCombiner()->updateRenderState(); } - FrameBufferList & frameBuffer = frameBufferList(); - if (frameBuffer.drawBuffer != GL_FRAMEBUFFER) - glViewport( 0, (frameBuffer.drawBuffer == GL_BACK ? OGL.heightOffset : 0), OGL.width, OGL.height ); - else - glViewport( 0, 0, frameBuffer.top->width*frameBuffer.top->scaleX, frameBuffer.top->height*frameBuffer.top->scaleY ); + FrameBufferList & fbList = frameBufferList(); + FrameBuffer* pBuffer = fbList.getCurrent(); + if (!fbList.isFboMode()) + glViewport( 0, OGL.heightOffset, OGL.width, OGL.height ); + else { + glViewport( 0, 0, pBuffer->m_width*pBuffer->m_scaleX, pBuffer->m_height*pBuffer->m_scaleY ); + } glDisable(GL_SCISSOR_TEST); glDisable(GL_CULL_FACE); - const float scaleX = frameBuffer.drawBuffer == GL_FRAMEBUFFER ? 1.0f/frameBuffer.top->width : VI.rwidth; - const float scaleY = frameBuffer.drawBuffer == GL_FRAMEBUFFER ? 1.0f/frameBuffer.top->height : VI.rheight; + const float scaleX = fbList.isFboMode() ? 1.0f/pBuffer->m_width : VI.rwidth; + const float scaleY = fbList.isFboMode() ? 1.0f/pBuffer->m_height : VI.rheight; OGL.rect[0].x = (float) ulx * (2.0f * scaleX) - 1.0; OGL.rect[0].y = (float) uly * (-2.0f * scaleY) + 1.0; OGL.rect[1].x = (float) (lrx+1) * (2.0f * scaleX) - 1.0; @@ -1073,15 +1075,16 @@ void OGL_DrawTexturedRect( float ulx, float uly, float lrx, float lry, float uls GLS_SetShadowMapCombiner(); #endif // GLES2 - FrameBufferList & frameBuffer = frameBufferList(); - if (frameBuffer.drawBuffer != GL_FRAMEBUFFER) - glViewport( 0, (frameBuffer.drawBuffer == GL_BACK ? OGL.heightOffset : 0), OGL.width, OGL.height ); + FrameBufferList & fbList = frameBufferList(); + FrameBuffer* pBuffer = fbList.getCurrent(); + if (!fbList.isFboMode()) + glViewport( 0, OGL.heightOffset, OGL.width, OGL.height ); else - glViewport( 0, 0, frameBuffer.top->width*frameBuffer.top->scaleX, frameBuffer.top->height*frameBuffer.top->scaleY ); + glViewport( 0, 0, pBuffer->m_width*pBuffer->m_scaleX, pBuffer->m_height*pBuffer->m_scaleY ); glDisable( GL_CULL_FACE ); - const float scaleX = frameBuffer.drawBuffer == GL_FRAMEBUFFER ? 1.0f/frameBuffer.top->width : VI.rwidth; - const float scaleY = frameBuffer.drawBuffer == GL_FRAMEBUFFER ? 1.0f/frameBuffer.top->height : VI.rheight; + const float scaleX = fbList.isFboMode() ? 1.0f/pBuffer->m_width : VI.rwidth; + const float scaleY = fbList.isFboMode() ? 1.0f/pBuffer->m_height : VI.rheight; OGL.rect[0].x = (float) ulx * (2.0f * scaleX) - 1.0f; OGL.rect[0].y = (float) uly * (-2.0f * scaleY) + 1.0f; OGL.rect[1].x = (float) (lrx) * (2.0f * scaleX) - 1.0f; @@ -1207,7 +1210,7 @@ void OGL_DrawTexturedRect( float ulx, float uly, float lrx, float lry, float uls void OGL_ClearDepthBuffer() { - if (config.frameBufferEmulation.enable && frameBufferList().top == NULL) + if (config.frameBufferEmulation.enable && frameBufferList().getCurrent() == NULL) return; DepthBuffer_ClearBuffer(); diff --git a/VI.cpp b/VI.cpp index 3e85c080..5733b051 100644 --- a/VI.cpp +++ b/VI.cpp @@ -61,19 +61,19 @@ void VI_UpdateScreen() const bool bNeedUpdate = bCFB ? true : (*REG.VI_ORIGIN != VI.lastOrigin);// && gDP.colorImage.changed; if (bNeedUpdate) { - FrameBuffer * pBuffer = FrameBuffer_FindBuffer(*REG.VI_ORIGIN); - if (pBuffer == NULL || pBuffer->width != *REG.VI_WIDTH) { + FrameBuffer * pBuffer = frameBufferList().findBuffer(*REG.VI_ORIGIN); + if (pBuffer == NULL || pBuffer->m_width != *REG.VI_WIDTH) { VI_UpdateSize(); OGL_UpdateScale(); const u32 size = *REG.VI_STATUS & 3; if (VI.height > 0 && size > G_IM_SIZ_8b) - FrameBuffer_SaveBuffer( *REG.VI_ORIGIN, G_IM_FMT_RGBA, size, *REG.VI_WIDTH, VI.height ); + frameBufferList().saveBuffer( *REG.VI_ORIGIN, G_IM_FMT_RGBA, size, *REG.VI_WIDTH, VI.height ); } if ((((*REG.VI_STATUS)&3) > 0) && (config.frameBufferEmulation.copyFromRDRAM || bCFB)) { VI_UpdateSize(); FrameBuffer_CopyFromRDRAM( *REG.VI_ORIGIN, config.frameBufferEmulation.copyFromRDRAM && !bCFB ); } - FrameBuffer_RenderBuffer( *REG.VI_ORIGIN ); + frameBufferList().renderBuffer(*REG.VI_ORIGIN); gDP.colorImage.changed = FALSE; VI.lastOrigin = *REG.VI_ORIGIN; diff --git a/ZilmarGFX_1_3.h b/ZilmarGFX_1_3.h index 932b397a..4faabf0a 100644 --- a/ZilmarGFX_1_3.h +++ b/ZilmarGFX_1_3.h @@ -27,7 +27,7 @@ extern "C" { #define PLUGIN_TYPE_GFX 2 #define EXPORT __declspec(dllexport) -#define CALL _cdecl +#define CALL __cdecl /***** Structures *****/ typedef struct { diff --git a/gDP.cpp b/gDP.cpp index 1031e373..53cb8ad1 100644 --- a/gDP.cpp +++ b/gDP.cpp @@ -277,7 +277,7 @@ void gDPSetColorImage( u32 format, u32 size, u32 width, u32 address ) if (config.frameBufferEmulation.enable)// && address != gDP.depthImageAddress) { //if (gDP.colorImage.changed) - FrameBuffer_SaveBuffer( address, (u16)format, (u16)size, (u16)width, height ); + frameBufferList().saveBuffer(address, (u16)format, (u16)size, (u16)width, height); gDP.colorImage.height = 1; //OGL_ClearDepthBuffer(); @@ -506,33 +506,33 @@ bool CheckForFrameBufferTexture(u32 _address, u32 _bytes) if (!config.frameBufferEmulation.enable) return false; - FrameBuffer *pBuffer = FrameBuffer_FindBuffer( _address ); + FrameBuffer *pBuffer = frameBufferList().findBuffer(_address); bool bRes = pBuffer != NULL; if ((bRes) //&& ((*(u32*)&RDRAM[pBuffer->startAddress] & 0xFFFEFFFE) == (pBuffer->startAddress & 0xFFFEFFFE)) // Does not work for Jet Force Gemini ) { const u32 texEndAddress = _address + _bytes - 1; - const u32 bufEndAddress = pBuffer->startAddress + (((pBuffer->width * (int)gDP.scissor.lry) << pBuffer->size >> 1) - 1); - if (_address > pBuffer->startAddress && texEndAddress > bufEndAddress) { + const u32 bufEndAddress = pBuffer->m_startAddress + (((pBuffer->m_width * (int)gDP.scissor.lry) << pBuffer->m_size >> 1) - 1); + if (_address > pBuffer->m_startAddress && texEndAddress > bufEndAddress) { // FrameBuffer_RemoveBuffer(pBuffer->startAddress); bRes = false; } - if (bRes && gDP.loadTile->loadType == LOADTYPE_TILE && gDP.textureImage.width != pBuffer->width && gDP.textureImage.size != pBuffer->size) { + if (bRes && gDP.loadTile->loadType == LOADTYPE_TILE && gDP.textureImage.width != pBuffer->m_width && gDP.textureImage.size != pBuffer->m_size) { //FrameBuffer_RemoveBuffer(pBuffer->startAddress); // Does not work with Zelda MM bRes = false; } - if (bRes && pBuffer->cleared && pBuffer->size == 2 + if (bRes && pBuffer->m_cleared && pBuffer->m_size == 2 && !config.frameBufferEmulation.copyToRDRAM - && (!config.frameBufferEmulation.copyDepthToRDRAM || pBuffer->fillcolor != DEPTH_CLEAR_COLOR) + && (!config.frameBufferEmulation.copyDepthToRDRAM || pBuffer->m_fillcolor != DEPTH_CLEAR_COLOR) ) { - const u32 endAddress = min(texEndAddress, pBuffer->endAddress); - const u32 color = pBuffer->fillcolor&0xFFFEFFFE; + const u32 endAddress = min(texEndAddress, pBuffer->m_endAddress); + const u32 color = pBuffer->m_fillcolor&0xFFFEFFFE; for (u32 i = _address + 4; i < endAddress; i+=4) { if (((*(u32*)&RDRAM[i])&0xFFFEFFFE) != color) { - FrameBuffer_RemoveBuffer(pBuffer->startAddress); + frameBufferList().removeBuffer(pBuffer->m_startAddress); bRes = false; break; } @@ -540,7 +540,7 @@ bool CheckForFrameBufferTexture(u32 _address, u32 _bytes) } if (bRes) { - pBuffer->loadTile = gDP.loadTile; + pBuffer->m_pLoadTile = gDP.loadTile; gDP.loadTile->frameBuffer = pBuffer; gDP.loadTile->textureMode = TEXTUREMODE_FRAMEBUFFER; } @@ -752,10 +752,10 @@ void gDPFillRDRAM(u32 address, s32 ulx, s32 uly, s32 lrx, s32 lry, u32 width, u3 { if (g_bDepthClearOnly && color != DEPTH_CLEAR_COLOR) return; - FrameBufferList & frameBuffer = frameBufferList(); - if (frameBuffer.drawBuffer == GL_FRAMEBUFFER) { - frameBuffer.top->cleared = true; - frameBuffer.top->fillcolor = color; + FrameBufferList & fbList = frameBufferList(); + if (fbList.isFboMode()) { + fbList.getCurrent()->m_cleared = true; + fbList.getCurrent()->m_fillcolor = color; } ulx = min(max((float)ulx, gDP.scissor.ulx), gDP.scissor.lrx); lrx = min(max((float)lrx, gDP.scissor.ulx), gDP.scissor.lrx); diff --git a/gSP.cpp b/gSP.cpp index fd8a563e..ff001e5e 100644 --- a/gSP.cpp +++ b/gSP.cpp @@ -1684,14 +1684,14 @@ void _copyDepthBuffer() // It will be copy depth buffer DepthBuffer_SetBuffer(gDP.colorImage.address); // Take any frame buffer and attach source depth buffer to it, to blit it into copy depth buffer - FrameBuffer * pTmpBuffer = frameBufferList().top->lower; - DepthBuffer * pTmpBufferDepth = pTmpBuffer->pDepthBuffer; - pTmpBuffer->pDepthBuffer = DepthBuffer_FindBuffer(gSP.bgImage.address); - glBindFramebuffer(GL_READ_FRAMEBUFFER, pTmpBuffer->fbo); - glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, pTmpBuffer->pDepthBuffer->renderbuf); + FrameBuffer * pTmpBuffer = frameBufferList().findTmpBuffer(frameBufferList().getCurrent()->m_startAddress); + DepthBuffer * pTmpBufferDepth = pTmpBuffer->m_pDepthBuffer; + pTmpBuffer->m_pDepthBuffer = DepthBuffer_FindBuffer(gSP.bgImage.address); + glBindFramebuffer(GL_READ_FRAMEBUFFER, pTmpBuffer->m_FBO); + glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, pTmpBuffer->m_pDepthBuffer->renderbuf); GLuint attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT }; glDrawBuffers(2, attachments); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().top->fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferList().getCurrent()->m_FBO); glBlitFramebuffer( 0, 0, OGL.width, OGL.height, 0, 0, OGL.width, OGL.height, @@ -1726,11 +1726,11 @@ void loadBGImage(const uObjScaleBg * _bgInfo, bool _loadScale) if (config.frameBufferEmulation.enable) { - FrameBuffer *buffer; - if (((buffer = FrameBuffer_FindBuffer( gSP.bgImage.address )) != NULL) && - ((*(u32*)&RDRAM[buffer->startAddress] & 0xFFFEFFFE) == (buffer->startAddress & 0xFFFEFFFE))) + FrameBuffer *pBuffer = frameBufferList().findBuffer(gSP.bgImage.address); + if ((pBuffer != NULL) && + ((*(u32*)&RDRAM[pBuffer->m_startAddress] & 0xFFFEFFFE) == (pBuffer->m_startAddress & 0xFFFEFFFE))) { - gDP.tiles[0].frameBuffer = buffer; + gDP.tiles[0].frameBuffer = pBuffer; gDP.tiles[0].textureMode = TEXTUREMODE_FRAMEBUFFER_BG; gDP.tiles[0].loadType = LOADTYPE_TILE; gDP.changed |= CHANGED_TMEM; @@ -1945,9 +1945,10 @@ void gSPObjSprite( u32 sp ) gDPSetTileSize( 0, 0, 0, (imageW - 1) << 2, (imageH - 1) << 2 ); gSPTexture( 1.0f, 1.0f, 0, 0, TRUE ); - FrameBufferList & frameBuffer = frameBufferList(); - const float scaleX = frameBuffer.drawBuffer == GL_FRAMEBUFFER ? 1.0f/frameBuffer.top->width : VI.rwidth; - const float scaleY = frameBuffer.drawBuffer == GL_FRAMEBUFFER ? 1.0f/frameBuffer.top->height : VI.rheight; + const FrameBufferList & fbList = frameBufferList(); + FrameBuffer * pBuffer = fbList.getCurrent(); + const float scaleX = fbList.isFboMode() ? 1.0f/pBuffer->m_width : VI.rwidth; + const float scaleY = fbList.isFboMode() ? 1.0f/pBuffer->m_height : VI.rheight; OGL.triangles.vertices[v0].x = 2.0f * scaleX * OGL.triangles.vertices[v0].x - 1.0f; OGL.triangles.vertices[v0].y = -2.0f * scaleY * OGL.triangles.vertices[v0].y + 1.0f; OGL.triangles.vertices[v0].z = -1.0f;