From f147927af92a018e5b9792464ca19db009f51dcf Mon Sep 17 00:00:00 2001 From: Sergey Lipskiy Date: Fri, 20 Jan 2017 18:47:19 +0700 Subject: [PATCH] Remove OpenGL use from FrameBuffer --- src/BufferCopy/DepthBufferToRDRAM.cpp | 4 +- src/BufferCopy/RDRAMtoColorBuffer.cpp | 2 +- src/DepthBuffer.cpp | 12 +- src/FrameBuffer.cpp | 239 +++++++++--------- src/FrameBuffer.h | 10 +- src/Graphics/Context.cpp | 2 + src/Graphics/Context.h | 3 + .../OpenGLContext/opengl_ContextImpl.cpp | 4 + .../windows/windows_DisplayWindow.cpp | 4 +- src/OpenGL.cpp | 4 +- src/TextureFilterHandler.cpp | 6 +- src/gSP.cpp | 11 +- src/windows/OpenGL_windows.cpp | 4 +- 13 files changed, 164 insertions(+), 141 deletions(-) diff --git a/src/BufferCopy/DepthBufferToRDRAM.cpp b/src/BufferCopy/DepthBufferToRDRAM.cpp index 9d30d1b3..00e44a00 100644 --- a/src/BufferCopy/DepthBufferToRDRAM.cpp +++ b/src/BufferCopy/DepthBufferToRDRAM.cpp @@ -164,10 +164,10 @@ bool DepthBufferToRDRAM::_prepareCopy(u32 _address, bool _copyChunk) return false; if (config.video.multisampling == 0) - glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_FBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER, GLuint(pBuffer->m_FBO)); else { m_pCurDepthBuffer->resolveDepthBufferTexture(pBuffer); - glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_resolveFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER, GLuint(pBuffer->m_resolveFBO)); } glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO); glDisable(GL_SCISSOR_TEST); diff --git a/src/BufferCopy/RDRAMtoColorBuffer.cpp b/src/BufferCopy/RDRAMtoColorBuffer.cpp index 9fad0e25..b764fd0e 100644 --- a/src/BufferCopy/RDRAMtoColorBuffer.cpp +++ b/src/BufferCopy/RDRAMtoColorBuffer.cpp @@ -280,7 +280,7 @@ void RDRAMtoColorBuffer::copyFromRDRAM(u32 _address, bool _bCFB) CombinerInfo::get().updateParameters(); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_pCurBuffer->m_FBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, GLuint(m_pCurBuffer->m_FBO)); GraphicsDrawer::TexturedRectParams params((float)x0, (float)y0, (float)width, (float)height, 0.0f, 0.0f, width - 1.0f, height - 1.0f, 1.0f, 1.0f, diff --git a/src/DepthBuffer.cpp b/src/DepthBuffer.cpp index 034dbb6d..62028a1a 100644 --- a/src/DepthBuffer.cpp +++ b/src/DepthBuffer.cpp @@ -118,7 +118,7 @@ void DepthBuffer::initDepthImageTexture(FrameBuffer * _pBuffer) gfxContext.addFrameBufferRenderTarget(bufTarget); } - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _pBuffer->m_FBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, GLuint(_pBuffer->m_FBO)); depthBufferList().clearBuffer(0, 0, VI.width, VI.height); } @@ -257,12 +257,12 @@ CachedTexture * DepthBuffer::resolveDepthBufferTexture(FrameBuffer * _pBuffer) return m_pDepthBufferTexture; if (m_resolved) return m_pResolveDepthBufferTexture; - glBindFramebuffer(GL_READ_FRAMEBUFFER, _pBuffer->m_FBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER, GLuint(_pBuffer->m_FBO)); glReadBuffer(GL_COLOR_ATTACHMENT0); GLuint attachment = GL_COLOR_ATTACHMENT0; glDrawBuffers(1, &attachment); assert(checkFBO()); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _pBuffer->m_resolveFBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, GLuint(_pBuffer->m_resolveFBO)); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_pResolveDepthBufferTexture->glName, 0); assert(checkFBO()); glDisable(GL_SCISSOR_TEST); @@ -273,7 +273,7 @@ CachedTexture * DepthBuffer::resolveDepthBufferTexture(FrameBuffer * _pBuffer) ); glEnable(GL_SCISSOR_TEST); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _pBuffer->m_FBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, GLuint(_pBuffer->m_FBO)); m_resolved = true; return m_pResolveDepthBufferTexture; #else @@ -292,7 +292,7 @@ CachedTexture * DepthBuffer::copyDepthBufferTexture(FrameBuffer * _pBuffer) _initDepthBufferTexture(_pBuffer, m_pDepthBufferCopyTexture, false); } - glBindFramebuffer(GL_READ_FRAMEBUFFER, _pBuffer->m_FBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER, GLuint(_pBuffer->m_FBO)); glReadBuffer(GL_COLOR_ATTACHMENT0); assert(checkFBO()); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_copyFBO); @@ -311,7 +311,7 @@ CachedTexture * DepthBuffer::copyDepthBufferTexture(FrameBuffer * _pBuffer) ); glEnable(GL_SCISSOR_TEST); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _pBuffer->m_FBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, GLuint(_pBuffer->m_FBO)); m_copied = true; return m_pDepthBufferCopyTexture; } diff --git a/src/FrameBuffer.cpp b/src/FrameBuffer.cpp index e5f38683..a9dbd0d7 100644 --- a/src/FrameBuffer.cpp +++ b/src/FrameBuffer.cpp @@ -28,6 +28,7 @@ #include "DisplayWindow.h" using namespace std; +using namespace graphics; FrameBuffer::FrameBuffer() : m_startAddress(0), m_endAddress(0), m_size(0), m_width(0), m_height(0), m_validityChecked(0), @@ -36,19 +37,19 @@ FrameBuffer::FrameBuffer() : m_isDepthBuffer(false), m_isPauseScreen(false), m_isOBScreen(false), m_needHeightCorrection(false), m_readable(false), m_loadType(LOADTYPE_BLOCK), m_pDepthBuffer(nullptr), - m_resolveFBO(0), m_pResolveTexture(nullptr), m_resolved(false), - m_SubFBO(0), m_pSubTexture(nullptr) + m_pResolveTexture(nullptr), m_resolved(false), + m_pSubTexture(nullptr) { m_loadTileOrigin.uls = m_loadTileOrigin.ult = 0; m_pTexture = textureCache().addFrameBufferTexture(config.video.multisampling != 0); - m_FBO = GLuint(gfxContext.createFramebuffer()); + m_FBO = gfxContext.createFramebuffer(); } FrameBuffer::~FrameBuffer() { - gfxContext.deleteFramebuffer(graphics::ObjectHandle(m_FBO)); - gfxContext.deleteFramebuffer(graphics::ObjectHandle(m_resolveFBO)); - gfxContext.deleteFramebuffer(graphics::ObjectHandle(m_SubFBO)); + gfxContext.deleteFramebuffer(m_FBO); + gfxContext.deleteFramebuffer(m_resolveFBO); + gfxContext.deleteFramebuffer(m_SubFBO); textureCache().removeFrameBufferTexture(m_pTexture); textureCache().removeFrameBufferTexture(m_pResolveTexture); @@ -57,7 +58,7 @@ FrameBuffer::~FrameBuffer() void FrameBuffer::_initTexture(u16 _width, u16 _height, u16 _format, u16 _size, CachedTexture *_pTexture) { - const graphics::FramebufferTextureFormats & fbTexFormats = gfxContext.getFramebufferTextureFormats(); + const FramebufferTextureFormats & fbTexFormats = gfxContext.getFramebufferTextureFormats(); _pTexture->width = (u32)(_width * m_scaleX); _pTexture->height = (u32)(_height * m_scaleY); @@ -83,12 +84,12 @@ void FrameBuffer::_initTexture(u16 _width, u16 _height, u16 _format, u16 _size, textureCache().addFrameBufferTextureSize(_pTexture->textureBytes); } -void FrameBuffer::_setAndAttachTexture(u32 _fbo, CachedTexture *_pTexture, u32 _t, bool _multisampling) +void FrameBuffer::_setAndAttachTexture(ObjectHandle _fbo, CachedTexture *_pTexture, u32 _t, bool _multisampling) { { - const graphics::FramebufferTextureFormats & fbTexFormat = gfxContext.getFramebufferTextureFormats(); - graphics::Context::InitTextureParams params; - params.handle = graphics::ObjectHandle(_pTexture->glName); + const FramebufferTextureFormats & fbTexFormat = gfxContext.getFramebufferTextureFormats(); + Context::InitTextureParams params; + params.handle = ObjectHandle(_pTexture->glName); if (_multisampling) params.msaaLevel = config.video.multisampling; params.width = _pTexture->realWidth; @@ -106,21 +107,21 @@ void FrameBuffer::_setAndAttachTexture(u32 _fbo, CachedTexture *_pTexture, u32 _ gfxContext.init2DTexture(params); } { - graphics::Context::TexParameters params; - params.handle = graphics::ObjectHandle(_pTexture->glName); - params.target = _multisampling ? graphics::target::TEXTURE_2D_MULTISAMPLE : graphics::target::TEXTURE_2D; - params.textureUnitIndex = graphics::textureIndices::Tex[_t]; - params.minFilter = graphics::textureParameters::FILTER_NEAREST; - params.magFilter = graphics::textureParameters::FILTER_NEAREST; + Context::TexParameters params; + params.handle = ObjectHandle(_pTexture->glName); + params.target = _multisampling ? target::TEXTURE_2D_MULTISAMPLE : target::TEXTURE_2D; + params.textureUnitIndex = textureIndices::Tex[_t]; + params.minFilter = textureParameters::FILTER_NEAREST; + params.magFilter = textureParameters::FILTER_NEAREST; gfxContext.setTextureParameters(params); } { - graphics::Context::FrameBufferRenderTarget bufTarget; - bufTarget.bufferHandle = graphics::ObjectHandle(_fbo); - bufTarget.bufferTarget = graphics::bufferTarget::FRAMEBUFFER; - bufTarget.attachment = graphics::bufferAttachment::COLOR_ATTACHMENT0; - bufTarget.textureTarget = _multisampling ? graphics::target::TEXTURE_2D_MULTISAMPLE : graphics::target::TEXTURE_2D; - bufTarget.textureHandle = graphics::ObjectHandle(_pTexture->glName); + Context::FrameBufferRenderTarget bufTarget; + bufTarget.bufferHandle = _fbo; + bufTarget.bufferTarget = bufferTarget::FRAMEBUFFER; + bufTarget.attachment = bufferAttachment::COLOR_ATTACHMENT0; + bufTarget.textureTarget = _multisampling ? target::TEXTURE_2D_MULTISAMPLE : target::TEXTURE_2D; + bufTarget.textureHandle = ObjectHandle(_pTexture->glName); gfxContext.addFrameBufferRenderTarget(bufTarget); } assert(checkFBO()); @@ -172,11 +173,11 @@ void FrameBuffer::init(u32 _address, u32 _endAddress, u16 _format, u16 _size, u1 m_pResolveTexture = textureCache().addFrameBufferTexture(false); _initTexture(_width, _height, _format, _size, m_pResolveTexture); - m_resolveFBO = GLuint(gfxContext.createFramebuffer()); + m_resolveFBO = gfxContext.createFramebuffer(); _setAndAttachTexture(m_resolveFBO, m_pResolveTexture, 0, false); assert(checkFBO()); - glBindFramebuffer(GL_FRAMEBUFFER, m_FBO); + gfxContext.bindFramebuffer(bufferTarget::FRAMEBUFFER, m_FBO); } else _setAndAttachTexture(m_FBO, m_pTexture, 0, false); @@ -189,7 +190,7 @@ void FrameBuffer::reinit(u16 _height) const u32 endAddress = m_startAddress + ((m_width * _height) << m_size >> 1) - 1; textureCache().removeFrameBufferTexture(m_pTexture); - gfxContext.deleteFramebuffer(graphics::ObjectHandle(m_resolveFBO)); + gfxContext.deleteFramebuffer(ObjectHandle(m_resolveFBO)); textureCache().removeFrameBufferTexture(m_pResolveTexture); m_pTexture = textureCache().addFrameBufferTexture(config.video.multisampling != 0); @@ -300,29 +301,38 @@ bool FrameBuffer::isValid(bool _forceCheck) const void FrameBuffer::resolveMultisampledTexture(bool _bForce) { -#ifdef GL_MULTISAMPLING_SUPPORT + if (!Context::multisampling) + return; + if (m_resolved && !_bForce) return; - glBindFramebuffer(GL_READ_FRAMEBUFFER, m_FBO); - glReadBuffer(GL_COLOR_ATTACHMENT0); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_resolveFBO); - glDisable(GL_SCISSOR_TEST); - glBlitFramebuffer( - 0, 0, m_pTexture->realWidth, m_pTexture->realHeight, - 0, 0, m_pResolveTexture->realWidth, m_pResolveTexture->realHeight, - GL_COLOR_BUFFER_BIT, GL_NEAREST - ); - glEnable(GL_SCISSOR_TEST); - glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + + Context::BlitFramebuffersParams blitParams; + blitParams.readBuffer = m_FBO; + blitParams.drawBuffer = m_resolveFBO; + blitParams.srcX0 = 0; + blitParams.srcY0 = 0; + blitParams.srcX1 = m_pTexture->realWidth; + blitParams.srcY1 = m_pTexture->realHeight; + blitParams.dstX0 = 0; + blitParams.dstY0 = 0; + blitParams.dstX1 = m_pResolveTexture->realWidth; + blitParams.dstY1 = m_pResolveTexture->realHeight; + blitParams.mask = blitMask::COLOR_BUFFER; + blitParams.filter = textureParameters::FILTER_NEAREST; + + gfxContext.blitFramebuffers(blitParams); + + gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle()); + frameBufferList().setCurrentDrawBuffer(); m_resolved = true; -#endif } bool FrameBuffer::_initSubTexture(u32 _t) { - if (m_SubFBO == 0) - m_SubFBO = GLuint(gfxContext.createFramebuffer()); + if (!m_SubFBO.isNotNull()) + m_SubFBO = gfxContext.createFramebuffer(); gDPTile * pTile = gSP.textureTile[_t]; if (pTile->lrs < pTile->uls || pTile->lrt < pTile->ult) @@ -354,11 +364,12 @@ bool FrameBuffer::_initSubTexture(u32 _t) CachedTexture * FrameBuffer::_getSubTexture(u32 _t) { -#ifdef GLES2 - return m_pTexture; -#else + if (!gfxContext.isSupported(SpecialFeatures::BlitFramebuffer)) + return m_pTexture; + if (!_initSubTexture(_t)) return m_pTexture; + GLint x0 = (GLint)(m_pTexture->offsetS * m_scaleX); GLint y0 = (GLint)(m_pTexture->offsetT * m_scaleY) - m_pSubTexture->realHeight; GLint copyWidth = m_pSubTexture->realWidth; @@ -368,27 +379,34 @@ CachedTexture * FrameBuffer::_getSubTexture(u32 _t) if (y0 + copyHeight > m_pTexture->realHeight) copyHeight = m_pTexture->realHeight - y0; -#ifdef GLESX - if (m_pTexture->frameBufferTexture == CachedTexture::fbMultiSample){ + ObjectHandle readFBO = m_FBO; + if (gfxContext.isSupported(SpecialFeatures::WeakBlitFramebuffer) && + m_pTexture->frameBufferTexture == CachedTexture::fbMultiSample) { resolveMultisampledTexture(true); - glBindFramebuffer(GL_READ_FRAMEBUFFER, m_resolveFBO); - }else -#endif - glBindFramebuffer(GL_READ_FRAMEBUFFER, m_FBO); + readFBO = m_resolveFBO; + } + + Context::BlitFramebuffersParams blitParams; + blitParams.readBuffer = readFBO; + blitParams.drawBuffer = m_SubFBO; + blitParams.srcX0 = x0; + blitParams.srcY0 = y0; + blitParams.srcX1 = x0 + copyWidth; + blitParams.srcY1 = y0 + copyHeight; + blitParams.dstX0 = 0; + blitParams.dstY0 = 0; + blitParams.dstX1 = copyWidth; + blitParams.dstY1 = copyHeight; + blitParams.mask = blitMask::COLOR_BUFFER; + blitParams.filter = textureParameters::FILTER_NEAREST; + + gfxContext.blitFramebuffers(blitParams); + + gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle()); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_SubFBO); - glDisable(GL_SCISSOR_TEST); - glBlitFramebuffer( - x0, y0, x0 + copyWidth, y0 + copyHeight, - 0, 0, copyWidth, copyHeight, - GL_COLOR_BUFFER_BIT, GL_NEAREST - ); - glEnable(GL_SCISSOR_TEST); - glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); frameBufferList().setCurrentDrawBuffer(); return m_pSubTexture; -#endif } CachedTexture * FrameBuffer::getTexture(u32 _t) @@ -455,7 +473,7 @@ void FrameBufferList::init() { m_pCurrent = nullptr; m_pCopy = nullptr; - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle()); m_prevColorImageHeight = 0; } @@ -463,7 +481,7 @@ void FrameBufferList::destroy() { m_list.clear(); m_pCurrent = nullptr; m_pCopy = nullptr; - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle()); } void FrameBufferList::setBufferChanged() @@ -507,14 +525,15 @@ void FrameBufferList::clearBuffersChanged() void FrameBufferList::setCurrentDrawBuffer() const { if (m_pCurrent != nullptr) - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_pCurrent->m_FBO); + gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, m_pCurrent->m_FBO); } FrameBuffer * FrameBufferList::findBuffer(u32 _startAddress) { - for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) - if (iter->m_startAddress <= _startAddress && iter->m_endAddress >= _startAddress) // [ { ] - return &(*iter); + for (auto iter = m_list.begin(); iter != m_list.end(); ++iter) { + if (iter->m_startAddress <= _startAddress && iter->m_endAddress >= _startAddress) // [ { ] + return &(*iter); + } return nullptr; } @@ -542,7 +561,7 @@ FrameBuffer * FrameBufferList::_findBuffer(u32 _startAddress, u32 _endAddress, u FrameBuffer * FrameBufferList::findTmpBuffer(u32 _address) { - for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) + for (auto iter = m_list.begin(); iter != m_list.end(); ++iter) if (iter->m_startAddress > _address || iter->m_endAddress < _address) return &(*iter); return nullptr; @@ -550,7 +569,9 @@ FrameBuffer * FrameBufferList::findTmpBuffer(u32 _address) void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _width, u16 _height, bool _cfb) { - if (m_pCurrent != nullptr && config.frameBufferEmulation.copyAuxToRDRAM != 0 && (config.generalEmulation.hacks & hack_Snap) == 0) { + if (m_pCurrent != nullptr && + config.frameBufferEmulation.copyAuxToRDRAM != 0 && + (config.generalEmulation.hacks & hack_Snap) == 0) { if (m_pCurrent->isAuxiliary()) { FrameBuffer_CopyToRDRAM(m_pCurrent->m_startAddress, true); removeBuffer(m_pCurrent->m_startAddress); @@ -559,7 +580,7 @@ void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _widt if (VI.width == 0 || _height == 0) { m_pCurrent = nullptr; - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle()); return; } @@ -612,10 +633,11 @@ void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _widt } else { m_pCurrent->m_resolved = false; #ifdef VC + // TODO const GLenum discards[] = {GL_DEPTH_ATTACHMENT}; glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards); #endif - glBindFramebuffer(GL_FRAMEBUFFER, m_pCurrent->m_FBO); + gfxContext.bindFramebuffer(bufferTarget::FRAMEBUFFER, m_pCurrent->m_FBO); if (m_pCurrent->m_size != _size) { f32 fillColor[4]; gDPGetFillColor(fillColor); @@ -671,7 +693,7 @@ void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _widt void FrameBufferList::copyAux() { - for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) { + for (auto 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); } @@ -679,11 +701,11 @@ void FrameBufferList::copyAux() void FrameBufferList::removeAux() { - for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) { + for (auto 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 = nullptr; - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle()); } iter = m_list.erase(iter); if (iter == m_list.end()) @@ -694,11 +716,11 @@ void FrameBufferList::removeAux() void FrameBufferList::removeBuffer(u32 _address ) { - for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) + for (auto iter = m_list.begin(); iter != m_list.end(); ++iter) if (iter->m_startAddress == _address) { if (&(*iter) == m_pCurrent) { m_pCurrent = nullptr; - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle()); } m_list.erase(iter); return; @@ -708,11 +730,11 @@ void FrameBufferList::removeBuffer(u32 _address ) void FrameBufferList::removeBuffers(u32 _width) { m_pCurrent = nullptr; - for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) { + for (auto iter = m_list.begin(); iter != m_list.end(); ++iter) { while (iter->m_width == _width) { if (&(*iter) == m_pCurrent) { m_pCurrent = nullptr; - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle()); } iter = m_list.erase(iter); if (iter == m_list.end()) @@ -726,7 +748,7 @@ void FrameBufferList::fillBufferInfo(void * _pinfo, u32 _size) FBInfo::FrameBufferInfo* pInfo = reinterpret_cast(_pinfo); u32 idx = 0; - for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) { + for (auto iter = m_list.begin(); iter != m_list.end(); ++iter) { if (iter->m_width == VI.width && !iter->m_cfb && !iter->m_isDepthBuffer) { pInfo[idx].addr = iter->m_startAddress; pInfo[idx].width = iter->m_width; @@ -744,41 +766,38 @@ void FrameBufferList::attachDepthBuffer() return; #ifdef VC + // TODO const GLenum discards[] = {GL_DEPTH_ATTACHMENT}; glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards); #endif DepthBuffer * pDepthBuffer = depthBufferList().getCurrent(); - if (m_pCurrent->m_FBO > 0 && pDepthBuffer != nullptr) { + if (m_pCurrent->m_FBO.isNotNull() && pDepthBuffer != nullptr) { pDepthBuffer->initDepthImageTexture(m_pCurrent); pDepthBuffer->initDepthBufferTexture(m_pCurrent); -#ifndef USE_DEPTH_RENDERBUFFER -#ifdef GLESX - if (pDepthBuffer->m_pDepthBufferTexture->realWidth == m_pCurrent->m_pTexture->realWidth) { -#else - if (pDepthBuffer->m_pDepthBufferTexture->realWidth >= m_pCurrent->m_pTexture->realWidth) { -#endif // GLES2 -#else +#ifdef USE_DEPTH_RENDERBUFFER + // TODO if (pDepthBuffer->m_depthRenderbufferWidth == m_pCurrent->m_pTexture->realWidth) { +#else + const bool goodDepthBufferTexture = gfxContext.isSupported(SpecialFeatures::WeakBlitFramebuffer) ? + pDepthBuffer->m_pDepthBufferTexture->realWidth == m_pCurrent->m_pTexture->realWidth : + pDepthBuffer->m_pDepthBufferTexture->realWidth >= m_pCurrent->m_pTexture->realWidth; + if (goodDepthBufferTexture) { #endif // USE_DEPTH_RENDERBUFFER m_pCurrent->m_pDepthBuffer = pDepthBuffer; - pDepthBuffer->setDepthAttachment(m_pCurrent->m_FBO, GL_DRAW_FRAMEBUFFER); - if (graphics::Context::imageTextures && config.frameBufferEmulation.N64DepthCompare != 0) + pDepthBuffer->setDepthAttachment(GLuint(m_pCurrent->m_FBO), GL_DRAW_FRAMEBUFFER); + if (Context::imageTextures && config.frameBufferEmulation.N64DepthCompare != 0) pDepthBuffer->bindDepthImageTexture(); } else m_pCurrent->m_pDepthBuffer = nullptr; } else m_pCurrent->m_pDepthBuffer = nullptr; -#ifndef GLES2 - GLuint attachments[1] = { GL_COLOR_ATTACHMENT0 }; - glDrawBuffers(1, attachments); -#endif assert(checkFBO()); } void FrameBufferList::clearDepthBuffer(DepthBuffer * _pDepthBuffer) { - for (FrameBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter) { + for (auto iter = m_list.begin(); iter != m_list.end(); ++iter) { if (iter->m_pDepthBuffer == _pDepthBuffer) { iter->m_pDepthBuffer = nullptr; } @@ -790,9 +809,7 @@ void FrameBuffer_Init() frameBufferList().init(); if (config.frameBufferEmulation.enable != 0) { ColorBufferToRDRAM::get().init(); -#ifndef GLES2 DepthBufferToRDRAM::get().init(); -#endif RDRAMtoColorBuffer::get().init(); } } @@ -800,9 +817,7 @@ void FrameBuffer_Init() void FrameBuffer_Destroy() { RDRAMtoColorBuffer::get().destroy(); -#ifndef GLES2 DepthBufferToRDRAM::get().destroy(); -#endif ColorBufferToRDRAM::get().destroy(); frameBufferList().destroy(); } @@ -923,7 +938,7 @@ void FrameBufferList::renderBuffer(u32 _address) #endif // GLESX // glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - gfxContext.bindFramebuffer(graphics::bufferTarget::DRAW_FRAMEBUFFER, graphics::ObjectHandle()); + gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle()); //glDrawBuffer( GL_BACK ); float clearColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; @@ -931,7 +946,7 @@ void FrameBufferList::renderBuffer(u32 _address) GLenum filter = GL_LINEAR; - graphics::ObjectHandle readBuffer; + ObjectHandle readBuffer; if (pFilteredBuffer->m_pTexture->frameBufferTexture == CachedTexture::fbMultiSample) { if (X0 > 0 || dstPartHeight > 0 || @@ -939,14 +954,14 @@ void FrameBufferList::renderBuffer(u32 _address) (srcCoord[3] - srcCoord[1]) != (dstCoord[3] - dstCoord[1])) { pFilteredBuffer->resolveMultisampledTexture(true); //glBindFramebuffer(GL_READ_FRAMEBUFFER, pFilteredBuffer->m_resolveFBO); - readBuffer = graphics::ObjectHandle(pFilteredBuffer->m_resolveFBO); + readBuffer = ObjectHandle(pFilteredBuffer->m_resolveFBO); } else { // glBindFramebuffer(GL_READ_FRAMEBUFFER, pFilteredBuffer->m_FBO); - readBuffer = graphics::ObjectHandle(pFilteredBuffer->m_FBO); + readBuffer = ObjectHandle(pFilteredBuffer->m_FBO); filter = GL_NEAREST; } } else { - readBuffer = graphics::ObjectHandle(pFilteredBuffer->m_FBO); + readBuffer = ObjectHandle(pFilteredBuffer->m_FBO); // glBindFramebuffer(GL_READ_FRAMEBUFFER, pFilteredBuffer->m_FBO); } @@ -966,7 +981,7 @@ void FrameBufferList::renderBuffer(u32 _address) blitParams.dstWidth = wnd.getScreenWidth(); blitParams.dstHeight = wnd.getScreenHeight() + wnd.getHeightOffset(); blitParams.filter = filter; - blitParams.mask = graphics::blitMask::COLOR_BUFFER; + blitParams.mask = blitMask::COLOR_BUFFER; blitParams.tex[0] = pBufferTexture; blitParams.combiner = CombinerInfo::get().getTexrectCopyProgram(); blitParams.readBuffer = readBuffer; @@ -985,11 +1000,11 @@ void FrameBufferList::renderBuffer(u32 _address) dstY1 = dstY0 + dstPartHeight; if (pFilteredBuffer->m_pTexture->frameBufferTexture == CachedTexture::fbMultiSample) { pFilteredBuffer->resolveMultisampledTexture(); - readBuffer = graphics::ObjectHandle(pFilteredBuffer->m_resolveFBO); + readBuffer = ObjectHandle(pFilteredBuffer->m_resolveFBO); // glBindFramebuffer(GL_READ_FRAMEBUFFER, pFilteredBuffer->m_resolveFBO); } else { // glBindFramebuffer(GL_READ_FRAMEBUFFER, pFilteredBuffer->m_FBO); - readBuffer = graphics::ObjectHandle(pFilteredBuffer->m_FBO); + readBuffer = ObjectHandle(pFilteredBuffer->m_FBO); } // glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); @@ -1014,11 +1029,13 @@ void FrameBufferList::renderBuffer(u32 _address) } } - glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle()); + wnd.swapBuffers(); if (m_pCurrent != nullptr) { - gfxContext.bindFramebuffer(graphics::bufferTarget::DRAW_FRAMEBUFFER, graphics::ObjectHandle(m_pCurrent->m_FBO)); + gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle(m_pCurrent->m_FBO)); #ifdef VC + // TODO const GLenum discards[] = {GL_DEPTH_ATTACHMENT}; glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards); #endif @@ -1095,7 +1112,6 @@ void FrameBuffer_CopyChunkToRDRAM(u32 _address) bool FrameBuffer_CopyDepthBuffer( u32 address ) { -#ifndef GLES2 FrameBuffer * pCopyBuffer = frameBufferList().getCopyBuffer(); if (pCopyBuffer != nullptr) { // This code is mainly to emulate Zelda MM camera. @@ -1105,18 +1121,11 @@ bool FrameBuffer_CopyDepthBuffer( u32 address ) return true; } else return DepthBufferToRDRAM::get().copyToRDRAM(address); -#else - return false; -#endif } bool FrameBuffer_CopyDepthBufferChunk(u32 address) { -#ifndef GLES2 return DepthBufferToRDRAM::get().copyChunkToRDRAM(address); -#else - return false; -#endif } void FrameBuffer_CopyFromRDRAM(u32 _address, bool _bCFB) diff --git a/src/FrameBuffer.h b/src/FrameBuffer.h index 483d5da4..63af641e 100644 --- a/src/FrameBuffer.h +++ b/src/FrameBuffer.h @@ -6,6 +6,8 @@ #include "Types.h" #include "Textures.h" +#include "Graphics/ObjectHandle.h" + struct gDPTile; struct DepthBuffer; @@ -45,17 +47,17 @@ struct FrameBuffer } m_loadTileOrigin; u32 m_loadType; - GLuint m_FBO; + graphics::ObjectHandle m_FBO; CachedTexture *m_pTexture; DepthBuffer *m_pDepthBuffer; // multisampling - GLuint m_resolveFBO; + graphics::ObjectHandle m_resolveFBO; CachedTexture *m_pResolveTexture; bool m_resolved; // subtexture - GLuint m_SubFBO; + graphics::ObjectHandle m_SubFBO; CachedTexture *m_pSubTexture; std::vector m_RdramCopy; @@ -67,7 +69,7 @@ private: } m_clearParams; void _initTexture(u16 _width, u16 _height, u16 _format, u16 _size, CachedTexture *_pTexture); - void _setAndAttachTexture(u32 _fbo, CachedTexture *_pTexture, u32 _t, bool _multisampling); + void _setAndAttachTexture(graphics::ObjectHandle _fbo, CachedTexture *_pTexture, u32 _t, bool _multisampling); bool _initSubTexture(u32 _t); CachedTexture * _getSubTexture(u32 _t); mutable u32 m_validityChecked; diff --git a/src/Graphics/Context.cpp b/src/Graphics/Context.cpp index 72951c0d..7d587d6b 100644 --- a/src/Graphics/Context.cpp +++ b/src/Graphics/Context.cpp @@ -6,6 +6,7 @@ using namespace graphics; Context gfxContext; bool Context::imageTextures = false; +bool Context::multisampling = false; Context::Context() {} @@ -20,6 +21,7 @@ void Context::init() m_impl->init(); m_fbTexFormats.reset(m_impl->getFramebufferTextureFormats()); imageTextures = isSupported(SpecialFeatures::ImageTextures); + multisampling = isSupported(SpecialFeatures::Multisampling); } void Context::destroy() diff --git a/src/Graphics/Context.h b/src/Graphics/Context.h index c0509a35..33768214 100644 --- a/src/Graphics/Context.h +++ b/src/Graphics/Context.h @@ -17,6 +17,8 @@ namespace graphics { Multisampling, NearPlaneClipping, FragmentDepthWrite, + BlitFramebuffer, + WeakBlitFramebuffer, ImageTextures }; @@ -225,6 +227,7 @@ namespace graphics { bool isError() const; static bool imageTextures; + static bool multisampling; private: std::unique_ptr m_impl; diff --git a/src/Graphics/OpenGLContext/opengl_ContextImpl.cpp b/src/Graphics/OpenGLContext/opengl_ContextImpl.cpp index cd1daaef..f4a2cce7 100644 --- a/src/Graphics/OpenGLContext/opengl_ContextImpl.cpp +++ b/src/Graphics/OpenGLContext/opengl_ContextImpl.cpp @@ -327,6 +327,10 @@ bool ContextImpl::isError() const bool ContextImpl::isSupported(graphics::SpecialFeatures _feature) const { switch (_feature) { + case graphics::SpecialFeatures::BlitFramebuffer: + return !m_glInfo.isGLES2; + case graphics::SpecialFeatures::WeakBlitFramebuffer: + return m_glInfo.isGLESX; case graphics::SpecialFeatures::FragmentDepthWrite: case graphics::SpecialFeatures::NearPlaneClipping: return !m_glInfo.isGLESX; diff --git a/src/Graphics/OpenGLContext/windows/windows_DisplayWindow.cpp b/src/Graphics/OpenGLContext/windows/windows_DisplayWindow.cpp index a88bf69c..3c5633bf 100644 --- a/src/Graphics/OpenGLContext/windows/windows_DisplayWindow.cpp +++ b/src/Graphics/OpenGLContext/windows/windows_DisplayWindow.cpp @@ -134,9 +134,9 @@ void DisplayWindowWindows::_saveScreenshot() else { if (config.video.multisampling != 0) { pBuffer->resolveMultisampledTexture(); - glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_resolveFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER, GLuint(pBuffer->m_resolveFBO)); } else - glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_FBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER, GLuint(pBuffer->m_FBO)); pixelData = (unsigned char*)malloc(pBuffer->m_pTexture->realWidth * pBuffer->m_pTexture->realHeight * 3); glReadPixels(0, 0, pBuffer->m_pTexture->realWidth, pBuffer->m_pTexture->realHeight, GL_RGB, GL_UNSIGNED_BYTE, pixelData); SaveScreenshot(m_strScreenDirectory, RSP.romname, pBuffer->m_pTexture->realWidth, pBuffer->m_pTexture->realHeight, pixelData); diff --git a/src/OpenGL.cpp b/src/OpenGL.cpp index 9702f2a4..37a63267 100644 --- a/src/OpenGL.cpp +++ b/src/OpenGL.cpp @@ -631,7 +631,7 @@ bool OGLRender::TexrectDrawer::draw() rect[3].t0 = t1; render.updateScissor(m_pBuffer); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_pBuffer != nullptr ? m_pBuffer->m_FBO : 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_pBuffer != nullptr ? GLuint(m_pBuffer->m_FBO) : 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO); @@ -652,7 +652,7 @@ bool OGLRender::TexrectDrawer::draw() glEnable(GL_SCISSOR_TEST); m_pBuffer = frameBufferList().getCurrent(); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_pBuffer != nullptr ? m_pBuffer->m_FBO : 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_pBuffer != nullptr ? GLuint(m_pBuffer->m_FBO) : 0); m_numRects = 0; m_vecRectCoords.clear(); diff --git a/src/TextureFilterHandler.cpp b/src/TextureFilterHandler.cpp index 29ef898b..c246e7d6 100644 --- a/src/TextureFilterHandler.cpp +++ b/src/TextureFilterHandler.cpp @@ -1,5 +1,7 @@ #include #include "GLideNHQ/Ext_TxFilter.h" +#include +#include #include "RSP.h" #include "OpenGL.h" @@ -66,7 +68,7 @@ void displayLoadProgress(const wchar_t *format, ...) FrameBuffer* pBuffer = frameBufferList().getCurrent(); if (pBuffer != nullptr) - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + gfxContext.bindFramebuffer(graphics::bufferTarget::DRAW_FRAMEBUFFER, graphics::ObjectHandle()); GraphicsDrawer & drawer = dwnd().getDrawer(); drawer.clearColorBuffer(nullptr); @@ -74,7 +76,7 @@ void displayLoadProgress(const wchar_t *format, ...) dwnd().swapBuffers(); if (pBuffer != nullptr) - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, pBuffer->m_FBO); + gfxContext.bindFramebuffer(graphics::bufferTarget::DRAW_FRAMEBUFFER, pBuffer->m_FBO); } u32 TextureFilterHandler::_getConfigOptions() const diff --git a/src/gSP.cpp b/src/gSP.cpp index 63a7988e..ceceaafe 100644 --- a/src/gSP.cpp +++ b/src/gSP.cpp @@ -2130,7 +2130,8 @@ void gSPObjRectangleR(u32 _sp) gSPDrawObjRect(objCoords); } -#ifndef GLES2 +//TODO +#ifdef REWRITE_COPY_DEPTH static void _copyDepthBuffer() { @@ -2166,7 +2167,7 @@ void _copyDepthBuffer() // Set back current depth buffer dbList.saveBuffer(gDP.depthImageAddress); } -#endif // GLES2 +#endif // REWRITE_COPY_DEPTH static void _loadBGImage(const uObjScaleBg * _bgInfo, bool _loadScale) @@ -2221,7 +2222,7 @@ void gSPBgRect1Cyc( u32 _bg ) uObjScaleBg *objScaleBg = (uObjScaleBg*)&RDRAM[address]; _loadBGImage(objScaleBg, true); -#ifndef GLES2 +#ifdef REWRITE_COPY_DEPTH // Zelda MM uses depth buffer copy in LoT and in pause screen. // In later case depth buffer is used as temporal color buffer, and usual rendering must be used. // Since both situations are hard to distinguish, do the both depth buffer copy and bg rendering. @@ -2229,7 +2230,7 @@ void gSPBgRect1Cyc( u32 _bg ) (gSP.bgImage.address == gDP.depthImageAddress || depthBufferList().findBuffer(gSP.bgImage.address) != nullptr) ) _copyDepthBuffer(); -#endif // GLES2 +#endif // REWRITE_COPY_DEPTH gDP.otherMode.cycleType = G_CYC_1CYCLE; gDP.changed |= CHANGED_CYCLETYPE; @@ -2245,7 +2246,7 @@ void gSPBgRectCopy( u32 _bg ) uObjScaleBg *objBg = (uObjScaleBg*)&RDRAM[address]; _loadBGImage(objBg, false); -#ifdef GL_IMAGE_TEXTURES_SUPPORT +#ifdef REWRITE_COPY_DEPTH // See comment to gSPBgRect1Cyc if ((config.generalEmulation.hacks & hack_ZeldaMM) != 0 && (gSP.bgImage.address == gDP.depthImageAddress || depthBufferList().findBuffer(gSP.bgImage.address) != nullptr) diff --git a/src/windows/OpenGL_windows.cpp b/src/windows/OpenGL_windows.cpp index dd1a38b1..4168df38 100644 --- a/src/windows/OpenGL_windows.cpp +++ b/src/windows/OpenGL_windows.cpp @@ -131,9 +131,9 @@ void OGLVideoWindows::_saveScreenshot() else { if (config.video.multisampling != 0) { pBuffer->resolveMultisampledTexture(); - glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_resolveFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER, GLuint(pBuffer->m_resolveFBO)); } else - glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_FBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER, GLuint(pBuffer->m_FBO)); pixelData = (unsigned char*)malloc(pBuffer->m_pTexture->realWidth * pBuffer->m_pTexture->realHeight * 3); glReadPixels(0, 0, pBuffer->m_pTexture->realWidth, pBuffer->m_pTexture->realHeight, GL_RGB, GL_UNSIGNED_BYTE, pixelData); SaveScreenshot(m_strScreenDirectory, RSP.romname, pBuffer->m_pTexture->realWidth, pBuffer->m_pTexture->realHeight, pixelData);